Source code for untwist.transforms.stft
"""
Forward and inverse Short-Time Fourier Transform
"""
import numpy as np
from numpy.lib import stride_tricks
from ..base import Processor
from ..data import audio
from untwist.base import parallel_process
[docs]class STFT(Processor):
"""
Short-Time Fourier Transform
Input should be a mono Wave, output is a complex spectrogram
"""
def __init__(self, window=None, fft_size=1024, hop_size=512):
if window is None:
self.window = np.hanning(fft_size)
else:
self.window = window
self.fft_size = fft_size
self.hop_size = hop_size
@parallel_process(1,2)
def process(self, wave):
wave.check_mono()
window_size = len(self.window)
half_window = np.floor(window_size / 2.0)
wave = wave.zero_pad(half_window, half_window)
num_frames = 1 + np.ceil((wave.shape[0] - window_size) /
float(self.hop_size))
col_size = wave.strides[0]
frames = stride_tricks.as_strided(wave, shape=(num_frames, window_size),
strides=(col_size*self.hop_size, col_size)).copy()
frames *= self.window
transform = np.fft.rfft(frames, self.fft_size)
return audio.Spectrogram(transform.T,
wave.sample_rate, len(self.window), self.hop_size)
[docs]class ISTFT(Processor):
"""
Inverse Short-Time Fourier Transform
Input should be a complex spectrogram, output is mono Wave
"""
def __init__(self, window=None, fft_size=1024, hop_size=512, sample_rate = 44100):
if window is None:
self.window = np.hanning(fft_size)
else:
self.window = window
self.fft_size = fft_size
self.hop_size = hop_size
self.sample_rate = sample_rate
@parallel_process(2,1)
def process(self, spectrogram):
frames = np.fft.irfft(spectrogram.T)
result_length = ((frames.shape[0] - 1) * self.hop_size) + self.fft_size
result = np.zeros((result_length, 1))
for i in range(frames.shape[0]):
indices = i * self.hop_size + np.r_[0:self.fft_size]
result[indices] = result[indices] + frames[i,:].reshape(self.fft_size,1)
result = result[self.hop_size:result_length - self.hop_size]
return audio.Wave(result, self.sample_rate)