Python 为什么最高的FFT峰值不是音乐音调的基频?
目前,我正在努力获得这个闪烁小星星文件的音高。大体上 这些音符的频率是正确的,这是我们通过变量索引_max得到的。然而,对于C5的音符,它返回C6。C5的频率约为523,而C6的频率约为1046。FFT告诉我们频率比预期结果高一个倍频程。这种情况实际上发生在许多其他文件中,而且似乎注释越低,出现问题的可能性就越大。如果您能提供更好的提问方式或答案,我们将不胜感激Python 为什么最高的FFT峰值不是音乐音调的基频?,python,numpy,audio,fft,audio-player,Python,Numpy,Audio,Fft,Audio Player,目前,我正在努力获得这个闪烁小星星文件的音高。大体上 这些音符的频率是正确的,这是我们通过变量索引_max得到的。然而,对于C5的音符,它返回C6。C5的频率约为523,而C6的频率约为1046。FFT告诉我们频率比预期结果高一个倍频程。这种情况实际上发生在许多其他文件中,而且似乎注释越低,出现问题的可能性就越大。如果您能提供更好的提问方式或答案,我们将不胜感激 import scipy.io.wavfile as wave import numpy as np from frequencyUt
import scipy.io.wavfile as wave
import numpy as np
from frequencyUtil import *
from scipy.fft import fft, ifft
def read_data(scale):
infile = "twinkle.wav"
rate, data = wave.read(infile)
sample_rate = int(rate/scale)
time_frames = [data[i:i + sample_rate] for i in range(0, len(data), sample_rate)]
notes = []
for x in range(len(time_frames)): # for each section, get the FFT
if(type(data[0]) is np.int16): # If not dual channel process like normal
dataZero = np.array(time_frames[x])
else: # if is dual channel get first ele of every list
data = np.array(time_frames[x]) # convert to np array
dataZero = [row[0] for row in data]
frequencies = fft(dataZero) # get the FFT of the wav file
inverse = ifft(np.real(frequencies))
index_max = np.argmax(np.abs(frequencies[0:8800//scale])) # get the index of the max number within music range
#print(abs(frequencies[index_max]))
# filters out the amplitudes that are lower than this value found through testing
# should eventually understand the scale of the fft frequencies
if(abs(frequencies[index_max]) < 4000000/scale):
continue
index_max = index_max*scale
print(index_max)
notes.append(index_max)
return notes```
将scipy.io.wav文件导入为wave
将numpy作为np导入
从frequencyUtil导入*
从scipy.fft导入fft,ifft
def读取数据(刻度):
infle=“闪烁.wav”
速率,数据=波形读取(填充)
样本率=整数(率/标度)
时间帧=[范围内i的数据[i:i+采样率](0,len(数据),采样率)]
注释=[]
对于范围内的x(len(时间帧)):#对于每个部分,获取FFT
if(type(data[0])是np.int16:#if不是正常的双通道过程
dataZero=np.array(时间帧[x])
否则:#如果是双通道,则获取每个列表的第一个元素
数据=np.数组(时间帧[x])#转换为np数组
dataZero=[数据中的行的行[0]
频率=fft(数据零点)#获取wav文件的fft
逆=ifft(np.实(频率))
index_max=np.argmax(np.abs(频率[0:8800//scale])#获取音乐范围内最大数字的索引
#打印(abs(频率[索引最大值])
#过滤掉低于通过测试发现的该值的振幅
#最终应了解fft频率的比例
如果(abs(频率[指数最大值])小于4000000/刻度):
持续
索引最大值=索引最大值*刻度
打印(索引最大值)
注释.追加(索引_max)
回执```
许多音调的声音(尤其是低音)在频谱中具有比基音强的泛音或谐波。这些泛音使乐器或声音听起来比正弦波发生器更有趣。但是由于音高是一种心理声学现象,人类的大脑会做出必要的修正来感知音高
因此,FFT幅度向量中最强的频谱峰值通常不在基音频率,因为音调具有非平凡频谱
关于基音检测与估计问题,已有大量的学术论文和文章。许多仪器使用倒谱/倒谱、自相关、机器学习等方法。据我所知,许多仪器在某些谐波中的功率比基音中的功率大。找到音调并不像在FFT中找到最高峰值那么简单。这里有很多问题,这将帮助您。例如,这里的第一个答案是非常有根据的:不像Chris已经指出的那样,您需要做更多的工作,而不是使用原始FFT。一个简单的方法是使用YIN或pYIN算法的现有实现,例如。