Обратите внимание на масштаб цветной полосы на графике, сгенерированном sox.Единицы измерения: дБФС : децибелы относительно полной шкалы.Чтобы воспроизвести график с помощью SciPy и Matplotlib, вам нужно масштабировать значения таким образом, чтобы максимальное значение составляло 1, а затем взять логарифм значений для преобразования в дБ.
Вот измененная версия вашего сценарияэто включает в себя ряд настроек для аргументов spectrogram
и pcolormesh
, что создает график, похожий на вывод 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
и noverlap
для spectrogram
, чтобы получить разрешение, превышающее значения по умолчанию по оси частот и времени.Я использовал window='hann'
, чтобы соответствовать поведению sox по умолчанию.(Вы можете найти детали для спектрограммы sox в http://sox.sourceforge.net/sox.html.) Я также использовал vmin=-120
и vmax=0
в pcolormesh
, чтобы соответствовать диапазону по умолчанию, используемому спектрограммой sox.
Вотplot:
Цветовая карта "Inferno" не такая интенсивная, как у используемой на графике sox. См. учебное пособие по "Выбор цветовых карт в Matplotlib " для альтернативных цветовых карт.