c - 如何用 ALSA 播放短音

标签 c linux audio alsa

我试图在一个小型 C 程序中通过 ALSA 生成可变长度的短音。我试过的几个例子在播放一秒钟的声音时效果很好,但比这更短的声音根本不会产生任何声音。

我正在用正弦波填充缓冲区,如下所示:

#define BUFFER_LEN 44100
int freq = 700;             //audio frequency
int fs = 44100;             //sampling frequency
float buffer [BUFFER_LEN];
for (k=0; k<BUFFER_LEN; k++) {
   buffer[k] = (sin(2*M_PI*freq/fs*k));                                 
}

设置pcm设备参数:

if ((err = snd_pcm_set_params(handle,
                              SND_PCM_FORMAT_FLOAT,
                              SND_PCM_ACCESS_RW_INTERLEAVED,
                              1,
                              44100,
                              1,
                              500000)) < 0) {
printf("Playback open error: %s\n", snd_strerror(err));
exit(EXIT_FAILURE);
}

回放:

frames = snd_pcm_writei(handle, buffer, BUFFER_LEN);

但是如果我想改变它来播放音调,比如四分之一秒(即将 BUFFER_LEN 更改为 11025),扬声器就再也没有声音了。

我试过将类型从浮点型更改为短型,将 PCM_FORMAT 设置为其他值,并尝试用不同的方式用正弦波填充缓冲区。

如果有的话,我听到扬声器中有一点“哔”的声音,但不是我所期望的。该程序不会出现段错误或崩溃,但我只是对如何让 ALSA 播放更短的样本感到困惑。

我不知道我是否需要使用一些确切的帧或缓冲区大小的倍数,但我非常愿意接受建议。

最佳答案

您的应用程序将样本写入缓冲区,硬件从缓冲区读取样本并播放它们是两个异步运行的不同进程。

如果缓冲区中没有足够的可用空间来容纳您尝试写入的样本数量,则 snd_pcm_writei() 将等待直到有足够的空间可用。但是当 snd_pcm_writei() 返回时,可能还没有播放完整的样本缓冲区。

要等到缓冲区为空,请使用 snd_pcm_drain()

关于c - 如何用 ALSA 播放短音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40399046/

相关文章:

C 使用 write(2) 检查 fd 是否打开

c - 指针值没有被加在一起。

linux - 尝试使用 'aocl install' 安装 de5a_net_i2 驱动程序但失败

linux - 是否可以从 linux 的用户空间执行 net_enable_timestamp()?

android - 从设备内存而不是 Assets 中读取音频文件

c - SDL:无法翻转多个表面

c - unsigned 和 signed int 指针之间的区别

php - 从 PHP 中执行我的程序?

javascript - 使用 HTML5 和 javascript 在后台顺序或随机播放多个音频文件

HTML5 Canvas 和音频跨浏览器兼容性