Index: CLAM/src/Processing/Controls/ControlTrace.cxx =================================================================== --- CLAM/src/Processing/Controls/ControlTrace.cxx (revision 0) +++ CLAM/src/Processing/Controls/ControlTrace.cxx (revision 0) @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) + * UNIVERSITAT POMPEU FABRA + * Copyright (c) 2007 Superlucidity Services, LLC and Zachary T Welch + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "ControlTrace.hxx" +#include "Factory.hxx" +#include "XMLAdapter.hxx" +#include "XMLStorage.hxx" +#include "XMLIterableAdapter.hxx" +#include "XMLAdapter.hxx" +#include "XmlStorageErr.hxx" +#include + +namespace CLAM +{ + +ControlTraceEvent::ControlTraceEvent(const ControlTraceEvent &obj) + : mValues(obj.mValues) +{ +} +ControlTraceEvent::ControlTraceEvent(const InControlArray &inputs) +{ + mValues.resize(inputs.Size()); + for (int i = 0; i < inputs.Size(); i++) + mValues[i] = inputs[i].GetLastValue(); +} + +void ControlTraceEvent::UpdateControls(OutControlArray &outputs) const +{ + for (int i = 0; i < outputs.Size(); i++) + outputs[i].SendControl(mValues[i]); +} + +void ControlTraceEvent::LoadFrom( Storage& storage ) +{ + XMLIterableAdapter adapter(mValues, "value", "values", true); + storage.Load(adapter); +} + +void ControlTraceEvent::StoreOn( Storage& storage ) const +{ + XMLIterableAdapter adapter(mValues, "value", "values", true); + storage.Store(adapter); +} + +const ControlTraceEvent& ControlTraceEvent::operator=(const ControlTraceEvent& obj) +{ + mValues = obj.mValues; + return *this; +} + +/* ================================================================== */ + +ControlTraceData::ControlTraceData(const ControlTraceData &obj) + : mEvents(obj.mEvents) +{ +} + +void ControlTraceData::LoadFrom( Storage& storage ) +{ + XMLIterableAdapter adapter(mEvents, "event", "events", true); + storage.Load(adapter); +} + +void ControlTraceData::StoreOn( Storage& storage ) const +{ + XMLIterableAdapter adapter(mEvents, "event", "events", true); + storage.Store(adapter); +} + +/* ================================================================== */ + +ControlTraceFile::ControlTraceFile( const ControlTraceFile& obj ) + : ConfigurableFile(obj) +{ +} + +const ControlTraceFile& ControlTraceFile::operator=( const ControlTraceFile& obj ) +{ + this->ConfigurableFile::operator=(obj); + return *this; +} + +ControlTraceFile::~ControlTraceFile() +{ +} + +const FileFormatFilterList &ControlTraceFile::GetFormatFilterList() const +{ + static FileFormatFilterList traceFormatFilterList; + if (traceFormatFilterList.size()) + return traceFormatFilterList; + FileFormatFilter filter("CLAM Control Traces (v0)", "*.clamtrace"); + traceFormatFilterList.push_back(filter); + return traceFormatFilterList; +} + + +void ControlTraceFileSource::LocationUpdated() +{ + // TODO: implement me +} +void ControlTraceFileSource::LoadTrace(ControlTraceData &data) const +{ + XMLStorage::Restore(data, GetLocation().c_str()); +} + + +void ControlTraceFileTarget::LocationUpdated() +{ + // TODO: implement me +} +void ControlTraceFileTarget::SaveTrace(const ControlTraceData &data) const +{ + XMLStorage::Dump(data, "trace", GetLocation().c_str()); +} + +/* ================================================================= */ + +void ControlTraceWriterConfig::DefaultInit() +{ + AddAll(); + UpdateData(); + SetNumberOfInputs(1.); +} + +ControlTraceWriter::ControlTraceWriter() +{ + Configure(mConfig); +} + +ControlTraceWriter::ControlTraceWriter( const ProcessingConfig& cfg ) +{ + Configure( cfg ); +} + +ControlTraceWriter::~ControlTraceWriter() +{ + RemoveOldControls(); +} + +bool ControlTraceWriter::ConcreteConfigure( const ProcessingConfig& cfgObj ) +{ + RemoveOldControls(); + CopyAsConcreteConfig( mConfig, cfgObj ); + if ( !mConfig.HasTraceFile() ) + { + AddConfigErrorMessage("No 'trace file' was specified in the configuration!"); + return false; + } + + ControlTraceFileTarget &file = mConfig.GetTraceFile(); + if ( file.GetLocation() == "" ) + { + AddConfigErrorMessage("No trace file selected"); + return false; + } + + if (!mConfig.HasNumberOfInputs() || mConfig.GetNumberOfInputs() < 1.) + { + AddConfigErrorMessage("The number of inputs has not been configured."); + return false; + } + + mInputs.Resize(int(mConfig.GetNumberOfInputs()), "Inputs", this); + return true; +} + +bool ControlTraceWriter::ConcreteStop() +{ + mConfig.GetTraceFile().SaveTrace(mTrace); + mTrace.Clear(); + return true; +} + +bool ControlTraceWriter::Do() +{ + mTrace.Append(ControlTraceEvent(mInputs)); + return true; +} + + +void ControlTraceWriter::RemoveOldControls() +{ + mInputs.Clear(); + GetInControls().Clear(); +} + +/* ================================================================= */ + +void ControlTraceReaderConfig::DefaultInit() +{ + AddAll(); + UpdateData(); +} + +ControlTraceReader::ControlTraceReader() +{ + Configure(mConfig); +} + +ControlTraceReader::ControlTraceReader( const ProcessingConfig& cfg ) +{ + Configure( cfg ); +} + +ControlTraceReader::~ControlTraceReader() +{ + RemoveOldControls(); +} + +bool ControlTraceReader::ConcreteConfigure( const ProcessingConfig& cfgObj ) +{ + RemoveOldControls(); + CopyAsConcreteConfig( mConfig, cfgObj ); + if ( !mConfig.HasTraceFile() ) + { + AddConfigErrorMessage("No 'trace file' was specified in the configuration!"); + return false; + } + + ControlTraceFileSource &file = mConfig.GetTraceFile(); + if ( file.GetLocation() == "" ) + { + AddConfigErrorMessage("No trace file selected"); + return false; + } + + try { + mConfig.GetTraceFile().LoadTrace(mTrace); + } + catch (XmlStorageErr &e) + { + AddConfigErrorMessage(e.what()); + return false; + } + + if (mTrace.GetNumberOfControls() < 1) + { + AddConfigErrorMessage("The specified file does not contain any control events."); + return false; + } + + mOutputs.Resize(mTrace.GetNumberOfControls(), "Outputs", this); + return true; +} + +bool ControlTraceReader::ConcreteStart() +{ + mIterator = mTrace.Begin(); + return true; +} + +bool ControlTraceReader::Do() +{ + if (mIterator == mTrace.End()) + return false; + + const ControlTraceEvent &event = *mIterator++; + event.UpdateControls(mOutputs); + return true; +} + +void ControlTraceReader::RemoveOldControls() +{ + mOutputs.Clear(); + GetOutControls().Clear(); +} + +/* ================================================================== */ + +namespace detail +{ +typedef CLAM::Factory ProcessingFactory; +static ProcessingFactory::Registrator + regtControlTraceReader("ControlTraceReader"); +static ProcessingFactory::Registrator + regtControlTraceWriter("ControlTraceWriter"); +} + + +} // CLAM namespace + Index: CLAM/src/Processing/Controls/ControlTrace.hxx =================================================================== --- CLAM/src/Processing/Controls/ControlTrace.hxx (revision 0) +++ CLAM/src/Processing/Controls/ControlTrace.hxx (revision 0) @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) + * UNIVERSITAT POMPEU FABRA + * Copyright (c) 2007 Superlucidity Services, LLC and Zachary T Welch + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef CONTROL_TRACE_HXX +#define CONTROL_TRACE_HXX + +#include +#include +#include +#include +#include +#include + +class Network; + +struct fann; + +namespace CLAM +{ + +class ControlTraceEvent : public Component { +public: + typedef std::vector ValueArray; + + ControlTraceEvent() { } + ControlTraceEvent(const InControlArray &inputs); + ControlTraceEvent(const ControlTraceEvent &event); + const ControlTraceEvent& operator=( const ControlTraceEvent& ); + virtual ~ControlTraceEvent() { } + + const char *GetClassName() const { return "ControlTraceEvent"; } + + void LoadFrom( Storage& storage); + void StoreOn( Storage& storage ) const; + + size_t Size() const { return mValues.size(); } + + void UpdateControls(OutControlArray &array) const; + +private: + ValueArray mValues; +}; + + +class ControlTraceData : public Component { +public: + typedef std::list EventList; + virtual ~ControlTraceData() { } + + ControlTraceData() { } + ControlTraceData(const ControlTraceData &obj); + + const char *GetClassName() const { return "ControlTraceData"; } + + void LoadFrom( Storage& storage); + void StoreOn( Storage& storage ) const; + + size_t GetNumberOfControls() const { return mEvents.front().Size(); } + + void Append(const ControlTraceEvent &data) { mEvents.push_back(data); } + + EventList::iterator Begin() { return mEvents.begin(); } + EventList::iterator End() { return mEvents.end(); } + + void Clear() { mEvents.clear(); } + +protected: + EventList mEvents; +}; + + +class ControlTraceFile : public ConfigurableFile +{ +public: + ControlTraceFile() { } + ControlTraceFile( const ControlTraceFile& ); + const ControlTraceFile& operator=( const ControlTraceFile& ); + virtual ~ControlTraceFile(); + + const char* GetClassName() const { return "ControlTraceFile"; } + const char* GetGroupName() const { return "control trace"; } + const FileFormatFilterList &GetFormatFilterList() const; +}; + +class ControlTraceFileSource : public ControlTraceFile +{ +public: + ControlTraceFileSource() { } + void LoadTrace(ControlTraceData &trace) const; + bool GetWriteMode() { return false; } + const char* GetClassName() const { return "ControlTraceFileSource"; } +protected: + void LocationUpdated(); +}; + +class ControlTraceFileTarget : public ControlTraceFile +{ +public: + ControlTraceFileTarget() { } + void SaveTrace(const ControlTraceData &trace) const; + bool GetWriteMode() { return true; } + const char* GetClassName() const { return "ControlTraceFileTarget"; } +protected: + void LocationUpdated(); +}; + + +class ControlTraceReaderConfig : public ProcessingConfig { + DYNAMIC_TYPE_USING_INTERFACE + ( ControlTraceReaderConfig, 1, ProcessingConfig ); + + DYN_ATTRIBUTE( 0, public, ControlTraceFileSource, TraceFile ); + +protected: + void DefaultInit(); +}; + +class ControlTraceReader : public Processing +{ +public: + ControlTraceReader(); + ControlTraceReader( const ProcessingConfig& cfg ); + virtual ~ControlTraceReader(); + + const char* GetClassName() const { return "ControlTraceReader"; } + const ProcessingConfig& GetConfig() const { return mConfig; } + + bool Do(); + +protected: // methods + bool ConcreteConfigure( const ProcessingConfig& cfgObject ); + bool ConcreteStart(); + void RemoveOldControls(); + +protected: // attributes + ControlTraceReaderConfig mConfig; + ControlTraceData mTrace; + ControlTraceData::EventList::iterator mIterator; + OutControlArray mOutputs; +}; + +class ControlTraceWriterConfig : public ProcessingConfig { + DYNAMIC_TYPE_USING_INTERFACE + ( ControlTraceWriterConfig, 2, ProcessingConfig ); + + DYN_ATTRIBUTE( 0, public, ControlTraceFileTarget, TraceFile ); + DYN_ATTRIBUTE( 1, public, TData, NumberOfInputs ); + +protected: + void DefaultInit(); +}; + +class ControlTraceWriter : public Processing +{ +public: + ControlTraceWriter(); + ControlTraceWriter( const ProcessingConfig& cfg ); + virtual ~ControlTraceWriter(); + + const char* GetClassName() const { return "ControlTraceWriter"; } + const ProcessingConfig& GetConfig() const { return mConfig; } + + bool Do(); + +protected: // methods + bool ConcreteConfigure( const ProcessingConfig& cfgObject ); + bool ConcreteStop(); + void RemoveOldControls(); + +protected: // attributes + ControlTraceWriterConfig mConfig; + ControlTraceData mTrace; + InControlArray mInputs; +}; + + + +} // CLAM namespace + +#endif Index: NetworkEditor/src/ProcessingTree.cxx =================================================================== --- NetworkEditor/src/ProcessingTree.cxx (revision 9990) +++ NetworkEditor/src/ProcessingTree.cxx (working copy) @@ -67,6 +67,8 @@ "ControlSource", "ControlSink", "ControlPrinter", + "ControlTraceReader", + "ControlTraceWriter", "ControlScaler", "AutoPanner", "FlagControl", Index: NetworkEditor/src/ProcessingBox.cxx =================================================================== --- NetworkEditor/src/ProcessingBox.cxx (revision 9990) +++ NetworkEditor/src/ProcessingBox.cxx (working copy) @@ -85,7 +85,7 @@ if (className=="ControlSurface") return new ControlSurfaceWidget(processing); - if (className=="ControlPrinter") + if (className=="ControlPrinter" || className=="ControlTraceWriter") return new ControlPrinterWidget(processing); if (className=="Vumeter") Index: NetworkEditor/src/RegisterConfiguratorLaunchers.cxx =================================================================== --- NetworkEditor/src/RegisterConfiguratorLaunchers.cxx (revision 9990) +++ NetworkEditor/src/RegisterConfiguratorLaunchers.cxx (working copy) @@ -66,6 +66,7 @@ #include #include "ControlSurface.hxx" #include +#include #include //MIDI @@ -129,6 +130,8 @@ STANDARD_PROCESSING_CONFIG_REGISTER(ControlScalerConfig); STANDARD_PROCESSING_CONFIG_REGISTER(ControlSourceConfig); STANDARD_PROCESSING_CONFIG_REGISTER(ControlSurfaceConfig); +STANDARD_PROCESSING_CONFIG_REGISTER(ControlTraceReaderConfig); +STANDARD_PROCESSING_CONFIG_REGISTER(ControlTraceWriterConfig); STANDARD_PROCESSING_CONFIG_REGISTER(FlagControlConfig); STANDARD_PROCESSING_CONFIG_REGISTER(Fundamental2ControlConfig); STANDARD_PROCESSING_CONFIG_REGISTER(OneOverFConfig); Index: CLAM/test/FunctionalTests/ProcessingTests/TestControlTraces.cxx =================================================================== --- CLAM/test/FunctionalTests/ProcessingTests/TestControlTraces.cxx (revision 0) +++ CLAM/test/FunctionalTests/ProcessingTests/TestControlTraces.cxx (revision 0) @@ -0,0 +1,279 @@ +#include +#include "cppUnitHelper.hxx" +#include +#include "similarityHelper.hxx" +#include +#include + +namespace CLAMTest +{ + +class ControlTraceReaderFunctionalTest; +CPPUNIT_TEST_SUITE_REGISTRATION( ControlTraceReaderFunctionalTest ); + +class ControlTraceReaderFunctionalTest + : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( ControlTraceReaderFunctionalTest ); + + // Configuration values checking tests + CPPUNIT_TEST( testConfigure_ReturnsTrueWithJustFilename ); + CPPUNIT_TEST( testConfigure_ReturnsFalseWithoutTraceFileInConfig ); + CPPUNIT_TEST( testConfigure_ReturnsTrueWhenFileExists ); + CPPUNIT_TEST( testConfigure_ReturnsFalseWhenFileDoesNotExist ); + CPPUNIT_TEST( testConfigure_ReturnsTrueWhenTraceEventsExist ); + CPPUNIT_TEST( testConfigure_ReturnsFalseWhenTraceFileIsEmpty ); + +#if 0 + // File reading checking + CPPUNIT_TEST( testDo_PCM_JustOneFrameFromMonoFile ); + CPPUNIT_TEST( testDo_PCM_JustTwoFramesFromMonoFile ); + CPPUNIT_TEST( testDo_PCM_JustOneFrameFromStereoFile ); + CPPUNIT_TEST( testDo_PCM_JustTwoFramesFromStereoFile ); + + CPPUNIT_TEST( testDo_OggVorbis_JustOneFrameFromStereoFile ); + CPPUNIT_TEST( testDo_OggVorbis_JustTwoFramesFromStereoFile ); + + CPPUNIT_TEST( test_MpegAudioFiles_AreDecoded_OK ); + + CPPUNIT_TEST( testDo_JustTwoFramesBeginTimesAreRight ); + CPPUNIT_TEST( testDo_JustOneFrame_SampleRateIsOK ); + + CPPUNIT_TEST( test_WindowsMedia_WAVE_File ); +#endif + + CPPUNIT_TEST_SUITE_END(); + +protected: // Attributes + + std::string mPathToTestData; + std::string mInputFileName; + std::string mEmptyFileName; + +protected: // Auxiliary methods + +public: // TestFixture interface + + void setUp() + { + mPathToTestData = GetTestDataDirectory() + "ControlTraceReader"; + mInputFileName = mPathToTestData + "Input.clamtrace"; + mEmptyFileName = mPathToTestData + "Empty.clamtrace"; + } + + void tearDown() + { + } + +private: // tests cases + + void testConfigure_ReturnsTrueWithJustFilename() + { + CLAM::ControlTraceFileSource file; + file.SetLocation(mInputFileName); + + CLAM::ControlTraceReaderConfig cfg; + cfg.SetTraceFile( file ); + + CLAM::ControlTraceReader proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( true, configResult ); + } + + void testConfigure_ReturnsFalseWithoutTraceFileInConfig() + { + CLAM::ControlTraceReaderConfig cfg; + cfg.RemoveTraceFile(); + cfg.UpdateData(); + + CLAM::ControlTraceReader proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( false, configResult ); + } + + void testConfigure_ReturnsTrueWhenFileExists() + { + CLAM::ControlTraceFileSource file; + file.SetLocation(mInputFileName); + CLAM::ControlTraceReaderConfig cfg; + cfg.SetTraceFile( file ); + + CLAM::ControlTraceReader proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( true, configResult ); + } + + void testConfigure_ReturnsFalseWhenFileDoesNotExist() + { + CLAM::ControlTraceFileSource file; + file.SetLocation(mPathToTestData + + std::string( "missing-file.clamtrace" ) ); + + CLAM::ControlTraceReaderConfig cfg; + cfg.SetTraceFile( file ); + + CLAM::ControlTraceReader proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( false, configResult ); + } + + void testConfigure_ReturnsTrueWhenTraceEventsExist() + { + CLAM::ControlTraceFileSource file; + file.SetLocation(mInputFileName); + + CLAM::ControlTraceReaderConfig cfg; + cfg.SetTraceFile( file ); + + CLAM::ControlTraceReader proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( true, configResult ); + } + + void testConfigure_ReturnsFalseWhenTraceFileIsEmpty() + { + CLAM::ControlTraceFileSource file; + file.SetLocation( mEmptyFileName ); + + CLAM::ControlTraceReaderConfig cfg; + cfg.SetTraceFile( file ); + + CLAM::ControlTraceReader proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( false, configResult ); + + } + +}; + +class ControlTraceWriterFunctionalTest; +CPPUNIT_TEST_SUITE_REGISTRATION( ControlTraceWriterFunctionalTest ); + +class ControlTraceWriterFunctionalTest + : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( ControlTraceWriterFunctionalTest ); + + // Configuration values checking tests + CPPUNIT_TEST( testConfigure_ReturnsTrueWithJustFilename ); + CPPUNIT_TEST( testConfigure_ReturnsFalseWithoutTraceFileInConfig ); + CPPUNIT_TEST( testConfigure_ReturnsTrueWhenFileExists ); + CPPUNIT_TEST( testConfigure_ReturnsFalseWithoutInputsInConfig ); + CPPUNIT_TEST( testConfigure_ReturnsFalseWhenConfiguredWithNoInputs ); + + CPPUNIT_TEST_SUITE_END(); + +protected: // Attributes + + std::string mPathToTestData; + std::string mOutputFileName; + +protected: // Auxiliary methods + +public: // TestFixture interface + + void setUp() + { + mPathToTestData = GetTestDataDirectory() + "ControlTraceWriter"; + mOutputFileName = mPathToTestData + "Output.clamtrace"; + } + + void tearDown() + { + } + +private: // tests cases + + void testConfigure_ReturnsTrueWithJustFilename() + { + CLAM::ControlTraceFileTarget file; + file.SetLocation(mOutputFileName); + + CLAM::ControlTraceWriterConfig cfg; + cfg.SetTraceFile( file ); + + CLAM::ControlTraceWriter proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( true, configResult ); + } + + void testConfigure_ReturnsFalseWithoutTraceFileInConfig() + { + CLAM::ControlTraceWriterConfig cfg; + cfg.RemoveTraceFile(); + cfg.UpdateData(); + + CLAM::ControlTraceWriter proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( false, configResult ); + } + + void testConfigure_ReturnsTrueWhenFileExists() + { + CLAM::ControlTraceFileTarget file; + file.SetLocation(mOutputFileName); + + CLAM::ControlTraceWriterConfig cfg; + cfg.SetTraceFile( file ); + + CLAM::ControlTraceWriter proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( true, configResult ); + } + + void testConfigure_ReturnsFalseWithoutInputsInConfig() + { + CLAM::ControlTraceFileTarget file; + file.SetLocation( mOutputFileName ); + + CLAM::ControlTraceWriterConfig cfg; + cfg.RemoveNumberOfInputs(); + cfg.UpdateData(); + cfg.SetTraceFile( file ); + + CLAM::ControlTraceWriter proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( false, configResult ); + + } + + void testConfigure_ReturnsFalseWhenConfiguredWithNoInputs() + { + CLAM::ControlTraceFileTarget file; + file.SetLocation( mOutputFileName ); + + CLAM::ControlTraceWriterConfig cfg; + cfg.SetTraceFile( file ); + cfg.SetNumberOfInputs( 0 ); + + CLAM::ControlTraceWriter proc; + + bool configResult = proc.Configure( cfg ); + + CPPUNIT_ASSERT_EQUAL( false, configResult ); + + } +}; + +} +