andrew@1: /* andrew@1: * PreciseOnsetLocator.cpp andrew@1: * peakOnsetDetector andrew@1: * andrew@1: * Created by Andrew on 21/09/2012. andrew@1: * Copyright 2012 QMUL. All rights reserved. andrew@1: * andrew@1: */ andrew@1: andrew@1: #include "PreciseOnsetLocator.h" andrew@1: andrew@1: PreciseOnsetLocator::PreciseOnsetLocator(){ andrew@1: setup(512); andrew@1: } andrew@1: andrew@1: PreciseOnsetLocator::~PreciseOnsetLocator(){ andrew@1: onsetSamples.clear(); andrew@1: recentBufferSamples.clear(); andrew@1: } andrew@1: andrew@1: andrew@1: void PreciseOnsetLocator::setup(const int& size){ andrew@1: onsetSamples.clear(); andrew@1: recentBufferSamples.clear(); andrew@1: bufferSize = size; andrew@1: onsetSamples.assign(bufferSize, 0.0); andrew@1: recentBufferSamples.assign(bufferSize, 0.0); andrew@1: } andrew@1: andrew@1: void PreciseOnsetLocator::storeSamples(double* newSamples){ andrew@1: andrew@1: for (int i = 0;i < bufferSize;i++) andrew@1: recentBufferSamples[i] = newSamples[i]; andrew@1: andrew@1: } andrew@1: andrew@1: int PreciseOnsetLocator::findExactOnset(double* frame){ andrew@1: //store the samples - mainly for viewing actually andrew@1: onsetSamples.clear(); andrew@1: for (int i = 0; i < bufferSize;i++) { andrew@1: onsetSamples.push_back(frame[i]); andrew@1: } andrew@1: andrew@1: double energySum = 0; andrew@1: double lastEnergySum, hopsizeLastEnergySum; andrew@1: double energyDifference; andrew@1: int bestEnergyIndex = 0; andrew@1: double bestEnergyDifference = 0; andrew@1: int endIndex = bufferSize; andrew@1: int hopSize; andrew@1: andrew@1: for (int resolution = bufferSize/2;resolution > 1;resolution/=2){ andrew@1: printf("resolution %i\n", resolution); andrew@1: andrew@1: bestEnergyDifference = 0; andrew@1: // printf("previous energy %f", lastEnergySum); andrew@1: //initialise last energySum andrew@1: hopSize = resolution/2; andrew@1: andrew@1: andrew@1: lastEnergySum = getLastEnergySum(bestEnergyIndex, resolution); andrew@1: hopsizeLastEnergySum = getLastEnergySum(bestEnergyIndex + hopSize, resolution); andrew@1: andrew@1: for (int startIndex = bestEnergyIndex;startIndex + resolution <= endIndex;startIndex += hopSize){ andrew@1: printf("index %i last energy %f hop energy %f ", startIndex, lastEnergySum, hopsizeLastEnergySum); andrew@1: andrew@1: //sum the energy for this new frame andrew@1: energySum = 0; andrew@1: for (int i = 0;i < resolution;i++){ andrew@1: energySum += onsetSamples[startIndex + i] * onsetSamples[startIndex + i]; andrew@1: } andrew@1: andrew@1: printf("energysum %f\n", energySum); andrew@1: //check if new max difference andrew@1: energyDifference = energySum - lastEnergySum; andrew@1: if (energyDifference > bestEnergyDifference){ andrew@1: bestEnergyDifference = energyDifference; andrew@1: bestEnergyIndex = startIndex; andrew@1: } andrew@1: andrew@1: //store the values for checking in two loops time (because proceeding at resolution/2 each step) andrew@1: //eg 0_to_128 compared to -128_to_0, 64_to_196 compared to -64_to_64, then 128_256 compared with 0_to_128, andrew@1: lastEnergySum = hopsizeLastEnergySum;// energySum; andrew@1: hopsizeLastEnergySum = energySum; andrew@1: andrew@1: } andrew@1: printf("winning index is %i\n", bestEnergyIndex); andrew@1: endIndex = bestEnergyIndex + resolution; andrew@1: andrew@1: } andrew@1: printf("TOTAL WINNER %i\n", bestEnergyIndex); andrew@1: return bestEnergyIndex; andrew@1: andrew@1: } andrew@1: andrew@1: double PreciseOnsetLocator::getLastEnergySum(const int& startIndex, const int& vectorSize){ andrew@1: double lastEnergySum = 0; andrew@1: andrew@1: for (int i = startIndex - vectorSize;i < startIndex;i++){ andrew@1: if (i > 0) andrew@1: lastEnergySum += onsetSamples[i] * onsetSamples[i]; andrew@1: else { andrew@1: lastEnergySum += recentBufferSamples[bufferSize + i] * recentBufferSamples[bufferSize + i]; andrew@1: } andrew@1: } andrew@1: return lastEnergySum; andrew@1: andrew@1: }