【问题标题】:Transforming Audio Samples From Time Domain to Frequency Domain将音频样本从时域转换为频域
【发布时间】:2012-08-15 07:25:16
【问题描述】:

作为一名软件工程师,我在处理信号处理问题时遇到了一些困难。我在这方面没有太多经验。

我尝试做的是以 44100 采样率和固定大小的窗口对环境声音进行采样,以测试是否存在特定频率 (20KHz) 并高于阈值。

这是我根据How to extract frequency information from samples from PortAudio using FFTW in C中的完美答案所做的

从音频端口以 44100 采样率收集 102400 个样本(2320 毫秒)。样本值介于 0.0 和 1.0 之间

int samplingRate = 44100;
int numberOfSamples = 102400;
float samples[numberOfSamples] = ListenMic_Function(numberOfSamples,samplingRate);

窗口大小或 FFT 大小为 1024 个样本(23.2 毫秒)

int N = 1024;

窗口数为 100

int noOfWindows = numberOfSamples / N;

将样本拆分为 noOfWindows (100) 个窗口,每个窗口的大小为 N (1024) 个样本

float windowSamplesIn[noOfWindows][N];
for i:= 0 to noOfWindows -1 
    windowSamplesIn[i] = subarray(samples,i*N,(i+1)*N);
endfor

在每个窗口上应用汉宁窗函数

float windowSamplesOut[noOfWindows][N];
for i:= 0 to noOfWindows -1 
    windowSamplesOut[i] = HanningWindow_Function(windowSamplesIn[i]);
endfor

在每个窗口上应用 FFT(在 FFT 函数内完成实数到复数的转换)

float frequencyData[noOfWindows][samplingRate/2]; 
for i:= 0 to noOfWindows -1 
    frequencyData[i] = RealToComplex_FFT_Function(windowSamplesOut[i], samplingRate);
endfor

最后一步,我使用了这个链接中实现的FFT函数:http://www.codeproject.com/Articles/9388/How-to-implement-the-FFT-algorithm;因为我无法从头开始实现 FFT 函数。

我不能确定的是,在将 N (1024) 个样本作为输入提供给 FFT 函数时,samplingRate/2 (22050) 分贝值作为输出返回。它是 FFT 函数的作用吗?

我知道由于奈奎斯特频率,我最多可以检测到一半的采样率频率。但是是否可以获得每个频率高达 samplingRate/2 (22050) Hz 的分贝值?

谢谢, 瓦希特

【问题讨论】:

    标签: audio signal-processing fft fftw audio-processing


    【解决方案1】:

    How do I obtain the frequencies of each value in an FFT?

    从 1024 个样本输入,您可以获得 512 个有意义的频率水平。

    所以,是的,在您的窗口内,您将恢复奈奎斯特频率的水平。

    您将看到的最低频率级别是 DC (0 Hz),下一个是 SampleRate/1024,或大约 44 Hz,下一个是 2 * SampleRate/1024,依此类推,向上至 512 * 采样率 / 1024 Hz。

    【讨论】:

    • 从另一个角度来看,您可能会发现这篇文章很有用:blog.bjornroche.com/2012/07/…
    • 关于为什么上述博文错误地将频率与音高混淆的原因,这里是另一篇博文:musingpaw.com/2012/04/…
    • 我同意大卫的观点。作为结论,我认为 FFT 实现here 在计算基频的函数末尾存在一些错误。朋友们,你们怎么看?
    • @Vahocan:FFT 不计算基频。 FFT 为您提供所有频率,其中基频可能不是最大幅度的,也可能不在任何 bin 中心。
    【解决方案2】:

    由于您的 FFT 中只使用了一个波段,因此我预计您的结果会因边带效应而受损,即使使用适当的窗口也是如此。它可能有效,但您也可能会在某些输入频率下得到误报。此外,您的信号接近您的 niquist,因此您假设到 FFT 的信号路径相当好。我认为这不是正确的方法。

    我认为这种信号检测的更好方法是使用高阶滤波器(根据您的要求,我猜是四阶或五阶,实际上并没有那么高)。如果您不知道如何设计高阶滤波器,您可以串联使用两个或三个二阶滤波器。此处描述了设计二阶滤波器,有时称为“双二阶”:

    http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt

    虽然非常简洁并且带有一些先验知识的假设。我会使用转角频率尽可能低的高通 (HP) 滤波器,可能在 18 到 20 kHz 之间。请记住,拐角频率存在一些衰减,因此在多次应用滤波器后,您会丢失一点信号。

    过滤音频后,取 RMS 或平均幅度(即绝对值的平均值),以找到一段时间内的平均电平。

    与您现在所做的相比,此技术有几个优点,包括更好的延迟(您可以在几个样本内开始检测)、更好的可靠性(您不会因为杂散频率的响亮信号而得到误报)、等等。

    这篇文章可能相关:http://blog.bjornroche.com/2012/08/why-eq-is-done-in-time-domain.html

    【讨论】:

    • 起初,我尝试在时域解决我的问题,但我完全失败了。我所做的只是在下面。 - 收集样本 - 对所有发布的样本应用 HPF here 在对样本应用 HPF 之前,我应该应用窗口函数吗?真的,我离信号处理还有很长的路要走。
    • 无需开窗——只需逐个采样。您链接到的过滤器是一阶的,几乎没有足够的选择性。
    • 那么您能指导我了解高阶 HPC 实施吗?即你的博客。谢谢。
    • 我所知道的最好的事情是 Audio-EQ-Cookbook。这些是二阶。连续做两三个(或更多!)。
    • 迟到总比不到好。这是过滤器的操作方法。它是为音频 EQing 编写的,但原理是一样的:blog.bjornroche.com/2012/08/basic-audio-eqs.html
    猜你喜欢
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多