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 (InvalidMidiDataException e) {}
69 * Sets the pitch of the current note.
70 * @param pitch the pitch of the note (0-127)
72 public void setPitch(int pitch) {
74 noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), (byte)pitch, noteOnMsg.getData2());
75 noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), (byte)pitch, noteOffMsg.getData2());
76 } catch (InvalidMidiDataException e) {}
80 * Sets the velocity of the current note.
81 * @param vel the velocity of the note (0-127)
83 public void setVelocity(int vel) {
85 noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), noteOnMsg.getData1(), (byte)vel);
86 noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), noteOffMsg.getData1(), noteOffMsg.getData2());
87 } catch (InvalidMidiDataException e) {}
91 * Sets the duration of the current note (or rather moves the note off event).
92 * @param n the duration of the note in ticks (96 per beat)
94 public void setDuration(int ticks) {
95 if (hasNoteOffEvent()) noteOffEvent.setTick(getTick() + ticks);
99 * Sets the timestamp of the current note.
100 * @param tick the timestamp of the note in ticks (96 per beat)
102 public void setTick(long tick) {
103 if (hasNoteOffEvent()) noteOffEvent.setTick(tick + getDuration());
108 * Returns the channel of the current note.
109 * @return the channel of the note (1-16)
111 public int getChannel() {
112 return noteOnMsg.getChannel();
116 * Returns the pitch of the current note.
117 * @return the pitch of the note (0-127)
119 public int getPitch() {
120 return noteOnMsg.getData1();
124 * Returns the velocity of the current note.
125 * @return the velocity of the note (0-127)
127 public int getVelocity() {
128 return noteOnMsg.getData2();
132 * Returns the duration of the current note.
133 * @return the duration of the note (in ticks)
135 public int getDuration() {
136 if (!hasNoteOffEvent()) return 0;
137 return (int)(getTick() - noteOffEvent.getTick());
141 * Returns whether the NoteOff event was found.
142 * @return the note off MidiEvent
144 public boolean hasNoteOffEvent() {
145 return noteOffEvent != null;