绘制1/3倍频程频谱图

对wav格式文件,绘制1/3倍频程频谱图,频率范围为20-10000Hz。

from scipy.io import wavfile
from scipy.fft import fft
import numpy as np
import matplotlib.pyplot as plt
import librosa
#from scipy.signal import hamming


def one_third_octave(audio_path):
    
    sample_rate, audio_data = wavfile.read(audio_path)
    
    # 确保音频数据是一维的(单声道)
    if len(audio_data.shape) == 2:
        audio_data = audio_data.mean(axis=1)

   # 计算FFT
    n = len(audio_data) # 数据长度为240000
    fft_audio = fft(audio_data, n) # 240000行×1列 复数
    fft_audio = fft_audio[range(n//2)]  # 只取一半,120000行×1列 复数
    
    # 计算功率谱
    power_spectrum = (2.0/n) * np.abs(fft_audio)**2 

    # 计算频率数组
    freqs = float(sample_rate) / n * np.arange(n//2) # 120000行× 1列

    # 计算1/3倍频程带的频率

    fmin = 20  # 最小频率
    fmax = sample_rate / 2  # 最大频率
    n_bins = 29  # 1/3倍频程带的数量
    bins_per_octave = 3  # 每个倍频程的1/3倍频程带数量
    n_octaves = int(np.ceil(np.log2(fmax / fmin)*3))  # 倍频程的数量

    # 计算1/3倍频程带的中心频率
    freqs13 = librosa.cqt_frequencies(n_bins=n_bins, fmin=fmin, bins_per_octave=bins_per_octave)

    # 计算1/3倍频程的边界

    one_third_octaves = freqs13
    # 计算每个1/3倍频程的功率值
    one_third_octave_power = np.zeros(len(one_third_octaves) - 1)
    for i in range(len(one_third_octaves) - 1):
        mask = (freqs >= one_third_octaves[i]) & (freqs <= one_third_octaves[i+1])
        one_third_octave_power[i] = np.trapz(power_spectrum[mask], freqs[mask])

    # 绘制1/3倍频程频谱图
    octaves_13 = np.round(one_third_octaves[:-1],decimals=0) # 取1/3倍频第0-倒数第1个数(0-25),并对元素四舍五入,保留0位小数
    octaves_13 = octaves_13.astype(int) # 转化为整型,去掉小数点
    str_octaves_13 = [str(item) for item in octaves_13] # 将数组转化为字符串列表

    # 绘图
    plt.figure(figsize=(20, 6))
    plt.bar(str_octaves_13, 10 * np.log10(one_third_octave_power),width=0.6)
    plt.title('1/3 Octave Frequency Spectrum')
    plt.xlabel('Frequency (Hz)')
    plt.ylabel('Power (dB)') #plt.xscale('log') #设置当前轴(通常是x轴)的缩放类型。
    #plt.grid(True, which="both", ls="--")
    plt.show()

# 加载音频文件
audio_path = '2023-03-20-10-34-59.wav'
one_third_octave(audio_path)

结果展示:
image

备注:librosa.cqt_frequencies生成的1/3倍频程频率结果有偏差,暂未找到原因,欢迎留言指教!

posted @ 2024-12-16 10:47  塞外声  阅读(502)  评论(0)    收藏  举报