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

发布于 2025-01-02 01:12:36 字数 1967 浏览 0 评论 0原文

我正在使用 SDL 音频 来播放声音。

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月静好 2025-01-09 01:12:36

最后我想通了。

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文