I've tried to implement STFT in functional way in Python. I've got code such as below:
def genSpectrums_dft(x, w, N, dft_func = fp.fft):
hN = N / 2
M = len(x)
hM1 = int(math.floor((M + 1) / 2))
hM2 = int(math.floor(M / 2))
wM = w(M)
w_sum = sum(wM)
xw = x * wM / w_sum
dft_buffer = np.concatenate(
(xw[hM2:], np.zeros(N - hM1 - hM2), xw[:hM2])
)
X = dft_func(dft_buffer)
mX = 20 * np.log10(abs(X[:hN]))
pX = np.unwrap(np.angle(X[:hN]))
return mX, pX
def genSpectrums_stft(x, w, M, N, H, dft_func = fp.fft):
hM1 = int(math.floor((M + 1) / 2))
hM2 = int(math.floor(M / 2))
x_ext = np.concatenate((np.zeros(hM2), x, np.zeros(hM2)))
lv = np.arange(len(x) / H + 1)
wM = w(M)
w_sum = sum(wM)
xlv = np.array([x_ext[l * H:l * H + M] / w_sum for l in lv])
return tuple(
np.transpose(np.array(X))
for X in zip(
*[genSpectrums_dft(xl, w, N, dft_func) for xl in xlv]
)
)
Full working code is available here (Python, numpy, scipy and matplotlib required to run it).
When I run my code for any wave, STFT magnitude spectrum seems to be quite good, but STFT phase spectrum always looks like this:
But as far as I know it should rather look like this:
Both these spectrums have been generated from the same wave and the second parameters. The second one has less frequencies. Why my phase spectrum has these strange vertical lines?
I've got a few remarks rewarding my code:
- I am almost positive that finding dft spectrums works correctly
- Though the spectrums distinct, when I inverse the process, I get something really similar to the input
If you are not familiar with functional programming, I don't mind if you correct my mistakes in structural way, but the most important thing for me is to understand the problem with my code.
randint
function which produces uniform but not normal distribution. $\endgroup$