Mercurial > hg > precise-onset-detection
comparison src/PeakProcessor.cpp @ 8:184a7c232049 tip
changed files since updating computer
author | Venetian |
---|---|
date | Thu, 14 Aug 2014 17:53:57 +0100 |
parents | 93b9a9471011 |
children |
comparison
equal
deleted
inserted
replaced
7:b1c13e8bec26 | 8:184a7c232049 |
---|---|
7 * | 7 * |
8 */ | 8 */ |
9 | 9 |
10 #include "PeakProcessor.h" | 10 #include "PeakProcessor.h" |
11 | 11 |
12 const bool printingOn = false;//true;//false; | 12 const bool printingOn = false;//true;//false;//true;//false; |
13 | |
14 | |
15 /* | |
16 how it works | |
17 detectionTriggerThreshold is a fairly fdast moving average (every twenty frames) | |
18 tend to require newValue > detectionTriggerRatio * detectionTriggerThreshold | |
19 */ | |
13 | 20 |
14 PeakProcessor::PeakProcessor(){ | 21 PeakProcessor::PeakProcessor(){ |
15 | 22 |
16 recentDFsamples.assign(vectorSize, 0.0); | 23 recentDFsamples.assign(vectorSize, 0.0); |
17 recentDFonsetFound.assign(vectorSize, false); | 24 recentDFonsetFound.assign(vectorSize, false); |
18 recentDFslopeValues.assign(vectorSize, 0.0); | 25 recentDFslopeValues.assign(vectorSize, 0.0); |
19 | 26 /* |
27 //all in reset | |
20 numberOfDetectionValuesToTest = 10; | 28 numberOfDetectionValuesToTest = 10; |
21 currentFrame = 0; | 29 currentFrame = 0; |
22 cutoffForRepeatOnsetsFrames = 4; | 30 cutoffForRepeatOnsetsFrames = 8; |
23 detectionTriggerRatio = 0.34f;//was 0.5 | 31 detectionTriggerRatio = 0.34f;//was 0.5 |
24 detectionTriggerThreshold = 1.5;//0.1; | 32 detectionTriggerThreshold = 0.2;//was 1.5 is trigger? |
25 bestSlopeMedian = 3; | 33 bestSlopeMedian = 3; |
26 thresholdRelativeToMedian = 1.1; | 34 thresholdRelativeToMedian = 1.1; |
27 slopeFallenBelowMedian = true; | 35 slopeFallenBelowMedian = true; |
28 lastSlopeOnsetFrame = 0; | 36 lastSlopeOnsetFrame = 0; |
37 */ | |
38 initialise(); | |
39 reset(); | |
40 minimumThreshold = 15.; | |
29 } | 41 } |
30 | 42 |
31 PeakProcessor::~PeakProcessor(){ | 43 PeakProcessor::~PeakProcessor(){ |
32 | 44 |
33 recentDFsamples.clear(); | 45 recentDFsamples.clear(); |
34 recentDFonsetFound.clear(); | 46 recentDFonsetFound.clear(); |
35 recentDFslopeValues.clear(); | 47 recentDFslopeValues.clear(); |
36 } | 48 } |
37 | 49 |
50 | |
51 void PeakProcessor::initialise(){ | |
52 numberOfDetectionValuesToTest = 10; | |
53 cutoffForRepeatOnsetsFrames = 8; | |
54 detectionTriggerRatio = 0.234f;//was 0.5 | |
55 thresholdRelativeToMedian = 1.01;//need to be this multiple above median value | |
56 //median tends to move relatively slowly | |
57 reset(); | |
58 /* slopeFallenBelowMedian = true; | |
59 lastSlopeOnsetFrame = 0; | |
60 currentFrame = 0; | |
61 */ | |
62 } | |
63 | |
64 void PeakProcessor::reset(){ | |
65 /* | |
66 numberOfDetectionValuesToTest = 10; | |
67 | |
68 cutoffForRepeatOnsetsFrames = 8; | |
69 detectionTriggerRatio = 0.234f;//was 0.5 | |
70 detectionTriggerThreshold = 0.2; | |
71 bestSlopeMedian = 3; | |
72 thresholdRelativeToMedian = 1.01;//need to be this multiple above median value | |
73 */ | |
74 //median tends to move relatively slowly | |
75 slopeFallenBelowMedian = true; | |
76 lastSlopeOnsetFrame = 0; | |
77 currentFrame = 0; | |
78 detectionTriggerThreshold = 0.4; | |
79 bestSlopeMedian = 16; | |
80 } | |
38 | 81 |
39 bool PeakProcessor::peakProcessing(const double& newDFval){ | 82 bool PeakProcessor::peakProcessing(const double& newDFval){ |
40 recentDFsamples.erase (recentDFsamples.begin(), recentDFsamples.begin()+1);//erase first val | 83 recentDFsamples.erase (recentDFsamples.begin(), recentDFsamples.begin()+1);//erase first val |
41 recentDFsamples.push_back(newDFval); | 84 recentDFsamples.push_back(newDFval); |
42 | 85 |
70 | 113 |
71 double PeakProcessor::getBestSlopeValue(const float& dfvalue){ | 114 double PeakProcessor::getBestSlopeValue(const float& dfvalue){ |
72 | 115 |
73 //the idea is we want a high slope | 116 //the idea is we want a high slope |
74 double bestValue = 0; | 117 double bestValue = 0; |
118 double bestCosAngle = 0; | |
75 | 119 |
76 for (int i = 1;i < min(numberOfDetectionValuesToTest, (int)recentDFsamples.size() - 1);i++){ | 120 for (int i = 1;i < min(numberOfDetectionValuesToTest, (int)recentDFsamples.size() - 1);i++){ |
77 double angle = 0; | 121 double angle = 0; |
78 int otherIndex = recentDFsamples.size() - i + 1; | 122 int otherIndex = recentDFsamples.size() - i + 1; |
79 double testValue = 0; | 123 double testValue = 0; |
83 ){ | 127 ){ |
84 angle = atan((float)(i * dfvalue)/ (numberOfDetectionValuesToTest*(dfvalue-recentDFsamples[otherIndex])) ); | 128 angle = atan((float)(i * dfvalue)/ (numberOfDetectionValuesToTest*(dfvalue-recentDFsamples[otherIndex])) ); |
85 testValue = (dfvalue - recentDFsamples[otherIndex]) * cos(angle); | 129 testValue = (dfvalue - recentDFsamples[otherIndex]) * cos(angle); |
86 } | 130 } |
87 | 131 |
88 if (testValue > bestValue) | 132 if (testValue > bestValue){ |
89 bestValue = testValue; | 133 bestValue = testValue; |
134 bestCosAngle = cos(angle); | |
135 } | |
90 } | 136 } |
91 | 137 if (printingOn) |
138 printf("best value %f dfValue %f cosAngle %f\n", bestValue, dfvalue, bestCosAngle); | |
139 | |
92 return bestValue; | 140 return bestValue; |
93 | 141 |
94 } | 142 } |
95 | 143 |
96 | 144 |
104 | 152 |
105 if (bestValue > bestSlopeMedian * thresholdRelativeToMedian && //better than recent average | 153 if (bestValue > bestSlopeMedian * thresholdRelativeToMedian && //better than recent average |
106 (currentFrame - lastSlopeOnsetFrame) > cutoffForRepeatOnsetsFrames //after cutoff time | 154 (currentFrame - lastSlopeOnsetFrame) > cutoffForRepeatOnsetsFrames //after cutoff time |
107 && slopeFallenBelowMedian // has had onset and fall away again | 155 && slopeFallenBelowMedian // has had onset and fall away again |
108 && bestValue > detectionTriggerThreshold * detectionTriggerRatio //longer term ratio of winning onsets | 156 && bestValue > detectionTriggerThreshold * detectionTriggerRatio //longer term ratio of winning onsets |
157 && bestValue > minimumThreshold//fixed minimum requirement | |
109 ){ | 158 ){ |
110 // printf("frame diff between onsets %6.1f", (1000*framesToSeconds(currentFrame - lastMedianOnsetFrame)) ); | 159 // printf("frame diff between onsets %6.1f", (1000*framesToSeconds(currentFrame - lastMedianOnsetFrame)) ); |
111 onsetDetected = true; | 160 onsetDetected = true; |
112 lastSlopeOnsetFrame = currentFrame; | 161 lastSlopeOnsetFrame = currentFrame; |
113 slopeFallenBelowMedian = false; | 162 slopeFallenBelowMedian = false; |
114 | 163 |
115 updateDetectionTriggerThreshold(bestValue); | 164 updateDetectionTriggerThreshold(bestValue); |
165 | |
166 if (printingOn) | |
167 printf("ONSET, best value %f, min %f\n", bestValue, minimumThreshold); | |
116 } | 168 } |
117 | 169 |
118 | 170 |
119 if (bestValue > bestSlopeMedian){ | 171 if (bestValue > bestSlopeMedian){ |
120 bestSlopeMedian += (bestValue - bestSlopeMedian)*0.04;//was 1.1 | 172 bestSlopeMedian += (bestValue - bestSlopeMedian)*0.04;//was 1.1 |