comparison hackday/testApp.cpp @ 24:5a11b19906c7

hackday code is added.
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Sat, 03 Dec 2011 17:19:43 +0000
parents
children 2a025ea7c793
comparison
equal deleted inserted replaced
23:032edf186a68 24:5a11b19906c7
1 #include "testApp.h"
2
3 //--------------------------------------------------------------
4 void testApp::setup(){
5 midiFileName = "../../../data/frerejacques.mid";
6 int retVal = cannamMainFunction();
7
8 cout << "MIDI INPUT EXAMPLE" << endl;
9 printf("midi in in in");
10 ofSetVerticalSync(true);
11 //ofBackground(255,255,255);
12
13 midiIn.listPorts();
14 midiIn.openPort(2);
15
16 transpose = 12;
17 noteInStream.transposeVal = &transpose;
18
19 noteInStream.startTime = &midiEvents.startTime;//point start time of note in stream to the same time in MIDI events
20
21 noteInStream.factor = &midiEvents.ticksFactor;
22 printf("TICKS FACTOR %f \n", midiEvents.ticksFactor);//noteInStream->factor)
23
24 // portName = "hello";//midiIn.portNames[2];
25 // printf("MIDI PORT %c\n", portName);
26 cout << "MIDI PORT " << endl;//portName << endl;
27
28
29 //midiIn.addListener(this);
30 ofAddListener(midiIn.newMessageEvent, this, &testApp::newMessage);
31
32
33
34 playing = false;
35
36
37 receiver.setup( PORT );
38
39 screenWidth = ofGetWidth();
40 screenHeight = ofGetHeight();
41 midiEvents.screenWidth = &screenWidth;
42 midiEvents.screenHeight = &screenHeight;
43 midiEvents.drawTempoMode = false;
44 ofSetFrameRate(30);
45 }
46
47 //--------------------------------------------------------------
48 void testApp::update(){
49 if (playing){
50 midiEvents.updatePlayPosition();
51 // midiEvents.bayesStruct.updateBestEstimate();
52 }
53 // drawer.tickLocation+=20;
54
55 // check for waiting messages
56 while( receiver.hasWaitingMessages() )
57 {
58 ofxOscMessage m;
59 receiver.getNextMessage( &m );
60
61 if ( m.getAddress() == "/midinoteon" )
62 {
63 int newMidiOnPitch = m.getArgAsInt32(0);
64 int velocity = m.getArgAsInt32(1);
65 double time = m.getArgAsFloat(2);
66
67 if (velocity != 0)
68 midiEvents.newNoteOnEvent(newMidiOnPitch, velocity, time);
69
70 }
71
72 if ( m.getAddress() == "/setSpeedPrior" )
73 {
74 float speedPrior = m.getArgAsFloat(0);
75 printf("speed prior set to %f\n", speedPrior);
76 midiEvents.speedPriorValue = speedPrior;
77 midiEvents.bayesStruct.speedPriorValue = speedPrior;
78 }
79
80 if ( m.getAddress() == "/startplaying" )
81 {
82 startPlaying();
83 }
84
85 if ( m.getAddress() == "/stopplaying" )
86 {
87 stopPlaying();
88 }
89
90
91 if ( m.getAddress() == "/integratedEstimate" )
92 {
93 midiEvents.bayesStruct.usingIntegratedTempoEstimate = true;
94 }
95
96 if ( m.getAddress() == "/MAPestimate" )
97 {
98 midiEvents.bayesStruct.usingIntegratedTempoEstimate = false;
99 }
100
101
102 if ( m.getAddress() == "/realtime" )
103 {
104 midiEvents.runningInRealTime = true;
105 }
106
107
108 if ( m.getAddress() == "/offline" )
109 {
110 midiEvents.runningInRealTime = false;
111 }
112
113 if ( m.getAddress() == "/minimumSpeedRatio" )
114 {
115
116 float minSpeed = m.getArgAsFloat(0);
117 //printf("minimum speed received is %f and max is %f\n", minSpeed, midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1));
118 if (minSpeed > 0 && minSpeed < midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1)){
119 printf("minimum speed accepted is %f\n", minSpeed);
120 midiEvents.minimumMatchSpeed = minSpeed;
121 }
122 }
123
124 }//end while osc
125
126 }
127
128 void testApp::newMessage(ofxMidiEventArgs &args){
129
130 int pitch;
131 if (noteInStream.noteInReceived(args)){
132 double timeNow = ofGetElapsedTimeMillis();
133
134 if (!liveInputPlaying){
135 firstNoteTime = timeNow;
136 liveInputPlaying = true;
137 startPlaying();
138 printf("FIRST LIVE NOTE IS NOW AT TIME %f\n", timeNow);
139 }
140
141 pitch = args.byteOne + transpose;
142
143 midiEvents.newNoteOnEvent(pitch, args.byteTwo, timeNow - firstNoteTime);
144
145
146 int tickTime = midiEvents.getEventTimeTicks(timeNow-firstNoteTime);
147 IntVector v;
148 v.push_back(tickTime);
149 v.push_back(pitch);
150 v.push_back(args.byteTwo);
151 noteInStream.midiInputEvents.push_back(v);
152 noteInStream.midiInputTimes.push_back(timeNow - firstNoteTime);
153 printf("NOTE %i at time %f at tick time %i\n", pitch, (timeNow - firstNoteTime), tickTime);
154 }
155
156 // cout << "MIDI message [port: " << args.port << ", channel: " << args.channel << ", status: " << args.status << ", byteOne: " << pitch << ", byteTwo: " << args.byteTwo << ", timestamp: " << args.timestamp << "]" << endl;
157 }
158
159 //--------------------------------------------------------------
160 void testApp::draw(){
161
162 midiEvents.drawFile();
163
164 midiEvents.drawMidiFile(noteInStream.midiInputEvents);
165
166 }
167
168 //--------------------------------------------------------------
169 void testApp::keyPressed(int key){
170
171
172 // if (key == ' '){
173 // startPlaying();
174 // }
175 if (key == '-')
176 transpose -= 12;
177
178 if (key == '=')
179 transpose += 12;
180
181 if (key == 'c'){
182 double timenow = ofGetElapsedTimeMillis();
183 midiEvents.exampleCrossUpdate();
184 timenow *= -1;
185 timenow += ofGetElapsedTimeMillis();
186 printf("CROSS UPDATE TOOK %f", timenow);
187 }
188
189 if (key == OF_KEY_RETURN)
190 stopPlaying();
191
192 if (key == OF_KEY_UP){
193 if (midiEvents.ticksPerScreen >= 4000)
194 midiEvents.ticksPerScreen += 2000;
195 else
196 midiEvents.ticksPerScreen += 500;
197 }
198
199 if (key == 'm'){
200 // midiEvents.findMatch(84, 0, 10000);
201 }
202
203 if (key == OF_KEY_DOWN){
204 if (midiEvents.ticksPerScreen >= 4000)
205 midiEvents.ticksPerScreen -= 2000;
206 else if (midiEvents.ticksPerScreen > 500)
207 midiEvents.ticksPerScreen -= 500;
208 }
209
210 if (key == 'w')
211 midiEvents.printMatchMatrix();
212
213 if (key == 'k'){
214 noteInStream.printNotes();
215 }
216
217 if (key == 'p'){
218 midiEvents.printNotes();
219 }
220
221 if (key == 'l')
222 midiEvents.bayesStruct.decaySpeedDistribution(100);
223
224 if (key == 't')
225 midiEvents.drawTempoMode = !midiEvents.drawTempoMode;
226
227 if (key == 'y')
228 midiEvents.drawPhaseMode = !midiEvents.drawPhaseMode;
229
230 if (key == 'r'){
231 noteInStream.reset();
232 liveInputPlaying = false;
233 stopPlaying();
234 }
235
236 if (key == 'o'){
237 //open audio file
238 string *filePtr;
239 filePtr = &midiFileName;
240
241 if (getFilenameFromDialogBox(filePtr)){
242 printf("Midifile: Loaded name okay :\n'%s' \n", midiFileName.c_str());
243 cannamMainFunction();
244 }
245 }
246
247
248
249 }
250
251 //--------------------------------------------------------------
252 void testApp::keyReleased(int key){
253
254 }
255
256 //--------------------------------------------------------------
257 void testApp::mouseMoved(int x, int y ){
258 midiEvents.mouseX = midiEvents.getEventTimeMillis((x * midiEvents.ticksPerScreen)/ screenWidth);
259 }
260
261 //--------------------------------------------------------------
262 void testApp::mouseDragged(int x, int y, int button){
263
264 }
265
266 //--------------------------------------------------------------
267 void testApp::mousePressed(int x, int y, int button){
268
269 }
270
271 //--------------------------------------------------------------
272 void testApp::mouseReleased(int x, int y, int button){
273
274 }
275
276 //--------------------------------------------------------------
277 void testApp::windowResized(int w, int h){
278 screenWidth = w;
279 screenHeight = h;
280 midiEvents.noteHeight = screenHeight / (float)(midiEvents.noteMaximum - midiEvents.noteMinimum);
281
282 }
283
284
285
286 void testApp::startPlaying(){
287 playing = !playing;
288 midiEvents.reset();
289 midiEvents.setStartPlayingTimes();
290
291 //this is where we stop and start playing
292 }
293
294 void testApp::stopPlaying(){
295 playing = false;
296 liveInputPlaying = false;
297 }
298
299 bool testApp::getFilenameFromDialogBox(string* fileNameToSave){
300 //this uses a pointer structure within the loader and returns true if the dialogue box was used successfully
301 // first, create a string that will hold the URL
302 string URL;
303
304 // openFile(string& URL) returns 1 if a file was picked
305 // returns 0 when something went wrong or the user pressed 'cancel'
306 int response = ofxFileDialogOSX::openFile(URL);
307 if(response){
308 // now you can use the URL
309 *fileNameToSave = URL;
310 //printf("\n filename is %s \n", soundFileName.c_str());
311 return true;
312 }
313 else {
314 // soundFileName = "OPEN canceled. ";
315 printf("\n open file cancelled \n");
316 return false;
317 }
318
319
320
321 }
322
323
324
325
326 int testApp::cannamMainFunction(){
327
328
329 midiEvents.clearAllEvents();
330
331 //int main(int argc, char **argv)
332 //{
333 // if (argc != 2) {
334 // cerr << "Usage: midifile <file.mid>" << endl;
335 // return 1;
336 // }
337
338 std::string filename = midiFileName;//argv[1];
339
340 // fileLoader.chopBeginning = true;
341 fileLoader.loadFile(filename, midiEvents);
342
343 }//new end of load function
344
345
346
347
348 //trying to port to new class
349 /*
350 MIDIFileReader fr(filename);
351
352 if (!fr.isOK()) {
353 std::cerr << "Error: " << fr.getError().c_str() << std::endl;
354 return 1;
355 }
356
357 MIDIComposition c = fr.load();
358
359 switch (fr.getFormat()) {
360 case MIDI_SINGLE_TRACK_FILE: cout << "Format: MIDI Single Track File" << endl; break;
361 case MIDI_SIMULTANEOUS_TRACK_FILE: cout << "Format: MIDI Simultaneous Track File" << endl; break;
362 case MIDI_SEQUENTIAL_TRACK_FILE: cout << "Format: MIDI Sequential Track File" << endl; break;
363 default: cout << "Format: Unknown MIDI file format?" << endl; break;
364 }
365
366 cout << "Tracks: " << c.size() << endl;
367
368 int td = fr.getTimingDivision();
369 if (td < 32768) {
370 cout << "Timing division: " << fr.getTimingDivision() << " ppq" << endl;
371
372 midiEvents.pulsesPerQuarternote = fr.getTimingDivision();
373 } else {
374 int frames = 256 - (td >> 8);
375 int subframes = td & 0xff;
376 cout << "SMPTE timing: " << frames << " fps, " << subframes << " subframes" << endl;
377 }
378
379 for (MIDIComposition::const_iterator i = c.begin(); i != c.end(); ++i) {
380
381 cout << "Start of track: " << i->first+1 << endl;
382
383 for (MIDITrack::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
384
385 unsigned int t = j->getTime();
386 int ch = j->getChannelNumber();
387
388 if (j->isMeta()) {
389 int code = j->getMetaEventCode();
390 string name;
391 bool printable = true;
392 switch (code) {
393
394 case MIDI_END_OF_TRACK:
395 cout << t << ": End of track" << endl;
396 break;
397
398 case MIDI_TEXT_EVENT: name = "Text"; break;
399 case MIDI_COPYRIGHT_NOTICE: name = "Copyright"; break;
400 case MIDI_TRACK_NAME: name = "Track name"; break;
401 case MIDI_INSTRUMENT_NAME: name = "Instrument name"; break;
402 case MIDI_LYRIC: name = "Lyric"; break;
403 case MIDI_TEXT_MARKER: name = "Text marker"; break;
404 case MIDI_SEQUENCE_NUMBER: name = "Sequence number"; printable = false; break;
405 case MIDI_CHANNEL_PREFIX_OR_PORT: name = "Channel prefix or port"; printable = false; break;
406 case MIDI_CUE_POINT: name = "Cue point"; break;
407 case MIDI_CHANNEL_PREFIX: name = "Channel prefix"; printable = false; break;
408 case MIDI_SEQUENCER_SPECIFIC: name = "Sequencer specific"; printable = false; break;
409 case MIDI_SMPTE_OFFSET: name = "SMPTE offset"; printable = false; break;
410
411 case MIDI_SET_TEMPO:
412 {
413 int m0 = j->getMetaMessage()[0];
414 int m1 = j->getMetaMessage()[1];
415 int m2 = j->getMetaMessage()[2];
416 long tempo = (((m0 << 8) + m1) << 8) + m2;
417
418 cout << t << ": Tempo: " << 60000000.0 / double(tempo) << endl;
419 midiEvents.tempo = 60000000.0 / double(tempo);
420 midiEvents.period = double(tempo)/1000.0;
421
422 printf("period double is %f\n", midiEvents.period);
423 }
424 break;
425
426 case MIDI_TIME_SIGNATURE:
427 {
428 int numerator = j->getMetaMessage()[0];
429 int denominator = 1 << (int)j->getMetaMessage()[1];
430
431 cout << t << ": Time signature: " << numerator << "/" << denominator << endl;
432 }
433
434 case MIDI_KEY_SIGNATURE:
435 {
436 int accidentals = j->getMetaMessage()[0];
437 int isMinor = j->getMetaMessage()[1];
438 bool isSharp = accidentals < 0 ? false : true;
439 accidentals = accidentals < 0 ? -accidentals : accidentals;
440 cout << t << ": Key signature: " << accidentals << " "
441 << (isSharp ?
442 (accidentals > 1 ? "sharps" : "sharp") :
443 (accidentals > 1 ? "flats" : "flat"))
444 << (isMinor ? ", minor" : ", major") << endl;
445 }
446
447 }
448
449
450 if (name != "") {
451 if (printable) {
452 cout << t << ": File meta event: code " << code
453 << ": " << name << ": \"" << j->getMetaMessage()
454 << "\"" << endl;
455 } else {
456 cout << t << ": File meta event: code " << code
457 << ": " << name << ": ";
458 for (int k = 0; k < j->getMetaMessage().length(); ++k) {
459 cout << (int)j->getMetaMessage()[k] << " ";
460 }
461 }
462 }
463 continue;
464 }
465
466 switch (j->getMessageType()) {
467
468 case MIDI_NOTE_ON:
469 cout << t << ": Note: channel " << ch
470 << " duration " << j->getDuration()
471 << " pitch " << j->getPitch()
472 << " velocity " << j->getVelocity()
473 << "event time " << midiEvents.getEventTimeMillis(t) << endl;
474 v.clear();
475 v.push_back(t);
476 v.push_back(j->getPitch());
477 v.push_back(j->getVelocity());
478 v.push_back(j->getDuration());
479 midiEvents.recordedNoteOnMatrix.push_back(v);
480 midiEvents.recordedEventTimes.push_back(midiEvents.getEventTimeMillis(t));
481 break;
482
483 case MIDI_POLY_AFTERTOUCH:
484 cout << t << ": Polyphonic aftertouch: channel " << ch
485 << " pitch " << j->getPitch()
486 << " pressure " << j->getData2() << endl;
487 break;
488
489 case MIDI_CTRL_CHANGE:
490 {
491 int controller = j->getData1();
492 string name;
493 switch (controller) {
494 case MIDI_CONTROLLER_BANK_MSB: name = "Bank select MSB"; break;
495 case MIDI_CONTROLLER_VOLUME: name = "Volume"; break;
496 case MIDI_CONTROLLER_BANK_LSB: name = "Bank select LSB"; break;
497 case MIDI_CONTROLLER_MODULATION: name = "Modulation wheel"; break;
498 case MIDI_CONTROLLER_PAN: name = "Pan"; break;
499 case MIDI_CONTROLLER_SUSTAIN: name = "Sustain"; break;
500 case MIDI_CONTROLLER_RESONANCE: name = "Resonance"; break;
501 case MIDI_CONTROLLER_RELEASE: name = "Release"; break;
502 case MIDI_CONTROLLER_ATTACK: name = "Attack"; break;
503 case MIDI_CONTROLLER_FILTER: name = "Filter"; break;
504 case MIDI_CONTROLLER_REVERB: name = "Reverb"; break;
505 case MIDI_CONTROLLER_CHORUS: name = "Chorus"; break;
506 case MIDI_CONTROLLER_NRPN_1: name = "NRPN 1"; break;
507 case MIDI_CONTROLLER_NRPN_2: name = "NRPN 2"; break;
508 case MIDI_CONTROLLER_RPN_1: name = "RPN 1"; break;
509 case MIDI_CONTROLLER_RPN_2: name = "RPN 2"; break;
510 case MIDI_CONTROLLER_SOUNDS_OFF: name = "All sounds off"; break;
511 case MIDI_CONTROLLER_RESET: name = "Reset"; break;
512 case MIDI_CONTROLLER_LOCAL: name = "Local"; break;
513 case MIDI_CONTROLLER_ALL_NOTES_OFF: name = "All notes off"; break;
514 }
515 cout << t << ": Controller change: channel " << ch
516 << " controller " << j->getData1();
517 if (name != "") cout << " (" << name << ")";
518 cout << " value " << j->getData2() << endl;
519 }
520 break;
521
522 case MIDI_PROG_CHANGE:
523 cout << t << ": Program change: channel " << ch
524 << " program " << j->getData1() << endl;
525 break;
526
527 case MIDI_CHNL_AFTERTOUCH:
528 cout << t << ": Channel aftertouch: channel " << ch
529 << " pressure " << j->getData1() << endl;
530 break;
531
532 case MIDI_PITCH_BEND:
533 cout << t << ": Pitch bend: channel " << ch
534 << " value " << (int)j->getData2() * 128 + (int)j->getData1() << endl;
535 break;
536
537 case MIDI_SYSTEM_EXCLUSIVE:
538 cout << t << ": System exclusive: code "
539 << (int)j->getMessageType() << " message length " <<
540 j->getMetaMessage().length() << endl;
541 break;
542
543
544 }
545
546
547 }
548
549
550 }
551
552 }//end cannam midi main
553
554 */
555
556