CLAM-Development  1.4.0
LadspaWrapper.cxx
Go to the documentation of this file.
1 #ifdef USE_LADSPA
2 
3 #include "LadspaWrapper.hxx"
4 #include "OSDefines.hxx"
5 #include "CLAM_Math.hxx"
6 #include "Factory.hxx"
7 #include "AudioInPort.hxx"
8 #include "AudioOutPort.hxx"
9 #include "InControl.hxx"
10 #include "OutControl.hxx"
11 #include <ctime>
12 #include <cstdlib>
13 
14 namespace CLAM
15 {
16 
17 
18 LadspaWrapper::LadspaWrapper( const Config & cfg)
19  : _instance(0)
20  , _descriptor(0)
21  , _sharedObject(0)
22  , _libraryFileName("")
23  , _bufferSize(0)
24 {
25  Configure(cfg);
26 }
27 
28 LadspaWrapper::LadspaWrapper( const std::string& libraryFileName, unsigned index, const std::string& key )
29  : _instance(0)
30  , _descriptor(0)
31  , _sharedObject(0)
32  , _libraryFileName("")
33  , _bufferSize(0)
34 {
35  //std::cout<<"LadspaWrapper()"<<std::endl;
36  Config cfg;
37  LoadLibraryFunction( libraryFileName, index, key);
38  Configure(cfg);
39 }
40 
42 {
43  //std::cout<<"~LadspaWrapper()"<<std::endl;
44  if (_instance)
45  {
46  if (_descriptor->cleanup) _descriptor->cleanup(_instance);
47  //std::cout<<"_descriptor->cleanup called"<<std::endl;
48  }
49  RemovePortsAndControls();
50  // if a library function was used, a handle is opened: close it
51  if (_sharedObject && (_libraryFileName!=""))
52  {
53  if (RunTimeLibraryLoader::ReleaseLibraryHandler(_sharedObject,_libraryFileName))
54  {
55  std::cout<<"[LADSPA] error unloading library handle of: "<<_libraryFileName<<std::endl;
56  std::cout<<RunTimeLibraryLoader::LibraryLoadError()<<std::endl;
57  }
58  }
59 }
60 
62 {
63  if (_descriptor->activate)
64  _descriptor->activate(_instance);
65  return true;
66 }
68 {
69  if (_descriptor->deactivate)
70  _descriptor->deactivate(_instance);
71  return true;
72 }
73 
74 bool LadspaWrapper::Do()
75 {
76  DoUpdatePortsPointers();
77 
78  _descriptor->run(_instance, _bufferSize );
79 
80  for(unsigned int i=0;i<_outputControlValues.size();i++)
81  SendFloatToOutControl(*this, i, _outputControlValues[i]);
82 
83  for(unsigned int i=0;i<_inputPorts.size();i++)
84  _inputPorts[i]->Consume();
85  for(unsigned int i=0;i<_outputPorts.size();i++)
86  _outputPorts[i]->Produce();
87  return true;
88 }
89 bool LadspaWrapper::LoadLibraryFunction(const std::string& libraryFileName, unsigned index, const std::string& factoryKey)
90 {
91  //std::cout<<"LadspaWrapper::LoadLibraryFunction("<<libraryFileName<<")"<<std::endl;
92  _sharedObject = RunTimeLibraryLoader::LazyLoadLibrary(libraryFileName);
93  LADSPA_Descriptor_Function function = (LADSPA_Descriptor_Function)RunTimeLibraryLoader::GetSymbol(_sharedObject, "ladspa_descriptor");
94  if(!function)
95  {
96  std::string error = "[LADSPA] can't open library: " + libraryFileName;
97  throw ErrFactory(error.c_str());
98  }
99  _descriptor = function(index);
100  _instance = _descriptor->instantiate(_descriptor, 44100);
101  _factoryKey = factoryKey;
102  _libraryFileName=libraryFileName;
103  return true;
104 }
105 bool LadspaWrapper::ConcreteConfigure(const ProcessingConfig&)
106 {
107  _bufferSize = BackendBufferSize();
108  ConfigurePortsAndControls();
109  ConfigureControlsPointers();
110  return true;
111 }
112 void LadspaWrapper::RemovePortsAndControls()
113 {
114  std::vector< AudioInPort* >::iterator itInPort;
115  for(itInPort=_inputPorts.begin(); itInPort!=_inputPorts.end(); itInPort++)
116  delete *itInPort;
117  _inputPorts.clear();
118 
119  std::vector< AudioOutPort* >::iterator itOutPort;
120  for(itOutPort=_outputPorts.begin(); itOutPort!=_outputPorts.end(); itOutPort++)
121  delete *itOutPort;
122  _outputPorts.clear();
123 
124  std::vector< FloatInControl* >::iterator itInControl;
125  for(itInControl=_inputControls.begin(); itInControl!=_inputControls.end(); itInControl++)
126  delete *itInControl;
127  _inputControls.clear();
128 
129  std::vector< FloatOutControl* >::iterator itOutControl;
130  for(itOutControl=_outputControls.begin(); itOutControl!=_outputControls.end(); itOutControl++)
131  delete *itOutControl;
132  _outputControls.clear();
133 
134  _outputControlValues.clear();
135 
136  GetInPorts().Clear();
137  GetOutPorts().Clear();
138  GetInControls().Clear();
139  GetOutControls().Clear();
140 }
141 
142 void LadspaWrapper::ConfigurePortsAndControls()
143 {
144  RemovePortsAndControls();
145  for(unsigned int i=0;i<_descriptor->PortCount;i++)
146  {
147  const LADSPA_PortDescriptor portDescriptor = _descriptor->PortDescriptors[i];
148  // in port
149  if(LADSPA_IS_PORT_INPUT(portDescriptor) && LADSPA_IS_PORT_AUDIO(portDescriptor))
150  {
151  AudioInPort * port = new AudioInPort(_descriptor->PortNames[i],this );
152  port->SetSize( _bufferSize );
153  _inputPorts.push_back(port);
154  }
155  // out port
156  if(LADSPA_IS_PORT_OUTPUT(portDescriptor) && LADSPA_IS_PORT_AUDIO(portDescriptor))
157  {
158  AudioOutPort * port = new AudioOutPort(_descriptor->PortNames[i],this );
159  port->SetSize( _bufferSize );
160  _outputPorts.push_back(port);
161  }
162 
163  // in control
164  if(LADSPA_IS_PORT_INPUT(portDescriptor) && LADSPA_IS_PORT_CONTROL(portDescriptor))
165  {
166  FloatInControl * control = new FloatInControl(_descriptor->PortNames[i], this);
167 
168  const LADSPA_PortRangeHint & hint = _descriptor->PortRangeHints[i];
169  bool isBounded = (
170  LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
171  LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)
172  );
173  if (isBounded)
174  {
175  control->SetBounds( hint.LowerBound, hint.UpperBound );
176  control->DoControl( control->DefaultValue() );
177  }
178  _inputControls.push_back(control);
179  }
180  // out control
181  if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && LADSPA_IS_PORT_CONTROL(portDescriptor))
182  {
183  FloatOutControl * control = new FloatOutControl(_descriptor->PortNames[i], this);
184  _outputControlValues.push_back(LADSPA_Data());
185  _outputControls.push_back(control);
186  }
187  }
188 }
189 
190 void LadspaWrapper::ConfigureControlsPointers()
191 {
192  int inControlIndex = 0;
193  int outControlIndex = 0;
194  for(unsigned int i=0;i<_descriptor->PortCount;i++)
195  {
196  const LADSPA_PortDescriptor portDescriptor = _descriptor->PortDescriptors[i];
197  if (LADSPA_IS_PORT_CONTROL(portDescriptor))
198  {
199  if (LADSPA_IS_PORT_INPUT(portDescriptor))
200  {
201  LADSPA_Data* inControlValue = const_cast<LADSPA_Data*>( &(_inputControls[inControlIndex]->GetLastValue()) );
202  _descriptor->connect_port(_instance, i, inControlValue);
203  inControlIndex++;
204  }
205  else
206  _descriptor->connect_port(_instance, i, & _outputControlValues[outControlIndex++]);
207  }
208  }
209 }
210 
211 void LadspaWrapper::DoUpdatePortsPointers()
212 {
213  int inPortIndex = 0;
214  int outPortIndex = 0;
215  for(unsigned int i=0;i<_descriptor->PortCount;i++)
216  {
217  const LADSPA_PortDescriptor portDescriptor = _descriptor->PortDescriptors[i];
218  if (!LADSPA_IS_PORT_CONTROL(portDescriptor)) // is audio port
219  {
220  if (LADSPA_IS_PORT_INPUT(portDescriptor))
221  _descriptor->connect_port(_instance, i, _inputPorts[inPortIndex++]->GetAudio().GetBuffer().GetPtr());
222  else
223  _descriptor->connect_port(_instance, i, _outputPorts[outPortIndex++]->GetAudio().GetBuffer().GetPtr());
224  }
225  }
226 
227 }
228 
229 const char * LadspaWrapper::GetClassName() const
230 {
231  return _factoryKey.c_str();
232 }
233 
234 } // namespace CLAM
235 
236 #endif // USE_LADSPA
237