简体   繁体   English

我可以从内部暂停回调吗?

[英]Can I pause the callback from within itself?

I am using SDL audio to play sounds. 我正在使用SDL音频播放声音。

SDL_LockAudio tells this : SDL_LockAudio告诉我:

Do not call this from the callback function or you will cause deadlock. 不要从回调函数中调用它,否则会导致死锁。

But, SDL_PauseAudio doesn't say that, instead it tells : 但是, SDL_PauseAudio没有说,而是告诉:

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. PlayingQueue是一个提供对静态std::queue对象的访问的类。 Nothing fancy. 没有什么花哨。

This worked fine, until we decided to update the SDL and alsa libraries (now there is no turning back anymore). 这很好,直到我们决定更新SDL和alsa库(现在已经没有回头了)。 Since then I see this in my log : 从那时起,我在日志中看到了这一点:

ALSA lib pcm.c:7316:(snd_pcm_recover) underrun occurred ALSA lib pcm.c:7316:(snd_pcm_recover)欠载发生

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. 如果我假设SDL或alsa库中没有错误(这很可能是错误的,在搜索此消息后),我想应该可以更改我的代码来修复,或者至少避免欠载。

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 ); 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). 在回调中调用,然后SDL将切换到另一个回调(只是将零放入音频流)。 The callback will finish the execution after the function is called. 调用函数后,回调将完成执行。

Therefore, it is safe to call this function from the callback. 因此,从回调中调用此函数是安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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