Created
December 4, 2016 07:19
-
-
Save antoinevg/9a0b86fd222887a4f706e63d300a41cd to your computer and use it in GitHub Desktop.
A multi-resolution sinusoidal model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import sys | |
| import math | |
| import numpy as np | |
| eps = np.finfo(float).eps # epsilon, minimum float value in python | |
| from scipy.fftpack import fft, ifft | |
| from scipy.signal import triang, get_window, blackmanharris | |
| sys.path.append("../../software/models/") | |
| import utilFunctions as UF | |
| import dftModel as DFT | |
| import sineModel as SM | |
| def sineModelMultiRes(x, fs, ws, Ns, Bs, t): | |
| Ms = np.array([w.size for w in ws]) | |
| M_max = np.max(Ms) # get largest window size | |
| hM1_max = int(math.floor((M_max+1)/2)) # half analysis window size by rounding | |
| Nsy = 512 # FFT size for synthesis (even) | |
| H = Nsy/4 # Hop size used for analysis and synthesis | |
| hNsy = Nsy/2 # half of synthesis FFT size | |
| pin = max(hNsy, hM1_max) # init sound pointer in middle of anal window | |
| pend = x.size - max(hNsy, hM1_max) # last sample to start a frame | |
| yw = np.zeros(Nsy) # initialize output sound frame | |
| y = np.zeros(x.size) # initialize output array | |
| w = w / sum(w) # normalize analysis window | |
| sw = np.zeros(Nsy) # initialize synthesis window | |
| ow = triang(2*H) # triangular window | |
| sw[hNsy-H:hNsy+H] = ow # add triangular window | |
| bh = blackmanharris(Nsy) # blackmanharris window | |
| bh = bh / sum(bh) # normalized blackmanharris window | |
| sw[hNsy-H:hNsy+H] = sw[hNsy-H:hNsy+H] / bh[hNsy-H:hNsy+H] # normalized synthesis window | |
| while pin < pend: | |
| ipfreqs = np.array([]) | |
| ipmags = np.array([]) | |
| ipphases = np.array([]) | |
| # - analysis ----------------- | |
| for w, N, B in zip(ws, Ns, Bs): # for each band | |
| M = w.size | |
| hM1 = int(math.floor((M + 1) / 2)) | |
| hM2 = int(math.floor(M / 2)) | |
| x1 = x[pin-hM1:pin+hM2] # select frame | |
| mX, pX = DFT.dftAnal(x1, w, N) # compute dft | |
| ploc = UF.peakDetection(mX, t) # detect locations of peaks | |
| iploc, ipmag, ipphase = UF.peakInterp(mX, pX, ploc) # refine peak values by interpolation | |
| ipfreq = fs*iploc/float(N) # convert peak locations to Hertz | |
| filt = np.where((ipfreq >= B[0]) & (ipfreq < B[1])) # bandfilter peaks | |
| ipfreq = np.take(ipfreq, filt)[0] | |
| ipmag = np.take(ipmag, filt)[0] | |
| ipphase = np.take(ipphase, filt)[0] | |
| ipfreqs = np.append(ipfreqs, ipfreq) # merge bands | |
| ipmags = np.append(ipmags, ipmag) | |
| ipphases = np.append(ipphases, ipphase) | |
| # - reconstruction ----------- | |
| frame = int(pin / float(H)) | |
| Y = UF.genSpecSines(ipfreqs, ipmags, ipphases, Nsy, fs) # generate sines in the spectrum | |
| fftbuffer = np.real(ifft(Y)) # compute inverse FFT | |
| yw[:hNsy-1] = fftbuffer[hNsy+1:] # undo zero-phase window | |
| yw[hNsy-1:] = fftbuffer[:hNsy+1] | |
| y[pin-hNsy:pin+hNsy] += sw*yw # overlap-add and apply a synthesis window | |
| pin += H # next frame | |
| return y |
Author
This was part of my homework for the "Audio Signal Processing for Music Application" course run by Prof Xavier Serra and Prof Julius Smith.
The missing modules come from the sms-tools repository which is used in the course.
You can find it here on Prof Serra's GitHub:
https://github.com/MTG/sms-tools
The course is very good and I highly recommend it:
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have an Error That says SineModel no such Module Found could you please Help me out