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