Mercurial > hg > aubio-onset-detector
comparison aubioOnsetDetectorOFvisualiser/src/testApp.cpp @ 3:979125db34ab
added OF visualiser src code. Added a long term median trigger threshold. New method is working very well on onsets
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Mon, 21 Nov 2011 23:22:40 +0000 |
parents | |
children | fb106f14e0a4 |
comparison
equal
deleted
inserted
replaced
2:b4c899822b4e | 3:979125db34ab |
---|---|
1 #include "testApp.h" | |
2 //#include "math.h" | |
3 | |
4 #define SAMPLING_FREQUENCY 44100 | |
5 #define FOURIER_LENGTH 2048 | |
6 #define TEXT_HEIGHT 10 | |
7 //-------------------------------------------------------------- | |
8 void testApp::setup(){ | |
9 // listen on the given port | |
10 // cout << "listening for osc messages on port " << PORT << "\n"; | |
11 receiver.setup( PORT ); | |
12 | |
13 current_msg_string = 0; | |
14 mouseX = 0; | |
15 mouseY = 0; | |
16 mouseButtonState = ""; | |
17 | |
18 ofBackground( 30, 30, 130 ); | |
19 | |
20 | |
21 outputGraphics = false; | |
22 | |
23 maximumDetectionFunction = 20; | |
24 minimumDetectionFunction = -20; | |
25 | |
26 screenWidth = (float) ofGetWidth(); | |
27 screenHeight = (float) ofGetHeight(); | |
28 | |
29 mouseDownX = 0; | |
30 mouseDownY = 0; | |
31 | |
32 amplitudeNumber = 256;//number of amplitudes shown on screen | |
33 | |
34 maxValue = 1.0; | |
35 | |
36 detectionType = "complex"; | |
37 lastOnsetDetectionValue; | |
38 | |
39 logMode = false; | |
40 | |
41 midiMode = true; | |
42 | |
43 resetMaxima = false; | |
44 | |
45 reIndexFlag = false; | |
46 | |
47 ofBackground(0,0,0); | |
48 | |
49 rawOnsetIndex = 0; | |
50 } | |
51 | |
52 //-------------------------------------------------------------- | |
53 void testApp::update(){ | |
54 maxValue *= 0.995; | |
55 // hide old messages | |
56 | |
57 // check for waiting messages | |
58 while( receiver.hasWaitingMessages() ) | |
59 { | |
60 // get the next message | |
61 ofxOscMessage m; | |
62 receiver.getNextMessage( &m ); | |
63 | |
64 // unrecognized message: display on the bottom of the screen | |
65 // string msg_string; | |
66 // msg_string = m.getAddress(); | |
67 if (m.getAddress() == "/aubioData" ){ | |
68 | |
69 if( m.getArgType( 0 ) == OFXOSC_TYPE_FLOAT ){ | |
70 | |
71 onsetIndex++; | |
72 onsetRecorded[onsetIndex] = false; | |
73 | |
74 if (onsetIndex >= NUM_DETECTION_SAMPLES) | |
75 onsetIndex = 0; | |
76 | |
77 onsetFunction[onsetIndex] = m.getArgAsFloat(0); | |
78 | |
79 checkMaxima(m.getArgAsFloat(0)); | |
80 | |
81 }//end if type FLOAT | |
82 }//end if aubioData | |
83 | |
84 | |
85 if (m.getAddress() == "/rawAubioData" ){ | |
86 | |
87 if( m.getArgType( 0 ) == OFXOSC_TYPE_FLOAT ){ | |
88 | |
89 rawOnsetIndex++; | |
90 | |
91 if (rawOnsetIndex >= NUM_DETECTION_SAMPLES) | |
92 rawOnsetIndex = 0; | |
93 | |
94 rawOnsetFunction[rawOnsetIndex] = m.getArgAsFloat(0); | |
95 checkRawMaxima(m.getArgAsFloat(0)); | |
96 | |
97 }//end if type FLOAT | |
98 }//end spec diff message | |
99 | |
100 | |
101 if (m.getAddress() == "/medianAubioData" ){ | |
102 | |
103 if( m.getArgType( 0 ) == OFXOSC_TYPE_FLOAT ){ | |
104 | |
105 medianOnsetIndex++; | |
106 | |
107 if (medianOnsetIndex >= NUM_DETECTION_SAMPLES){ | |
108 medianOnsetIndex = 0; | |
109 } | |
110 | |
111 if(medianOnsetIndex > 0) | |
112 medianOnsetRecorded[medianOnsetIndex] = false;//but how do we know this happens first! | |
113 | |
114 medianOnsetFunction[medianOnsetIndex] = m.getArgAsFloat(0); | |
115 | |
116 }//end if type FLOAT | |
117 }//end spec diff message | |
118 | |
119 | |
120 | |
121 | |
122 if (m.getAddress() == "/onset" ){ | |
123 onsetRecorded[onsetIndex] = true; | |
124 lastOnsetDetectionValue = onsetFunction[onsetIndex]; | |
125 } | |
126 | |
127 if (m.getAddress() == "/medianOnset" ){ | |
128 medianOnsetRecorded[onsetIndex] = true; | |
129 } | |
130 | |
131 | |
132 | |
133 if (m.getAddress() == "/rawOnset" ){ | |
134 rawOnsetRecorded[rawOnsetIndex] = true; | |
135 | |
136 } | |
137 | |
138 if (m.getAddress() == "/mode" ){ | |
139 resetMaxima = true; | |
140 detectionType = m.getArgAsString(0); | |
141 } | |
142 | |
143 }//end while | |
144 | |
145 } | |
146 | |
147 | |
148 void testApp::checkMaxima(float f){ | |
149 | |
150 //maximumDetectionFunction *= 0.99999; | |
151 //minimumDetectionFunction += (maximumDetectionFunction - minimumDetectionFunction)*0.00001; | |
152 | |
153 if (maximumDetectionFunction * 1.08 < f){ | |
154 maximumDetectionFunction = 1.08*f; | |
155 } | |
156 | |
157 if (minimumDetectionFunction + (fabs(minimumDetectionFunction * 0.08)) > f){ | |
158 minimumDetectionFunction = f - (0.08 * fabs(f)); | |
159 } | |
160 | |
161 if (resetMaxima == true){ | |
162 maximumDetectionFunction = 30; | |
163 minimumDetectionFunction = 0; | |
164 resetMaxima = false; | |
165 } | |
166 | |
167 } | |
168 | |
169 | |
170 void testApp::checkRawMaxima(float f){ | |
171 | |
172 //maximumDetectionFunction *= 0.99999; | |
173 //minimumDetectionFunction += (maximumDetectionFunction - minimumDetectionFunction)*0.00001; | |
174 | |
175 if (maximumDetectionFunction * 1.08 < f){ | |
176 maximumDetectionFunction = 1.08*f; | |
177 } | |
178 | |
179 if (minimumDetectionFunction + (fabs(minimumDetectionFunction * 0.08)) > f){ | |
180 minimumDetectionFunction = f - (0.08 * fabs(f)); | |
181 } | |
182 | |
183 } | |
184 | |
185 | |
186 | |
187 //-------------------------------------------------------------- | |
188 void testApp::draw(){ | |
189 | |
190 drawOnsetFunction(); | |
191 printInfo(); | |
192 | |
193 } | |
194 | |
195 void testApp::printMessages(){ | |
196 string buf; | |
197 buf = "listening for osc messages on port" + ofToString( PORT ); | |
198 ofDrawBitmapString( buf, 10, 20 ); | |
199 | |
200 for ( int i=0; i<NUM_MSG_STRINGS; i++ ) | |
201 { | |
202 ofDrawBitmapString( msg_strings[i], 10, 40+15*i ); | |
203 } | |
204 | |
205 } | |
206 | |
207 void testApp::printInfo(){ | |
208 ofSetColor(255,255,255); | |
209 string printString; | |
210 | |
211 /* printString = "Max "; | |
212 printString += ofToString(maximumDetectionFunction); | |
213 printString += " Min "; | |
214 printString += ofToString(minimumDetectionFunction); | |
215 */ | |
216 | |
217 printString += detectionType; | |
218 printString +=" "; | |
219 printString += ofToString(lastOnsetDetectionValue, 1); | |
220 ofDrawBitmapString( printString , 10, ofGetHeight() - 20); | |
221 } | |
222 | |
223 //-------------------------------------------------------------- | |
224 void testApp::keyPressed (int key){ | |
225 | |
226 if (key == OF_KEY_UP){ | |
227 | |
228 } | |
229 | |
230 if (key == OF_KEY_DOWN ){ | |
231 | |
232 } | |
233 | |
234 | |
235 if (key == OF_KEY_RIGHT ){ | |
236 | |
237 } | |
238 | |
239 if (key == OF_KEY_LEFT ){ | |
240 | |
241 } | |
242 | |
243 if (key == 'L' || key == 'l'){ | |
244 logMode = !logMode; | |
245 } | |
246 | |
247 if (key == 'p' || key == 'P'){ | |
248 | |
249 } | |
250 | |
251 if (key == 'm' || key == 'M'){ | |
252 midiMode = !midiMode; | |
253 } | |
254 | |
255 if (key == 'x' || key == 'X'){ | |
256 amplitudeNumber *= 2; | |
257 } | |
258 | |
259 if (key == 'z' || key == 'Z'){ | |
260 amplitudeNumber /= 2; | |
261 } | |
262 | |
263 if ((key == '=' || key == '+') && amplitudeNumber < 120){ | |
264 amplitudeNumber += 8; | |
265 } | |
266 | |
267 if ((key == '-' || key == '_') && amplitudeNumber > 12){ | |
268 amplitudeNumber -= 8; | |
269 } | |
270 | |
271 } | |
272 | |
273 | |
274 | |
275 void testApp::drawOnsetFunction(){ | |
276 int tmpIndex = onsetIndex; | |
277 float width = screenWidth / (float) amplitudeNumber; | |
278 float maximumValue = maximumDetectionFunction ; | |
279 float minimumValue = minimumDetectionFunction ; | |
280 float difference = maximumValue - minimumValue; | |
281 float scale_factor = screenHeight/ difference; | |
282 | |
283 //draw axis | |
284 ofSetColor(255,255,255); | |
285 ofLine(0, screenHeight - (scale_factor*(0 - minimumValue)), | |
286 (int) (width*(amplitudeNumber)), screenHeight - (scale_factor*(0 - minimumValue)) ); | |
287 | |
288 | |
289 for (int Xvalue = 0;Xvalue < amplitudeNumber; Xvalue++){ | |
290 | |
291 int Xindex = (onsetIndex-Xvalue) ; | |
292 int previousIndex = (Xindex-1); | |
293 | |
294 ofSetColor(55,100,255); | |
295 | |
296 ofLine((int) (width*(amplitudeNumber - Xvalue - 1)), screenHeight - (scale_factor*(onsetFunction[previousIndex]- minimumValue)), | |
297 (int) (width*(amplitudeNumber - Xvalue)), screenHeight - (scale_factor*(onsetFunction[Xindex]- minimumValue)) ); | |
298 | |
299 if (onsetRecorded[Xindex] == true){ | |
300 ofSetColor(255,100,255); | |
301 ofCircle(width*(amplitudeNumber - Xvalue), screenHeight - (scale_factor*(onsetFunction[Xindex]- minimumValue)) , 3); | |
302 } | |
303 | |
304 //specDiffOnsets | |
305 ofSetColor(55,100,55); | |
306 Xindex = (rawOnsetIndex-Xvalue) ; | |
307 previousIndex = (Xindex-1); | |
308 | |
309 ofLine((int) (width*(amplitudeNumber - Xvalue - 1)), screenHeight - (scale_factor*(rawOnsetFunction[previousIndex]- minimumValue)), | |
310 (int) (width*(amplitudeNumber - Xvalue)), screenHeight - (scale_factor*(rawOnsetFunction[Xindex]- minimumValue)) ); | |
311 | |
312 //median of Onset fn | |
313 ofSetColor(205,0,0); | |
314 Xindex = (medianOnsetIndex-Xvalue) ; | |
315 previousIndex = (Xindex-1); | |
316 | |
317 ofLine((int) (width*(amplitudeNumber - Xvalue - 1)), screenHeight - (scale_factor*(medianOnsetFunction[previousIndex]- minimumValue)), | |
318 (int) (width*(amplitudeNumber - Xvalue)), screenHeight - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) ); | |
319 | |
320 | |
321 | |
322 if (rawOnsetRecorded[Xindex] == true){ | |
323 ofSetColor(255,100,0); | |
324 ofCircle(width*(amplitudeNumber - Xvalue), screenHeight - (scale_factor*(rawOnsetFunction[Xindex]- minimumValue)) , 3); | |
325 } | |
326 | |
327 if (medianOnsetRecorded[Xindex] == true){ | |
328 ofSetColor(255,0,0); | |
329 ofCircle(width*(amplitudeNumber - Xvalue), screenHeight - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) , 3); | |
330 } | |
331 | |
332 | |
333 /* | |
334 if (medianOnsetRecorded[Xindex] == true){ | |
335 ofSetColor(255,0,0); | |
336 ofCircle(width*(amplitudeNumber - Xvalue), screenHeight - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) , 3); | |
337 } | |
338 */ | |
339 ofSetColor(255,100,0); | |
340 | |
341 }//end for Xvalue (across the recent observations of osc data) | |
342 | |
343 | |
344 //label y axis | |
345 int axisHeight, stepSize; | |
346 ofSetColor(255,255,255); | |
347 stepSize = 1000; | |
348 | |
349 while((difference / stepSize) < 3) | |
350 stepSize /= 2; | |
351 | |
352 while ((difference / stepSize) > 7)// maximum 6 numbers to display | |
353 stepSize *= 2; | |
354 | |
355 | |
356 for (axisHeight = 0; axisHeight < maximumDetectionFunction; axisHeight += stepSize){ | |
357 ofDrawBitmapString( ofToString((int)axisHeight), ofGetWidth()-50, | |
358 (int) ((TEXT_HEIGHT/2) +(screenHeight - (scale_factor*(axisHeight- minimumValue)))) ); | |
359 } | |
360 | |
361 for (axisHeight = max(0, (int)minimumDetectionFunction); axisHeight > min(0, (int)minimumDetectionFunction); axisHeight -= stepSize){ | |
362 ofDrawBitmapString( ofToString((int)axisHeight), ofGetWidth()-50, | |
363 (int) ((TEXT_HEIGHT/2) +(screenHeight - (scale_factor*(axisHeight- minimumValue)))) ); | |
364 } | |
365 | |
366 //label x axis | |
367 stepSize = 20;//need to make sure not too many of these: | |
368 | |
369 while((amplitudeNumber / stepSize) < 4) | |
370 stepSize /= 2; | |
371 | |
372 while ((amplitudeNumber / stepSize) > 8) | |
373 stepSize *= 2; | |
374 | |
375 int labelIndex = onsetIndex - (onsetIndex % stepSize); | |
376 for (int y = labelIndex; y > onsetIndex - amplitudeNumber; y -= stepSize){ | |
377 ofDrawBitmapString( ofToString((int)y), (int) (width*(amplitudeNumber - (onsetIndex - y))), | |
378 (int) ((TEXT_HEIGHT+2) + (screenHeight - (scale_factor*(0 - minimumValue)))) ); | |
379 } | |
380 | |
381 }//end label | |
382 //-------------------------------------------------------------- | |
383 void testApp::mouseMoved(int x, int y ){ | |
384 | |
385 | |
386 | |
387 } | |
388 | |
389 //-------------------------------------------------------------- | |
390 void testApp::mouseDragged(int x, int y, int button){ | |
391 if ((x - mouseDownX) > 50 ){ | |
392 mouseDownX = x; | |
393 } | |
394 | |
395 if ((x - mouseDownX) < -50){ | |
396 | |
397 mouseDownX = x; | |
398 } | |
399 | |
400 | |
401 } | |
402 | |
403 //-------------------------------------------------------------- | |
404 void testApp::mousePressed(int x, int y, int button){ | |
405 | |
406 mouseDownX = x; | |
407 mouseDownY = y; | |
408 | |
409 } | |
410 | |
411 //-------------------------------------------------------------- | |
412 void testApp::mouseReleased(int x, int y, int button){ | |
413 | |
414 } | |
415 | |
416 //-------------------------------------------------------------- | |
417 void testApp::windowResized(int w, int h){ | |
418 | |
419 screenWidth = (float) ofGetWidth(); | |
420 screenHeight = (float) ofGetHeight(); | |
421 | |
422 } | |
423 |