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