-
Notifications
You must be signed in to change notification settings - Fork 1
/
stft.py
59 lines (50 loc) · 2.1 KB
/
stft.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
53
54
55
56
57
58
59
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
# takes in wave file as input
# win_size is the length of the window in samples
# overlap is the amount of overlap between windows in samples
def my_stft(wave, win_size, overlap):
# power sinbell analysis window
win = sinebell(win_size, overlap)
# make the frames
frames, wave_pad = make_frames(wave, win, overlap)
# fft, for each column
stft = np.fft.fft(frames, axis = 0)
# keep the spectrum associated with the positive frequencies (potentially times to the upper frequencies)
if len(win)%2 == 0:
stft = stft[:int(len(win)/2)+1]
else:
stft = stft[:int((len(win)+1)/2)]
return stft, wave_pad
# create sinebell window of length win_size, with overlap, DONE
def sinebell(win_size, overlap):
win = np.zeros(win_size)
win[0:overlap] = np.sin( math.pi * (np.array([i for i in range(overlap)])) / (2*(overlap-1)) )
win[overlap : win_size - overlap] = 1
win[win_size - overlap:] = np.sin( math.pi * (win_size - np.array([i for i in range(win_size-overlap, win_size)]) - 1 ) / (2*(overlap - 1)) )
return win
# x is the input signal, win is the analysis window, overlap
# returns frame matrix and padded input signal x_pad
def make_frames(x, win, overlap):
win_len = win.shape[0]
win_size = 256
x_len = len(x)
# number of frames
num_frames = int(np.ceil((x_len + overlap)/(win_len - overlap)))
# initializing zero padded signal
pad_len = int(overlap + num_frames * (win_len - overlap))
x_pad = np.zeros(pad_len)
x_pad[overlap: overlap + x_len] = x
# index of beginning of each frame in x_pad
frame_ind = np.array([i for i in range(num_frames)]) * (win_len - overlap)
# initialize frames matrix
frames = np.zeros((win_size, num_frames))
for i in range(num_frames):
frames[:,i] = (x_pad[frame_ind[i] : frame_ind[i] + win_size] * win)
return frames, x_pad