comparison dsp/tempotracking/TempoTrack.cpp @ 47:38bf09927942

* Build fixes for gcc 4.3.2 * _Maybe_, but probably not, fix crash in tempo tracker... let's see how we get on
author cannam
date Mon, 10 Nov 2008 14:01:55 +0000
parents 4f1870dbab2c
children 09aba2ccd94a
comparison
equal deleted inserted replaced
46:4f1870dbab2c 47:38bf09927942
14 #include "maths/MathUtilities.h" 14 #include "maths/MathUtilities.h"
15 15
16 #include <iostream> 16 #include <iostream>
17 17
18 #include <cassert> 18 #include <cassert>
19
20 //#define DEBUG_TEMPO_TRACK 1
19 21
20 22
21 #define RAY43VAL 23 #define RAY43VAL
22 24
23 ////////////////////////////////////////////////////////////////////// 25 //////////////////////////////////////////////////////////////////////
162 else 164 else
163 { 165 {
164 numelem = tsig; 166 numelem = tsig;
165 } 167 }
166 168
169 #ifdef DEBUG_TEMPO_TRACK
167 std::cerr << "tempoMM: m_winLength = " << m_winLength << ", m_lagLength = " << m_lagLength << ", numelem = " << numelem << std::endl; 170 std::cerr << "tempoMM: m_winLength = " << m_winLength << ", m_lagLength = " << m_lagLength << ", numelem = " << numelem << std::endl;
171 #endif
168 172
169 for(i=1;i<m_lagLength-1;i++) 173 for(i=1;i<m_lagLength-1;i++)
170 { 174 {
171 //first and last output values are left intentionally as zero 175 //first and last output values are left intentionally as zero
172 for (a=1;a<=numelem;a++) 176 for (a=1;a<=numelem;a++)
310 double locked = 5168.f / maxIndexRCF; 314 double locked = 5168.f / maxIndexRCF;
311 if (locked >= 30 && locked <= 180) { 315 if (locked >= 30 && locked <= 180) {
312 m_lockedTempo = locked; 316 m_lockedTempo = locked;
313 } 317 }
314 318
319 #ifdef DEBUG_TEMPO_TRACK
320 std::cerr << "tempoMM: locked tempo = " << m_lockedTempo << std::endl;
321 #endif
322
315 if( tsig == 0 ) 323 if( tsig == 0 )
316 tsig = 4; 324 tsig = 4;
317 325
318 326
327 #ifdef DEBUG_TEMPO_TRACK
319 std::cerr << "tempoMM: maxIndexRCF = " << maxIndexRCF << std::endl; 328 std::cerr << "tempoMM: maxIndexRCF = " << maxIndexRCF << std::endl;
329 #endif
320 330
321 if( tsig == 4 ) 331 if( tsig == 4 )
322 { 332 {
333 #ifdef DEBUG_TEMPO_TRACK
334 std::cerr << "tsig == 4" << std::endl;
335 #endif
336
323 pdPeaks = new double[ 4 ]; 337 pdPeaks = new double[ 4 ];
324 for( i = 0; i < 4; i++ ){ pdPeaks[ i ] = 0.0;} 338 for( i = 0; i < 4; i++ ){ pdPeaks[ i ] = 0.0;}
325 339
326 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1; 340 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
327 341
372 386
373 387
374 period = MathUtilities::mean( pdPeaks, 4 ); 388 period = MathUtilities::mean( pdPeaks, 4 );
375 } 389 }
376 else 390 else
377 { 391 {
392 #ifdef DEBUG_TEMPO_TRACK
393 std::cerr << "tsig != 4" << std::endl;
394 #endif
395
378 pdPeaks = new double[ 3 ]; 396 pdPeaks = new double[ 3 ];
379 for( i = 0; i < 3; i++ ){ pdPeaks[ i ] = 0.0;} 397 for( i = 0; i < 3; i++ ){ pdPeaks[ i ] = 0.0;}
380 398
381 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1; 399 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
382 400
528 void TempoTrack::createPhaseExtractor(double *Filter, unsigned int winLength, double period, unsigned int fsp, unsigned int lastBeat) 546 void TempoTrack::createPhaseExtractor(double *Filter, unsigned int winLength, double period, unsigned int fsp, unsigned int lastBeat)
529 { 547 {
530 int p = (int)MathUtilities::round( period ); 548 int p = (int)MathUtilities::round( period );
531 int predictedOffset = 0; 549 int predictedOffset = 0;
532 550
551 #ifdef DEBUG_TEMPO_TRACK
533 std::cerr << "TempoTrack::createPhaseExtractor: period = " << period << ", p = " << p << std::endl; 552 std::cerr << "TempoTrack::createPhaseExtractor: period = " << period << ", p = " << p << std::endl;
534 553 #endif
535 assert(p < 10000); 554
536 555 if (p > 10000) {
537 double* phaseScratch = new double[ p*2 ]; 556 std::cerr << "TempoTrack::createPhaseExtractor: WARNING! Highly implausible period value " << p << "!" << std::endl;
557 period = 5168 / 120;
558 }
559
560 double* phaseScratch = new double[ p*2 + 2 ];
561 for (int i = 0; i < p*2 + 2; ++i) phaseScratch[i] = 0.0;
538 562
539 563
540 if( lastBeat != 0 ) 564 if( lastBeat != 0 )
541 { 565 {
542 lastBeat = (int)MathUtilities::round((double)lastBeat );///(double)winLength); 566 lastBeat = (int)MathUtilities::round((double)lastBeat );///(double)winLength);
543 567
544 predictedOffset = lastBeat + p - fsp; 568 predictedOffset = lastBeat + p - fsp;
545 569
546 if (predictedOffset < 0) 570 if (predictedOffset < 0)
547 { 571 {
548 lastBeat = 0; 572 lastBeat = 0;
549 } 573 }
550 } 574 }
551 575
552 if( lastBeat != 0 ) 576 if( lastBeat != 0 )
553 { 577 {
554 int mu = p; 578 int mu = p;
569 { 593 {
570 temp = phaseScratch[ i ]; 594 temp = phaseScratch[ i ];
571 phaseScratch[ i ] = (temp - PhaseMin)/PhaseMax; 595 phaseScratch[ i ] = (temp - PhaseMin)/PhaseMax;
572 } 596 }
573 597
598 #ifdef DEBUG_TEMPO_TRACK
574 std::cerr << "predictedOffset = " << predictedOffset << std::endl; 599 std::cerr << "predictedOffset = " << predictedOffset << std::endl;
600 #endif
575 601
576 unsigned int index = 0; 602 unsigned int index = 0;
577 for(int i = p - ( predictedOffset - 1); i < p + ( p - predictedOffset) + 1; i++) 603 for (int i = p - ( predictedOffset - 1); i < p + ( p - predictedOffset) + 1; i++)
578 { 604 {
579 std::cerr << "assigning to filter index " << index << " (size = " << p*2 << ")" << std::endl; 605 #ifdef DEBUG_TEMPO_TRACK
606 std::cerr << "assigning to filter index " << index << " (size = " << p*2 << ")" << " value " << phaseScratch[i] << " from scratch index " << i << std::endl;
607 #endif
580 Filter[ index++ ] = phaseScratch[ i ]; 608 Filter[ index++ ] = phaseScratch[ i ];
581 } 609 }
582 } 610 }
583 else 611 else
584 { 612 {
656 } 684 }
657 685
658 return beat; 686 return beat;
659 } 687 }
660 688
661 vector<int> TempoTrack::process(double *DF, unsigned int length) 689
662 { 690
663 m_dataLength = length; 691 vector<int> TempoTrack::process( vector <double> DF,
664 692 vector <double> *tempoReturn )
693 {
694 m_dataLength = DF.size();
695
696 m_lockedTempo = 0.0;
697
665 double period = 0.0; 698 double period = 0.0;
666 int stepFlag = 0; 699 int stepFlag = 0;
667 int constFlag = 0; 700 int constFlag = 0;
668 int FSP = 0; 701 int FSP = 0;
669 int tsig = 0; 702 int tsig = 0;
670 int lastBeat = 0; 703 int lastBeat = 0;
671 704
705 vector <double> causalDF;
706
707 causalDF = DF;
708
709 //Prepare Causal Extension DFData
710 unsigned int DFCLength = m_dataLength + m_winLength;
711
712 for( unsigned int j = 0; j < m_winLength; j++ )
713 {
714 causalDF.push_back( 0 );
715 }
716
672 717
673 double* RW = new double[ m_lagLength ]; 718 double* RW = new double[ m_lagLength ];
674 for( unsigned int clear = 0; clear < m_lagLength; clear++){ RW[ clear ] = 0.0;} 719 for( unsigned int clear = 0; clear < m_lagLength; clear++){ RW[ clear ] = 0.0;}
675 720
676 double* GW = new double[ m_lagLength ]; 721 double* GW = new double[ m_lagLength ];
677 for(unsigned int clear = 0; clear < m_lagLength; clear++){ GW[ clear ] = 0.0;} 722 for(unsigned int clear = 0; clear < m_lagLength; clear++){ GW[ clear ] = 0.0;}
678 723
679 double* PW = new double[ m_lagLength ]; 724 double* PW = new double[ m_lagLength ];
680 for(unsigned int clear = 0; clear < m_lagLength; clear++){ PW[ clear ] = 0.0;} 725 for(unsigned clear = 0; clear < m_lagLength; clear++){ PW[ clear ] = 0.0;}
681 726
682 m_DFFramer.setSource( DF, m_dataLength ); 727 m_DFFramer.setSource( &causalDF[0], m_dataLength );
683 728
684 unsigned int TTFrames = m_DFFramer.getMaxNoFrames(); 729 unsigned int TTFrames = m_DFFramer.getMaxNoFrames();
730
731 #ifdef DEBUG_TEMPO_TRACK
732 std::cerr << "TTFrames = " << TTFrames << std::endl;
733 #endif
685 734
686 double* periodP = new double[ TTFrames ]; 735 double* periodP = new double[ TTFrames ];
687 for(unsigned int clear = 0; clear < TTFrames; clear++){ periodP[ clear ] = 0.0;} 736 for(unsigned clear = 0; clear < TTFrames; clear++){ periodP[ clear ] = 0.0;}
688 737
689 double* periodG = new double[ TTFrames ]; 738 double* periodG = new double[ TTFrames ];
690 for(unsigned int clear = 0; clear < TTFrames; clear++){ periodG[ clear ] = 0.0;} 739 for(unsigned clear = 0; clear < TTFrames; clear++){ periodG[ clear ] = 0.0;}
691 740
692 double* alignment = new double[ TTFrames ]; 741 double* alignment = new double[ TTFrames ];
693 for(unsigned int clear = 0; clear < TTFrames; clear++){ alignment[ clear ] = 0.0;} 742 for(unsigned clear = 0; clear < TTFrames; clear++){ alignment[ clear ] = 0.0;}
694 743
695 m_beats.clear(); 744 m_beats.clear();
696 745
697 createCombFilter( RW, m_lagLength, 0, 0 ); 746 createCombFilter( RW, m_lagLength, 0, 0 );
698 747
742 791
743 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig ); 792 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
744 793
745 period = periodG[ TTLoopIndex ]; 794 period = periodG[ TTLoopIndex ];
746 795
747 // am temporarily changing the last input parameter to lastBeat instead of '0' 796 #ifdef DEBUG_TEMPO_TRACK
748 createPhaseExtractor( PW, m_winLength, period, FSP, lastBeat ); 797 std::cerr << "TempoTrack::process: constFlag == " << constFlag << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl;
798 #endif
799
800 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
749 801
750 constFlag = 0; 802 constFlag = 0;
751 803
752 } 804 }
753 else 805 else
754 { 806 {
755 if( GW[ 0 ] != 0 ) 807 if( GW[ 0 ] != 0 )
756 { 808 {
757 period = periodG[ TTLoopIndex ]; 809 period = periodG[ TTLoopIndex ];
758 createPhaseExtractor( PW, m_winLength, period, FSP, lastBeat ); 810
759 811 #ifdef DEBUG_TEMPO_TRACK
760 } 812 std::cerr << "TempoTrack::process: GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl;
761 else 813 #endif
762 {
763 period = periodP[ TTLoopIndex ];
764 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
765 }
766 }
767
768 alignment[ TTLoopIndex ] = phaseMM( m_rawDFFrame, PW, m_winLength, period );
769
770 lastBeat = beatPredict(FSP, alignment[ TTLoopIndex ], period, m_lagLength );
771
772 FSP += (m_lagLength);
773
774 TTLoopIndex++;
775 }
776
777
778 delete [] periodP;
779 delete [] periodG;
780 delete [] alignment;
781
782 delete [] RW;
783 delete [] GW;
784 delete [] PW;
785
786 return m_beats;
787 }
788
789
790
791
792
793 vector<int> TempoTrack::process( vector <double> DF,
794 vector <double> *tempoReturn )
795 {
796 m_dataLength = DF.size();
797
798 m_lockedTempo = 0.0;
799
800 double period = 0.0;
801 int stepFlag = 0;
802 int constFlag = 0;
803 int FSP = 0;
804 int tsig = 0;
805 int lastBeat = 0;
806
807 vector <double> causalDF;
808
809 causalDF = DF;
810
811 //Prepare Causal Extension DFData
812 unsigned int DFCLength = m_dataLength + m_winLength;
813
814 for( unsigned int j = 0; j < m_winLength; j++ )
815 {
816 causalDF.push_back( 0 );
817 }
818
819
820 double* RW = new double[ m_lagLength ];
821 for( unsigned int clear = 0; clear < m_lagLength; clear++){ RW[ clear ] = 0.0;}
822
823 double* GW = new double[ m_lagLength ];
824 for(unsigned int clear = 0; clear < m_lagLength; clear++){ GW[ clear ] = 0.0;}
825
826 double* PW = new double[ m_lagLength ];
827 for(unsigned clear = 0; clear < m_lagLength; clear++){ PW[ clear ] = 0.0;}
828
829 m_DFFramer.setSource( &causalDF[0], m_dataLength );
830
831 unsigned int TTFrames = m_DFFramer.getMaxNoFrames();
832
833 double* periodP = new double[ TTFrames ];
834 for(unsigned clear = 0; clear < TTFrames; clear++){ periodP[ clear ] = 0.0;}
835
836 double* periodG = new double[ TTFrames ];
837 for(unsigned clear = 0; clear < TTFrames; clear++){ periodG[ clear ] = 0.0;}
838
839 double* alignment = new double[ TTFrames ];
840 for(unsigned clear = 0; clear < TTFrames; clear++){ alignment[ clear ] = 0.0;}
841
842 m_beats.clear();
843
844 createCombFilter( RW, m_lagLength, 0, 0 );
845
846 int TTLoopIndex = 0;
847
848 for( unsigned int i = 0; i < TTFrames; i++ )
849 {
850 m_DFFramer.getFrame( m_rawDFFrame );
851
852 m_DFConditioning->process( m_rawDFFrame, m_smoothDFFrame );
853
854 m_correlator.doAutoUnBiased( m_smoothDFFrame, m_frameACF, m_winLength );
855
856 periodP[ TTLoopIndex ] = tempoMM( m_frameACF, RW, 0 );
857
858 if( GW[ 0 ] != 0 )
859 {
860 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
861 }
862 else
863 {
864 periodG[ TTLoopIndex ] = 0.0;
865 }
866
867 stepDetect( periodP, periodG, TTLoopIndex, &stepFlag );
868
869 if( stepFlag == 1)
870 {
871 constDetect( periodP, TTLoopIndex, &constFlag );
872 stepFlag = 0;
873 }
874 else
875 {
876 stepFlag -= 1;
877 }
878
879 if( stepFlag < 0 )
880 {
881 stepFlag = 0;
882 }
883
884 if( constFlag != 0)
885 {
886 tsig = findMeter( m_frameACF, m_winLength, periodP[ TTLoopIndex ] );
887
888 createCombFilter( GW, m_lagLength, tsig, periodP[ TTLoopIndex ] );
889
890 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
891
892 period = periodG[ TTLoopIndex ];
893
894 std::cerr << "TempoTrack::process(2): constFlag == " << constFlag << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl;
895
896 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
897
898 constFlag = 0;
899
900 }
901 else
902 {
903 if( GW[ 0 ] != 0 )
904 {
905 period = periodG[ TTLoopIndex ];
906
907 std::cerr << "TempoTrack::process(2): GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl;
908 814
909 if (period > 10000) { 815 if (period > 10000) {
910 std::cerr << "WARNING! Highly implausible period value!" << std::endl; 816 std::cerr << "TempoTrack::process: WARNING! Highly implausible period value " << period << "!" << std::endl;
911 std::cerr << "periodG contains (of " << TTFrames << " frames): " << std::endl; 817 std::cerr << "periodG contains (of " << TTFrames << " frames): " << std::endl;
912 for (int i = 0; i < TTLoopIndex + 3 && i < TTFrames; ++i) { 818 for (int i = 0; i < TTLoopIndex + 3 && i < TTFrames; ++i) {
913 std::cerr << i << " -> " << periodG[i] << std::endl; 819 std::cerr << i << " -> " << periodG[i] << std::endl;
914 } 820 }
915 std::cerr << "periodP contains (of " << TTFrames << " frames): " << std::endl; 821 std::cerr << "periodP contains (of " << TTFrames << " frames): " << std::endl;
916 for (int i = 0; i < TTLoopIndex + 3 && i < TTFrames; ++i) { 822 for (int i = 0; i < TTLoopIndex + 3 && i < TTFrames; ++i) {
917 std::cerr << i << " -> " << periodP[i] << std::endl; 823 std::cerr << i << " -> " << periodP[i] << std::endl;
918 } 824 }
825 period = 5168 / 120;
919 } 826 }
920 827
921 createPhaseExtractor( PW, m_winLength, period, FSP, lastBeat ); 828 createPhaseExtractor( PW, m_winLength, period, FSP, lastBeat );
922 829
923 } 830 }
924 else 831 else
925 { 832 {
926 period = periodP[ TTLoopIndex ]; 833 period = periodP[ TTLoopIndex ];
927 834
928 std::cerr << "TempoTrack::process(2): GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodP = " << period << std::endl; 835 #ifdef DEBUG_TEMPO_TRACK
836 std::cerr << "TempoTrack::process: GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodP = " << period << std::endl;
837 #endif
929 838
930 createPhaseExtractor( PW, m_winLength, period, FSP, 0 ); 839 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
931 } 840 }
932 } 841 }
933 842