我试图在一个小型 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/