comparison vibrato.cpp @ 5:5f3c32dc6e17

* Adjust comment syntax to permit Doxygen to generate HTML documentation; add Doxyfile
author Chris Cannam
date Wed, 06 Oct 2010 15:19:49 +0100
parents fc19d45615d1
children 977f541d6683
comparison
equal deleted inserted replaced
4:92ee28024c05 5:5f3c32dc6e17
1 //--------------------------------------------------------------------------- 1 //---------------------------------------------------------------------------
2
3 2
4 #include <math.h> 3 #include <math.h>
5 #include <string.h> 4 #include <string.h>
6 #include "vibrato.h" 5 #include "vibrato.h"
7 #include "arrayalloc.h" 6 #include "arrayalloc.h"
8 #include "fft.h" 7 #include "fft.h"
9 #include "hssf.h" 8 #include "hssf.h"
10 #include "matrix.h" 9 #include "matrix.h"
11 #include "splines.h" 10 #include "splines.h"
12 #include "xcomplex.h" 11 #include "xcomplex.h"
12
13 /** \file vibrato.h */
14
13 //--------------------------------------------------------------------------- 15 //---------------------------------------------------------------------------
14 //method TVo::TVo: default constructor 16 //method TVo::TVo: default constructor
15 TVo::TVo() 17 TVo::TVo()
16 { 18 {
17 memset(this, 0, sizeof(TVo)); 19 memset(this, 0, sizeof(TVo));
27 if (fxr) DeAlloc2(fxr); 29 if (fxr) DeAlloc2(fxr);
28 if (fres) DeAlloc2(fres); 30 if (fres) DeAlloc2(fres);
29 if (LogASp) DeAlloc2(LogASp); 31 if (LogASp) DeAlloc2(LogASp);
30 }//~TVo 32 }//~TVo
31 33
32 /* 34 /**
33 method TVo::AllocateL: allocates or reallocates storage space whose size depends on L. This uses an 35 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. 36 external L value for allocation and updates L itself.
35 */ 37 */
36 void TVo::AllocateL(int AnL) 38 void TVo::AllocateL(int AnL)
37 { 39 {
39 delete[] F0; 41 delete[] F0;
40 F0=new double[(L+2)*4]; 42 F0=new double[(L+2)*4];
41 F0C=&F0[L+2], F0D=&F0[(L+2)*2], A0C=&F0[(L+2)*3]; 43 F0C=&F0[L+2], F0D=&F0[(L+2)*2], A0C=&F0[(L+2)*3];
42 }//AllocateL 44 }//AllocateL
43 45
44 /* 46 /**
45 method TVo::AllocateP: allocates or reallocates storage space whose size depends on P, using the 47 method TVo::AllocateP: allocates or reallocates storage space whose size depends on P, using the
46 interal P. 48 interal P.
47 */ 49 */
48 void TVo::AllocateP() 50 void TVo::AllocateP()
49 { 51 {
52 Dp=&lp[P+2]; 54 Dp=&lp[P+2];
53 Kp=(int*)&lp[(P+2)*2]; 55 Kp=(int*)&lp[(P+2)*2];
54 if (LogASp) DeAlloc2(LogASp); Allocate2(double, P, M, LogASp); 56 if (LogASp) DeAlloc2(LogASp); Allocate2(double, P, M, LogASp);
55 }//AllocateP 57 }//AllocateP
56 58
57 /* 59 /**
58 method TVo::AllocatePK: allocates or reallocates storage space whose size depends on both P and K. 60 method TVo::AllocatePK: allocates or reallocates storage space whose size depends on both P and K.
59 */ 61 */
60 void TVo::AllocatePK() 62 void TVo::AllocatePK()
61 { 63 {
62 if (fxr) DeAlloc2(fxr); 64 if (fxr) DeAlloc2(fxr);
64 memset(fxr[0], 0, sizeof(double)*P*(2*K+1)); 66 memset(fxr[0], 0, sizeof(double)*P*(2*K+1));
65 if (fres) DeAlloc2(fres); 67 if (fres) DeAlloc2(fres);
66 Allocate2(double, P, K, fres); 68 Allocate2(double, P, K, fres);
67 }//AllocatePK 69 }//AllocatePK
68 70
69 /* 71 /**
70 method TVo::GetOldP: returns the number of "equivalent" cycles of the whole duration. Although P-1 72 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 73 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. 74 harmonic sinusoid being modeled and therefore should be taken into account when necessary.
73 */ 75 */
74 double TVo::GetOldP() 76 double TVo::GetOldP()
75 { 77 {
76 return P-1+lp[0]/(lp[1]-lp[0])+(L-lp[P-1])/(lp[P-1]-lp[P-2]); 78 return P-1+lp[0]/(lp[1]-lp[0])+(L-lp[P-1])/(lp[P-1]-lp[P-2]);
77 }//GetOldP 79 }//GetOldP
78 80
79 /* 81 /**
80 methodTVo::LoadFromFileHandle: reads TVo object from a file stream. 82 methodTVo::LoadFromFileHandle: reads TVo object from a file stream.
81 */ 83 */
82 void TVo::LoadFromFileHandle(FILE* file) 84 void TVo::LoadFromFileHandle(FILE* file)
83 { 85 {
84 fread(&M, sizeof(int), 1, file); 86 fread(&M, sizeof(int), 1, file);
97 fread(Kp, sizeof(int), P, file); 99 fread(Kp, sizeof(int), P, file);
98 fread(fxr[0], sizeof(double), P*(2*K+1), file); 100 fread(fxr[0], sizeof(double), P*(2*K+1), file);
99 fread(LogASp[0], sizeof(double), P*M, file); 101 fread(LogASp[0], sizeof(double), P*M, file);
100 }//LoadFromFileHandle 102 }//LoadFromFileHandle
101 103
102 /* 104 /**
103 method TVo::ReAllocateL: reallocates storage space whose size depends on L, and transfer the contents. 105 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. 106 This uses an external L value for allocation but does not update L itself.
105 */ 107 */
106 void TVo::ReAllocateL(int newL) 108 void TVo::ReAllocateL(int newL)
107 { 109 {
113 memcpy(newF0, F0, sizeof(double)*(L+2)); 115 memcpy(newF0, F0, sizeof(double)*(L+2));
114 delete[] F0; 116 delete[] F0;
115 F0=newF0; 117 F0=newF0;
116 }//ReAllocateL 118 }//ReAllocateL
117 119
118 /* 120 /**
119 method TVo::SaveToFile: saves a TVo object to a file. 121 method TVo::SaveToFile: saves a TVo object to a file.
120 122
121 In: filename: path to the destination file. 123 In: filename: path to the destination file.
122 */ 124 */
123 void TVo::SaveToFile(char* filename) 125 void TVo::SaveToFile(char* filename)
132 { 134 {
133 throw(strcat((char*)"Cannot open file ", filename)); 135 throw(strcat((char*)"Cannot open file ", filename));
134 } 136 }
135 }//SaveToFile 137 }//SaveToFile
136 138
137 /* 139 /**
138 method TVo::SaveToFileHandle: saves a TVo object to an open file stream. 140 method TVo::SaveToFileHandle: saves a TVo object to an open file stream.
139 */ 141 */
140 void TVo::SaveToFileHandle(FILE* file) 142 void TVo::SaveToFileHandle(FILE* file)
141 { 143 {
142 fwrite(&M, sizeof(int), 1, file); 144 fwrite(&M, sizeof(int), 1, file);
158 160
159 //--------------------------------------------------------------------------- 161 //---------------------------------------------------------------------------
160 //functions 162 //functions
161 163
162 164
163 /* 165 /**
164 function AnalyzeV: calculates all basic and non-basic descriptors of a vibrato from a harmonic 166 function AnalyzeV: calculates all basic and non-basic descriptors of a vibrato from a harmonic
165 sinusoid 167 sinusoid
166 168
167 In: HS: harmonic sinusoid to compute vibrato representation from 169 In: HS: harmonic sinusoid to compute vibrato representation from
168 sps: sampling rate 170 sps: sampling rate
331 } 333 }
332 V.FXR[2*k-1]/=sumdp, V.FXR[2*k]/=sumdp, V.FRes[k]/=sumdp; 334 V.FXR[2*k-1]/=sumdp, V.FXR[2*k]/=sumdp, V.FRes[k]/=sumdp;
333 } 335 }
334 }//AnalyzeV 336 }//AnalyzeV
335 337
336 /* 338 /**
337 function copeak: measures the similarity of F0 between frst and fren to a cosine cycle 0~2pi. 339 function copeak: measures the similarity of F0 between frst and fren to a cosine cycle 0~2pi.
338 340
339 In: F0[peakfr[frst]:peakfr[fren]] 341 In: F0[peakfr[frst]:peakfr[fren]]
340 periodinframe: period of the cosine reference, in frames 342 periodinframe: period of the cosine reference, in frames
341 343
351 rfs+=(f-ef0)*s; rff+=(f-ef0)*(f-ef0); rss+=s*s; 353 rfs+=(f-ef0)*s; rff+=(f-ef0)*(f-ef0); rss+=s*s;
352 } 354 }
353 return rfs/sqrt(rff*rss); 355 return rfs/sqrt(rff*rss);
354 }//copeak 356 }//copeak
355 357
356 /* 358 /**
357 function CorrectFS: time-shifts Fourier series so that maximum is reached at 0. This is done by 359 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. 360 finding the actual peak numerically then shifting it to 0.
359 361
360 In: c[2K-1]: Fourier series coefficients, in the order of 0r, 1i, 1r, 2i, 2r, ..., so that the series 362 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 363 is expanded as c[0]+c[1]sinx+c[2]cosx+c[3]sin2x+c[4]cos2x+...c[2K-2]cos(K-1)x
397 double tmp=c[2*k]*cc+c[2*k-1]*ss; 399 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; 400 c[2*k-1]=-c[2*k]*ss+c[2*k-1]*cc; c[2*k]=tmp;
399 } 401 }
400 }//CorrectFS 402 }//CorrectFS
401 403
402 /* 404 /**
403 function DeAM: amplitude demodulation based on given segmentation into cycles 405 function DeAM: amplitude demodulation based on given segmentation into cycles
404 406
405 In: A1[Fr]: original amplitude 407 In: A1[Fr]: original amplitude
406 peakfr[npfr]: cycle boundaries (literally, "frame indices of frequency modulation peaks") 408 peakfr[npfr]: cycle boundaries (literally, "frame indices of frequency modulation peaks")
407 Out: A2[Fr]: demodulated amplitude 409 Out: A2[Fr]: demodulated amplitude
447 delete[] fa; 449 delete[] fa;
448 } 450 }
449 delete[] frs; 451 delete[] frs;
450 }//DeAM 452 }//DeAM
451 453
452 /* 454 /**
453 function DeAM: wrapper function using floating-point cycle boundaries 455 function DeAM: wrapper function using floating-point cycle boundaries
454 456
455 In: A1[Fr]: original amplitude 457 In: A1[Fr]: original amplitude
456 lp[npfr]: cycle boundaries 458 lp[npfr]: cycle boundaries
457 Out: A2[Fr]: demodulated amplitude 459 Out: A2[Fr]: demodulated amplitude
464 for (int i=0; i<npfr; i++) peakfr[i]=ceil(lp[i]); 466 for (int i=0; i<npfr; i++) peakfr[i]=ceil(lp[i]);
465 DeAM(A2, A1, npfr, peakfr, Fr); 467 DeAM(A2, A1, npfr, peakfr, Fr);
466 delete[] peakfr; 468 delete[] peakfr;
467 }//DeAM 469 }//DeAM
468 470
469 /* 471 /**
470 function DeFM: frequency demodulation based on given segmentation into cycles 472 function DeFM: frequency demodulation based on given segmentation into cycles
471 473
472 In: f1[Fr], AA[Fr]: original frequency and partial-independent amplitude 474 In: f1[Fr], AA[Fr]: original frequency and partial-independent amplitude
473 peakfr[npfr]: cycle boundaries (literally, "frame indices of frequency modulation peaks") 475 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 476 furthursmoothing: specifies if a second round demodulation is to be performed for more smooth
538 540
539 if (localfrs) delete[] frs; 541 if (localfrs) delete[] frs;
540 if (localf) delete[] f; 542 if (localf) delete[] f;
541 }//DeFM 543 }//DeFM
542 544
543 /* 545 /**
544 function DeFM: wrapper function using floating-point cycle boundaries 546 function DeFM: wrapper function using floating-point cycle boundaries
545 547
546 In: f1[Fr], AA[Fr]: original frequency and partial-independent amplitude 548 In: f1[Fr], AA[Fr]: original frequency and partial-independent amplitude
547 lp[npfr]: cycle boundaries 549 lp[npfr]: cycle boundaries
548 furthursmoothing: specifies if a second round demodulation is to be performed for more smooth 550 furthursmoothing: specifies if a second round demodulation is to be performed for more smooth
559 for (int i=0; i<npfr; i++) peakfr[i]=ceil(lp[i]); 561 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); 562 DeFM(f2, f1, AA, npfr, peakfr, Fr, fct, fcount, frs, f, furthersmoothing);
561 delete[] peakfr; 563 delete[] peakfr;
562 }//DeFM 564 }//DeFM
563 565
564 /* 566 /**
565 function FindPeaks: find modulation peaks of signal F0[] roughly periodical at $periodinframe 567 function FindPeaks: find modulation peaks of signal F0[] roughly periodical at $periodinframe
566 568
567 In: F0[Fr]: modulated signal 569 In: F0[Fr]: modulated signal
568 periodinframe: reference modulation period 570 periodinframe: reference modulation period
569 Out: npfr, peakfr[npfr]: modulation peaks 571 Out: npfr, peakfr[npfr]: modulation peaks
667 npfr=pen-pst; 669 npfr=pen-pst;
668 memmove(peakfr, &peakfr[pst], sizeof(int)*npfr); //*/ 670 memmove(peakfr, &peakfr[pst], sizeof(int)*npfr); //*/
669 if (localpeaky) delete[] peaky; 671 if (localpeaky) delete[] peaky;
670 }//FindPeaks 672 }//FindPeaks
671 673
672 /* 674 /**
673 function FS: Fourier series decomposition 675 function FS: Fourier series decomposition
674 676
675 In: data[frst:fren]: signal to decompose 677 In: data[frst:fren]: signal to decompose
676 period: period of Fourier series decomposition 678 period: period of Fourier series decomposition
677 shift: amount of original shift of Fourier components (from frst to frst-shift) 679 shift: amount of original shift of Fourier components (from frst to frst-shift)
724 } 726 }
725 delete[] rec; 727 delete[] rec;
726 delete[] res; 728 delete[] res;
727 }//FS 729 }//FS
728 730
729 /* 731 /**
730 function FS_QR: Fourier series decomposition with QR orthogonalization. Since the Fourier series is 732 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 733 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 734 other. A decreasing residue can be guaranteed by applying QR (or any other) orthogonalization process
733 to the Fourier components before decomposition. 735 to the Fourier components before decomposition.
734 736
802 /* debug only 804 /* debug only
803 delete[] res; //*/ 805 delete[] res; //*/
804 DeAlloc2(A); DeAlloc2(Q); DeAlloc2(R); 806 DeAlloc2(A); DeAlloc2(Q); DeAlloc2(R);
805 }//FS_QR 807 }//FS_QR
806 808
807 /* 809 /**
808 function InterpolateV: adjusts modulation rate to $rate times the current value. Since TVo is based on 810 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- 811 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. 812 cycle descriptors by interpolation. This is used for time stretching and cycle rate adjustment.
811 813
812 In: V: a TVo object to adjust 814 In: V: a TVo object to adjust
888 890
889 //vibrato rate boundaries, in Hz 891 //vibrato rate boundaries, in Hz
890 #define MAXMOD 15.0 892 #define MAXMOD 15.0
891 #define MINMOD 3.0 893 #define MINMOD 3.0
892 894
893 /* 895 /**
894 function RateAndReg: evaluates modulation rate and regularity 896 function RateAndReg: evaluates modulation rate and regularity
895 897
896 In: data[frst:fren]: modulated signal, time measured in frames 898 In: data[frst:fren]: modulated signal, time measured in frames
897 padrate: padding rate used for inverse FFT 899 padrate: padding rate used for inverse FFT
898 sps: sampling frequency 900 sps: sampling frequency
949 regularity=(maxlf-0.25*b_*b_/a_)/lf[0]*(fren-frst)/(fren-frst-period); 951 regularity=(maxlf-0.25*b_*b_/a_)/lf[0]*(fren-frst)/(fren-frst-period);
950 952
951 delete[] lf; 953 delete[] lf;
952 }//RateAndReg 954 }//RateAndReg
953 955
954 /* 956 /**
955 function RegularizeV: synthesize a regular vibrato from the basic descriptors. 957 function RegularizeV: synthesize a regular vibrato from the basic descriptors.
956 958
957 In: V: a TVo object hosting vibrato descriptors 959 In: V: a TVo object hosting vibrato descriptors
958 sps: sampling rate 960 sps: sampling rate
959 h: hop size 961 h: hop size
993 } 995 }
994 996
995 delete[] fxr; 997 delete[] fxr;
996 }//RegularizeV 998 }//RegularizeV
997 999
998 /* 1000 /**
999 function QIE: computes extremum using quadratic interpolation 1001 function QIE: computes extremum using quadratic interpolation
1000 1002
1001 In: y[-1:1]: three points to interpolate from. It is assumed y[0] is larger (or smaller) than both 1003 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]. 1004 y[-1] and y[1].
1003 1005
1007 { 1009 {
1008 double a=0.5*(y[1]+y[-1])-y[0], b=0.5*(y[1]-y[-1]); 1010 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; 1011 return y[0]-0.25*b*b/a;
1010 }//QIE 1012 }//QIE
1011 1013
1012 /* 1014 /**
1013 function QIE: computes extremum using quadratic interpolation 1015 function QIE: computes extremum using quadratic interpolation
1014 1016
1015 In: y[-1:1]: three points to interpolate from. It is assumed y[0] is larger (or smaller) than both 1017 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]. 1018 y[-1] and y[1].
1017 Out: x: the argument value that yields extremum of y(x) 1019 Out: x: the argument value that yields extremum of y(x)
1023 double a=0.5*(y[1]+y[-1])-y[0], b=0.5*(y[1]-y[-1]); 1025 double a=0.5*(y[1]+y[-1])-y[0], b=0.5*(y[1]-y[-1]);
1024 x=-0.5*b/a; 1026 x=-0.5*b/a;
1025 return y[0]-0.25*b*b/a; 1027 return y[0]-0.25*b*b/a;
1026 }//QIE 1028 }//QIE
1027 1029
1028 /* 1030 /**
1029 function S_F: original source-filter estimation used in AES124. 1031 function S_F: original source-filter estimation used in AES124.
1030 1032
1031 In: afres: filter response resolution 1033 In: afres: filter response resolution
1032 Partials[M][Fr]: HS partials 1034 Partials[M][Fr]: HS partials
1033 A0C[Fr]: partial-independent amplitude carrier 1035 A0C[Fr]: partial-independent amplitude carrier
1140 else LogAS[m]=0; 1142 else LogAS[m]=0;
1141 } 1143 }
1142 return 0; 1144 return 0;
1143 }//S_F 1145 }//S_F
1144 1146
1145 /* 1147 /**
1146 function S_F_SV: slow-variation source-filter estimation used in AES126, adapted from TSF to TVo. 1148 function S_F_SV: slow-variation source-filter estimation used in AES126, adapted from TSF to TVo.
1147 1149
1148 In: afres: filter response resolution 1150 In: afres: filter response resolution
1149 Partials[M][Fr]: HS partials 1151 Partials[M][Fr]: HS partials
1150 A0C[Fr]: partial-independent amplitude carrier 1152 A0C[Fr]: partial-independent amplitude carrier
1214 1216
1215 DeAlloc2(loga); DeAlloc2(f); DeAlloc2(h); 1217 DeAlloc2(loga); DeAlloc2(f); DeAlloc2(h);
1216 return 0; 1218 return 0;
1217 }//S_F_SV 1219 }//S_F_SV
1218 1220
1219 /* 1221 /**
1220 function SynthesizeV: synthesizes a harmonic sinusoid from vibrato descriptors 1222 function SynthesizeV: synthesizes a harmonic sinusoid from vibrato descriptors
1221 1223
1222 In: V: a TVo object hosting vibrato descriptors 1224 In: V: a TVo object hosting vibrato descriptors
1223 sps: sampling rate 1225 sps: sampling rate
1224 UseK: maximal number of Fourier series components to use to construct frequency modulator 1226 UseK: maximal number of Fourier series components to use to construct frequency modulator