Closing Audio-Device - endless loop of last buffer


#1

this is may a bug in the driver, but in the end this will fall back to the app which is using the device.

When closing an ASIO-Device, the last buffer which was filled will be played in a endless loop.
It would be better, when closing the device, to set a flag, that the buffer in the callback will be filled with silence, and wait until such a buffer has proceeded, before the object will be destroyed.


#2

Never heard of that one before, I guess it must be the driver that’s acting weird.

Does it help if you add a delay in juce_win32_ASIO, line 600ish:

[code] if (isASIOOpen && isOpen_)
{
Thread::sleep (3 * (int) (getCurrentBufferSizeSamples() * 1000 / getCurrentSampleRate()));

        const ScopedLock sl (callbackLock);

[/code]

?


#3

crazy, just want to reconstruct the issue, but it will not fail :-/

But another thing i noticed is, when changing the device it can take up to 20 seconds where the application is totally unresponsive (but the mouse has no waiting symbol. It would be nice to add a “wait” label, as long the changing is taken:

void AudioDeviceSelectorComponent::comboBoxChanged (ComboBox* comboBoxThatHasChanged)
{
    if (comboBoxThatHasChanged == deviceTypeDropDown)
    {
        AudioIODeviceType* const type = deviceManager.getAvailableDeviceTypes() [deviceTypeDropDown->getSelectedId() - 1];

        if (type != 0)
        {
            audioDeviceSettingsComp = 0;
		
			{																                        						//New
				ScopedPointer<Label> wlabel=new Label(String::empty,"wait");				         		  //New
				wlabel->setColour(Label::textColourId,Colours::black);								          //New
				wlabel->setColour(Label::backgroundColourId,Colours::lightgrey.withAlpha(0.6f));	    //New
				wlabel->setJustificationType(Justification::centred);						        		//New
				wlabel->setBounds(getWidth()/2-70,getHeight()/2-20,140,40);							//New
				addAndMakeVisible(wlabel);												           			//New
				MessageManager::getInstance()->runDispatchLoopUntil(300);							//New
				
			
				deviceManager.setCurrentAudioDeviceType (type->getTypeName(), true);
			};																						//New

            changeListenerCallback (0); // needed in case the type hasn't actally changed
        }
    }
    else if (comboBoxThatHasChanged == midiOutputSelector)
    {
        deviceManager.setDefaultMidiOutput (midiOutputSelector->getText());
    }
}

#4

Hmm. Sounds like a dodgy driver to me then. Don’t like the hacky wait message idea - the “correct” way to do it would be to have a thread and a proper progress box, I’ll have to have a think about it.


#5

yes, this was hacky (only for demo), the drivers are from RME Fireface and they have a good reputation to be very stable


#6

oh i could reproduce the (initial) problem, your suggestion does NOT fix the issue.


#7

WHOA…are we really talking about a progress box for closing an audio device? I’ve noticed that even my top-specced PC pauses for a second or two when I change audio parameters but 20 seconds? I’m using an RME Fireface 400 with the latest drivers.

Why not just have Juce, instead of calling the user provided audioCallback, supply its own audioCallback which fills the buffers with zero, just for during the time when the driver is performing its close operation?

It sounds a little crazy to think that in order to shut down a thread we must first create a new one (LOL). Are audio drivers that bad?


#8

That’s exactly what should happen with the change I suggested above - it turns off the user callback, which means that any audio callbacks will just clear the buffers, and then I suggested adding a delay to wait until a few buffers have been processed before actually stopping the device. Maybe this driver has an even bigger internal buffer, and you’d need to wait until the whole thing has been filled with zeros… Maybe try changing it to Thread::sleep (1000) instead of what I said above?

In my experience, yes, ASIO drivers are surprisingly bad.


#9

yeah, it does not always took so long, only sometimes

switching “ASIO/ASIO Fireface” to “DirectSound” 1 sec.
switching “ASIO/ASIO Fireface” to “ASIO/ASIO DirectX Full Duplex Driver” 20 sec.
switching “ASIO/ASIO DirectX Full Duplex Driver” to Direct X 1 sec.