在scipy中重现sox频谱图

时间:2019-06-05 08:04:06

标签: python scipy sox spectrogram

例如,我有一个带语音的wav文件。

我可以使用sox创建很好的频谱图可视化:

wget https://google.github.io/tacotron/publications/tacotron2/demos/romance_gt.wav
sox romance_gt.wav -n spectrogram -o spectrogram.png

enter image description here

如何在python中重现该频谱图?

以下是使用scipy.signal.spectrogram

的示例
input_file = 'temp/romance_gt.wav'
fs, x = wavfile.read(input_file)
print('fs', fs)
print('x.shape', x.shape)

f, t, Sxx = signal.spectrogram(x, fs)
print('f.shape', f.shape)
print('t.shape', t.shape)
print('Sxx.shape', Sxx.shape)
plt.pcolormesh(t, f, Sxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.savefig('spectrogram_scipy.png')

但是看起来有些参数错误或某些东西坏了: enter image description here

1 个答案:

答案 0 :(得分:1)

请注意sox生成的图中色条的比例。单位为dBFS:相对于满刻度的分贝。要使用SciPy和Matplotlib重现该图,您需要缩放值以使最大值为1,然后取值的对数以转换为dB。

这是脚本的修改版本,其中包括对spectrogrampcolormesh的参数的各种调整,从而创建了类似于sox输出的图。

import numpy as np
from scipy.io import wavfile
from scipy import signal
import matplotlib.pyplot as plt

input_file = 'romance_gt.wav'
fs, x = wavfile.read(input_file)
print('fs', fs)
print('x.shape', x.shape)

nperseg = 1025
noverlap = nperseg - 1
f, t, Sxx = signal.spectrogram(x, fs,
                               nperseg=nperseg,
                               noverlap=noverlap,
                               window='hann')
print('f.shape', f.shape)
print('t.shape', t.shape)
print('Sxx.shape', Sxx.shape)
plt.pcolormesh(1000*t, f/1000, 10*np.log10(Sxx/Sxx.max()),
               vmin=-120, vmax=0, cmap='inferno')
plt.ylabel('Frequency [kHz]')
plt.xlabel('Time [ms]')
plt.colorbar()
plt.savefig('spectrogram_scipy.png')

我将Sxx除以Sxx.max()来说明dBFS的“满量程”方面。我调整了nperseg的{​​{1}}和noverlap参数,使其沿频率和时间轴的分辨率都高于默认值。我使用spectrogram来匹配sox的默认行为。 (您可以在http://sox.sourceforge.net/sox.html上找到Sox频谱图的详细信息。)我还使用了window='hann'中的vmin=-120vmax=0,以匹配sox频谱图使用的默认范围。 / p>

这是情节:

spectogram

“地狱”色彩图不像sox图中使用的那样强烈。有关替代色图,请参见"Choosing Colormaps in Matplotlib"上的教程。