为啥 ALSA 示例使用循环播放/捕获?

Posted

技术标签:

【中文标题】为啥 ALSA 示例使用循环播放/捕获?【英文标题】:Why do ALSA examples use a loop for playing/capturing?为什么 ALSA 示例使用循环播放/捕获? 【发布时间】:2017-06-15 07:52:30 【问题描述】:

我正在运行 Debian OS 的 ARM 电脑上使用“C”语言开发 linux alsa(高级 linux 声音架构)库。我正在尝试录制和播放声音。我的示例项目(一个用于录制,一个用于播放)在for 循环中完成工作。我的意思是,读取或写入缓冲区。这个 for 循环使用的目的是什么?

例如http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_min_8c-example.html,播放声音的官方示例。他们为声音数据创建一个缓冲区并随机填充。没关系,但他们将此缓冲区数组写入到循环 16 次的 for 循环内的声音设备缓冲区。并且循环内的循环计数器i 没有做任何事情:

for (i = 0; i < 16; i++) 
    frames = snd_pcm_writei(handle, buffer, sizeof(buffer));
    if (frames < 0)
        frames = snd_pcm_recover(handle, frames, 0);
    if (frames < 0) 
        printf("snd_pcm_writei failed: %s\n", snd_strerror(frames));
        break;
    
    if (frames > 0 && frames < (long)sizeof(buffer))
        printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), frames);

同recording sample:

for (i = 0; i < 10; ++i) 
   if ((err = snd_pcm_readi (capture_handle, buffer, buffer_frames)) != buffer_frames) 
      fprintf (stderr, "read from audio interface failed (%s)\n",
               err, snd_strerror (err));
      exit (1);
   
   fprintf(stdout, "read %d done\n", i);

【问题讨论】:

【参考方案1】:

播放示例将相同的缓冲区播放 16 次,因此您会得到 5 秒的噪音,而不是只有 1/3 秒。

同样,录制示例使用循环来显示如何录制更长的时间。 (在一个真实的程序中,你会对记录的样本做一些事情,而不是仅仅打印“read x done”。)

【讨论】:

这完全有道理。感谢您的编辑和回答。 获取程序运行时间 Run time ./pcm_min 将输出 ~5 秒。

以上是关于为啥 ALSA 示例使用循环播放/捕获?的主要内容,如果未能解决你的问题,请参考以下文章

如何配置不同的 ALSA 默认值以通过一台设备捕获并通过另一台设备播放?

为啥我的背景音乐没有循环播放?

cocostudio UI编辑器做循环动画为啥会有卡顿呢 是多播放了几帧么

为啥我的 Java 应用程序没有在每个循环中播放声音?

为啥我的 HTML5 音频不会循环播放?

使用 snd_pcm_writei() 播放音频时如何正确处理 ALSA 编程中的 xrun?