CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * Copyright (c) 2007 Superlucidity Services, LLC and Zachary T Welch 00005 * 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 */ 00022 00023 #include "ControlTrace.hxx" 00024 #include "XMLAdapter.hxx" 00025 #include "XMLStorage.hxx" 00026 #include "XMLIterableAdapter.hxx" 00027 #include "XMLAdapter.hxx" 00028 #include "XmlStorageErr.hxx" 00029 #include <sstream> 00030 #include "ProcessingFactory.hxx" 00031 00032 namespace CLAM 00033 { 00034 namespace Hidden 00035 { 00036 static const char * metadataReader[] = { 00037 "key", "ControlTraceReader", 00038 "category", "Controls", 00039 "description", "ControlTraceReader", 00040 0 00041 }; 00042 static FactoryRegistrator<ProcessingFactory, ControlTraceReader> regReader = metadataReader; 00043 00044 static const char * metadataWriter[] = { 00045 "key", "ControlTraceWriter", 00046 "category", "Controls", 00047 "description", "ControlTraceWriter", 00048 0 00049 }; 00050 static FactoryRegistrator<ProcessingFactory, CLAM::ControlTraceWriter> regWriter = metadataWriter; 00051 } 00052 00053 ControlTraceEvent::ControlTraceEvent() 00054 : mRepeats(0) 00055 { 00056 } 00057 ControlTraceEvent::ControlTraceEvent(const ControlTraceEvent &obj) 00058 : mRepeats(obj.mRepeats) 00059 , mValues(obj.mValues) 00060 { 00061 } 00062 ControlTraceEvent::ControlTraceEvent(const InControlArray &inputs) 00063 : mRepeats(0) 00064 { 00065 mValues.resize(inputs.Size()); 00066 for (int i = 0; i < inputs.Size(); i++) 00067 mValues[i] = inputs[i].GetLastValue(); 00068 } 00069 00070 void ControlTraceEvent::UpdateControls(OutControlArray &outputs) const 00071 { 00072 for (int i = 0; i < outputs.Size(); i++) 00073 outputs[i].SendControl(mValues[i]); 00074 } 00075 00076 void ControlTraceEvent::LoadFrom( Storage& storage ) 00077 { 00078 XMLIterableAdapter<ValueArray> vAdapter(mValues, "x", "controls", true); 00079 storage.Load(vAdapter); 00080 00081 XMLAdapter<unsigned int> sAdapter(mRepeats, "repeats", true); 00082 storage.Load(sAdapter); 00083 } 00084 00085 void ControlTraceEvent::StoreOn( Storage& storage ) const 00086 { 00087 XMLIterableAdapter<ValueArray> vAdapter(mValues, "x", "controls", true); 00088 storage.Store(vAdapter); 00089 00090 if (mRepeats) 00091 { 00092 XMLAdapter<unsigned int> sAdapter(mRepeats, "repeats", true); 00093 storage.Store(sAdapter); 00094 } 00095 } 00096 00097 const ControlTraceEvent& ControlTraceEvent::operator=(const ControlTraceEvent& rhs) 00098 { 00099 mValues = rhs.mValues; 00100 return *this; 00101 } 00102 00103 bool ControlTraceEvent::ValuesEqual(const ControlTraceEvent &rhs) const 00104 { 00105 if (mValues.size() != rhs.mValues.size()) 00106 return false; 00107 00108 for (size_t i = 0; i < mValues.size(); i++) 00109 { 00110 if (mValues[i] != rhs.mValues[i]) 00111 return false; 00112 } 00113 00114 return true; 00115 } 00116 00117 /* ================================================================== */ 00118 00119 const unsigned int ControlTraceData::DumpVersion = 1; 00120 00121 ControlTraceData::ControlTraceData() 00122 : mVersion(DumpVersion) 00123 { 00124 } 00125 ControlTraceData::ControlTraceData(const ControlTraceData &obj) 00126 : mVersion(DumpVersion), mEvents(obj.mEvents) 00127 { 00128 } 00129 00130 void ControlTraceData::LoadFrom( Storage& storage ) 00131 { 00132 mVersion = 0; 00133 XMLAdapter<unsigned int> versionAdapter(mVersion, "version"); 00134 storage.Load(versionAdapter); 00135 if (!mVersion || mVersion > DumpVersion) 00136 { 00137 std::stringstream err; 00138 err << "Unknown CLAM Control Trace file version: " << mVersion; 00139 throw XmlStorageErr(err.str()); 00140 } 00141 00142 XMLIterableAdapter<EventList> adapter(mEvents, "event", "events", true); 00143 storage.Load(adapter); 00144 } 00145 void ControlTraceData::StoreOn( Storage& storage ) const 00146 { 00147 XMLAdapter<unsigned int> versionAdapter(mVersion, "version"); 00148 storage.Store(versionAdapter); 00149 00150 XMLIterableAdapter<EventList> adapter(mEvents, "event", "events", true); 00151 storage.Store(adapter); 00152 } 00153 00154 void ControlTraceData::Append(const ControlTraceEvent &data) 00155 { 00156 ControlTraceEvent &prev = mEvents.back(); 00157 if (prev.ValuesEqual(data)) 00158 prev.WasRepeated(); 00159 else 00160 mEvents.push_back(data); 00161 } 00162 00163 /* ================================================================== */ 00164 00165 static const char clamControlTraceFileTypeFamily[] = "CLAM Control Trace"; 00166 static const Filename::Filter clamControlTraceFileFilters[] = { 00167 { "CLAM Control Traces (v1)", "*.clamtrace" }, 00168 }; 00169 00170 const char* ControlTraceInFilename::TypeFamily() const 00171 { 00172 return clamControlTraceFileTypeFamily; 00173 } 00174 const Filename::Filter * ControlTraceInFilename::Filters() const 00175 { 00176 return clamControlTraceFileFilters; 00177 } 00178 00179 const char* ControlTraceOutFilename::TypeFamily() const 00180 { 00181 return clamControlTraceFileTypeFamily; 00182 } 00183 const Filename::Filter * ControlTraceOutFilename::Filters() const 00184 { 00185 return clamControlTraceFileFilters; 00186 } 00187 00188 /* ================================================================= */ 00189 00190 void ControlTraceWriterConfig::DefaultInit() 00191 { 00192 AddAll(); 00193 UpdateData(); 00194 SetNumberOfInputs(1.); 00195 } 00196 00197 ControlTraceWriter::ControlTraceWriter() 00198 { 00199 Configure(mConfig); 00200 } 00201 00202 ControlTraceWriter::ControlTraceWriter( const ProcessingConfig& cfg ) 00203 { 00204 Configure( cfg ); 00205 } 00206 00207 ControlTraceWriter::~ControlTraceWriter() 00208 { 00209 RemoveOldControls(); 00210 } 00211 00212 bool ControlTraceWriter::ConcreteConfigure( const ProcessingConfig& cfgObj ) 00213 { 00214 RemoveOldControls(); 00215 CopyAsConcreteConfig( mConfig, cfgObj ); 00216 if ( !mConfig.HasTraceFile() ) 00217 { 00218 AddConfigErrorMessage("No 'trace file' was specified in the configuration!"); 00219 return false; 00220 } 00221 00222 ControlTraceOutFilename &file = mConfig.GetTraceFile(); 00223 if ( file == "" ) 00224 { 00225 AddConfigErrorMessage("No trace file selected"); 00226 return false; 00227 } 00228 00229 if (!mConfig.HasNumberOfInputs() || mConfig.GetNumberOfInputs() < 1.) 00230 { 00231 AddConfigErrorMessage("The number of inputs has not been configured."); 00232 return false; 00233 } 00234 00235 mInputs.Resize(int(mConfig.GetNumberOfInputs()), "Input", this); 00236 return true; 00237 } 00238 00239 bool ControlTraceWriter::ConcreteStop() 00240 { 00241 XMLStorage::Dump(mTrace, "trace", mConfig.GetTraceFile().c_str()); 00242 mTrace.Clear(); 00243 return true; 00244 } 00245 00246 bool ControlTraceWriter::Do() 00247 { 00248 mTrace.Append(ControlTraceEvent(mInputs)); 00249 return true; 00250 } 00251 00252 00253 void ControlTraceWriter::RemoveOldControls() 00254 { 00255 mInputs.Clear(); 00256 GetInControls().Clear(); 00257 } 00258 00259 /* ================================================================= */ 00260 00261 void ControlTraceReaderConfig::DefaultInit() 00262 { 00263 AddAll(); 00264 UpdateData(); 00265 } 00266 00267 ControlTraceReader::ControlTraceReader() 00268 { 00269 Configure(mConfig); 00270 } 00271 00272 ControlTraceReader::ControlTraceReader( const ProcessingConfig& cfg ) 00273 { 00274 Configure( cfg ); 00275 } 00276 00277 ControlTraceReader::~ControlTraceReader() 00278 { 00279 RemoveOldControls(); 00280 } 00281 00282 bool ControlTraceReader::ConcreteConfigure( const ProcessingConfig& cfgObj ) 00283 { 00284 RemoveOldControls(); 00285 CopyAsConcreteConfig( mConfig, cfgObj ); 00286 if ( !mConfig.HasTraceFile() ) 00287 { 00288 AddConfigErrorMessage("No 'trace file' was specified in the configuration!"); 00289 return false; 00290 } 00291 00292 ControlTraceInFilename &file = mConfig.GetTraceFile(); 00293 if ( file == "" ) 00294 { 00295 AddConfigErrorMessage("No trace file selected"); 00296 return false; 00297 } 00298 00299 try { 00300 XMLStorage::Restore(mTrace, mConfig.GetTraceFile().c_str()); 00301 } 00302 catch (XmlStorageErr &e) 00303 { 00304 AddConfigErrorMessage(e.what()); 00305 return false; 00306 } 00307 00308 if (mTrace.GetNumberOfControls() < 1) 00309 { 00310 AddConfigErrorMessage("The specified file does not contain any control events."); 00311 return false; 00312 } 00313 00314 mOutputs.Resize(mTrace.GetNumberOfControls(), "Output", this); 00315 return true; 00316 } 00317 00318 bool ControlTraceReader::ConcreteStart() 00319 { 00320 mIterator = mTrace.Begin(); 00321 mRepeatCounter = 0; 00322 return true; 00323 } 00324 00325 bool ControlTraceReader::Do() 00326 { 00327 if (mIterator == mTrace.End()) 00328 return false; 00329 00330 const ControlTraceEvent &event = *mIterator; 00331 00332 // if this is the zeroth (first) step, update the controls 00333 if (!mRepeatCounter) 00334 event.UpdateControls(mOutputs); 00335 00336 // if this step completes the current event, advance and reset counter 00337 if (mRepeatCounter++ == event.Repeats()) { 00338 mIterator++; 00339 mRepeatCounter = 0; 00340 } 00341 00342 return true; 00343 } 00344 00345 void ControlTraceReader::RemoveOldControls() 00346 { 00347 mOutputs.Clear(); 00348 GetOutControls().Clear(); 00349 } 00350 00351 /* ================================================================== */ 00352 00353 00354 00355 } // CLAM namespace 00356