如何从 python 中的 .wav 文件创建频谱图以解决音频分类问题

How can I create spectograms from .wav files in python for audio classification problem

我想使用频谱图对 CNN 的音频文件进行分类。问题是我的音频文件有不同的长度(在 2 秒到 17 秒之间)以及我生成频谱图的时间。它们都具有相同的大小,这意味着较短的音频文件的频谱会变宽。如何生成频谱图以使信号不被改变?

我尝试使用 matplotlib.pyplot 库创建频谱图,但所有图像都是 640 x 480。

这是我使用的代码

import matplotlib.pyplot as plt
from scipy.io import wavfile

samplingFrequency, signalData = wavfile.read('dia0_utt0.wav')

plt.title('Spectrogram')

plt.specgram(signalData,Fs=samplingFrequency,NFFT=512)

plt.xlabel('Time')

plt.ylabel('Frequency')

plt.savefig('fig11.png')

我不知道如何根据它们的长度获得可变维度的频谱图,或者如何让它们具有相同的维度但在没有信息的情况下填充其余部分直到最大长度。 例如,如果我有一个 3 秒的文件,最大长度为 17 秒,则生成 3 秒的频谱图,并在没有噪音的情况下填充频谱图的其余部分,使其达到 17 秒。

您可以使用 matplotlib.pyplot.xlimmatplotlib.pyplot.ylim 函数来设置两个轴的范围。

[已编辑] 在下面的示例中,我加载了从 this website:

下载的 Cantina 乐队歌曲的 3 秒长 wav 文件
import matplotlib.pyplot as plt
from scipy.io import wavfile

samplingFrequency, signalData = wavfile.read('C:/Users/Sheldon/Desktop/WAVEEXAMPLE/CantinaBand3.wav')


plt.title('Spectrogram')    
Pxx, freqs, bins, im = plt.specgram(signalData,Fs=samplingFrequency,NFFT=512)
plt.xlabel('Time')
plt.ylabel('Frequency')
plt.xlim(left=0,right=17)

plt.savefig('C:/Users/Sheldon/Desktop/WAVEEXAMPLE/fig11.png')

此脚本生成以下图像:

如果我没有指定 plt.xlim(left=0, right=17),输出数字将介于 0 到 3 秒之间:

您也可以使用 Python 的 Librosa。根据您的要求,这是完整的代码:

import librosa
import matplotlib.pyplot as plt

sig, fs = librosa.load(filename, sr=44100) #you can specify sample rate as well 
save_path = filename[:-4]+'.png'
plt.figure(figsize=(6.40,4.80), dpi=1000) #this makes the image resolution as 640x480
plt.axis('off') # no axis
plt.axes([0., 0., 1., 1.], frameon=False, xticks=[], yticks=[])
S = librosa.feature.melspectrogram(y=y, sr=44100, n_fft=4096, hop_length=2205, n_mels=512) #you can update it as per your requirement
librosa.display.specshow(librosa.power_to_db(S, ref=np.max),  cmap='jet')
plt.xlim(left=0,right=17)
plt.savefig(save_path, dpi=100, bbox_inches=None, pad_inches=0)
plt.close()