-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathistft.py
52 lines (42 loc) · 1.89 KB
/
istft.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from __future__ import division
import numpy as np
import random
import wave, struct, numpy as np, matplotlib.mlab as mlab, pylab as pl
import math
import matplotlib.pyplot as plt
import gc
from scipy.io import wavfile
import nmf
from stft import sinebell
def my_istft(stft, win_size, overlap):
# power sinbell analysis window
win = sinebell(win_size, overlap)
(num_coeff, num_frames) = stft.shape
# recover full stft by conjugate symmetry of the fourier expansion of real signals
stft_full = np.zeros((win_size, num_frames), dtype = np.complex128)
stft_full[:num_coeff,:] = stft
# reasoning: stft[ num_coeff - 1] is the both the negative and positive Nyquist frequency if win_size is even
# thus, we take the conjugate only of stft[ num_coeff - 2:0:-1 ]
if win_size%2 == 0:
stft_full[num_coeff:, :] = np.conj(stft[num_coeff-2:0:-1, :])
else:
stft_full[num_coeff:,:] = np.conj(stft[num_coeff-1:0:-1, :])
# take inverse fft of recovered stft
istft = np.fft.ifft(stft_full, axis = 0)
# reconstruct padded signal by taking overlap into account
x_pad = overlap_add(istft, win_size, overlap)
return x_pad
def overlap_add(signal, win_size, overlap):
win = sinebell(win_size, overlap)
(temp, num_frames) = signal.shape
if temp != win_size:
print("Dimensions of ISTFT are wrong!")
pad_len = overlap + num_frames * (win_size - overlap)
x_pad = np.zeros(pad_len, dtype = np.complex128)
# index of beginning of each frame in x_pad
frame_ind = np.array([i for i in range(num_frames)]) * (win_size - overlap)
# do we really need the window again here?
x_pad[frame_ind[0]:frame_ind[0] + win_size] = signal[:,0] * win
for i in range(1,num_frames):
x_pad[frame_ind[i]:frame_ind[i] + win_size] = x_pad[frame_ind[i]:frame_ind[i] + win_size] + signal[:,i] * win
return x_pad