andrew@1
|
1 /*
|
andrew@1
|
2 * PreciseOnsetLocator.cpp
|
andrew@1
|
3 * peakOnsetDetector
|
andrew@1
|
4 *
|
andrew@1
|
5 * Created by Andrew on 21/09/2012.
|
andrew@1
|
6 * Copyright 2012 QMUL. All rights reserved.
|
andrew@1
|
7 *
|
andrew@1
|
8 */
|
andrew@1
|
9
|
andrew@1
|
10 #include "PreciseOnsetLocator.h"
|
andrew@1
|
11
|
andrew@1
|
12 PreciseOnsetLocator::PreciseOnsetLocator(){
|
andrew@1
|
13 setup(512);
|
andrew@1
|
14 }
|
andrew@1
|
15
|
andrew@1
|
16 PreciseOnsetLocator::~PreciseOnsetLocator(){
|
andrew@1
|
17 onsetSamples.clear();
|
andrew@1
|
18 recentBufferSamples.clear();
|
andrew@1
|
19 }
|
andrew@1
|
20
|
andrew@1
|
21
|
andrew@1
|
22 void PreciseOnsetLocator::setup(const int& size){
|
andrew@1
|
23 onsetSamples.clear();
|
andrew@1
|
24 recentBufferSamples.clear();
|
andrew@1
|
25 bufferSize = size;
|
andrew@1
|
26 onsetSamples.assign(bufferSize, 0.0);
|
andrew@1
|
27 recentBufferSamples.assign(bufferSize, 0.0);
|
andrew@1
|
28 }
|
andrew@1
|
29
|
andrew@1
|
30 void PreciseOnsetLocator::storeSamples(double* newSamples){
|
andrew@1
|
31
|
andrew@1
|
32 for (int i = 0;i < bufferSize;i++)
|
andrew@1
|
33 recentBufferSamples[i] = newSamples[i];
|
andrew@1
|
34
|
andrew@1
|
35 }
|
andrew@1
|
36
|
andrew@1
|
37 int PreciseOnsetLocator::findExactOnset(double* frame){
|
andrew@1
|
38 //store the samples - mainly for viewing actually
|
andrew@1
|
39 onsetSamples.clear();
|
andrew@1
|
40 for (int i = 0; i < bufferSize;i++) {
|
andrew@1
|
41 onsetSamples.push_back(frame[i]);
|
andrew@1
|
42 }
|
andrew@1
|
43
|
andrew@1
|
44 double energySum = 0;
|
andrew@1
|
45 double lastEnergySum, hopsizeLastEnergySum;
|
andrew@1
|
46 double energyDifference;
|
andrew@1
|
47 int bestEnergyIndex = 0;
|
andrew@1
|
48 double bestEnergyDifference = 0;
|
andrew@1
|
49 int endIndex = bufferSize;
|
andrew@1
|
50 int hopSize;
|
andrew@1
|
51
|
andrew@1
|
52 for (int resolution = bufferSize/2;resolution > 1;resolution/=2){
|
andrew@1
|
53 printf("resolution %i\n", resolution);
|
andrew@1
|
54
|
andrew@1
|
55 bestEnergyDifference = 0;
|
andrew@1
|
56 // printf("previous energy %f", lastEnergySum);
|
andrew@1
|
57 //initialise last energySum
|
andrew@1
|
58 hopSize = resolution/2;
|
andrew@1
|
59
|
andrew@1
|
60
|
andrew@1
|
61 lastEnergySum = getLastEnergySum(bestEnergyIndex, resolution);
|
andrew@1
|
62 hopsizeLastEnergySum = getLastEnergySum(bestEnergyIndex + hopSize, resolution);
|
andrew@1
|
63
|
andrew@1
|
64 for (int startIndex = bestEnergyIndex;startIndex + resolution <= endIndex;startIndex += hopSize){
|
andrew@1
|
65 printf("index %i last energy %f hop energy %f ", startIndex, lastEnergySum, hopsizeLastEnergySum);
|
andrew@1
|
66
|
andrew@1
|
67 //sum the energy for this new frame
|
andrew@1
|
68 energySum = 0;
|
andrew@1
|
69 for (int i = 0;i < resolution;i++){
|
andrew@1
|
70 energySum += onsetSamples[startIndex + i] * onsetSamples[startIndex + i];
|
andrew@1
|
71 }
|
andrew@1
|
72
|
andrew@1
|
73 printf("energysum %f\n", energySum);
|
andrew@1
|
74 //check if new max difference
|
andrew@1
|
75 energyDifference = energySum - lastEnergySum;
|
andrew@1
|
76 if (energyDifference > bestEnergyDifference){
|
andrew@1
|
77 bestEnergyDifference = energyDifference;
|
andrew@1
|
78 bestEnergyIndex = startIndex;
|
andrew@1
|
79 }
|
andrew@1
|
80
|
andrew@1
|
81 //store the values for checking in two loops time (because proceeding at resolution/2 each step)
|
andrew@1
|
82 //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
|
83 lastEnergySum = hopsizeLastEnergySum;// energySum;
|
andrew@1
|
84 hopsizeLastEnergySum = energySum;
|
andrew@1
|
85
|
andrew@1
|
86 }
|
andrew@1
|
87 printf("winning index is %i\n", bestEnergyIndex);
|
andrew@1
|
88 endIndex = bestEnergyIndex + resolution;
|
andrew@1
|
89
|
andrew@1
|
90 }
|
andrew@1
|
91 printf("TOTAL WINNER %i\n", bestEnergyIndex);
|
andrew@1
|
92 return bestEnergyIndex;
|
andrew@1
|
93
|
andrew@1
|
94 }
|
andrew@1
|
95
|
andrew@1
|
96 double PreciseOnsetLocator::getLastEnergySum(const int& startIndex, const int& vectorSize){
|
andrew@1
|
97 double lastEnergySum = 0;
|
andrew@1
|
98
|
andrew@1
|
99 for (int i = startIndex - vectorSize;i < startIndex;i++){
|
andrew@1
|
100 if (i > 0)
|
andrew@1
|
101 lastEnergySum += onsetSamples[i] * onsetSamples[i];
|
andrew@1
|
102 else {
|
andrew@1
|
103 lastEnergySum += recentBufferSamples[bufferSize + i] * recentBufferSamples[bufferSize + i];
|
andrew@1
|
104 }
|
andrew@1
|
105 }
|
andrew@1
|
106 return lastEnergySum;
|
andrew@1
|
107
|
andrew@1
|
108 }
|