Ejemplo n.º 1
0
def harmonicModelAnal(x, fs, w, N, H, t, nH, minf0, maxf0, f0et, harmDevSlope=0.01, minSineDur=0.02):
    # Analysis of a sound using the sinusoidal harmonic model
    # x: input sound, fs: sampling rate, w: analysis window,
    # N: FFT size (minimum 512), t: threshold in negative dB,
    # nH: maximum number of harmonics, minf0: minimum f0 frequency in Hz,
    # maxf0: maximim f0 frequency in Hz,
    # f0et: error threshold in the f0 detection (ex: 5),
    # harmDevSlope: slope of harmonic deviation
    # minSineDur: minimum length of harmonics
    # returns xhfreq, xhmag, xhphase: harmonic frequencies, magnitudes and phases
    hN = N / 2  # size of positive spectrum
    hM1 = int(math.floor((w.size + 1) / 2))  # half analysis window size by rounding
    hM2 = int(math.floor(w.size / 2))  # half analysis window size by floor
    x = np.append(np.zeros(hM2), x)  # add zeros at beginning to center first window at sample 0
    x = np.append(x, np.zeros(hM2))  # add zeros at the end to analyze last sample
    pin = hM1  # init sound pointer in middle of anal window
    pend = x.size - hM1  # last sample to start a frame
    fftbuffer = np.zeros(N)  # initialize buffer for FFT
    w = w / sum(w)  # normalize analysis window
    hfreqp = []
    f0t = 0
    f0stable = 0
    while pin <= pend:
        x1 = x[pin - hM1 : pin + hM2]  # select frame
        mX, pX = DFT.dftAnal(x1, w, N)  # compute dft
        ploc = UF.peakDetection(mX, hN, t)  # detect peak locations
        iploc, ipmag, ipphase = UF.peakInterp(mX, pX, ploc)  # refine peak values
        ipfreq = fs * iploc / N
        f0t = UF.f0DetectionTwm(ipfreq, ipmag, f0et, minf0, maxf0, f0stable)  # find f0
        if ((f0stable == 0) & (f0t > 0)) or ((f0stable > 0) & (np.abs(f0stable - f0t) < f0stable / 5.0)):
            f0stable = f0t  # consider a stable f0 if it is close to the previous one
        else:
            f0stable = 0
        hfreq, hmag, hphase = UF.harmonicDetection(
            ipfreq, ipmag, ipphase, f0t, nH, hfreqp, fs, harmDevSlope
        )  # find harmonics
        hfreqp = hfreq
        if pin == hM1:
            xhfreq = np.array([hfreq])
            xhmag = np.array([hmag])
            xhphase = np.array([hphase])
        else:
            xhfreq = np.vstack((xhfreq, np.array([hfreq])))
            xhmag = np.vstack((xhmag, np.array([hmag])))
            xhphase = np.vstack((xhphase, np.array([hphase])))
        pin += H  # advance sound pointer
    xhfreq = UF.cleaningSineTracks(xhfreq, round(fs * minSineDur / H))
    return xhfreq, xhmag, xhphase
Ejemplo n.º 2
0
def sineModelAnal(x, fs, w, N, H, t, maxnSines = 100, minSineDur=.01, freqDevOffset=20, freqDevSlope=0.01):
  # Analysis of a sound using the sinusoidal model
  # x: input array sound, w: analysis window, N: size of complex spectrum,
  # H: hop-size, t: threshold in negative dB
  # maxnSines: maximum number of sines per frame
  # minSineDur: minimum duration of sines in seconds
  # freqDevOffset: minimum frequency deviation at 0Hz 
  # freqDevSlope: slope increase of minimum frequency deviation
  # returns xtfreq, xtmag, xtphase: frequencies, magnitudes and phases of sinusoids
  hN = N/2                                                # size of positive spectrum
  hM1 = int(math.floor((w.size+1)/2))                     # half analysis window size by rounding
  hM2 = int(math.floor(w.size/2))                         # half analysis window size by floor
  x = np.append(np.zeros(hM2),x)                          # add zeros at beginning to center first window at sample 0
  x = np.append(x,np.zeros(hM2))                          # add zeros at the end to analyze last sample
  pin = hM1                                               # initialize sound pointer in middle of analysis window       
  pend = x.size - hM1                                     # last sample to start a frame
  w = w / sum(w)                                          # normalize analysis window
  tfreq = np.array([])
  while pin<pend:                                         # while input sound pointer is within sound            
    x1 = x[pin-hM1:pin+hM2]                               # select frame
    mX, pX = DFT.dftAnal(x1, w, N)                        # compute dft
    ploc = UF.peakDetection(mX, hN, t)                    # detect locations of peaks
    pmag = mX[ploc]                                       # get the magnitude of the peaks
    iploc, ipmag, ipphase = UF.peakInterp(mX, pX, ploc)   # refine peak values by interpolation
    ipfreq = fs*iploc/float(N)
    tfreq, tmag, tphase = UF.sineTracking(ipfreq, ipmag, ipphase, tfreq, freqDevOffset, freqDevSlope)
    tfreq = np.resize(tfreq, min(maxnSines, tfreq.size))
    tmag = np.resize(tmag, min(maxnSines, tmag.size))
    tphase = np.resize(tphase, min(maxnSines, tphase.size))
    jtfreq = np.zeros(maxnSines) 
    jtmag = np.zeros(maxnSines)  
    jtphase = np.zeros(maxnSines)    
    jtfreq[:tfreq.size]=tfreq 
    jtmag[:tmag.size]=tmag
    jtphase[:tphase.size]=tphase 
    if pin == hM1:
      xtfreq = jtfreq 
      xtmag = jtmag
      xtphase = jtphase
    else:
      xtfreq = np.vstack((xtfreq, jtfreq))
      xtmag = np.vstack((xtmag, jtmag))
      xtphase = np.vstack((xtphase, jtphase))
    pin += H
  xtfreq = UF.cleaningSineTracks(xtfreq, round(fs*minSineDur/H))
  return xtfreq, xtmag, xtphase