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

Posted

技术标签:

【中文标题】我可以从内部暂停回调吗?【英文标题】:Can I pause the callback from within itself? 【发布时间】:2012-02-25 06:38:02 【问题描述】:

我正在使用SDL audio 播放声音。

SDL_LockAudio 告诉我们:

不要从回调函数中调用它,否则会导致死锁。

但是,SDL_PauseAudio 没有这么说,而是告诉:

此函数暂停和取消暂停音频回调处理

我的混音器回调如下所示:

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 是一个提供对静态std::queue 对象的访问的类。没什么特别的。

这很好,直到我们决定更新 SDL 和 alsa 库(现在没有回头路了)。从那时起,我在我的日志中看到了这一点:

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

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

所以,问题是:我可以暂停回调本身吗?它会导致我看到的欠载吗?

【问题讨论】:

【参考方案1】:

我终于想通了。

当在回调中调用SDL_PauseAudio( 1 ); 时,SDL 将切换到另一个回调(它只是将零放入音频流中)。回调将在函数被调用后完成。

因此,从回调中调用该函数是安全的。

【讨论】:

以上是关于我可以从内部暂停回调吗?的主要内容,如果未能解决你的问题,请参考以下文章

单独线程上的可暂停计时器

我可以从另一个帐户免费发布付费暂停的 Android 应用程序吗?

如何让C#程序在执行中暂停一段时间

使用 MPRemoteCommandCenter 时未调用播放/暂停回调

如何在 MutationObserver 的回调中“暂停”观察

如何在调整窗口大小时暂停 GtkDrawingArea 绘制回调?