comparison src/BTrack.cpp @ 104:677c44fe42e0

Moved calculating of cumulative score value to generic function
author Adam Stark <adamstark.uk@gmail.com>
date Tue, 12 Sep 2017 00:29:00 +0100
parents 6b522d568ba4
children 3647be01027b
comparison
equal deleted inserted replaced
103:6b522d568ba4 104:677c44fe42e0
626 { 626 {
627 int windowStart = onsetDFBufferSize - round (2. * beatPeriod); 627 int windowStart = onsetDFBufferSize - round (2. * beatPeriod);
628 int windowEnd = onsetDFBufferSize - round (beatPeriod / 2.); 628 int windowEnd = onsetDFBufferSize - round (beatPeriod / 2.);
629 int windowSize = windowEnd - windowStart + 1; 629 int windowSize = windowEnd - windowStart + 1;
630 630
631 // create log gaussian transition window
631 double logGaussianTransitionWeighting[windowSize]; 632 double logGaussianTransitionWeighting[windowSize];
632 createLogGaussianTransitionWeighting (logGaussianTransitionWeighting, windowSize, beatPeriod); 633 createLogGaussianTransitionWeighting (logGaussianTransitionWeighting, windowSize, beatPeriod);
633 634
634 // calculate new cumulative score value 635 // calculate the new cumulative score value
635 double maxValue = 0; 636 latestCumulativeScoreValue = calculateNewCumulativeScoreValue (cumulativeScore, logGaussianTransitionWeighting, windowStart, windowEnd, onsetDetectionFunctionSample, alpha);
636 int n = 0; 637
637 for (int i = windowStart; i <= windowEnd; i++) 638 // add the new cumulative score value to the buffer
638 {
639 double weightedCumulativeScore = cumulativeScore[i] * logGaussianTransitionWeighting[n];
640
641 if (weightedCumulativeScore > maxValue)
642 maxValue = weightedCumulativeScore;
643
644 n++;
645 }
646
647 latestCumulativeScoreValue = ((1 - alpha) * onsetDetectionFunctionSample) + (alpha * maxValue);
648 cumulativeScore.addSampleToEnd (latestCumulativeScoreValue); 639 cumulativeScore.addSampleToEnd (latestCumulativeScoreValue);
649 } 640 }
650 641
651 //======================================================================= 642 //=======================================================================
652 void BTrack::predictBeat() 643 void BTrack::predictBeat()
653 { 644 {
654 int beatExpectationWindowSize = (int) beatPeriod; 645 int beatExpectationWindowSize = static_cast<int> (beatPeriod);
655 double futureCumulativeScore[onsetDFBufferSize + beatExpectationWindowSize]; 646 double futureCumulativeScore[onsetDFBufferSize + beatExpectationWindowSize];
656 double beatExpectationWindow[beatExpectationWindowSize]; 647 double beatExpectationWindow[beatExpectationWindowSize];
657 648
658 // copy cumulativeScore to first part of futureCumulativeScore 649 // copy cumulativeScore to first part of futureCumulativeScore
659 for (int i = 0;i < onsetDFBufferSize;i++) 650 for (int i = 0;i < onsetDFBufferSize;i++)
675 // It is a log-Gaussian transition weighting running from from 2 beat periods 666 // It is a log-Gaussian transition weighting running from from 2 beat periods
676 // in the past to half a beat period in the past. It favours the time exactly 667 // in the past to half a beat period in the past. It favours the time exactly
677 // one beat period in the past 668 // one beat period in the past
678 // This is W1 in Adam Stark's PhD thesis, equation 3.2, page 60 669 // This is W1 in Adam Stark's PhD thesis, equation 3.2, page 60
679 670
680
681 int startIndex = onsetDFBufferSize - round (2 * beatPeriod); 671 int startIndex = onsetDFBufferSize - round (2 * beatPeriod);
682 int endIndex = onsetDFBufferSize - round (beatPeriod / 2); 672 int endIndex = onsetDFBufferSize - round (beatPeriod / 2);
683 int pastWindowSize = endIndex - startIndex + 1; 673 int pastWindowSize = endIndex - startIndex + 1;
684 674
685 double logGaussianTransitionWeighting[pastWindowSize]; 675 double logGaussianTransitionWeighting[pastWindowSize];
686 createLogGaussianTransitionWeighting (logGaussianTransitionWeighting, pastWindowSize, beatPeriod); 676 createLogGaussianTransitionWeighting (logGaussianTransitionWeighting, pastWindowSize, beatPeriod);
687 677
688 // Calculate the future cumulative score, using the log Gaussian transition weighting 678 // Calculate the future cumulative score, by shifting the log Gaussian transition weighting from its
689 679 // start position of [-2 beat periods, 0.5 beat periods] forwards over the size of the beat
680 // expectation window, calculating a new cumulative score where the onset detection function sample
681 // is zero. This uses the "momentum" of the function to generate itself into the future.
690 for (int i = onsetDFBufferSize; i < (onsetDFBufferSize + beatExpectationWindowSize); i++) 682 for (int i = onsetDFBufferSize; i < (onsetDFBufferSize + beatExpectationWindowSize); i++)
691 { 683 {
692 startIndex = i - round (2 * beatPeriod); 684 // note here that we pass 0.0 in for the onset detection function value and 1.0 for the alpha weighting factor
693 endIndex = i - round (beatPeriod / 2); 685 // see equation 3.4 and page 60 - 62 of Adam Stark's PhD thesis for details
694 686 futureCumulativeScore[i] = calculateNewCumulativeScoreValue (futureCumulativeScore, logGaussianTransitionWeighting, startIndex, endIndex, 0.0, 1.0);
695 double maxValue = 0; 687
696 int n = 0; 688 startIndex++;
697 for (int k = startIndex; k <= endIndex; k++) 689 endIndex++;
698 {
699 double weightedCumulativeScore = futureCumulativeScore[k] * logGaussianTransitionWeighting[n];
700
701 if (weightedCumulativeScore > maxValue)
702 maxValue = weightedCumulativeScore;
703
704 n++;
705 }
706
707 futureCumulativeScore[i] = maxValue;
708 } 690 }
709 691
710 // Predict the next beat, finding the maximum point of the future cumulative score 692 // Predict the next beat, finding the maximum point of the future cumulative score
711 // over the next beat, after being weighted by the beat expectation window 693 // over the next beat, after being weighted by the beat expectation window
712 694
740 double a = tightness * log (-v / beatPeriod); 722 double a = tightness * log (-v / beatPeriod);
741 weightingArray[i] = exp ((-1. * a * a) / 2.); 723 weightingArray[i] = exp ((-1. * a * a) / 2.);
742 v++; 724 v++;
743 } 725 }
744 } 726 }
727
728 //=======================================================================
729 template <typename T>
730 double BTrack::calculateNewCumulativeScoreValue (T cumulativeScoreArray, double* logGaussianTransitionWeighting, int startIndex, int endIndex, double onsetDetectionFunctionSample, double alphaWeightingFactor)
731 {
732 // calculate new cumulative score value by weighting the cumulative score between
733 // startIndex and endIndex and finding the maximum value
734 double maxValue = 0;
735 int n = 0;
736 for (int i = startIndex; i <= endIndex; i++)
737 {
738 double weightedCumulativeScore = cumulativeScoreArray[i] * logGaussianTransitionWeighting[n];
739
740 if (weightedCumulativeScore > maxValue)
741 maxValue = weightedCumulativeScore;
742
743 n++;
744 }
745
746 // now mix with the incoming onset detection function sample
747 // (equation 3.4 on page 60 of Adam Stark's PhD thesis)
748 double cumulativeScoreValue = ((1. - alphaWeightingFactor) * onsetDetectionFunctionSample) + (alphaWeightingFactor * maxValue);
749
750 return cumulativeScoreValue;
751 }