andrew@0: /* andrew@0: * PreciseOnsetLocator.cpp andrew@0: * peakOnsetDetector andrew@0: * andrew@2: * Created by Andrew Robertson on 21/09/2012. andrew@0: * Copyright 2012 QMUL. All rights reserved. andrew@0: * andrew@0: */ andrew@0: andrew@0: #include "PreciseOnsetLocator.h" andrew@0: andrew@4: const bool printingOn = false;//true; andrew@2: andrew@0: PreciseOnsetLocator::PreciseOnsetLocator(){ andrew@0: setup(512); andrew@0: } andrew@0: andrew@0: PreciseOnsetLocator::~PreciseOnsetLocator(){ andrew@0: onsetSamples.clear(); andrew@0: recentBufferSamples.clear(); andrew@0: } andrew@0: andrew@0: andrew@0: void PreciseOnsetLocator::setup(const int& size){ andrew@0: onsetSamples.clear(); andrew@0: recentBufferSamples.clear(); andrew@0: bufferSize = size; andrew@0: onsetSamples.assign(bufferSize, 0.0); andrew@0: recentBufferSamples.assign(bufferSize, 0.0); andrew@2: if (printingOn) andrew@2: printf("Precise onset locator - using %i samples as framesize\n", size); andrew@0: } andrew@0: andrew@0: void PreciseOnsetLocator::storeSamples(double* newSamples){ andrew@0: andrew@0: for (int i = 0;i < bufferSize;i++) andrew@0: recentBufferSamples[i] = newSamples[i]; andrew@0: andrew@0: } andrew@0: Venetian@8: int PreciseOnsetLocator::findExactOnset(float* frame){ Venetian@8: //store the samples - mainly for viewing actually Venetian@8: onsetSamples.clear(); Venetian@8: for (int i = 0; i < bufferSize;i++){ Venetian@8: onsetSamples.push_back(frame[i]); Venetian@8: } Venetian@8: return findExactOnset(); Venetian@8: } Venetian@8: andrew@0: int PreciseOnsetLocator::findExactOnset(double* frame){ andrew@0: //store the samples - mainly for viewing actually andrew@0: onsetSamples.clear(); andrew@2: for (int i = 0; i < bufferSize;i++){ andrew@0: onsetSamples.push_back(frame[i]); andrew@0: } Venetian@8: return findExactOnset(); Venetian@8: } Venetian@8: Venetian@8: int PreciseOnsetLocator::findExactOnset(){ andrew@0: double energySum = 0; andrew@0: double lastEnergySum, hopsizeLastEnergySum; andrew@0: double energyDifference; andrew@0: int bestEnergyIndex = 0; andrew@0: double bestEnergyDifference = 0; andrew@0: int endIndex = bufferSize; andrew@0: int hopSize; andrew@0: andrew@2: for (int resolution = bufferSize/2; resolution > 1; resolution/=2){ andrew@2: if (printingOn) andrew@2: printf("resolution %i\n", resolution); andrew@0: andrew@0: bestEnergyDifference = 0; andrew@0: // printf("previous energy %f", lastEnergySum); andrew@0: //initialise last energySum andrew@0: hopSize = resolution/2; andrew@0: andrew@0: lastEnergySum = getLastEnergySum(bestEnergyIndex, resolution); andrew@0: hopsizeLastEnergySum = getLastEnergySum(bestEnergyIndex + hopSize, resolution); andrew@0: andrew@0: for (int startIndex = bestEnergyIndex;startIndex + resolution <= endIndex;startIndex += hopSize){ andrew@2: if (printingOn) andrew@2: printf("index %i last energy %f hop energy %f ", startIndex, lastEnergySum, hopsizeLastEnergySum); andrew@0: andrew@0: //sum the energy for this new frame andrew@0: energySum = 0; andrew@0: for (int i = 0;i < resolution;i++){ andrew@0: energySum += onsetSamples[startIndex + i] * onsetSamples[startIndex + i]; andrew@0: } andrew@0: andrew@2: if (printingOn) andrew@2: printf("energysum %f\n", energySum); andrew@0: //check if new max difference andrew@0: energyDifference = energySum - lastEnergySum; andrew@0: if (energyDifference > bestEnergyDifference){ andrew@0: bestEnergyDifference = energyDifference; andrew@0: bestEnergyIndex = startIndex; andrew@0: } andrew@0: andrew@0: //store the values for checking in two loops time (because proceeding at resolution/2 each step) andrew@0: //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@0: lastEnergySum = hopsizeLastEnergySum;// energySum; andrew@0: hopsizeLastEnergySum = energySum; andrew@0: andrew@0: } andrew@2: if (printingOn) andrew@2: printf("winning index is %i\n", bestEnergyIndex); andrew@0: endIndex = bestEnergyIndex + resolution; andrew@0: andrew@0: } andrew@2: if (printingOn) andrew@2: printf("TOTAL WINNER %i\n", bestEnergyIndex); andrew@0: return bestEnergyIndex; andrew@0: andrew@0: } andrew@0: andrew@0: double PreciseOnsetLocator::getLastEnergySum(const int& startIndex, const int& vectorSize){ andrew@0: double lastEnergySum = 0; andrew@6: if (bufferSize + startIndex < recentBufferSamples.size()){ andrew@6: for (int i = startIndex - vectorSize;i < startIndex;i++){ andrew@6: if (i > 0) andrew@6: lastEnergySum += onsetSamples[i] * onsetSamples[i]; andrew@6: else { andrew@6: lastEnergySum += recentBufferSamples[bufferSize + i] * recentBufferSamples[bufferSize + i]; andrew@6: } andrew@0: } andrew@0: } andrew@0: return lastEnergySum; andrew@0: andrew@0: }