//------------------------------------------------------------------------- // Filename: sequence.cc // Version: $Id: sequence.cc,v 1.1.2.2 1999/06/09 10:14:05 erik Exp $ // Copyright: Copyright (C) 1999, Erik Mouw (J.A.K.Mouw@its.tudelft.nl) // Author: Erik Mouw // Description: MIDI track class // Created at: Sat May 15 14:57:08 1999 // Modified by: Erik Mouw // Modified at: Wed May 26 23:59:00 1999 //------------------------------------------------------------------------- // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ident "$Id: sequence.cc,v 1.1.2.2 1999/06/09 10:14:05 erik Exp $" #ifdef HAVE_CONFIG_H # include #endif #include #ifdef HAVE_LIMITS_H # include #endif #if (MUSICA_DEBUG || TIMING_DEBUG) # include #endif #include "sequence.hh" #ifndef LONG_MAX # define LONG_MAX 2147483647L #endif #ifdef TIMING_DEBUG static long int lastNextTime = 0L; static int lastNextTrack = 0; #endif void midiSequence::updateState(void) { int i; // calculate current times for(i = 0; i < numTracks; i++) currentTimes[i] = tracks[i]->getCurrentTime(); // find out the smallest currentTime. that is the current played track allCurrentTime = LONG_MAX; currentTrack = -1; for(i = 0; i < numTracks; i++) { if((currentTimes[i] >= 0L) && (currentTimes[i] < allCurrentTime)) { allCurrentTime = currentTimes[i]; currentTrack = i; } } // calculate next times for(i = 0; i < numTracks; i++) { if(i != currentTrack) nextTimes[i] = currentTimes[i]; else nextTimes[i] = tracks[i]->getNextTime(); } // find out the smallest nextSumTime. that is the next track to be played allNextTime = LONG_MAX; nextTrack = -1; for(i = 0; i < numTracks; i++) { if((nextTimes[i] >= 0L) && (nextTimes[i] < allNextTime)) { allNextTime = nextTimes[i]; nextTrack = i; } } if(currentTrack == -1) allCurrentTime = -1L; if(nextTrack == -1) allNextTime = -1L; #ifdef TIMING_DEBUG cout<< "updating current track# "<< currentTrack<< " at "<< allCurrentTime<< ", next track# "<< nextTrack<< " at "<< allNextTime<< endl; if(lastNextTime != allCurrentTime) cout<< "*** lastNextTime != allCurrentTime: "<< lastNextTime<< " != "<< allCurrentTime<< endl; if(lastNextTrack != currentTrack) cout<< "*** lastNextTrack != currentTrack: "<< lastNextTrack<< " != "<< currentTrack<< endl; lastNextTime = allNextTime; lastNextTrack = nextTrack; #endif } midiSequence::midiSequence(void) { int i; numTracks = 0; division = 120; // default value units = frames = -1; for(i = 0; i < maxMidiTracks; i++) { tracks[i] = 0; currentTimes[i] = -1L; nextTimes[i] = -1L; } allCurrentTime = -1L; allNextTime = -1L; currentTrack = nextTrack = -1; } midiSequence::~midiSequence(void) { int i; // delete all tracks for(i = 0; i < numTracks; i++) delete tracks[i]; } int midiSequence::getDivision(void) { if(division == -1) { // FIXME: this is NOT correct return(120); } else { return(division); } } int midiSequence::addTrack(midiTrack *track) { // sanity check assert(track != 0); if(numTracks >= maxMidiTracks) return(-1); tracks[numTracks] = track; numTracks++; rewind(); return(numTracks - 1); } void midiSequence::rewind(void) { int i; for(i = 0; i < numTracks; i++) tracks[i]->rewind(); updateState(); } // get next event time long int midiSequence::getDeltaTime(void) { if((allCurrentTime == -1L) || (allNextTime == -1L)) return(-1L); else return(allNextTime - allCurrentTime); } void midiSequence::play(midiDevice *device, midiPlayer *player) { assert(device != 0); assert(player != 0); if(currentTrack != -1) { #ifdef TIMING_DEBUG cout<< "playing current track# " << currentTrack<< " at "<< allCurrentTime<< endl; #endif tracks[currentTrack]->play(device, player); #ifdef TIMING_DEBUG cout<< endl; #endif } updateState(); }