]> ruin.nu Git - moosique.git/blob - MooNote.java
no message
[moosique.git] / MooNote.java
1 import javax.sound.midi.*;
2
3 /**
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.
6  * 
7  * @author  Einar Pehrson
8  */
9  
10 public class MooNote extends MidiEvent {
11
12         protected MidiEvent noteOffEvent;
13         protected ShortMessage noteOnMsg, noteOffMsg;
14
15         /** 
16          * Creates a MooNote from the given NoteOn event in the current track.
17          * @param noteOnEvent   the NoteOn event of the note
18          */
19         public MooNote (MidiEvent noteOnEvent) {
20                 super(noteOnEvent.getMessage(), noteOnEvent.getTick());
21                 noteOnMsg = (ShortMessage)getMessage();
22         }
23
24         /** 
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
29          */
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();
35         }
36
37         /** 
38          * Creates a MooNote of the given pitch, velocity and duration in the current track.
39          * @param channel       the channel of the note (1-16)
40          * @param pitch         the pitch of the note (0-127)
41          * @param velocity      the velocity of the note (0-127)
42          * @param timestamp     the timestamp of the note in ticks (96 per beat)
43          * @param duration      the duration of the note in ticks (96 per beat)
44          */
45         public MooNote (int channel, int pitch, int velocity, long timestamp, int duration) {
46                 super(new ShortMessage(), timestamp);
47                 noteOffEvent = new MidiEvent(new ShortMessage(), timestamp + duration);
48                 noteOnMsg = (ShortMessage)getMessage();
49                 noteOffMsg = (ShortMessage)noteOffEvent.getMessage();
50                 try {
51                         noteOnMsg.setMessage(ShortMessage.NOTE_ON, channel, pitch, velocity);
52                         noteOffMsg.setMessage(ShortMessage.NOTE_OFF, channel, pitch, 0);
53                 } catch (InvalidMidiDataException e) {System.out.println("Invalid data!");}
54         }
55
56         /** 
57          * Sets the channel of the current note.
58          * @param channel       the channel of the note (1-16)
59          */
60         public void setChannel(int channel) {
61                 try {
62                         noteOnMsg.setMessage(noteOnMsg.getCommand(), (byte)channel, noteOnMsg.getData1(), noteOnMsg.getData2());
63                         if(hasNoteOffEvent()) noteOffMsg.setMessage(noteOffMsg.getCommand(), (byte)channel, noteOffMsg.getData1(), noteOffMsg.getData2());
64                 } catch (InvalidMidiDataException e) {}
65         }
66
67         /** 
68          * Sets the pitch of the current note.
69          * @param pitch         the pitch of the note (0-127)
70          */
71         public void setPitch(int pitch) {
72                 try {
73                         noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), (byte)pitch, noteOnMsg.getData2());
74                         if(hasNoteOffEvent()) noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), (byte)pitch, noteOffMsg.getData2());
75                 } catch (InvalidMidiDataException e) {}
76         }
77
78         /** 
79          * Transposes the current note the given number of halftones.
80          * @param halftones             the number of halftones to transpose - positive for up, negative for down
81          */
82         public void transpose(int halftones) {
83                 setPitch(getPitch() + halftones);
84         }
85
86         /** 
87          * Sets the velocity of the current note.
88          * @param vel   the velocity of the note (0-127)
89          */
90         public void setVelocity(int vel) {
91                 try {
92                         noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), noteOnMsg.getData1(), (byte)vel);
93                         if(hasNoteOffEvent()) noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), noteOffMsg.getData1(), noteOffMsg.getData2());
94                 } catch (InvalidMidiDataException e) {}
95         }
96
97         /** 
98          * Sets the duration of the current note (or rather moves the note off event).
99          * @param n     the duration of the note in ticks (96 per beat)
100          */
101         public void setDuration(int ticks) {
102                 if (hasNoteOffEvent()) noteOffEvent.setTick(getTick() + ticks);
103         }
104
105         /** 
106          * Sets the timestamp of the current note.
107          * @param tick  the timestamp of the note in ticks (96 per beat)
108          */
109         public void setTick(long tick) {
110                 if (hasNoteOffEvent()) noteOffEvent.setTick(tick + getDuration());
111                 super.setTick(tick);
112         }
113
114         /** 
115          * Returns the channel of the current note.
116          * @return the channel of the note (1-16)
117          */
118         public int getChannel() {
119                 return noteOnMsg.getChannel();
120         }
121
122         /** 
123          * Returns the pitch of the current note.
124          * @return the pitch of the note (0-127)
125          */
126         public int getPitch() {
127                 return noteOnMsg.getData1();
128         }
129
130         /** 
131          * Returns the velocity of the current note.
132          * @return the velocity of the note (0-127)
133          */
134         public int getVelocity() {
135                 return noteOnMsg.getData2();
136         }
137
138         /** 
139          * Returns the duration of the current note.
140          * @return the duration of the note (in ticks)
141          */
142         public int getDuration() {
143                 if (!hasNoteOffEvent()) return 0;
144                 return (int)(noteOffEvent.getTick() - getTick());
145         }
146
147         /** 
148          * Returns whether the NoteOff event was found.
149          * @return      the note off MidiEvent
150          */
151         public boolean hasNoteOffEvent() {
152                 return noteOffEvent != null;
153         }
154
155         /**
156          * Adds this note (both noteOn and noteOffEvents) to a track.
157          * @param track the track it'll be added to.
158          */
159         public void addTo(Track track){
160                 track.add(this);
161                 if (hasNoteOffEvent()) track.add(noteOffEvent);
162         }
163         
164         /**
165          * Removes this note (both noteOn and noteOffEvents) from a track.
166          * @param track the track it'll be removed from.
167          */
168         public void removeFrom(Track track){
169                 track.remove(this);
170                 if (hasNoteOffEvent()) track.remove(noteOffEvent);
171         }
172 }