我在玩pa_simple
api 来更好地理解数字音频。我编写了一些代码来将自定义生成的音频数据提供给 pulseaudio 服务器:
char buff[2];
while (playing) {
timePassed += periodMicros;
int val = userFunc(timePassed/1000000.0);
buff[0] = (val >> 0) & 0xff;
buff[1] = (val >> 1) & 0xff;
int error;
pa_simple_write(s, buff, 2, &error);
}
func
生成一个简单的正弦波,如下所示:uint16_t func(double time)
{
double op = sin(2*3.14*freq * time);
return op * 100;
}
它按预期产生了一个注释,但是由于不受限制的
while
占用了我机器上 50% 的 cpu在第一个代码块中循环。所以我试着像这样修复它:void _mainLoop() {
char buff[2*bufSize];
while (playing) {
for ( int i = 0; i < bufSize; i++ ) {
uint8_t word = userFunc(timePassed/1000000.0);
timePassed += periodMicros;
buff[i*2+0] = (word >> 0) & 0xff;
buff[i*2+1] = (word >> 1) & 0xff;
}
pa_simple_write(s, buff, 2*bufSize, &error);
this_thread::sleep_for(chrono::microseconds(bufSize*periodMicros));
}
}
它修复了 cpu 问题,但它生成的音频不再是完美的音符。它似乎有点高音,带有复古的感觉。
我想知道使用
pa_simple
的正确方法api没有我的代码吃掉cpu。请注意,即使我更改
bufSize
,第二个代码生成的声音也不会固定。至1
并删除 sleep
线。编辑:
这就是我初始化pulseaudio连接的方式:
pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE,
.channels = 1,
.rate = 44100
};
s = pa_simple_new(
NULL,
"SYNTH",
PA_STREAM_PLAYBACK,
NULL,
"Music",
&ss,
NULL,
NULL,
NULL
);
最佳答案
这是程序中的一个错误。我将 userFunc 的输出存储在 uint
中,因此负值被截断。将其更改为 int
并删除 sleep
调用解决了问题,因为 pa_simple
api 在 synchronous
.
关于audio - 有效地使用 pa_simple api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54633368/