如何以特定采样率写入音频数据?

时间:2016-07-01 17:39:47

标签: c frequency

我正在制作一个合成器,将数据传输到aplay(我知道它并不理想),并且声音落后于改变声音的按键。我相信这是因为aplay持续8000赫兹,但c程序的速度不稳定。如何让for循环在C中达到8000 Hz?

2 个答案:

答案 0 :(得分:1)

要以8000 Hz(或任何固定速率)生成音频样本,您不希望您的循环以“该速率”运行。这将涉及大量的开销(99.99%或更多),在生成下一个样本的时间之前无所事事,并且(特别是如果你睡觉而不是旋转)将是不可靠的,因为你的过程可能不会唤醒/获得预定及时处理一些样本。

相反,您只想以与消费者(aplay /音频设备)预期相匹配的总体速率生成样本。您可以计算您应该生成的总体当前样本编号,如下所示:

current_time + buffer_depth - start_time

然后,在生成该样本之后,睡眠一段时间与缓冲深度成比例,但是如果您的过程没有立即再次安排,那么您将不会遇到麻烦。您可以使用的缓冲区深度取决于您需要的延迟类型。如果您正在为实时/实时事件发出声音,则可能需要1/50秒(20毫秒)或更短的缓冲深度。如果没有,你可以愉快地使用巨大的缓冲区,如5-10秒。

答案 1 :(得分:0)

如果要将数据传输到{ "database": { "rules": "database.rules.json" }, "hosting": { "public": "public", "rewrites": [ { "source": "**", "destination": "/index.html" } ] }, "headers": [ { "source" : "bundle.js", "headers" : [ { "key" : "Access-Control-Allow-Origin", "value" : "*" } ] }] } ,则不会遇到采样率(例如8 kHz)的任何问题,因为当缓冲区为aplay时,内核将阻止您的程序充分。这将有效地将您的音频生成限制在8 kHz,而无需您的工作。

然而,这远非理想。只有管​​道的内核缓冲区已满,您的应用程序才会受到限制,Linux上管道缓冲区的默认大小为64 kB。对于8 kHz的立体声16位数据,这是两秒钟的音频数据,因此您可能希望音频距离用户输入至少两秒钟。这对于合成器应用来说是不可接受的。

唯一真正的解决方案是直接使用ALSA库(或一些替代声音API)。使用此API,您可以将缓冲的音频数据发送到音频输出设备,而不会在内核缓冲区中累积过多的排队数据。

有关提示,请参阅A Guide Through The Linux Sound API Jungle