0

有人可以解释如何安全地停止玩 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() 与动态分配的缓冲区一起使用的任何想法?

4

1 回答 1

0

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

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

于 2013-08-09T16:32:25.623 回答