MIDIOutControl.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 "InControl.hxx"
00023 #include "MIDIOutControl.hxx"
00024 #include <string>
00025
00026 namespace CLAM {
00027
00028 MIDIOutControl::MIDIOutControl():MIDIOut(false)
00029 {
00030 mpDevice = 0;
00031 InitMembers();
00032 Configure(MIDIIOConfig());
00033 }
00034
00035 MIDIOutControl::MIDIOutControl(const MIDIIOConfig &c):MIDIOut(false)
00036 {
00037 mpDevice = 0;
00038 InitMembers();
00039 Configure(c);
00040 }
00041
00042 void MIDIOutControl::InitMembers(void)
00043 {
00044 mUniqId = 0;
00045
00046 mMessage = 0;
00047 mReceivedUniqId = 0;
00048 mControlIdToMsgByteId = 0;
00049
00050 mMessageSize = 0;
00051
00052 mControlledBytes = 0;
00053 mControlsReceived = 0;
00054 }
00055
00056 bool MIDIOutControl::ConcreteConfigure(const ProcessingConfig& c)
00057 throw(ErrProcessingObj)
00058 {
00059 bool ret = MIDIOut::ConcreteConfigure(c);
00060
00061 if (ret==false) return false;
00062
00063 MIDI::Message m = MIDI::Message(mConfig.GetMessage());
00064
00065 mMessageSize = MIDI::GetMessageInfo(m).length;
00066
00067
00068
00069 mControlledBytes = MIDI::GetMessageInfo(m).length;
00070
00071 if (mConfig.GetChannel()!=0) mControlledBytes--;
00072
00073
00074 if (mConfig.GetFirstData()!=128) mControlledBytes--;
00075
00076 mControlsReceived = 0;
00077
00078
00079 if (mMessage) delete [] mMessage;
00080 mMessage = new unsigned char[mMessageSize];
00081
00082 if (mReceivedUniqId) delete [] mReceivedUniqId;
00083 mReceivedUniqId = new unsigned char[mControlledBytes];
00084
00085 if (mControlIdToMsgByteId) delete mControlIdToMsgByteId;
00086 mControlIdToMsgByteId = new unsigned char[mControlledBytes];
00087
00088
00089 for (int i = 0; i < mControlledBytes ; i++ )
00090 {
00091 mReceivedUniqId[i] = mUniqId;
00092 }
00093
00094 if (m==MIDI::eNoteOnOff) m = MIDI::eNoteOn;
00095
00096 mStatusByte = 0x80|(int(m)<<4);
00097
00098 int ctrlid = 0;
00099
00100
00101 for (int i=0;i<MIDI::GetMessageInfo(m).length;i++)
00102 {
00103 const char* fieldname = 0;
00104
00105
00106 switch (i)
00107 {
00108 case 0:
00109 if (mConfig.GetChannel()==0)
00110
00111 fieldname = "Channel";
00112 else
00113
00114
00115 mStatusByte |= (mConfig.GetChannel()+1);
00116 break;
00117 case 1:
00118 if (mConfig.GetFirstData()==128)
00119
00120 fieldname = MIDI::GetMessageInfo(m).field[i-1];
00121 else
00122
00123 mMessage[1] = mConfig.GetFirstData();
00124 break;
00125 default:
00126
00127 fieldname = MIDI::GetMessageInfo(m).field[i-1];
00128 break;
00129 }
00130 if (fieldname)
00131 {
00132 std::string controlName = std::string(MIDI::GetMessageInfo(m).name) + ":" + fieldname;
00133
00134
00135 mControlIdToMsgByteId[ctrlid] = i;
00136 mMyInControls.AddElem(new FloatInControl(ctrlid++,controlName,this,&MIDIOutControl::DoControl));
00137 }
00138 }
00139
00140 return true;
00141 }
00142
00143 void MIDIOutControl::DoControl(unsigned id,TControlData val)
00144 {
00145
00146
00147 if (mReceivedUniqId[id]!=mUniqId)
00148 {
00149
00150
00151 fprintf(stderr,"ERROR!!!! receiving a byte when the prev message was not fully constructed yet... TODO: should we throw or assert?\n");
00152 return;
00153 }
00154
00155 int i = mControlIdToMsgByteId[id];
00156 if (i==0)
00157 {
00158
00159
00160 mStatusByte = (mStatusByte&0xF0) | ((unsigned char)(val)-1);
00161 }else{
00162 mMessage[i] = (unsigned char) val;
00163 }
00164 mReceivedUniqId[id]++;
00165 mControlsReceived++;
00166 if (mControlsReceived==mControlledBytes)
00167 {
00168
00169
00170
00171 mUniqId++;
00172 mControlsReceived = 0;
00173 mMessage[0]=mStatusByte;
00174 Handle(mMessage,mMessageSize);
00175 }
00176 }
00177
00178 void MIDIOutControl::Handle(unsigned char* msg,int size)
00179 {
00180
00181 CLAM_ASSERT(mpDevice,"MIDIOutControl used without a valid device");
00182 if ((msg[0]&0xF0)==0x90 && msg[2]==0) msg[0] &=0x8F;
00183 mpDevice->Write(msg,size);
00184 }
00185
00186 }
00187