X-Git-Url: https://ruin.nu/git/?p=moosique.git;a=blobdiff_plain;f=MooNote.java;h=2a82b6d21b5ac48489aa1a5548f49f96152bb21e;hp=fcf32e047c8af6d1819937c914cd57a7bd82f498;hb=HEAD;hpb=ade446bcfe30be5e4a058926387763f72fc3d4a7 diff --git a/MooNote.java b/MooNote.java index fcf32e0..2a82b6d 100644 --- a/MooNote.java +++ b/MooNote.java @@ -1,96 +1,182 @@ 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 existing 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 implements Cloneable, Comparable { - private MidiEvent noteOnEvent, noteOffEvent; + private MidiEvent noteOffEvent; private ShortMessage noteOnMsg, noteOffMsg; - private long noteOnTime, noteOffTime; - /* - * 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 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 (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, MidiEvent noteOffEvent) { + super(noteOnEvent.getMessage(), noteOnEvent.getTick()); + this.noteOffEvent = noteOffEvent; + noteOnMsg = (ShortMessage)getMessage(); + noteOffMsg = (ShortMessage)noteOffEvent.getMessage(); } - /* + /** + * Creates a MooNote of the given pitch, velocity and duration in the current track. + * @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 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, 64); + } catch (InvalidMidiDataException e) {System.out.println("Invalid data!");} + } + + /** + * Returns the note off event of this note. + * @return the note off event + */ + public MidiEvent getNoteOffEvent() { + return noteOffEvent; + } + + /** + * Returns the channel of the current note. + * @return the channel of the note (1-16) + */ + public int getChannel() { + return noteOnMsg.getChannel(); + } + + /** + * Returns the pitch of the current 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 (0-127) + */ + public int getVelocity() { + return noteOnMsg.getData2(); + } + + /** + * Returns the duration of the current note. + * @return the duration of the note (in ticks) + */ + public int getDuration() { + return (int)(noteOffEvent.getTick() - getTick()); + } + + /** + * 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) { + 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) { + noteOffEvent.setTick(tick + getDuration()); + super.setTick(tick); } - /* - * Returns the note off event of the current note. - * @return the note off MidiEvent + /** + * Transposes the current note the given number of halftones. + * @param halftones the number of halftones to transpose - positive for up, negative for down */ - public MidiEvent getNoteOffEvent() { - return noteOffEvent; + public void transpose(int halftones) { + setPitch(getPitch() + halftones); } - /* - * Returns the pitch of the current note. - * @return the pitch of the note + /** + * Adds this note (both noteOn and noteOffEvents) to a track. + * @param track the track it'll be added to. */ - public int getPitch() { - return noteOnMsg.getData1(); + public void addTo(Track track) { + track.add(this); + track.add(noteOffEvent); + } + + /** + * Removes this note (both noteOn and noteOffEvents) from a track. + * @param track the track it'll be removed from. + */ + public void removeFrom(Track track) { + track.remove(this); + track.remove(noteOffEvent); } - /* - * Returns the velocity of the current note. - * @return the velocity of the note + /** + * Returns a clone of this note. */ - public int getVelocity() { - return noteOnMsg.getData2(); + public Object clone() { + return new MooNote( + new MidiEvent((ShortMessage)getMessage().clone(), getTick()), + new MidiEvent((ShortMessage)noteOffEvent.getMessage().clone(), noteOffEvent.getTick()) + ); } - /* - * Returns the length of the current note. - * @return the length of the note + /** + * Compares this note to another note. + * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object */ - public int getLength() { - + public int compareTo(Object o) { + int diff = (int)(getTick() - ((MidiEvent)o).getTick()); + if (diff != 0) return diff; + return (noteOnMsg.getData1() - ((ShortMessage)((MidiEvent)o).getMessage()).getData1()); } -} \ No newline at end of file +}