FileMIDIDevice.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "MIDIIn.hxx"
00023 #include "MIDIDeviceList.hxx"
00024 #include "MIDIDevice.hxx"
00025
00026 #include "MIDIEvent.hxx"
00027 #include "MIDITrack.hxx"
00028 #include "MIDISong.hxx"
00029 #include "MIDITempo.hxx"
00030 #include "MIDIReader.hxx"
00031 #include "MIDISongPlayer.hxx"
00032
00033 namespace CLAM {
00034
00035 class FileMIDIDevice: public MIDIDevice
00036 {
00037 private:
00038 std::string mFilename;
00039 ::MIDI::Song mSong;
00040 ::MIDI::SongPlayer mSongPlayer;
00041 ::MIDI::Tempo mTempo;
00042 bool mHavePendingEvent;
00043 ::MIDI::Event mPendingEvent;
00044 int mPendingTrackId;
00045 ::MIDI::Milliseconds mPendingTime;
00046 ::MIDI::Milliseconds mCurTime;
00047 bool mReadDone;
00048 public:
00049 FileMIDIDevice(const std::string& name,const std::string& device);
00050 ~FileMIDIDevice();
00051
00052 void ConcreteStart(void) throw(Err);
00053 void ConcreteStop(void) throw(Err);
00054
00055 void Read(void) throw(Err);
00056 void Write(unsigned char* msg,int size) throw(Err);
00057 void SetClock(TControlData val);
00058 };
00059
00060 FileMIDIDevice::FileMIDIDevice(const std::string& name,const std::string& fname):
00061 MIDIDevice(name)
00062 {
00063 mFilename = fname;
00064 mHavePendingEvent = false;
00065 mReadDone = false;
00066 mCurTime = 0;
00067 }
00068
00069 void FileMIDIDevice::ConcreteStart(void) throw(Err)
00070 {
00071 if (!mReadDone)
00072 {
00073
00074 mReadDone = true;
00075 ::MIDI::Reader reader(mFilename.c_str());
00076
00077 if (!reader.Ok())
00078 {
00079 std::string str("Could not open FileMIDIDevice with file ");
00080 str += mFilename;
00081 throw Err(str.c_str());
00082 }
00083 try{
00084 reader.Read(mSong);
00085 }
00086 catch(::MIDI::Reader::Error err)
00087 {
00088 throw Err(err.mStr);
00089 }
00090 mSongPlayer.Init(&mSong);
00091 mTempo.Init(&mSong);
00092
00093 }
00094 }
00095
00096 void FileMIDIDevice::ConcreteStop(void) throw(Err)
00097 {
00098 }
00099
00100 void FileMIDIDevice::SetClock(TControlData val)
00101 {
00102 mCurTime = (::MIDI::Milliseconds) val;
00103 }
00104
00105 void FileMIDIDevice::Write(unsigned char* msg,int size) throw(Err)
00106 {
00107 throw Err("FileMIDIDevice::Write not implemented yet");
00108 }
00109
00110 void FileMIDIDevice::Read(void) throw(Err)
00111 {
00112 bool flag;
00113 static int nbytesPerChnMsg[7] =
00114 { 3,3,3,3,2,3,3 };
00115 do
00116 {
00117 flag = false;
00118 if (!mHavePendingEvent)
00119 {
00120 mHavePendingEvent =
00121 mSongPlayer.GetEvent(mPendingEvent,mPendingTrackId);
00122 if (mHavePendingEvent)
00123 {
00124 mPendingTime = mTempo.TicksToTime(mPendingEvent.GetTicks());
00125 }else{
00126 HandleRawByte(0xF0|int(MIDI::eStop));
00127 }
00128 }
00129 if (mHavePendingEvent) {
00130 if (mCurTime >= mPendingTime)
00131 {
00132 if (
00133 mPendingEvent[0] != 0xF0 &&
00134 mPendingEvent[0] != 0xF7 &&
00135 mPendingEvent[0] != 0xFF)
00136
00137 {
00138 int nbytes = nbytesPerChnMsg[((mPendingEvent[0]&0xF0)>>4)-8];
00139 if ((mPendingEvent[0]&0xF0)==0x80)
00140 {
00141 HandleRawByte((mPendingEvent[0]&0x0F)|0x90);
00142 HandleRawByte(mPendingEvent[1]);
00143 HandleRawByte(0);
00144 }else
00145 for (int i = 0; i < nbytes; i++)
00146 {
00147 HandleRawByte(mPendingEvent[i]);
00148 }
00149 }
00150 mHavePendingEvent = false;
00151 flag = true;
00152 }
00153 }
00154 } while (flag);
00155 }
00156
00157 FileMIDIDevice::~FileMIDIDevice()
00158 {
00159 }
00160
00161 class FileMIDIDeviceList: public MIDIDeviceList
00162 {
00163 static FileMIDIDeviceList sDevices;
00164
00165 FileMIDIDeviceList()
00166 :MIDIDeviceList(std::string("file"))
00167 {
00168 AddMe();
00169 mAvailableDevices.push_back("*.mid");
00170 }
00171 public:
00172
00173 std::string DefaultDevice(void)
00174 {
00175 return "file:unknown.mid";
00176 }
00177
00178 MIDIDevice* Create(
00179 const std::string& name,const std::string& device)
00180 {
00181 return new FileMIDIDevice(name,device);
00182 }
00183 };
00184
00185 FileMIDIDeviceList FileMIDIDeviceList::sDevices;
00186 }
00187
00188
00189
00190
00191
00192
00193