Mercurial > hg > btrack
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 } |