andrew@0
|
1 #include "testApp.h"
|
andrew@0
|
2
|
andrew@0
|
3
|
andrew@0
|
4 //--------------------------------------------------------------
|
andrew@0
|
5 void testApp::setup(){
|
andrew@0
|
6
|
andrew@0
|
7 ofSetVerticalSync(true);
|
andrew@0
|
8 ofSetCircleResolution(80);
|
andrew@0
|
9 ofBackground(54, 54, 54);
|
andrew@0
|
10
|
andrew@0
|
11 // 0 output channels,
|
andrew@0
|
12 // 2 input channels
|
andrew@0
|
13 // 44100 samples per second
|
andrew@0
|
14 // 256 samples per buffer
|
andrew@0
|
15 // 4 num buffers (latency)
|
andrew@0
|
16
|
andrew@0
|
17 soundStream.listDevices();
|
andrew@0
|
18 soundStream.setDeviceID(0);//this now uses the audio input rather than mic input for mac
|
andrew@0
|
19 //outputStream.setDeviceID(1);
|
andrew@0
|
20
|
andrew@0
|
21 //if you want to set a different device id
|
andrew@0
|
22 //soundStream.setDeviceID(0); //bear in mind the device id corresponds to all audio devices, including input-only and output-only devices.
|
andrew@0
|
23
|
andrew@0
|
24 bufferSize = 512;
|
andrew@0
|
25
|
andrew@0
|
26 left.assign(bufferSize, 0.0);
|
andrew@0
|
27 right.assign(bufferSize, 0.0);
|
andrew@0
|
28 volHistory.assign(400, 0.0);
|
andrew@0
|
29
|
andrew@0
|
30 bufferCounter = 0;
|
andrew@0
|
31 drawCounter = 0;
|
andrew@0
|
32 smoothedVol = 0.0;
|
andrew@0
|
33 scaledVol = 0.0;
|
andrew@0
|
34
|
andrew@0
|
35 soundStream.setup(this, 0, 2, 44100, bufferSize, 4);
|
andrew@0
|
36
|
andrew@0
|
37 //peak analysis
|
andrew@0
|
38 onsetSamples.assign(bufferSize, 0.0);
|
andrew@0
|
39 // recentBufferSamples.assign(bufferSize, 0.0);
|
andrew@0
|
40 holdOn = false;
|
andrew@0
|
41 exactOnsetIndex = 0;
|
andrew@0
|
42
|
andrew@0
|
43 precisionLocator.setup(bufferSize);
|
andrew@0
|
44
|
andrew@0
|
45 }
|
andrew@0
|
46
|
andrew@0
|
47 //--------------------------------------------------------------
|
andrew@0
|
48 void testApp::update(){
|
andrew@0
|
49 //lets scale the vol up to a 0-1 range
|
andrew@0
|
50 scaledVol = ofMap(smoothedVol, 0.0, 0.17, 0.0, 1.0, true);
|
andrew@0
|
51
|
andrew@0
|
52 //lets record the volume into an array
|
andrew@0
|
53 volHistory.push_back( scaledVol );
|
andrew@0
|
54
|
andrew@0
|
55 //if we are bigger the the size we want to record - lets drop the oldest value
|
andrew@0
|
56 if( volHistory.size() >= 400 ){
|
andrew@0
|
57 volHistory.erase(volHistory.begin(), volHistory.begin()+1);
|
andrew@0
|
58 }
|
andrew@0
|
59 }
|
andrew@0
|
60
|
andrew@0
|
61 //--------------------------------------------------------------
|
andrew@0
|
62 void testApp::draw(){
|
andrew@0
|
63
|
andrew@0
|
64 ofSetColor(225);
|
andrew@2
|
65 ofDrawBitmapString("AUDIO INPUT :: PRECISE ONSET DETECTION " + ofToString(exactOnsetIndex), 32, 32);
|
andrew@0
|
66 ofDrawBitmapString("press 's' to unpause the audio\n'e' to pause the audio", 31, 92);
|
andrew@0
|
67
|
andrew@0
|
68 ofNoFill();
|
andrew@0
|
69
|
andrew@0
|
70 // draw the left channel:
|
andrew@0
|
71 ofPushStyle();
|
andrew@0
|
72 ofPushMatrix();
|
andrew@0
|
73 ofTranslate(32, 120, 0);
|
andrew@0
|
74
|
andrew@0
|
75 ofSetColor(225);
|
andrew@0
|
76 ofDrawBitmapString("Left Channel", 4, 18);
|
andrew@0
|
77
|
andrew@0
|
78 ofSetLineWidth(1);
|
andrew@0
|
79 ofRect(0, 0, 512, 200);
|
andrew@0
|
80
|
andrew@0
|
81 ofSetColor(245, 58, 135);
|
andrew@0
|
82 ofSetLineWidth(3);
|
andrew@0
|
83
|
andrew@0
|
84 ofBeginShape();
|
andrew@0
|
85 for (int i = 0; i < left.size(); i++){
|
andrew@0
|
86 ofVertex(i, 100 -left[i]*180.0f);
|
andrew@0
|
87 }
|
andrew@0
|
88 ofEndShape(false);
|
andrew@0
|
89
|
andrew@0
|
90 ofPopMatrix();
|
andrew@0
|
91 ofPopStyle();
|
andrew@0
|
92
|
andrew@0
|
93 // draw the right channel:
|
andrew@0
|
94 ofPushStyle();
|
andrew@0
|
95 ofPushMatrix();
|
andrew@0
|
96 ofTranslate(32, 320, 0);
|
andrew@0
|
97
|
andrew@0
|
98 ofSetColor(225);
|
andrew@0
|
99 ofDrawBitmapString("Onset DF function", 4, 18);
|
andrew@0
|
100
|
andrew@0
|
101 ofSetLineWidth(1);
|
andrew@0
|
102 ofRect(0, 0, 512, 200);
|
andrew@2
|
103
|
andrew@2
|
104 //param
|
andrew@2
|
105 float heightFactor = 0.15;
|
andrew@2
|
106
|
andrew@0
|
107 ofSetColor(245, 58, 135);
|
andrew@0
|
108 ofSetLineWidth(3);
|
andrew@0
|
109
|
andrew@0
|
110 ofBeginShape();
|
andrew@0
|
111 for (int i = 0; i < peakProcess.recentDFsamples.size(); i++){
|
andrew@2
|
112 int height = 200 - peakProcess.recentDFsamples[i]*heightFactor;
|
andrew@0
|
113 ofVertex(i*6, height);
|
andrew@0
|
114 // if (recentDFonsetFound[i]){
|
andrew@0
|
115 // ofCircle(32+i*6, 376+height , 10);
|
andrew@0
|
116 // }
|
andrew@0
|
117 // ofVertex(i*2, 100 -right[i]*180.0f);
|
andrew@0
|
118 }
|
andrew@0
|
119 ofEndShape(false);
|
andrew@0
|
120
|
andrew@0
|
121 ofPopMatrix();
|
andrew@0
|
122 ofPopStyle();
|
andrew@0
|
123
|
andrew@0
|
124 //slope values
|
andrew@0
|
125 ofPushStyle();
|
andrew@0
|
126 ofPushMatrix();
|
andrew@0
|
127 ofTranslate(32, 320, 0);
|
andrew@0
|
128
|
andrew@0
|
129 ofSetLineWidth(1);
|
andrew@0
|
130
|
andrew@0
|
131 ofSetColor(25, 124, 235);
|
andrew@0
|
132 ofSetLineWidth(3);
|
andrew@0
|
133
|
andrew@0
|
134 ofBeginShape();
|
andrew@0
|
135 for (int i = 0; i < peakProcess.recentDFsamples.size(); i++){
|
andrew@2
|
136 int height = 200 - peakProcess.recentDFslopeValues[i]*heightFactor;
|
andrew@0
|
137 ofVertex(i*6, height);
|
andrew@0
|
138
|
andrew@0
|
139 }
|
andrew@0
|
140 ofEndShape(false);
|
andrew@0
|
141
|
andrew@0
|
142 ofPopMatrix();
|
andrew@0
|
143 ofPopStyle();
|
andrew@0
|
144
|
andrew@0
|
145
|
andrew@0
|
146 //ONSETS
|
andrew@0
|
147 ofPushStyle();
|
andrew@0
|
148 ofPushMatrix();
|
andrew@0
|
149 ofTranslate(32, 320, 0);
|
andrew@0
|
150
|
andrew@0
|
151 ofSetColor(25, 224, 135);
|
andrew@2
|
152
|
andrew@0
|
153 ofSetLineWidth(3);
|
andrew@0
|
154
|
andrew@0
|
155 ofBeginShape();
|
andrew@0
|
156 for (int i = 0; i < peakProcess.recentDFsamples.size(); i++){
|
andrew@0
|
157 if (peakProcess.recentDFonsetFound[i])
|
andrew@0
|
158 ofVertex(i*6, 0);
|
andrew@0
|
159 else {
|
andrew@2
|
160 ofVertex(i*6, 200);
|
andrew@0
|
161 }
|
andrew@0
|
162 }
|
andrew@0
|
163 ofEndShape(false);
|
andrew@0
|
164
|
andrew@0
|
165 ofPopMatrix();
|
andrew@0
|
166 ofPopStyle();
|
andrew@0
|
167
|
andrew@2
|
168
|
andrew@2
|
169
|
andrew@0
|
170 //ONSET Samples
|
andrew@0
|
171 ofPushStyle();
|
andrew@0
|
172 ofPushMatrix();
|
andrew@0
|
173 ofTranslate(32, 520, 0);
|
andrew@0
|
174
|
andrew@0
|
175 ofSetColor(245, 224, 235);
|
andrew@2
|
176 ofDrawBitmapString("exact onset index (in buffer) "+ofToString(exactOnsetIndex), 0, 20);
|
andrew@2
|
177
|
andrew@0
|
178 ofSetLineWidth(3);
|
andrew@0
|
179
|
andrew@0
|
180 ofBeginShape();
|
andrew@0
|
181 for (int i = 0; i < precisionLocator.onsetSamples.size(); i++){
|
andrew@0
|
182 int height = 100 + 100 * precisionLocator.onsetSamples[i];
|
andrew@0
|
183 ofVertex(i, height);
|
andrew@0
|
184 }
|
andrew@0
|
185 ofEndShape(false);
|
andrew@0
|
186
|
andrew@0
|
187 ofSetColor(240,0,0);
|
andrew@0
|
188 ofLine(exactOnsetIndex, 0, exactOnsetIndex, 200);//stripe where on
|
andrew@0
|
189
|
andrew@0
|
190 ofPopMatrix();
|
andrew@0
|
191 ofPopStyle();
|
andrew@0
|
192
|
andrew@0
|
193
|
andrew@0
|
194 // draw the average volume:
|
andrew@0
|
195 ofPushStyle();
|
andrew@0
|
196 ofPushMatrix();
|
andrew@0
|
197 ofTranslate(565, 120, 0);
|
andrew@0
|
198
|
andrew@0
|
199 ofSetColor(225);
|
andrew@0
|
200 ofDrawBitmapString("Scaled average vol (0-100): " + ofToString(scaledVol * 100.0, 0), 4, 18);
|
andrew@0
|
201 ofRect(0, 0, 400, 400);
|
andrew@0
|
202
|
andrew@0
|
203 ofSetColor(245, 58, 135);
|
andrew@0
|
204 ofFill();
|
andrew@0
|
205 ofCircle(200, 200, scaledVol * 190.0f);
|
andrew@0
|
206
|
andrew@0
|
207 //lets draw the volume history as a graph
|
andrew@0
|
208 ofBeginShape();
|
andrew@0
|
209 for (int i = 0; i < volHistory.size(); i++){
|
andrew@0
|
210 if( i == 0 ) ofVertex(i, 400);
|
andrew@0
|
211
|
andrew@0
|
212 ofVertex(i, 400 - volHistory[i] * 70);
|
andrew@0
|
213
|
andrew@0
|
214 if( i == volHistory.size() -1 ) ofVertex(i, 400);
|
andrew@0
|
215 }
|
andrew@0
|
216 ofEndShape(false);
|
andrew@0
|
217
|
andrew@0
|
218 ofPopMatrix();
|
andrew@0
|
219 ofPopStyle();
|
andrew@0
|
220
|
andrew@0
|
221 drawCounter++;
|
andrew@0
|
222
|
andrew@0
|
223 ofSetColor(225);
|
andrew@0
|
224 string reportString = "buffers received: "+ofToString(bufferCounter)+"\ndraw routines called: "+ofToString(drawCounter)+"\nticks: " + ofToString(soundStream.getTickCount());
|
andrew@0
|
225 ofDrawBitmapString(reportString, 32, 89);
|
andrew@0
|
226
|
andrew@0
|
227
|
andrew@0
|
228 if (peakProcess.newOnsetFound){
|
andrew@0
|
229 ofSetColor(255,0,0);
|
andrew@0
|
230 ofCircle(200,200,200);
|
andrew@0
|
231 }
|
andrew@0
|
232 }
|
andrew@0
|
233
|
andrew@0
|
234 //--------------------------------------------------------------
|
andrew@0
|
235 void testApp::audioIn(float * input, int bufferSize, int nChannels){
|
andrew@0
|
236
|
andrew@0
|
237 float curVol = 0.0;
|
andrew@0
|
238
|
andrew@0
|
239 // samples are "interleaved"
|
andrew@0
|
240 int numCounted = 0;
|
andrew@0
|
241
|
andrew@0
|
242 double frame[bufferSize];
|
andrew@0
|
243
|
andrew@0
|
244 for (int i = 0;i < bufferSize;i++){
|
andrew@0
|
245 frame[i] = (double) input[i*2];
|
andrew@0
|
246 }
|
andrew@0
|
247
|
andrew@0
|
248 double df_sample = (float) odf.getDFsample(frame);
|
andrew@0
|
249
|
andrew@0
|
250 bool peakFound = peakProcess.peakProcessing(df_sample);//our new fn to look for DF onset events
|
andrew@0
|
251
|
andrew@0
|
252 //when we find a peak, we get the precise location of it
|
andrew@0
|
253 if (peakFound && !holdOn){
|
andrew@1
|
254 exactOnsetIndex = precisionLocator.findExactOnset(&frame[0]);//divide by 512.0 or bufferSize to get [0,1] value
|
andrew@0
|
255 }
|
andrew@0
|
256
|
andrew@0
|
257 //need to store these continually to help in location process
|
andrew@0
|
258 precisionLocator.storeSamples(&frame[0]);
|
andrew@0
|
259
|
andrew@0
|
260
|
andrew@0
|
261 //lets go through each sample and calculate the root mean square which is a rough way to calculate volume
|
andrew@0
|
262 for (int i = 0; i < bufferSize; i++){
|
andrew@0
|
263
|
andrew@0
|
264 //recentBufferSamples[i] = frame[i];//store the last buffer in case needed for exact onset detection
|
andrew@0
|
265
|
andrew@0
|
266
|
andrew@0
|
267
|
andrew@0
|
268
|
andrew@0
|
269 left[i] = input[i*2]*0.5;
|
andrew@0
|
270 right[i] = input[i*2+1]*0.5;
|
andrew@0
|
271
|
andrew@0
|
272 curVol += left[i] * left[i];
|
andrew@0
|
273 curVol += right[i] * right[i];
|
andrew@0
|
274 numCounted+=2;
|
andrew@0
|
275
|
andrew@0
|
276 }
|
andrew@0
|
277
|
andrew@0
|
278 //this is how we get the mean of rms :)
|
andrew@0
|
279 curVol /= (float)numCounted;
|
andrew@0
|
280
|
andrew@0
|
281 // this is how we get the root of rms :)
|
andrew@0
|
282 curVol = sqrt( curVol );
|
andrew@0
|
283
|
andrew@0
|
284 smoothedVol *= 0.93;
|
andrew@0
|
285 smoothedVol += 0.07 * curVol;
|
andrew@0
|
286
|
andrew@0
|
287 bufferCounter++;
|
andrew@0
|
288
|
andrew@0
|
289 }
|
andrew@0
|
290 /*
|
andrew@0
|
291 int testApp::findExactOnset(){
|
andrew@0
|
292 double energySum = 0;
|
andrew@0
|
293 double lastEnergySum, hopsizeLastEnergySum;
|
andrew@0
|
294 double energyDifference;
|
andrew@0
|
295 int bestEnergyIndex = 0;
|
andrew@0
|
296 double bestEnergyDifference = 0;
|
andrew@0
|
297 int endIndex = bufferSize;
|
andrew@0
|
298 int hopSize;
|
andrew@0
|
299
|
andrew@0
|
300 for (int resolution = bufferSize/2;resolution > 1;resolution/=2){
|
andrew@0
|
301 printf("resolution %i\n", resolution);
|
andrew@0
|
302 /// for (int i = bufferSize - resolution;i < bufferSize;i++){
|
andrew@0
|
303 // lastEnergySum += recentBufferSamples[i] * recentBufferSamples[i];
|
andrew@0
|
304 // }
|
andrew@0
|
305
|
andrew@0
|
306 bestEnergyDifference = 0;
|
andrew@0
|
307 // printf("previous energy %f", lastEnergySum);
|
andrew@0
|
308 //initialise last energySum
|
andrew@0
|
309 hopSize = resolution/2;
|
andrew@0
|
310
|
andrew@0
|
311
|
andrew@0
|
312 lastEnergySum = getLastEnergySum(bestEnergyIndex, resolution);
|
andrew@0
|
313 hopsizeLastEnergySum = getLastEnergySum(bestEnergyIndex + hopSize, resolution);
|
andrew@0
|
314
|
andrew@0
|
315 for (int startIndex = bestEnergyIndex;startIndex + resolution <= endIndex;startIndex += hopSize){
|
andrew@0
|
316 printf("index %i last energy %f hop energy %f ", startIndex, lastEnergySum, hopsizeLastEnergySum);
|
andrew@0
|
317
|
andrew@0
|
318 //sum the energy for this new frame
|
andrew@0
|
319 energySum = 0;
|
andrew@0
|
320 for (int i = 0;i < resolution;i++){
|
andrew@0
|
321 energySum += onsetSamples[startIndex + i] * onsetSamples[startIndex + i];
|
andrew@0
|
322 }
|
andrew@0
|
323
|
andrew@0
|
324 printf("energysum %f\n", energySum);
|
andrew@0
|
325 //check if new max difference
|
andrew@0
|
326 energyDifference = energySum - lastEnergySum;
|
andrew@0
|
327 if (energyDifference > bestEnergyDifference){
|
andrew@0
|
328 bestEnergyDifference = energyDifference;
|
andrew@0
|
329 bestEnergyIndex = startIndex;
|
andrew@0
|
330 }
|
andrew@0
|
331
|
andrew@0
|
332 //store the values for checking in two loops time (because proceeding at resolution/2 each step)
|
andrew@0
|
333 //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
|
334 lastEnergySum = hopsizeLastEnergySum;// energySum;
|
andrew@0
|
335 hopsizeLastEnergySum = energySum;
|
andrew@0
|
336
|
andrew@0
|
337 }
|
andrew@0
|
338 printf("winning index is %i\n", bestEnergyIndex);
|
andrew@0
|
339 endIndex = bestEnergyIndex + resolution;
|
andrew@0
|
340
|
andrew@0
|
341 }
|
andrew@0
|
342 printf("TOTAL WINNER %i\n", bestEnergyIndex);
|
andrew@0
|
343 return bestEnergyIndex;
|
andrew@0
|
344
|
andrew@0
|
345 }
|
andrew@0
|
346
|
andrew@0
|
347 double testApp::getLastEnergySum(const int& startIndex, const int& vectorSize){
|
andrew@0
|
348 double lastEnergySum = 0;
|
andrew@0
|
349
|
andrew@0
|
350 for (int i = startIndex - vectorSize;i < startIndex;i++){
|
andrew@0
|
351 if (i > 0)
|
andrew@0
|
352 lastEnergySum += onsetSamples[i] * onsetSamples[i];
|
andrew@0
|
353 else {
|
andrew@0
|
354 lastEnergySum += recentBufferSamples[bufferSize + i] * recentBufferSamples[bufferSize + i];
|
andrew@0
|
355 }
|
andrew@0
|
356 }
|
andrew@0
|
357 return lastEnergySum;
|
andrew@0
|
358
|
andrew@0
|
359 }
|
andrew@0
|
360 */
|
andrew@0
|
361 /*
|
andrew@0
|
362 bool testApp::peakProcessing(const double& newDFval){
|
andrew@0
|
363 recentDFsamples.erase (recentDFsamples.begin(), recentDFsamples.begin()+1);//erase first val
|
andrew@0
|
364 recentDFsamples.push_back(newDFval);
|
andrew@0
|
365
|
andrew@0
|
366 double slopeVal = getBestSlopeValue(newDFval);
|
andrew@0
|
367
|
andrew@0
|
368 newOnsetFound = checkForSlopeOnset(slopeVal);
|
andrew@0
|
369 printf("slope %f median %f det median %f\n", slopeVal, bestSlopeMedian, detectionTriggerThreshold);
|
andrew@0
|
370
|
andrew@0
|
371 if (newOnsetFound)
|
andrew@0
|
372 printf("BANG!\n");
|
andrew@0
|
373
|
andrew@0
|
374 recentDFslopeValues.erase (recentDFslopeValues.begin(), recentDFslopeValues.begin()+1);//erase first val
|
andrew@0
|
375 recentDFslopeValues.push_back(slopeVal);
|
andrew@0
|
376
|
andrew@0
|
377 recentDFonsetFound.erase (recentDFonsetFound.begin(), recentDFonsetFound.begin()+1);//erase first val
|
andrew@0
|
378 recentDFonsetFound.push_back(newOnsetFound);
|
andrew@0
|
379
|
andrew@0
|
380
|
andrew@0
|
381 //printf("\n");
|
andrew@0
|
382 // for (int i = 0;i < recentDFsamples.size();i++){
|
andrew@0
|
383 // printf("rdf[%i] %f\n", i, recentDFsamples[i]);
|
andrew@0
|
384 // }
|
andrew@0
|
385 //printf("SLOPE %f\n", slopeVal);
|
andrew@0
|
386 }
|
andrew@0
|
387
|
andrew@0
|
388
|
andrew@0
|
389 double testApp::getBestSlopeValue(const float& dfvalue){
|
andrew@0
|
390
|
andrew@0
|
391 //the idea is we want a high slope
|
andrew@0
|
392 double bestValue = 0;
|
andrew@0
|
393
|
andrew@0
|
394 for (int i = 1;i < min(numberOfDetectionValuesToTest, (int)recentDFsamples.size() - 1);i++){
|
andrew@0
|
395 double angle = 0;
|
andrew@0
|
396 int otherIndex = recentDFsamples.size() - i + 1;
|
andrew@0
|
397 double testValue = 0;
|
andrew@0
|
398
|
andrew@0
|
399 if (otherIndex > 0 && recentDFsamples[otherIndex] > 0
|
andrew@0
|
400 && recentDFsamples[otherIndex] < dfvalue
|
andrew@0
|
401 ){
|
andrew@0
|
402 angle = atan((float)(i * dfvalue)/ (numberOfDetectionValuesToTest*(dfvalue-recentDFsamples[otherIndex])) );
|
andrew@0
|
403 testValue = (dfvalue - recentDFsamples[otherIndex]) * cos(angle);
|
andrew@0
|
404 }
|
andrew@0
|
405
|
andrew@0
|
406 if (testValue > bestValue)
|
andrew@0
|
407 bestValue = testValue;
|
andrew@0
|
408 }
|
andrew@0
|
409
|
andrew@0
|
410 return bestValue;
|
andrew@0
|
411
|
andrew@0
|
412 }
|
andrew@0
|
413
|
andrew@0
|
414
|
andrew@0
|
415
|
andrew@0
|
416 bool testApp :: checkForSlopeOnset(const float& bestValue){
|
andrew@0
|
417 bool onsetDetected = false;
|
andrew@0
|
418 //check for onset relative to our processed slope function
|
andrew@0
|
419 //a mix between increase in value and the gradient of that increase
|
andrew@0
|
420
|
andrew@0
|
421 currentFrame++;
|
andrew@0
|
422
|
andrew@0
|
423 if (bestValue > bestSlopeMedian * thresholdRelativeToMedian && //better than recent average
|
andrew@0
|
424 (currentFrame - lastSlopeOnsetFrame) > cutoffForRepeatOnsetsFrames //after cutoff time
|
andrew@0
|
425 && slopeFallenBelowMedian // has had onset and fall away again
|
andrew@0
|
426 && bestValue > detectionTriggerThreshold * detectionTriggerRatio //longer term ratio of winning onsets
|
andrew@0
|
427 ){
|
andrew@0
|
428 // printf("frame diff between onsets %6.1f", (1000*framesToSeconds(currentFrame - lastMedianOnsetFrame)) );
|
andrew@0
|
429 onsetDetected = true;
|
andrew@0
|
430 lastSlopeOnsetFrame = currentFrame;
|
andrew@0
|
431 slopeFallenBelowMedian = false;
|
andrew@0
|
432
|
andrew@0
|
433 updateDetectionTriggerThreshold(bestValue);
|
andrew@0
|
434 }
|
andrew@0
|
435
|
andrew@0
|
436
|
andrew@0
|
437 if (bestValue > bestSlopeMedian){
|
andrew@0
|
438 bestSlopeMedian += (bestValue - bestSlopeMedian)*0.04;//was 1.1
|
andrew@0
|
439 }
|
andrew@0
|
440 else{
|
andrew@0
|
441 bestSlopeMedian *= 0.99;
|
andrew@0
|
442 slopeFallenBelowMedian = true;;
|
andrew@0
|
443 }
|
andrew@0
|
444
|
andrew@0
|
445 //bestSlopeMedian += 0.02* (bestValue - bestSlopeMedian);
|
andrew@0
|
446
|
andrew@0
|
447
|
andrew@0
|
448
|
andrew@0
|
449 return onsetDetected;
|
andrew@0
|
450 }
|
andrew@0
|
451
|
andrew@0
|
452 void testApp :: updateDetectionTriggerThreshold(const float& val){
|
andrew@0
|
453 float detectionAdaptSpeed = 0.05;//moving average, roughly last twenty onsets
|
andrew@0
|
454 detectionTriggerThreshold *= 1- detectionAdaptSpeed;
|
andrew@0
|
455 detectionTriggerThreshold += (val * detectionAdaptSpeed);
|
andrew@0
|
456 }
|
andrew@0
|
457
|
andrew@0
|
458 */
|
andrew@0
|
459 //--------------------------------------------------------------
|
andrew@0
|
460 void testApp::keyPressed (int key){
|
andrew@0
|
461 if( key == 's' ){
|
andrew@0
|
462 soundStream.start();
|
andrew@0
|
463 }
|
andrew@0
|
464
|
andrew@0
|
465 if( key == 'e' ){
|
andrew@0
|
466 soundStream.stop();
|
andrew@0
|
467 }
|
andrew@0
|
468
|
andrew@0
|
469 if (key == 'h'){
|
andrew@0
|
470 holdOn = !holdOn;
|
andrew@0
|
471 }
|
andrew@0
|
472 }
|
andrew@0
|
473
|
andrew@0
|
474 //--------------------------------------------------------------
|
andrew@0
|
475 void testApp::keyReleased(int key){
|
andrew@0
|
476
|
andrew@0
|
477 }
|
andrew@0
|
478
|
andrew@0
|
479 //--------------------------------------------------------------
|
andrew@0
|
480 void testApp::mouseMoved(int x, int y ){
|
andrew@0
|
481
|
andrew@0
|
482 }
|
andrew@0
|
483
|
andrew@0
|
484 //--------------------------------------------------------------
|
andrew@0
|
485 void testApp::mouseDragged(int x, int y, int button){
|
andrew@0
|
486
|
andrew@0
|
487 }
|
andrew@0
|
488
|
andrew@0
|
489 //--------------------------------------------------------------
|
andrew@0
|
490 void testApp::mousePressed(int x, int y, int button){
|
andrew@0
|
491
|
andrew@0
|
492 }
|
andrew@0
|
493
|
andrew@0
|
494 //--------------------------------------------------------------
|
andrew@0
|
495 void testApp::mouseReleased(int x, int y, int button){
|
andrew@0
|
496
|
andrew@0
|
497 }
|
andrew@0
|
498
|
andrew@0
|
499 //--------------------------------------------------------------
|
andrew@0
|
500 void testApp::windowResized(int w, int h){
|
andrew@0
|
501
|
andrew@0
|
502 }
|
andrew@0
|
503
|
andrew@0
|
504 //--------------------------------------------------------------
|
andrew@0
|
505 void testApp::gotMessage(ofMessage msg){
|
andrew@0
|
506
|
andrew@0
|
507 }
|
andrew@0
|
508
|
andrew@0
|
509 //--------------------------------------------------------------
|
andrew@0
|
510 void testApp::dragEvent(ofDragInfo dragInfo){
|
andrew@0
|
511
|
andrew@0
|
512 }
|
andrew@0
|
513
|