import javax.sound.midi.*;
-/*
- * Functional representation of a MIDI note, which contains two MIDI events, note on and note off.
+/**
+ * Functional representation of a MIDI note, which adds functionality to the existent MidiEvent class.
+ * Also provides a reference to the corresponding NoteOff event.
*
- * @author Andersson, Andreen, Lanneskog, Pehrson
- * @version 1
+ * @author Einar Pehrson
*/
-public class MooNote {
+public class MooNote extends MidiEvent {
- private MidiEvent noteOnEvent, noteOffEvent;
- private ShortMessage noteOnMsg, noteOffMsg;
- private long noteOnTime, noteOffTime;
+ protected MidiEvent noteOffEvent;
+ protected ShortMessage noteOnMsg, noteOffMsg;
- /*
- * Creates a MooNote of the given pitch, velocity and length in the current track.
+ /**
+ * Creates a MooNote from the given NoteOn event in the current track.
+ * @param noteOnEvent the NoteOn event of the note
*/
- public MooNote (int pitch, int velocity, int length) {
- // MidiEvent(MidiMessage message, long tick)
- noteOnMsg = new ShortMessage();
- noteOffMsg = new ShortMessage();
- noteOnMsg.setMessage(ShortMessage.NOTE_ON, pitch, velocity);
- noteOffMsg.setMessage(ShortMessage.NOTE_OFF, pitch, velocity);
-// noteOnTime = ???;
- noteOffTime = noteOnTime + length;
- noteOnEvent = new MidiEvent(noteOnMsg, noteOnTime)
- noteOffEvent = new MidiEvent(noteOffMsg, noteOffTime)
+ public MooNote (MidiEvent noteOnEvent) {
+ super(noteOnEvent.getMessage(), noteOnEvent.getTick());
+ noteOnMsg = (ShortMessage)getMessage();
}
- /*
+ /**
+ * Creates a MooNote from the given NoteOn event in the current track and creates a reference to
+ * the corresponding NoteOff event.
+ * @param noteOnEvent the NoteOn event of the note
+ * @param noteOffEvent the NoteOff event of the note
+ */
+ public MooNote (MidiEvent noteOnEvent, MidiEvent noteOffEvent) {
+ super(noteOnEvent.getMessage(), noteOnEvent.getTick());
+ noteOffEvent = new MidiEvent(noteOffEvent.getMessage(), noteOffEvent.getTick());
+ noteOnMsg = (ShortMessage)getMessage();
+ noteOffMsg = (ShortMessage)noteOffEvent.getMessage();
+ }
+
+ /**
+ * Creates a MooNote of the given pitch, velocity and duration in the current track.
+ * @param track the track to which the MooNote was added
+ * @param channel the channel of the note (1-16)
+ * @param pitch the pitch of the note (0-127)
+ * @param velocity the velocity of the note (0-127)
+ * @param timestamp the timestamp of the note in ticks (96 per beat)
+ * @param duration the duration of the note in ticks (96 per beat)
+ */
+ public MooNote (int track, int channel, int pitch, int velocity, long timestamp, int duration) {
+ super(new ShortMessage(), timestamp);
+ noteOffEvent = new MidiEvent(new ShortMessage(), timestamp + duration);
+ noteOnMsg = (ShortMessage)getMessage();
+ noteOffMsg = (ShortMessage)noteOffEvent.getMessage();
+ try {
+ noteOnMsg.setMessage(ShortMessage.NOTE_ON, channel, pitch, velocity);
+ noteOffMsg.setMessage(ShortMessage.NOTE_OFF, channel, pitch, 0);
+ } catch (InvalidMidiDataException e) {}
+ }
+
+ /**
+ * Sets the channel of the current note.
+ * @param channel the channel of the note (1-16)
+ */
+ public void setChannel(int channel) {
+ try {
+ noteOnMsg.setMessage(noteOnMsg.getCommand(), (byte)channel, noteOnMsg.getData1(), noteOnMsg.getData2());
+ noteOffMsg.setMessage(noteOffMsg.getCommand(), (byte)channel, noteOffMsg.getData1(), noteOffMsg.getData2());
+ } catch (InvalidMidiDataException e) {}
+ }
+
+ /**
* Sets the pitch of the current note.
- + @param pitch the pitch of the note (0-127)
+ * @param pitch the pitch of the note (0-127)
*/
public void setPitch(int pitch) {
- noteOnMsg.setMessage(ShortMessage.NOTE_ON, pitch, noteOnMsg.getData2());
- noteOffMsg.setMessage(ShortMessage.NOTE_OFF, pitch, noteOffMsg.getData2());
+ try {
+ noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), (byte)pitch, noteOnMsg.getData2());
+ noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), (byte)pitch, noteOffMsg.getData2());
+ } catch (InvalidMidiDataException e) {}
}
- /*
+ /**
* Sets the velocity of the current note.
- + @param vel the velocity of the note (0-127)
+ * @param vel the velocity of the note (0-127)
*/
public void setVelocity(int vel) {
- noteOnMsg.setMessage(ShortMessage.NOTE_ON, noteOnMsg.getData1(), vel);
- noteOffMsg.setMessage(ShortMessage.NOTE_OFF, noteOffMsg.getData1(), vel);
+ try {
+ noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), noteOnMsg.getData1(), (byte)vel);
+ noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), noteOffMsg.getData1(), noteOffMsg.getData2());
+ } catch (InvalidMidiDataException e) {}
}
- /*
- * Sets the length of the current note (or rather moves the note off event).
- + @param n the length of the note in ticks (100 per beat)
+ /**
+ * Sets the duration of the current note (or rather moves the note off event).
+ * @param n the duration of the note in ticks (96 per beat)
*/
- public void setLength(int ticks) {
-
+ public void setDuration(int ticks) {
+ if (hasNoteOffEvent()) noteOffEvent.setTick(getTick() + ticks);
}
- /*
- * Returns the note on event of the current note.
- * @return the note on MidiEvent
+ /**
+ * Sets the timestamp of the current note.
+ * @param tick the timestamp of the note in ticks (96 per beat)
*/
- public MidiEvent getNoteOnEvent() {
- return noteOnEvent;
+ public void setTick(long tick) {
+ if (hasNoteOffEvent()) noteOffEvent.setTick(tick + getDuration());
+ super.setTick(tick);
}
- /*
- * Returns the note off event of the current note.
- * @return the note off MidiEvent
+ /**
+ * Returns the channel of the current note.
+ * @return the channel of the note (1-16)
*/
- public MidiEvent getNoteOffEvent() {
- return noteOffEvent;
+ public int getChannel() {
+ return noteOnMsg.getChannel();
}
- /*
+ /**
* Returns the pitch of the current note.
- * @return the pitch of the note
+ * @return the pitch of the note (0-127)
*/
public int getPitch() {
return noteOnMsg.getData1();
}
- /*
+ /**
* Returns the velocity of the current note.
- * @return the velocity of the note
+ * @return the velocity of the note (0-127)
*/
public int getVelocity() {
return noteOnMsg.getData2();
}
- /*
- * Returns the length of the current note.
- * @return the length of the note
+ /**
+ * Returns the duration of the current note.
+ * @return the duration of the note (in ticks)
+ */
+ public int getDuration() {
+ if (!hasNoteOffEvent()) return 0;
+ return (int)(getTick() - noteOffEvent.getTick());
+ }
+
+ /**
+ * Returns whether the NoteOff event was found.
+ * @return the note off MidiEvent
*/
- public int getLength() {
-
+ public boolean hasNoteOffEvent() {
+ return noteOffEvent == null;
}
}
\ No newline at end of file