重新采样声音样本,我使用什么过滤器?

时间:2010-12-08 23:53:11

标签: c audio filter signal-processing sampling

我正在尝试将信号(声音样本)从一个采样率重采样到更高的采样率。 不幸的是,它需要某种过滤器,因为有些“混叠”似乎会发生,而且我不熟悉过滤器。以下是我提出的建议:

int i, j, a, b, z;

a = 44100;
b = 8363;

// upsample by a
for(i = z = 0; i < samplen; i++)
    for(j = 0; j < a; j++)
        cbuf[z++] = sampdata[i];

// some filter goes here???

// downsample by b
for(j = i = 0; i < z; i += b)
    buf[j++] = cbuf[i];

新样本与原始样本非常相似,但它有某种噪音。 你能告诉我我需要添加哪些过滤器,最好是一些与该过滤器相关的代码吗?

原声:http://www.mediafire.com/?9gnga1in52d6t4x 重新采样的声音:http://www.mediafire.com/?x34h7ggk8n9k8z1

6 个答案:

答案 0 :(得分:11)

除非采样率(源和目标)都远高于数据中的最高频率,否则不要使用线性插值。这是一个非常差的低通滤波器。

你想要的是一个内插低通滤波器,其阻带开始低于你正在处理的两个采样率中较低者的一半。实现这一点的常用方法是使用IIR滤波器和使用多相FIR滤波器进行上采样/下采样。如果您不需要实时性能,并且不想上采样/下采样,则窗口Sinc内插器也适用于此。这是一个Windowed Sinc interpolating low-pass filter in Basic,转化为C应该是微不足道的。

如果您想使用IIR过滤,请参阅规范Cookbook for biquad IIR filters

如果您想要对音频重采样理论进行最佳解释,请参阅Stanford CCRMA's Resampling page

答案 1 :(得分:10)

您是否考虑过使用专门的库,例如libsamplerate

它非常便于携带,它由知道如何正确执行此类操作的人开发。即使您不直接使用它,您也可能会发现它实现的算法非常有趣。

答案 2 :(得分:2)

一些评论,虽然我只是猜测你的实际意图:

  • 您的采样率 44100次原始采样率。例如,如果您的输入为10kHz,则中间cbuf[]将为441MHz,这对于大多数音频分析来说有点高。假设您希望cbuf[]为44100Hz,则只需在44100/OrigSampleRate中的每个样本cbuf[]中创建sampdata[]个样本。
  • 您在上采样循环中递增z两次。这导致cbuf[]的所有奇数元素都具有其原始值。我相信这最终导致最终的buf[]具有无效的奇数元素,这些元素可能是噪声的来源。如果你没有创建至少两倍于所需元素数量的cbuf,那么cbuf中也可能存在缓冲区溢出。
  • 正如Steve所提到的,线性插值通常是最简单的,在上采样时产生良好的结果。如果需要,可以进行更复杂的上采样(多项式,样条等)。同样,在进行下采样时,您可能希望对样本进行平均而不是截断。

答案 3 :(得分:1)

我遇到过的最佳重新采样代码:http://shibatch.sourceforge.net/

拿源,并尝试从中学到一些东西。它处于恶劣的状态,但重新采样器的结果远远超过其他所有。

答案 4 :(得分:0)

直接使用FFMpeg和avcodec。这是一个很好的例子,展示了如何做到这一点:

http://tdistler.com/projects/audio-resampling-with-ffmpeg

答案 5 :(得分:0)

在重新采样到较低的采样率之前,必须通过低通滤波器将原始滤波器小于采样率的1/2,否则将引入alizing工件。对于频率超过采样率1/2的频率,频谱将折叠回自身。因此,如果你想从44100重新采样到11025,你必须在11025或5500赫兹的1/2处过滤44100低通,因为再现的忠诚度随着带宽的降低而降低,最好用幅度-10Db这样的最大幅度来实现。对于16位有符号,对于最大幅度,该值类似于10 ^( - 10/20)* 2 ^(16-1)或10362 +/-。确切的算法可以在网上找到,因为这些旧的和基本的想法应该没有知识产权。在没有舍入双精度浮点的情况下进行所有计算之后,将结果四舍五入到它们的正确整数值,并在时间刻度上插入一个集合截取另一个集合的精确位置。它需要相当的想象力和记忆力以及之前的经验,然后将您置于数学家物理程序员的领域。 :-O: - )