// Original MIT-licensed diagnostics; build against a separately supplied ASIO SDK. // This example inspects an explicitly selected driver. It never starts audio, // changes sample rate, opens a control panel, or installs/registers a driver. #include "asiosys.h" #include "asio.h" #include "asiodrivers.h" #include #include #include // The SDK dispatch layer (including ASIOExit) uses this SDK-owned pointer. extern AsioDrivers* asioDrivers; namespace { struct Driver { AsioDrivers drivers; bool initialized = false; Driver() { asioDrivers = &drivers; } ~Driver() { if (initialized) ASIOExit(); drivers.removeCurrentDriver(); asioDrivers = nullptr; } }; } int main(int argc, char** argv) { if (argc != 1 && (argc != 3 || std::strcmp(argv[1], "--driver"))) { std::fprintf(stderr, "Usage: xtc-asio-devices [--driver \"installed driver name\"]\n"); return 2; } Driver session; if (argc == 1) { const long count = session.drivers.asioGetNumDev(); if (count < 0) return 1; for (long i = 0; i < count; ++i) { std::array name{}; if (session.drivers.asioGetDriverName(static_cast(i), name.data(), static_cast(name.size())) != 0) return 1; std::puts(name.data()); } if (!count) std::puts("No ASIO drivers registered for this executable's architecture."); return 0; } // ASIO SDK uses char*, but does not retain or modify this argument. if (!session.drivers.loadDriver(argv[2])) { std::fprintf(stderr, "Cannot load the named ASIO driver.\n"); return 1; } ASIODriverInfo info{}; info.asioVersion = 2; info.sysRef = GetDesktopWindow(); if (ASIOInit(&info) != ASE_OK) { std::fprintf(stderr, "ASIO initialization failed: %.124s\n", info.errorMessage); return 1; } session.initialized = true; long inputs = 0, outputs = 0, minimum = 0, maximum = 0, preferred = 0, granularity = 0; long inputLatency = 0, outputLatency = 0; ASIOSampleRate rate = 0; if (ASIOGetChannels(&inputs, &outputs) != ASE_OK || ASIOGetSampleRate(&rate) != ASE_OK || ASIOGetBufferSize(&minimum, &maximum, &preferred, &granularity) != ASE_OK || ASIOGetLatencies(&inputLatency, &outputLatency) != ASE_OK) { std::fprintf(stderr, "ASIO format/status query failed.\n"); return 1; } std::printf("%.32s | version %ld\nrate %.0f Hz | %ld inputs / %ld outputs\n" "buffer %ld..%ld frames, preferred %ld, granularity %ld\n" "latency input %ld / output %ld frames\n", info.name, info.driverVersion, rate, inputs, outputs, minimum, maximum, preferred, granularity, inputLatency, outputLatency); if (inputs < 0 || outputs < 0 || inputs > 1024 || outputs > 1024) return 1; for (long direction = 0; direction < 2; ++direction) { for (long i = 0; i < (direction ? outputs : inputs); ++i) { ASIOChannelInfo channel{}; channel.channel = i; channel.isInput = direction ? ASIOFalse : ASIOTrue; if (ASIOGetChannelInfo(&channel) != ASE_OK) return 1; std::printf("%s %ld: %.32s | ASIO sample type %ld\n", direction ? "output" : "input", i, channel.name, channel.type); } } return 0; }