Mercurial > hg > x
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 |