Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么最高的FFT峰值不是音乐音调的基频?_Python_Numpy_Audio_Fft_Audio Player - Fatal编程技术网

Python 为什么最高的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

目前,我正在努力获得这个闪烁小星星文件的音高。大体上 这些音符的频率是正确的,这是我们通过变量索引_max得到的。然而,对于C5的音符,它返回C6。C5的频率约为523,而C6的频率约为1046。FFT告诉我们频率比预期结果高一个倍频程。这种情况实际上发生在许多其他文件中,而且似乎注释越低,出现问题的可能性就越大。如果您能提供更好的提问方式或答案,我们将不胜感激

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算法的现有实现,例如。