在Python中提取与FFT值相关的频率,需要使用科学计算的Python库Numpy。
步骤一:读取音频文件
首先需要使用Python中的库来读取音频文件。常用的库有scipy.io.wavefile
和pydub
。这里以pydub
库为例:
from pydub import AudioSegment
mp3_audio = AudioSegment.from_file("example.mp3", format="mp3")
samples = mp3_audio.get_array_of_samples()
这段代码可以读取名为example.mp3
的音频文件,并获得其所有样本值。
步骤二:对音频信号应用FFT
对于一个长度为N的音频信号,应用FFT以获得其频域范围内的信号。FFT函数在Numpy库中建议使用:
import numpy as np
fft_result = np.fft.fft(samples)
freqs = np.fft.fftfreq(samples.shape[-1])
此处的samples.shape[-1]
表示样本长度。fft_result
是一个频域范围内的复数数组,freqs
是对应的频率数组。
步骤三:获取FFT值相关的频率
FFT函数的输出结果中,其前一半数据代表正频率幅值,后一半数据代表负频率幅值。因此,需要将频域数据以某种方式归一化。以下代码展示如何使用Numpy库的peakutils模块,寻找给定FFT值的相关频率:
from peakutils import indexes
positive_freqs = freqs[:len(samples) // 2]
positive_amplitude = np.abs(fft_result[:len(samples) // 2])
# 寻找谷值作为分界点
valley = np.percentile(positive_amplitude, 70)
positive_amplitude[positive_amplitude < valley] = 0
# 获取峰值的索引
peak_idx = indexes(positive_amplitude, thres=0.5, min_dist=1)[0]
# 获取对应的频率
target_frequency = positive_freqs[peak_idx]
以上代码使用了peakutils模块的indexes
函数,返回的峰值索引赋值给peak_idx
。接下来的代码可以将峰值索引转换为对应的频率。
示例1:
下面展示一个简单的例子,展示如何提取针对一段信号的峰值频率:
import numpy as np
from pydub import AudioSegment
from peakutils import indexes
mp3_audio = AudioSegment.from_file("example.mp3", format="mp3")
samples = mp3_audio.get_array_of_samples()
fft_result = np.fft.fft(samples)
freqs = np.fft.fftfreq(samples.shape[-1])
positive_freqs = freqs[:len(samples) // 2]
positive_amplitude = np.abs(fft_result[:len(samples) // 2])
# 寻找谷值作为分界点
valley = np.percentile(positive_amplitude, 70)
positive_amplitude[positive_amplitude < valley] = 0
# 获取峰值的索引
peak_idx = indexes(positive_amplitude, thres=0.5, min_dist=1)[0]
# 获取对应的频率
target_frequency = positive_freqs[peak_idx]
print(target_frequency)
这个示例读取了名为example.mp3
的音频文件,使用了前面讲述的提取FFT值相关的频率方法来计算此音频文件的峰值频率,并将结果输出。
示例2:
以下示例展示了如何使用Matplotlib库将FFT结果和峰值频率可视化:
import numpy as np
from pydub import AudioSegment
import matplotlib.pyplot as plt
from peakutils import indexes
mp3_audio = AudioSegment.from_file("example.mp3", format="mp3")
samples = mp3_audio.get_array_of_samples()
fft_result = np.fft.fft(samples)
freqs = np.fft.fftfreq(samples.shape[-1])
positive_freqs = freqs[:len(samples) // 2]
positive_amplitude = np.abs(fft_result[:len(samples) // 2])
# 寻找谷值作为分界点
valley = np.percentile(positive_amplitude, 70)
positive_amplitude[positive_amplitude < valley] = 0
# 获取峰值的索引
peak_idx = indexes(positive_amplitude, thres=0.5, min_dist=1)[0]
# 获取对应的频率
target_frequency = positive_freqs[peak_idx]
# 绘制FFT结果
fig, ax = plt.subplots()
ax.plot(positive_freqs, np.abs(fft_result)[:len(samples) // 2])
ax.set_xlabel('Frequency')
ax.set_ylabel('Amplitude')
ax.vlines(target_frequency, ymin=0, ymax=10000000, colors='red')
plt.show()
这个示例读取了名为example.mp3
的音频文件,使用了前面讲述的提取FFT值相关的频率方法来计算此音频文件的峰值频率,并将结果可视化。