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