【发布时间】:2019-04-25 05:19:29
【问题描述】:
我有一些音频文件,我想绘制音频文件的平均频谱,例如使用 PYTHON(librosa 库)的“大胆”软件。我可以看到他们正在绘制整个音频的平均频率与幅度图。
之后,我想应用 CNN 对两类样本进行分类。寻找建议。
谢谢。
【问题讨论】:
标签: python audio spectrum librosa
我有一些音频文件,我想绘制音频文件的平均频谱,例如使用 PYTHON(librosa 库)的“大胆”软件。我可以看到他们正在绘制整个音频的平均频率与幅度图。
之后,我想应用 CNN 对两类样本进行分类。寻找建议。
谢谢。
【问题讨论】:
标签: python audio spectrum librosa
通常您使用librosa.display.specshow 绘制随时间变化的频谱图,而不是整个文件。事实上,作为 CNN 的输入,您可能更愿意使用 librosa.stft 生成的频谱图或一些 Mel 频谱图,具体取决于您的分类目标。
例如,如果您想对流派进行分类,梅尔谱图可能是最合适的。如果您想找出键或和弦,则需要恒定 Q 谱图 (CQT) 等。
也就是说,这里有一些代码可以回答您的问题:
import librosa
import numpy as np
import matplotlib.pyplot as plt
file = YOUR_FILE
# load the file
y, sr = librosa.load(file, sr=44100)
# short time fourier transform
# (n_fft and hop length determine frequency/time resolution)
n_fft = 2048
S = librosa.stft(y, n_fft=n_fft, hop_length=n_fft//2)
# convert to db
# (for your CNN you might want to skip this and rather ensure zero mean and unit variance)
D = librosa.amplitude_to_db(np.abs(S), ref=np.max)
# average over file
D_AVG = np.mean(D, axis=1)
plt.bar(np.arange(D_AVG.shape[0]), D_AVG)
x_ticks_positions = [n for n in range(0, n_fft // 2, n_fft // 16)]
x_ticks_labels = [str(sr / 2048 * n) + 'Hz' for n in x_ticks_positions]
plt.xticks(x_ticks_positions, x_ticks_labels)
plt.xlabel('Frequency')
plt.ylabel('dB')
plt.show()
这导致了这个输出:
【讨论】:
1)与实际能量之间的关系。因此,如果您的样本在 -1 到 1 的范围内,则任何带有 |v|=1(v 是样本值)的样本都有 0 分贝。
import matplotlib.pyplot as plt
from scipy import signal
from scipy.io import wavfile
sample_rate, samples = wavfile.read('h1.wav')
samples=samples[:,0]
frequencies, times, spectrogram = signal.spectrogram(samples, sample_rate)
plt.imshow(spectrogram)
plt.pcolormesh(times, frequencies, spectrogram)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()
【讨论】: