简体   繁体   中英

Can I pause the callback from within itself?

I am using SDL audio to play sounds.

SDL_LockAudio tells this :

Do not call this from the callback function or you will cause deadlock.

But, SDL_PauseAudio doesn't say that, instead it tells :

This function pauses and unpauses the audio callback processing

My mixer callback looks like this :

void AudioPlaybackCallback( void *, core::bty::UInt8 *stream, int len )
{
         // number of bytes left to play in the current sample
        const int thisSampleLeft = currentSample.dataLength - currentSample.dataPos;
        // number of bytes that will be sent to the audio stream
        const int amountToPlay = std::min( thisSampleLeft, len );

        if ( amountToPlay > 0 )
        {
            SDL_MixAudio( stream,
                          currentSample.data + currentSample.dataPos,
                          amountToPlay,
                          currentSample.volume );

            // update the current sample
            currentSample.dataPos += amountToPlay;
        }
        else
        {
            if ( PlayingQueue::QueueHasElements() )
            {
                // update the current sample
                currentSample = PlayingQueue::QueuePop();
            }
            else
            {
                // since the current sample finished, and there are no more samples to
                // play, pause the playback
                SDL_PauseAudio( 1 );
            }
        }
}

PlayingQueue is a class which provides access to a static std::queue object. Nothing fancy.

This worked fine, until we decided to update the SDL and alsa libraries (now there is no turning back anymore). Since then I see this in my log :

ALSA lib pcm.c:7316:(snd_pcm_recover) underrun occurred

If I assume there are no bugs in SDL or alsa library (this is most likely wrong, after googling this message), I guess it should be possible to change my code to fix, or at least avoid the underrun.

So, the question is : can I pause the callback from itself? Can it cause underruns I am seeing?

Finally I figured out.

When the SDL_PauseAudio( 1 ); is called in the callback, then the SDL is going to switch to another callback (which just put zeros into the audio stream). The callback will finish the execution after the function is called.

Therefore, it is safe to call this function from the callback.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM