diff --git a/lib/cepstrum.py b/lib/cepstrum.py index daaf1c7..1e00dac 100644 --- a/lib/cepstrum.py +++ b/lib/cepstrum.py @@ -1,4 +1,5 @@ import numpy as np +from .util import pad2 # fast cepstrum and inverted fast cepstrum fcs = lambda s: np.fft.ifft(np.log(np.fft.fft(s))) @@ -32,8 +33,11 @@ def fold(r): rw = np.hstack((r[0], rf, np.zeros(n-nt-1))) return rw -def minphase(s, os=True): +def minphase(s, pad=True, os=False): # via https://ccrma.stanford.edu/~jos/fp/Matlab_listing_mps_m.html + # TODO: actual oversampling + if pad: + s = pad2(s) if os: s = np.hstack((s, np.zeros(len(s)))) cepstrum = np.fft.ifft(np.log(clipdb(np.fft.fft(s), -100))) diff --git a/lib/util.py b/lib/util.py index 34d40a5..2c71c80 100644 --- a/lib/util.py +++ b/lib/util.py @@ -14,6 +14,9 @@ tau = 2*np.pi unwarp = lambda w: np.tan(w/2) warp = lambda w: np.arctan(w)*2 +ceil2 = lambda x: np.power(2, np.ceil(np.log2(x))) +pad2 = lambda x: np.hstack((x, np.zeros(ceil2(len(x)) - len(x)))) + rfft = lambda src, size: np.fft.rfft(src, size*2) magnitude = lambda src, size: 10*np.log10(np.abs(rfft(src, size))**2)[0:size] diff --git a/lib/wav.py b/lib/wav.py index 880c1bb..e6414f2 100644 --- a/lib/wav.py +++ b/lib/wav.py @@ -1,5 +1,5 @@ import numpy as np -from . import lament +from .util import lament, count_channels # TODO: don't use wavfile, it breaks on perfectly good files import scipy.io.wavfile as wav @@ -30,3 +30,9 @@ def wav_read(fn): bits = s.dtype.itemsize*8 s = np.asfarray(s)/2**(bits - 1) return s, srate + +def wav_write(fn, s, srate, dtype='h'): + if dtype in ('b', 'h', 'i', 'l') and np.max(np.abs(s)) > 1: + lament('wav_write(): WARNING; clipping') + with ewave.open(fn, 'w', srate, dtype, count_channels(s)) as f: + f.write(s)