我可以使用DirectSound轻松进行带过滤吗?如果没有,我该怎么办?

时间:2008-11-03 13:51:11

标签: audio filtering signal-processing waveform equalizer

我想知道这样的事情是否可行(并且相对容易),如果是这样,我该怎么做呢?

我想对我正在复制的波形文件进行波段滤波。类似于你在大多数类似Winamp的应用程序中看到的“均衡器” 然而,我的想法是不均衡声音,而是使用非常高的负dB值,几乎杀死我正在过滤的频段。

第一个问题是:DirectSound能给我一些允许我这样做的东西吗? 如果没有:你将如何实施这一点?
我知道(尽管我并不完全理解)你可以使用快速傅里叶变换将采样波形转换为频率分布。现在,在改变某些频率的振幅值后,我显然无法从该分布返回到原始波形:-)

我怎么能这样做?

另外,我可以精确制作这些滤镜吗? (如果我想过滤掉从2250Hz到2275Hz的所有内容,过滤器会出现什么错误?我可以获得的最大精度取决于什么?)

谢谢!

7 个答案:

答案 0 :(得分:3)

我不知道DirectSound是否提供此功能,我认为它不是因为DSP相当复杂并且因情况而异,因此经常变化很大。您想要做的通常在DSP(数字信号处理)中称为“过滤”。很多时候,这涉及使用FIR(有限脉冲响应)滤波器。有很多图书馆可以做你想要的。滤波器设计最棘手的方面是速度,精度和误差之间总是存在权衡。在您的示例中,您将能够在频率之间移除信号,但这也会影响周围的频率。它的影响量与处理时间和滤波器设计有关。

也许从这里开始(数学重):FIR Filter

然后google获取您自己的Windows / DirectSound特定FIR相关信息

答案 1 :(得分:2)

就我所知,DirectSound不像你在这里描述的那样进行带过滤。

带通滤波背后的一般思想是使用延迟线,它接收信号输出并将其反馈到输入流中,具有指定的延迟时间和衰减(或衰减)因子。仔细设计滤波器可以放大或衰减音频源中的特定频率范围。请注意,此技术不使用FFT,除非在测试滤镜效果时可能是诊断工具。 FFT技术可以更精确地限制或放大频率,但延迟线通常更快(并且更容易编码)。

为了处理WAV文件(与进行实时合成/过滤相反),在音频缓冲区上执行延迟线非常简单:

for (int i = 0; i < samples.Length - delay; i++)
{
    samples[i + delay] += samples[i] * decay;
}

在实践中它比这更复杂(例如,你必须处理潜在的溢出值,并且某些类型的延迟线必须反向运行,这在C风格编码中总是很痛苦),当然。

就过滤器的精确程度而言,这取决于它的设计好坏(这非常困难)。当您使用延迟线设计滤波器时,您实际上就像电子工程师在廉价微处理器之前几十年所做的那样(现在仍然如此)。

答案 2 :(得分:1)

DirectSound根本不提供信号处理设施。您可以使用各种技术来完成您想要的任务。可以使用FFT来做你想要的,但它可能不是最好或最简单的方法。您应该阅读音频DSP,特别是数字滤波(IIR,FIR)。有一本很好的免费在线DSP书,名为The Scientist and Engineer's Guide to Digital Signal Processing,绝对值得一看。亚马逊等也提供了许多其他优秀的DSP书籍。

答案 3 :(得分:1)

我不知道有任何图书馆会直接处理这类事情。

你可以通过傅里叶变换实现你想要的东西,FFTW之类的实现为你做计算工作,但在我的实验中使用非常讨厌,并且使用大量的内存,特别是如果你想要的话在一次点击中处理更长的音频位。

使用FFT应用eq的基本思想是:

  1. 获取音频。音频只是一个非常长的值(样本)数组,它是扬声器锥体随时间的位移。
  2. 对音频进行傅里叶变换(图书馆将执行此操作,但您必须将音频样本分流为正确的格式。这会将基于时间的样本转换为基于频率的表示 - 实际上这会将信号转换为显示信号中频率的分布。
  3. 将频率分布向上划分 - 将分布分成区域,每个区域将是一系列频率。
  4. 然后,您可以对频段进行调整 - 例如,您可以将一个区域归零以删除其中的所有痕迹。
  5. 采用更新频率分布的逆傅里叶变换。这将使表示返回到时域,重建原始信号的(近似值),但是进行了调整。
  6. 做这样的事情会让你准确地操纵音频中的频率,给你一种你想要的控制。但请注意,实施起来并不简单。

    我建议阅读这个主题。节拍检测与很多相关联(使用基本技术很多) - 尝试前几节here作为开始。

    希望有所帮助。

答案 4 :(得分:0)

DirectSound可能不会直接支持,但DirectShow应该。你可以使用那个API吗?

答案 5 :(得分:0)

我是第二个FIR滤波器的想法。要获得一个狭窄的缺口,你需要一个长滤波器内核。

基本上,您使用输入流对一组值(内核)进行卷积。每个输出样本都是前N个样本的总和乘以其在过滤器内核中的相应条目。

因此,您需要保留内核数组和相同数量样本的FIFO或循环缓冲区。

它们是网络上的FIR滤波器内核计算器,只是google“FIR滤波器计算器”。

答案 6 :(得分:0)

你应该可以做一个FFT,在频域(缩放频率区)中乱七八糟,然后做一个IFFT来恢复时域信号。否则,使用ScopeFIR或MATLAB设计滤波器非常简单。 ScopeFIR可以轻松设计带阻滤波器并为您提供系数,以便您可以对信号进行卷积。以下是ScopeFIR网站的教程:http://www.iowegian.com/fir/tutor/firintro.htm