Skip to content

Instantly share code, notes, and snippets.

@antoinevg
Created December 4, 2016 07:19
Show Gist options
  • Select an option

  • Save antoinevg/9a0b86fd222887a4f706e63d300a41cd to your computer and use it in GitHub Desktop.

Select an option

Save antoinevg/9a0b86fd222887a4f706e63d300a41cd to your computer and use it in GitHub Desktop.
A multi-resolution sinusoidal model
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
@msafdarkhan
Copy link

I have an Error That says SineModel no such Module Found could you please Help me out

@antoinevg
Copy link
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:

https://www.coursera.org/learn/audio-signal-processing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment