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)