I am experimenting with audio (wav files) using Short-Time Fourier Transform (STFT) in Python using scipy.signal.stft. As I understand we get data for freq, time and magnitude + phase in rectangular format. for e.g. (shortened for illustration)

freq, time, Zxx = scipy.signal.stft(signal, fs=fs , .. and some other parms)

If I take a single value from Zxx , e.g.

x = -0.01224990-0.01877387j ,

I would like to convert this value to dB, do some modification such as

  • add/reduce few dB's
  • Also change angle or phase
  • and reconstruct the value back to x

So far I have,

m = np.abs(-0.01224990-0.01877387j)

#angle in degrees
ad =np.angle(-0.01224990-0.01877387j, deg=True)


#magnitude in dB
dB = 20*np.log10(abs(p))

#modified magnitude
dB = dB + 10.0

#Modified angle
ad = -123.12434072219258 + 50.0

Now, How do I convert it back to modified x. using above values?

I researched but couldn't find a straightforward solution. Before reinventing the wheel of constructing the complex mathematical functions, i thought I would ask the experts.

The only reference I found was mag2db and db2mag at matlab, but not sure how to access or implement these in python.

Please note: I am not trying to reconstruct original signal (or x value) back. I need to modify Zxx values and hence I know I will get a different signal back using scipy.signal.istft.

Although I can directly manipulate x+jy which affect both magnitude and phase, I would like to modify them individually and Hence this question. Thanks in advance.

  • $\begingroup$ Converting mel spectrogram to spectrogram <- Does not solve my problem as the linked question is to convert spectrogram back. I am trying to understand how to convert a magnitude + phase back to rectangular entity (x + jy) using python. $\endgroup$ – Anil_M Dec 15 '17 at 22:58

If $X_\mathrm{db} = 20 \cdot \mathrm{log}_{10}(|X|)$, then $|X| = 10^{X_\mathrm{db} / 20}$, of course. Furthermore, you can compute the cartesian representation of a complex number $c = a + ib$ from its magnitude $|c|$ and phase $\varphi$: $c = |c| \cdot \mathrm{exp}(i \varphi)$

So you are probably looking for something like this:

import numpy as np
from matplotlib import pyplot as plt

fs = 100
t = np.arange(100)
x = np.sin(2 * np.pi * 3 * t / fs)

X = np.fft.fft(x)
X_mag = np.abs(X)
X_db = 20 * np.log10(X_mag)
X_phase = np.angle(X)

# ... do modification on X_db and X_phase ...

X_mag_rec = 10 ** (X_db / 20)
X_rec = X_mag_rec * np.exp(1j * X_phase)
x_rec = np.real(np.fft.ifft(X_rec))

plt.plot(t, x, label='original')
plt.plot(t, x_rec, label='reconstructed')

If you are doing the modification in the STFT domain, note there may be no valid inverse STFT. For details on that look into:

D. Griffin, J. Lim: Signal estimation from modified short-time Fourier transform, in: IEEE Transactions on Acoustics, Speech, and Signal Processing, vol. 32, no. 2, pp. 236–243, Apr 1984.


Not the answer you're looking for? Browse other questions tagged or ask your own question.