annotate sinsyn.cpp @ 13:de3961f74f30 tip

Add Linux/gcc Makefile; build fix
author Chris Cannam
date Mon, 05 Sep 2011 15:22:35 +0100
parents 977f541d6683
children
rev   line source
xue@11 1 /*
xue@11 2 Harmonic sinusoidal modelling and tools
xue@11 3
xue@11 4 C++ code package for harmonic sinusoidal modelling and relevant signal processing.
xue@11 5 Centre for Digital Music, Queen Mary, University of London.
xue@11 6 This file copyright 2011 Wen Xue.
xue@11 7
xue@11 8 This program is free software; you can redistribute it and/or
xue@11 9 modify it under the terms of the GNU General Public License as
xue@11 10 published by the Free Software Foundation; either version 2 of the
xue@11 11 License, or (at your option) any later version.
xue@11 12 */
xue@1 13 //---------------------------------------------------------------------------
xue@1 14
xue@1 15 #include "align8.h"
Chris@2 16 #include "sinsyn.h"
xue@1 17 #include "splines.h"
xue@1 18
Chris@5 19 /** \file sinsyn.h */
Chris@5 20
xue@1 21 //---------------------------------------------------------------------------
Chris@5 22 /**
xue@7 23 function CosSin: recursive cos-sin generator with trinomial frequency
xue@7 24
xue@7 25 In: CountSt, CountEn
xue@7 26 f3, f2, f1, f0: trinomial coefficients of frequency
xue@7 27 ph: initial phase angle at 0 (NOT at CountSt)
xue@7 28 Out: datar[CountSt:CountEn-1], datai[CountSt:CountEn-1]: synthesized pair of cosine and sine functions
xue@7 29 ph: phase angle at CountEn
xue@7 30
xue@7 31 No return value.
xue@7 32 */
xue@7 33 void CosSin(double* datar, double* datai, int CountSt, int CountEn, double f3, double f2, double f1, double f0, double &ph)
xue@7 34 {
xue@7 35 int i;
xue@7 36 double dph, ddph, dddph, ddddph,
xue@7 37 sph, cph, sdph, cdph, sddph, cddph, sdddph, cdddph, sddddph, cddddph,
xue@7 38 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 39 if (CountSt==0)
xue@7 40 {
xue@7 41 dph=p1+p2+p3+p4; ddph=2*p2+6*p3+14*p4; dddph=6*p3+36*p4; ddddph=24*p4;
xue@7 42 }
xue@7 43 else
xue@7 44 {
xue@7 45 ph=p0+CountSt*(p1+CountSt*(p2+CountSt*(p3+CountSt*p4)));
xue@7 46 dph=p1+p2+p3+p4+CountSt*(2*p2+3*p3+4*p4+CountSt*(3*p3+6*p4+CountSt*4*p4));
xue@7 47 ddph=2*p2+6*p3+14*p4+CountSt*(6*p3+24*p4+CountSt*12*p4);
xue@7 48 dddph=6*p3+36*p4+CountSt*24*p4; ddddph=24*p4;
xue@7 49 }
xue@7 50 sph=sin(ph), cph=cos(ph);
xue@7 51 sdph=sin(dph), cdph=cos(dph);
xue@7 52 sddph=sin(ddph), cddph=cos(ddph);
xue@7 53 sdddph=sin(dddph), cdddph=cos(dddph);
xue@7 54 sddddph=sin(ddddph), cddddph=cos(ddddph);
xue@7 55
xue@7 56 for (i=CountSt; i<CountEn; i++)
xue@7 57 {
xue@7 58 datar[i]=cph; datai[i]=sph;
xue@7 59 tmp=cph*cdph-sph*sdph; sph=sph*cdph+cph*sdph; cph=tmp;
xue@7 60 tmp=cdph*cddph-sdph*sddph; sdph=sdph*cddph+cdph*sddph; cdph=tmp;
xue@7 61 tmp=cddph*cdddph-sddph*sdddph; sddph=sddph*cdddph+cddph*sdddph; cddph=tmp;
xue@7 62 tmp=cdddph*cddddph-sdddph*sddddph; sdddph=sdddph*cddddph+cdddph*sddddph; cdddph=tmp;
xue@7 63 }
xue@7 64 ph=p0+CountEn*(p1+CountEn*(p2+CountEn*(p3+CountEn*p4)));
xue@7 65 }//CosSin*/
xue@7 66
xue@7 67 /**
xue@1 68 function Sinuoid: original McAuley-Quatieri synthesizer interpolation between two measurement points.
xue@1 69
xue@1 70 In: T: length from measurement point 1 to measurement point 2
xue@1 71 a1, f1, p2: amplitude, frequency and phase angle at measurement point 1
xue@1 72 a2, f2, p2: amplitude, frequency and phase angle at measurement point 2
xue@1 73 ad: specifies if the resynthesized sinusoid is to be added to or to replace the contents of output buffer
xue@1 74 Out: data[T]: output buffer
xue@1 75 a[T], f[T], p[T]: resynthesized amplitude, frequency and phase
xue@1 76
xue@1 77 No return value.
xue@1 78 */
xue@1 79 void Sinusoid(double* data, int T, double a1, double a2, double f1, double f2, double p1, double p2, double* a, double* f, double* p, bool ad)
xue@1 80 {
xue@1 81 int M=floor(((p1-p2)/M_PI+(f1+f2)*T)/2.0+0.5);
xue@1 82 double b1=p2-p1-2*M_PI*(f1*T-M), b2=2*M_PI*(f2-f1);
xue@1 83 double pa=(3*b1/T-b2)/T, pb=(-2*b1/T+b2)/T/T, pc=2*M_PI*f1, pd=p1;
xue@1 84 double la=a1, da=(a2-a1)/T;
xue@1 85 if (ad)
xue@1 86 for (int t=0; t<T; t++)
xue@1 87 {
xue@1 88 double lp=pd+t*(pc+t*(pa+t*pb)), lf=(pc+2*pa*t+3*pb*t*t)/2/M_PI;
xue@1 89 data[t]+=la*cos(lp);
xue@1 90 a[t]=la;
xue@1 91 p[t]=lp;
xue@1 92 f[t]=lf;
xue@1 93 la=la+da;
xue@1 94 }
xue@1 95 else
xue@1 96 for (int t=0; t<T; t++)
xue@1 97 {
xue@1 98 double lp=pd+t*(pc+t*(pa+t*pb)), lf=(pc+2*pa*t+3*pb*t*t)/2/M_PI;
xue@1 99 data[t]=la*cos(lp);
xue@1 100 a[t]=la;
xue@1 101 p[t]=lp;
xue@1 102 f[t]=lf;
xue@1 103 la=la+da;
xue@1 104 }
xue@1 105 }//Sinusoid
xue@1 106
Chris@5 107 /**
xue@1 108 function Sinuoid: original McAuley-Quatieri synthesizer interpolation between two measurement points,
xue@1 109 without returning interpolated sinusoid parameters.
xue@1 110
xue@1 111 In: T: length from measurement point 1 to measurement point 2
xue@1 112 a1, f1, p2: amplitude, frequency and phase angle at measurement point 1
xue@1 113 a2, f2, p2: amplitude, frequency and phase angle at measurement point 2
xue@1 114 ad: specifies if the resynthesized sinusoid is to be added to or to replace the contents of output buffer
xue@1 115 Out: data[T]: output buffer
xue@1 116
xue@1 117 No return value.
xue@1 118 */
xue@1 119 void Sinusoid(double* data, int T, double a1, double a2, double f1, double f2, double p1, double p2, bool ad)
xue@1 120 {
xue@1 121 int M=floor(((p1-p2)/M_PI+(f1+f2)*T)/2.0+0.5);
xue@1 122 double b1=p2-p1-2*M_PI*(f1*T-M), b2=2*M_PI*(f2-f1);
xue@1 123 double pa=(3*b1/T-b2)/T, pb=(-2*b1/T+b2)/T/T, pc=2*M_PI*f1, pd=p1;
xue@1 124 double la=a1, da=(a2-a1)/T;
xue@1 125 if (ad)
xue@1 126 for (int t=0; t<T; t++)
xue@1 127 {
xue@1 128 data[t]+=la*cos(pd+t*(pc+t*(pa+t*pb)));
xue@1 129 la=la+da;
xue@1 130 }
xue@1 131 else
xue@1 132 for (int t=0; t<T; t++)
xue@1 133 {
xue@1 134 data[t]=la*cos(pd+t*(pc+t*(pa+t*pb)));
xue@1 135 la=la+da;
xue@1 136 }
xue@1 137 }//Sinusoid
xue@1 138
xue@1 139 //---------------------------------------------------------------------------
Chris@5 140 /**
xue@1 141 function Sinusoid_direct: synthesizes sinusoid over [CountSt, CountEn) from tronomial coefficients of
xue@1 142 amplitude and frequency, direct implementation.
xue@1 143
xue@1 144 In: CountSt, CountEn
xue@1 145 aa, ab, ac, ad: trinomial coefficients of amplitude
xue@1 146 fa, fb, fc, fd: trinomial coefficients of frequency
xue@1 147 p1: initial phase angle at 0 (NOT at CountSt)
xue@1 148 add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output buffer
xue@1 149 Out: data[CountSt:CountEn-1]: output buffer.
xue@1 150 p1: phase angle at CountEn
xue@1 151
xue@1 152 No return value.
xue@1 153 */
xue@1 154 void Sinusoid_direct(double* data, int CountSt, int CountEn, double aa, double ab, double ac, double ad,
xue@1 155 double fa, double fb, double fc, double fd, double &p1, bool add)
xue@1 156 {
xue@1 157 int i; double a, ph;
xue@1 158 for (i=CountSt; i<CountEn; i++)
xue@1 159 {
xue@1 160 a=ad+i*(ac+i*(ab+i*aa));
xue@1 161 ph=p1+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)));
xue@1 162 if (add) data[i]+=a*cos(ph);
xue@1 163 else data[i]=a*cos(ph);
xue@1 164 }
xue@1 165 p1=p1+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)));
xue@1 166 }//Sinusoid
xue@1 167
Chris@5 168 /**
xue@7 169 function Sinusoid_direct: synthesizes sinusoid over [CountSt, CountEn) from tronomial coefficients of
xue@7 170 amplitude and frequency, direct implementation returning sinusoid coefficients rather than waveform.
xue@7 171
xue@7 172 In: CountSt, CountEn
xue@7 173 aa, ab, ac, ad: trinomial coefficients of amplitude
xue@7 174 fa, fb, fc, fd: trinomial coefficients of frequency
xue@7 175 p1: initial phase angle at 0 (NOT at CountSt)
xue@7 176 Out: f[CountSt:CountEn-1], a[:], ph[:], da[:]: output buffers.
xue@7 177 p1: phase angle at CountEn
xue@7 178
xue@7 179 No return value.
xue@7 180 */
xue@7 181 void Sinusoid_direct(double* f, double* a, double* ph, double* da, int CountSt, int CountEn, double aa, double ab, double ac, double ad,
xue@7 182 double fa, double fb, double fc, double fd, double &p1, bool LogA)
xue@7 183 {
xue@7 184 int i;
xue@7 185 if (LogA)
xue@7 186 {
xue@7 187 for (i=CountSt; i<CountEn; i++)
xue@7 188 {
xue@7 189 a[i]=exp(ad+i*(ac+i*(ab+i*aa)));
xue@7 190 f[i]=fd+i*(fc+i*(fb+i*fa));
xue@7 191 ph[i]=p1+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)));
xue@7 192 da[i]=a[i]*(ac+i*(2*ab+3*i*aa));
xue@7 193 }
xue@7 194 }
xue@7 195 else
xue@7 196 {
xue@7 197 for (i=CountSt; i<CountEn; i++)
xue@7 198 {
xue@7 199 a[i]=ad+i*(ac+i*(ab+i*aa));
xue@7 200 f[i]=fd+i*(fc+i*(fb+i*fa));
xue@7 201 ph[i]=p1+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)));
xue@7 202 da[i]=ac+i*(2*ab+3*i*aa);
xue@7 203 }
xue@7 204 }
xue@7 205 p1=p1+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)));
xue@7 206 }//Sinusoid
xue@7 207
xue@7 208 /**
xue@7 209 function Sinusoid_direct: synthesizes sinusoid over [CountSt, CountEn) from tronomial coefficients of
xue@7 210 frequency, direct implementation returning frequency and phase rather than waveform.
xue@7 211
xue@7 212 In: CountSt, CountEn
xue@7 213 fa, fb, fc, fd: trinomial coefficients of frequency
xue@7 214 p1: initial phase angle at 0 (NOT at CountSt)
xue@7 215 Out: f[CountSt:CountEn-1], ph[CountSt:CountEn-1]: output buffers.
xue@7 216 p1: phase angle at CountEn
xue@7 217
xue@7 218 No return value.
xue@7 219 */
xue@7 220 void Sinusoid_direct(double* f, double* ph, int CountSt, int CountEn, double fa, double fb, double fc,
xue@7 221 double fd, double &p1)
xue@7 222 {
xue@7 223 int i;
xue@7 224 for (i=CountSt; i<CountEn; i++)
xue@7 225 {
xue@7 226 f[i]=fd+i*(fc+i*(fb+i*fa));
xue@7 227 ph[i]=p1+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)));
xue@7 228 }
xue@7 229 p1=p1+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)));
xue@7 230 }//Sinusoid
xue@7 231
xue@7 232 /**
xue@1 233 function Sinusoid: synthesizes sinusoid over [CountSt, CountEn) from tronomial coefficients of
xue@1 234 amplitude and frequency, recursive implementation.
xue@1 235
xue@1 236 In: CountSt, CountEn
xue@1 237 a3, a2, a1, a0: trinomial coefficients of amplitude
xue@1 238 f3, f2, f1, f0: trinomial coefficients of frequency
xue@1 239 ph: initial phase angle at 0 (NOT at CountSt)
xue@1 240 add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output buffer
xue@1 241 Out: data[CountSt:CountEn-1]: output buffer.
xue@1 242 ph: phase angle at CountEn
xue@1 243
xue@1 244 No return value. This function requires 8-byte stack alignment for optimal speed.
xue@1 245 */
xue@1 246 void Sinusoid(double* data, int CountSt, int CountEn, double a3, double a2, double a1, double a0,
xue@1 247 double f3, double f2, double f1, double f0, double &ph, bool add)
xue@1 248 {
xue@1 249 int i;
xue@1 250 double a, da, dda, ddda, dph, ddph, dddph, ddddph,
xue@1 251 sph, cph, sdph, cdph, sddph, cddph, sdddph, cdddph, sddddph, cddddph,
xue@1 252 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@1 253 if (CountSt==0)
xue@1 254 {
xue@1 255 a=a0; da=a1+a2+a3; dda=2*a2+6*a3; ddda=6*a3;
xue@1 256 dph=p1+p2+p3+p4; ddph=2*p2+6*p3+14*p4; dddph=6*p3+36*p4; ddddph=24*p4;
xue@1 257 }
xue@1 258 else
xue@1 259 {
xue@1 260 a=a0+CountSt*(a1+CountSt*(a2+CountSt*a3));
xue@1 261 da=a1+a2+a3+CountSt*(2*a2+3*a3+CountSt*3*a3);
xue@1 262 dda=2*a2+6*a3+CountSt*6*a3; ddda=6*a3;
xue@1 263 ph=p0+CountSt*(p1+CountSt*(p2+CountSt*(p3+CountSt*p4)));
xue@1 264 dph=p1+p2+p3+p4+CountSt*(2*p2+3*p3+4*p4+CountSt*(3*p3+6*p4+CountSt*4*p4));
xue@1 265 ddph=2*p2+6*p3+14*p4+CountSt*(6*p3+24*p4+CountSt*12*p4);
xue@1 266 dddph=6*p3+36*p4+CountSt*24*p4; ddddph=24*p4;
xue@1 267 }
xue@1 268 sph=sin(ph), cph=cos(ph);
xue@1 269 sdph=sin(dph), cdph=cos(dph);
xue@1 270 sddph=sin(ddph), cddph=cos(ddph);
xue@1 271 sdddph=sin(dddph), cdddph=cos(dddph);
xue@1 272 sddddph=sin(ddddph), cddddph=cos(ddddph);
xue@1 273 if (add)
xue@1 274 {
xue@1 275 for (i=CountSt; i<CountEn; i++)
xue@1 276 {
xue@1 277 data[i]+=a*cph;
xue@1 278 a=a+da; da=da+dda; dda=dda+ddda;
xue@1 279 tmp=cph*cdph-sph*sdph; sph=sph*cdph+cph*sdph; cph=tmp;
xue@1 280 tmp=cdph*cddph-sdph*sddph; sdph=sdph*cddph+cdph*sddph; cdph=tmp;
xue@1 281 tmp=cddph*cdddph-sddph*sdddph; sddph=sddph*cdddph+cddph*sdddph; cddph=tmp;
xue@1 282 tmp=cdddph*cddddph-sdddph*sddddph; sdddph=sdddph*cddddph+cdddph*sddddph; cdddph=tmp;
xue@1 283 }
xue@1 284 }
xue@1 285 else
xue@1 286 {
xue@1 287 for (i=CountSt; i<CountEn; i++)
xue@1 288 {
xue@1 289 data[i]=a*cph;
xue@1 290 a=a+da; da=da+dda; dda=dda+ddda;
xue@1 291 tmp=cph*cdph-sph*sdph; sph=sph*cdph+cph*sdph; cph=tmp;
xue@1 292 tmp=cdph*cddph-sdph*sddph; sdph=sdph*cddph+cdph*sddph; cdph=tmp;
xue@1 293 tmp=cddph*cdddph-sddph*sdddph; sddph=sddph*cdddph+cddph*sdddph; cddph=tmp;
xue@1 294 tmp=cdddph*cddddph-sdddph*sddddph; sdddph=sdddph*cddddph+cdddph*sddddph; cdddph=tmp;
xue@1 295 }
xue@1 296 }
xue@1 297 ph=p0+CountEn*(p1+CountEn*(p2+CountEn*(p3+CountEn*p4)));
xue@1 298 }
xue@1 299
Chris@5 300 /**
xue@1 301 function SinusoidExp: synthesizes complex sinusoid whose derivative log amplitude and frequency are
xue@1 302 trinomials
xue@1 303
xue@1 304 In: CountSt, CountEn
xue@1 305 a3, a2, a1, a0: trinomial coefficients for the derivative of log amplitude
xue@1 306 omg3, omg2, omg1, omg0: trinomial coefficients for angular frequency
xue@1 307 ea, ph: initial log amplitude and phase angle at 0
xue@1 308 add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output buffer
xue@1 309 Out: data[CountSt:CountEn-1]: output buffer.
xue@1 310 ea, ph: log amplitude and phase angle at CountEn.
xue@1 311
xue@1 312 No return value.
xue@1 313 */
xue@1 314 void SinusoidExp(cdouble* data, int CountSt, int CountEn, double a3, double a2, double a1, double a0,
xue@1 315 double omg3, double omg2, double omg1, double omg0, double &ea, double &ph, bool add)
xue@1 316 {
xue@1 317 double e0=ea, e1=a0, e2=0.5*a1, e3=a2/3, e4=a3/4,
xue@1 318 p0=ph, p1=omg0, p2=0.5*omg1, p3=omg2/3, p4=omg3/4;
xue@1 319 if (add) for (int i=CountSt; i<CountEn; i++)
xue@1 320 {
xue@1 321 double lea=e0+i*(e1+i*(e2+i*(e3+i*e4)));
xue@1 322 double lph=p0+i*(p1+i*(p2+i*(p3+i*p4)));
xue@1 323 data[i]+=exp(cdouble(lea, lph));
xue@1 324 }
xue@1 325 else for (int i=CountSt; i<CountEn; i++)
xue@1 326 {
xue@1 327 double lea=e0+i*(e1+i*(e2+i*(e3+i*e4)));
xue@1 328 double lph=p0+i*(p1+i*(p2+i*(p3+i*p4)));
xue@1 329 data[i]=exp(cdouble(lea, lph));
xue@1 330 }
xue@1 331 ea=e0+CountEn*(e1+CountEn*(e2+CountEn*(e3+CountEn*e4)));
xue@1 332 ph=p0+CountEn*(p1+CountEn*(p2+CountEn*(p3+CountEn*p4)));
xue@1 333 }//SinusoidExp
xue@1 334
Chris@5 335 /**
xue@1 336 function SinusoidExp: synthesizes complex sinusoid piece whose derivative logarithm is h[M]'lamda[M].
xue@1 337 This version also synthesizes its derivative.
xue@1 338
xue@1 339 In: h[M][T], dih[M][T]: basis functions and their difference-integrals
xue@1 340 lamda[M]: coefficients of h[M]
xue@1 341 tmpexp: inital logarithm at 0
xue@1 342 Out: s[T], ds[T]: synthesized sinusoid and its derivative
xue@1 343 tmpexp: logarithm at T
xue@1 344
xue@1 345 No return value.
xue@1 346 */
xue@1 347 void SinusoidExp(int T, cdouble* s, cdouble* ds, int M, cdouble* lamda, double** h, double** dih, cdouble& tmpexp)
xue@1 348 {
xue@1 349 for (int t=0; t<T; t++)
xue@1 350 {
xue@1 351 s[t]=exp(tmpexp);
xue@1 352 cdouble dexp=0, dR=0;
xue@1 353 for (int m=0; m<M; m++) dexp+=lamda[m]*dih[m][t], dR+=lamda[m]*h[m][t];
xue@1 354 tmpexp+=dexp;
xue@1 355 ds[t]=s[t]*dR;
xue@1 356 }
xue@1 357 }//SinusoidExp
xue@1 358
Chris@5 359 /**
xue@1 360 function SinusoidExp: synthesizes complex sinusoid piece whose derivative logarithm is h[M]'lamda[M].
xue@1 361 This version does not synthesize its derivative.
xue@1 362
xue@1 363 In: dih[M][T]: difference of integrals of basis functions h[M]
xue@1 364 lamda[M]: coefficients of h[M]
xue@1 365 tmpexp: inital logarithm at 0
xue@1 366 Out: s[T]: synthesized sinusoid
xue@1 367 tmpexp: logarithm at T
xue@1 368
xue@1 369 No return value.
xue@1 370 */
xue@1 371 void SinusoidExp(int T, cdouble* s, int M, cdouble* lamda, double** dih, cdouble& tmpexp)
xue@1 372 {
xue@1 373 for (int t=0; t<T; t++)
xue@1 374 {
xue@1 375 s[t]=exp(tmpexp);
xue@1 376 cdouble dexp=0;
xue@1 377 for (int m=0; m<M; m++) dexp+=lamda[m]*dih[m][t];
xue@1 378 tmpexp+=dexp;
xue@1 379 }
xue@1 380 }//SinusoidExp
xue@1 381
Chris@5 382 /**
xue@1 383 function SinusoidExpA: synthesizes complex sinusoid whose log amplitude and frequency are trinomials
xue@1 384
xue@1 385 In: CountSt, CountEn
xue@1 386 a3, a2, a1, a0: trinomial coefficients for log amplitude
xue@1 387 omg3, omg2, omg1, omg0: trinomial coefficients for angular frequency
xue@1 388 ph: initial phase angle at 0
xue@1 389 add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output buffer
xue@1 390 Out: data[CountSt:CountEn-1]: output buffer.
xue@1 391 ph: phase angle at CountEn.
xue@1 392
xue@1 393 No return value.
xue@1 394 */
xue@1 395 void SinusoidExpA(cdouble* data, int CountSt, int CountEn, double a3, double a2, double a1, double a0,
xue@1 396 double omg3, double omg2, double omg1, double omg0, double &ph, bool add)
xue@1 397 {
xue@1 398 double p0=ph, p1=omg0, p2=0.5*omg1, p3=omg2/3, p4=omg3/4;
xue@1 399 if (add) for (int i=CountSt; i<CountEn; i++)
xue@1 400 {
xue@1 401 double lea=a0+i*(a1+i*(a2+i*a3));
xue@1 402 double lph=p0+i*(p1+i*(p2+i*(p3+i*p4)));
xue@1 403 data[i]+=exp(cdouble(lea, lph));
xue@1 404 }
xue@1 405 else for (int i=CountSt; i<CountEn; i++)
xue@1 406 {
xue@1 407 double lea=a0+i*(a1+i*(a2+i*a3));
xue@1 408 double lph=p0+i*(p1+i*(p2+i*(p3+i*p4)));
xue@1 409 data[i]=exp(cdouble(lea, lph));
xue@1 410 }
xue@1 411 ph=p0+CountEn*(p1+CountEn*(p2+CountEn*(p3+CountEn*p4)));
xue@1 412 }//SinusoidExpA
xue@1 413
Chris@5 414 /**
xue@1 415 function SinusoidExpA: synthesizes complex sinusoid whose log amplitude and frequency are trinomials
xue@1 416 with phase angle specified at both ends.
xue@1 417
xue@7 418 In: T
xue@1 419 a3, a2, a1, a0: trinomial coefficients for log amplitude
xue@1 420 omg3, omg2, omg1, omg0: trinomial coefficients for angular frequency
xue@1 421 ph0, ph2: phase angles at 0 and CountEn.
xue@1 422 add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output buffer
xue@7 423 Out: data[T]: output buffer.
xue@1 424
xue@1 425 No return value.
xue@1 426 */
xue@7 427 void SinusoidExpA(int T, cdouble* data, double a3, double a2, double a1, double a0,
xue@1 428 double omg3, double omg2, double omg1, double omg0, double ph0, double ph2, bool add)
xue@1 429 {
xue@1 430 double p0=ph0, p1=omg0, p2=0.5*omg1, p3=omg2/3, p4=omg3/4;
xue@7 431 double pend=p0+T*(p1+T*(p2+T*(p3+T*p4)));
xue@1 432
xue@1 433 int k=floor((pend-ph2)/2/M_PI+0.5);
xue@1 434 double d=ph2-pend+2*M_PI*k;
xue@7 435 double _p=-2*d/T/T/T;
xue@7 436 double _q=3*d/T/T;
xue@1 437
xue@7 438 if (add) for (int i=0; i<T; i++)
xue@1 439 {
xue@1 440 double lea=a0+i*(a1+i*(a2+i*a3));
xue@1 441 double lph=p0+i*(p1+i*(p2+i*(p3+i*p4)));
xue@1 442 data[i]+=exp(cdouble(lea, lph+(i*i*(_q+i*_p))));
xue@1 443 }
xue@7 444 else for (int i=0; i<T; i++)
xue@1 445 {
xue@1 446 double lea=a0+i*(a1+i*(a2+i*a3));
xue@1 447 double lph=p0+i*(p1+i*(p2+i*(p3+i*p4)));
xue@1 448 data[i]=exp(cdouble(lea, lph+(i*i*(_q+i*_p))));
xue@1 449 }
xue@1 450 }//SinusoidExpA
xue@1 451
Chris@5 452 /**
xue@1 453 function SinusoidExpA: synthesizes complex sinusoid piece whose log amplitude is h[M]'p[M] and
xue@1 454 frequency is h[M]'q[M]. This version also synthesizes its derivative.
xue@1 455
xue@1 456 In: h[M][T], dh[M][T], dih[M][T]: basis functions and their derivatives and difference-integrals
xue@1 457 p[M], q[M]: real and imaginary parts of coefficients of h[M]
xue@1 458 tmpph: inital phase angle at 0
xue@1 459 Out: s[T], ds[T]: synthesized sinusoid and its derivative
xue@1 460 tmpph: phase angle at T
xue@1 461
xue@1 462 No return value.
xue@1 463 */
xue@1 464 void SinusoidExpA(int T, cdouble* s, cdouble* ds, int M, double* p, double* q, double** h, double** dh, double** dih, double& tmpph)
xue@1 465 {
xue@1 466 for (int t=0; t<T; t++)
xue@1 467 {
xue@1 468 double e=0, dph=0, drr=0, dri=0;
xue@1 469 for (int m=0; m<M; m++) e+=p[m]*h[m][t], dph+=q[m]*dih[m][t], drr+=p[m]*dh[m][t], dri+=q[m]*h[m][t];
xue@1 470 s[t]=exp(cdouble(e, tmpph));
xue@1 471 ds[t]=s[t]*cdouble(drr, dri);
xue@1 472 tmpph+=dph;
xue@1 473 }
xue@1 474 }//SinusoidExpA
xue@1 475
Chris@5 476 /**
xue@1 477 function SinusoidExpA: synthesizes complex sinusoid piece whose log amplitude is h[M]'p[M] and
xue@1 478 frequency is h[M]'q[M]. This version does not synthesize its derivative.
xue@1 479
xue@1 480 In: h[M][T], dih[M][T]: basis functions and their difference-integrals
xue@1 481 p[M], q[M]: real and imaginary parts of coefficients of h[M]
xue@1 482 tmpph: inital phase angle at 0
xue@1 483 Out: s[T]: synthesized sinusoid
xue@1 484 tmpph: phase angle at T
xue@1 485
xue@1 486 No return value.
xue@1 487 */
xue@1 488 void SinusoidExpA(int T, cdouble* s, int M, double* p, double* q, double** h, double** dih, double& tmpph)
xue@1 489 {
xue@1 490 for (int t=0; t<T; t++)
xue@1 491 {
xue@1 492 double e=0, dph=0;
xue@1 493 for (int m=0; m<M; m++) e+=p[m]*h[m][t], dph+=q[m]*dih[m][t];
xue@1 494 s[t]=exp(cdouble(e, tmpph));
xue@1 495 tmpph+=dph;
xue@1 496 }
xue@1 497 }//SinusoidExpA
xue@1 498
Chris@5 499 /**
xue@1 500 function SinusoidExpA: synthesizes complex sinusoid piece whose log amplitude is h[M]'p[M] and
xue@1 501 frequency is h[M]'q[M] with phase angle specified at both ends. This version does not synthesize its
xue@1 502 derivative.
xue@1 503
xue@1 504 In: h[M][T], dih[M][T]: basis functions and their difference-integrals
xue@1 505 p[M], q[M]: real and imaginary parts of coefficients of h[M]
xue@1 506 ph1, ph2: phase angles at 0 and T.
xue@1 507 Out: s[T]: synthesized sinusoid
xue@1 508
xue@1 509 No return value.
xue@1 510 */
xue@1 511 void SinusoidExpA(int T, cdouble* s, int M, double* p, double* q, double** h, double** dih, double ph1, double ph2)
xue@1 512 {
xue@1 513 double pend=ph1;
xue@1 514 for (int t=0; t<T; t++)
xue@1 515 {
xue@1 516 double dph=0;
xue@1 517 for (int m=0; m<M; m++) dph+=q[m]*dih[m][t];
xue@1 518 pend+=dph;
xue@1 519 }
xue@1 520
xue@1 521 int k=floor((pend-ph2)/2/M_PI+0.5);
xue@1 522 double d=ph2-pend+2*M_PI*k;
xue@1 523 double _p=-2*d/T/T/T;
xue@1 524 double _q=3*d/T/T;
xue@1 525
xue@1 526 double ph=ph1;
xue@1 527 for (int t=0; t<T; t++)
xue@1 528 {
xue@1 529 double e=0, dph=0;
xue@1 530 for (int m=0; m<M; m++) e+=p[m]*h[m][t], dph+=q[m]*dih[m][t];
xue@1 531 if (e>300) e=300;
xue@1 532 if (e<-300) e=-300;
xue@1 533 s[t]=exp(cdouble(e, ph+(t*t*(_q+t*_p))));
xue@1 534 ph+=dph;
xue@1 535 }
xue@1 536 }//SinusoidExpA
xue@1 537
xue@1 538 /*
xue@1 539 //This is not used any longer as the recursion does not seem to help saving computation with all its overheads.
xue@1 540 void SinusoidExp(cdouble* data, int CountSt, int CountEn, double a3, double a2, double a1, double a0,
xue@1 541 double omg3, double omg2, double omg1, double omg0, double &ea, double &ph, bool add)
xue@1 542 {
xue@1 543 int i;
xue@1 544 double dea, ddea, dddea, ddddea,
xue@1 545 dph, ddph, dddph, ddddph,
xue@1 546 sph, cph, sdph, cdph, sddph, cddph, sdddph, cdddph, sddddph, cddddph,
xue@1 547 e0=ea, e1=a0, e2=0.5*a1, e3=a2/3, e4=a3/4,
xue@1 548 p0=ph, p1=omg0, p2=0.5*omg1, p3=omg2/3, p4=omg3/4, tmp;
xue@1 549 if (CountSt==0)
xue@1 550 {
xue@1 551 dea=e1+e2+e3+e4; ddea=2*e2+6*e3+14*e4; dddea=6*e3+36*e4; ddddea=24*e3;
xue@1 552 dph=p1+p2+p3+p4; ddph=2*p2+6*p3+14*p4; dddph=6*p3+36*p4; ddddph=24*p4;
xue@1 553 }
xue@1 554 else
xue@1 555 {
xue@1 556 ea=e0+CountSt*(e1+CountSt*(e2+CountSt*(e3+CountSt*e4)));
xue@1 557 dea=e1+e2+e3+e4+CountSt*(2*e2+3*e3+4*e4+CountSt*(3*e3+6*e4+CountSt*4*e4));
xue@1 558 ddea=2*e2+6*e3+14*e4+CountSt*(6*e3+24*e4+CountSt*12*e4);
xue@1 559 dddea=6*e3+36*e4+CountSt*24*e4; ddddea=24*e4;
xue@1 560 ph=p0+CountSt*(p1+CountSt*(p2+CountSt*(p3+CountSt*p4)));
xue@1 561 dph=p1+p2+p3+p4+CountSt*(2*p2+3*p3+4*p4+CountSt*(3*p3+6*p4+CountSt*4*p4));
xue@1 562 ddph=2*p2+6*p3+14*p4+CountSt*(6*p3+24*p4+CountSt*12*p4);
xue@1 563 dddph=6*p3+36*p4+CountSt*24*p4; ddddph=24*p4;
xue@1 564 }
xue@1 565 sph=sin(ph), cph=cos(ph);
xue@1 566 sdph=sin(dph), cdph=cos(dph);
xue@1 567 sddph=sin(ddph), cddph=cos(ddph);
xue@1 568 sdddph=sin(dddph), cdddph=cos(dddph);
xue@1 569 sddddph=sin(ddddph), cddddph=cos(ddddph);
xue@1 570 if (add)
xue@1 571 {
xue@1 572 for (i=CountSt; i<CountEn; i++)
xue@1 573 {
xue@1 574 data[i]+=exp(ea)*cdouble(cph, sph);
xue@1 575 ea=ea+dea; dea=dea+ddea; ddea=ddea+dddea; dddea+dddea+ddddea;
xue@1 576 tmp=cph*cdph-sph*sdph; sph=sph*cdph+cph*sdph; cph=tmp;
xue@1 577 tmp=cdph*cddph-sdph*sddph; sdph=sdph*cddph+cdph*sddph; cdph=tmp;
xue@1 578 tmp=cddph*cdddph-sddph*sdddph; sddph=sddph*cdddph+cddph*sdddph; cddph=tmp;
xue@1 579 tmp=cdddph*cddddph-sdddph*sddddph; sdddph=sdddph*cddddph+cdddph*sddddph; cdddph=tmp;
xue@1 580 }
xue@1 581 }
xue@1 582 else
xue@1 583 {
xue@1 584 for (i=CountSt; i<CountEn; i++)
xue@1 585 {
xue@1 586 data[i]=exp(ea)*cdouble(cph, sph);
xue@1 587 ea=ea+dea; dea=dea+ddea; ddea=ddea+dddea; dddea+dddea+ddddea;
xue@1 588 tmp=cph*cdph-sph*sdph; sph=sph*cdph+cph*sdph; cph=tmp;
xue@1 589 tmp=cdph*cddph-sdph*sddph; sdph=sdph*cddph+cdph*sddph; cdph=tmp;
xue@1 590 tmp=cddph*cdddph-sddph*sdddph; sddph=sddph*cdddph+cddph*sdddph; cddph=tmp;
xue@1 591 tmp=cdddph*cddddph-sdddph*sddddph; sdddph=sdddph*cddddph+cdddph*sddddph; cdddph=tmp;
xue@1 592 }
xue@1 593 }
xue@1 594 ea=e0+CountEn*(e1+CountEn*(e2+CountEn*(e3+CountEn*e4)));
xue@1 595 ph=p0+CountEn*(p1+CountEn*(p2+CountEn*(p3+CountEn*p4)));
xue@1 596 } //*/
xue@1 597
xue@1 598
Chris@5 599 /**
xue@1 600 function Sinusoids: recursive harmonic multi-sinusoid generator
xue@1 601
xue@1 602 In: st, en
xue@1 603 M: number of partials
xue@1 604 a3[M], a2[M], a1[M], a0[M]: trinomial coefficients for partial amplitudes
xue@1 605 f3, f2, f1, f0: trinomial coefficients for fundamental frequency
xue@1 606 ph[M]: partial phases at 0.
xue@1 607 add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output buffer
xue@1 608 Out: data[st:en-1]: output buffer.
xue@1 609 ph[M]: partial phases at en.
xue@1 610
xue@1 611 No return value.
xue@1 612 */
xue@1 613 void Sinusoids(int M, double* data, int st, int en, double* a3, double* a2, double* a1, double* a0, double f3, double f2, double f1, double f0, double* ph, bool add)
xue@1 614 {
xue@1 615 double dph, ddph, dddph, ddddph;
xue@1 616 double sdph, cdph, cdph2, sddph, cddph, sdddph, cdddph, sddddph, cddddph, sdmph, cdmph, sdm_1ph, cdm_1ph;
xue@1 617 double p0, p1, p2, p3, p4, tmp, tmp2;
xue@1 618 double *a=(double*)malloc8(sizeof(double)*M*6), *da=&a[M], *dda=&a[M*2], *ddda=&a[M*3],
xue@1 619 *sph=&a[M*4], *cph=&a[M*5];
xue@1 620
xue@1 621 for (int m=0; m<M; m++)
xue@1 622 {
xue@1 623 p0=ph[m], p1=2*M_PI*f0, p2=M_PI*f1, p3=2.0*M_PI*f2/3, p4=2.0*M_PI*f3/4;
xue@1 624 if (st==0)
xue@1 625 {
xue@1 626 a[m]=a0[m]; da[m]=a1[m]+a2[m]+a3[m]; dda[m]=2*a2[m]+6*a3[m]; ddda[m]=6*a3[m];
xue@1 627 }
xue@1 628 else
xue@1 629 {
xue@1 630 a[m]=a0[m]+st*(a1[m]+st*(a2[m]+st*a3[m]));
xue@1 631 da[m]=a1[m]+a2[m]+a3[m]+st*(2*a2[m]+3*a3[m]+st*3*a3[m]);
xue@1 632 dda[m]=2*a2[m]+6*a3[m]+st*6*a3[m]; ddda[m]=6*a3[m];
xue@1 633 ph[m]=p0+st*(p1+st*(p2+st*(p3+st*p4)));
xue@1 634 }
xue@1 635 sph[m]=sin(ph[m]), cph[m]=cos(ph[m]);
xue@1 636 ph[m]=p0+(m+1)*en*(p1+en*(p2+en*(p3+en*p4)));
xue@1 637 }
xue@1 638
xue@1 639 if (st==0)
xue@1 640 {
xue@1 641 dph=p1+p2+p3+p4; ddph=2*p2+6*p3+14*p4; dddph=6*p3+36*p4; ddddph=24*p4;
xue@1 642 }
xue@1 643 else
xue@1 644 {
xue@1 645 dph=p1+p2+p3+p4+st*(2*p2+3*p3+4*p4+st*(3*p3+6*p4+st*4*p4));
xue@1 646 ddph=2*p2+6*p3+14*p4+st*(6*p3+24*p4+st*12*p4);
xue@1 647 dddph=6*p3+36*p4+st*24*p4; ddddph=24*p4;
xue@1 648 }
xue@1 649 sdph=sin(dph), cdph=cos(dph);
xue@1 650 sddph=sin(ddph), cddph=cos(ddph);
xue@1 651 sdddph=sin(dddph), cdddph=cos(dddph);
xue@1 652 sddddph=sin(ddddph), cddddph=cos(ddddph);
xue@1 653
xue@1 654 if (add)
xue@1 655 {
xue@1 656 for (int i=st; i<en; i++)
xue@1 657 {
xue@1 658 data[i]+=a[0]*cph[0]; a[0]+=da[0]; da[0]+=dda[0]; dda[0]+=ddda[0];
xue@1 659 tmp=cph[0]*cdph-sph[0]*sdph; sph[0]=sph[0]*cdph+cph[0]*sdph; cph[0]=tmp;
xue@1 660 cdm_1ph=1, sdm_1ph=0, cdmph=cdph, sdmph=sdph, cdph2=2*cdph;
xue@1 661
xue@1 662 for (int m=1; m<M; m++)
xue@1 663 {
xue@1 664 data[i]+=a[m]*cph[m]; a[m]+=da[m]; da[m]+=dda[m]; dda[m]+=ddda[m];
xue@1 665 // asm{mov ecx,m} asm{mov eax,a} asm{fld qword ptr [eax+ecx*8]} asm{mov edx,cph} asm{fld qword ptr [edx+ecx*8]} asm{fmul st(0),st(1)} asm{mov edx,data} asm{mov ebx,i} asm{fadd qword ptr [edx+ebx*8]} asm{fstp qword ptr [edx+ebx*8]} asm{mov edx,da} asm{fld qword ptr [edx+ecx*8]} asm{fadd st(1),st(0)} asm{mov ebx,dda} asm{fld qword ptr [ebx+ecx*8]} asm{fadd st(1),st(0)} asm{mov edi,ddda} asm{fadd qword ptr [edi+ecx*8]} asm{fstp qword ptr [ebx+ecx*8]} asm{fstp qword ptr [edx+ecx*8]} asm{fstp qword ptr [eax+ecx*8]}
xue@1 666 tmp=cdmph, tmp2=sdmph;
xue@1 667 cdmph=cdmph*cdph2-cdm_1ph; sdmph=sdmph*cdph2-sdm_1ph;
xue@1 668 cdm_1ph=tmp, sdm_1ph=tmp2;
xue@1 669
xue@1 670 tmp=cph[m]*cdmph-sph[m]*sdmph; sph[m]=sph[m]*cdmph+cph[m]*sdmph; cph[m]=tmp;
xue@1 671 // asm{mov ecx,m} asm{mov eax,cph} asm{fld qword ptr [eax+ecx*8]} asm{mov edx,sph} asm{fld qword ptr [edx+ecx*8]} asm{fld st(1)} asm{fmul sdmph} asm{fld st(1)} asm{fmul sdmph} asm{fld cdmph} asm{fmul st(4),st(0)} asm{fmulp st(3),st(0)} asm{fsubp st(3),st(0)} asm{faddp} asm{fstp qword ptr [edx+ecx*8]} asm{fstp qword ptr [eax+ecx*8]}
xue@1 672 }
xue@1 673
xue@1 674 tmp=cdph*cddph-sdph*sddph; sdph=sdph*cddph+cdph*sddph; cdph=tmp;
xue@1 675 tmp=cddph*cdddph-sddph*sdddph; sddph=sddph*cdddph+cddph*sdddph; cddph=tmp;
xue@1 676 tmp=cdddph*cddddph-sdddph*sddddph; sdddph=sdddph*cddddph+cdddph*sddddph; cdddph=tmp;
xue@1 677 }
xue@1 678 }
xue@1 679 else
xue@1 680 {
xue@1 681 }
xue@1 682 free8(a);
xue@1 683 }//Sinusoids*/
xue@1 684
Chris@5 685 /**
xue@1 686 function Sinusoid: synthesizes sinusoid piece from trinomial frequency and amplitude coefficients.
xue@1 687
xue@7 688 In: T
xue@1 689 aa, ab, ac, ad: trinomial coefficients of amplitude.
xue@1 690 fa, fb, fc, fd: trinomial coefficients of frequency.
xue@1 691 ph0, ph2: phase angles at 0 and CountEn.
xue@1 692 add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output buffer
xue@7 693 Out: data[T]: output buffer.
xue@1 694
xue@1 695 No return value.
xue@1 696 */
xue@7 697 void Sinusoid(int T, double* data, double aa, double ab, double ac, double ad,
xue@1 698 double fa, double fb, double fc, double fd, double ph0, double ph2, bool add)
xue@1 699 {
xue@7 700 double pend=ph0+2*M_PI*T*(fd+T*(fc/2+T*(fb/3+T*fa/4)));
xue@1 701 int k=floor((pend-ph2)/2/M_PI+0.5);
xue@1 702 double d=ph2-pend+2*M_PI*k;
xue@7 703 double p=-2*d/T/T/T;
xue@7 704 double q=3*d/T/T, a, ph;
xue@7 705 for (int i=0; i<T; i++)
xue@1 706 {
xue@1 707 a=ad+i*(ac+i*(ab+i*aa)); if (a<0) a=0;
xue@1 708 ph=ph0+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)))+i*i*(q+i*p);
xue@1 709 if (add) data[i]+=a*cos(ph);
xue@1 710 else data[i]=a*cos(ph);
xue@1 711 }
xue@1 712 }//Sinusoid
xue@1 713
Chris@5 714 /**
xue@1 715 function Sinusoid: synthesizes sinusoid piece from trinomial frequency and amplitude coefficients,
xue@1 716 returning sinusoid coefficients instead of waveform.
xue@1 717
xue@7 718 In: T
xue@1 719 aa, ab, ac, ad: trinomial coefficients of amplitude (or log amplitude if LogA=true)
xue@1 720 fa, fb, fc, fd: trinomial coefficients of frequency.
xue@1 721 ph0, ph2: phase angles at 0 and CountEn.
xue@1 722 LogA: specifies whether log amplitude or amplitude is a trinomial
xue@1 723 Out: f[CountSt:CountEn-1], a[CountSt:CountEn-1], ph[CountSt:CountEn-1]: synthesized sinusoid parameters
xue@1 724 da[CountSt:CountEn-1]: derivative of synthesized amplitude, optional
xue@1 725
xue@1 726 No return value.
xue@1 727 */
xue@7 728 void Sinusoid(int T, double* f, double* a, double* ph, double* da, double aa, double ab,
xue@1 729 double ac, double ad, double fa, double fb, double fc, double fd, double ph0, double ph2, bool LogA)
xue@1 730 {
xue@7 731 double pend=ph0+2*M_PI*T*(fd+T*(fc/2+T*(fb/3+T*fa/4)));
xue@1 732 int k=floor((pend-ph2)/2/M_PI+0.5);
xue@1 733 double d=ph2-pend+2*M_PI*k;
xue@7 734 double p=-2*d/T/T/T;
xue@7 735 double q=3*d/T/T;
xue@7 736 if (LogA) for (int i=0; i<T; i++)
xue@1 737 {
xue@1 738 a[i]=exp(ad+i*(ac+i*(ab+i*aa)));
xue@1 739 if (da) da[i]=a[i]*(ac+i*(2*ab+i*3*aa));
xue@1 740 f[i]=fd+i*(fc+i*(fb+i*fa))+i*(2*q+3*i*p)/(2*M_PI);
xue@1 741 ph[i]=ph0+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)))+i*i*(q+i*p);
xue@1 742 }
xue@7 743 else for (int i=0; i<T; i++)
xue@1 744 {
xue@1 745 a[i]=ad+i*(ac+i*(ab+i*aa));
xue@1 746 if (da) da[i]=ac+i*(2*ab+i*3*aa);
xue@1 747 f[i]=fd+i*(fc+i*(fb+i*fa))+i*(2*q+3*i*p)/(2*M_PI);
xue@1 748 ph[i]=ph0+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)))+i*i*(q+i*p);
xue@1 749 }
xue@1 750 }//Sinusoid
xue@1 751
Chris@5 752 /**
xue@1 753 function Sinusoid: generates trinomial frequency and phase with phase correction.
xue@1 754
xue@7 755 In: T
xue@1 756 fa, fb, fc, fd: trinomial coefficients of frequency.
xue@1 757 ph0, ph2: phase angles at 0 and CountEn.
xue@7 758 Out: f[T], ph[T]: output buffers holding frequency and phase.
xue@1 759
xue@1 760 No return value.
xue@1 761 */
xue@7 762 void Sinusoid(int T, double* f, double* ph, double fa, double fb,
xue@1 763 double fc, double fd, double ph0, double ph2)
xue@1 764 {
xue@7 765 double pend=ph0+2*M_PI*T*(fd+T*(fc/2+T*(fb/3+T*fa/4)));
xue@1 766 int k=floor((pend-ph2)/2/M_PI+0.5);
xue@1 767 double d=ph2-pend+2*M_PI*k;
xue@7 768 double p=-2*d/T/T/T;
xue@7 769 double q=3*d/T/T;
xue@7 770 for (int i=0; i<T; i++)
xue@1 771 {
xue@1 772 f[i]=fd+i*(fc+i*(fb+i*fa))+i*(2*q+3*i*p)/(2*M_PI);
xue@1 773 ph[i]=ph0+2*M_PI*i*(fd+i*((fc/2)+i*((fb/3)+i*fa/4)))+i*i*(q+i*p);
xue@1 774 }
xue@1 775 }//Sinusoid
xue@1 776
Chris@5 777 /**
xue@1 778 function SynthesizeSinusoid: synthesizes a time-varying sinusoid from a sequence of frequencies and amplitudes
xue@1 779
xue@1 780 In: xs[Fr]: measurement points, should be integers although *xs has double type.
xue@1 781 fs[Fr], as[Fr]: sequence of frequencies and amplitudes at xs[Fr]
xue@1 782 phs[0]: initial phase angle at (int)xs[0].
xue@1 783 dst, den: start and end time of synthesis, dst<=xs[0], den>=xs[Fr-1]
xue@1 784 add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output buffer
xue@1 785 Out: xrec[0:den-dst-1]: output buffer hosting synthesized sinusoid from dst to den.
xue@1 786 phs[Fr]: phase angles at xs[Fr]
xue@1 787
xue@1 788 Returns pointer to xrec.
xue@1 789 */
xue@1 790 double* SynthesizeSinusoid(double* xrec, int dst, int den, double* phs, int Fr, double* xs, double* fs, double* as, bool add, bool* terminatetag)
xue@1 791 {
xue@1 792 double *f3=new double[Fr*8], *f2=&f3[Fr], *f1=&f3[Fr*2], *f0=&f3[Fr*3],
xue@1 793 *a3=&f3[Fr*4], *a2=&a3[Fr], *a1=&a3[Fr*2], *a0=&a3[Fr*3];
xue@1 794 CubicSpline(Fr-1, f3, f2, f1, f0, xs, fs, 1, 1);
xue@1 795 CubicSpline(Fr-1, a3, a2, a1, a0, xs, as, 1, 1);
xue@1 796 double ph=phs[0];
xue@1 797 for (int fr=0; fr<Fr-1; fr++)
xue@1 798 {
xue@1 799 phs[fr]=ph;
xue@1 800 ALIGN8(Sinusoid(&xrec[(int)xs[fr]-dst], 0, xs[fr+1]-xs[fr], a3[fr], a2[fr], a1[fr], a0[fr], f3[fr], f2[fr], f1[fr], f0[fr], ph, add);)
xue@1 801 if (terminatetag && *terminatetag) {delete[] f3; return 0;}
xue@1 802 }
xue@11 803 phs[Fr-1]=ph; ph=phs[Fr-2];
xue@1 804 ALIGN8(Sinusoid(&xrec[(int)xs[Fr-2]-dst], xs[Fr-1]-xs[Fr-2], den-xs[Fr-2], a3[Fr-2], a2[Fr-2], a1[Fr-2], a0[Fr-2], f3[Fr-2], f2[Fr-2], f1[Fr-2], f0[Fr-2], ph, add);
xue@1 805 Sinusoid(&xrec[(int)xs[0]-dst], dst-xs[0], 0, a3[0], a2[0], a1[0], a0[0], f3[0], f2[0], f1[0], f0[0], phs[0], add);)
xue@1 806 delete[] f3;
xue@1 807 return xrec;
xue@1 808 }//SynthesizeSinusoid
xue@1 809
Chris@5 810 /**
xue@1 811 function ShiftTrinomial: shifts the origin of a trinomial from 0 to T
xue@1 812
xue@1 813 In: a3, a2, a1, a0.
xue@1 814 Out: b3, b2, b1, b0, so that a3*x^3+a2*x^2+a1*x+a0=b3(x-T)^3+b2(x-T)^2+b1(x-T)+b0
xue@1 815
xue@1 816 No return value.
xue@1 817 */
xue@1 818 void ShiftTrinomial(double T, double& b3, double& b2, double& b1, double& b0, double a3, double a2, double a1, double a0)
xue@1 819 {
xue@1 820 b3=a3;
xue@1 821 b2=a2+T*3*b3;
xue@1 822 b1=a1+T*(2*b2-T*3*b3);
xue@1 823 b0=a0+T*(b1-T*(b2-T*b3));
xue@1 824 }//ShiftTrinomial
xue@1 825
Chris@5 826 /**
xue@1 827 function SynthesizeSinusoidP: synthesizes a time-varying sinusoid from a sequence of frequencies,
xue@1 828 amplitudes and phase angles
xue@1 829
xue@1 830 In: xs[Fr]: measurement points, should be integers although *xs has double type.
xue@1 831 fs[Fr], as[Fr], phs[Fr]: sequence of frequencies, amplitudes and phase angles at xs[Fr]
xue@1 832 dst, den: start and end time of synthesis, dst<=xs[0], den>=xs[Fr-1]
xue@1 833 add: specifies if the resynthesized sinusoid is to be added to or to replace the content of output
xue@1 834 buffer
xue@1 835 Out: xrecm[0:den-dst-1]: output buffer hosting synthesized sinusoid from dst to den.
xue@1 836
xue@1 837 Returns pointer to xrecm.
xue@1 838 */
xue@1 839 double* SynthesizeSinusoidP(double* xrecm, int dst, int den, double* phs, int Fr, double* xs, double* fs, double* as, bool add)
xue@1 840 {
xue@1 841 double *f3=new double[Fr*8], *f2=&f3[Fr], *f1=&f3[Fr*2], *f0=&f3[Fr*3],
xue@1 842 *a3=&f3[Fr*4], *a2=&a3[Fr], *a1=&a3[Fr*2], *a0=&a3[Fr*3];
xue@1 843 CubicSpline(Fr-1, f3, f2, f1, f0, xs, fs, 1, 1);
xue@1 844 CubicSpline(Fr-1, a3, a2, a1, a0, xs, as, 1, 1);
xue@7 845 for (int fr=0; fr<Fr-1; fr++) Sinusoid(xs[fr+1]-xs[fr], &xrecm[(int)xs[fr]-dst], a3[fr], a2[fr], a1[fr], a0[fr], f3[fr], f2[fr], f1[fr], f0[fr], phs[fr], phs[fr+1], add);
xue@1 846 double tmpph=phs[0]; Sinusoid(&xrecm[(int)xs[0]-dst], dst-xs[0], 0, 0, 0, 0, a0[0], f3[0], f2[0], f1[0], f0[0], tmpph, add);
xue@1 847 //extend the trinomials on [xs[Fr-2], xs[Fr-1]) based at xs[Fr-2] to beyond xs[Fr-1] based at xs[Fr-1].
xue@1 848 tmpph=phs[Fr-1];
xue@1 849 ShiftTrinomial(xs[Fr-1]-xs[Fr-2], f3[Fr-1], f2[Fr-1], f1[Fr-1], f0[Fr-1], f3[Fr-2], f2[Fr-2], f1[Fr-2], f0[Fr-2]);
xue@1 850 ShiftTrinomial(xs[Fr-1]-xs[Fr-2], a3[Fr-1], a2[Fr-1], a1[Fr-1], a0[Fr-1], a3[Fr-2], a2[Fr-2], a1[Fr-2], a0[Fr-2]);
xue@1 851 Sinusoid(&xrecm[(int)xs[Fr-1]-dst], 0, den-xs[Fr-1], 0, 0, 0, a0[Fr-1], f3[Fr-1], f2[Fr-1], f1[Fr-1], f0[Fr-1], tmpph, add);
xue@1 852 delete[] f3;
xue@1 853 return xrecm;
xue@1 854 }//SynthesizeSinusoidP