4

我正在尝试从音频流中提取音高数据。据我所见,FFT 似乎是最好的算法。

与其直接钻研数学,有人可以帮我理解这个 FFT 算法的作用吗?

请不要说“FFT 从原始信号中提取频率数据”之类的明显内容。我需要更详细的信息。

我输入什么,输出什么?

一旦我清楚地理解了接口,这将有助于我理解实现。

我认为我需要传入一个音频缓冲区,我需要告诉它每次计算要使用多少字节(比如这个缓冲区中最近的 1024 个字节)。也许我需要指定我希望它检测到的音高范围。现在它要回传什么?一组频率区间?这些是什么?

(编辑:)我找到了一个可以使用的 C++ 算法(如果我只能理解的话)

Performous从麦克风中提取音高。代码也是开源的。下面是对算法功能的描述,来自编写它的人。

  • PCM 输入(带缓冲)
  • FFT(一次 1024 个样本,之后从缓冲区前面删除 200 个样本)
  • 重新分配方法(针对之前 200 个样本的 FFT)
  • 峰值过滤(这部分可以做得更好,甚至可以省略)
  • 将峰值组合成谐波组(我们称组合为音调)
  • 音调的时间过滤(更新之前检测到的音调集,而不是简单地使用新检测到的音调)
  • 选择最好的人声(频率限制,加权,也可以使用谐波阵列,但我不认为我们这样做)

但是有人可以帮我理解这是如何工作的吗?从 FFT 发送到重新分配方法的内容是什么?

4

3 回答 3

3

FFT 只是该过程中的一个组成部分,它可能不是音高检测的最佳方法。阅读音高检测并决定您首先要使用哪种算法(这将取决于您要测量的具体音高 - 语音、单一乐器、其他类型的声音等。在进入低音之前先做好准备级细节,例如 FFT(一些,但不是所有音高检测算法在内部使用 FFT)。

关于 SO 已经有很多类似的问题,例如Real-time pitch detection using FFTPitch detection using FFT for trumpet,维基百科上有很好的概述材料等 - 阅读这些然后决定你是否仍然想推出自己的 FFT -基于解决方案或可能使用适合您特定应用程序的现有库。

于 2010-11-01T10:21:55.750 回答
2

这里有一个选择元素。最简单的实现方法是输入 (2^n 个样本) 复数,然后输出 2^n 个复数,所以也许你应该从它开始。

在 DCT(离散余弦变换)的特殊情况下,通常输入的是 2^n 个样本(通常是浮点数),而输出是 2^n 个值,通常也是浮点数。DCT 是一种 FFT,但它只采用实数值,并根据余弦分析函数。

定义一个结构来处理复杂值是明智的(但通常被跳过)。传统上 FFT 是就地完成的,但如果你不这样做,它也能正常工作。

实例化一个包含 FFT 工作缓冲区的类(如果您不想就地进行 FFT)并将其重用于多个 FFT 会很有用。

于 2010-11-01T10:26:52.020 回答
1

输入 N 个 PCM 样本(纯实复数)。输出 N 个频域 bin(每个 bin 对应一个 1/N 的采样率切片)。每个 bin 都是一个复数。这些值通常应以极坐标格式(绝对值和参数)处理,而不是实部和虚部。绝对值告诉 bin 中心频率附近的声音量,而参数告诉相位(正弦波在哪个位置传播)。

大多数情况下,编码器只使用幅度(绝对值)并丢弃相位角(参数)。

于 2010-12-16T00:47:02.823 回答