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 // Updated 1/5/2020 to pass the MIDIchannel from draw() logic, since // the client uses only 1 channel at a time, which can change, // stored in global variable oscClientMidiChan, and passed here // via MIDIchannel parameter in playNote. Musician(int programNumber, int controlEffectNumber, int controlEffectData2) { this.programNumber = programNumber ; this.controlEffectNumber = controlEffectNumber ; this.controlEffectData2 = controlEffectData2 ; //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(). // MIDIchannel added 1/5/2019, see comments above. void playNote(Note note, boolean isHighlighted, boolean isSounding, int MIDIchannel) { //try { //if (isSounding) { //ShortMessage controllerOn = new ShortMessage() ; //controllerOn.setMessage(ShortMessage.CONTROL_CHANGE, MIDIchannel, //controlEffectNumber, controlEffectData2); //receiver.send(controllerOn, -1L); // send it now //} if (MIDIchannel >= 0 && MIDIchannel < 16) { note.display(isHighlighted, 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 ; } }