Mercurial > hg > x
comparison multires.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 | 6422640a802f |
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 "multires.h" | 4 #include "multires.h" |
6 #include "arrayalloc.h" | 5 #include "arrayalloc.h" |
7 #include "procedures.h" | 6 #include "procedures.h" |
8 | 7 |
8 /** \file multires.h */ | |
9 | |
9 //--------------------------------------------------------------------------- | 10 //--------------------------------------------------------------------------- |
10 | 11 |
11 //function xlogx(x): returns x*log(x) | 12 //function xlogx(x): returns x*log(x) |
12 inline double xlogx(double x) | 13 inline double xlogx(double x) |
13 { | 14 { |
18 //macro NORMAL_: a normalization step used for tiling | 19 //macro NORMAL_: a normalization step used for tiling |
19 #define NORMAL_(A, a) A=a*(A+log(a)); | 20 #define NORMAL_(A, a) A=a*(A+log(a)); |
20 // #define NORMAL_(A, a) A=a*a*A; | 21 // #define NORMAL_(A, a) A=a*a*A; |
21 // #define NORMAL_(A, a) A=sqrt(a)*A; | 22 // #define NORMAL_(A, a) A=sqrt(a)*A; |
22 | 23 |
23 /* | 24 /** |
24 function DoCutSpectrogramSquare: find optimal tiling of a square. This is a recursive procedure. | 25 function DoCutSpectrogramSquare: find optimal tiling of a square. This is a recursive procedure. |
25 | 26 |
26 In: Specs[0][1][N], Specs[1][2][N/2], ..., Specs[log2(N)][N][1], multiresolution power spectrogram | 27 In: Specs[0][1][N], Specs[1][2][N/2], ..., Specs[log2(N)][N][1], multiresolution power spectrogram |
27 e[Res]: total power of each level, e[i] equals the sum of Specs[i][][] | 28 e[Res]: total power of each level, e[i] equals the sum of Specs[i][][] |
28 NN: maximal tile height | 29 NN: maximal tile height |
167 } | 168 } |
168 | 169 |
169 return result; | 170 return result; |
170 }//DoCutSpectrogramSquare | 171 }//DoCutSpectrogramSquare |
171 | 172 |
172 /* | 173 /** |
173 function DoMixSpectrogramSquare: renders a composite spectrogram on a pixel grid. This is a recursive | 174 function DoMixSpectrogramSquare: renders a composite spectrogram on a pixel grid. This is a recursive |
174 procedure. | 175 procedure. |
175 | 176 |
176 In: Specs[0][1][N], Specs[1][2][N/2], Specs[2][4][N/4], ..., Specs[][N][1]: multiresolution power | 177 In: Specs[0][1][N], Specs[1][2][N/2], Specs[2][4][N/4], ..., Specs[][N][1]: multiresolution power |
177 spectrogram | 178 spectrogram |
252 | 253 |
253 delete[] lSpec; delete[] rSpec; DeAlloc2(lSpecs); DeAlloc2(rSpecs); | 254 delete[] lSpec; delete[] rSpec; DeAlloc2(lSpecs); DeAlloc2(rSpecs); |
254 } | 255 } |
255 }//DoMixSpectrogramSquare | 256 }//DoMixSpectrogramSquare |
256 | 257 |
257 /* | 258 /** |
258 function DoMixSpectrogramSquare: retrieves a composite spectrogram as a vector. This is a recursive | 259 function DoMixSpectrogramSquare: retrieves a composite spectrogram as a vector. This is a recursive |
259 procedure. | 260 procedure. |
260 | 261 |
261 In: Specs[0][1][N], Specs[1][2][N/2], Specs[2][4][N/4], ..., Specs[][N][1]: multiresolution power | 262 In: Specs[0][1][N], Specs[1][2][N/2], Specs[2][4][N/4], ..., Specs[][N][1]: multiresolution power |
262 spectrogram | 263 spectrogram |
332 DeAlloc2(lSpecs); DeAlloc2(rSpecs); | 333 DeAlloc2(lSpecs); DeAlloc2(rSpecs); |
333 } | 334 } |
334 }//DoMixSpectrogramSquare | 335 }//DoMixSpectrogramSquare |
335 | 336 |
336 //--------------------------------------------------------------------------- | 337 //--------------------------------------------------------------------------- |
337 /* | 338 /** |
338 function HSplitSpec: split a spectrogram horizontally into lower and upper halves. | 339 function HSplitSpec: split a spectrogram horizontally into lower and upper halves. |
339 | 340 |
340 In: Spec[X][Y]: spectrogram to split | 341 In: Spec[X][Y]: spectrogram to split |
341 Out: lSpec[X][Y/2], uSpec[X][Y/2]: the two half spectrograms | 342 Out: lSpec[X][Y/2], uSpec[X][Y/2]: the two half spectrograms |
342 | 343 |
348 lSpec=new double*[X], uSpec=new double*[X]; | 349 lSpec=new double*[X], uSpec=new double*[X]; |
349 for (int i=0; i<X; i++) | 350 for (int i=0; i<X; i++) |
350 lSpec[i]=Spec[i], uSpec[i]=&Spec[i][Y/2]; | 351 lSpec[i]=Spec[i], uSpec[i]=&Spec[i][Y/2]; |
351 }//HSplitSpec | 352 }//HSplitSpec |
352 | 353 |
353 /* | 354 /** |
354 function HSplitSpecs: split a multiresolution spectrogram horizontally into lower and upper halves | 355 function HSplitSpecs: split a multiresolution spectrogram horizontally into lower and upper halves |
355 | 356 |
356 A full spectrogram array is given in log2(N)+1 spectrograms, with the base spec of 1*N, 1st octave of | 357 A full spectrogram array is given in log2(N)+1 spectrograms, with the base spec of 1*N, 1st octave of |
357 2*(N/2), ..., last octave of N*1. When this array is split into two spectrogram arrays horizontally, | 358 2*(N/2), ..., last octave of N*1. When this array is split into two spectrogram arrays horizontally, |
358 the last spec (with the highest time resolution). Each of the two new arrays is given in log2(N) | 359 the last spec (with the highest time resolution). Each of the two new arrays is given in log2(N) |
371 for (int i=0, Fr=1, n=N; i<nRes; i++, Fr*=2, n/=2) | 372 for (int i=0, Fr=1, n=N; i<nRes; i++, Fr*=2, n/=2) |
372 for (int j=0; j<Fr; j++) lSpecs[i][j]=Specs[i][j], uSpecs[i][j]=&Specs[i][j][n/2]; | 373 for (int j=0; j<Fr; j++) lSpecs[i][j]=Specs[i][j], uSpecs[i][j]=&Specs[i][j][n/2]; |
373 }//HSplitSpecs | 374 }//HSplitSpecs |
374 | 375 |
375 //--------------------------------------------------------------------------- | 376 //--------------------------------------------------------------------------- |
376 /* | 377 /** |
377 function MixSpectrogramSquare: find composite spectrogram from multiresolution spectrogram,output as | 378 function MixSpectrogramSquare: find composite spectrogram from multiresolution spectrogram,output as |
378 pixel grid | 379 pixel grid |
379 | 380 |
380 In: Specs[0][1][N], Specs[1][2][N/2], ..., Specs[Res-1][N][1], multiresolution spectrogram | 381 In: Specs[0][1][N], Specs[1][2][N/2], ..., Specs[Res-1][N][1], multiresolution spectrogram |
381 Out: Spec[N][N]: composite spectrogram as pixel grid (N time redundant) | 382 Out: Spec[N][N]: composite spectrogram as pixel grid (N time redundant) |
429 if (createcuts) delete[] cuts; | 430 if (createcuts) delete[] cuts; |
430 return result; | 431 return result; |
431 }//MixSpectrogramSquare | 432 }//MixSpectrogramSquare |
432 | 433 |
433 //--------------------------------------------------------------------------- | 434 //--------------------------------------------------------------------------- |
434 /* | 435 /** |
435 function MixSpectrogramSquare: find composite spectrogram from multiresolution spectrogram,output as | 436 function MixSpectrogramSquare: find composite spectrogram from multiresolution spectrogram,output as |
436 vectors | 437 vectors |
437 | 438 |
438 In: Specs[0][1][N], Specs[1][2][N/2], ..., Specs[Res-1][N][1], multiresolution spectrogram | 439 In: Specs[0][1][N], Specs[1][2][N/2], ..., Specs[Res-1][N][1], multiresolution spectrogram |
439 Out: spl[N-1], Spec[N]: composite spectrogram as tiling and value vectors | 440 Out: spl[N-1], Spec[N]: composite spectrogram as tiling and value vectors |
482 DoMixSpectrogramSquare(Spec, spl, Specs, N, NormMix); | 483 DoMixSpectrogramSquare(Spec, spl, Specs, N, NormMix); |
483 return result; | 484 return result; |
484 }//MixSpectrogramSquare | 485 }//MixSpectrogramSquare |
485 | 486 |
486 //--------------------------------------------------------------------------- | 487 //--------------------------------------------------------------------------- |
487 /* | 488 /** |
488 function MixSpectrogramBlock: obtain the composite spectrogram of a waveform block as pixel grid. | 489 function MixSpectrogramBlock: obtain the composite spectrogram of a waveform block as pixel grid. |
489 | 490 |
490 This method deals with the effective duration of WID/2 samples of a frame of WID samples. The maximal | 491 This method deals with the effective duration of WID/2 samples of a frame of WID samples. The maximal |
491 frame width is WID, minimal frame width is wid. The spectrum with frame width WID (base) is given in | 492 frame width is WID, minimal frame width is wid. The spectrum with frame width WID (base) is given in |
492 lSpecs[0][0], the spectra with frame width WID/2 (1st octave) is given in lSpecs[1][0] & lSpecs[1][1], | 493 lSpecs[0][0], the spectra with frame width WID/2 (1st octave) is given in lSpecs[1][0] & lSpecs[1][1], |
537 DeAlloc2(lSpecs); | 538 DeAlloc2(lSpecs); |
538 if (createcuts) delete[] cuts; | 539 if (createcuts) delete[] cuts; |
539 return result; | 540 return result; |
540 }//MixSpectrogramBlock | 541 }//MixSpectrogramBlock |
541 | 542 |
542 /* | 543 /** |
543 function MixSpectrogramBlock: obtain the composite spectrogram of a waveform block as vectors. | 544 function MixSpectrogramBlock: obtain the composite spectrogram of a waveform block as vectors. |
544 | 545 |
545 In: Specs[0][1][WID], Specs[1][2][WID/2], ..., Specs[Res-1][WID/wid][wid], multiresolution spectrogram | 546 In: Specs[0][1][WID], Specs[1][2][WID/2], ..., Specs[Res-1][WID/wid][wid], multiresolution spectrogram |
546 Out: spl[WID], Spec[WID], composite spectrogram as tiling and value vectors. Each of the vectors is | 547 Out: spl[WID], Spec[WID], composite spectrogram as tiling and value vectors. Each of the vectors is |
547 made up of $wid subvectors, each subvector pair describing a N*N block of the composite | 548 made up of $wid subvectors, each subvector pair describing a N*N block of the composite |
579 return result; | 580 return result; |
580 }//MixSpectrogramBlock | 581 }//MixSpectrogramBlock |
581 | 582 |
582 | 583 |
583 //--------------------------------------------------------------------------- | 584 //--------------------------------------------------------------------------- |
584 /* | 585 /** |
585 Functions names as ...Block2(...) implement the same functions as the above directly without | 586 functions names as ...Block2(...) implement the same functions as the above directly without |
586 explicitly dividing the multiresolution spectrogram into square blocks. | 587 explicitly dividing the multiresolution spectrogram into square blocks. |
587 */ | 588 */ |
588 | 589 |
589 /* | 590 /** |
590 function DoCutSpectrogramBlock2: find optimal tiling for a block | 591 function DoCutSpectrogramBlock2: find optimal tiling for a block |
591 | 592 |
592 In: Specs[R0][x0:x0+x-1][Y0:Y0+Y-1], [R0+1][2x0:2x0+2x-1][Y0/2:Y0/2+Y/2-1],..., | 593 In: Specs[R0][x0:x0+x-1][Y0:Y0+Y-1], [R0+1][2x0:2x0+2x-1][Y0/2:Y0/2+Y/2-1],..., |
593 Specs[R0+?][Nx0:Nx0+Nx-1][Y0/N:Y0/N+Y/N-1], multiresolution spectrogram | 594 Specs[R0+?][Nx0:Nx0+Nx-1][Y0/N:Y0/N+Y/N-1], multiresolution spectrogram |
594 Out: spl[Y-1], tiling of this block | 595 Out: spl[Y-1], tiling of this block |
641 } | 642 } |
642 } | 643 } |
643 return ent; | 644 return ent; |
644 }//DoCutSpectrogramBlock2 | 645 }//DoCutSpectrogramBlock2 |
645 | 646 |
646 /* | 647 /** |
647 function DoMixSpectrogramBlock2: sampling multiresolution spectrogram according to given tiling | 648 function DoMixSpectrogramBlock2: sampling multiresolution spectrogram according to given tiling |
648 | 649 |
649 In: Specs[R0][x0:x0+x-1][Y0:Y0+Y-1], [R0+1][2x0:2x0+2x-1][Y0/2:Y0/2+Y/2-1],..., | 650 In: Specs[R0][x0:x0+x-1][Y0:Y0+Y-1], [R0+1][2x0:2x0+2x-1][Y0/2:Y0/2+Y/2-1],..., |
650 Specs[R0+?][Nx0:Nx0+Nx-1][Y0/N:Y0/N+Y/N-1], multiresolution spectrogram | 651 Specs[R0+?][Nx0:Nx0+Nx-1][Y0/N:Y0/N+Y/N-1], multiresolution spectrogram |
651 spl[Y-1]; tiling of this block | 652 spl[Y-1]; tiling of this block |
695 } | 696 } |
696 } | 697 } |
697 return 0; | 698 return 0; |
698 }//DoMixSpectrogramBlock2 | 699 }//DoMixSpectrogramBlock2 |
699 | 700 |
700 /* | 701 /** |
701 function MixSpectrogramBlock2: obtain the composite spectrogram of a waveform block as vectors. | 702 function MixSpectrogramBlock2: obtain the composite spectrogram of a waveform block as vectors. |
702 | 703 |
703 In: Specs[0][1][WID], Specs[1][2][WID/2], ..., Specs[Res-1][WID/wid][wid], multiresolution spectrogram | 704 In: Specs[0][1][WID], Specs[1][2][WID/2], ..., Specs[Res-1][WID/wid][wid], multiresolution spectrogram |
704 Out: spl[WID], Spec[WID], composite spectrogram as tiling and value vectors. Each of the | 705 Out: spl[WID], Spec[WID], composite spectrogram as tiling and value vectors. Each of the |
705 vectors is made up of $wid subvectors, each subvector pair describing a N*N block of the | 706 vectors is made up of $wid subvectors, each subvector pair describing a N*N block of the |
737 DoMixSpectrogramBlock2(spl, Spec, Specs, WID, 0, 0, 0, normmix, log2(WID/wid)+1, e); | 738 DoMixSpectrogramBlock2(spl, Spec, Specs, WID, 0, 0, 0, normmix, log2(WID/wid)+1, e); |
738 return result; | 739 return result; |
739 }//MixSpectrogramBlock2 | 740 }//MixSpectrogramBlock2 |
740 | 741 |
741 //--------------------------------------------------------------------------- | 742 //--------------------------------------------------------------------------- |
742 /* | 743 /** |
743 function MixSpectrogram: obtain composite spectrogram from multiresolutin spectrogram as pixel grid | 744 function MixSpectrogram: obtain composite spectrogram from multiresolutin spectrogram as pixel grid |
744 | 745 |
745 This method deals with Fr (base) frames of WID samples. Each base frame may be divided into 2 1st- | 746 This method deals with Fr (base) frames of WID samples. Each base frame may be divided into 2 1st- |
746 octave frames, 4 2nd-octave frames, ..., etc. The spectrogram calculated on base frame is given in | 747 octave frames, 4 2nd-octave frames, ..., etc. The spectrogram calculated on base frame is given in |
747 Specs[0] (Fr frames); that of 1st octave is given in Specs[1] (2*Fr frames); etc. The method resamples | 748 Specs[0] (Fr frames); that of 1st octave is given in Specs[1] (2*Fr frames); etc. The method resamples |
778 delete[] lSpecs; | 779 delete[] lSpecs; |
779 if (createcuts) delete[] cuts; | 780 if (createcuts) delete[] cuts; |
780 return 0; | 781 return 0; |
781 }//MixSpectrogram | 782 }//MixSpectrogram |
782 | 783 |
783 /* | 784 /** |
784 function MixSpectrogram: obtain composite spectrogram from multiresolutin spectrogram as vectors | 785 function MixSpectrogram: obtain composite spectrogram from multiresolutin spectrogram as vectors |
785 | 786 |
786 In: Specs[0][Fr][WID], Specs[1][Fr*2][WID/2], ..., Specs[Res-1] [Fr*(WID/wid)][wid], multiresolution | 787 In: Specs[0][Fr][WID], Specs[1][Fr*2][WID/2], ..., Specs[Res-1] [Fr*(WID/wid)][wid], multiresolution |
787 spectrogram | 788 spectrogram |
788 Out: spl[Fr][WID], Spec[Fr][WID], composite spectrogram as tiling and value vectors by frame. | 789 Out: spl[Fr][WID], Spec[Fr][WID], composite spectrogram as tiling and value vectors by frame. |
805 delete[] lSpecs; | 806 delete[] lSpecs; |
806 return 0; | 807 return 0; |
807 }//MixSpectrogram | 808 }//MixSpectrogram |
808 | 809 |
809 //--------------------------------------------------------------------------- | 810 //--------------------------------------------------------------------------- |
810 /* | 811 /** |
811 function VSplitSpec: split a spectrogram vertically into left and right halves. | 812 function VSplitSpec: split a spectrogram vertically into left and right halves. |
812 | 813 |
813 In: Spec[X][Y]: spectrogram to split | 814 In: Spec[X][Y]: spectrogram to split |
814 Out: lSpec[X][Y/2], rSpec[X][Y/2]: the two half spectrograms | 815 Out: lSpec[X][Y/2], rSpec[X][Y/2]: the two half spectrograms |
815 | 816 |
821 lSpec=new double*[X/2], rSpec=new double*[X/2]; | 822 lSpec=new double*[X/2], rSpec=new double*[X/2]; |
822 for(int i=0; i<X/2; i++) | 823 for(int i=0; i<X/2; i++) |
823 lSpec[i]=Spec[i], rSpec[i]=Spec[i+X/2]; | 824 lSpec[i]=Spec[i], rSpec[i]=Spec[i+X/2]; |
824 }//VSplitSpec | 825 }//VSplitSpec |
825 | 826 |
826 /* | 827 /** |
827 function VSplitSpecs: split a multiresolution spectrogram vertically into left and right halves | 828 function VSplitSpecs: split a multiresolution spectrogram vertically into left and right halves |
828 | 829 |
829 A full spectrogram array is given in log2(N)+1 spectrograms, with the base spec of 1*N, 1st octave of | 830 A full spectrogram array is given in log2(N)+1 spectrograms, with the base spec of 1*N, 1st octave of |
830 2*(N/2), ..., last octave of N*1. When this array is split into two spectrogram arrays horizontally, | 831 2*(N/2), ..., last octave of N*1. When this array is split into two spectrogram arrays horizontally, |
831 the last spec (with the highest time resolution). Each of the two new arrays is given in log2(N) | 832 the last spec (with the highest time resolution). Each of the two new arrays is given in log2(N) |