I'm trying to compute the STFT by my self. Thus, I wrote the following code:
hann_win = scipy.signal.hanning(256, sym=True)
frame_spectrum = np.zeros((int(fft_Size / 2 + 1), N_frames))
for i in range(N_frames):
frame_spectrum[:, i] = abs(np.fft.rfft(hann_win * signal[start:start + frame_size], fft_Size))**2
start += 128
fft_size = frame_size = 256. Using the scipy.signal.stft function, the output result is different. It looks like it is normalized in some way.
f, t, STFT = scipy.signal.stft(signal, Fs, 'hann', 256, 128, 256, boundary = None, padded = False, axis = 0)
The ouput for my implementation is:
frame_spectrum
Out[239]:
array([[1.39350590e+05, 1.28392811e+05, 3.01856941e+05, ...,
6.44869243e+05, 6.86848227e+05, 2.35430292e+05],
[2.45825457e+04, 1.11256638e+04, 5.85035486e+04, ...,
2.01218021e+05, 1.96921261e+05, 1.20836787e+05],
[2.12379247e+04, 2.13193995e+04, 6.98189265e+03, ...,
4.81385299e+03, 2.79953520e+04, 1.11993281e+04],
...,
[2.35902280e+02, 2.06442959e+02, 8.19946703e+02, ...,
5.85829771e+02, 4.35596749e+01, 3.36198896e+02],
[2.77258143e+02, 1.61436920e+02, 6.49894194e+02, ...,
5.80593478e+02, 3.19306802e+02, 1.09445294e+03],
[3.93939998e+02, 1.50623962e+02, 5.51785739e+02, ...,
4.90244067e+02, 4.83394024e+02, 1.97937846e+03]])
For the scipy.signal.stft function, the output is:
STFT
Out[242]:
array([[ 2.9267783 +0. j, 2.8191867 +0. j,
4.3128223 +0. j, ..., 6.2927547 +0. j,
6.5078945 +0. j, 3.778513 +0. j],
[-1.0943314 -0.51656187j, -0.8138022 +0.10491034j,
-1.8788935 -0.0876543 j, ..., -3.498077 -0.11071016j,
-3.3105822 +1.0691631 j, -1.8662903 -1.960599 j],
[-0.8903561 +0.71827334j, -1.1007539 +0.3362887 j,
-0.60977626+0.25182465j, ..., 0.5338975 +0.02365825j,
-0.07851043-1.3080015 j, 0.15810308+0.80889297j],
...,
[-0.06972471+0.09730107j, -0.06172764-0.09533134j,
-0.22229262+0.02101982j, ..., -0.18767883+0.02727323j,
-0.05091092-0.00271361j, -0.12367946-0.07388743j],
[ 0.12895514-0.01280107j, 0.09401653-0.03171136j,
0.19183227+0.05289177j, ..., 0.18554814-0.02986654j,
0.12113474+0.06995475j, 0.2588121 -0.00447672j],
[-0.15553662+0. j, -0.09567829+0. j,
-0.18430477+0. j, ..., -0.17289034+0. j,
-0.17330773+0. j, -0.34770313+0. j]],
dtype=complex64)
Could anyone give me an explanation please? I missed something?
Edit:
abs(STFT)**2
Out[3]:
array([[8.56603146e+00, 7.94781351e+00, 1.86004372e+01, ...,
3.95987625e+01, 4.23526917e+01, 1.42771597e+01],
[1.46439719e+00, 6.73280120e-01, 3.53792381e+00, ...,
1.22487984e+01, 1.21030636e+01, 7.32698822e+00],
[1.30865073e+00, 1.32474923e+00, 4.35242742e-01, ...,
2.85606265e-01, 1.71703196e+00, 6.79304421e-01],
...,
[1.43290339e-02, 1.28983660e-02, 4.98558395e-02, ...,
3.59671712e-02, 2.59928545e-03, 2.07559634e-02],
[1.67932957e-02, 9.84471757e-03, 3.95971648e-02, ...,
3.53201218e-02, 1.95672903e-02, 6.70037419e-02],
[2.41916403e-02, 9.15433560e-03, 3.39682512e-02, ...,
2.98910681e-02, 3.00355703e-02, 1.20897464e-01]], dtype=float32)
Ratio between frame_spectrum and abs(STFT)**2:
absolute_frame_spectrum / (abs(STFT)**2)
Out[59]:
array([[16267.81209577, 16154.4821358 , 16228.4863926 , ...,
16285.0857511 , 16217.34535357, 16489.99500715],
[16786.8020194 , 16524.568988 , 16536.12449353, ...,
16427.57227861, 16270.36492832, 16492.01333113],
[16228.87161575, 16093.15862715, 16041.37639628, ...,
16854.8578121 , 16304.50260254, 16486.46436409],
...,
[16463.23688692, 16005.35752565, 16446.35236183, ...,
16287.90231531, 16758.32674005, 16197.70134645],
[16510.04947047, 16398.32925761, 16412.64461434, ...,
16438.03727133, 16318.39649219, 16334.20625631],
[16284.13753068, 16453.83875639, 16244.16092896, ...,
16401.02205314, 16094.05180593, 16372.37367461]])
Spectrogram for my implementation: Spectrogram for scipy.signal.stft function: