如何用 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()
。
我试图在一个小的 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()
。