annotate vibrato.cpp @ 1:6422640a802f

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