xue@11: /* xue@11: Harmonic sinusoidal modelling and tools xue@11: xue@11: C++ code package for harmonic sinusoidal modelling and relevant signal processing. xue@11: Centre for Digital Music, Queen Mary, University of London. xue@11: This file copyright 2011 Wen Xue. xue@11: xue@11: This program is free software; you can redistribute it and/or xue@11: modify it under the terms of the GNU General Public License as xue@11: published by the Free Software Foundation; either version 2 of the xue@11: License, or (at your option) any later version. xue@11: */ xue@1: //--------------------------------------------------------------------------- xue@1: xue@1: #include "align8.h" Chris@2: #include "sinsyn.h" xue@1: #include "splines.h" xue@1: Chris@5: /** \file sinsyn.h */ Chris@5: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@7: function CosSin: recursive cos-sin generator with trinomial frequency xue@7: xue@7: In: CountSt, CountEn xue@7: f3, f2, f1, f0: trinomial coefficients of frequency xue@7: ph: initial phase angle at 0 (NOT at CountSt) xue@7: Out: datar[CountSt:CountEn-1], datai[CountSt:CountEn-1]: synthesized pair of cosine and sine functions xue@7: ph: phase angle at CountEn xue@7: xue@7: No return value. xue@7: */ xue@7: void CosSin(double* datar, double* datai, int CountSt, int CountEn, double f3, double f2, double f1, double f0, double &ph) xue@7: { xue@7: int i; xue@7: double dph, ddph, dddph, ddddph, xue@7: sph, cph, sdph, cdph, sddph, cddph, sdddph, cdddph, sddddph, cddddph, xue@7: p0=ph, p1=2*M_PI*f0, p2=M_PI*f1, p3=2.0*M_PI*f2/3, p4=2.0*M_PI*f3/4, tmp; xue@7: if (CountSt==0) xue@7: { xue@7: dph=p1+p2+p3+p4; ddph=2*p2+6*p3+14*p4; dddph=6*p3+36*p4; ddddph=24*p4; xue@7: } xue@7: else xue@7: { xue@7: ph=p0+CountSt*(p1+CountSt*(p2+CountSt*(p3+CountSt*p4))); xue@7: dph=p1+p2+p3+p4+CountSt*(2*p2+3*p3+4*p4+CountSt*(3*p3+6*p4+CountSt*4*p4)); xue@7: ddph=2*p2+6*p3+14*p4+CountSt*(6*p3+24*p4+CountSt*12*p4); xue@7: dddph=6*p3+36*p4+CountSt*24*p4; ddddph=24*p4; xue@7: } xue@7: sph=sin(ph), cph=cos(ph); xue@7: sdph=sin(dph), cdph=cos(dph); xue@7: sddph=sin(ddph), cddph=cos(ddph); xue@7: sdddph=sin(dddph), cdddph=cos(dddph); xue@7: sddddph=sin(ddddph), cddddph=cos(ddddph); xue@7: xue@7: for (i=CountSt; i300) e=300; xue@1: if (e<-300) e=-300; xue@1: s[t]=exp(cdouble(e, ph+(t*t*(_q+t*_p)))); xue@1: ph+=dph; xue@1: } xue@1: }//SinusoidExpA xue@1: xue@1: /* xue@1: //This is not used any longer as the recursion does not seem to help saving computation with all its overheads. xue@1: void SinusoidExp(cdouble* data, int CountSt, int CountEn, double a3, double a2, double a1, double a0, xue@1: double omg3, double omg2, double omg1, double omg0, double &ea, double &ph, bool add) xue@1: { xue@1: int i; xue@1: double dea, ddea, dddea, ddddea, xue@1: dph, ddph, dddph, ddddph, xue@1: sph, cph, sdph, cdph, sddph, cddph, sdddph, cdddph, sddddph, cddddph, xue@1: e0=ea, e1=a0, e2=0.5*a1, e3=a2/3, e4=a3/4, xue@1: p0=ph, p1=omg0, p2=0.5*omg1, p3=omg2/3, p4=omg3/4, tmp; xue@1: if (CountSt==0) xue@1: { xue@1: dea=e1+e2+e3+e4; ddea=2*e2+6*e3+14*e4; dddea=6*e3+36*e4; ddddea=24*e3; xue@1: dph=p1+p2+p3+p4; ddph=2*p2+6*p3+14*p4; dddph=6*p3+36*p4; ddddph=24*p4; xue@1: } xue@1: else xue@1: { xue@1: ea=e0+CountSt*(e1+CountSt*(e2+CountSt*(e3+CountSt*e4))); xue@1: dea=e1+e2+e3+e4+CountSt*(2*e2+3*e3+4*e4+CountSt*(3*e3+6*e4+CountSt*4*e4)); xue@1: ddea=2*e2+6*e3+14*e4+CountSt*(6*e3+24*e4+CountSt*12*e4); xue@1: dddea=6*e3+36*e4+CountSt*24*e4; ddddea=24*e4; xue@1: ph=p0+CountSt*(p1+CountSt*(p2+CountSt*(p3+CountSt*p4))); xue@1: dph=p1+p2+p3+p4+CountSt*(2*p2+3*p3+4*p4+CountSt*(3*p3+6*p4+CountSt*4*p4)); xue@1: ddph=2*p2+6*p3+14*p4+CountSt*(6*p3+24*p4+CountSt*12*p4); xue@1: dddph=6*p3+36*p4+CountSt*24*p4; ddddph=24*p4; xue@1: } xue@1: sph=sin(ph), cph=cos(ph); xue@1: sdph=sin(dph), cdph=cos(dph); xue@1: sddph=sin(ddph), cddph=cos(ddph); xue@1: sdddph=sin(dddph), cdddph=cos(dddph); xue@1: sddddph=sin(ddddph), cddddph=cos(ddddph); xue@1: if (add) xue@1: { xue@1: for (i=CountSt; i=xs[Fr-1] xue@1: add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output buffer xue@1: Out: xrec[0:den-dst-1]: output buffer hosting synthesized sinusoid from dst to den. xue@1: phs[Fr]: phase angles at xs[Fr] xue@1: xue@1: Returns pointer to xrec. xue@1: */ xue@1: double* SynthesizeSinusoid(double* xrec, int dst, int den, double* phs, int Fr, double* xs, double* fs, double* as, bool add, bool* terminatetag) xue@1: { xue@1: double *f3=new double[Fr*8], *f2=&f3[Fr], *f1=&f3[Fr*2], *f0=&f3[Fr*3], xue@1: *a3=&f3[Fr*4], *a2=&a3[Fr], *a1=&a3[Fr*2], *a0=&a3[Fr*3]; xue@1: CubicSpline(Fr-1, f3, f2, f1, f0, xs, fs, 1, 1); xue@1: CubicSpline(Fr-1, a3, a2, a1, a0, xs, as, 1, 1); xue@1: double ph=phs[0]; xue@1: for (int fr=0; fr=xs[Fr-1] xue@1: add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output xue@1: buffer xue@1: Out: xrecm[0:den-dst-1]: output buffer hosting synthesized sinusoid from dst to den. xue@1: xue@1: Returns pointer to xrecm. xue@1: */ xue@1: double* SynthesizeSinusoidP(double* xrecm, int dst, int den, double* phs, int Fr, double* xs, double* fs, double* as, bool add) xue@1: { xue@1: double *f3=new double[Fr*8], *f2=&f3[Fr], *f1=&f3[Fr*2], *f0=&f3[Fr*3], xue@1: *a3=&f3[Fr*4], *a2=&a3[Fr], *a1=&a3[Fr*2], *a0=&a3[Fr*3]; xue@1: CubicSpline(Fr-1, f3, f2, f1, f0, xs, fs, 1, 1); xue@1: CubicSpline(Fr-1, a3, a2, a1, a0, xs, as, 1, 1); xue@7: for (int fr=0; fr