annotate vibrato.cpp @ 5:5f3c32dc6e17

* Adjust comment syntax to permit Doxygen to generate HTML documentation; add Doxyfile
author Chris Cannam
date Wed, 06 Oct 2010 15:19:49 +0100
parents fc19d45615d1
children 977f541d6683
rev   line source
xue@1 1 //---------------------------------------------------------------------------
xue@1 2
xue@1 3 #include <math.h>
Chris@2 4 #include <string.h>
xue@1 5 #include "vibrato.h"
xue@1 6 #include "arrayalloc.h"
xue@1 7 #include "fft.h"
xue@1 8 #include "hssf.h"
Chris@2 9 #include "matrix.h"
xue@1 10 #include "splines.h"
xue@1 11 #include "xcomplex.h"
Chris@5 12
Chris@5 13 /** \file vibrato.h */
Chris@5 14
xue@1 15 //---------------------------------------------------------------------------
xue@1 16 //method TVo::TVo: default constructor
xue@1 17 TVo::TVo()
xue@1 18 {
xue@1 19 memset(this, 0, sizeof(TVo));
xue@1 20 afres=8192;
xue@1 21 }//TVo
xue@1 22
xue@1 23 //method TVo::~TVo: default destructor
xue@1 24 TVo::~TVo()
xue@1 25 {
xue@1 26 free(peakfr);
xue@1 27 delete[] lp;
xue@1 28 delete[] F0;
xue@1 29 if (fxr) DeAlloc2(fxr);
xue@1 30 if (fres) DeAlloc2(fres);
xue@1 31 if (LogASp) DeAlloc2(LogASp);
xue@1 32 }//~TVo
xue@1 33
Chris@5 34 /**
xue@1 35 method TVo::AllocateL: allocates or reallocates storage space whose size depends on L. This uses an
xue@1 36 external L value for allocation and updates L itself.
xue@1 37 */
xue@1 38 void TVo::AllocateL(int AnL)
xue@1 39 {
xue@1 40 L=AnL;
xue@1 41 delete[] F0;
xue@1 42 F0=new double[(L+2)*4];
xue@1 43 F0C=&F0[L+2], F0D=&F0[(L+2)*2], A0C=&F0[(L+2)*3];
xue@1 44 }//AllocateL
xue@1 45
Chris@5 46 /**
xue@1 47 method TVo::AllocateP: allocates or reallocates storage space whose size depends on P, using the
xue@1 48 interal P.
xue@1 49 */
xue@1 50 void TVo::AllocateP()
xue@1 51 {
xue@1 52 peakfr=(int*)realloc(peakfr, sizeof(int)*P);
xue@1 53 delete[] lp; lp=new double[(P+2)*3];
xue@1 54 Dp=&lp[P+2];
xue@1 55 Kp=(int*)&lp[(P+2)*2];
xue@1 56 if (LogASp) DeAlloc2(LogASp); Allocate2(double, P, M, LogASp);
xue@1 57 }//AllocateP
xue@1 58
Chris@5 59 /**
xue@1 60 method TVo::AllocatePK: allocates or reallocates storage space whose size depends on both P and K.
xue@1 61 */
xue@1 62 void TVo::AllocatePK()
xue@1 63 {
xue@1 64 if (fxr) DeAlloc2(fxr);
xue@1 65 Allocate2(double, P, 2*K+1, fxr);
xue@1 66 memset(fxr[0], 0, sizeof(double)*P*(2*K+1));
xue@1 67 if (fres) DeAlloc2(fres);
xue@1 68 Allocate2(double, P, K, fres);
xue@1 69 }//AllocatePK
xue@1 70
Chris@5 71 /**
xue@1 72 method TVo::GetOldP: returns the number of "equivalent" cycles of the whole duration. Although P-1
xue@1 73 cycles are delineated by lp[P], the parts before lp[0] and after lp[P-1] are also a part of the
xue@1 74 harmonic sinusoid being modeled and therefore should be taken into account when necessary.
xue@1 75 */
xue@1 76 double TVo::GetOldP()
xue@1 77 {
xue@1 78 return P-1+lp[0]/(lp[1]-lp[0])+(L-lp[P-1])/(lp[P-1]-lp[P-2]);
xue@1 79 }//GetOldP
xue@1 80
Chris@5 81 /**
xue@1 82 methodTVo::LoadFromFileHandle: reads TVo object from a file stream.
xue@1 83 */
xue@1 84 void TVo::LoadFromFileHandle(FILE* file)
xue@1 85 {
xue@1 86 fread(&M, sizeof(int), 1, file);
xue@1 87 fread(&L, sizeof(int), 1, file);
xue@1 88 fread(&P, sizeof(int), 1, file);
xue@1 89 fread(&K, sizeof(int), 1, file);
xue@1 90 fread(&h, sizeof(double), 1, file);
xue@1 91 fread(&afres, sizeof(int), 1, file);
xue@1 92 AllocateL(L); AllocateP(); AllocatePK();
xue@1 93 fread(F0C, sizeof(double), L, file);
xue@1 94 fread(A0C, sizeof(double), L, file);
xue@1 95 fread(LogAF, sizeof(double), 4096, file);
xue@1 96 fread(peakfr, sizeof(int), P, file);
xue@1 97 fread(lp, sizeof(double), P, file);
xue@1 98 fread(Dp, sizeof(double), P, file);
xue@1 99 fread(Kp, sizeof(int), P, file);
xue@1 100 fread(fxr[0], sizeof(double), P*(2*K+1), file);
xue@1 101 fread(LogASp[0], sizeof(double), P*M, file);
xue@1 102 }//LoadFromFileHandle
xue@1 103
Chris@5 104 /**
xue@1 105 method TVo::ReAllocateL: reallocates storage space whose size depends on L, and transfer the contents.
xue@1 106 This uses an external L value for allocation but does not update L itself.
xue@1 107 */
xue@1 108 void TVo::ReAllocateL(int newL)
xue@1 109 {
xue@1 110 double* newF0=new double[(newL+2)*4];
xue@1 111 F0C=&newF0[newL+2], F0D=&newF0[(newL+2)*2], A0C=&newF0[(newL+2)*3];
xue@1 112 memcpy(A0C, &F0[(L+2)*3], sizeof(double)*(L+2));
xue@1 113 memcpy(F0D, &F0[(L+2)*2], sizeof(double)*(L+2));
xue@1 114 memcpy(F0C, &F0[L+2], sizeof(double)*(L+2));
xue@1 115 memcpy(newF0, F0, sizeof(double)*(L+2));
xue@1 116 delete[] F0;
xue@1 117 F0=newF0;
xue@1 118 }//ReAllocateL
xue@1 119
Chris@5 120 /**
xue@1 121 method TVo::SaveToFile: saves a TVo object to a file.
xue@1 122
xue@1 123 In: filename: path to the destination file.
xue@1 124 */
xue@1 125 void TVo::SaveToFile(char* filename)
xue@1 126 {
xue@1 127 FILE* file=fopen(filename, "wb");
xue@1 128 if (file)
xue@1 129 {
xue@1 130 SaveToFileHandle(file);
xue@1 131 fclose(file);
xue@1 132 }
xue@1 133 else
xue@1 134 {
xue@1 135 throw(strcat((char*)"Cannot open file ", filename));
xue@1 136 }
xue@1 137 }//SaveToFile
xue@1 138
Chris@5 139 /**
xue@1 140 method TVo::SaveToFileHandle: saves a TVo object to an open file stream.
xue@1 141 */
xue@1 142 void TVo::SaveToFileHandle(FILE* file)
xue@1 143 {
xue@1 144 fwrite(&M, sizeof(int), 1, file);
xue@1 145 fwrite(&L, sizeof(int), 1, file);
xue@1 146 fwrite(&P, sizeof(int), 1, file);
xue@1 147 fwrite(&K, sizeof(int), 1, file);
xue@1 148 fwrite(&h, sizeof(double), 1, file);
xue@1 149 fwrite(&afres, sizeof(int), 1, file);
xue@1 150 fwrite(F0C, sizeof(double), L, file);
xue@1 151 fwrite(A0C, sizeof(double), L, file);
xue@1 152 fwrite(LogAF, sizeof(double), 4096, file);
xue@1 153 fwrite(peakfr, sizeof(int), P, file);
xue@1 154 fwrite(lp, sizeof(double), P, file);
xue@1 155 fwrite(Dp, sizeof(double), P, file);
xue@1 156 fwrite(Kp, sizeof(int), P, file);
xue@1 157 fwrite(fxr[0], sizeof(double), P*(2*K+1), file);
xue@1 158 fwrite(LogASp[0], sizeof(double), P*M, file);
xue@1 159 }//SaveToFileHandle
xue@1 160
xue@1 161 //---------------------------------------------------------------------------
xue@1 162 //functions
xue@1 163
xue@1 164
Chris@5 165 /**
xue@1 166 function AnalyzeV: calculates all basic and non-basic descriptors of a vibrato from a harmonic
xue@1 167 sinusoid
xue@1 168
xue@1 169 In: HS: harmonic sinusoid to compute vibrato representation from
xue@1 170 sps: sampling rate
xue@1 171 h: hop size
xue@1 172 SFMode: specifies source-filter estimation criterion, 0=FB (filter bank), 1=SV (slow variation)
xue@1 173 SFF: filter response sampling interval
xue@1 174 SFScale: set if filter sampling uses mel scale
xue@1 175 SFtheta: balancing factor of amplitude and frequency variations, needed for SV approach
xue@1 176 Out: V: a TVo object hosting vibrato descriptors (vibrato representation) of HS
xue@1 177 cyclefrcount: number of cycles between cycle boundaries, equals V.P-1.
xue@1 178 cyclefrs[cyclefrcount], cyclefs[cyclefrcount]: time (in frames) and F0 centroid of cycles. These are
xue@1 179 knots from which V.F0C[] is interpolated.
xue@1 180 peaky[V.P]: shape score of cycle peaks
xue@1 181
xue@1 182 No return value.
xue@1 183 */
xue@1 184 void AnalyzeV(THS& HS, TVo& V, double*& peaky, double*& cyclefrs, double*& cyclefs, double sps, double h, int* cyclefrcount,
xue@1 185 int SFMode, double SFF, int SFFScale, double SFtheta)
xue@1 186 {
xue@1 187 int M=HS.M, Fr=HS.Fr;
xue@1 188 if (M<=0 || Fr<=0) return;
xue@1 189 atom** Partials=HS.Partials;
xue@1 190
xue@1 191 //basic descriptor: h
xue@1 192 V.h=h;
xue@1 193
xue@1 194 //demodulating pitch
xue@1 195 //Basic descriptor: L
xue@1 196 V.AllocateL(Fr);
xue@1 197
xue@1 198 double* AA=new double[Fr];
xue@1 199 //find the pitch track
xue@1 200 V.F0max=0, V.F0min=1;
xue@1 201 for (int fr=0; fr<Fr; fr++)
xue@1 202 {
xue@1 203 double suma2=0, suma2p=0;
xue@1 204 for (int m=0; m<M; m++)
xue@1 205 {
xue@1 206 double a=Partials[m][fr].a, p=Partials[m][fr].f/(m+1);
xue@1 207 if (p<=0) break;
xue@1 208 suma2+=a*a, suma2p+=a*a*p;
xue@1 209 }
xue@1 210 V.F0[fr]=suma2p/suma2;
xue@1 211 if (V.F0max<V.F0[fr]) V.F0max=V.F0[fr];
xue@1 212 if (V.F0min>V.F0[fr]) V.F0min=V.F0[fr];
xue@1 213 AA[fr]=suma2;
xue@1 214 }
xue@1 215
xue@1 216 //Basic descriptor: M
xue@1 217 V.M=0.45/V.F0max;
xue@1 218 if (V.M>M) V.M=M;
xue@1 219
xue@1 220 //rough estimation of rate
xue@1 221 double* f0d=new double[Fr-1]; for (int i=0; i<Fr-1; i++) f0d[i]=V.F0[i+1]-V.F0[i];
xue@1 222 RateAndReg(V.rate, V.regularity, f0d, 0, Fr-2, 8, sps, h);
xue@1 223 delete[] f0d;
xue@1 224
xue@1 225 //find peaks of the pitch track
xue@1 226 free(V.peakfr); V.peakfr=(int*)malloc(sizeof(int)*Fr/2);
xue@1 227 double periodinframe=sps/(V.rate*h);
xue@1 228 FindPeaks(V.peakfr, V.P, V.F0, Fr, periodinframe, peaky);
xue@1 229 if (V.P>=1) //de-modulation
xue@1 230 {
xue@1 231 //Basic descriptor: F0C[]
xue@1 232 DeFM(V.F0C, V.F0, AA, V.P, V.peakfr, Fr, V.F0Overall, *cyclefrcount, cyclefrs, cyclefs, true);
xue@1 233 //Basic descriptor: A0C[]
xue@1 234 DeAM(V.A0C, AA, V.P, V.peakfr, Fr);
xue@1 235 }
xue@1 236
xue@1 237 V.F0Cmax=0; V.F0Dmax=-1; V.F0Cmin=1; V.F0Dmin=1;
xue@1 238 for (int fr=0; fr<Fr; fr++)
xue@1 239 {
xue@1 240 if (V.F0Cmax<V.F0C[fr]) V.F0Cmax=V.F0C[fr];
xue@1 241 if (V.F0Cmin>V.F0C[fr]) V.F0Cmin=V.F0C[fr];
xue@1 242 V.F0D[fr]=V.F0[fr]-V.F0C[fr];
xue@1 243 }
xue@1 244
xue@1 245 V.D=0; int cyclestart=(V.P>=2)?V.peakfr[0]:0, cycleend=(V.P>=2)?V.peakfr[V.P-1]:Fr;
xue@1 246 for (int fr=cyclestart; fr<cycleend; fr++)
xue@1 247 {
xue@1 248 double lf0d=V.F0D[fr];
xue@1 249 if (V.F0Dmax<lf0d) V.F0Dmax=lf0d;
xue@1 250 if (V.F0Dmin>lf0d) V.F0Dmin=lf0d;
xue@1 251 V.D+=lf0d*lf0d;
xue@1 252 }
xue@1 253 V.D=sqrt(V.D/(cycleend-cyclestart));
xue@1 254 delete[] AA;
xue@1 255
xue@1 256 //Calculate rate and regularity
xue@1 257 //find the section used for calculating regularity and rate
xue@1 258 {
xue@1 259 int frst=0, fren=Fr-1;
xue@1 260 while (frst<fren && V.F0D[frst]*V.F0D[frst+1]>0) frst++;
xue@1 261 while (fren>frst && V.F0D[fren]*V.F0D[fren-1]>0) fren--;
xue@1 262
xue@1 263 RateAndReg(V.rate, V.regularity, V.F0D, frst, fren, 8, sps, h);
xue@1 264 }
xue@1 265
xue@1 266 //Basic descriptor: P
xue@1 267 //Basic descriptor: peakfr[]
xue@1 268 periodinframe=sps/(V.rate*h);
xue@1 269 FindPeaks(V.peakfr, V.P, V.F0D, Fr, periodinframe, peaky);
xue@1 270
xue@1 271 //Basic descriptor: lp[]
xue@1 272 V.AllocateP();
xue@1 273 for (int p=0; p<V.P; p++)
xue@1 274 {
xue@1 275 double startfr; QIE(&V.F0D[V.peakfr[p]], startfr); V.lp[p]=startfr+V.peakfr[p];
xue@1 276 }
xue@1 277
xue@1 278 //Basic descriptor: LogAF[]
xue@1 279 //Source-filter modeling
xue@1 280 if (SFMode==0)
xue@1 281 S_F(V.afres, V.LogAF, V.LogAS, Fr, M, Partials, V.A0C, V.lp, V.P, V.F0Overall);
xue@1 282 else
xue@1 283 S_F_SV(V.afres, V.LogAF, V.LogAS, Fr, M, Partials, V.A0C, V.lp, V.P, SFF, SFFScale, SFtheta, sps);
xue@1 284
xue@1 285
xue@1 286 //the alternative: find K only
xue@1 287 V.K=50;
xue@1 288 if (V.K>periodinframe/2) V.K=periodinframe/2;
xue@1 289
xue@1 290 //single-cycle analyses
xue@1 291 //Basic descriptor: Dp[]
xue@1 292 V.AllocatePK();
xue@1 293 for (int p=1; p<V.P; p++)
xue@1 294 {
xue@1 295 //int frst=ceil(V.lp[p-1]), freninc=floor(V.lp[p]);
xue@1 296 int frst=V.peakfr[p-1], freninc=V.peakfr[p];
xue@1 297 V.Dp[p]=0; for (int fr=frst; fr<=freninc; fr++) V.Dp[p]+=V.F0D[fr]*V.F0D[fr]; V.Dp[p]=sqrt(V.Dp[p]/(freninc-frst+1));
xue@1 298 double* f0e=new double[freninc-frst+1];
xue@1 299 for (int fr=0; fr<=freninc-frst; fr++) f0e[fr]=V.F0D[frst+fr]/V.Dp[p];
xue@1 300 V.Kp[p]=V.K; FS_QR(V.Kp[p], V.fxr[p], &f0e[0], freninc-frst, V.lp[p]-V.lp[p-1], V.lp[p-1]-frst, V.fres[p]);
xue@1 301 delete[] f0e;
xue@1 302
xue@1 303 memset(V.LogASp[p], 0, sizeof(double)*V.M);
xue@1 304 for (int m=0; m<V.M; m++)
xue@1 305 {
xue@1 306 int ccount=0;
xue@1 307 for (int fr=frst; fr<=freninc; fr++)
xue@1 308 {
xue@1 309 double f=Partials[m][fr].f*V.afres;
xue@1 310 if (f<=0) continue;
xue@1 311 int intf=floor(f);
xue@1 312 V.LogASp[p][m]=V.LogASp[p][m]+log(Partials[m][fr].a/V.A0C[fr])-(V.LogAF[intf]*(intf+1-f)+V.LogAF[intf+1]*(f-intf));
xue@1 313 ccount++;
xue@1 314 }
xue@1 315 if (ccount>0) V.LogASp[p][m]/=ccount;
xue@1 316 else V.LogASp[p][m]=0;
xue@1 317 }
xue@1 318 }
xue@1 319 memset(V.FXR, 0, sizeof(double)*2*V.K); memset(V.FRes, 0, sizeof(double)*V.K);
xue@1 320 double sumdp=0; for (int p=1; p<V.P; p++) sumdp+=V.Dp[p], V.FXR[0]+=V.fxr[p][0]*V.Dp[p], V.FRes[0]+=V.fres[p][0]*V.Dp[p]; V.FXR[0]/=sumdp, V.FRes[0]/=sumdp;
xue@1 321 for (int k=1; k<V.K; k++)
xue@1 322 {
xue@1 323 double sumdp=0;
xue@1 324 for (int p=1; p<V.P; p++)
xue@1 325 {
xue@1 326 if (k<V.Kp[p])
xue@1 327 {
xue@1 328 V.FXR[2*k-1]+=V.fxr[p][2*k-1]*V.Dp[p];
xue@1 329 V.FXR[2*k]+=V.fxr[p][2*k]*V.Dp[p];
xue@1 330 V.FRes[k]+=V.fres[p][k]*V.Dp[p];
xue@1 331 sumdp+=V.Dp[p];
xue@1 332 }
xue@1 333 }
xue@1 334 V.FXR[2*k-1]/=sumdp, V.FXR[2*k]/=sumdp, V.FRes[k]/=sumdp;
xue@1 335 }
xue@1 336 }//AnalyzeV
xue@1 337
Chris@5 338 /**
xue@1 339 function copeak: measures the similarity of F0 between frst and fren to a cosine cycle 0~2pi.
xue@1 340
xue@1 341 In: F0[peakfr[frst]:peakfr[fren]]
xue@1 342 periodinframe: period of the cosine reference, in frames
xue@1 343
xue@1 344 Returns the correlation coefficient.
xue@1 345 */
xue@1 346 double copeak(double* F0, int* peakfr, int frst, int fren, double periodinframe)
xue@1 347 {
xue@1 348 double ef0=0, rfs=0, rff=0, rss=0; int frcount=0;
xue@1 349 for (int fr=peakfr[frst]; fr<=peakfr[fren]; fr++) ef0+=F0[fr], frcount++; ef0/=frcount;
xue@1 350 for (int fr=peakfr[frst]; fr<=peakfr[fren]; fr++)
xue@1 351 {
xue@1 352 double s=cos(2*M_PI*(fr-peakfr[frst])/periodinframe), f=F0[fr];
xue@1 353 rfs+=(f-ef0)*s; rff+=(f-ef0)*(f-ef0); rss+=s*s;
xue@1 354 }
xue@1 355 return rfs/sqrt(rff*rss);
xue@1 356 }//copeak
xue@1 357
Chris@5 358 /**
xue@1 359 function CorrectFS: time-shifts Fourier series so that maximum is reached at 0. This is done by
xue@1 360 finding the actual peak numerically then shifting it to 0.
xue@1 361
xue@1 362 In: c[2K-1]: Fourier series coefficients, in the order of 0r, 1i, 1r, 2i, 2r, ..., so that the series
xue@1 363 is expanded as c[0]+c[1]sinx+c[2]cosx+c[3]sin2x+c[4]cos2x+...c[2K-2]cos(K-1)x
xue@1 364 epx: a small positive value for convergence test for finding the peak
xue@1 365 maxiter: maximal number of iterates for finding the peak
xue@1 366 Out: c[2K-1]: updated Fourier series coefficients.
xue@1 367
xue@1 368 No return value.
xue@1 369 */
xue@1 370 void CorrectFS(int K, double* c, double epx=1e-8, int maxiter=10)
xue@1 371 {
xue@1 372 double y=0, kb=0, kka=0, th2pi=0, dth2pi=0, my, mth2pi;
xue@1 373 epx=2*M_PI*epx;
xue@1 374 int iter=0;
xue@1 375 for (int k=1; k<K; k++) y+=c[2*k], kb+=k*c[2*k-1], kka+=k*k*c[2*k]; my=y;
xue@1 376 dth2pi=(kka>0)?(kb/kka):(kb*0.1);
xue@1 377 while (iter<maxiter && fabs(dth2pi)>epx)
xue@1 378 {
xue@1 379 iter++;
xue@1 380 th2pi+=dth2pi;
xue@1 381 kb=kka=y=0;
xue@1 382 for (int k=1; k<K; k++)
xue@1 383 {
xue@1 384 double cc=cos(k*th2pi), ss=sin(k*th2pi);
xue@1 385 y+=(c[2*k]*cc+c[2*k-1]*ss);
xue@1 386 kb+=k*(-c[2*k]*ss+c[2*k-1]*cc);
xue@1 387 kka+=k*k*(c[2*k]*cc+c[2*k-1]*ss);
xue@1 388 }
xue@1 389 if (y>my) my=y, mth2pi=th2pi;
xue@1 390 dth2pi=(kka>0)?(kb/kka):(kb*0.1);
xue@1 391 }
xue@1 392 if (iter>=maxiter || th2pi!=mth2pi)
xue@1 393 {
xue@1 394 th2pi=mth2pi;
xue@1 395 }
xue@1 396 for (int k=1; k<K; k++)
xue@1 397 {
xue@1 398 double cc=cos(k*th2pi), ss=sin(k*th2pi);
xue@1 399 double tmp=c[2*k]*cc+c[2*k-1]*ss;
xue@1 400 c[2*k-1]=-c[2*k]*ss+c[2*k-1]*cc; c[2*k]=tmp;
xue@1 401 }
xue@1 402 }//CorrectFS
xue@1 403
Chris@5 404 /**
xue@1 405 function DeAM: amplitude demodulation based on given segmentation into cycles
xue@1 406
xue@1 407 In: A1[Fr]: original amplitude
xue@1 408 peakfr[npfr]: cycle boundaries (literally, "frame indices of frequency modulation peaks")
xue@1 409 Out: A2[Fr]: demodulated amplitude
xue@1 410
xue@1 411 No return value.
xue@1 412 */
xue@1 413 void DeAM(double* A2, double* A1, int npfr, int* peakfr, int Fr)
xue@1 414 {
xue@1 415 if (npfr==1) {memcpy(A2, A1, sizeof(double)*Fr); return;}
xue@1 416 double *frs=new double[npfr*2], *a=&frs[npfr];
xue@1 417 for (int i=0; i<npfr-1; i++)
xue@1 418 {
xue@1 419 int frst=peakfr[i], fren=peakfr[i+1];
xue@1 420 a[i]=(A1[frst]+A1[fren])*0.5;
xue@1 421 frs[i]=(frst*A1[frst]+fren*A1[fren])*0.5;
xue@1 422 for (int fr=frst+1; fr<fren; fr++) a[i]+=A1[fr], frs[i]+=fr*A1[fr];
xue@1 423 frs[i]/=a[i]; a[i]=log(sqrt(a[i]/(fren-frst)));
xue@1 424 }
xue@1 425 if (npfr==2)
xue@1 426 {
xue@1 427 A2[0]=exp(a[0]);
xue@1 428 for (int fr=1; fr<Fr; fr++) A2[fr]=A2[0];
xue@1 429 }
xue@1 430 else if (npfr==3)
xue@1 431 {
xue@1 432 double alp=(a[1]-a[0])/(frs[1]-frs[0]);
xue@1 433 for (int fr=0; fr<Fr; fr++) A2[fr]=exp(a[0]+(fr-frs[0])*alp);
xue@1 434 }
xue@1 435 else if (npfr==4)
xue@1 436 {
xue@1 437 double x0=frs[0], x1=frs[1], x2=frs[2], y0=log(a[0]), y1=log(a[1]), y2=log(a[2]);
xue@1 438 double ix0_12=y0/((x0-x1)*(x0-x2)), ix1_02=y1/((x1-x0)*(x1-x2)), ix2_01=y2/((x2-x0)*(x2-x1));
xue@1 439 double aa=ix0_12+ix1_02+ix2_01,
xue@1 440 b=-(x1+x2)*ix0_12-(x0+x2)*ix1_02-(x0+x1)*ix2_01,
xue@1 441 c=x1*x2*ix0_12+x0*x2*ix1_02+x0*x1*ix2_01;
xue@1 442 for (int fr=0; fr<Fr; fr++) A2[fr]=exp(c+fr*(b+fr*aa));
xue@1 443 }
xue@1 444 else
xue@1 445 {
xue@1 446 double *fa=new double[npfr*4], *fb=&fa[npfr], *fc=&fa[npfr*2], *fd=&fa[npfr*3];
xue@1 447 CubicSpline(npfr-2, fa, fb, fc, fd, frs, a, 0, 1, A2, 1, 0, Fr-1);
xue@1 448 for (int fr=0; fr<Fr; fr++) A2[fr]=exp(A2[fr]);
xue@1 449 delete[] fa;
xue@1 450 }
xue@1 451 delete[] frs;
xue@1 452 }//DeAM
xue@1 453
Chris@5 454 /**
xue@1 455 function DeAM: wrapper function using floating-point cycle boundaries
xue@1 456
xue@1 457 In: A1[Fr]: original amplitude
xue@1 458 lp[npfr]: cycle boundaries
xue@1 459 Out: A2[Fr]: demodulated amplitude
xue@1 460
xue@1 461 No return value.
xue@1 462 */
xue@1 463 void DeAM(double* A2, double* A1, int npfr, double* lp, int Fr)
xue@1 464 {
xue@1 465 int* peakfr=new int[npfr];
xue@1 466 for (int i=0; i<npfr; i++) peakfr[i]=ceil(lp[i]);
xue@1 467 DeAM(A2, A1, npfr, peakfr, Fr);
xue@1 468 delete[] peakfr;
xue@1 469 }//DeAM
xue@1 470
Chris@5 471 /**
xue@1 472 function DeFM: frequency demodulation based on given segmentation into cycles
xue@1 473
xue@1 474 In: f1[Fr], AA[Fr]: original frequency and partial-independent amplitude
xue@1 475 peakfr[npfr]: cycle boundaries (literally, "frame indices of frequency modulation peaks")
xue@1 476 furthursmoothing: specifies if a second round demodulation is to be performed for more smooth
xue@1 477 carrier
xue@1 478 Out: f2[Fr]: demodulated frequency
xue@1 479 f[fcount], frs[fcount]: frequency and time (in frames) of carrier knots, optional
xue@1 480 fct: frequency centroid
xue@1 481
xue@1 482 No return value.
xue@1 483 */
xue@1 484 void DeFM(double* f2, double* f1, double* AA, int npfr, int* peakfr, int Fr, double& fct, int& fcount, double* &frs, double* &f, bool furthersmoothing)
xue@1 485 {
xue@1 486 double ac=0;
xue@1 487 fct=0;
xue@1 488
xue@1 489 if (npfr==1)
xue@1 490 {
xue@1 491 memcpy(f2, f1, sizeof(double)*Fr);
xue@1 492 for (int fr=0; fr<Fr; fr++) ac+=AA[fr], fct+=f1[fr]*AA[fr]; fct/=ac;
xue@1 493 return;
xue@1 494 }
xue@1 495
xue@1 496 bool localfrs=(frs==(double*)0xFFFFFFFF), localf=(f==(double*)0xFFFFFFFF);
xue@1 497 if (!localfrs) delete[] frs;
xue@1 498 if (!localf) delete[] f;
xue@1 499 frs=new double[npfr]; f=new double[npfr];
xue@1 500 for (int i=0; i<npfr-1; i++)
xue@1 501 {
xue@1 502 int frst=peakfr[i], fren=peakfr[i+1];
xue@1 503 f[i]=(f1[frst]*AA[frst]+f1[fren]*AA[fren])*0.5;
xue@1 504 frs[i]=(frst*AA[frst]+fren*AA[fren])*0.5;
xue@1 505 double lrec=(AA[frst]+AA[fren])*0.5;
xue@1 506 for (int fr=frst+1; fr<fren; fr++) f[i]+=f1[fr]*AA[fr], frs[i]+=fr*AA[fr], lrec+=AA[fr];
xue@1 507 ac+=lrec;
xue@1 508 fct+=f[i];
xue@1 509 f[i]/=lrec, frs[i]/=lrec;
xue@1 510 }
xue@1 511 fct/=ac;
xue@1 512
xue@1 513 if (furthersmoothing)
xue@1 514 {
xue@1 515 //further smoothing
xue@1 516 int newnpfr=1;
xue@1 517 for (int pfr=1; pfr<npfr-2; pfr++)
xue@1 518 {
xue@1 519 if ((f[pfr]>f[pfr-1] && f[pfr]>f[pfr+1]) || (f[pfr]<f[pfr-1] && f[pfr]<f[pfr+1]))
xue@1 520 {
xue@1 521 //this is a peak or valley
xue@1 522 if ((pfr+1<npfr-2 && f[pfr+1]>f[pfr] && f[pfr+1]>f[pfr+2]) || (f[pfr+1]<f[pfr] && f[pfr+1]<f[pfr+2]))
xue@1 523 {
xue@1 524 frs[newnpfr]=0.5*(frs[pfr]+frs[pfr+1]), f[newnpfr]=0.5*(f[pfr]+f[pfr+1]);
xue@1 525 newnpfr++;
xue@1 526 }
xue@1 527 }
xue@1 528 else
xue@1 529 {
xue@1 530 frs[newnpfr]=frs[pfr], f[newnpfr]=f[pfr];
xue@1 531 newnpfr++;
xue@1 532 }
xue@1 533 }
xue@1 534 frs[newnpfr]=frs[npfr-2], f[newnpfr]=f[npfr-2]; newnpfr++; newnpfr++;
xue@1 535 npfr=newnpfr;
xue@1 536 }
xue@1 537
xue@1 538 Smooth_Interpolate(f2, Fr, npfr, f, frs);
xue@1 539 fcount=npfr-1;
xue@1 540
xue@1 541 if (localfrs) delete[] frs;
xue@1 542 if (localf) delete[] f;
xue@1 543 }//DeFM
xue@1 544
Chris@5 545 /**
xue@1 546 function DeFM: wrapper function using floating-point cycle boundaries
xue@1 547
xue@1 548 In: f1[Fr], AA[Fr]: original frequency and partial-independent amplitude
xue@1 549 lp[npfr]: cycle boundaries
xue@1 550 furthursmoothing: specifies if a second round demodulation is to be performed for more smooth
xue@1 551 carrier
xue@1 552 Out: f2[Fr]: demodulated frequency
xue@1 553 f[fcount], frs[fcount]: frequency and time (in frames) of carrier knots, optional
xue@1 554 fct: frequency centroid
xue@1 555
xue@1 556 No return value.
xue@1 557 */
xue@1 558 void DeFM(double* f2, double* f1, double* AA, int npfr, double* lp, int Fr, double& fct, int& fcount, double* &frs, double* &f, bool furthersmoothing)
xue@1 559 {
xue@1 560 int* peakfr=new int[npfr];
xue@1 561 for (int i=0; i<npfr; i++) peakfr[i]=ceil(lp[i]);
xue@1 562 DeFM(f2, f1, AA, npfr, peakfr, Fr, fct, fcount, frs, f, furthersmoothing);
xue@1 563 delete[] peakfr;
xue@1 564 }//DeFM
xue@1 565
Chris@5 566 /**
xue@1 567 function FindPeaks: find modulation peaks of signal F0[] roughly periodical at $periodinframe
xue@1 568
xue@1 569 In: F0[Fr]: modulated signal
xue@1 570 periodinframe: reference modulation period
xue@1 571 Out: npfr, peakfr[npfr]: modulation peaks
xue@1 572 peaky[npfr]: shape score for the peaks measuring their similarity to cosine peak, optional
xue@1 573
xue@1 574 No return value.
xue@1 575 */
xue@1 576 void FindPeaks(int* peakfr, int& npfr, double* F0, int Fr, double periodinframe, double*& peaky)
xue@1 577 {
xue@1 578 npfr=0;
xue@1 579 for (int fr=1; fr<Fr-1; fr++)
xue@1 580 {
xue@1 581 if (F0[fr]>F0[fr-1] && F0[fr]>F0[fr+1])
xue@1 582 {
xue@1 583 peakfr[npfr++]=fr;
xue@1 584 }
xue@1 585 }
xue@1 586
xue@1 587 bool localpeaky=(peaky==(double*)0xFFFFFFFF); if (!localpeaky) delete[] peaky;
xue@1 588
xue@1 589 peaky=new double[npfr];
xue@1 590 for (int pfr=0; pfr<npfr; pfr++)
xue@1 591 {
xue@1 592 double rfs=0, rff=0, rss=0;
xue@1 593 if (peakfr[pfr]>periodinframe/2)
xue@1 594 {
xue@1 595 double ef0=0; int frcount=0; for (int fr=peakfr[pfr]-periodinframe/2; fr<peakfr[pfr]; fr++) ef0+=F0[fr], frcount++; ef0/=frcount;
xue@1 596 for (int fr=peakfr[pfr]-periodinframe/2; fr<peakfr[pfr]; fr++)
xue@1 597 {
xue@1 598 double s=cos(2*M_PI*(fr-peakfr[pfr])/periodinframe), f=F0[fr];
xue@1 599 rfs+=(f-ef0)*s; rff+=(f-ef0)*(f-ef0); rss+=s*s;
xue@1 600 }
xue@1 601 }
xue@1 602 if (peakfr[pfr]<Fr-periodinframe/2)
xue@1 603 {
xue@1 604 double ef0=0; int frcount=0; for (int fr=peakfr[pfr]; fr<peakfr[pfr]+periodinframe/2; fr++) ef0+=F0[fr], frcount++; ef0/=frcount;
xue@1 605 for (int fr=peakfr[pfr]; fr<peakfr[pfr]+periodinframe/2; fr++)
xue@1 606 {
xue@1 607 double s=cos(2*M_PI*(fr-peakfr[pfr])/periodinframe), f=F0[fr];
xue@1 608 rfs+=(f-ef0)*s; rff+=(f-ef0)*(f-ef0); rss+=s*s;
xue@1 609 }
xue@1 610 }
xue@1 611 peaky[pfr]=rfs/sqrt(rff*rss);
xue@1 612 }
xue@1 613 int pst=0; for (int pfr=1; pfr<npfr; pfr++) if (peaky[pst]<peaky[pfr]) pst=pfr;
xue@1 614 // return;
xue@1 615 //*
xue@1 616 int pen=pst+1, pfr=pst+1;
xue@1 617 while (pfr<npfr)
xue@1 618 {
xue@1 619 int impfr=-1;
xue@1 620 while (pfr<npfr && peakfr[pfr]<peakfr[pen-1]+periodinframe*0.5) pfr++;
xue@1 621 if (pfr<npfr && peakfr[pfr]<peakfr[pen-1]+periodinframe*1.5)
xue@1 622 {
xue@1 623 double mpfr=peaky[pfr]+copeak(F0, peakfr, pen-1, pfr, periodinframe);
xue@1 624 impfr=pfr; pfr++;
xue@1 625 while (pfr<npfr && peakfr[pfr]<peakfr[pen-1]+periodinframe*1.5)
xue@1 626 {
xue@1 627 double mp=peaky[pfr]+copeak(F0, peakfr, pen-1, pfr, periodinframe);
xue@1 628 if (mp>mpfr) impfr=pfr, mpfr=mp;
xue@1 629 pfr++;
xue@1 630 }
xue@1 631 }
xue@1 632 else
xue@1 633 {
xue@1 634 while (pfr<npfr)
xue@1 635 {
xue@1 636 if (peaky[pfr]>0) {impfr=pfr; break;}
xue@1 637 pfr++;
xue@1 638 }
xue@1 639 }
xue@1 640 if (impfr>=0) peakfr[pen++]=peakfr[impfr];
xue@1 641 }
xue@1 642 pst--; pfr=pst;
xue@1 643 while (pfr>=0)
xue@1 644 {
xue@1 645 int impfr=-1;
xue@1 646 while (pfr>=0 && peakfr[pfr]>peakfr[pst+1]-periodinframe*0.5) pfr--;
xue@1 647 if (pfr>=0 && peakfr[pfr]>=peakfr[pst+1]-periodinframe*1.5)
xue@1 648 {
xue@1 649 double mpfr=peaky[pfr]+copeak(F0, peakfr, pfr, pst+1, periodinframe);
xue@1 650 impfr=pfr; pfr--;
xue@1 651 while (pfr>=0 && peakfr[pfr]>=peakfr[pst+1]-periodinframe*1.5)
xue@1 652 {
xue@1 653 double mp=peaky[pfr]+copeak(F0, peakfr, pfr, pst+1, periodinframe);
xue@1 654 if (mp>mpfr) impfr=pfr, mpfr=mp;
xue@1 655 pfr--;
xue@1 656 }
xue@1 657 }
xue@1 658 else
xue@1 659 {
xue@1 660 while (pfr>=0)
xue@1 661 {
xue@1 662 if (peaky[pfr]>0) {impfr=pfr; break;}
xue@1 663 pfr--;
xue@1 664 }
xue@1 665 }
xue@1 666 if (impfr>=0) peakfr[pst--]=peakfr[impfr];
xue@1 667 }
xue@1 668 pst++;
xue@1 669 npfr=pen-pst;
xue@1 670 memmove(peakfr, &peakfr[pst], sizeof(int)*npfr); //*/
xue@1 671 if (localpeaky) delete[] peaky;
xue@1 672 }//FindPeaks
xue@1 673
Chris@5 674 /**
xue@1 675 function FS: Fourier series decomposition
xue@1 676
xue@1 677 In: data[frst:fren]: signal to decompose
xue@1 678 period: period of Fourier series decomposition
xue@1 679 shift: amount of original shift of Fourier components (from frst to frst-shift)
xue@1 680 K: number of Fourier components requested
xue@1 681 Out: K: number of Fourier components returned
xue@1 682 FXR[K], FXI[K]: real and imaginary parts of Fourier series coefficients
xue@1 683 FRES[K]: decomposition residues
xue@1 684
xue@1 685 No return value.
xue@1 686 */
xue@1 687 void FS(int& K, double* FXR, double* FXI, double* FRES, double* data, int frst, int fren, double period, double shift)
xue@1 688 {
xue@1 689 if (K>period/2) K=period/2;
xue@1 690 int len=fren-frst+1;
xue@1 691 double omg0=2*M_PI/period, ilen=1.0/len;
xue@1 692
xue@1 693 //for (int fr=frst; fr<=fren; fr++) data[fr]=cos(2*M_PI*fr/period+1);
xue@1 694
xue@1 695 double* res=new double[len]; memcpy(res, &data[frst], sizeof(double)*len);
xue@1 696 double* rec=new double[len];
xue@1 697 double resene=0; for (int i=0; i<len; i++) resene+=res[i]*res[i]; double ene=resene;
xue@1 698
xue@1 699 for (int k=0; k<K; k++)
xue@1 700 {
xue@1 701 // double eer=0, eei=0;
xue@1 702 double xr=0, xi=0, omg=k*omg0;
xue@1 703 for (int fr=frst; fr<=fren; fr++)
xue@1 704 {
xue@1 705 double ph=omg*(fr-shift);
xue@1 706 double c=cos(ph), s=sin(ph);
xue@1 707 xr+=data[fr]*c, xi+=data[fr]*s;
xue@1 708 // eer+=c*c, eei+=s*s;
xue@1 709 }
xue@1 710 xr*=ilen, xi*=ilen;
xue@1 711 // if (eer>0) xr/=eer;
xue@1 712 // if (eei>0) xi/=eei;
xue@1 713 FXR[k]=xr, FXI[k]=xi;
xue@1 714 double lresene=0;
xue@1 715 for (int fr=frst; fr<=fren; fr++)
xue@1 716 {
xue@1 717 double ph=omg*(fr-shift);
xue@1 718 // rec[fr-frst]=xr*cos(ph)+xi*sin(ph);
xue@1 719 if (k==0) rec[fr-frst]=xr*cos(ph)+xi*sin(ph);
xue@1 720 else rec[fr-frst]=2*(xr*cos(ph)+xi*sin(ph));
xue@1 721 res[fr-frst]-=rec[fr-frst];
xue@1 722 lresene+=res[fr-frst]*res[fr-frst];
xue@1 723 }
xue@1 724 resene=lresene;
xue@1 725 FRES[k]=resene/ene;
xue@1 726 }
xue@1 727 delete[] rec;
xue@1 728 delete[] res;
xue@1 729 }//FS
xue@1 730
Chris@5 731 /**
xue@1 732 function FS_QR: Fourier series decomposition with QR orthogonalization. Since the Fourier series is
xue@1 733 applied on finite-length discrate signal, the Fourier components are no longer orthogonal to each
xue@1 734 other. A decreasing residue can be guaranteed by applying QR (or any other) orthogonalization process
xue@1 735 to the Fourier components before decomposition.
xue@1 736
xue@1 737 In: data[0:Fr]: signal to decompose
xue@1 738 period: period of Fourier series decomposition
xue@1 739 shift: amount of original shift of Fourier components (from 0 to -shift)
xue@1 740 K: number of Fourier components requested
xue@1 741 Out: K: number of Fourier components returned
xue@1 742 FXR[2K-1]: Fourier series coefficients, in the order of 0r, 1i, 1r, 2i, 2r, ....
xue@1 743 FRES[K]: decomposition residues, optional
xue@1 744
xue@1 745 No return value.
xue@1 746 */
xue@1 747 void FS_QR(int& K, double* FXR, double* data, int Fr, double period, double shift, double* FRES)
xue@1 748 {
xue@1 749 int len=Fr+1;
xue@1 750 if (K>period/2) K=period/2;
xue@1 751 if (K>Fr/2) K=Fr/2;
xue@1 752 if (K>len/2) K=len/2;
xue@1 753 if (K<=0) return;
xue@1 754 memset(FXR, 0, sizeof(double)*(2*K-1));
xue@1 755
xue@1 756 double omg0=2*M_PI/period, ene, resene;
xue@1 757
xue@1 758 if (FRES)
xue@1 759 {
xue@1 760 ene=0; for (int i=0; i<len; i++) ene+=data[i]*data[i]; resene=ene;
xue@1 761 }
xue@1 762
xue@1 763 /*debug only
xue@1 764 double *res=new double[len*4], *rec=&res[len];
xue@1 765 memcpy(res, data, sizeof(double)*len); memset(rec, 0, sizeof(double)*len);
xue@1 766 double resene2=resene;//*/
xue@1 767
xue@1 768 int NK=K*2-1;
xue@1 769
xue@1 770 Alloc2(len, NK, A); Alloc2(len, len, Q); Alloc2(len, NK, R);
xue@1 771 for (int fr=0; fr<=Fr; fr++) A[fr][0]=1;
xue@1 772 for (int k=1; k<(NK+1)/2; k++)
xue@1 773 {
xue@1 774 double omg=k*omg0;
xue@1 775 for (int fr=0; fr<=Fr; fr++){double ph=omg*(fr-shift); A[fr][2*k-1]=2*sin(ph), A[fr][2*k]=2*cos(ph);}
xue@1 776 }
xue@1 777 QR_householder(len, NK, A, Q, R);///////////////////
xue@1 778 GIUT(NK, R);
xue@1 779 for (int k=0; k<NK; k++)
xue@1 780 {
xue@1 781 double xr=0;
xue@1 782 for (int fr=0; fr<=Fr; fr++)
xue@1 783 {
xue@1 784 double c=Q[fr][k];
xue@1 785 xr+=data[fr]*c;
xue@1 786 }
xue@1 787 for (int kk=0; kk<=k; kk++) FXR[kk]+=xr*R[kk][k];
xue@1 788 /*debug only
xue@1 789 double lresene=0;
xue@1 790 for (int fr=0; fr<=Fr; fr++)
xue@1 791 {
xue@1 792 rec[fr]=0; for (int kk=0; kk<=k; kk++) rec[fr]+=FXR[kk]*A[fr][kk];
xue@1 793 res[fr]=data[fr]-rec[fr];
xue@1 794 lresene+=res[fr]*res[fr];
xue@1 795 }
xue@1 796 resene2=lresene; */
xue@1 797
xue@1 798 if (FRES)
xue@1 799 {
xue@1 800 resene-=xr*xr;
xue@1 801 if (k%2==0) FRES[k/2]=resene/ene;
xue@1 802 }
xue@1 803 }
xue@1 804 /* debug only
xue@1 805 delete[] res; //*/
xue@1 806 DeAlloc2(A); DeAlloc2(Q); DeAlloc2(R);
xue@1 807 }//FS_QR
xue@1 808
Chris@5 809 /**
xue@1 810 function InterpolateV: adjusts modulation rate to $rate times the current value. Since TVo is based on
xue@1 811 individual cycles, this operation involves finding new cycle boundaries and recomputing other single-
xue@1 812 cycle descriptors by interpolation. This is used for time stretching and cycle rate adjustment.
xue@1 813
xue@1 814 In: V: a TVo object to adjust
xue@1 815 newP: number of total cycles after adjustment.
xue@1 816 rate: amount of adjustment.
xue@1 817 Out: another TVo object with new cycle boundaries and single-cycle descriptors interpoated from V
xue@1 818
xue@1 819 Returns pointer to the output TVo. This function does not affect the content in V.
xue@1 820 */
xue@1 821 TVo* InterpolateV(double newP, double rate, TVo& V)
xue@1 822 {
xue@1 823 double Pst=-V.lp[0]/(V.lp[1]-V.lp[0]);
xue@1 824 double oldP=V.P-1+(V.L-V.lp[V.P-1])/(V.lp[V.P-1]-V.lp[V.P-2])-Pst;
xue@1 825
xue@1 826 TVo* newV=new TVo;
xue@1 827 memcpy(newV, &V, sizeof(TVo));
xue@1 828
xue@1 829 newV->F0C=0; newV->A0C=0; newV->peakfr=0; newV->Dp=0; newV->lp=0, newV->Kp=0;
xue@1 830 newV->fxr=0; newV->LogASp=0; newV->F0=0; newV->F0D=0; newV->fres=0;
xue@1 831
xue@1 832 int inewP=ceil(newP+Pst);
xue@1 833 newV->P=inewP;
xue@1 834
xue@1 835 newV->peakfr=new int[inewP];
xue@1 836 newV->AllocateP(); newV->AllocatePK();
xue@1 837
xue@1 838 newV->lp[0]=V.lp[0]/rate;
xue@1 839 newV->peakfr[0]=floor(newV->lp[0]+0.5);
xue@1 840 for (int p=1; p<inewP; p++)
xue@1 841 {
xue@1 842 double rp=1+(p-1)*(oldP-2+Pst)/(newP-2+Pst);
xue@1 843 int ip=floor(rp); rp=rp-ip;
xue@1 844 if (ip+1>=V.P) ip=V.P-1, rp=0;
xue@1 845 if (fabs(rp)<1e-16)
xue@1 846 {
xue@1 847 newV->lp[p]=newV->lp[p-1]+(V.lp[ip]-V.lp[ip-1])/rate;
xue@1 848 newV->Dp[p]=V.Dp[ip];
xue@1 849 newV->Kp[p]=V.Kp[ip];
xue@1 850 memcpy(newV->fxr[p], V.fxr[ip], sizeof(double)*2*newV->Kp[p]);
xue@1 851 memcpy(newV->LogASp[p], V.LogASp[ip], sizeof(double)*V.M);
xue@1 852 }
xue@1 853 else
xue@1 854 {
xue@1 855 double fv1=1.0/(V.lp[ip]-V.lp[ip-1]), fv2=1.0/(V.lp[ip+1]-V.lp[ip]);
xue@1 856 double fv=rate*(fv1*(1-rp)+fv2*rp);
xue@1 857 newV->lp[p]=newV->lp[p-1]+1.0/fv;
xue@1 858 newV->Dp[p]=V.Dp[ip]*(1-rp)+V.Dp[ip+1]*rp;
xue@1 859 int minK=V.Kp[ip]; if (minK>V.Kp[ip+1]) minK=V.Kp[ip+1];
xue@1 860 for (int k=0; k<2*minK-1; k++) newV->fxr[p][k]=V.fxr[ip][k]*(1-rp)+V.fxr[ip+1][k]*rp;
xue@1 861 for (int m=0; m<V.M; m++) newV->LogASp[p][m]=V.LogASp[ip][m]*(1-rp)+V.LogASp[ip+1][m]*rp;
xue@1 862 newV->Kp[p]=minK;
xue@1 863 }
xue@1 864 newV->peakfr[p]=floor(newV->lp[p]+0.5);
xue@1 865 memset(newV->fres[0], 0, sizeof(double)*newV->P*V.K);
xue@1 866 }
xue@1 867 int newL=newV->lp[inewP-1]+(newP+Pst-(inewP-1))*(V.lp[V.P-1]-V.lp[V.P-2])/rate+0.5;
xue@1 868 newV->AllocateL(newL);
xue@1 869
xue@1 870 //F0C and A0C
xue@1 871 if (V.L!=newL)
xue@1 872 {
xue@1 873 for (int l=0; l<newL; l++)
xue@1 874 {
xue@1 875 double rl=1.0*l*(V.L-1)/(newL-1);
xue@1 876 int il=floor(rl); rl-=il;
xue@1 877 newV->F0C[l]=V.F0C[il]*(1-rl)+V.F0C[il+1]*rl;
xue@1 878 newV->A0C[l]=V.A0C[il]*(1-rl)+V.A0C[il+1]*rl;
xue@1 879 }
xue@1 880 }
xue@1 881 else
xue@1 882 {
xue@1 883 memcpy(newV->F0C, V.F0C, sizeof(double)*V.L);
xue@1 884 memcpy(newV->A0C, V.A0C, sizeof(double)*V.L);
xue@1 885 // memcpy(newV->F0, V.F0, sizeof(double)*V.L);
xue@1 886 // memcpy(newV->F0D, V.F0D, sizeof(double)*V.L);
xue@1 887 }
xue@1 888 return newV;
xue@1 889 }//InterpoalteV
xue@1 890
xue@1 891 //vibrato rate boundaries, in Hz
xue@1 892 #define MAXMOD 15.0
xue@1 893 #define MINMOD 3.0
xue@1 894
Chris@5 895 /**
xue@1 896 function RateAndReg: evaluates modulation rate and regularity
xue@1 897
xue@1 898 In: data[frst:fren]: modulated signal, time measured in frames
xue@1 899 padrate: padding rate used for inverse FFT
xue@1 900 sps: sampling frequency
xue@1 901 offst: hop size
xue@1 902 Out: rate, regularity: rate and regularity
xue@1 903
xue@1 904 No return value.
xue@1 905 */
xue@1 906 void RateAndReg(double& rate, double& regularity, double* data, int frst, int fren, int padrate, double sps, double offst)
xue@1 907 {
xue@1 908 rate=0; regularity=0;
xue@1 909 //find the section used for calculating regularity and rate
xue@1 910 int frlen=fren-frst+1, frlenp=1<<(int(log2(fren))+2), frlenpp=frlenp*padrate;
xue@1 911 double *lf=new double[frlenpp*4];
xue@1 912 cdouble *w=(cdouble*)&lf[frlenpp];
xue@1 913 cdouble *x=(cdouble*)&lf[frlenpp*2];
xue@1 914 SetTwiddleFactors(frlenp, w);
xue@1 915
xue@1 916 memset(lf, 0, sizeof(double)*frlenp);
xue@1 917 memcpy(lf, &data[frst], sizeof(double)*frlen);
xue@1 918 // for (int i=0; i<frlen; i++) lf[i]=data[frst+i]-edata;
xue@1 919
xue@1 920 double* rdata=new double[50];
xue@1 921 for (int i=0; i<50; i++)
xue@1 922 {
xue@1 923 rdata[i]=0; for (int j=0; j<fren-i; j++) rdata[i]+=data[j]*data[j+i];
xue@1 924 }
xue@1 925
xue@1 926
xue@1 927 RFFTC(lf, NULL, NULL, log2(frlenp), w, x, 0);
xue@1 928 // xr[0]=0;
xue@1 929 for (int i=0; i<frlenp/2; i++) {x[i].x=x[i].x*x[i].x+x[i].y*x[i].y; x[i].y=0;}
xue@1 930 memset(&x[frlenp/2], 0, sizeof(cdouble)*(frlenpp-frlenp/2));
xue@1 931
xue@1 932 SetTwiddleFactors(frlenpp, w);
xue@1 933 CIFFTR(x, log2(frlenpp), w, lf);
xue@1 934
xue@1 935 delete[] rdata;
xue@1 936
xue@1 937 double minpeak=sps/(offst*MAXMOD), maxpeak=sps/(offst*MINMOD);
xue@1 938
xue@1 939 //find 2nd highest peak at interval padrate
xue@1 940 int imaxlf=padrate*minpeak;
xue@1 941 while (imaxlf<frlenpp && imaxlf<padrate*maxpeak && lf[imaxlf]<=lf[imaxlf-padrate]) imaxlf+=padrate;
xue@1 942 double maxlf=lf[imaxlf];
xue@1 943 for (int i=imaxlf/padrate; i<frlen/2; i++) if (maxlf<lf[i*padrate]) maxlf=lf[i*padrate], imaxlf=i*padrate;
xue@1 944 //locate the peak at interval 1
xue@1 945 int ii=imaxlf; for (int i=ii-padrate+1; i<ii+padrate; i++) if (maxlf<lf[i]) maxlf=lf[i], imaxlf=i;
xue@1 946
xue@1 947 double a_=0.5*(lf[imaxlf-1]+lf[imaxlf+1])-maxlf, b_=0.5*(lf[imaxlf+1]-lf[imaxlf-1]);
xue@1 948 double period=imaxlf-0.5*b_/a_;
xue@1 949 period=period/padrate; //period in frames
xue@1 950 rate=sps/(period*offst); //rate in hz
xue@1 951 regularity=(maxlf-0.25*b_*b_/a_)/lf[0]*(fren-frst)/(fren-frst-period);
xue@1 952
xue@1 953 delete[] lf;
xue@1 954 }//RateAndReg
xue@1 955
Chris@5 956 /**
xue@1 957 function RegularizeV: synthesize a regular vibrato from the basic descriptors.
xue@1 958
xue@1 959 In: V: a TVo object hosting vibrato descriptors
xue@1 960 sps: sampling rate
xue@1 961 h: hop size
xue@1 962 Out: HS: a harmonic sinusoid
xue@1 963
xue@1 964 No return value.
xue@1 965 */
xue@1 966 void RegularizeV(THS& HS, TVo& V, double sps, double h)
xue@1 967 {
xue@1 968 int K=V.Kp[1]; for (int p=2; p<V.P; p++) if (K>V.Kp[p]) K=V.Kp[p];
xue@1 969 double D=0, *fxr=new double[2*K-1];
xue@1 970 memset(fxr, 0, sizeof(double)*(2*K-1));
xue@1 971 for (int p=1; p<V.P; p++)
xue@1 972 {
xue@1 973 D+=V.Dp[p]; for (int k=0; k<2*K-1; k++) fxr[k]+=V.fxr[p][k]*V.Dp[p];
xue@1 974 }
xue@1 975 //uncomment the following line if re-normalization needed
xue@1 976 //double alfa=fxr[0]*fxr[0]; for (int k=1; k<2*K-1; k++) alfa+=2*fxr[k]*fxr[k]; alfa=sqrt(alfa); D=alfa;
xue@1 977 for (int k=0; k<2*K-1; k++) fxr[k]/=D;
xue@1 978 D/=(V.P-1);
xue@1 979 V.D=D;
xue@1 980
xue@1 981 atom** Partials=HS.Partials;
xue@1 982 for (int l=0; l<V.L; l++)
xue@1 983 {
xue@1 984 double theta=V.rate*l*V.h/sps;//-0.25;
xue@1 985 //f0(theta)
xue@1 986 double f0=fxr[0]; for (int k=1; k<K; k++) f0=f0+2*(fxr[2*k-1]*sin(2*M_PI*k*theta)+fxr[2*k]*cos(2*M_PI*k*theta));
xue@1 987 V.F0D[l]=D*f0; V.F0[l]=V.F0C[l]+V.F0D[l];
xue@1 988 for (int m=0; m<V.M; m++)
xue@1 989 {
xue@1 990 if (Partials[m][l].t<0) Partials[m][l].t=Partials[0][l].t;
xue@1 991 Partials[m][l].f=(m+1)*V.F0[l];
xue@1 992 if (Partials[m][l].f>0.5 || Partials[m][l].f<0) Partials[m][l].f=-1, Partials[m][l].a=0;
xue@1 993 else Partials[m][l].a=V.A0C[l]*exp(V.LogAS[m]+V.LogAF[int(Partials[m][l].f*V.afres)]);
xue@1 994 }
xue@1 995 }
xue@1 996
xue@1 997 delete[] fxr;
xue@1 998 }//RegularizeV
xue@1 999
Chris@5 1000 /**
xue@1 1001 function QIE: computes extremum using quadratic interpolation
xue@1 1002
xue@1 1003 In: y[-1:1]: three points to interpolate from. It is assumed y[0] is larger (or smaller) than both
xue@1 1004 y[-1] and y[1].
xue@1 1005
xue@1 1006 Returns the extremum of y.
xue@1 1007 */
xue@1 1008 double QIE(double* y)
xue@1 1009 {
xue@1 1010 double a=0.5*(y[1]+y[-1])-y[0], b=0.5*(y[1]-y[-1]);
xue@1 1011 return y[0]-0.25*b*b/a;
xue@1 1012 }//QIE
xue@1 1013
Chris@5 1014 /**
xue@1 1015 function QIE: computes extremum using quadratic interpolation
xue@1 1016
xue@1 1017 In: y[-1:1]: three points to interpolate from. It is assumed y[0] is larger (or smaller) than both
xue@1 1018 y[-1] and y[1].
xue@1 1019 Out: x: the argument value that yields extremum of y(x)
xue@1 1020
xue@1 1021 Returns the extremum of y.
xue@1 1022 */
xue@1 1023 double QIE(double* y, double& x)
xue@1 1024 {
xue@1 1025 double a=0.5*(y[1]+y[-1])-y[0], b=0.5*(y[1]-y[-1]);
xue@1 1026 x=-0.5*b/a;
xue@1 1027 return y[0]-0.25*b*b/a;
xue@1 1028 }//QIE
xue@1 1029
Chris@5 1030 /**
xue@1 1031 function S_F: original source-filter estimation used in AES124.
xue@1 1032
xue@1 1033 In: afres: filter response resolution
xue@1 1034 Partials[M][Fr]: HS partials
xue@1 1035 A0C[Fr]: partial-independent amplitude carrier
xue@1 1036 lp[P]: cycle boundaries
xue@1 1037 F0Overall: average fundamental frequency
xue@1 1038 Out: LogAF[afres/2]: filter response
xue@1 1039 LogAS[M]: source amplitudes
xue@1 1040
xue@1 1041 Returns 0.
xue@1 1042 */
xue@1 1043 double S_F(int afres, double* LogAF, double* LogAS, int Fr, int M, atom** Partials, double* A0C, double* lp, int P, double F0Overall)
xue@1 1044 {
xue@1 1045 //SOURCE-FILTER estimation routines
xue@1 1046 //derivative of log A(f), f is sampled at 1/8192 (5hz), averaged over (-15hz, 15hz)
xue@1 1047 double *DAF=new double[afres], *NAF=&DAF[afres/2];
xue@1 1048 memset(DAF, 0, sizeof(double)*afres);
xue@1 1049 double avgwidth1, avgwidth2;
xue@1 1050 for (int fr=lp[1]; fr<lp[P-1]; fr++) for (int m=0; m<M; m++)
xue@1 1051 {
xue@1 1052 if (Partials[m][fr].f>0 && Partials[m][fr-1].f>0 && Partials[m][fr+1].f>0)
xue@1 1053 {
xue@1 1054 double f_1=Partials[m][fr-1].f, f0=Partials[m][fr].f, f1=Partials[m][fr+1].f, a_1=Partials[m][fr-1].a/A0C[fr-1], a1=Partials[m][fr+1].a/A0C[fr+1];
xue@1 1055 if ((f0-f_1)*(f0-f1)<0)
xue@1 1056 {
xue@1 1057 double dlogaf_df=(log(a1)-log(a_1))/(f1-f_1); //calculate derivative of log
xue@1 1058
xue@1 1059 //this derivative contributes within a frequency interval of |f1-f_1|
xue@1 1060 if (f1<f_1) {double tmp=f1; f1=f_1; f_1=tmp;}
xue@1 1061 int startbin=ceil(f_1*afres), endbin=floor(f1*afres);
xue@1 1062
xue@1 1063 if (startbin<0) startbin=0;
xue@1 1064 avgwidth1=(f0-f_1)*afres, avgwidth2=(f1-f0)*afres;
xue@1 1065 for (int i=startbin; i<=endbin; i++)
xue@1 1066 {
xue@1 1067 double fi=i-f0*afres, w;
xue@1 1068 if (fi<0) w=1-fabs(fi)/avgwidth1; else w=1-fabs(fi)/avgwidth2;
xue@1 1069 DAF[i]+=dlogaf_df*w, NAF[i]+=w;
xue@1 1070 }
xue@1 1071 }
xue@1 1072 }
xue@1 1073 }
xue@1 1074 for (int i=0; i<afres/2; i++) if (NAF[i]>0) DAF[i]=DAF[i]/NAF[i]; //else NAF[i]=0;
xue@1 1075 int i=0, nbands=0, bandsstart[100], bandsendinc[100]; double mininaf=3;
xue@1 1076 while (i<afres/2)
xue@1 1077 {
xue@1 1078 while (i<afres/2 && NAF[i]<mininaf) i++; if (i>=afres/2) break;
xue@1 1079 bandsstart[nbands]=i;
xue@1 1080 while (i<afres/2 && NAF[i]>0) i++; if (i>=afres/2) {bandsendinc[nbands++]=i-1; break;}
xue@1 1081 if (NAF[i]<=0) while (NAF[i]<mininaf) i--;
xue@1 1082 bandsendinc[nbands++]=i++;
xue@1 1083 }
xue@1 1084
xue@1 1085 //integrate DAF over the fundamental band, with AF(F0Overall)=1
xue@1 1086 i=F0Overall*afres;
xue@1 1087 double theta=F0Overall*afres-i;
xue@1 1088 LogAF[i]=-0.5*theta*(DAF[i]+DAF[i]*(1-theta)+DAF[i+1]*theta)/afres; i--;
xue@1 1089 while (i>=bandsstart[0]){LogAF[i]=LogAF[i+1]-0.5*(DAF[i]+DAF[i+1])/afres; i--;}
xue@1 1090 i=F0Overall*afres+1;
xue@1 1091 LogAF[i]=0.5*(1-theta)*(DAF[i]+DAF[i-1]*(1-theta)+DAF[i]*theta)/afres; i++;
xue@1 1092 while (i<=bandsendinc[0]){LogAF[i]=LogAF[i-1]+0.5*(DAF[i]+DAF[i-1])/afres; i++;}
xue@1 1093
xue@1 1094 int band=1;
xue@1 1095 while (band<nbands)
xue@1 1096 {
xue@1 1097 //integrate DAF over band-th band, first ignore the blank band
xue@1 1098 LogAF[bandsstart[band]]=LogAF[bandsendinc[band-1]];
xue@1 1099 for (int i=bandsstart[band]+1; i<=bandsendinc[band]; i++) LogAF[i]=LogAF[i-1]+0.5*(DAF[i]+DAF[i-1])/afres;
xue@1 1100 //then look for the shift required between bands
xue@1 1101 double cshift=0; int ccount=0;
xue@1 1102 for (int fr=lp[1]; fr<lp[P-1]; fr++)
xue@1 1103 {
xue@1 1104 double f=Partials[band-1][fr].f*afres;
xue@1 1105 if (bandsendinc[band-1]>bandsstart[band-1] && (f<bandsstart[band-1] || f>bandsendinc[band-1])) continue;
xue@1 1106 int intf=floor(f);
xue@1 1107 double logaflast=LogAF[intf]+(DAF[intf]+0.5*(DAF[intf+1]-DAF[intf])*(f-intf))*(f-intf)/afres;
xue@1 1108 f=Partials[band][fr].f*afres;
xue@1 1109 if (bandsendinc[band]>bandsstart[band] && (f<bandsstart[band] || f>bandsendinc[band])) continue;
xue@1 1110 intf=floor(f);
xue@1 1111 double logafthis=LogAF[intf]+(DAF[intf]+0.5*(DAF[intf+1]-DAF[intf])*(f-intf))*(f-intf)/afres;
xue@1 1112 cshift=cshift+log(Partials[band][fr].a*(band+1)/(Partials[band-1][fr].a*band))+logaflast-logafthis;
xue@1 1113 ccount++;
xue@1 1114 }
xue@1 1115 cshift/=ccount;
xue@1 1116 //apply the shift
xue@1 1117 for (int i=bandsstart[band]; i<=bandsendinc[band]; i++) LogAF[i]+=cshift;
xue@1 1118 //make up the blank band
xue@1 1119 int lastend=bandsendinc[band-1], thisstart=bandsstart[band];
xue@1 1120 for (int i=lastend+1; i<thisstart; i++) LogAF[i]=LogAF[lastend]+cshift*(i-lastend)/(thisstart-lastend);
xue@1 1121 band++;
xue@1 1122 }
xue@1 1123 delete[] DAF;
xue@1 1124
xue@1 1125 int tmpband=bandsstart[0]; for (int i=0; i<tmpband; i++) LogAF[i]=LogAF[tmpband];
xue@1 1126 tmpband=bandsendinc[nbands-1]; for (int i=tmpband; i<afres/2; i++) LogAF[i]=LogAF[tmpband];
xue@1 1127
xue@1 1128 //Here LogAF contains the filter model, new get the source model
xue@1 1129 memset(LogAS, 0, sizeof(double)*100);
xue@1 1130 for (int m=0; m<M; m++)
xue@1 1131 {
xue@1 1132 int ccount=0;
xue@1 1133 for (int fr=lp[1]; fr<lp[P-1]; fr++)
xue@1 1134 {
xue@1 1135 double f=Partials[m][fr].f*afres;
xue@1 1136 if (f<=0) continue;
xue@1 1137 int intf=floor(f);
xue@1 1138 LogAS[m]=LogAS[m]+log(Partials[m][fr].a/A0C[fr])-(LogAF[intf]*(intf+1-f)+LogAF[intf+1]*(f-intf));
xue@1 1139 ccount++;
xue@1 1140 }
xue@1 1141 if (ccount>0) LogAS[m]/=ccount;
xue@1 1142 else LogAS[m]=0;
xue@1 1143 }
xue@1 1144 return 0;
xue@1 1145 }//S_F
xue@1 1146
Chris@5 1147 /**
xue@1 1148 function S_F_SV: slow-variation source-filter estimation used in AES126, adapted from TSF to TVo.
xue@1 1149
xue@1 1150 In: afres: filter response resolution
xue@1 1151 Partials[M][Fr]: HS partials
xue@1 1152 A0C[Fr]: partial-independent amplitude carrier
xue@1 1153 lp[P]: cycle boundaries
xue@1 1154 F: filter response sampling interval
xue@1 1155 FScaleMode: set if filter sampling uses mel scale
xue@1 1156 theta: balancing factor of amplitude and frequency variations, needed for SV approach
xue@1 1157 Out: LogAF[afres/2]: filter response
xue@1 1158 LogAS[M]: source amplitudes
xue@1 1159
xue@1 1160 Returns 0.
xue@1 1161 */
xue@1 1162 double S_F_SV(int afres, double* LogAF, double* LogAS, int Fr, int M, atom** Partials, double* A0C, double* lp, int P, double F, int FScaleMode, double theta, double Fs)
xue@1 1163 {
xue@1 1164 int lp0=lp[1], lpp=lp[P-1];
xue@1 1165 int L=lpp-lp0;
xue@1 1166 Alloc2(L, M, loga); Alloc2(L, M, f);
xue@1 1167 double fmax=0;
xue@1 1168 for (int l=0; l<L; l++)
xue@1 1169 {
xue@1 1170 int fr=lp0+l;
xue@1 1171 for (int m=0; m<M; m++)
xue@1 1172 {
xue@1 1173 f[l][m]=Partials[m][fr].f;
xue@1 1174 if (FScaleMode) f[l][m]=log(1+f[l][m]*Fs/700)/log(1+Fs/700);
xue@1 1175 if (f[l][m]>0) loga[l][m]=log(Partials[m][fr].a);
xue@1 1176 else loga[l][m]=-100;
xue@1 1177 if (fmax<f[l][m]) fmax=f[l][m];
xue@1 1178 }
xue@1 1179 }
xue@1 1180 int K=floor(fmax/F);
xue@1 1181
xue@1 1182 Alloc2(L, K+2, h); memset(h[0], 0, sizeof(double)*L*(K+2));
xue@1 1183
xue@1 1184 SF_SV(h, L, M, K, loga, f, F, theta, 1e-6, L*(K+2));
xue@1 1185
xue@1 1186 for (int k=0; k<K+2; k++)
xue@1 1187 {
xue@1 1188 for (int l=1; l<L; l++) h[0][k]+=h[l][k];
xue@1 1189 h[0][k]/=L;
xue@1 1190 }
xue@1 1191
xue@1 1192 for (int i=0; i<afres/2; i++)
xue@1 1193 {
xue@1 1194 double freq=i*1.0/afres;
xue@1 1195 int k=floor(freq/F);
xue@1 1196 double f_plus=freq/F-k;
xue@1 1197 if (k<K+1) LogAF[i]=h[0][k]*(1-f_plus)+h[0][k+1]*f_plus;
xue@1 1198 else LogAF[i]=h[0][K+1];
xue@1 1199 }
xue@1 1200
xue@1 1201 memset(LogAS, 0, sizeof(double)*100);
xue@1 1202 for (int m=0; m<M; m++)
xue@1 1203 {
xue@1 1204 int ccount=0;
xue@1 1205 for (int fr=lp[1]; fr<lp[P-1]; fr++)
xue@1 1206 {
xue@1 1207 double f=Partials[m][fr].f*afres;
xue@1 1208 if (f<=0) continue;
xue@1 1209 int intf=floor(f);
xue@1 1210 LogAS[m]=LogAS[m]+log(Partials[m][fr].a/A0C[fr])-(LogAF[intf]*(intf+1-f)+LogAF[intf+1]*(f-intf));
xue@1 1211 ccount++;
xue@1 1212 }
xue@1 1213 if (ccount>0) LogAS[m]/=ccount;
xue@1 1214 else LogAS[m]=0;
xue@1 1215 }
xue@1 1216
xue@1 1217 DeAlloc2(loga); DeAlloc2(f); DeAlloc2(h);
xue@1 1218 return 0;
xue@1 1219 }//S_F_SV
xue@1 1220
Chris@5 1221 /**
xue@1 1222 function SynthesizeV: synthesizes a harmonic sinusoid from vibrato descriptors
xue@1 1223
xue@1 1224 In: V: a TVo object hosting vibrato descriptors
xue@1 1225 sps: sampling rate
xue@1 1226 UseK: maximal number of Fourier series components to use to construct frequency modulator
xue@1 1227 Out: HS: a harmonic sinusoid
xue@1 1228
xue@1 1229 No return value.
xue@1 1230 */
xue@1 1231 void SynthesizeV(THS* HS, TVo* V, double sps, int UseK)
xue@1 1232 {
xue@1 1233 int HSt0=HS->Partials[0][0].t, HSs0=HS->Partials[0][0].s, L=V->L, M=V->M,
xue@1 1234 P=V->P, *Kp=V->Kp, K=V->K, afres=V->afres;
xue@1 1235 double **fxr=V->fxr, *lp=V->lp, **LogASp=V->LogASp, *LogAF=V->LogAF, *Dp=V->Dp,
xue@1 1236 *F0C=V->F0C, *F0D=V->F0D, *F0=V->F0, *A0C=V->A0C, h=V->h;
xue@1 1237 HS->Resize(M, L);
xue@1 1238 double *gamp=new double[4*P], *gamm=&gamp[P];
xue@1 1239
xue@1 1240 Alloc2(P, K*2, newfxr);
xue@1 1241 int* newKp=new int[P];
xue@1 1242 for (int p=1; p<P; p++)
xue@1 1243 {
xue@1 1244 memcpy(newfxr[p], fxr[p], sizeof(double)*2*K);
xue@1 1245 newKp[p]=Kp[p]; if (UseK>=2 && newKp[p]>UseK) newKp[p]=UseK;
xue@1 1246 CorrectFS(newKp[p], newfxr[p]);
xue@1 1247 }
xue@1 1248
xue@1 1249 double f0, f1;
xue@1 1250 for (int p=1; p<P-1; p++)
xue@1 1251 {
xue@1 1252 if (p==1)
xue@1 1253 {
xue@1 1254 f0=newfxr[p][0]; for (int k=1; k<newKp[p]; k++) f0=f0+2*newfxr[p][2*k];
xue@1 1255 }
xue@1 1256 else f0=f1;
xue@1 1257 f1=newfxr[p+1][0]; for (int k=1; k<newKp[p+1]; k++) f1=f1+2*newfxr[p+1][2*k];
xue@1 1258 gamp[p]=(Dp[p+1]*f1-Dp[p]*f0)/2; gamm[p+1]=-gamp[p]; //additive correction
xue@1 1259 }
xue@1 1260 gamm[1]=-gamp[1], gamp[P-1]=-gamm[P-1]; //additive correction
xue@1 1261 atom** Partials=HS->Partials;
xue@1 1262 for (int p=0; p<P; p++)
xue@1 1263 {
xue@1 1264 double l0, lrange;
xue@1 1265 int lst, len, ilp;
xue@1 1266 if (p==0) lst=0, len=ceil(lp[0]), ilp=1;
xue@1 1267 else if (p==P-1) lst=ceil(lp[p-1]), len=L, ilp=p-1;
xue@1 1268 else lst=ceil(lp[p-1]), len=ceil(lp[p]), ilp=p;
xue@1 1269 l0=lp[ilp-1], lrange=lp[ilp]-l0;
xue@1 1270 for (int l=lst; l<len; l++)
xue@1 1271 {
xue@1 1272 Partials[0][l].s=HSs0;
xue@1 1273 Partials[0][l].t=HSt0+h*l;
xue@1 1274 double theta=(l-l0)/lrange;
xue@1 1275 double f0=newfxr[ilp][0]; for (int k=1; k<newKp[ilp]-1; k++) f0=f0+2*(newfxr[ilp][2*k-1]*sin(2*M_PI*k*theta)+newfxr[ilp][2*k]*cos(2*M_PI*k*theta));
xue@1 1276 F0D[l]=f0*Dp[ilp]+gamm[ilp]*(1-theta)+gamp[ilp]*theta; //additive correction
xue@1 1277 // V.F0D[l]=f0*V.Dp[lp]; //no correction
xue@1 1278 F0[l]=F0C[l]+F0D[l];
xue@1 1279 for (int m=0; m<M; m++)
xue@1 1280 {
xue@1 1281 Partials[m][l].s=HSs0;
xue@1 1282 Partials[m][l].t=Partials[0][l].t;
xue@1 1283 Partials[m][l].f=(m+1)*F0[l];
xue@1 1284 if (Partials[m][l].f>0.5 || Partials[m][l].f<0) Partials[m][l].a=0;
xue@1 1285 else if (ilp==1) Partials[m][l].a=A0C[l]*exp(LogASp[1][m]*(1-0.5*theta)+LogASp[2][m]*0.5*theta+LogAF[int(Partials[m][l].f*afres)]);
xue@1 1286 else if (ilp==P-1) Partials[m][l].a=A0C[l]*exp(LogASp[ilp][m]*0.5*(1+theta)+LogASp[ilp-1][m]*0.5*(1-theta)+LogAF[int(Partials[m][l].f*afres)]);
xue@1 1287 else
xue@1 1288 // Partials[m][l].a=A0C[l]*exp(LogASp[ilp][m]*0.5+LogASp[ilp-1][m]*0.5*(1-theta)+LogASp[ilp+1][m]*0.5*theta+LogAF[int(Partials[m][l].f*afres)]);
xue@1 1289 Partials[m][l].a=A0C[l]*exp(LogASp[p][m]+LogAF[int(Partials[m][l].f*afres)]);
xue@1 1290 }
xue@1 1291 }
xue@1 1292 }
xue@1 1293 delete[] gamp;
xue@1 1294 DeAlloc2(newfxr);
xue@1 1295 delete[] newKp;
xue@1 1296 // VibratoDemoForm->Label13->Caption=L;
xue@1 1297 }//SynthesizeV
xue@1 1298
xue@1 1299
xue@1 1300
xue@1 1301
xue@1 1302
xue@1 1303