AudioTransportSource issue with isPlaying()


#1

If you call AudioTransportSource::stop() then isPlaying() will return true even that AudioTransportSource did not realy stop, only started stopping. AudioTransportSource::stop() will return only after it gets another audio block or after 1 second timeout if it doesn’t get any.

Is this issue with isPlaying() a bug or a planned behaviour?


#2

hmm - yes, though everything would have to have gone very badly wrong if it doesn’t manage to stop within the timeout! If that happens then it might as well say it’s stopped, because it sure as hell isn’t playing properly. I should probably make it return a bool, though.


#3

my problem was that in the processBlock() method I had

if (!isPlaying())
return // do nothing

else
send buffer to transport, etc.

so it didn’t stop since it got to get blocks in order to stop so it waited for the timeout… .

i had to remove the isPlaying and let it always play even if stopped…

The efficient solution will be to fix the isPlaying method or for me to get events from the transport and have my own isPlaying flag that is false only when its realy stopped…


#4

huh? If it’s stopped, it stops asking for blocks, so you don’t need to check whether it’s playing when it’s in the callback - it always will be…


#5

I am doign a VST so host always asks for more blocks, my code looks like that:

void SCFilePlayer::process (float **inputs, float **outputs, long sampleFrames)
{
// do nothing if not playing
if ( !transport.isPlaying() )
return;

// prepare buffer in JUCE format, assume stero output
AudioSampleBuffer output (outputs, 2, sampleFrames);

// get next block from transport
AudioSourceChannelInfo	info;
info.buffer = &output;
info.startSample = 0;
info.numSamples = output.getNumSamples();
transport.getNextAudioBlock( info );

}

In another place I called transport.stop() and I got this 1 sec delay. I found that the transport needs to process blocks until it stops but the isPlaying() returns false before the transport internal ‘stopped’ flag is true…so in order to avoid the 1 sec delay I removed the isPlaying() call and just keep sending blocks to the transport even after it stopped and it just ignores them and the code works, although maybe not very efficient, i didn’t check…

this is the code from JUCE, you can see playing becomes false but stopped is still not true…

void AudioTransportSource::stop()
{
if (playing)
{
callbackLock.enter();
playing = false;
callbackLock.exit();

    int n = 500;
    while (--n >= 0 && ! stopped)
        Thread::sleep (2);

    sendChangeMessage (this);
}

}


#6

Ok, well what you should be doing is to keep letting the transport process blocks regardless of whether it’s stopped or not. The isPlaying() call isn’t there for dsp tasks, it’s there so bits of UI can see when it’s running. The idea is that the transport is continuously called back even when it’s stopped.


#7

thats exactly what I already did and it works! Maybe a suggestion for a future version of the transport is to have a getState() method with stopped, playing, stopping, etc. Then the GUI can decide how accurate it want to be…


#8