Mercurial > hg > x
comparison procedures.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 | 42c078b19e9a |
children | f0d2c9b5d3a3 |
comparison
equal
deleted
inserted
replaced
4:92ee28024c05 | 5:5f3c32dc6e17 |
---|---|
6 #include "procedures.h" | 6 #include "procedures.h" |
7 #include "matrix.h" | 7 #include "matrix.h" |
8 #include "opt.h" | 8 #include "opt.h" |
9 #include "sinest.h" | 9 #include "sinest.h" |
10 | 10 |
11 /** \file procedures.h */ | |
12 | |
11 //--------------------------------------------------------------------------- | 13 //--------------------------------------------------------------------------- |
12 //TGMM methods | 14 //TGMM methods |
13 | 15 |
14 //method TGMM::TGMM: default constructor | 16 //method TGMM::TGMM: default constructor |
15 TGMM::TGMM() | 17 TGMM::TGMM() |
38 TTFSpans::~TTFSpans() | 40 TTFSpans::~TTFSpans() |
39 { | 41 { |
40 delete[] Items; | 42 delete[] Items; |
41 }//~TTFSpans | 43 }//~TTFSpans |
42 | 44 |
43 /* | 45 /** |
44 method Add: add a new span to the list | 46 method Add: add a new span to the list |
45 | 47 |
46 In: ATFSpan: the new span to add | 48 In: ATFSpan: the new span to add |
47 */ | 49 */ |
48 void TTFSpans::Add(TTFSpan& ATFSpan) | 50 void TTFSpans::Add(TTFSpan& ATFSpan) |
58 } | 60 } |
59 Items[Count]=ATFSpan; | 61 Items[Count]=ATFSpan; |
60 Count++; | 62 Count++; |
61 }//Add | 63 }//Add |
62 | 64 |
63 /* | 65 /** |
64 method Clear: discard the current content without freeing memory. | 66 method Clear: discard the current content without freeing memory. |
65 */ | 67 */ |
66 void TTFSpans::Clear() | 68 void TTFSpans::Clear() |
67 { | 69 { |
68 Count=0; | 70 Count=0; |
69 }//Clear | 71 }//Clear |
70 | 72 |
71 /* | 73 /** |
72 method Delete: delete a span from current list | 74 method Delete: delete a span from current list |
73 | 75 |
74 In: Index: index to the span to delete | 76 In: Index: index to the span to delete |
75 */ | 77 */ |
76 int TTFSpans::Delete(int Index) | 78 int TTFSpans::Delete(int Index) |
83 }//Delete | 85 }//Delete |
84 | 86 |
85 //--------------------------------------------------------------------------- | 87 //--------------------------------------------------------------------------- |
86 //SpecTrack methods | 88 //SpecTrack methods |
87 | 89 |
88 /* | 90 /** |
89 method TSpecTrack::Add: adds a SpecPeak to the track. | 91 method TSpecTrack::Add: adds a SpecPeak to the track. |
90 | 92 |
91 In: APeak: the SpecPeak to add. | 93 In: APeak: the SpecPeak to add. |
92 */ | 94 */ |
93 int TSpecTrack::Add(TSpecPeak& APeak) | 95 int TSpecTrack::Add(TSpecPeak& APeak) |
115 else if (f>fmax) fmax=f; | 117 else if (f>fmax) fmax=f; |
116 } | 118 } |
117 return ind; | 119 return ind; |
118 }//Add | 120 }//Add |
119 | 121 |
120 /* | 122 /** |
121 method TSpecTrack::TSpecTrack: creates a SpecTrack with an inital capacity. | 123 method TSpecTrack::TSpecTrack: creates a SpecTrack with an inital capacity. |
122 | 124 |
123 In: ACapacity: initial capacity, i.e. the number SpecPeak's to allocate storage space for. | 125 In: ACapacity: initial capacity, i.e. the number SpecPeak's to allocate storage space for. |
124 */ | 126 */ |
125 TSpecTrack::TSpecTrack(int ACapacity) | 127 TSpecTrack::TSpecTrack(int ACapacity) |
133 TSpecTrack::~TSpecTrack() | 135 TSpecTrack::~TSpecTrack() |
134 { | 136 { |
135 delete[] Peaks; | 137 delete[] Peaks; |
136 }//TSpecTrack | 138 }//TSpecTrack |
137 | 139 |
138 /* | 140 /** |
139 method InsertPeak: inserts a new SpecPeak into the track at a given index. Internal use only. | 141 method InsertPeak: inserts a new SpecPeak into the track at a given index. Internal use only. |
140 | 142 |
141 In: APeak: the SpecPeak to insert. | 143 In: APeak: the SpecPeak to insert. |
142 index: the position in the list to place the new SpecPeak. Original SpecPeak's at and after this | 144 index: the position in the list to place the new SpecPeak. Original SpecPeak's at and after this |
143 position are shifted by 1 posiiton. | 145 position are shifted by 1 posiiton. |
147 memmove(&Peaks[index+1], &Peaks[index], sizeof(TSpecPeak)*(Count-index)); | 149 memmove(&Peaks[index+1], &Peaks[index], sizeof(TSpecPeak)*(Count-index)); |
148 Peaks[index]=APeak; | 150 Peaks[index]=APeak; |
149 Count++; | 151 Count++; |
150 }//InsertPeak | 152 }//InsertPeak |
151 | 153 |
152 /* | 154 /** |
153 method TSpecTrack::LocatePeak: looks for a SpecPeak in the track that has the same time (t) as APeak. | 155 method TSpecTrack::LocatePeak: looks for a SpecPeak in the track that has the same time (t) as APeak. |
154 | 156 |
155 In: APeak: a SpecPeak | 157 In: APeak: a SpecPeak |
156 | 158 |
157 Returns the index in this track of the first SpecPeak that has the same time stamp as APeak. However, | 159 Returns the index in this track of the first SpecPeak that has the same time stamp as APeak. However, |
175 } | 177 } |
176 return -a-2; | 178 return -a-2; |
177 }//LocatePeak | 179 }//LocatePeak |
178 | 180 |
179 //--------------------------------------------------------------------------- | 181 //--------------------------------------------------------------------------- |
180 /* | 182 /** |
181 function: ACPower: AC power | 183 function: ACPower: AC power |
182 | 184 |
183 In: data[Count]: a signal | 185 In: data[Count]: a signal |
184 | 186 |
185 Returns the power of its AC content. | 187 Returns the power of its AC content. |
197 power=(power-avg*avg)/Count; | 199 power=(power-avg*avg)/Count; |
198 return power; | 200 return power; |
199 }//ACPower | 201 }//ACPower |
200 | 202 |
201 //--------------------------------------------------------------------------- | 203 //--------------------------------------------------------------------------- |
202 /* | 204 /** |
203 function Add: vector addition | 205 function Add: vector addition |
204 | 206 |
205 In: dest[Count], source[Count]: two vectors | 207 In: dest[Count], source[Count]: two vectors |
206 Out: dest[Count]: their sum | 208 Out: dest[Count]: their sum |
207 | 209 |
210 void Add(double* dest, double* source, int Count) | 212 void Add(double* dest, double* source, int Count) |
211 { | 213 { |
212 for (int i=0; i<Count; i++) *(dest++)+=*(source++); | 214 for (int i=0; i<Count; i++) *(dest++)+=*(source++); |
213 }//Add | 215 }//Add |
214 | 216 |
215 /* | 217 /** |
216 function Add: vector addition | 218 function Add: vector addition |
217 | 219 |
218 In: addend[count], adder[count]: two vectors | 220 In: addend[count], adder[count]: two vectors |
219 Out: out[count]: their sum | 221 Out: out[count]: their sum |
220 | 222 |
225 for (int i=0; i<count; i++) *(out++)=*(addend++)+*(adder++); | 227 for (int i=0; i<count; i++) *(out++)=*(addend++)+*(adder++); |
226 }//Add | 228 }//Add |
227 | 229 |
228 //--------------------------------------------------------------------------- | 230 //--------------------------------------------------------------------------- |
229 | 231 |
230 /* | 232 /** |
231 function ApplyWindow: applies window function to signal buffer. | 233 function ApplyWindow: applies window function to signal buffer. |
232 | 234 |
233 In: Buffer[Size]: signal to be windowed | 235 In: Buffer[Size]: signal to be windowed |
234 Weight[Size]: the window | 236 Weight[Size]: the window |
235 Out: OutBuffer[Size]: windowed signal | 237 Out: OutBuffer[Size]: windowed signal |
240 { | 242 { |
241 for (int i=0; i<Size; i++) *(OutBuffer++)=*(Buffer++)**(Weights++); | 243 for (int i=0; i<Size; i++) *(OutBuffer++)=*(Buffer++)**(Weights++); |
242 }//ApplyWindow | 244 }//ApplyWindow |
243 | 245 |
244 //--------------------------------------------------------------------------- | 246 //--------------------------------------------------------------------------- |
245 /* | 247 /** |
246 function Avg: average | 248 function Avg: average |
247 | 249 |
248 In: data[Count]: a data array | 250 In: data[Count]: a data array |
249 | 251 |
250 Returns the average of the array. | 252 Returns the average of the array. |
257 avg/=Count; | 259 avg/=Count; |
258 return avg; | 260 return avg; |
259 }//Avg | 261 }//Avg |
260 | 262 |
261 //--------------------------------------------------------------------------- | 263 //--------------------------------------------------------------------------- |
262 /* | 264 /** |
263 function AvgFilter: get slow-varying wave trace by averaging | 265 function AvgFilter: get slow-varying wave trace by averaging |
264 | 266 |
265 In: data[Count]: input signal | 267 In: data[Count]: input signal |
266 HWid: half the size of the averaging window | 268 HWid: half the size of the averaging window |
267 Out: datout[Count]: the slow-varying part of data[]. | 269 Out: datout[Count]: the slow-varying part of data[]. |
292 dataout[i]=sum/(2*(Count-i)-1); | 294 dataout[i]=sum/(2*(Count-i)-1); |
293 } | 295 } |
294 }//AvgFilter | 296 }//AvgFilter |
295 | 297 |
296 //--------------------------------------------------------------------------- | 298 //--------------------------------------------------------------------------- |
297 /* | 299 /** |
298 function CalculateSpectrogram: computes the spectrogram of a signal | 300 function CalculateSpectrogram: computes the spectrogram of a signal |
299 | 301 |
300 In: data[Count]: the time-domain signal | 302 In: data[Count]: the time-domain signal |
301 start, end: start and end points marking the section for which the spectrogram is to be computed | 303 start, end: start and end points marking the section for which the spectrogram is to be computed |
302 Wid, Offst: frame size and hop size | 304 Wid, Offst: frame size and hop size |
335 } | 337 } |
336 FreeFFTBuffer(fft); | 338 FreeFFTBuffer(fft); |
337 }//CalculateSpectrogram | 339 }//CalculateSpectrogram |
338 | 340 |
339 //--------------------------------------------------------------------------- | 341 //--------------------------------------------------------------------------- |
340 /* | 342 /** |
341 function Conv: simple convolution | 343 function Conv: simple convolution |
342 | 344 |
343 In: in1[N1], in2[N2]: two sequences | 345 In: in1[N1], in2[N2]: two sequences |
344 Out: out[N1+N2-1]: their convolution | 346 Out: out[N1+N2-1]: their convolution |
345 | 347 |
353 for (int n2=0; n2<N2; n2++) | 355 for (int n2=0; n2<N2; n2++) |
354 out[n1+n2]+=in1[n1]*in2[n2]; | 356 out[n1+n2]+=in1[n1]*in2[n2]; |
355 }//Conv | 357 }//Conv |
356 | 358 |
357 //--------------------------------------------------------------------------- | 359 //--------------------------------------------------------------------------- |
358 /* | 360 /** |
359 function Correlation: computes correlation coefficient of 2 vectors a & b, equals cos(aOb). | 361 function Correlation: computes correlation coefficient of 2 vectors a & b, equals cos(aOb). |
360 | 362 |
361 In: a[Count], b[Count]: two vectors | 363 In: a[Count], b[Count]: two vectors |
362 | 364 |
363 Returns their correlation coefficient. | 365 Returns their correlation coefficient. |
373 } | 375 } |
374 return ab/sqrt(aa*bb); | 376 return ab/sqrt(aa*bb); |
375 }//Correlation | 377 }//Correlation |
376 | 378 |
377 //--------------------------------------------------------------------------- | 379 //--------------------------------------------------------------------------- |
378 /* | 380 /** |
379 function DCAmplitude: DC amplitude | 381 function DCAmplitude: DC amplitude |
380 | 382 |
381 In: data[Count]: a signal | 383 In: data[Count]: a signal |
382 | 384 |
383 Returns its DC amplitude (=AC amplitude without DC removing) | 385 Returns its DC amplitude (=AC amplitude without DC removing) |
393 } | 395 } |
394 power/=Count; | 396 power/=Count; |
395 return sqrt(2*power); | 397 return sqrt(2*power); |
396 }//DCAmplitude | 398 }//DCAmplitude |
397 | 399 |
398 /* | 400 /** |
399 function DCPower: DC power | 401 function DCPower: DC power |
400 | 402 |
401 In: data[Count]: a signal | 403 In: data[Count]: a signal |
402 | 404 |
403 Returns its DC power. | 405 Returns its DC power. |
414 power/=Count; | 416 power/=Count; |
415 return power; | 417 return power; |
416 }//DCPower | 418 }//DCPower |
417 | 419 |
418 //--------------------------------------------------------------------------- | 420 //--------------------------------------------------------------------------- |
419 /* | 421 /** |
420 DCT: discrete cosine transform, direct computation. For fast DCT, see fft.cpp. | 422 DCT: discrete cosine transform, direct computation. For fast DCT, see fft.cpp. |
421 | 423 |
422 In: input[N]: a signal | 424 In: input[N]: a signal |
423 Out: output[N]: its DCT | 425 Out: output[N]: its DCT |
424 | 426 |
437 if (n==0) output[n]*=1.4142135623730950488016887242097/N; | 439 if (n==0) output[n]*=1.4142135623730950488016887242097/N; |
438 else output[n]*=2.0/N; | 440 else output[n]*=2.0/N; |
439 } | 441 } |
440 }//DCT | 442 }//DCT |
441 | 443 |
442 /* | 444 /** |
443 function IDCT: inverse discrete cosine transform, direct computation. For fast IDCT, see fft.cpp. | 445 function IDCT: inverse discrete cosine transform, direct computation. For fast IDCT, see fft.cpp. |
444 | 446 |
445 In: input[N]: a signal | 447 In: input[N]: a signal |
446 Out: output[N]: its IDCT | 448 Out: output[N]: its IDCT |
447 | 449 |
457 output[k]+=input[n]*cos(n*Wk); | 459 output[k]+=input[n]*cos(n*Wk); |
458 } | 460 } |
459 }//IDCT | 461 }//IDCT |
460 | 462 |
461 //--------------------------------------------------------------------------- | 463 //--------------------------------------------------------------------------- |
462 /* | 464 /** |
463 function DeDC: removes DC component of a signal | 465 function DeDC: removes DC component of a signal |
464 | 466 |
465 In: data[Count]: the signal | 467 In: data[Count]: the signal |
466 HWid: half of averaging window size | 468 HWid: half of averaging window size |
467 Out: data[Count]: de-DC-ed signal | 469 Out: data[Count]: de-DC-ed signal |
475 for (int i=0; i<Count; i++) | 477 for (int i=0; i<Count; i++) |
476 *(data++)-=*(data2++); | 478 *(data++)-=*(data2++); |
477 delete[] data2; | 479 delete[] data2; |
478 }//DeDC | 480 }//DeDC |
479 | 481 |
480 /* | 482 /** |
481 function DeDC_static: removes DC component statically | 483 function DeDC_static: removes DC component statically |
482 | 484 |
483 In: data[Count]: the signal | 485 In: data[Count]: the signal |
484 Out: data[Count]: DC-removed signal | 486 Out: data[Count]: DC-removed signal |
485 | 487 |
490 double avg=Avg(data, Count, 0); | 492 double avg=Avg(data, Count, 0); |
491 for (int i=0; i<Count; i++) *(data++)-=avg; | 493 for (int i=0; i<Count; i++) *(data++)-=avg; |
492 }//DeDC_static | 494 }//DeDC_static |
493 | 495 |
494 //--------------------------------------------------------------------------- | 496 //--------------------------------------------------------------------------- |
495 /* | 497 /** |
496 function DoubleToInt: converts double-precision floating point array to integer array | 498 function DoubleToInt: converts double-precision floating point array to integer array |
497 | 499 |
498 In: in[Count]: the double array | 500 In: in[Count]: the double array |
499 BytesPerSample: bytes per sample of destination integers | 501 BytesPerSample: bytes per sample of destination integers |
500 Out: out[Count]: the integer array | 502 Out: out[Count]: the integer array |
505 { | 507 { |
506 if (BytesPerSample==1){unsigned char* out8=(unsigned char*)out; for (int k=0; k<Count; k++) *(out8++)=*(in++)+128.5;} | 508 if (BytesPerSample==1){unsigned char* out8=(unsigned char*)out; for (int k=0; k<Count; k++) *(out8++)=*(in++)+128.5;} |
507 else {__int16* out16=(__int16*)out; for (int k=0; k<Count; k++) *(out16++)=floor(*(in++)+0.5);} | 509 else {__int16* out16=(__int16*)out; for (int k=0; k<Count; k++) *(out16++)=floor(*(in++)+0.5);} |
508 }//DoubleToInt | 510 }//DoubleToInt |
509 | 511 |
510 /* | 512 /** |
511 function DoubleToIntAdd: adds double-precision floating point array to integer array | 513 function DoubleToIntAdd: adds double-precision floating point array to integer array |
512 | 514 |
513 In: in[Count]: the double array | 515 In: in[Count]: the double array |
514 out[Count]: the integer array | 516 out[Count]: the integer array |
515 BytesPerSample: bytes per sample of destination integers | 517 BytesPerSample: bytes per sample of destination integers |
530 for (int k=0; k<Count; k++){*out16=*out16+floor(*in+0.5); out16++; in++;} | 532 for (int k=0; k<Count; k++){*out16=*out16+floor(*in+0.5); out16++; in++;} |
531 } | 533 } |
532 }//DoubleToIntAdd | 534 }//DoubleToIntAdd |
533 | 535 |
534 //--------------------------------------------------------------------------- | 536 //--------------------------------------------------------------------------- |
535 /* | 537 /** |
536 DPower: in-frame power variation | 538 DPower: in-frame power variation |
537 | 539 |
538 In: data[Count]: a signal | 540 In: data[Count]: a signal |
539 | 541 |
540 returns the different between AC powers of its first and second halves. | 542 returns the different between AC powers of its first and second halves. |
545 double ene2=ACPower(&data[Count/2], Count/2, 0); | 547 double ene2=ACPower(&data[Count/2], Count/2, 0); |
546 return ene2-ene1; | 548 return ene2-ene1; |
547 }//DPower | 549 }//DPower |
548 | 550 |
549 //--------------------------------------------------------------------------- | 551 //--------------------------------------------------------------------------- |
550 /* | 552 /** |
551 funciton Energy: energy | 553 function Energy: energy |
552 | 554 |
553 In: data[Count]: a signal | 555 In: data[Count]: a signal |
554 | 556 |
555 Returns its total energy | 557 Returns its total energy |
556 */ | 558 */ |
560 for (int i=0; i<Count; i++) result+=data[i]*data[i]; | 562 for (int i=0; i<Count; i++) result+=data[i]*data[i]; |
561 return result; | 563 return result; |
562 }//Energy | 564 }//Energy |
563 | 565 |
564 //--------------------------------------------------------------------------- | 566 //--------------------------------------------------------------------------- |
565 /* | 567 /** |
566 function ExpOnsetFilter: onset filter with exponential impulse response h(t)=Aexp(-t/Tr)-Bexp(-t/Ta), | 568 function ExpOnsetFilter: onset filter with exponential impulse response h(t)=Aexp(-t/Tr)-Bexp(-t/Ta), |
567 A=1-exp(-1/Tr), B=1-exp(-1/Ta). | 569 A=1-exp(-1/Tr), B=1-exp(-1/Ta). |
568 | 570 |
569 In: data[Count]: signal to filter | 571 In: data[Count]: signal to filter |
570 Tr, Ta: time constants of h(t) | 572 Tr, Ta: time constants of h(t) |
585 *(dataout++)=(A*FA-B*FB)*NormFactor; | 587 *(dataout++)=(A*FA-B*FB)*NormFactor; |
586 } | 588 } |
587 return NormFactor; | 589 return NormFactor; |
588 }//ExpOnsetFilter | 590 }//ExpOnsetFilter |
589 | 591 |
590 /* | 592 /** |
591 function ExpOnsetFilter_balanced: exponential onset filter without starting step response. It | 593 function ExpOnsetFilter_balanced: exponential onset filter without starting step response. It |
592 extends the input signal at the front end by bal*Ta samples by repeating the its value at 0, then | 594 extends the input signal at the front end by bal*Ta samples by repeating the its value at 0, then |
593 applies the onset filter on the extended signal instead. | 595 applies the onset filter on the extended signal instead. |
594 | 596 |
595 In: data[Count]: signal to filter | 597 In: data[Count]: signal to filter |
610 delete[] tmpdata; | 612 delete[] tmpdata; |
611 return result; | 613 return result; |
612 }//ExpOnsetFilter_balanced | 614 }//ExpOnsetFilter_balanced |
613 | 615 |
614 //--------------------------------------------------------------------------- | 616 //--------------------------------------------------------------------------- |
615 /* | 617 /** |
616 function ExtractLinearComponent: Legendre linear component | 618 function ExtractLinearComponent: Legendre linear component |
617 | 619 |
618 In: data[Count+1]: a signal | 620 In: data[Count+1]: a signal |
619 Out: dataout[Count+1]: its Legendre linear component, optional. | 621 Out: dataout[Count+1]: its Legendre linear component, optional. |
620 | 622 |
630 for (int n=0; n<=Count; n++) *(dataout++)=tmp*n; | 632 for (int n=0; n<=Count; n++) *(dataout++)=tmp*n; |
631 return tmp; | 633 return tmp; |
632 }//ExtractLinearComponent | 634 }//ExtractLinearComponent |
633 | 635 |
634 //--------------------------------------------------------------------------- | 636 //--------------------------------------------------------------------------- |
635 /* | 637 /** |
636 function FFTConv: fast convolution of two series by FFT overlap-add. In an overlap-add scheme it is | 638 function FFTConv: fast convolution of two series by FFT overlap-add. In an overlap-add scheme it is |
637 assumed that one of the convolvends is short compared to the other one, which can be potentially | 639 assumed that one of the convolvends is short compared to the other one, which can be potentially |
638 infinitely long. The long convolvend is devided into short segments, each of which is convolved with | 640 infinitely long. The long convolvend is devided into short segments, each of which is convolved with |
639 the short convolvend, the results of which are then assembled into the final result. The minimal delay | 641 the short convolvend, the results of which are then assembled into the final result. The minimal delay |
640 from input to output is the amount of overlap, which is the size of the short convolvend minus 1. | 642 from input to output is the amount of overlap, which is the size of the short convolvend minus 1. |
777 delete[] x2; | 779 delete[] x2; |
778 delete[] tmp; | 780 delete[] tmp; |
779 delete[] hbitinv; | 781 delete[] hbitinv; |
780 }//FFTConv | 782 }//FFTConv |
781 | 783 |
782 /* | 784 /** |
783 function FFTConv: the simplified version using two output buffers instead of three. This is almost | 785 function FFTConv: the simplified version using two output buffers instead of three. This is almost |
784 equivalent to setting zero=-size2 in the three-output-buffer version (so that post_buffer no longer | 786 equivalent to setting zero=-size2 in the three-output-buffer version (so that post_buffer no longer |
785 exists), except that this version requires size2 (renamed HWid) be a power of 2, and pre_buffer point | 787 exists), except that this version requires size2 (renamed HWid) be a power of 2, and pre_buffer point |
786 to the END of the storage (so that pre_buffer=dest automatically connects the two buffers in a | 788 to the END of the storage (so that pre_buffer=dest automatically connects the two buffers in a |
787 continuous memory block). | 789 continuous memory block). |
879 | 881 |
880 FreeFFTBuffer(fft); | 882 FreeFFTBuffer(fft); |
881 delete[] x2; delete[] tmp; delete[] hbitinv; | 883 delete[] x2; delete[] tmp; delete[] hbitinv; |
882 }//FFTConv | 884 }//FFTConv |
883 | 885 |
884 /* | 886 /** |
885 function FFTConv: fast convolution of two series by FFT overlap-add. Same as the three-output-buffer | 887 function FFTConv: fast convolution of two series by FFT overlap-add. Same as the three-output-buffer |
886 version above but using integer output buffers as well as integer source1. | 888 version above but using integer output buffers as well as integer source1. |
887 | 889 |
888 In: source1[size1]: convolvend | 890 In: source1[size1]: convolvend |
889 bps: bytes per sample of integer units in source1[]. | 891 bps: bytes per sample of integer units in source1[]. |
1020 delete[] tmp; | 1022 delete[] tmp; |
1021 delete[] hbitinv; | 1023 delete[] hbitinv; |
1022 }//FFTConv | 1024 }//FFTConv |
1023 | 1025 |
1024 //--------------------------------------------------------------------------- | 1026 //--------------------------------------------------------------------------- |
1025 /* | 1027 /** |
1026 function FFTFilter: FFT with cosine-window overlap-add: This FFT filter is not an actural LTI system, | 1028 function FFTFilter: FFT with cosine-window overlap-add: This FFT filter is not an actural LTI system, |
1027 but an block processing with overlap-add. In this function the blocks are overlapped by 50% and summed | 1029 but an block processing with overlap-add. In this function the blocks are overlapped by 50% and summed |
1028 up with Hann windowing. | 1030 up with Hann windowing. |
1029 | 1031 |
1030 In: data[Count]: input data | 1032 In: data[Count]: input data |
1087 delete[] win; | 1089 delete[] win; |
1088 delete[] tmpdata; | 1090 delete[] tmpdata; |
1089 FreeFFTBuffer(ldata); | 1091 FreeFFTBuffer(ldata); |
1090 }//FFTFilter | 1092 }//FFTFilter |
1091 | 1093 |
1092 /* | 1094 /** |
1093 funtion FFTFilterOLA: FFTFilter with overlap-add support. This is a true LTI filter whose impulse | 1095 function FFTFilterOLA: FFTFilter with overlap-add support. This is a true LTI filter whose impulse |
1094 response is constructed using IFFT. The filtering is implemented by fast convolution. | 1096 response is constructed using IFFT. The filtering is implemented by fast convolution. |
1095 | 1097 |
1096 In: data[Count]: input data | 1098 In: data[Count]: input data |
1097 Wid: FFT size | 1099 Wid: FFT size |
1098 On, Off: cut-off frequencies, in bins, of the filter | 1100 On, Off: cut-off frequencies, in bins, of the filter |
1121 CIFFTR(x, log2(Wid), w, spec); | 1123 CIFFTR(x, log2(Wid), w, spec); |
1122 FFTConv(dataout, data, BytesPerSample, Count, spec, Wid, -Wid, pre_buffer, NULL); | 1124 FFTConv(dataout, data, BytesPerSample, Count, spec, Wid, -Wid, pre_buffer, NULL); |
1123 FreeFFTBuffer(spec); | 1125 FreeFFTBuffer(spec); |
1124 }//FFTFilterOLA | 1126 }//FFTFilterOLA |
1125 | 1127 |
1126 /* | 1128 /** |
1127 function FFTFilterOLA: FFT filter with overlap-add support. | 1129 function FFTFilterOLA: FFT filter with overlap-add support. |
1128 | 1130 |
1129 In: data[Count]: input data | 1131 In: data[Count]: input data |
1130 amp[0:HWid]: amplitude response | 1132 amp[0:HWid]: amplitude response |
1131 ph[0:HWid]: phase response, where ph[0]=ph[HWid]=0; | 1133 ph[0:HWid]: phase response, where ph[0]=ph[HWid]=0; |
1150 CIFFTR(x, log2(Wid), w, spec); | 1152 CIFFTR(x, log2(Wid), w, spec); |
1151 FFTConv(dataout, data, Count, spec, Wid, -Wid, pre_buffer, NULL); | 1153 FFTConv(dataout, data, Count, spec, Wid, -Wid, pre_buffer, NULL); |
1152 FreeFFTBuffer(spec); | 1154 FreeFFTBuffer(spec); |
1153 }//FFTFilterOLA | 1155 }//FFTFilterOLA |
1154 | 1156 |
1155 /* | 1157 /** |
1156 function FFTMask: masks a band of a signal with noise | 1158 function FFTMask: masks a band of a signal with noise |
1157 | 1159 |
1158 In: data[Count]: input signal | 1160 In: data[Count]: input signal |
1159 DigiOn, DigiOff: cut-off frequences of the band to mask | 1161 DigiOn, DigiOff: cut-off frequences of the band to mask |
1160 maskcoef: masking noise amplifier. If set to 1 than the mask level is set to the highest signal | 1162 maskcoef: masking noise amplifier. If set to 1 than the mask level is set to the highest signal |
1245 | 1247 |
1246 return max; | 1248 return max; |
1247 }//FFTMask | 1249 }//FFTMask |
1248 | 1250 |
1249 //--------------------------------------------------------------------------- | 1251 //--------------------------------------------------------------------------- |
1250 /* | 1252 /** |
1251 function FindInc: find the element in ordered list data that is closest to value. | 1253 function FindInc: find the element in ordered list data that is closest to value. |
1252 | 1254 |
1253 In: data[Count]: a ordered list | 1255 In: data[Count]: a ordered list |
1254 value: the value to locate in the list | 1256 value: the value to locate in the list |
1255 | 1257 |
1263 if (fabs(value-data[end-1])<fabs(value-data[end])) return end-1; | 1265 if (fabs(value-data[end-1])<fabs(value-data[end])) return end-1; |
1264 else return end; | 1266 else return end; |
1265 }//FindInc | 1267 }//FindInc |
1266 | 1268 |
1267 //--------------------------------------------------------------------------- | 1269 //--------------------------------------------------------------------------- |
1268 /* | 1270 /** |
1269 function Gaussian: Gaussian function | 1271 function Gaussian: Gaussian function |
1270 | 1272 |
1271 In: Vector[Dim]: a vector | 1273 In: Vector[Dim]: a vector |
1272 Mean[Dim]: mean of Gaussian function | 1274 Mean[Dim]: mean of Gaussian function |
1273 Dev[Fim]: diagonal autocorrelation matrix of Gaussian function | 1275 Dev[Fim]: diagonal autocorrelation matrix of Gaussian function |
1291 return bmt; | 1293 return bmt; |
1292 }//Gaussian | 1294 }//Gaussian |
1293 | 1295 |
1294 | 1296 |
1295 //--------------------------------------------------------------------------- | 1297 //--------------------------------------------------------------------------- |
1296 /* | 1298 /** |
1297 function Hamming: calculates the amplitude spectrum of Hamming window at a given frequency | 1299 function Hamming: calculates the amplitude spectrum of Hamming window at a given frequency |
1298 | 1300 |
1299 In: f: frequency | 1301 In: f: frequency |
1300 T: size of Hamming window | 1302 T: size of Hamming window |
1301 | 1303 |
1331 c=c1+c2+c3; | 1333 c=c1+c2+c3; |
1332 return abs(c); | 1334 return abs(c); |
1333 }//Hamming*/ | 1335 }//Hamming*/ |
1334 | 1336 |
1335 //--------------------------------------------------------------------------- | 1337 //--------------------------------------------------------------------------- |
1336 /* | 1338 /** |
1337 function HannSq: computes the square norm of Hann window spectrum (window-size-normalized) | 1339 function HannSq: computes the square norm of Hann window spectrum (window-size-normalized) |
1338 | 1340 |
1339 In: x: frequency, in bins | 1341 In: x: frequency, in bins |
1340 N: size of Hann window | 1342 N: size of Hann window |
1341 | 1343 |
1368 im=0.25*sin(pif)*(-spmdivbyspmpf+spmdivbyspmmf); | 1370 im=0.25*sin(pif)*(-spmdivbyspmpf+spmdivbyspmmf); |
1369 | 1371 |
1370 return (re*re+im*im)/(N*N); | 1372 return (re*re+im*im)/(N*N); |
1371 }//HannSq | 1373 }//HannSq |
1372 | 1374 |
1373 /* | 1375 /** |
1374 function Hann: computes the Hann window amplitude spectrum (window-size-normalized). | 1376 function Hann: computes the Hann window amplitude spectrum (window-size-normalized). |
1375 | 1377 |
1376 In: x: frequency, in bins | 1378 In: x: frequency, in bins |
1377 N: size of Hann window | 1379 N: size of Hann window |
1378 | 1380 |
1404 double result=0.5*spmdivbyspmf-0.25*(spmdivbyspmpf+spmdivbyspmmf); | 1406 double result=0.5*spmdivbyspmf-0.25*(spmdivbyspmpf+spmdivbyspmmf); |
1405 | 1407 |
1406 return result/N; | 1408 return result/N; |
1407 }//HannC | 1409 }//HannC |
1408 | 1410 |
1409 /* | 1411 /** |
1410 function HxPeak2: fine spectral peak detection. This does detection and high-precision LSE estimation | 1412 function HxPeak2: fine spectral peak detection. This does detection and high-precision LSE estimation |
1411 in one go. However, since in practise most peaks are spurious, LSE estimation is not necessary on | 1413 in one go. However, since in practise most peaks are spurious, LSE estimation is not necessary on |
1412 them. Accordingly, HxPeak2 is deprecated in favour of faster but coarser peak picking methods, such as | 1414 them. Accordingly, HxPeak2 is deprecated in favour of faster but coarser peak picking methods, such as |
1413 QIFFT, which leaves fine estimation to a later stage of processing. | 1415 QIFFT, which leaves fine estimation to a later stage of processing. |
1414 | 1416 |
1511 if (allocvhps) vhps=(double*)realloc(vhps, sizeof(double)*count); | 1513 if (allocvhps) vhps=(double*)realloc(vhps, sizeof(double)*count); |
1512 return count; | 1514 return count; |
1513 }//HxPeak2 | 1515 }//HxPeak2 |
1514 | 1516 |
1515 //--------------------------------------------------------------------------- | 1517 //--------------------------------------------------------------------------- |
1516 /* | 1518 /** |
1517 function InsertDec: inserts value into sorted decreasing list | 1519 function InsertDec: inserts value into sorted decreasing list |
1518 | 1520 |
1519 In: data[Count]: a sorted decreasing list. | 1521 In: data[Count]: a sorted decreasing list. |
1520 value: the value to be added | 1522 value: the value to be added |
1521 Out: data[Count]: the list with $value inserted if the latter is larger than its last entry, in which | 1523 Out: data[Count]: the list with $value inserted if the latter is larger than its last entry, in which |
1578 memmove(&data[end+1], &data[end], sizeof(double)*(Count-end-1)); | 1580 memmove(&data[end+1], &data[end], sizeof(double)*(Count-end-1)); |
1579 data[end]=value; | 1581 data[end]=value; |
1580 return end; | 1582 return end; |
1581 }//InsertDec | 1583 }//InsertDec |
1582 | 1584 |
1583 /* | 1585 /** |
1584 function InsertDec: inserts value and attached integer into sorted decreasing list | 1586 function InsertDec: inserts value and attached integer into sorted decreasing list |
1585 | 1587 |
1586 In: data[Count]: a sorted decreasing list | 1588 In: data[Count]: a sorted decreasing list |
1587 indices[Count]: a list of integers attached to entries of data[] | 1589 indices[Count]: a list of integers attached to entries of data[] |
1588 value, index: the value to be added and its attached integer | 1590 value, index: the value to be added and its attached integer |
1620 memmove(&indices[end+1], &indices[end], sizeof(int)*(Count-end-1)); | 1622 memmove(&indices[end+1], &indices[end], sizeof(int)*(Count-end-1)); |
1621 data[end]=value, indices[end]=index; | 1623 data[end]=value, indices[end]=index; |
1622 return end; | 1624 return end; |
1623 }//InsertDec | 1625 }//InsertDec |
1624 | 1626 |
1625 /* | 1627 /** |
1626 InsertInc: inserts value into sorted increasing list. | 1628 InsertInc: inserts value into sorted increasing list. |
1627 | 1629 |
1628 In: data[Count]: a sorted increasing list. | 1630 In: data[Count]: a sorted increasing list. |
1629 Capacity: maximal size of data[] | 1631 Capacity: maximal size of data[] |
1630 value: the value to be added | 1632 value: the value to be added |
1673 data[PosToInsert]=value; | 1675 data[PosToInsert]=value; |
1674 } | 1676 } |
1675 return PosToInsert; | 1677 return PosToInsert; |
1676 }//InsertInc | 1678 }//InsertInc |
1677 | 1679 |
1678 /* | 1680 /** |
1679 function InsertInc: inserts value into sorted increasing list | 1681 function InsertInc: inserts value into sorted increasing list |
1680 | 1682 |
1681 In: data[Count]: a sorted increasing list. | 1683 In: data[Count]: a sorted increasing list. |
1682 value: the value to be added | 1684 value: the value to be added |
1683 doinsert: specifies whether the actually insertion is to be performed | 1685 doinsert: specifies whether the actually insertion is to be performed |
1747 data[end]=value; | 1749 data[end]=value; |
1748 } | 1750 } |
1749 return end; | 1751 return end; |
1750 }//InsertInc | 1752 }//InsertInc |
1751 | 1753 |
1752 /* | 1754 /** |
1753 function InsertInc: inserts value and attached integer into sorted increasing list | 1755 function InsertInc: inserts value and attached integer into sorted increasing list |
1754 | 1756 |
1755 In: data[Count]: a sorted increasing list | 1757 In: data[Count]: a sorted increasing list |
1756 indices[Count]: a list of integers attached to entries of data[] | 1758 indices[Count]: a list of integers attached to entries of data[] |
1757 value, index: the value to be added and its attached integer | 1759 value, index: the value to be added and its attached integer |
1819 memmove(&indices[end+1], &indices[end], sizeof(double)*(Count-end-1)); | 1821 memmove(&indices[end+1], &indices[end], sizeof(double)*(Count-end-1)); |
1820 data[end]=value, indices[end]=index; | 1822 data[end]=value, indices[end]=index; |
1821 return end; | 1823 return end; |
1822 }//InsertInc | 1824 }//InsertInc |
1823 | 1825 |
1824 /* | 1826 /** |
1825 function InsertIncApp: inserts value into flexible-length sorted increasing list | 1827 function InsertIncApp: inserts value into flexible-length sorted increasing list |
1826 | 1828 |
1827 In: data[Count]: a sorted increasing list. | 1829 In: data[Count]: a sorted increasing list. |
1828 value: the value to be added | 1830 value: the value to be added |
1829 Out: data[Count+1]: the list with $value inserted. | 1831 Out: data[Count+1]: the list with $value inserted. |
1860 | 1862 |
1861 return end; | 1863 return end; |
1862 }//InsertIncApp | 1864 }//InsertIncApp |
1863 | 1865 |
1864 //--------------------------------------------------------------------------- | 1866 //--------------------------------------------------------------------------- |
1865 /* | 1867 /** |
1866 function InstantFreq; calculates instantaneous frequency from spectrum, evaluated at bin k | 1868 function InstantFreq; calculates instantaneous frequency from spectrum, evaluated at bin k |
1867 | 1869 |
1868 In: x[hwid]: spectrum with scale 2hwid | 1870 In: x[hwid]: spectrum with scale 2hwid |
1869 k: reference frequency, in bins | 1871 k: reference frequency, in bins |
1870 mode: must be 1. | 1872 mode: must be 1. |
1898 break; | 1900 break; |
1899 } | 1901 } |
1900 return result; | 1902 return result; |
1901 }//InstantFreq | 1903 }//InstantFreq |
1902 | 1904 |
1903 /* | 1905 /** |
1904 function InstantFreq; calculates "frequency spectrum", a sequence of frequencies evaluated at DFT bins | 1906 function InstantFreq; calculates "frequency spectrum", a sequence of frequencies evaluated at DFT bins |
1905 | 1907 |
1906 In: x[hwid]: spectrum with scale 2hwid | 1908 In: x[hwid]: spectrum with scale 2hwid |
1907 mode: must be 1. | 1909 mode: must be 1. |
1908 Out: freqspec[hwid]: the frequency spectrum | 1910 Out: freqspec[hwid]: the frequency spectrum |
1914 for (int i=0; i<hwid; i++) | 1916 for (int i=0; i<hwid; i++) |
1915 freqspec[i]=InstantFreq(i, hwid, x, mode); | 1917 freqspec[i]=InstantFreq(i, hwid, x, mode); |
1916 }//InstantFreq | 1918 }//InstantFreq |
1917 | 1919 |
1918 //--------------------------------------------------------------------------- | 1920 //--------------------------------------------------------------------------- |
1919 /* | 1921 /** |
1920 function IntToDouble: copy content of integer array to double array | 1922 function IntToDouble: copy content of integer array to double array |
1921 | 1923 |
1922 In: in: pointer to integer array | 1924 In: in: pointer to integer array |
1923 BytesPerSample: number of bytes each integer takes | 1925 BytesPerSample: number of bytes each integer takes |
1924 Count: size of integer array, in integers | 1926 Count: size of integer array, in integers |
1934 if (BytesPerSample==1){unsigned char* in8=(unsigned char*)in; for (int k=0; k<Count; k++) *(out++)=*(in8++)-128.0;} | 1936 if (BytesPerSample==1){unsigned char* in8=(unsigned char*)in; for (int k=0; k<Count; k++) *(out++)=*(in8++)-128.0;} |
1935 else {__int16* in16=(__int16*)in; for (int k=0; k<Count; k++) *(out++)=*(in16++);} | 1937 else {__int16* in16=(__int16*)in; for (int k=0; k<Count; k++) *(out++)=*(in16++);} |
1936 }//IntToDouble*/ | 1938 }//IntToDouble*/ |
1937 | 1939 |
1938 //--------------------------------------------------------------------------- | 1940 //--------------------------------------------------------------------------- |
1939 /* | 1941 /** |
1940 function IPHannC: inner product with Hann window spectrum | 1942 function IPHannC: inner product with Hann window spectrum |
1941 | 1943 |
1942 In: x[N]: spectrum | 1944 In: x[N]: spectrum |
1943 f: reference frequency | 1945 f: reference frequency |
1944 K1, K2: spectral truncation bounds | 1946 K1, K2: spectral truncation bounds |
1953 return abs(IPWindowC(f, x, N, M, c, iH2, K1, K2)); | 1955 return abs(IPWindowC(f, x, N, M, c, iH2, K1, K2)); |
1954 }//IPHannC | 1956 }//IPHannC |
1955 | 1957 |
1956 | 1958 |
1957 //--------------------------------------------------------------------------- | 1959 //--------------------------------------------------------------------------- |
1958 /* | 1960 /** |
1959 function lse: linear regression y=ax+b | 1961 function lse: linear regression y=ax+b |
1960 | 1962 |
1961 In: x[Count], y[Count]: input points | 1963 In: x[Count], y[Count]: input points |
1962 Out: a, b: LSE estimation of coefficients in y=ax+b | 1964 Out: a, b: LSE estimation of coefficients in y=ax+b |
1963 | 1965 |
1976 b=(sxx*sy-sx*sxy)/(Count*sxx-sx*sx); | 1978 b=(sxx*sy-sx*sxy)/(Count*sxx-sx*sx); |
1977 a=(sy-Count*b)/sx; | 1979 a=(sy-Count*b)/sx; |
1978 }//lse | 1980 }//lse |
1979 | 1981 |
1980 //-------------------------------------------------------------------------- | 1982 //-------------------------------------------------------------------------- |
1981 /* | 1983 /** |
1982 memdoubleadd: vector addition | 1984 memdoubleadd: vector addition |
1983 | 1985 |
1984 In: dest[count], source[count]: addends | 1986 In: dest[count], source[count]: addends |
1985 Out: dest[count]: sum | 1987 Out: dest[count]: sum |
1986 | 1988 |
1990 { | 1992 { |
1991 for (int i=0; i<count; i++){*dest=*dest+*source; dest++; source++;} | 1993 for (int i=0; i<count; i++){*dest=*dest+*source; dest++; source++;} |
1992 }//memdoubleadd | 1994 }//memdoubleadd |
1993 | 1995 |
1994 //-------------------------------------------------------------------------- | 1996 //-------------------------------------------------------------------------- |
1995 /* | 1997 /** |
1996 function Mel: converts frequency in Hz to frequency in mel. | 1998 function Mel: converts frequency in Hz to frequency in mel. |
1997 | 1999 |
1998 In: f: frequency, in Hz | 2000 In: f: frequency, in Hz |
1999 | 2001 |
2000 Returns the frequency measured on mel scale. | 2002 Returns the frequency measured on mel scale. |
2002 double Mel(double f) | 2004 double Mel(double f) |
2003 { | 2005 { |
2004 return 1127.01048*log(1+f/700); | 2006 return 1127.01048*log(1+f/700); |
2005 }//Mel | 2007 }//Mel |
2006 | 2008 |
2007 /* | 2009 /** |
2008 function InvMel: converts frequency in mel to frequency in Hz. | 2010 function InvMel: converts frequency in mel to frequency in Hz. |
2009 | 2011 |
2010 In: f: frequency, in mel. | 2012 In: f: frequency, in mel. |
2011 | 2013 |
2012 Returns the frequency in Hz. | 2014 Returns the frequency in Hz. |
2014 double InvMel(double mel) | 2016 double InvMel(double mel) |
2015 { | 2017 { |
2016 return 700*(exp(mel/1127.01048)-1); | 2018 return 700*(exp(mel/1127.01048)-1); |
2017 }//InvMel | 2019 }//InvMel |
2018 | 2020 |
2019 /* | 2021 /** |
2020 function MFCC: calculates MFCC. | 2022 function MFCC: calculates MFCC. |
2021 | 2023 |
2022 In: Data[FrameWidth]: data | 2024 In: Data[FrameWidth]: data |
2023 NumBands: number of frequency bands on mel scale | 2025 NumBands: number of frequency bands on mel scale |
2024 Bands[3*NumBands]: mel frequency bands, comes as $NumBands triples, each containing the lower, | 2026 Bands[3*NumBands]: mel frequency bands, comes as $NumBands triples, each containing the lower, |
2061 tmp+=Amps[j]*cos(M_PI*(i+0.5)*(j+0.5)/NumBands); | 2063 tmp+=Amps[j]*cos(M_PI*(i+0.5)*(j+0.5)/NumBands); |
2062 C[i]=tmp; | 2064 C[i]=tmp; |
2063 } | 2065 } |
2064 }//MFCC | 2066 }//MFCC |
2065 | 2067 |
2066 /* | 2068 /** |
2067 function MFCCPrepareBands: returns a array of OVERLAPPING bands given in triples, whose 1st and 3rd | 2069 function MFCCPrepareBands: returns a array of OVERLAPPING bands given in triples, whose 1st and 3rd |
2068 entries are the start and end of a band, in bins, and the 2nd is a middle frequency. | 2070 entries are the start and end of a band, in bins, and the 2nd is a middle frequency. |
2069 | 2071 |
2070 In: SamplesPerSec: sampling rate | 2072 In: SamplesPerSec: sampling rate |
2071 NumberOfBins: FFT size | 2073 NumberOfBins: FFT size |
2092 } | 2094 } |
2093 return Bands; | 2095 return Bands; |
2094 }//MFCCPrepareBands | 2096 }//MFCCPrepareBands |
2095 | 2097 |
2096 //--------------------------------------------------------------------------- | 2098 //--------------------------------------------------------------------------- |
2097 /* | 2099 /** |
2098 function Multi: vector-constant multiplication | 2100 function Multi: vector-constant multiplication |
2099 | 2101 |
2100 In: data[count]: a vector | 2102 In: data[count]: a vector |
2101 mul: a constant | 2103 mul: a constant |
2102 Out: data[count]: their product | 2104 Out: data[count]: their product |
2106 void Multi(double* data, int count, double mul) | 2108 void Multi(double* data, int count, double mul) |
2107 { | 2109 { |
2108 for (int i=0; i<count; i++){*data=*data*mul; data++;} | 2110 for (int i=0; i<count; i++){*data=*data*mul; data++;} |
2109 }//Multi | 2111 }//Multi |
2110 | 2112 |
2111 /* | 2113 /** |
2112 function Multi: vector-constant multiplication | 2114 function Multi: vector-constant multiplication |
2113 | 2115 |
2114 In: in[count]: a vector | 2116 In: in[count]: a vector |
2115 mul: a constant | 2117 mul: a constant |
2116 Out: out[count]: their product | 2118 Out: out[count]: their product |
2120 void Multi(double* out, double* in, int count, double mul) | 2122 void Multi(double* out, double* in, int count, double mul) |
2121 { | 2123 { |
2122 for (int i=0; i<count; i++) *(out++)=*(in++)*mul; | 2124 for (int i=0; i<count; i++) *(out++)=*(in++)*mul; |
2123 }//Multi | 2125 }//Multi |
2124 | 2126 |
2125 /* | 2127 /** |
2126 function Multi: vector-constant multiply-addition | 2128 function Multi: vector-constant multiply-addition |
2127 | 2129 |
2128 In: in[count], adder[count]: vectors | 2130 In: in[count], adder[count]: vectors |
2129 mul: a constant | 2131 mul: a constant |
2130 Out: out[count]: in[]+adder[]*mul | 2132 Out: out[count]: in[]+adder[]*mul |
2135 { | 2137 { |
2136 for (int i=0; i<count; i++) *(out++)=*(in++)+*(adder++)*mul; | 2138 for (int i=0; i<count; i++) *(out++)=*(in++)+*(adder++)*mul; |
2137 }//MultiAdd | 2139 }//MultiAdd |
2138 | 2140 |
2139 //--------------------------------------------------------------------------- | 2141 //--------------------------------------------------------------------------- |
2140 /* | 2142 /** |
2141 function NearestPeak: finds a peak value in an array that is nearest to a given index | 2143 function NearestPeak: finds a peak value in an array that is nearest to a given index |
2142 | 2144 |
2143 In: data[count]: an array | 2145 In: data[count]: an array |
2144 anindex: an index | 2146 anindex: an index |
2145 | 2147 |
2167 else if (data[upind]<data[downind]) return downind; | 2169 else if (data[upind]<data[downind]) return downind; |
2168 else return upind; | 2170 else return upind; |
2169 }//NearestPeak | 2171 }//NearestPeak |
2170 | 2172 |
2171 //--------------------------------------------------------------------------- | 2173 //--------------------------------------------------------------------------- |
2172 /* | 2174 /** |
2173 function NegativeExp: fits the curve y=1-x^lmd. | 2175 function NegativeExp: fits the curve y=1-x^lmd. |
2174 | 2176 |
2175 In: x[Count], y[Count]: sample points to fit, x[0]=0, x[Count-1]=1, y[0]=1, y[Count-1]=0 | 2177 In: x[Count], y[Count]: sample points to fit, x[0]=0, x[Count-1]=1, y[0]=1, y[Count-1]=0 |
2176 Out: lmd: coefficient of y=1-x^lmd. | 2178 Out: lmd: coefficient of y=1-x^lmd. |
2177 | 2179 |
2212 while (e && iter<=maxiter && (!laste || fabs(laste-e)/e>eps)); | 2214 while (e && iter<=maxiter && (!laste || fabs(laste-e)/e>eps)); |
2213 return sqrt(e/Count); | 2215 return sqrt(e/Count); |
2214 }//NegativeExp | 2216 }//NegativeExp |
2215 | 2217 |
2216 //--------------------------------------------------------------------------- | 2218 //--------------------------------------------------------------------------- |
2217 /* | 2219 /** |
2218 function: NL: noise level, calculated on 5% of total frames with least energy | 2220 function: NL: noise level, calculated on 5% of total frames with least energy |
2219 | 2221 |
2220 In: data[Count]: | 2222 In: data[Count]: |
2221 Wid: window width for power level estimation | 2223 Wid: window width for power level estimation |
2222 | 2224 |
2238 result=sqrt(result); | 2240 result=sqrt(result); |
2239 return result; | 2241 return result; |
2240 }//NL | 2242 }//NL |
2241 | 2243 |
2242 //--------------------------------------------------------------------------- | 2244 //--------------------------------------------------------------------------- |
2243 /* | 2245 /** |
2244 function Normalize: normalizes data to [-Maxi, Maxi], without zero shift | 2246 function Normalize: normalizes data to [-Maxi, Maxi], without zero shift |
2245 | 2247 |
2246 In: data[Count]: data to be normalized | 2248 In: data[Count]: data to be normalized |
2247 Maxi: destination maximal absolute value | 2249 Maxi: destination maximal absolute value |
2248 Out: data[Count]: normalized data | 2250 Out: data[Count]: normalized data |
2265 for (int i=0; i<Count; i++) *(data++)*=Maxi; | 2267 for (int i=0; i<Count; i++) *(data++)*=Maxi; |
2266 } | 2268 } |
2267 return max; | 2269 return max; |
2268 }//Normalize | 2270 }//Normalize |
2269 | 2271 |
2270 /* | 2272 /** |
2271 function Normalize2: normalizes data to a specified Euclidian norm | 2273 function Normalize2: normalizes data to a specified Euclidian norm |
2272 | 2274 |
2273 In: data[Count]: data to normalize | 2275 In: data[Count]: data to normalize |
2274 Norm: destination Euclidian norm | 2276 Norm: destination Euclidian norm |
2275 Out: data[Count]: normalized data. | 2277 Out: data[Count]: normalized data. |
2285 if (mul!=0) for (int i=0; i<Count; i++) data[i]/=mul; | 2287 if (mul!=0) for (int i=0; i<Count; i++) data[i]/=mul; |
2286 return norm; | 2288 return norm; |
2287 }//Normalize2 | 2289 }//Normalize2 |
2288 | 2290 |
2289 //--------------------------------------------------------------------------- | 2291 //--------------------------------------------------------------------------- |
2290 /* | 2292 /** |
2291 function PhaseSpan: computes the unwrapped phase variation across the Nyquist range | 2293 function PhaseSpan: computes the unwrapped phase variation across the Nyquist range |
2292 | 2294 |
2293 In: data[Count]: time-domain data | 2295 In: data[Count]: time-domain data |
2294 aparams: a fftparams structure | 2296 aparams: a fftparams structure |
2295 | 2297 |
2312 FreeFFTBuffer(Amp); | 2314 FreeFFTBuffer(Amp); |
2313 return result; | 2315 return result; |
2314 }//PhaseSpan | 2316 }//PhaseSpan |
2315 | 2317 |
2316 //--------------------------------------------------------------------------- | 2318 //--------------------------------------------------------------------------- |
2317 /* | 2319 /** |
2318 function PolyFit: least square polynomial fitting y=sum(i){a[i]*x^i} | 2320 function PolyFit: least square polynomial fitting y=sum(i){a[i]*x^i} |
2319 | 2321 |
2320 In: x[N], y[N]: sample points | 2322 In: x[N], y[N]: sample points |
2321 P: order of polynomial, P<N | 2323 P: order of polynomial, P<N |
2322 Out: a[P+1]: coefficients of polynomial | 2324 Out: a[P+1]: coefficients of polynomial |
2342 GESCP(P+1, a, aa, bb); | 2344 GESCP(P+1, a, aa, bb); |
2343 DeAlloc2(aa); delete[] bb; delete[] s; delete[] r; | 2345 DeAlloc2(aa); delete[] bb; delete[] s; delete[] r; |
2344 }//PolyFit | 2346 }//PolyFit |
2345 | 2347 |
2346 //--------------------------------------------------------------------------- | 2348 //--------------------------------------------------------------------------- |
2347 /* | 2349 /** |
2348 function Pow: vector power function | 2350 function Pow: vector power function |
2349 | 2351 |
2350 In: data[Count]: a vector | 2352 In: data[Count]: a vector |
2351 ex: expontnet | 2353 ex: expontnet |
2352 Out: data[Count]: point-wise $ex-th power of data[] | 2354 Out: data[Count]: point-wise $ex-th power of data[] |
2358 for (int i=0; i<Count; i++) | 2360 for (int i=0; i<Count; i++) |
2359 data[i]=pow(data[i], ex); | 2361 data[i]=pow(data[i], ex); |
2360 }//Power | 2362 }//Power |
2361 | 2363 |
2362 //--------------------------------------------------------------------------- | 2364 //--------------------------------------------------------------------------- |
2363 /* | 2365 /** |
2364 Rectify: semi-wave rectification | 2366 Rectify: semi-wave rectification |
2365 | 2367 |
2366 In: data[Count]: data to rectify | 2368 In: data[Count]: data to rectify |
2367 th: rectification threshold: values below th are rectified to th | 2369 th: rectification threshold: values below th are rectified to th |
2368 Out: data[Count]: recitified data | 2370 Out: data[Count]: recitified data |
2379 } | 2381 } |
2380 return Result; | 2382 return Result; |
2381 }//Rectify | 2383 }//Rectify |
2382 | 2384 |
2383 //--------------------------------------------------------------------------- | 2385 //--------------------------------------------------------------------------- |
2384 /* | 2386 /** |
2385 function Res: minimum absolute residue. | 2387 function Res: minimum absolute residue. |
2386 | 2388 |
2387 In: in: a number | 2389 In: in: a number |
2388 mod: modulus | 2390 mod: modulus |
2389 | 2391 |
2397 if (in<-mod/2) in+=mod; | 2399 if (in<-mod/2) in+=mod; |
2398 return in; | 2400 return in; |
2399 }//Res | 2401 }//Res |
2400 | 2402 |
2401 //--------------------------------------------------------------------------- | 2403 //--------------------------------------------------------------------------- |
2402 /* | 2404 /** |
2403 function Romberg: Romberg algorithm for numerical integration | 2405 function Romberg: Romberg algorithm for numerical integration |
2404 | 2406 |
2405 In: f: function to integrate | 2407 In: f: function to integrate |
2406 params: extra argument for calling f | 2408 params: extra argument for calling f |
2407 a, b: integration boundaries | 2409 a, b: integration boundaries |
2430 delete[] r1; | 2432 delete[] r1; |
2431 delete[] r2; | 2433 delete[] r2; |
2432 return h; | 2434 return h; |
2433 }//Romberg | 2435 }//Romberg |
2434 | 2436 |
2435 /* | 2437 /** |
2436 function Romberg: Romberg algorithm for numerical integration, may return before specified depth on | 2438 function Romberg: Romberg algorithm for numerical integration, may return before specified depth on |
2437 convergence. | 2439 convergence. |
2438 | 2440 |
2439 In: f: function to integrate | 2441 In: f: function to integrate |
2440 params: extra argument for calling f | 2442 params: extra argument for calling f |
2479 | 2481 |
2480 //--------------------------------------------------------------------------- | 2482 //--------------------------------------------------------------------------- |
2481 //analog and digital sinc functions | 2483 //analog and digital sinc functions |
2482 | 2484 |
2483 //sinca(0)=1, sincd(0)=N, sinca(1)=sincd(1)=0. | 2485 //sinca(0)=1, sincd(0)=N, sinca(1)=sincd(1)=0. |
2484 /* | 2486 /** |
2485 function sinca: analog sinc function. | 2487 function sinca: analog sinc function. |
2486 | 2488 |
2487 In: x: frequency | 2489 In: x: frequency |
2488 | 2490 |
2489 Returns sinc(x)=sin(pi*x)/(pi*x), sinca(0)=1, sinca(1)=0 | 2491 Returns sinc(x)=sin(pi*x)/(pi*x), sinca(0)=1, sinca(1)=0 |
2492 { | 2494 { |
2493 if (x==0) return 1; | 2495 if (x==0) return 1; |
2494 return sin(M_PI*x)/(M_PI*x); | 2496 return sin(M_PI*x)/(M_PI*x); |
2495 }//sinca | 2497 }//sinca |
2496 | 2498 |
2497 /* | 2499 /** |
2498 function sincd_unn: unnormalized discrete sinc function | 2500 function sincd_unn: unnormalized discrete sinc function |
2499 | 2501 |
2500 In: x: frequency | 2502 In: x: frequency |
2501 N: scale (window size, DFT size) | 2503 N: scale (window size, DFT size) |
2502 | 2504 |
2507 if (x==0) return N; | 2509 if (x==0) return N; |
2508 return sin(M_PI*x)/sin(M_PI*x/N); | 2510 return sin(M_PI*x)/sin(M_PI*x/N); |
2509 }//sincd | 2511 }//sincd |
2510 | 2512 |
2511 //--------------------------------------------------------------------------- | 2513 //--------------------------------------------------------------------------- |
2512 /* | 2514 /** |
2513 SmoothPhase: phase unwrapping on module mpi*PI, 2PI by default | 2515 SmoothPhase: phase unwrapping on module mpi*PI, 2PI by default |
2514 | 2516 |
2515 In: Arg[Count]: phase angles to unwrap | 2517 In: Arg[Count]: phase angles to unwrap |
2516 mpi: unwrapping modulus, in pi's | 2518 mpi: unwrapping modulus, in pi's |
2517 Out: Arg[Count]: unwrapped phase | 2519 Out: Arg[Count]: unwrapped phase |
2531 }//SmoothPhase | 2533 }//SmoothPhase |
2532 | 2534 |
2533 //--------------------------------------------------------------------------- | 2535 //--------------------------------------------------------------------------- |
2534 //the stiff string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). | 2536 //the stiff string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). |
2535 | 2537 |
2536 /* | 2538 /** |
2537 StiffB: computes stiffness coefficient from fundamental and another partial frequency based on the | 2539 StiffB: computes stiffness coefficient from fundamental and another partial frequency based on the |
2538 stiff string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). | 2540 stiff string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). |
2539 | 2541 |
2540 In: f0: fundamental frequency | 2542 In: f0: fundamental frequency |
2541 m: 1-based partial index | 2543 m: 1-based partial index |
2548 double f2=fm/m/f0; | 2550 double f2=fm/m/f0; |
2549 return (f2*f2-1)/(m*m-1); | 2551 return (f2*f2-1)/(m*m-1); |
2550 }//StiffB | 2552 }//StiffB |
2551 | 2553 |
2552 //StiffF: partial frequency of a stiff string | 2554 //StiffF: partial frequency of a stiff string |
2553 /* | 2555 /** |
2554 StiffFm: computes a partial frequency from fundamental frequency and partial index based on the stiff | 2556 StiffFm: computes a partial frequency from fundamental frequency and partial index based on the stiff |
2555 string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). | 2557 string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). |
2556 | 2558 |
2557 In: f0: fundamental frequency | 2559 In: f0: fundamental frequency |
2558 m: 1-based partial index | 2560 m: 1-based partial index |
2563 double StiffFm(double f0, int m, double B) | 2565 double StiffFm(double f0, int m, double B) |
2564 { | 2566 { |
2565 return m*f0*sqrt(1+B*(m*m-1)); | 2567 return m*f0*sqrt(1+B*(m*m-1)); |
2566 }//StiffFm | 2568 }//StiffFm |
2567 | 2569 |
2568 /* | 2570 /** |
2569 StiffF0: computes fundamental frequency from another partial frequency and stiffness coefficient based | 2571 StiffF0: computes fundamental frequency from another partial frequency and stiffness coefficient based |
2570 on the stiff string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). | 2572 on the stiff string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). |
2571 | 2573 |
2572 In: m: 1-based partial index | 2574 In: m: 1-based partial index |
2573 fm: frequency of partial m | 2575 fm: frequency of partial m |
2578 double StiffF0(double fm, int m, double B) | 2580 double StiffF0(double fm, int m, double B) |
2579 { | 2581 { |
2580 return fm/m/sqrt(1+B*(m*m-1)); | 2582 return fm/m/sqrt(1+B*(m*m-1)); |
2581 }//StiffF0 | 2583 }//StiffF0 |
2582 | 2584 |
2583 /* | 2585 /** |
2584 StiffM: computes 1-based partial index from partial frequency, fundamental frequency and stiffness | 2586 StiffM: computes 1-based partial index from partial frequency, fundamental frequency and stiffness |
2585 coefficient based on the stiff string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). | 2587 coefficient based on the stiff string partial frequency model f[m]=mf[1]*sqrt(1+B(m*m-1)). |
2586 | 2588 |
2587 In: f0: fundamental freqency | 2589 In: f0: fundamental freqency |
2588 fm: a partial frequency | 2590 fm: a partial frequency |
2601 else | 2603 else |
2602 return sqrt((b1+sqrt(delta))/2/B); | 2604 return sqrt((b1+sqrt(delta))/2/B); |
2603 }//StiffMd | 2605 }//StiffMd |
2604 | 2606 |
2605 //--------------------------------------------------------------------------- | 2607 //--------------------------------------------------------------------------- |
2606 /* | 2608 /** |
2607 TFFilter: time-frequency filtering with Hann-windowed overlap-add. | 2609 TFFilter: time-frequency filtering with Hann-windowed overlap-add. |
2608 | 2610 |
2609 In: data[Count]: input data | 2611 In: data[Count]: input data |
2610 Spans: time-frequency spans | 2612 Spans: time-frequency spans |
2611 wt, windp: type and extra parameter of FFT window | 2613 wt, windp: type and extra parameter of FFT window |