src/share/classes/javax/sound/midi/Track.java
Print this page
*** 23,67 ****
* questions.
*/
package javax.sound.midi;
- import java.util.Vector;
import java.util.ArrayList;
import java.util.HashSet;
import com.sun.media.sound.MidiUtils;
/**
! * A MIDI track is an independent stream of MIDI events (time-stamped MIDI
! * data) that can be stored along with other tracks in a standard MIDI file.
! * The MIDI specification allows only 16 channels of MIDI data, but tracks
! * are a way to get around this limitation. A MIDI file can contain any number
! * of tracks, each containing its own stream of up to 16 channels of MIDI data.
* <p>
! * A <code>Track</code> occupies a middle level in the hierarchy of data played
! * by a <code>{@link Sequencer}</code>: sequencers play sequences, which contain tracks,
! * which contain MIDI events. A sequencer may provide controls that mute
! * or solo individual tracks.
* <p>
* The timing information and resolution for a track is controlled by and stored
! * in the sequence containing the track. A given <code>Track</code>
! * is considered to belong to the particular <code>{@link Sequence}</code> that
! * maintains its timing. For this reason, a new (empty) track is created by calling the
! * <code>{@link Sequence#createTrack}</code> method, rather than by directly invoking a
! * <code>Track</code> constructor.
* <p>
! * The <code>Track</code> class provides methods to edit the track by adding
! * or removing <code>MidiEvent</code> objects from it. These operations keep
! * the event list in the correct time order. Methods are also
! * included to obtain the track's size, in terms of either the number of events
! * it contains or its duration in ticks.
! *
! * @see Sequencer#setTrackMute
! * @see Sequencer#setTrackSolo
*
* @author Kara Kytle
* @author Florian Bomers
*/
public class Track {
// TODO: use arrays for faster access
--- 23,66 ----
* questions.
*/
package javax.sound.midi;
import java.util.ArrayList;
import java.util.HashSet;
+
import com.sun.media.sound.MidiUtils;
/**
! * A MIDI track is an independent stream of MIDI events (time-stamped MIDI data)
! * that can be stored along with other tracks in a standard MIDI file. The MIDI
! * specification allows only 16 channels of MIDI data, but tracks are a way to
! * get around this limitation. A MIDI file can contain any number of tracks,
! * each containing its own stream of up to 16 channels of MIDI data.
* <p>
! * A {@code Track} occupies a middle level in the hierarchy of data played by a
! * {@link Sequencer}: sequencers play sequences, which contain tracks, which
! * contain MIDI events. A sequencer may provide controls that mute or solo
! * individual tracks.
* <p>
* The timing information and resolution for a track is controlled by and stored
! * in the sequence containing the track. A given {@code Track} is considered to
! * belong to the particular {@link Sequence} that maintains its timing. For this
! * reason, a new (empty) track is created by calling the
! * {@link Sequence#createTrack} method, rather than by directly invoking a
! * {@code Track} constructor.
* <p>
! * The {@code Track} class provides methods to edit the track by adding or
! * removing {@code MidiEvent} objects from it. These operations keep the event
! * list in the correct time order. Methods are also included to obtain the
! * track's size, in terms of either the number of events it contains or its
! * duration in ticks.
*
* @author Kara Kytle
* @author Florian Bomers
+ * @see Sequencer#setTrackMute
+ * @see Sequencer#setTrackSolo
*/
public class Track {
// TODO: use arrays for faster access
*** 71,102 ****
// use a hashset to detect duplicate events in add(MidiEvent)
private HashSet<MidiEvent> set = new HashSet<>();
private MidiEvent eotEvent;
-
/**
! * Package-private constructor. Constructs a new, empty Track object,
! * which initially contains one event, the meta-event End of Track.
*/
Track() {
// start with the end of track event
MetaMessage eot = new ImmutableEndOfTrack();
eotEvent = new MidiEvent(eot, 0);
eventsList.add(eotEvent);
set.add(eotEvent);
}
/**
! * Adds a new event to the track. However, if the event is already
! * contained in the track, it is not added again. The list of events
! * is kept in time order, meaning that this event inserted at the
! * appropriate place in the list, not necessarily at the end.
*
* @param event the event to add
! * @return <code>true</code> if the event did not already exist in the
! * track and was added, otherwise <code>false</code>
*/
public boolean add(MidiEvent event) {
if (event == null) {
return false;
}
--- 70,100 ----
// use a hashset to detect duplicate events in add(MidiEvent)
private HashSet<MidiEvent> set = new HashSet<>();
private MidiEvent eotEvent;
/**
! * Package-private constructor. Constructs a new, empty Track object, which
! * initially contains one event, the meta-event End of Track.
*/
Track() {
// start with the end of track event
MetaMessage eot = new ImmutableEndOfTrack();
eotEvent = new MidiEvent(eot, 0);
eventsList.add(eotEvent);
set.add(eotEvent);
}
/**
! * Adds a new event to the track. However, if the event is already contained
! * in the track, it is not added again. The list of events is kept in time
! * order, meaning that this event inserted at the appropriate place in the
! * list, not necessarily at the end.
*
* @param event the event to add
! * @return {@code true} if the event did not already exist in the track and
! * was added, otherwise {@code false}
*/
public boolean add(MidiEvent event) {
if (event == null) {
return false;
}
*** 174,189 ****
}
return false;
}
-
/**
* Removes the specified event from the track.
* @param event the event to remove
! * @return <code>true</code> if the event existed in the track and was removed,
! * otherwise <code>false</code>
*/
public boolean remove(MidiEvent event) {
// this implementation allows removing the EOT event.
// pretty bad, but would probably be too risky to
--- 172,187 ----
}
return false;
}
/**
* Removes the specified event from the track.
+ *
* @param event the event to remove
! * @return {@code true} if the event existed in the track and was removed,
! * otherwise {@code false}
*/
public boolean remove(MidiEvent event) {
// this implementation allows removing the EOT event.
// pretty bad, but would probably be too risky to
*** 205,223 ****
}
}
return false;
}
-
/**
* Obtains the event at the specified index.
* @param index the location of the desired event in the event vector
- * @throws ArrayIndexOutOfBoundsException if the
- * specified index is negative or not less than the current size of
- * this track.
- * @see #size
* @return the event at the specified index
*/
public MidiEvent get(int index) throws ArrayIndexOutOfBoundsException {
try {
synchronized(eventsList) {
return eventsList.get(index);
--- 203,220 ----
}
}
return false;
}
/**
* Obtains the event at the specified index.
+ *
* @param index the location of the desired event in the event vector
* @return the event at the specified index
+ * @throws ArrayIndexOutOfBoundsException if the specified index is negative
+ * or not less than the current size of this track
+ * @see #size
*/
public MidiEvent get(int index) throws ArrayIndexOutOfBoundsException {
try {
synchronized(eventsList) {
return eventsList.get(index);
*** 225,251 ****
} catch (IndexOutOfBoundsException ioobe) {
throw new ArrayIndexOutOfBoundsException(ioobe.getMessage());
}
}
-
/**
* Obtains the number of events in this track.
* @return the size of the track's event vector
*/
public int size() {
synchronized(eventsList) {
return eventsList.size();
}
}
-
/**
! * Obtains the length of the track, expressed in MIDI ticks. (The
! * duration of a tick in seconds is determined by the timing resolution
! * of the <code>Sequence</code> containing this track, and also by
! * the tempo of the music as set by the sequencer.)
* @return the duration, in ticks
* @see Sequence#Sequence(float, int)
* @see Sequencer#setTempoInBPM(float)
* @see Sequencer#getTickPosition()
*/
--- 222,248 ----
} catch (IndexOutOfBoundsException ioobe) {
throw new ArrayIndexOutOfBoundsException(ioobe.getMessage());
}
}
/**
* Obtains the number of events in this track.
+ *
* @return the size of the track's event vector
*/
public int size() {
synchronized(eventsList) {
return eventsList.size();
}
}
/**
! * Obtains the length of the track, expressed in MIDI ticks. (The duration
! * of a tick in seconds is determined by the timing resolution of the
! * {@code Sequence} containing this track, and also by the tempo of the
! * music as set by the sequencer.)
! *
* @return the duration, in ticks
* @see Sequence#Sequence(float, int)
* @see Sequencer#setTempoInBPM(float)
* @see Sequencer#getTickPosition()
*/
*** 269,275 ****
public void setMessage(int type, byte[] data, int length) throws InvalidMidiDataException {
throw new InvalidMidiDataException("cannot modify end of track message");
}
}
-
}
--- 266,271 ----