如何用 ALSA 播放短音

how to play short tones with 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 设置为其他值,并尝试用不同的方式用正弦波填充缓冲区。

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

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

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

如果缓冲区中没有足够的空闲 space 用于您尝试写入的样本数量,则 snd_pcm_writei() 将等待直到有足够的 space 可用。但是当 snd_pcm_writei() returns 时,最多可能尚未播放完整缓冲区的样本。

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