2

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

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

第一个问题是:DirectSound 是否给了我一些允许我这样做的东西?
如果不是:您将如何解决这个问题?
我知道(尽管我不太了解)您可以使用快速傅立叶变换将采样波形转换为频率分布。现在,在更改某些频率的幅度值后,我显然无法从该分布返回到原始波形:-)

我怎么能做这样的事情?

另外,我可以使这些过滤器精确到什么程度?(如果我想过滤掉从 2250Hz 到 2275Hz 的所有内容,那么过滤器会有什么误差?我可以获得的最大精度取决于什么?)

谢谢!

4

7 回答 7

3

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

也许从这里开始(数学重):FIR 滤波器

然后用谷歌搜索你自己的 Windows/DirectSound 特定的 FIR 相关信息

于 2008-11-03T14:01:25.157 回答
2

据我所知,DirectSound 不会像您在此处描述的那样进行频带过滤。

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

对于处理 WAV 文件(而不是进行实时合成/过滤),在音频缓冲区上执行延迟线非常简单:

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

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

至于过滤器的精确度,这仅取决于其设计的好坏(这非常困难)。当您使用延迟线设计滤波器时,您实际上所做的事情与电子工程师在廉价微处理器出现之前的几十年中所做的(并且现在仍在做)相同的事情。

于 2008-11-03T14:04:15.853 回答
1

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

于 2008-11-03T14:00:31.103 回答
1

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

您可以使用傅里叶变换实现您想要的,诸如FFTW之类的实现会为您完成计算工作,但根据我的经验,使用起来非常讨厌,并且使用大量内存,特别是如果您想处理更长的音频位一击。

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

  1. 获取您的音频。音频只是一个非常长的值(样本)数组,它是扬声器锥体的位移/随着时间的推移。
  2. 对音频进行傅里叶变换(库会这样做,但您必须将音频样本分流为正确的格式。这会将基于时间的样本转换为基于频率的表示 - 本质上这会将信号转换为显示分布信号中的频率。
  3. 向上划分频率分布 - 将分布划分为多个区域,每个区域将是一个频率范围。
  4. 然后,您可以对频段进行调整 - 对于您的示例,您可以将一个区域归零以删除它的所有痕迹。
  5. 取更新后的频率分布的傅里叶逆变换。这会将表示返回到时域,重建原始信号的(近似值),但要进行您所做的调整。

这样做可以让您准确地操纵音频中存在的频率,从而为您提供您想要的那种控制。但是请注意,实施起来并不简单。

我建议围绕这个主题阅读。节拍检测与其中很多密切相关(大量使用基本技术) - 尝试这里的前几个部分作为开​​始。

希望能有所帮助。

于 2008-11-04T12:20:32.257 回答
0

DirectSound 可能不直接支持这一点,但 DirectShow 应该。你可以改用那个 API 吗?

于 2008-11-14T19:44:31.383 回答
0

我支持 FIR 滤波器的想法。要获得窄缺口,您将需要一个长滤波器内核。

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

所以你需要保持一个内核数组和一个相同数量的样本的 FIFO 或循环缓冲区。

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

于 2009-01-04T21:12:23.307 回答
0

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

于 2009-01-28T05:57:00.773 回答