1 import javax.sound.midi.*;
4 * Functional representation of a MIDI note, which adds functionality to the existent MidiEvent class.
5 * Also provides a reference to the corresponding NoteOff event.
7 * @author Einar Pehrson
10 public class MooNote extends MidiEvent {
12 protected MidiEvent noteOffEvent;
13 protected ShortMessage noteOnMsg, noteOffMsg;
16 * Creates a MooNote from the given NoteOn event in the current track.
17 * @param noteOnEvent the NoteOn event of the note
19 public MooNote (MidiEvent noteOnEvent) {
20 super(noteOnEvent.getMessage(), noteOnEvent.getTick());
21 noteOnMsg = (ShortMessage)getMessage();
25 * Creates a MooNote from the given NoteOn event in the current track and creates a reference to
26 * the corresponding NoteOff event.
27 * @param noteOnEvent the NoteOn event of the note
28 * @param noteOffEvent the NoteOff event of the note
30 public MooNote (MidiEvent noteOnEvent, MidiEvent noteOffEvent) {
31 super(noteOnEvent.getMessage(), noteOnEvent.getTick());
32 this.noteOffEvent = noteOffEvent;
33 noteOnMsg = (ShortMessage)getMessage();
34 noteOffMsg = (ShortMessage)noteOffEvent.getMessage();
38 * Creates a MooNote of the given pitch, velocity and duration in the current track.
39 * @param track the track to which the MooNote was added
40 * @param channel the channel of the note (1-16)
41 * @param pitch the pitch of the note (0-127)
42 * @param velocity the velocity of the note (0-127)
43 * @param timestamp the timestamp of the note in ticks (96 per beat)
44 * @param duration the duration of the note in ticks (96 per beat)
46 public MooNote (int track, int channel, int pitch, int velocity, long timestamp, int duration) {
47 super(new ShortMessage(), timestamp);
48 noteOffEvent = new MidiEvent(new ShortMessage(), timestamp + duration);
49 noteOnMsg = (ShortMessage)getMessage();
50 noteOffMsg = (ShortMessage)noteOffEvent.getMessage();
52 noteOnMsg.setMessage(ShortMessage.NOTE_ON, channel, pitch, velocity);
53 noteOffMsg.setMessage(ShortMessage.NOTE_OFF, channel, pitch, 0);
54 } catch (InvalidMidiDataException e) {}
58 * Sets the channel of the current note.
59 * @param channel the channel of the note (1-16)
61 public void setChannel(int channel) {
63 noteOnMsg.setMessage(noteOnMsg.getCommand(), (byte)channel, noteOnMsg.getData1(), noteOnMsg.getData2());
64 noteOffMsg.setMessage(noteOffMsg.getCommand(), (byte)channel, noteOffMsg.getData1(), noteOffMsg.getData2());
65 } catch (Exception e) {}
66 //} catch (InvalidMidiDataException e) {}
70 * Sets the pitch of the current note.
71 * @param pitch the pitch of the note (0-127)
73 public void setPitch(int pitch) {
75 noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), (byte)pitch, noteOnMsg.getData2());
76 noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), (byte)pitch, noteOffMsg.getData2());
77 } catch (Exception e) {}
78 //} catch (InvalidMidiDataException e) {}
82 * Sets the velocity of the current note.
83 * @param vel the velocity of the note (0-127)
85 public void setVelocity(int vel) {
87 noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), noteOnMsg.getData1(), (byte)vel);
88 noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), noteOffMsg.getData1(), noteOffMsg.getData2());
89 } catch (Exception e) {}
90 //} catch (InvalidMidiDataException e) {}
94 * Sets the duration of the current note (or rather moves the note off event).
95 * @param n the duration of the note in ticks (96 per beat)
97 public void setDuration(int ticks) {
98 if (hasNoteOffEvent()) noteOffEvent.setTick(getTick() + ticks);
102 * Sets the timestamp of the current note.
103 * @param tick the timestamp of the note in ticks (96 per beat)
105 public void setTick(long tick) {
106 if (hasNoteOffEvent()) noteOffEvent.setTick(tick + getDuration());
111 * Returns the channel of the current note.
112 * @return the channel of the note (1-16)
114 public int getChannel() {
115 return noteOnMsg.getChannel();
119 * Returns the pitch of the current note.
120 * @return the pitch of the note (0-127)
122 public int getPitch() {
123 return noteOnMsg.getData1();
127 * Returns the velocity of the current note.
128 * @return the velocity of the note (0-127)
130 public int getVelocity() {
131 return noteOnMsg.getData2();
135 * Returns the duration of the current note.
136 * @return the duration of the note (in ticks)
138 public int getDuration() {
139 if (!hasNoteOffEvent()) return 0;
140 return (int)(noteOffEvent.getTick() - getTick());
144 * Returns whether the NoteOff event was found.
145 * @return the note off MidiEvent
147 public boolean hasNoteOffEvent() {
148 return noteOffEvent != null;