我正在制作一个合成器,将数据传输到aplay(我知道它并不理想),并且声音落后于改变声音的按键。我相信这是因为aplay持续8000赫兹,但c程序的速度不稳定。如何让for循环在C中达到8000 Hz?
答案 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,您可以将缓冲的音频数据发送到音频输出设备,而不会在内核缓冲区中累积过多的排队数据。