So librosa.core.stft returns a complex single sided spectrogram.
My question is:
What normalization of the amplitude values should I perform afterwards?
I believe I have to multiply the amplitude outputs by 2 in order to preserve the energy that was assignated to the negative frequencies. I have not seen in the code that librosa.core.stft does this, although I might have missed it.
And then the other normalization step would be to divide the outputs by the length of the window size right?
However, after doing these two amplitude normalization steps, I still lack a factor of 2 somewhere. This can be seen in the picture below, where in the coloured picture the spectrogram has been calculated and an amplitude value of 0.5 is observed. And in the second plot, the FT of the whole signal has been computed and, applying the same normalization, the expected value of 1 is observed.
Picture: The frequency axis are not in Hz, the only important thing here are the amplitude values.
Here is the code:
%Import packages import scipy.fftpack as fft import librosa import numpy as np %Create sine wave of frequency 1000 Hz and 20000 samples frequency = 1000 fs = 4 * frequency time_vector = 1/fs * np.arange(20000) sine_wave = np.sin(2 * np.pi * frequency * time_vector) window_size = 1024 hop_length = 512 out = librosa.core.spectrum.stft(sine_wave, n_fft = window_size, hop_length = hop_length) %Take magnitude and normalize out = 2 * np.abs(out) / window_size fig = plt.figure() axes = fig.add_subplot(111) im = axes.pcolormesh(out) fig.colorbar(im) plt.show() %And plot also the fourier transform of the whole signal transform = 2 * np.abs(fft.fft(sine_wave)) / len(sine_wave) %Plot only positive frequencies plt.plot(transform[10000:])