我曾假设这将输出一个固定的频率桶,我可以用它来做基音检测(比如aubio音调)。但这似乎并不是它所做的。我启动了语音应用程序,并使用它的频率显示播放各种音符通过我的麦克风。酒吧出现,全部在左手端,几乎没有区分高低音符。我提高了FFT的大小,只是为了看看这是否改变了什么,似乎没有。我找到了一个picthdetect js项目,并看到它使用了分析器,啊哈,这里我会找到正确的用法,但是代码的实质并不是使用频域输出,而是将时域输入到自己的算法中。因此,为了解决我的问题,我将使用那个库,但我仍然好奇频率域数据代表什么。
发布于 2021-12-27 19:00:37
它所做的正是你所认为的那样,但在该网站上的具体实现并不是很好的看到。
由于音程是线性映射的,而不是逻辑映射的,所以对于看到高低声道范围之间的音高变化,这些值的映射是不同的。如果你要以对数的方式映射每个频率箱,你会得到一个更有用的图表。现在,右手3/4的可视化显示从5000 of到20000hz (大致),其中包含非常少的数据在一个音频信号相比,0-5000 of。人类声音(和大多数乐器)的根频率主要在100-1000赫兹之间.在这上面有谐波,但是在降低振幅时,你得到的越高。
我修改了代码,告诉你每个桶的峰值频率和大小。使用这个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://stackoverflow.com/a/43369065/13801789
我相信我完全明白你的意思。问题不在于您的代码,而在于FFT底层的getByteFrequencyData。核心问题是,音乐音符是对数间距的,而FFT频率箱是线性间隔的。
音符是对数间隔的:连续的低音,例如A2(110 Hz)和A2#(116.5 Hz)的差值是6.5Hz,而在高倍频程的A3(220 Hz)和A3#(233.1 Hz)上的相同2个音符的差值为13.1Hz。
FFT的回收箱是线性间隔的:假设我们每秒处理44100个样本,FFT需要一个由1024个样本组成的窗口(一个波),首先用一个波乘以1024个样本(我们称其为wave1),因此这将是1024/44100=0.023 seconds的一个周期,即43.48 Hz,并将产生的振幅放在第一个垃圾桶中。然后用wave1 * 2的频率乘以它,即86.95 Hz,wave1 *3= 130.43 Hz。所以频率之间的差异是线性的,它总是相同的= 43.48,不像音符的变化。
这就是为什么关闭的低音符将捆绑在同一个垃圾箱,而关闭的高音是分开的。这就是FFT的频率分辨率问题。它可以通过获取大于1024个样本的窗口来解决,但这将是时间分辨率的权衡。
https://stackoverflow.com/questions/70372294
复制相似问题