CLAM-Development  1.4.0
MIDISongPlayer.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * MIDIFileReader C++ classes
20  * This code is part of the CLAM library, but also usable stand-alone.
21  * Maarten de Boer <mdeboer@iua.upf.es>
22  *
23  */
24 #include <vector>
25 #include "MIDISongPlayer.hxx"
26 #include "MIDITrack.hxx"
27 #include "MIDISong.hxx"
28 
29 
30 namespace MIDI
31 {
32 
33  class TrackPlayer
34  /* a helper class for SongPlayerImpl to iterate through each track */
35  {
36  friend class SongPlayerImpl;
37  private:
38  Track* mTrack;
39  std::list<Event*>::const_iterator mIterator;
40  public:
41  TrackPlayer(Track* track);
42 
43  };
44 
45  TrackPlayer::TrackPlayer(Track* track)
46  {
47  mTrack = track;
48  mIterator = mTrack->Begin();
49  }
50 
51  class SongPlayerImpl
52  {
53  /* hidden implementation of class SongPlayer */
54  friend class SongPlayer;
55  private:
56  Song* mSong;
57  std::vector<TrackPlayer*> mTrackPlayerList;
58  SongPlayerImpl(Song* song)
59  {
60  Init(song);
61  }
62 
63  void Init(Song* song)
64  {
65  mTrackPlayerList.clear();
66  mSong = song;
67  if (mSong)
68  {
69  for (int i=0;i<mSong->Tracks();i++)
70  {
71  mTrackPlayerList.push_back(
72  new TrackPlayer(mSong->GetTrack(i)));
73  }
74  }
75  }
76 
77  bool GetEvent(Event& event,int& trackId)
78  {
79  Ticks smallest = 0;
80  int smallestId = -1;
81 
82  for (unsigned int i=0;i<mTrackPlayerList.size();i++)
83  /* look for the track with the next event */
84  {
85  if (mTrackPlayerList[i]->mIterator !=
86  mTrackPlayerList[i]->mTrack->End())
87  {
88  Event* ev = *mTrackPlayerList[i]->mIterator;
89  if (smallestId==-1 || ev->GetTicks()<smallest)
90  {
91  smallest = ev->GetTicks();
92  smallestId = i;
93  }
94  }
95  }
96  if (smallestId != -1)
97  {
98  /* return it and increment the iterator of that track */
99  event = *(*(mTrackPlayerList[smallestId]->mIterator));
100  trackId = smallestId;
101  mTrackPlayerList[smallestId]->mIterator++;
102  return true;
103  }
104  return false;
105  }
106 
107  };
108 
110  {
111  mImpl = new SongPlayerImpl(song);
112  }
113 
114  void SongPlayer::Init(Song* song)
115  {
116  mImpl->Init(song);
117  }
118 
120  {
121  delete mImpl;
122  }
123 
124  bool SongPlayer::GetEvent(Event& event,int& trackId)
125  {
126  return mImpl->GetEvent(event,trackId);
127  }
128 
129 }
130 
131 
132