48 * reason, a new (empty) track is created by calling the
49 * {@link Sequence#createTrack} method, rather than by directly invoking a
50 * {@code Track} constructor.
51 * <p>
52 * The {@code Track} class provides methods to edit the track by adding or
53 * removing {@code MidiEvent} objects from it. These operations keep the event
54 * list in the correct time order. Methods are also included to obtain the
55 * track's size, in terms of either the number of events it contains or its
56 * duration in ticks.
57 *
58 * @author Kara Kytle
59 * @author Florian Bomers
60 * @see Sequencer#setTrackMute
61 * @see Sequencer#setTrackSolo
62 */
63 public class Track {
64
65 // TODO: use arrays for faster access
66
67 // the list containing the events
68 private ArrayList<MidiEvent> eventsList = new ArrayList<>();
69
70 // use a hashset to detect duplicate events in add(MidiEvent)
71 private HashSet<MidiEvent> set = new HashSet<>();
72
73 private MidiEvent eotEvent;
74
75 /**
76 * Package-private constructor. Constructs a new, empty Track object, which
77 * initially contains one event, the meta-event End of Track.
78 */
79 Track() {
80 // start with the end of track event
81 MetaMessage eot = new ImmutableEndOfTrack();
82 eotEvent = new MidiEvent(eot, 0);
83 eventsList.add(eotEvent);
84 set.add(eotEvent);
85 }
86
87 /**
88 * Adds a new event to the track. However, if the event is already contained
89 * in the track, it is not added again. The list of events is kept in time
90 * order, meaning that this event inserted at the appropriate place in the
91 * list, not necessarily at the end.
92 *
93 * @param event the event to add
247 * @see Sequencer#getTickPosition()
248 */
249 public long ticks() {
250 long ret = 0;
251 synchronized (eventsList) {
252 if (eventsList.size() > 0) {
253 ret = (eventsList.get(eventsList.size() - 1)).getTick();
254 }
255 }
256 return ret;
257 }
258
259 private static class ImmutableEndOfTrack extends MetaMessage {
260 private ImmutableEndOfTrack() {
261 super(new byte[3]);
262 data[0] = (byte) META;
263 data[1] = MidiUtils.META_END_OF_TRACK_TYPE;
264 data[2] = 0;
265 }
266
267 public void setMessage(int type, byte[] data, int length) throws InvalidMidiDataException {
268 throw new InvalidMidiDataException("cannot modify end of track message");
269 }
270 }
271 }
|
48 * reason, a new (empty) track is created by calling the
49 * {@link Sequence#createTrack} method, rather than by directly invoking a
50 * {@code Track} constructor.
51 * <p>
52 * The {@code Track} class provides methods to edit the track by adding or
53 * removing {@code MidiEvent} objects from it. These operations keep the event
54 * list in the correct time order. Methods are also included to obtain the
55 * track's size, in terms of either the number of events it contains or its
56 * duration in ticks.
57 *
58 * @author Kara Kytle
59 * @author Florian Bomers
60 * @see Sequencer#setTrackMute
61 * @see Sequencer#setTrackSolo
62 */
63 public class Track {
64
65 // TODO: use arrays for faster access
66
67 // the list containing the events
68 private final ArrayList<MidiEvent> eventsList = new ArrayList<>();
69
70 // use a hashset to detect duplicate events in add(MidiEvent)
71 private final HashSet<MidiEvent> set = new HashSet<>();
72
73 private final MidiEvent eotEvent;
74
75 /**
76 * Package-private constructor. Constructs a new, empty Track object, which
77 * initially contains one event, the meta-event End of Track.
78 */
79 Track() {
80 // start with the end of track event
81 MetaMessage eot = new ImmutableEndOfTrack();
82 eotEvent = new MidiEvent(eot, 0);
83 eventsList.add(eotEvent);
84 set.add(eotEvent);
85 }
86
87 /**
88 * Adds a new event to the track. However, if the event is already contained
89 * in the track, it is not added again. The list of events is kept in time
90 * order, meaning that this event inserted at the appropriate place in the
91 * list, not necessarily at the end.
92 *
93 * @param event the event to add
247 * @see Sequencer#getTickPosition()
248 */
249 public long ticks() {
250 long ret = 0;
251 synchronized (eventsList) {
252 if (eventsList.size() > 0) {
253 ret = (eventsList.get(eventsList.size() - 1)).getTick();
254 }
255 }
256 return ret;
257 }
258
259 private static class ImmutableEndOfTrack extends MetaMessage {
260 private ImmutableEndOfTrack() {
261 super(new byte[3]);
262 data[0] = (byte) META;
263 data[1] = MidiUtils.META_END_OF_TRACK_TYPE;
264 data[2] = 0;
265 }
266
267 @Override
268 public void setMessage(int type, byte[] data, int length) throws InvalidMidiDataException {
269 throw new InvalidMidiDataException("cannot modify end of track message");
270 }
271 }
272 }
|