Mercurial > hg > precise-onset-detection
view src/PeakProcessor.cpp @ 4:93b9a9471011
Changes to precise onset
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Mon, 06 Jan 2014 18:10:01 +0000 |
parents | 7ec1ed0b2eb0 |
children | 184a7c232049 |
line wrap: on
line source
/* * PeakProcessor.cpp * peakOnsetDetector * * Created by Andrew Robertson on 07/09/2012. * Copyright 2012 QMUL. All rights reserved. * */ #include "PeakProcessor.h" const bool printingOn = false;//true;//false; PeakProcessor::PeakProcessor(){ recentDFsamples.assign(vectorSize, 0.0); recentDFonsetFound.assign(vectorSize, false); recentDFslopeValues.assign(vectorSize, 0.0); numberOfDetectionValuesToTest = 10; currentFrame = 0; cutoffForRepeatOnsetsFrames = 4; detectionTriggerRatio = 0.34f;//was 0.5 detectionTriggerThreshold = 1.5;//0.1; bestSlopeMedian = 3; thresholdRelativeToMedian = 1.1; slopeFallenBelowMedian = true; lastSlopeOnsetFrame = 0; } PeakProcessor::~PeakProcessor(){ recentDFsamples.clear(); recentDFonsetFound.clear(); recentDFslopeValues.clear(); } bool PeakProcessor::peakProcessing(const double& newDFval){ recentDFsamples.erase (recentDFsamples.begin(), recentDFsamples.begin()+1);//erase first val recentDFsamples.push_back(newDFval); double slopeVal = getBestSlopeValue(newDFval); newOnsetFound = checkForSlopeOnset(slopeVal); if (printingOn) printf("PeakProcessor: slope %f best slope median %f det trigger thresh median %f\n", slopeVal, bestSlopeMedian, detectionTriggerThreshold); if (newOnsetFound && printingOn){ printf("PeakProcessor: BANG!\n"); } recentDFslopeValues.erase (recentDFslopeValues.begin(), recentDFslopeValues.begin()+1);//erase first val recentDFslopeValues.push_back(slopeVal); recentDFonsetFound.erase (recentDFonsetFound.begin(), recentDFonsetFound.begin()+1);//erase first val recentDFonsetFound.push_back(newOnsetFound); //printf("\n"); // for (int i = 0;i < recentDFsamples.size();i++){ // printf("rdf[%i] %f\n", i, recentDFsamples[i]); // } //printf("SLOPE %f\n", slopeVal); return newOnsetFound; } double PeakProcessor::getBestSlopeValue(const float& dfvalue){ //the idea is we want a high slope double bestValue = 0; for (int i = 1;i < min(numberOfDetectionValuesToTest, (int)recentDFsamples.size() - 1);i++){ double angle = 0; int otherIndex = recentDFsamples.size() - i + 1; double testValue = 0; if (otherIndex > 0 && recentDFsamples[otherIndex] > 0 && recentDFsamples[otherIndex] < dfvalue ){ angle = atan((float)(i * dfvalue)/ (numberOfDetectionValuesToTest*(dfvalue-recentDFsamples[otherIndex])) ); testValue = (dfvalue - recentDFsamples[otherIndex]) * cos(angle); } if (testValue > bestValue) bestValue = testValue; } return bestValue; } bool PeakProcessor :: checkForSlopeOnset(const float& bestValue){ bool onsetDetected = false; //check for onset relative to our processed slope function //a mix between increase in value and the gradient of that increase currentFrame++; if (bestValue > bestSlopeMedian * thresholdRelativeToMedian && //better than recent average (currentFrame - lastSlopeOnsetFrame) > cutoffForRepeatOnsetsFrames //after cutoff time && slopeFallenBelowMedian // has had onset and fall away again && bestValue > detectionTriggerThreshold * detectionTriggerRatio //longer term ratio of winning onsets ){ // printf("frame diff between onsets %6.1f", (1000*framesToSeconds(currentFrame - lastMedianOnsetFrame)) ); onsetDetected = true; lastSlopeOnsetFrame = currentFrame; slopeFallenBelowMedian = false; updateDetectionTriggerThreshold(bestValue); } if (bestValue > bestSlopeMedian){ bestSlopeMedian += (bestValue - bestSlopeMedian)*0.04;//was 1.1 } else{ bestSlopeMedian *= 0.99; slopeFallenBelowMedian = true;; } //bestSlopeMedian += 0.02* (bestValue - bestSlopeMedian); return onsetDetected; } void PeakProcessor :: updateDetectionTriggerThreshold(const float& val){ float detectionAdaptSpeed = 0.05;//moving average, roughly last twenty onsets detectionTriggerThreshold *= 1- detectionAdaptSpeed; detectionTriggerThreshold += (val * detectionAdaptSpeed); }