class Musician { // The default Musician class plays notes using its PROGRAM & CONTROLLER. int programNumber ; // PROGRAM NUMBER is the instrument. // INSTRUMENT FROM http://midi.teragonaudio.com/tutr/gm.htm int controlEffectNumber ; // CONTROLLER for special effects. // EFFECT FROM http://midi.teragonaudio.com/tech/midispec.htm int controlEffectData2 ; // strength of effect, 0..127 int MIDIchannel = 0 ; Musician(int programNumber, int controlEffectNumber, int controlEffectData2, int MIDIchannel) { this.programNumber = programNumber ; this.controlEffectNumber = controlEffectNumber ; this.controlEffectData2 = controlEffectData2 ; this.MIDIchannel = MIDIchannel ; //if (midiDeviceIndex == 0) { try { // Since there is only 1 Musician per MIDIchannel, just set the instrument // PROGRAM for that MIDIchannel in this constructor. ShortMessage patchMessage = new ShortMessage() ; patchMessage.setMessage(ShortMessage.PROGRAM_CHANGE, MIDIchannel, programNumber, 0); receiver.send(patchMessage, -1L); // send it now } catch (InvalidMidiDataException ix) { System.err.println("InvalidMidiDataException: " + ix.getMessage()); } //} } // Play or silence the note parameter. Play when isSounding is true. // Parameter isHighlighted when true means to visually highlight the Note. // When parameter isSounding is also true, pop the graphic to 3D. // Visual display and NOTE_ON NOTE_OFF are delegated to Note.display(). // STUDENT: Extend this function to pass tonic and scaleix from the // incoming function call to function note.display() below // by adding parameters to playNote(). When you try to run you will // see errors in one or more calls to playNote() because of the added // parameters tonic and scaleix. For an incoming OSC message those // parameters must be the values arriving in the OSC message. // For mousePressed played notes in the main server draw() code, just // pass arguments of -1 for these new parameters. void playNote(Note note, boolean isSounding) { try { if (isSounding) { ShortMessage patchMessage = new ShortMessage() ; patchMessage.setMessage(ShortMessage.PROGRAM_CHANGE, MIDIchannel, programNumber, 0); receiver.send(patchMessage, -1L); // send it now ShortMessage controllerOn = new ShortMessage() ; controllerOn.setMessage(ShortMessage.CONTROL_CHANGE, MIDIchannel, controlEffectNumber, controlEffectData2); receiver.send(controllerOn, -1L); // send it now } note.display(isSounding, MIDIchannel); } catch (InvalidMidiDataException ix) { System.err.println("InvalidMidiDataException: " + ix.getMessage()); } } // Increase or decrease the CONTROL_CHANGE effect level. void setEffectLevel(int level) { this.controlEffectData2 = level ; } }