ASIO Issue

Hi
I discovered an issue opening ASIO drivers on windows.
If you load the same driver twise (re-loading)
Juce will try to close the driver first, around line 397 of juce_win32_ASIO.cpp

   if (isOpen())
        close();

When stopping it is asumed that asioObject will go to nullptr during several Thread::sleep(20) in the close() function.
This is not always the case it seems.
I get crashes using this. So i added

asioObject = nullptr;

after the last sleep. that seems to solve the issue.
I have no idea if this was a good solution or not? any ideas?

Can you provide some more information? Where is the crash occurring? If you can provide a minimal reproducible example or at least a stack trace of the crash this will help to track it down.

Hi
Sorry for not being clear.
It is not so easy to explain. I only get the issue with RME devices (as far as I can tell)
There is no need to find the bug, I believe I found it, it seems like a dangling pointer to asioObject. Let me try to explain again.
The issue is only present when I have the RME device open, and then call setAudioDeviceSetup with the same device as is already open, with (or without) the same device settings.

  1. Call AudioDeviceManager::setAudioDeviceSetup(newSetup,true) ← With the currently open RME device
  2. Now, ASIOAudioIODEvice::open() is called (in juce_win32_ASIO.cpp)
    First thing this function does is this: (line 397)
if (isOpen())
        close();

Since the device is open, it will try to close it and continue on.
Now, a bit further down on line 405, it only opens the device if asioObject == nullptr, and it seems that is not always the case.

    if (asioObject == nullptr)
    {
        auto openingError = openDevice();

        if (asioObject == nullptr)
            return openingError;
    } 

With the RME device we get a crash on the next line:

 auto err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans);
    jassert (err == ASE_OK);

The problem is that asioObject is not nullptr, so the device is never opened before the call to asioObject->getChannels. since asioObject points to the closed device (or god knows what) you get an access violation.

The source of this, as far as I can tell, is in the close() function:
In the close() function you have this:

if (asioObject != nullptr)
{
Thread::sleep (20);
asioObject->stop();
Thread::sleep (10);
disposeBuffers();
}

        Thread::sleep (10);

Then it returns, but asioObjects is never set to nullptr, but is rather a dangling pointer, and thereby the device is not opened (as pointed to earlier).

if I add

asioObject = nullptr ;

after the last sleep(10) it all seems to work fine.
Problem is, I don’t know enough about the underlying logic here to know if it is a stupid fix or not.

1 Like