/* * Sequence.java * * This file is part of Tritonus: http://www.tritonus.org/ */ /* * Copyright (c) 1999, 2000 by Matthias Pfisterer * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* |<--- this code is formatted to fit into 80 columns --->| */ package javax.sound.midi; import java.util.Iterator; import java.util.Vector; // TODO: some synchronization now obsolete? (after change from ArrayList to Vector) public class Sequence { public static final float PPQ = 0.0F; public static final float SMPTE_24 = 24.0F; public static final float SMPTE_25 = 25.0F; public static final float SMPTE_30DROP = 29.97F; public static final float SMPTE_30 = 30.0F; private static final Track[] EMPTY_TRACK_ARRAY = new Track[0]; protected float divisionType; protected int resolution; protected Vector tracks; public Sequence(float fDivisionType, int nResolution) throws InvalidMidiDataException { this(fDivisionType, nResolution, 0); } public Sequence(float fDivisionType, int nResolution, int nNumTracks) throws InvalidMidiDataException { if (fDivisionType == PPQ || fDivisionType == SMPTE_24 || fDivisionType == SMPTE_25 || fDivisionType == SMPTE_30DROP || fDivisionType == SMPTE_30) { divisionType = fDivisionType; } else { throw new InvalidMidiDataException("Invalid division type: " + fDivisionType); } resolution = nResolution; tracks = new Vector(); for (int i = 0; i < nNumTracks; i++) { createTrack(); } } public float getDivisionType() { return divisionType; } public int getResolution() { return resolution; } @SuppressWarnings("unchecked") public Track createTrack() { Track track = new Track(); synchronized (tracks) { tracks.add(track); } return track; } public boolean deleteTrack(Track track) { synchronized (tracks) { return tracks.remove(track); } } @SuppressWarnings("unchecked") public Track[] getTracks() { synchronized (tracks) { return (Track[]) tracks.toArray(EMPTY_TRACK_ARRAY); } } public long getMicrosecondLength() { if (getDivisionType() != PPQ) { return (long) (getTickLength() * 1000000 / (getDivisionType() * getResolution())); } else { // TODO: find all tempo change events and calculate length according to them. return -1; } } public long getTickLength() { long lLength = 0; Iterator tracksIterator = tracks.iterator(); while (tracksIterator.hasNext()) { Track track = (Track) tracksIterator.next(); lLength = Math.max(lLength, track.ticks()); } return lLength; } // make abstract ?? public Patch[] getPatchList() { // TODO: // not implemented in sun version, too return new Patch[0]; } } /*** Sequence.java ***/