LadspaWrapper.cxx

Go to the documentation of this file.
00001 #ifdef USE_LADSPA
00002 
00003 #include "LadspaWrapper.hxx"
00004 //#include <ladspa.h>
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         //std::cout<<"LadspaWrapper()"<<std::endl;
00038         Config cfg;
00039         LoadLibraryFunction( libraryFileName, index, key);
00040         Configure(cfg);
00041 }
00042 
00043 LadspaWrapper::~LadspaWrapper()
00044 {
00045         //std::cout<<"~LadspaWrapper()"<<std::endl;
00046         if (_instance)
00047         {
00048                 if (_descriptor->cleanup) _descriptor->cleanup(_instance);
00049                 //std::cout<<"_descriptor->cleanup called"<<std::endl;
00050         }
00051         RemovePortsAndControls();
00052         // if a library function was used, a handle is opened: close it
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         //std::cout<<"LadspaWrapper::LoadLibraryFunction("<<libraryFileName<<")"<<std::endl;
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                 // in port
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                 // out port
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                 // in control
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                 // out control
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)) // is audio port
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 } // namespace CLAM
00239 
00240 #endif // USE_LADSPA
00241 

Generated on Tue Aug 12 22:33:43 2008 for CLAM by  doxygen 1.5.5