MIDIDevice.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #include "MIDIDevice.hxx"
00023 #include "MIDIIn.hxx"
00024 #include "MIDIOut.hxx"
00025 #include "MIDIClocker.hxx"
00026 #include "MIDIEnums.hxx"
00027 #include <algorithm>
00028 #include <cstdio>
00029 
00030 using std::find;
00031 
00032 using namespace CLAM;
00033 
00034 MIDIManager& MIDIDevice::_MIDIManager(void)
00035 {
00036         if (mMIDIManager==0) 
00037                 throw Err("This MIDIDevice is not associated with any MIDIManager");
00038 
00039         return *mMIDIManager; 
00040 }
00041 
00042 void MIDIDevice::_SetMIDIManager(MIDIManager* am)
00043 {
00044         if (mMIDIManager==0) mMIDIManager = am;
00045         else if (mMIDIManager!=am)
00046         {
00047                 throw Err("An MIDIDevice can only be associated with one MIDIManager");
00048         }
00049 }
00050 
00051 bool MIDIDevice::Register(MIDIManager* mm,MIDIIn& in)
00052 {
00055         mInputs.push_back(&in);
00056         _SetMIDIManager(mm);
00057         in.mpDevice = this;
00058         return true;
00059 }
00060 
00061 bool MIDIDevice::Register(MIDIManager* mm,MIDIClocker& in)
00062 {
00063         _SetMIDIManager(mm);
00064         in.mpDevice = this;
00065         return true;
00066 }
00067 
00068 bool MIDIDevice::Register(MIDIManager* mm,MIDIOut& out)
00069 {
00070         mOutputs.push_back(&out);
00071         _SetMIDIManager(mm);
00072         out.mpDevice = this;
00073         return true;
00074 }
00075 
00076 void MIDIDevice::Unregister(MIDIIn& in)
00077 {
00078         if (in.mpDevice != this)
00079         {
00080                 throw(Err("MIDIDevice::Unregister(): I am not this MIDIIn object's device."));
00081         }
00082         std::vector<MIDIIn*>::iterator it = std::find(mInputs.begin(),mInputs.end(),&in);
00083         if (it == mInputs.end())
00084         {
00085                 throw(Err("MIDIDevice::Unregister(): MIDIIn object not registered in this device."));
00086         }
00087 
00090         for (int status = 0;status<8;status++)
00091         {
00092                 for (int channel = 0;channel<16;channel++)
00093                 {       
00094                         for (int i=0;i<128;i++)
00095                         {
00096                                 if (target[status][channel][i]==&in)
00097                                         target[status][channel][i] = 0;
00098                         }
00099                 }
00100         }
00101 
00102         mInputs.erase(it);
00103         in.mpDevice = 0;
00104 }
00105 
00106 void MIDIDevice::Unregister(MIDIClocker& in)
00107 {
00108         in.mpDevice = 0;
00109 }
00110 
00111 
00112 void MIDIDevice::Unregister(MIDIOut& out)
00113 {
00114         std::vector<MIDIOut*>::iterator it = std::find(mOutputs.begin(),mOutputs.end(),&out);
00115         if (it == mOutputs.end())
00116         {
00117                 throw(Err("MIDIDevice::Unregister(): MIDIOut object not registered in this device."));
00118         }
00119         mOutputs.erase(it);
00120         out.mpDevice = 0;
00121 }
00122 
00123 
00124 void MIDIDevice::GetInfo(MIDIDevice::TInfo &info)
00125 {
00126         info.mName = mName;
00127 }
00128 
00129 void MIDIDevice::SetTarget(
00130         MIDI::Message msg,
00131         unsigned char chn,unsigned char firstData,
00132         MIDIIn* inp)
00133 {
00134         if (msg==MIDI::eNoteOnOff)
00135         {
00136                 SetTarget(MIDI::eNoteOn, chn, firstData, inp);
00137                 SetTarget(MIDI::eNoteOff,chn, firstData, inp);
00138                 return;
00139         }
00140 
00141         if (firstData==0x80)
00142         {
00143                 for (firstData=0;firstData<128;firstData++)
00144                 {
00145                         SetTarget(msg,chn,firstData,inp);
00146                 }
00147                 return;
00148         }
00149 
00150         if (msg==MIDI::eSystem)
00151         {
00152                 if (chn==0)
00153                 {
00154                         fprintf(stderr,"SysEx not       yet implemented\n");
00155                         exit(-1);
00156                 }
00157         }else{
00158                 if (chn==0)
00159                 {
00160                         for (chn = 1;chn<=16;chn++)
00161                         {
00162                                 SetTarget(msg,chn,firstData,inp);
00163                         }
00164                         return;
00165                 }
00166                 chn--;
00167         }
00168         target[msg][chn][firstData] = inp;
00169 }
00170 
00171 void MIDIDevice::Start(void)
00172 {
00173         int status ;
00174 
00177         for (status = 0;status<8;status++)
00178         {
00179                 for (int channel = 0;channel<16;channel++)
00180                 {       
00181                         for (int byte=0;byte<128;byte++)
00182                         {
00183                                                         target[status][channel][byte] = 0;
00184                         }
00185                 }
00186         }
00187         
00188         for (unsigned int i=0; i<mInputs.size(); i++)
00189         {
00190                 const MIDIIOConfig &cfg = 
00191                         dynamic_cast<const MIDIIOConfig&>(mInputs[i]->GetConfig());
00192 
00193                 SetTarget(
00194                         MIDI::Message(cfg.GetMessage()),
00195                         cfg.GetChannel(),
00196                         cfg.GetFirstData(),
00197                         mInputs[i]);
00198         }
00199 
00200         ConcreteStart();
00201 }
00202 
00203 void MIDIDevice::Stop(void)
00204 {
00205         ConcreteStop();
00206 }
00207 
00208 int MIDIDevice::GetMessageLength(unsigned char byte)
00209 {
00210         MIDI::Message cm = MIDI::StatusByteToMessage(byte);
00211         if (cm == MIDI::eSystem)
00212         {
00213                 MIDI::SysMsg sm = MIDI::StatusByteToSysMsg(mData[0]);
00214                 return MIDI::sNBytesPerSysMsg[int(sm)];
00215         }
00216         else
00217         {
00218                 mLastStatus = mData[0];
00219                 return MIDI::GetMessageInfo(cm).length;
00220         }
00221 }
00222 
00223 void MIDIDevice::HandleRawByte(unsigned char byte)
00224 {       
00225         if (byte==0xfe) return;  
00226         if (mIndex==0)           
00227         {
00228                 if (byte&0x80)       
00229                 {
00230                         mData[0] = byte;
00231                         mIndex = 1;
00232                 }
00233                 else                 
00234                 {
00235                         if (mLastStatus) 
00236                         {
00237                                 mData[0] = mLastStatus;
00238                                 mData[1] = byte;
00239                                 mIndex = 2;
00240                         }
00241                 }
00242                 mLength = GetMessageLength(mData[0]);
00243         }else                   
00244         {
00245                 mData[mIndex++] = byte;
00246         }
00247         if (mLength && mIndex == mLength)   
00248         {
00250                 int status = ((mData[0]&0xF0)>>4)-8;                    
00251                 int channel = mData[0]&0x0F;                                    
00252                 if (status == MIDI::eNoteOn && mData[2]==0)             
00253                 {
00254                         status = MIDI::eNoteOff;                                        
00255                         mData[0] = 0x80|channel;                                        
00257                 }
00258                 MIDIIn* t = target[status][channel][mData[1]];  
00260                 if (t)
00261                 {
00262                         t->Handle(mData,mLength);
00263                 }
00264                 mIndex = 0;
00265         }
00266 }
00267 

Generated on Tue Feb 22 09:53:23 2011 for CLAM-Development by  doxygen 1.5.9