目前,我正在开发一款用于和弦识别的软件。上面有 FFT 和音高等级分析。我尝试使用 Takuya Fujishima 提出的音级配置文件,但结果不太准确。这可能是因为我误解了音级配置文件算法。
我不明白以下公式公式:
- 这里的和是什么?
- 是指 FFT 的样本大小( 4096、1024等)还是频谱的总 bin?
目前,我正在开发一款用于和弦识别的软件。上面有 FFT 和音高等级分析。我尝试使用 Takuya Fujishima 提出的音级配置文件,但结果不太准确。这可能是因为我误解了音级配置文件算法。
我不明白以下公式公式:
我知道这是一个旧线程,但供该领域的未来爱好者参考:
Fujishima 描述的完整 PCP 算法的方程如下:
OP 的困惑在于第二个等式:
是用于计算 FFT 的样本数,或通常称为 FFT 大小。请注意,更大的(更多样本,更长的时间)意味着 FFT 的分辨率更高。
是您正在处理的音频文件的采样频率。通常这是 44 100Hz。
是您尝试匹配的音级的参考频率。这通常是一组 12 个频率,代表古典键盘的 12 个半音的基本频率。供您参考,它们是 [16.35, 17.32, 18.35, 19.45, 20.60, 21.83, 23.12, 24.50, 25.96, 27.50, 29.14, 30.87],从 C0 到 B0。
的总称相当于将 FFT bin 转换为 bin 表示的实际频率。 这里只是 FFT 输出的 bin 计数。因此,对于 FFT 的每个 bin,可以使用此项计算关联频率。
因为每个八度音程实际上是前一个八度音程频率的两倍(如果 C0 为 16.35Hz,则 C1 = 2*C0 = 32.70 C2 = 2*C1)。因此,为了扭转这种情况,我们从上一步中获取计算频率的。
现在到第一个等式,注意所有的总和,使得。这意味着对于所有不同的音级 p (0-11),我们必须只使用 FFT 中的 bin,使得。为了找到这样的条件,我们在 FFT 中扫描所有频率的 fref,以便我们找到对各个音级贡献最大的频率。
请注意,方程不应为您提供负数。原因是 FFT 会产生正频率和负频率。但是对于所有真实信号(例如音频信号),负频率只是正频率的反映。您只需要处理正频率,它位于 FFT 输出的前半部分。或者您可以使用专门处理真实信号的 rFFT(例如 python - numpy 中的那个)算法,并且只会将正频率返回给您。
如果要实现此算法,您将执行以下操作:
选择一个音高等级配置文件(假设您想查看以查找属于音乐 C 的所有音符)
现在,根据第一个等式,您需要找到所有使得
您转到第二个等式,遍历 FFT 的所有箱(即 l)。您还将设置为您所追求的 PCP bin 的参考频率(在这种情况下,由于我们正在寻找 C,我们可以将设置为 16.35Hz)。
的所有值,使得。回到第一个方程,现在使用的子集列表,取那些特定 bin ( ) 处的 FFT 幅度,以找到音高等级 0 的最终总和。
是对应于第一个音级剖面(或 PCP[0])的参考频率,是声音中用于实现短时傅里叶变换的样本数。原始声音序列将被分割成重叠的片段,长度为.