00001 #ifdef USE_LADSPA
00002
00003 #include "LadspaWrapper.hxx"
00004
00005 #include "OSDefines.hxx"
00006 #include "CLAM_Math.hxx"
00007 #include "Factory.hxx"
00008 #include "AudioInPort.hxx"
00009 #include "AudioOutPort.hxx"
00010 #include "InControl.hxx"
00011 #include "OutControl.hxx"
00012 #include <ctime>
00013 #include <cstdlib>
00014 #include <dlfcn.h>
00015
00016 namespace CLAM
00017 {
00018
00019
00020 LadspaWrapper::LadspaWrapper( const Config & cfg)
00021 : _instance(0)
00022 , _descriptor(0)
00023 , _sharedObject(0)
00024 , _libraryFileName("")
00025 , _bufferSize(0)
00026 {
00027 Configure(cfg);
00028 }
00029
00030 LadspaWrapper::LadspaWrapper( 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 LadspaWrapper::~LadspaWrapper()
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 LadspaWrapper::ConcreteStart()
00064 {
00065 if (_descriptor->activate)
00066 _descriptor->activate(_instance);
00067 return true;
00068 }
00069 bool LadspaWrapper::ConcreteStop()
00070 {
00071 if (_descriptor->deactivate)
00072 _descriptor->deactivate(_instance);
00073 return true;
00074 }
00075
00076 bool LadspaWrapper::Do()
00077 {
00078 DoUpdatePortsPointers();
00079
00080 _descriptor->run(_instance, _bufferSize );
00081
00082 for(unsigned int i=0;i<_outputControlValues.size();i++)
00083 SendFloatToOutControl(*this, i, _outputControlValues[i]);
00084
00085 for(unsigned int i=0;i<_inputPorts.size();i++)
00086 _inputPorts[i]->Consume();
00087 for(unsigned int i=0;i<outputPorts.size();i++)
00088 outputPorts[i]->Produce();
00089 return true;
00090 }
00091 bool LadspaWrapper::LoadLibraryFunction(const std::string& libraryFileName, unsigned index, const std::string& factoryKey)
00092 {
00093
00094 _sharedObject = RunTimeLibraryLoader::LazyLoadLibrary(libraryFileName);
00095 LADSPA_Descriptor_Function function = (LADSPA_Descriptor_Function)dlsym(_sharedObject, "ladspa_descriptor");
00096 if(!function)
00097 {
00098 std::string error = "[LADSPA] can't open library: " + libraryFileName;
00099 throw ErrFactory(error.c_str());
00100 }
00101 _descriptor = function(index);
00102 _instance = _descriptor->instantiate(_descriptor, 44100);
00103 _factoryKey = factoryKey;
00104 _libraryFileName=libraryFileName;
00105 return true;
00106 }
00107 bool LadspaWrapper::ConcreteConfigure(const ProcessingConfig&)
00108 {
00109 _bufferSize = BackendBufferSize();
00110 ConfigurePortsAndControls();
00111 ConfigureControlsPointers();
00112 return true;
00113 }
00114 void LadspaWrapper::RemovePortsAndControls()
00115 {
00116 std::vector< AudioInPort* >::iterator itInPort;
00117 for(itInPort=_inputPorts.begin(); itInPort!=_inputPorts.end(); itInPort++)
00118 delete *itInPort;
00119 _inputPorts.clear();
00120
00121 std::vector< AudioOutPort* >::iterator itOutPort;
00122 for(itOutPort=outputPorts.begin(); itOutPort!=outputPorts.end(); itOutPort++)
00123 delete *itOutPort;
00124 outputPorts.clear();
00125
00126 std::vector< InControl* >::iterator itInControl;
00127 for(itInControl=_inputControls.begin(); itInControl!=_inputControls.end(); itInControl++)
00128 delete *itInControl;
00129 _inputControls.clear();
00130
00131 std::vector< OutControl* >::iterator itOutControl;
00132 for(itOutControl=_outputControls.begin(); itOutControl!=_outputControls.end(); itOutControl++)
00133 delete *itOutControl;
00134 _outputControls.clear();
00135
00136 _outputControlValues.clear();
00137
00138 GetInPorts().Clear();
00139 GetOutPorts().Clear();
00140 GetInControls().Clear();
00141 GetOutControls().Clear();
00142 }
00143
00144 void LadspaWrapper::ConfigurePortsAndControls()
00145 {
00146 RemovePortsAndControls();
00147 for(unsigned int i=0;i<_descriptor->PortCount;i++)
00148 {
00149 const LADSPA_PortDescriptor portDescriptor = _descriptor->PortDescriptors[i];
00150
00151 if(LADSPA_IS_PORT_INPUT(portDescriptor) && LADSPA_IS_PORT_AUDIO(portDescriptor))
00152 {
00153 AudioInPort * port = new AudioInPort(_descriptor->PortNames[i],this );
00154 port->SetSize( _bufferSize );
00155 _inputPorts.push_back(port);
00156 }
00157
00158 if(LADSPA_IS_PORT_OUTPUT(portDescriptor) && LADSPA_IS_PORT_AUDIO(portDescriptor))
00159 {
00160 AudioOutPort * port = new AudioOutPort(_descriptor->PortNames[i],this );
00161 port->SetSize( _bufferSize );
00162 outputPorts.push_back(port);
00163 }
00164
00165
00166 if(LADSPA_IS_PORT_INPUT(portDescriptor) && LADSPA_IS_PORT_CONTROL(portDescriptor))
00167 {
00168 InControl * control = new InControl(_descriptor->PortNames[i], this);
00169
00170 const LADSPA_PortRangeHint & hint = _descriptor->PortRangeHints[i];
00171 bool isBounded = (
00172 LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
00173 LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)
00174 );
00175 if (isBounded)
00176 {
00177 control->SetBounds( hint.LowerBound, hint.UpperBound );
00178 control->DoControl( control->DefaultValue() );
00179 }
00180 _inputControls.push_back(control);
00181 }
00182
00183 if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && LADSPA_IS_PORT_CONTROL(portDescriptor))
00184 {
00185 OutControl * control = new OutControl(_descriptor->PortNames[i], this);
00186 _outputControlValues.push_back(LADSPA_Data());
00187 _outputControls.push_back(control);
00188 }
00189 }
00190 }
00191
00192 void LadspaWrapper::ConfigureControlsPointers()
00193 {
00194 int inControlIndex = 0;
00195 int outControlIndex = 0;
00196 for(unsigned int i=0;i<_descriptor->PortCount;i++)
00197 {
00198 const LADSPA_PortDescriptor portDescriptor = _descriptor->PortDescriptors[i];
00199 if (LADSPA_IS_PORT_CONTROL(portDescriptor))
00200 {
00201 if (LADSPA_IS_PORT_INPUT(portDescriptor))
00202 {
00203 LADSPA_Data* inControlValue = const_cast<LADSPA_Data*>( &(_inputControls[inControlIndex]->GetLastValue()) );
00204 _descriptor->connect_port(_instance, i, inControlValue);
00205 inControlIndex++;
00206 }
00207 else
00208 _descriptor->connect_port(_instance, i, & _outputControlValues[outControlIndex++]);
00209 }
00210 }
00211
00212 }
00213
00214 void LadspaWrapper::DoUpdatePortsPointers()
00215 {
00216 int inPortIndex = 0;
00217 int outPortIndex = 0;
00218 for(unsigned int i=0;i<_descriptor->PortCount;i++)
00219 {
00220 const LADSPA_PortDescriptor portDescriptor = _descriptor->PortDescriptors[i];
00221 if (!LADSPA_IS_PORT_CONTROL(portDescriptor))
00222 {
00223 if (LADSPA_IS_PORT_INPUT(portDescriptor))
00224 _descriptor->connect_port(_instance, i, _inputPorts[inPortIndex++]->GetAudio().GetBuffer().GetPtr());
00225 else
00226 _descriptor->connect_port(_instance, i, outputPorts[outPortIndex++]->GetAudio().GetBuffer().GetPtr());
00227 }
00228 }
00229
00230
00231 }
00232
00233 const char * LadspaWrapper::GetClassName() const
00234 {
00235 return _factoryKey.c_str();
00236 }
00237
00238 }
00239
00240 #endif // USE_LADSPA
00241