Time steps difference in spectrogram

459 views Asked by At

I have an audio file of 10 seconds in length. If I generate the spectrogram using matplotlib, then I get a different number of timesteps as compared to the spectrogram generated by librosa.

Here is the code:

fs = 8000
nfft = 200
noverlap = 120
hop_length = 120

audio = librosa.core.load(path, sr=fs)

# Spectogram generated using matplotlib
spec, freqs, bins, _ = plt.specgram(audio, nfft, fs, noverlap = noverlap)

print(spec.shape) # (101, 5511)


# Using librosa
spectrogram_librosa = np.abs(librosa.stft(audio,
                                              n_fft=n_fft,
                                              hop_length=hop_length,
                                              win_length=nfft,
                                              window='hann')) ** 2
spectrogram_librosa_db = librosa.power_to_db(spectrogram_librosa, ref=np.max)

print(spectrogram_librosa_db.shape) # (101, 3676)

Can someone explain it to me why is there a huge diff in the time steps and how to make sure that both generate the same output?

1

There are 1 answers

0
Leonard On BEST ANSWER

This is because the noverlap of plt.specgram consider the number of points to overlap the audio segments with, whereas the hop_length consider the step between the segments.

That being said, there is still a 2-points difference between the two results, but this is most possibly due to the boundaries.

import numpy as np
import librosa
import matplotlib.pyplot as plt

path = librosa.util.example_audio_file()
fs = 8000
nfft = 200
noverlap = 120  # overlap
hop_length = 80  # step

audio, fs = librosa.core.load(path, sr=fs)

# Spectogram generated using matplotlib
spec, freqs, bins, _ = plt.specgram(
    audio, NFFT=nfft, Fs=fs, noverlap=noverlap,
)
spec = np.log10(spec + 1e-14)

print(spec.shape)  # (101, 6144)


# Using librosa
spectrogram_librosa = (
    np.abs(
        librosa.stft(
            audio,
            n_fft=nfft,
            hop_length=hop_length,
            win_length=nfft,
            window="hann",
        )
    )
    ** 2
)
spectrogram_librosa_db = librosa.power_to_db(spectrogram_librosa, ref=np.max)

print(spectrogram_librosa_db.shape)  # (101, 6146)

fig, ax = plt.subplots(2)
ax[0].pcolorfast(spec)
ax[1].pcolorfast(spectrogram_librosa_db)
plt.show()

This outputs the following picture:

specgrams