频域分析的目的是啥

Posted

技术标签:

【中文标题】频域分析的目的是啥【英文标题】:what is the purpose of the frequency domain analysis频域分析的目的是什么 【发布时间】:2022-01-19 03:31:47 【问题描述】:

我曾假设这将输出一组可用于进行音高检测的频率桶(如音频音高)。但这似乎不是它的作用。我启动了语音 omatic 应用程序,并使用它的频率显示通过我的麦克风播放各种音符。小节出现,都在左手端,高低音符几乎没有区别。我增加了 FFT 大小只是为了看看这是否改变了任何东西,似乎没有。我找到了一个 picthdetect js 项目,看到它使用了分析器,啊哈,在这里我会找到正确的用法,但是代码的核心不使用频域输出,它将时域输入到它自己的算法中。所以为了解决我的问题,我将使用那个库,但我仍然很好奇频域数据代表什么

【问题讨论】:

【参考方案1】:

它完全按照您的想法做,但该网站上的具体实现并不适合看到这一点。

这些值的映射方式与查看高低音范围之间的音高变化所必需的不同,因为该范围是线性映射的,而不是对数映射的。如果您要以对数方式映射每个频率仓,您会得到一个更有用的图表。现在,可视化器的右手 3/4 显示从 5000hz 到 20000hz(大致),与 0-5000hz 相比,音频信号中包含的数据非常少。人声(和大多数乐器)的根频率大多在 100-1000hz 之间。上面还有谐波,但幅度越小,你得到的就越高。

我已经调整了代码以告诉您峰值频率和每个存储桶的大小。使用这个 app.js:https://puu.sh/Izcws/ded6aae55b.js - 您可以使用手机上的音调发生器来查看它的准确度。 https://puu.sh/Izcx3/d5a9d74764.png

代码的工作方式是计算每个桶的大小,如我在var bucketSize = 1 / (analyser.fftSize / analyser.context.sampleRate); 的回答中所述(并添加两个跨度以显示数据),然后在绘制每个条时计算哪个条最大,然后将每个桶的大小乘以最大的桶得到峰值频率(并将其写入el2)。您可以使用 fftSize 并了解为什么使用较小的值根本无法确定您是在播放 A2(110 Hz)还是 A2#(116.5 Hz)。

来自https://***.com/a/43369065/13801789

我相信我完全理解您的意思。问题不在于您的代码,而在于底层的 FFT getByteFrequencyData。核心问题是音乐音符是对数间隔,而FFT频率区间是线性间隔

音符以对数间隔:连续低音符之间的差异,例如 A2(110 Hz) 和 A2#(116.5 Hz) 是6.5 Hz,而在较高八度音阶 A3(220 Hz) 和 A3#(233.1 Hz) 上的相同 2 个音符之间的差异为 13.1 Hz。

FFT 箱是线性间隔的: 假设我们每秒处理 44100 个样本,FFT 采用 1024 个样本(一个波)的窗口,并首先将它与一个波相乘,只要1024 个样本(我们称之为 wave1),所以这将是一个周期 1024/44100=0.023 seconds,即 43.48 Hz,并将得到的幅度放在第一个 bin 中。然后将其与频率为 wave1 * 2 的波相乘,即86.95 Hz,然后是 wave1 * 3 = 130.43 Hz。所以频率之间的差异是线性的;它总是一样的 = 43.48,不像变化的音符差异。

这就是为什么关闭的低音会被捆绑在同一个箱子中,而关闭的高音会被分开。这就是 FFT 的频率分辨率的问题。它可以通过采用大于 1024 个样本的窗口来解决,但这会以时间分辨率为代价。

【讨论】:

这里是我提到的代码mdn.github.io/voice-change-o-matic,它是webaudio输入处理的主要示例(与音频生成相比)。我已将其更改为 2048 fft 大小,它没有任何区别,只是在左手端更细粒度的拥挤。我怎么知道什么频率在哪个桶里?我找不到使用此接口进行音高检测的示例,这是显而易见的用例(例如吉他调音器) 答案中写道,每个“桶”都是线性间隔的频率选择。请参阅以“FFT 箱是线性间隔的:”开头的段落。我已经调整了代码来告诉你峰值频率和每个桶的大小。使用这个 app.js:puu.sh/Izcws/ded6aae55b.js - 您可以使用手机上的音调发生器来查看它的准确度。 puu.sh/Izcx3/d5a9d74764.png 代码的工作方式是计算每个桶的大小,如我在var bucketSize = 1 / (analyser.fftSize / analyser.context.sampleRate); 的回答中所述(并添加两个跨度以显示数据),然后在绘制每个条时计算哪个条是最大的,然后将每个桶的大小乘以最大的桶得到峰值频率(并将其写入el2)。您可以使用 fftSize 并了解为什么使用较小的值根本无法确定您是在播放 A2(110 Hz)还是 A2#(116.5 Hz)。

以上是关于频域分析的目的是啥的主要内容,如果未能解决你的问题,请参考以下文章

实验三 基于MATLAB的离散时间信号的频域分析

中值滤波+Matlab仿真+频域响应分析

信号与系统实验 01 - | 连续系统频域分析的MATLAB实现

求助“利用MATLAB实现离散时间系统的时域和频域分析”的中译英翻译,数字信号处理,请高手帮帮忙

SQL Schema分析:AdventureWorks的ProductCategory中loop的目的是啥?

在matlab中,如何对一个信号的频域进行分析,并画出频域图?