如何在实时流中从 16000Hz 样本制作 44100Hz 样本?

How can i make 16000Hz sample from 44100Hz sample in a real-time stream?

提问人:sanghyun park 提问时间:1/13/2021 更新时间:1/13/2021 访问量:737

问:

我在 Cpp 作品中使用 portaudio。 我的信号模型处理唯一的 16000Hz 音频输入和

当 First 发布我的作品时,我不需要使用 44100 采样率。它只是大约 48000Hz 的麦克风。 因此,我使用简单的抽取算法和线性插值对信号进行了重新采样,例如 48000 -> 16000 -> 48000。

但现在我想使用 44100 麦克风。在实时处理中,My 缓冲区为 256 Hz 的 16000 个点。因此,很难找到 44100 Hz 的输入缓冲区大小,并且很难从 44100 到 16000 进行下采样。

当我只使用抽取或平均滤波器(https://github.com/mattdiamond/Recorderjs/issues/186)时,输出语音高于输入,并且窗口化 sinc 函数插值会失真。

有没有办法让44100->16000下采样进行实时处理?请让我知道...

谢谢。

C++ C 信号处理 下采样 抽取

评论

0赞 the kamilz 1/14/2021
你为什么不使用 FFmpeg 的 libav?
0赞 sanghyun park 1/16/2021
实际上,我已经为我的工作找到了一个很好的库。但是他们的一些案例给了我同样的结果。所以我想知道理论上的东西和原始算法来纠正我的误解......

答:

0赞 Damien 1/13/2021 #1

过去,我不得不实现类似的问题,不是为了音频,而是为了模拟发射信号采样频率和接收机采样频率之间的异步。

我是这样进行的:

我们称输入信号的采样持续时间为: 和 我们称之为要生成的信号的采样持续时间。T1xT1=1/44100T2y

要计算信号的值,请选择两个输入值,并围绕要计算的值:y[n*T2]x[k*T1]x[(k+1)*T2]

k*T1 <= n*T2 < (k+1)*T1

然后从这两个值执行线性插值。必须重新计算每个样本的插值因子。

如果 和 ,则t = n*T2a = k*T1b = (k+1)*T2

p = (x[b] - x[a])/T1
y[t] = p*(t-a) + x[a]

频率为44.1kHz,并且应该具有相当好的相关性,并且线性插值可能足够好。x|a]x[a+T1]

在获得的质量不够好的情况下,您可以用固定的插值比对输入信号进行插值, 例如2,使用经典的定义良好的插值滤波器。

然后,您可以应用前面的过程,借助新的计算信号, 采样持续时间为 。T1/2

如果输入信号具有一些高频,则为了避免混叠,您需要在下采样之前对输入信号应用低噪声滤波器。请注意,即使在您之前的情况下,这也是必要的 48kHz -> 16kHz