【问题标题】:alsa, snd_pcm_drain(handle), the stream isn't played to the endalsa,snd_pcm_drain(handle),流没有播放到最后
【发布时间】:2013-08-04 17:48:01
【问题描述】:

有人能解释一下如何安全地停止玩 ALSA 驱动程序吗? 我使用 snd_pcm_writei() 以“周期”缓冲区大小的块写入 ALSA 环形缓冲区,非常简单。写完后,我发现很难安全退出,因为需要在环形缓冲区(内部驱动程序)播放完所有样本后退出。

播放后,我发现流仍然处于 SND_PCM_STATE_RUNNING 状态(枚举 3),这看起来很正常,因为需要播放剩余的环形缓冲区。所以我尝试汇集状态

do
{
    err = snd_pcm_state(handle);
}while(err==3);

printf("\nDone.\n\n"); // never gets here

好的,有一个音频流引流功能:

snd_pcm_drain(handle);
    do
    {
        err = snd_pcm_state(handle);
    }while(err==3);

    printf("\nDone.\n\n");

这以代码 1 结束,这意味着 SND_PCM_STATE_SETUP 不应该停止或其他什么? 但无论如何,直到结束才播放流。唯一的测试方法是放一个

while(1);

这样可以确保播放整个音频。有什么想法吗?

非常感谢,

我发现了问题,但需要帮助解决:

函数 snd_pcm_writei() 需要一个 const void* 缓冲区,我使用一个动态分配的缓冲区:

snd_pcm_sframes_t snd_pcm_writei    (   snd_pcm_t *     pcm,
        const void *    buffer,
        snd_pcm_uframes_t   size 
    ) 

frames = snd_pcm_writei (handle, buff, period_size);

static short buf[240]; // this works

// this is not working
if ((buff = calloc(0,period_size)) == NULL) {
        printf("No enough memory for period buffer\n");
        exit(EXIT_FAILURE);
}   

知道如何将 snd_pcm_writei() 与动态分配的缓冲区一起使用吗?

【问题讨论】:

    标签: linux alsa


    【解决方案1】:

    要等待缓冲区播放完毕,必须在阻塞模式下调用snd_pcm_drain,即之前调用snd_pcm_nonblock(handle, 0)

    calloc 的一个参数设置为零将分配零字节。 要分配一个可以容纳一个周期的样本数据的缓冲区,请使用calloc(period_size, frame_size)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 2018-05-12
      • 2017-07-12
      • 1970-01-01
      • 2014-03-02
      • 1970-01-01
      相关资源
      最近更新 更多