How to find the correct magnitude with scipy.signal.spectogram

Viewed 555

I tried to create a spectogram of magnitudes using scipy.signal.spectogram. Unfortunately I didn't get it working.

My test signal should be a sine with frequency 400 Hz and an amplitude of 1. The result for the magnitude of the spectogram seems to be 0.5 instead of 1.0. I have no idea what the problem could be.

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

# 2s time range with 44kHz
t = np.arange(0, 2, 1/44000)

# test signal: sine with 400Hz amplitude 1
x = np.sin(t*2*np.pi*440)

# spectogram for spectrum of magnitudes
f, t, Sxx = signal.spectrogram(x,
                               44000,
                               "hanning",
                               nperseg=1000,
                               noverlap=0,
                               scaling="spectrum",
                               return_onesided=True,
                               mode="magnitude"
                              )

# plot last frequency plot
plt.plot(f, Sxx[:,-1])
print("highest magnitude is: %f" %np.max(Sxx))
1 Answers

A strictly real time domain signal is conjugate symmetric in the frequency domain. e.g. will appear in both the positive and negative (or upper) half of a complex result FFT.

Thus you need to add together the two "halves" together of an FFT result to get the total energy (Parseval's theorem). Or just double one side, since complex conjugates have equal magnitudes.

Related