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