问题标签 [pitch-detection]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
2344 浏览

signal-processing - 我对 FFT 和音高检测的理解在这里正确吗?

关于 Stackoverflow 以及 FFT 和音高检测的讨论已经不计其数了。

人们普遍认为,FFT 虽然速度很快,但对于许多应用程序来说并不是很准确,但通常不会解释原因。

我想解释一下我对为什么会这样的理解,希望比我聪明的人可以纠正我并填补我无法填补的空白。


FFT 将输入数据从时域转换到频域。

最初,我们从一系列数据开始,如果我们要在图表上绘制这些数据,则 Y 轴为给定时间点的声音幅度,X 轴为时间。这是在时域中。

FFT 将这些时间点的幅度值转换为不同频率的幅度。

FFT 输出的数据数量与输入的数据数量相同

如果我们输入 10 个时间点(10 个样本)的幅度,FFT 将输出这些样本中 10 个不同频率的幅度(在乘以虚数和实数的 sqrt 之后)。

哪些频率由以下因素决定:

我们将 FFT 的输出称为bin,每个 bin 的宽度通过将采样率除以 FFT 中的样本数来计算:

使用一些实际值,可能是:

bin_width = 44100 / 512 = 86.132

因此,我们的 FFT 有 512 个 bin(请记住,输入和输出的数据数量相同),每个 bin 的频率跨度为 86.132 Hz。

因此,对于给定的 bin,我们可以通过以下方式计算它所代表的频率:

使用上面的值,FFT 输出中的第 3 个 bin 将表示 258.398Hz 处的幅度:

这意味着在给定采样率和缓冲区大小的情况下,FFT 输出的准确度不能超过 ± 86.132Hz。

如果您需要更高的精度(例如 1Hz),则必须降低采样率或增加缓冲区大小(或两者兼而有之)。

随着缓冲区大小越来越接近采样率,延迟问题变得更加严重。

(每秒 44100 个样本,填充 44100 个样本缓冲区 = 每秒 1 个完整缓冲区)。

我意识到 FFT 不仅仅是计算基频(幅度最高的 bin),但到目前为止我对音高检测中的 FFT 的理解是否正确?

有什么方法可以在不牺牲延迟的情况下提高 FFT 的准确性?

0 投票
1 回答
168 浏览

c# - FFT 结果因我使用的计算机而异

我正在使用 Unity3D 进行音高检测项目。我对编码、统一以及我目前正在处理的几乎所有其他事情都很陌生!:-) 我遇到了这个网页,它帮助我开始并在我的项目中使用 FFT 代码:

http://www.kaappine.fi/tutorials/fundamental-frequencies-and-detecting-notes/

它大部分工作得非常好,但是检测到的频率似乎因我使用的计算机而异。我已经在各种台式机和笔记本电脑(pc 和 mac 的混合)上尝试过它,在某些计算机上它可以拾取正确的频率,但在其他计算机上它给了我大约 100 的频率。1.5个半音平坦。有趣的是,在我尝试过的 6 台计算机中,有 3 台是正确的,另外 3 台都是相同的 1.5 个半音。

这不能归结为麦克风,因为我在某些计算机上尝试了内置麦克风以及单独的麦克风,结果没有变化。

有谁知道这可能是什么原因以及我如何解决这个问题?我可以对代码进行任何调整吗?我正在从事的项目最终将作为 iPhone 应用程序分发,因此我需要它能够跨设备普遍工作。

顺便说一句,我目前只能使用 C# 编程语言。

非常感谢您的任何帮助和建议

最良好的祝愿

菲尔

0 投票
1 回答
567 浏览

matlab - Matlab - 更好地理解 FFT 并找到 Pitch

我知道有很多关于从 FFT 中找到音高的主题,并且我已经对从时域 -> 频域转换数据样本的整个过程有了不错的理解,但是仍然有一些领域(可能更高级) 我有点坚持。

我将逐步完成我当前的流程,希望有人可以帮助我了解我哪里出错了!

