CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 * 00019 * MIDIFileReader C++ classes 00020 * This code is part of the CLAM library, but also usable stand-alone. 00021 * Maarten de Boer <mdeboer@iua.upf.es> 00022 * 00023 */ 00024 #include <vector> 00025 #include "MIDISongPlayer.hxx" 00026 #include "MIDITrack.hxx" 00027 #include "MIDISong.hxx" 00028 00029 00030 namespace MIDI 00031 { 00032 00033 class TrackPlayer 00034 /* a helper class for SongPlayerImpl to iterate through each track */ 00035 { 00036 friend class SongPlayerImpl; 00037 private: 00038 Track* mTrack; 00039 std::list<Event*>::const_iterator mIterator; 00040 public: 00041 TrackPlayer(Track* track); 00042 00043 }; 00044 00045 TrackPlayer::TrackPlayer(Track* track) 00046 { 00047 mTrack = track; 00048 mIterator = mTrack->Begin(); 00049 } 00050 00051 class SongPlayerImpl 00052 { 00053 /* hidden implementation of class SongPlayer */ 00054 friend class SongPlayer; 00055 private: 00056 Song* mSong; 00057 std::vector<TrackPlayer*> mTrackPlayerList; 00058 SongPlayerImpl(Song* song) 00059 { 00060 Init(song); 00061 } 00062 00063 void Init(Song* song) 00064 { 00065 mTrackPlayerList.clear(); 00066 mSong = song; 00067 if (mSong) 00068 { 00069 for (int i=0;i<mSong->Tracks();i++) 00070 { 00071 mTrackPlayerList.push_back( 00072 new TrackPlayer(mSong->GetTrack(i))); 00073 } 00074 } 00075 } 00076 00077 bool GetEvent(Event& event,int& trackId) 00078 { 00079 Ticks smallest = 0; 00080 int smallestId = -1; 00081 00082 for (unsigned int i=0;i<mTrackPlayerList.size();i++) 00083 /* look for the track with the next event */ 00084 { 00085 if (mTrackPlayerList[i]->mIterator != 00086 mTrackPlayerList[i]->mTrack->End()) 00087 { 00088 Event* ev = *mTrackPlayerList[i]->mIterator; 00089 if (smallestId==-1 || ev->GetTicks()<smallest) 00090 { 00091 smallest = ev->GetTicks(); 00092 smallestId = i; 00093 } 00094 } 00095 } 00096 if (smallestId != -1) 00097 { 00098 /* return it and increment the iterator of that track */ 00099 event = *(*(mTrackPlayerList[smallestId]->mIterator)); 00100 trackId = smallestId; 00101 mTrackPlayerList[smallestId]->mIterator++; 00102 return true; 00103 } 00104 return false; 00105 } 00106 00107 }; 00108 00109 SongPlayer::SongPlayer(Song* song) 00110 { 00111 mImpl = new SongPlayerImpl(song); 00112 } 00113 00114 void SongPlayer::Init(Song* song) 00115 { 00116 mImpl->Init(song); 00117 } 00118 00119 SongPlayer::~SongPlayer() 00120 { 00121 delete mImpl; 00122 } 00123 00124 bool SongPlayer::GetEvent(Event& event,int& trackId) 00125 { 00126 return mImpl->GetEvent(event,trackId); 00127 } 00128 00129 } 00130 00131 00132