view src/PreciseOnsetLocator.cpp @ 6:eb29c6b6dff8

added pointer version of visualiser
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Sun, 19 Jan 2014 23:07:13 +0000
parents 93b9a9471011
children 184a7c232049
line wrap: on
line source
/*
 *  PreciseOnsetLocator.cpp
 *  peakOnsetDetector
 *
 *  Created by Andrew Robertson on 21/09/2012.
 *  Copyright 2012 QMUL. All rights reserved.
 *
 */

#include "PreciseOnsetLocator.h"

const bool printingOn = false;//true;

PreciseOnsetLocator::PreciseOnsetLocator(){
	setup(512);
}

PreciseOnsetLocator::~PreciseOnsetLocator(){
	onsetSamples.clear();
	recentBufferSamples.clear();
}


void PreciseOnsetLocator::setup(const int& size){
	onsetSamples.clear();
	recentBufferSamples.clear();
	bufferSize = size;
	onsetSamples.assign(bufferSize, 0.0);
	recentBufferSamples.assign(bufferSize, 0.0);
	if (printingOn)
		printf("Precise onset locator - using %i samples as framesize\n", size);
}

void PreciseOnsetLocator::storeSamples(double* newSamples){
	
	for (int i = 0;i < bufferSize;i++)
		recentBufferSamples[i] = newSamples[i];
	
}

int PreciseOnsetLocator::findExactOnset(double* frame){
	//store the samples - mainly for viewing actually
	onsetSamples.clear();
	for (int i = 0; i < bufferSize;i++){
		onsetSamples.push_back(frame[i]);
	}
	
	double energySum = 0;
	double lastEnergySum, hopsizeLastEnergySum;
	double energyDifference;
	int bestEnergyIndex = 0;
	double bestEnergyDifference = 0;
	int endIndex = bufferSize;
	int hopSize;
	
	for (int resolution = bufferSize/2; resolution > 1; resolution/=2){
		if (printingOn)
			printf("resolution %i\n", resolution);
		
		bestEnergyDifference = 0;
		//	printf("previous energy %f", lastEnergySum);
		//initialise last energySum
		hopSize = resolution/2;
		
		lastEnergySum = getLastEnergySum(bestEnergyIndex, resolution);
		hopsizeLastEnergySum = getLastEnergySum(bestEnergyIndex + hopSize, resolution);
		
		for (int startIndex = bestEnergyIndex;startIndex + resolution <= endIndex;startIndex += hopSize){
			if (printingOn)
				printf("index %i last energy %f hop energy %f ", startIndex, lastEnergySum, hopsizeLastEnergySum);
			
			//sum the energy for this new frame
			energySum = 0;
			for (int i = 0;i < resolution;i++){
				energySum += onsetSamples[startIndex + i] * onsetSamples[startIndex + i];
			}
			
			if (printingOn)
				printf("energysum %f\n", energySum);
			//check if new max difference
			energyDifference = energySum - lastEnergySum;
			if (energyDifference > bestEnergyDifference){
				bestEnergyDifference = energyDifference;
				bestEnergyIndex = startIndex;
			}
			
			//store the values for checking in two loops time (because proceeding at resolution/2 each step)
			//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, 
			lastEnergySum = hopsizeLastEnergySum;// energySum;
			hopsizeLastEnergySum = energySum;
			
		}
		if (printingOn)
			printf("winning index is %i\n", bestEnergyIndex);
		endIndex = bestEnergyIndex + resolution;
		
	}
	if (printingOn)
		printf("TOTAL WINNER %i\n", bestEnergyIndex);
	return bestEnergyIndex;
	
}

double PreciseOnsetLocator::getLastEnergySum(const int& startIndex, const int& vectorSize){
	double lastEnergySum = 0;
	if (bufferSize + startIndex < recentBufferSamples.size()){
		for (int i = startIndex - vectorSize;i < startIndex;i++){
			if (i > 0)
				lastEnergySum += onsetSamples[i] * onsetSamples[i];
			else {
				lastEnergySum += recentBufferSamples[bufferSize + i] * recentBufferSamples[bufferSize + i];
			}
		}
	}
	return lastEnergySum;
	
}