在开始之前,我在这里使用的示例是我在 Logic 中创建的 Wav 文件,它只是A 音阶中的钢琴预设,从Key A4开始,它只是向上移动音阶(A4、B4、C# 5, D5...) 每半个小节以120 bpm4 秒。如果有帮助,这是 wav 的链接:[a https://www.dropbox.com/s/zq1u9aylh5cwlmm/PianoA4_120.wav?dl=0]

第 1 步: 我解析出元数据和实际的样本数据。元数据: channels => 2, sample_rate => 44100, byte_rate => 176400, bits_per_sample => 16, data_chunk_size => 705600, data => ...

第 2 步: 由于有 2 个通道,我有一个左右数组,其中包含相应的样本数据,然后将它们中的每一个都通过 FFT。每个 FFT 的结果给出了给定频率的幅度和相位

第 3 步: 我现在需要找到每个 FFT 的最大值。我通过找到真实/复杂结果的所有大小然后找到最大值来做到这一点。我正在使用 Matlab 来帮助我,所以我运行max(abs(fft(data))). 我从找到每个 FFT 的最大值中得到的值是1275.61084.0

第 4 步: 从它们各自的 FFT 中找到这些最大值的索引,然后在映射的频域值的该索引处找到频率。这给了我1177.0 Hz1177.5 Hz

这就是我困惑的地方!我已经绘制了时域图,并通过查看 Period 并知道 A4 的周期是如何发现音高是A4,但我试图了解如何通过快速傅里叶变换。任何帮助/指向我的地方将不胜感激!

0 投票
1 回答
813 浏览

signal-processing - 如何执行倒谱以进行音高检测

好的,这里有很多问题,谷歌上有很多阅读材料,但我不知何故无法弄清楚。我想获得一段语音的基频。基本步骤应该是:

  • 取窗口信号的 FFT
  • 将 FFT 从直角坐标转换为极坐标(这样您就可以获得幅度)
  • 丢弃相位信息
  • 取平方,然后是大小的每个 bin 的自然对数
  • 再做一次 FFT(或者一些消息来源说取反 fft?)

以下是我在 AS3 中的实现方式:

现在,当我这样做并以 FFT 结束时,当我绘制它时,这些垃圾箱似乎是相反的顺序?我还看到二次谐波的峰值比基频的峰值更大。当我这样做并进行逆 FFT 时,我得到一个看起来反射在 N/2 附近的音频信号,并且峰值似乎再次反转。整个事情也相当嘈杂。我究竟做错了什么?

0 投票
1 回答
88 浏览

matlab - MATLAB 半对数缩放

我是 MATLAB 新手,正在开发一个基于麦克风输入处理人声频率的程序。我遇到的最大问题是音符(我在这个项目中处理的)频率呈指数增长,音阶中每个半音大约为 1.059463^x。
在我正在处理的程序中,我需要缩放图表以使检测到的频率接近它对应的音符编号,并缩放数据以便我可以根据音符和音分来处理音符编号因此频率图可以很容易地转换为 MIDI 数据。
我发现的唯一其他选择是为记录的频率创建一个频率库以进行比较,但这不必要地复杂且耗时。
所以,从本质上讲,我正在尝试缩放数据,以便频率为 110Hz 的 A2 对应于它的音符编号 45。有没有办法做到这一点?

0 投票
1 回答
137 浏览

ios - 如何将 LittleEndian Pitch Detector SDK 添加到 Xcode?

我正在尝试将LittleEndian Pitch Detector SDK添加到 Xcode 项目中。但是,将开发静态库和头文件添加到项目后出现错误。

我所做的步骤是,

  1. 下载 LittleEndian Pitch Detector SDK
  2. 将 libs/development 中可用的静态库拖放到项目中
  3. 将包含文件夹拖放到项目中
  4. 将构建设置中的用户标头搜索路径设置为包含文件夹
  5. 在#import "ViewController.h" 之后添加#import "pitchDetector.hpp"

在此处输入图像描述

之后我收到 3 个错误

在此处输入图像描述

0 投票
1 回答
349 浏览

javascript - 音高检测 - 数音符

我正在使用自相关算法对单声道声音(嗡嗡声、口哨声)执行音高检测,并且我得到的结果足以满足我正在尝试做的事情。但是,如果我用GF# D#的音符吹出一段旋律并记录结果,我会得到以下序列:

2x F#
3x G
14x F#
54x G
14x G#
2x D
52x F#
6x G
14x F#
3x G
2x G
28x D#
2x D
33x D#
4x D
16x D#
2x E
2x D
2x D#

我们可以看到正确的音符被识别并且它们是重复次数更多的音符,我怎么知道它是真正的音符还是只是一个过渡?是否有任何类型的过滤器可以应用于该数组并仅获取真正的音符 GF# 和 D#?

我正在使用这个 javascript 代码:https ://github.com/cwilso/pitchdetect ://github.com/cwilso/pitchdetect来执行音高检测,我想知道是否有一些后处理算法可以应用于我的结果来过滤音符,或者如果我有增加自相关算法的窗口。

在关于信号处理的那个线程(https://dsp.stackexchange.com/questions/16753/how-to-get-the-melody-from-a-signal)中,接受的答案提到了应用模式的简单后处理过滤我的音高结果序列。这个模式过滤器是什么?

0 投票
2 回答
1728 浏览

audio - 来自 .wav 文件的 TarsosDSP 音高检测。结果频率总是不到一半

我正在尝试使用 TarsosDSP 库从 .wav 文件中检测音高,并且频率的结果总是小于一半。

这是我的代码。

329.wav 文件是从http://onlinetonegenerator.com/网站以 329Hz 生成的。我不知道为什么结果音高总是 164.5Hz。我的代码有问题吗?

0 投票
1 回答
5598 浏览

python - Pydub 原始音频数据

我在 Python 3.4 中使用 Pydub 来尝试检测一些音频文件的音高。

我有一个有效的音高检测算法(McLeod Pitch Method),它对于实时应用程序非常强大(我什至用它制作了一个 Android 音高检测应用程序:https ://github.com/sevagh/Pitcha )。

我的问题是,当我将算法应用于 AudioSegment._data 时,我没有从算法中获得任何有意义的输出。

代码:

输出:

如果我从扬声器播放相同的 wav 文件,从麦克风录制它并将算法应用于原始麦克风捕获(有符号的 16 位小端 PCM,44100Hz,单声道),我会得到正确的音高。

AudioSegment._data 不会返回我所期望的吗?

0 投票
0 回答
81 浏览

android - 为什么 UI 直到 while 循环中断才显示?

此代码在 Android 应用程序中的语音检测中得到解答。它工作正常,但存在页面内容不会加载的问题,除非检测到任何声音,并且此代码段也会使应用程序崩溃几次