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(). void playNote(Note note, boolean isHighlighted, boolean isSounding, boolean isOSCmessage) { 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(isHighlighted, isSounding, MIDIchannel, isOSCmessage); } catch (InvalidMidiDataException ix) { System.err.println("InvalidMidiDataException: " + ix.getMessage()); } } // Increase or decrease the CONTROL_CHANGE effect level. void setEffectLevel(int level) { this.controlEffectData2 = level ; } }