annotate sinsyn.cpp @ 7:9b1c0825cc77

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