如何在Python中提取与fft值相关的频率

  • Post category:Python

在Python中提取与FFT值相关的频率,需要使用科学计算的Python库Numpy。

步骤一:读取音频文件

首先需要使用Python中的库来读取音频文件。常用的库有scipy.io.wavefilepydub。这里以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值相关的频率方法来计算此音频文件的峰值频率,并将结果可视化。