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