【问题标题】:Using a low pass filter on audio在音频上使用低通滤波器
【发布时间】:2014-03-14 13:16:21
【问题描述】:

我对 DSP 和滤波领域非常陌生。就像我一周前开始的那样。无论如何,我一直在寻找对我得到的一些数据使用过滤器(低通、高通、陷波等)的方法。数据来自一个双精度数组,我可以在这个数组中获得超过 100 万个点。我试图在给定截止频率的情况下过滤掉声音,但无法让任何算法起作用。我一直在互联网上上下移动并尝试了一堆不同的库和方法,但我无法得到任何结果。我偏爱 NAudio 库,因为它似乎拥有我需要的一切(FFT 和 BiQuadFilter 类过滤)。我很确定我的问题是我极度缺乏获得所需输出的知识和数学。从我读过的内容来看,我认为这个过程应该是这样的:

  1. 将数据插入 FFT 以将数据放入频域
  2. 将结果数据传递到过滤器(低、高、缺口)
  3. 从第 2 步的结果中进行 IFFT 以返回时域
  4. 播放声音

这是过滤音频的正确方法吗?我可以将整个阵列推入 FFT 还是必须将其分成更小的块?我如何处理我在 FFT 结果中得到的复数(即只使用实部并丢弃虚部,或者使用幅度和相位)?我真的不知道什么是“正确的方法”。

编辑

我终于让它工作了!这是我所做的:

        byte[] data = doubleArray.SelectMany(value => BitConverter.GetBytes(value)).ToArray();
        wms = new WaveMemoryStream(data, sampleRate, (ushort)audioBitsPerSample, (ushort)channels);
        WaveFileReader wfr = new WaveFileReader(wms);
        SampleChannel sample = new SampleChannel(wfr, false);
        LowPassSampleProvider sampleProvider = new LowPassSampleProvider(sample);
        WaveOutEvent player = new WaveOutEvent();
        player.Init(sampleProvider);
        player.Play();

doubleArray 是我的加速度计数据数组,目前包含 100 万个点,每个点在 1.84 左右...

WaveMemoryStream 是我找到的一个类on another post here

LowPassSampleProvider 是我创建的一个类,它实现 ISampleProvider 并将样本传递给 BiQuadFilter.LowPassFilter 函数。

【问题讨论】:

标签: c# audio fft naudio lowpass-filter


【解决方案1】:

NAudio 中的BiQuadFilter 在时域中运行。您不需要对它使用 FFT。将每个样本传递给Transform 方法以获取输出样本。如果您有立体声音频,请使用两个过滤器,一个用于左侧,一个用于右侧。

我通常会创建一个ISampleProvider 实现,它在 Read 方法中从源 ISampleProvider(例如 AudioFileReader)读取,并将样本通过过滤器。

【讨论】:

  • 这个答案是正确的。如果您发现使用时域而不是频域来改变信号频率是违反直觉的,我确实写了一篇关于此的博客文章:blog.bjornroche.com/2012/08/why-eq-is-done-in-time-domain.html
  • 感谢您的提示,但我似乎仍然无法正常工作。你能看看我在 OP 上所做的编辑,看看我做错了什么吗?
  • 那里正在进行大量的转换。您的信号链应该是 A->B->C,其中 A 是一个 SampleProvider,它返回您要在其 Read 方法中处理的样本,B 是一个样本提供者,它通过 Read 上的样本传递音频,C 是您的接收器(WaveOutEvent 或 WaveFileWriter)。
【解决方案2】:

通常您会通过时域过滤器运行时域数据。另一种等效的方法是取数据的 FFT 和滤波器的 FFT,在频域相乘,然后取逆 FFT。对于小型滤波器,时域方法通常更快。您通常会在数据帧上执行此操作,例如通过过滤器的 8192 个样本。然后重复后续帧。如果不查看您的代码,我将无法提供更多帮助。另外,看看这些examples 使用英特尔的 IPP。时域和频域的实现应该有助于您前进。

【讨论】:

  • 并非所有时域滤波器都可以正确理解为卷积。例如,IIR 滤波器(在音频中最常见)虽然可以用长卷积来近似,但并不等同于卷积。
  • @AndrewFernandes 这些英特尔 IPP 示例不再可用。您能否提供另一个来源或将它们上传到某个地方?这真的很有帮助。
  • @Lati 示例可用,您只需谷歌搜索英特尔 IPP 示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
相关资源
最近更新 更多