LadspaWrapper.cxx

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