我试图在一个小的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),没有什么从演讲者出来了。
我尝试过将types从浮动变为短裤,将PCM_FORMAT
设置为其他值并尝试用正弦波填充缓冲区的不同方法。
如果有的话,我在扬声器里听到一点点'bip'的声音,但是不是我所期望的。 该程序不segregs或崩溃,但我只是困惑如何使ALSA发挥更短的样本。
我不知道是否需要使用一些确切的帧或缓冲区大小倍数,但我很乐意提供build议。
您的应用程序将样本写入缓冲区,硬件从缓冲区中读取样本并播放它们是异步运行的两个不同的进程。
如果缓冲区中没有足够的可用空间用于写入数量的样本,则snd_pcm_writei()
将等待足够的空间可用。 但是,当snd_pcm_writei()
返回时,可能还没有播放完整的样本缓冲区。
要等到缓冲区为空,请使用snd_pcm_drain()
。