In order to handle an input-only ASIO stream, the code
AudioIODevice* createDevice (const String& outputDeviceName,
const String& inputDeviceName)
{
// ASIO can't open two different devices for input and output - they must be the same one.
jassert (inputDeviceName == outputDeviceName || outputDeviceName.isEmpty() || inputDeviceName.isEmpty());
jassert (hasScanned); // need to call scanForDevices() before doing this
const int index = deviceNames.indexOf (outputDeviceName.isNotEmpty() ? outputDeviceName
: inputDeviceName);
if (index >= 0)
{
const int freeSlot = findFreeSlot();
if (freeSlot >= 0)
return new ASIOAudioIODevice (this, outputDeviceName,
classIds.getReference (index), freeSlot);
}
return nullptr;
}
should be changed to
AudioIODevice* createDevice (const String& outputDeviceName,
const String& inputDeviceName)
{
// ASIO can't open two different devices for input and output - they must be the same one.
jassert (inputDeviceName == outputDeviceName || outputDeviceName.isEmpty() || inputDeviceName.isEmpty());
jassert (hasScanned); // need to call scanForDevices() before doing this
const String deviceName = outputDeviceName.isNotEmpty() ? outputDeviceName
: inputDeviceName;
const int index = deviceNames.indexOf (deviceName);
if (index >= 0)
{
const int freeSlot = findFreeSlot();
if (freeSlot >= 0)
return new ASIOAudioIODevice (this, deviceName,
classIds.getReference (index), freeSlot);
}
return nullptr;
}
While we're on the subject, the size of the currentASIODev array is 3. Any reason it is this small ? I'm enumerating devices and store instances of them and the number of ASIO devices might well surpass 3 (even though the devices won't be opened/streaming at the same time). Is there any reason to limit the number of ASIO devices ? After all, they're just COM objects...
There's no particular reason, other than it needs to be a static array, so I didn't want to allocate a lot of space, and didn't really expect people to open more than a couple at once. I guess it could be a higher number, but I would recommend not opening more than you need simultaneously anyway, since you never know how drivers will interact with each other - if you're enumerating then better to open + close them one at a time.
But if ill behaved drivers do interact, they could do that with only two drivers open (with enough bad luck), thereby rendering the limit moot. That would be an argument against a limit, wouldn't you agree?
Sure. There does have to be a limit, because it's a preallocated array, but yes, it could indeed be a bit higher without any problem. TBH even a number as low as 8 should be more than enough - I can't imagine anyone would have more than 8 difference ASIO devices connected at one time!
Yes - normally an ASIO device appears as a single object that you open - inside it, it can have as many input + output channels as it wants.
ASIO was only ever designed to allow an application to have a single device open at once - in fact the only reason JUCE lets you open more than one is via a bit of a hack. Since the ASIO callbacks provide no per-device information, the only way to run more than one device is by giving each device a different set of functions to call, each of which is hard-coded to know which instance of a device it's attached to. Have a look at the horrible things I had to do with templates in setCallbackFunctions() to see what a pain this is! For each extra simultaneous device that can be opened, there needs to be another set of static functions declared. (And actually, I just noticed that I shouldn't have changed the maximum number to 4 without updating the templates.. I'll fix that now..)
Yes, the designers of ASIO weren't the brightest. Just to leave out the possibility to pass a void* pointer via the callback mechanism (which is programming 101 in C callbacks)...
Ah well, anyways, if you're interested, I've managed to make a hack via "thunking", so that I can provide a per-ASIO-device specific C++ callback interface (which ASIOAudioIODevice inherits), supporting an arbitrary number of devices :)
That way, there's no need for the device index template hack.
Yes, by necessity. But it's not that nasty, and not a lot of code really, and by making sure that the calling convention is cdecl, it only involved making the stack look correct upon calling the C++ functions, and before returning.
I got x86 working, now porting it to x64.
I can send you the code when I'm done with that.
Edit: Wow! x64 is really a different beast! This'll take time, not even sure if I'll manage :(