annotate vibrato.cpp @ 13:de3961f74f30 tip

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