81 lines
3.4 KiB
C++
81 lines
3.4 KiB
C++
// 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 <array>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
|
|
// 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<char, MAXDRVNAMELEN> name{};
|
|
if (session.drivers.asioGetDriverName(static_cast<int>(i), name.data(),
|
|
static_cast<int>(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;
|
|
}
|