LadspaWrapperBuffer.cxx
Go to the documentation of this file.00001 #ifdef USE_LADSPA
00002
00003 #include "LadspaWrapperBuffer.hxx"
00004
00005 #include "OSDefines.hxx"
00006 #include "CLAM_Math.hxx"
00007 #include "Factory.hxx"
00008 #include "InPort.hxx"
00009 #include "OutPort.hxx"
00010 #include "InControl.hxx"
00011 #include "OutControl.hxx"
00012 #include "Audio.hxx"
00013 #include <ctime>
00014 #include <cstdlib>
00015
00016 namespace CLAM
00017 {
00018
00019
00020 LadspaWrapperBuffer::LadspaWrapperBuffer( const Config & cfg)
00021 : _instance(0)
00022 , _descriptor(0)
00023 , _sharedObject(0)
00024 , _libraryFileName("")
00025 {
00026 Configure(cfg);
00027 }
00028
00029 LadspaWrapperBuffer::LadspaWrapperBuffer( const std::string& libraryFileName, unsigned index, const std::string& key )
00030 : _instance(0)
00031 , _descriptor(0)
00032 , _sharedObject(0)
00033 , _libraryFileName("")
00034 {
00035
00036 Config cfg;
00037 LoadLibraryFunction( libraryFileName, index, key);
00038 Configure(cfg);
00039 }
00040
00041 LadspaWrapperBuffer::~LadspaWrapperBuffer()
00042 {
00043
00044 if (_instance)
00045 {
00046 if (_descriptor->cleanup) _descriptor->cleanup(_instance);
00047
00048 }
00049 RemovePortsAndControls();
00050
00051 if (_sharedObject && (_libraryFileName!=""))
00052 {
00053 if (RunTimeLibraryLoader::ReleaseLibraryHandler(_sharedObject,_libraryFileName))
00054 {
00055 std::cout<<"[LADSPA] error unloading library handle of: "<<_libraryFileName<<std::endl;
00056 std::cout<<RunTimeLibraryLoader::LibraryLoadError()<<std::endl;
00057 }
00058 }
00059 }
00060
00061 bool LadspaWrapperBuffer::ConcreteStart()
00062 {
00063 if (_descriptor->activate)
00064 _descriptor->activate(_instance);
00065 return true;
00066 }
00067 bool LadspaWrapperBuffer::ConcreteStop()
00068 {
00069 if (_descriptor->deactivate)
00070 _descriptor->deactivate(_instance);
00071 return true;
00072 }
00073
00074 bool LadspaWrapperBuffer::Do()
00075 {
00076 _bufferSize = _inputPorts[0]->GetData().GetSize();
00077
00078 bool eachInputPortUsingSameSize=true;
00079 for(unsigned int i=1;i<_inputPorts.size()&&eachInputPortUsingSameSize;i++)
00080 eachInputPortUsingSameSize = eachInputPortUsingSameSize && (_inputPorts[i-1]->GetData().GetSize() == _inputPorts[i]->GetData().GetSize());
00081
00082 CLAM_ASSERT(eachInputPortUsingSameSize, "Some InputPorts have not the same buffer size.");
00083
00084 for(unsigned int i=0;i<_outputPorts.size();i++)
00085 _outputPorts[i]->GetData().SetSize(_bufferSize);
00086
00087 DoUpdatePortsPointers();
00088 _descriptor->run(_instance, _bufferSize);
00089
00090 for(unsigned int i=0;i<_outputControlValues.size();i++)
00091 SendFloatToOutControl(*this, i, _outputControlValues[i]);
00092
00093 for(unsigned int i=0;i<_inputPorts.size();i++)
00094 {
00095 _inputPorts[i]->Consume();
00096 }
00097 for(unsigned int i=0;i<_outputPorts.size();i++)
00098 {
00099 _outputPorts[i]->Produce();
00100 }
00101 return true;
00102 }
00103 bool LadspaWrapperBuffer::LoadLibraryFunction(const std::string& libraryFileName, unsigned index, const std::string& factoryKey)
00104 {
00105
00106 _sharedObject = RunTimeLibraryLoader::LazyLoadLibrary(libraryFileName);
00107 LADSPA_Descriptor_Function function = (LADSPA_Descriptor_Function)RunTimeLibraryLoader::GetSymbol(_sharedObject, "ladspa_descriptor");
00108 if(!function)
00109 {
00110 std::string error = "[LADSPA] can't open library: " + libraryFileName;
00111 throw ErrFactory(error.c_str());
00112 }
00113 _descriptor = function(index);
00114 _instance = _descriptor->instantiate(_descriptor, 44100);
00115 _factoryKey = factoryKey;
00116 _libraryFileName=libraryFileName;
00117 return true;
00118 }
00119 bool LadspaWrapperBuffer::ConcreteConfigure(const ProcessingConfig&)
00120 {
00121 ConfigurePortsAndControls();
00122 ConfigureControlsPointers();
00123 return true;
00124 }
00125 void LadspaWrapperBuffer::RemovePortsAndControls()
00126 {
00127 std::vector< InPort<Audio>* >::iterator itInPort;
00128 for(itInPort=_inputPorts.begin(); itInPort!=_inputPorts.end(); itInPort++)
00129 delete *itInPort;
00130 _inputPorts.clear();
00131
00132 std::vector< OutPort<Audio>* >::iterator itOutPort;
00133 for(itOutPort=_outputPorts.begin(); itOutPort!=_outputPorts.end(); itOutPort++)
00134 delete *itOutPort;
00135 _outputPorts.clear();
00136
00137 std::vector< FloatInControl* >::iterator itInControl;
00138 for(itInControl=_inputControls.begin(); itInControl!=_inputControls.end(); itInControl++)
00139 delete *itInControl;
00140 _inputControls.clear();
00141
00142 std::vector< FloatOutControl* >::iterator itOutControl;
00143 for(itOutControl=_outputControls.begin(); itOutControl!=_outputControls.end(); itOutControl++)
00144 delete *itOutControl;
00145 _outputControls.clear();
00146
00147 _outputControlValues.clear();
00148
00149 GetInPorts().Clear();
00150 GetOutPorts().Clear();
00151 GetInControls().Clear();
00152 GetOutControls().Clear();
00153 }
00154
00155 void LadspaWrapperBuffer::ConfigurePortsAndControls()
00156 {
00157 RemovePortsAndControls();
00158 for(unsigned int i=0;i<_descriptor->PortCount;i++)
00159 {
00160 const LADSPA_PortDescriptor portDescriptor = _descriptor->PortDescriptors[i];
00161
00162 if(LADSPA_IS_PORT_INPUT(portDescriptor) && LADSPA_IS_PORT_AUDIO(portDescriptor))
00163 {
00164 InPort<Audio> * port = new InPort<Audio>(_descriptor->PortNames[i],this );
00165 port->SetSize( 1 );
00166 port->SetHop( 1 );
00167 _inputPorts.push_back(port);
00168 }
00169
00170 if(LADSPA_IS_PORT_OUTPUT(portDescriptor) && LADSPA_IS_PORT_AUDIO(portDescriptor))
00171 {
00172 OutPort<Audio> * port = new OutPort<Audio>(_descriptor->PortNames[i],this );
00173 port->SetSize( 1 );
00174 port->SetHop( 1 );
00175 _outputPorts.push_back(port);
00176 }
00177
00178
00179 if(LADSPA_IS_PORT_INPUT(portDescriptor) && LADSPA_IS_PORT_CONTROL(portDescriptor))
00180 {
00181 FloatInControl * control = new FloatInControl(_descriptor->PortNames[i], this);
00182
00183 const LADSPA_PortRangeHint & hint = _descriptor->PortRangeHints[i];
00184 bool isBounded = (
00185 LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
00186 LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)
00187 );
00188 if (isBounded)
00189 {
00190 control->SetBounds( hint.LowerBound, hint.UpperBound );
00191 control->DoControl( control->DefaultValue() );
00192 }
00193 _inputControls.push_back(control);
00194 }
00195
00196 if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && LADSPA_IS_PORT_CONTROL(portDescriptor))
00197 {
00198 FloatOutControl * control = new FloatOutControl(_descriptor->PortNames[i], this);
00199 _outputControlValues.push_back(LADSPA_Data());
00200 _outputControls.push_back(control);
00201 }
00202 }
00203 }
00204
00205 void LadspaWrapperBuffer::ConfigureControlsPointers()
00206 {
00207 int inControlIndex = 0;
00208 int outControlIndex = 0;
00209 for(unsigned int i=0;i<_descriptor->PortCount;i++)
00210 {
00211 const LADSPA_PortDescriptor portDescriptor = _descriptor->PortDescriptors[i];
00212 if (LADSPA_IS_PORT_CONTROL(portDescriptor))
00213 {
00214 if (LADSPA_IS_PORT_INPUT(portDescriptor))
00215 {
00216 LADSPA_Data* inControlValue = const_cast<LADSPA_Data*>( &(_inputControls[inControlIndex]->GetLastValue()) );
00217 _descriptor->connect_port(_instance, i, inControlValue);
00218 inControlIndex++;
00219 }
00220 else
00221 _descriptor->connect_port(_instance, i, & _outputControlValues[outControlIndex++]);
00222 }
00223 }
00224 }
00225
00226 void LadspaWrapperBuffer::DoUpdatePortsPointers()
00227 {
00228 int inPortIndex = 0;
00229 int outPortIndex = 0;
00230 for(unsigned int i=0;i<_descriptor->PortCount;i++)
00231 {
00232 const LADSPA_PortDescriptor portDescriptor = _descriptor->PortDescriptors[i];
00233 if (!LADSPA_IS_PORT_CONTROL(portDescriptor))
00234 {
00235 if (LADSPA_IS_PORT_INPUT(portDescriptor))
00236 _descriptor->connect_port(_instance, i, _inputPorts[inPortIndex++]->GetData().GetBuffer().GetPtr());
00237 else
00238 _descriptor->connect_port(_instance, i, _outputPorts[outPortIndex++]->GetData().GetBuffer().GetPtr());
00239 }
00240 }
00241 }
00242
00243 const char * LadspaWrapperBuffer::GetClassName() const
00244 {
00245 return _factoryKey.c_str();
00246 }
00247
00248 }
00249
00250 #endif // USE_LADSPA
00251