CLAM-Development
1.1
|
00001 #include "LadspaNetworkExporter.hxx" 00002 #include "ControlSource.hxx" 00003 #include "ControlSink.hxx" 00004 00005 namespace CLAM 00006 { 00007 00008 template<class T> 00009 class LADSPAInfo 00010 { 00011 public: 00012 std::string name; 00013 T* processing; 00014 LADSPA_Data *dataBuffer; 00015 }; 00016 00017 class NetworkLADSPAPlugin 00018 { 00019 private: 00020 typedef std::vector< LADSPAInfo<AudioSource> > LADSPAInPortList; 00021 typedef std::vector< LADSPAInfo<AudioSink> > LADSPAOutPortList; 00022 typedef std::vector< LADSPAInfo<ControlSource> > LADSPAInControlList; 00023 typedef std::vector< LADSPAInfo<ControlSink> > LADSPAOutControlList; 00024 00025 Network _network; 00026 LADSPAInPortList mReceiverList; 00027 LADSPAOutPortList mSenderList; 00028 LADSPAInControlList mInControlList; 00029 LADSPAOutControlList mOutControlList; 00030 unsigned long mClamBufferSize, mExternBufferSize; 00031 00032 public: 00033 NetworkLADSPAPlugin(const std::string & networkXmlContent); 00034 ~NetworkLADSPAPlugin(); 00035 00036 void Activate(); 00037 void Deactivate(); 00038 00039 void LocateConnections(); 00040 void UpdatePortFrameAndHopSize(); 00041 void FillPortInfo( LADSPA_PortDescriptor* descriptors, char** names, LADSPA_PortRangeHint* rangehints ); 00042 void ConnectTo(unsigned long port, LADSPA_Data * data); 00043 00044 void Run( unsigned long nsamples ); 00045 void CopyLadspaBuffersToGenerators(const unsigned long nframes); 00046 void CopySinksToLadspaBuffers(const unsigned long nframes); 00047 void ProcessInControlValues(); 00048 void ProcessOutControlValues(); 00049 static LADSPA_Descriptor * CreateLADSPADescriptor( 00050 const std::string & networkXmlContent, 00051 unsigned id, 00052 const std::string & label, 00053 const std::string & name, 00054 const std::string & maker, 00055 const std::string & copyright 00056 ); 00057 }; 00058 00059 } 00060 00061 // Ladspa Callbacks 00062 extern "C" 00063 { 00064 // Construct a new plugin instance. 00065 static LADSPA_Handle Instantiate(const LADSPA_Descriptor * descriptor, unsigned long sampleRate) 00066 { 00067 // std::cerr << "Network2Ladspa: instantiate" << std::endl; 00068 return new CLAM::NetworkLADSPAPlugin((const char*)descriptor->ImplementationData); 00069 } 00070 // Destruct plugin instance 00071 static void CleanUp(LADSPA_Handle handle) 00072 { 00073 // std::cerr << "Network2Ladspa: cleanup " << handle << std::endl; 00074 delete (CLAM::NetworkLADSPAPlugin*) handle; 00075 } 00076 00077 // Run the plugin 00078 static void Run(LADSPA_Handle handle, unsigned long sampleCount) 00079 { 00080 CLAM::NetworkLADSPAPlugin *p = (CLAM::NetworkLADSPAPlugin*) handle; 00081 p->Run( sampleCount ); 00082 } 00083 // Activate Plugin 00084 static void Activate(LADSPA_Handle handle) 00085 { 00086 // std::cerr << "Network2Ladspa: activate " << handle << std::endl; 00087 CLAM::NetworkLADSPAPlugin *p = (CLAM::NetworkLADSPAPlugin*) handle; 00088 p->Activate(); 00089 } 00090 00091 static void Deactivate(LADSPA_Handle handle) 00092 { 00093 // std::cerr << "Network2Ladspa: deactivate " << handle << std::endl; 00094 CLAM::NetworkLADSPAPlugin *p = (CLAM::NetworkLADSPAPlugin*) handle; 00095 p->Deactivate(); 00096 } 00097 00098 // Connect a port to a data location. 00099 static void ConnectTo(LADSPA_Handle handle, unsigned long port, LADSPA_Data * dataLocation) 00100 { 00101 // std::cerr << "Network2Ladspa: connect " << port << std::endl; 00102 CLAM::NetworkLADSPAPlugin *p = (CLAM::NetworkLADSPAPlugin*) handle; 00103 p->ConnectTo( port, dataLocation ); 00104 } 00105 } 00106 00107 namespace CLAM 00108 { 00109 00110 00111 NetworkLADSPAPlugin::NetworkLADSPAPlugin(const std::string & networkXmlContent) 00112 { 00113 mClamBufferSize=512; 00114 mExternBufferSize=mClamBufferSize; 00115 _network.SetName("Testing name"); 00116 00117 // std::cerr << "NetworkLADSPAPlugin: Constructed" << std::endl; 00118 std::istringstream xmlfile(networkXmlContent); 00119 try 00120 { 00121 XmlStorage::Restore( _network, xmlfile); 00122 } 00123 catch ( XmlStorageErr err) 00124 { 00125 std::cerr << "CLAM::NetworkLADSPAPlugin WARNING: error opening file <" << xmlfile << "> . Plugin not loaded" <<std::endl; 00126 std::cerr << err.what() << std::endl; 00127 return; 00128 } 00129 00130 LocateConnections(); 00131 } 00132 00133 NetworkLADSPAPlugin::~NetworkLADSPAPlugin() 00134 { 00135 // std::cerr << "NetworkLADSPAPlugin: DELETED" << std::endl; 00136 } 00137 00138 void NetworkLADSPAPlugin::Activate() 00139 { 00140 _network.Start(); 00141 } 00142 00143 void NetworkLADSPAPlugin::Deactivate() 00144 { 00145 _network.Stop(); 00146 } 00147 00148 void NetworkLADSPAPlugin::LocateConnections() 00149 { 00150 CLAM_ASSERT( mReceiverList.empty(), "NetworkLADSPAPlugin::LocateConnections() : there are already registered input ports"); 00151 CLAM_ASSERT( mSenderList.empty(), "NetworkLADSPAPlugin::LocateConnections() : there are already registered output ports"); 00152 CLAM_ASSERT( mInControlList.empty(), "NetworkLADSPAPlugin::LocateConnections() : there are already registered controls"); 00153 CLAM_ASSERT( mOutControlList.empty(), "NetworkLADSPAPlugin::LocateConnections() : there are already registered controls"); 00154 00155 //Get them from the Network and add it to local list 00156 for (Network::ProcessingsMap::const_iterator it=_network.BeginProcessings(); it!=_network.EndProcessings(); it++) 00157 { 00158 CLAM::Processing * processing = it->second; 00159 const std::string & className = processing->GetClassName(); 00160 if (className == "AudioSource") 00161 { 00162 LADSPAInfo<AudioSource> info; 00163 info.name=it->first; 00164 info.processing=(AudioSource*)processing; 00165 info.processing->SetFrameAndHopSize( mExternBufferSize ); 00166 mReceiverList.push_back(info); 00167 } 00168 if (className == "AudioSink") 00169 { 00170 LADSPAInfo<AudioSink> info; 00171 info.name=it->first; 00172 info.processing=(AudioSink*)it->second; 00173 info.processing->SetFrameAndHopSize( mExternBufferSize ); 00174 mSenderList.push_back(info); 00175 } 00176 if (className == "ControlSource") 00177 { 00178 LADSPAInfo<ControlSource> info; 00179 info.name=it->first; 00180 info.processing=(ControlSource*)it->second; 00181 mInControlList.push_back(info); 00182 } 00183 if (className == "ControlSink") 00184 { 00185 LADSPAInfo<ControlSink> info; 00186 info.name=it->first; 00187 info.processing=(ControlSink*)it->second; 00188 mOutControlList.push_back(info); 00189 } 00190 } 00191 } 00192 00193 void NetworkLADSPAPlugin::UpdatePortFrameAndHopSize() 00194 { 00195 //AudioSources 00196 for (LADSPAInPortList::iterator it=mReceiverList.begin(); it!=mReceiverList.end(); it++) 00197 it->processing->SetFrameAndHopSize( mExternBufferSize ); 00198 00199 //AudioSinks 00200 for (LADSPAOutPortList::iterator it=mSenderList.begin(); it!=mSenderList.end(); it++) 00201 it->processing->SetFrameAndHopSize( mExternBufferSize ); 00202 } 00203 00204 void NetworkLADSPAPlugin::FillPortInfo( LADSPA_PortDescriptor* descriptors, char** names, LADSPA_PortRangeHint* rangehints ) 00205 { 00206 int currentport=0; 00207 00208 //Manage InPorts (AudioSources) 00209 for (LADSPAInPortList::iterator it=mReceiverList.begin(); it!=mReceiverList.end(); it++) 00210 { 00211 descriptors[currentport] = (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO); 00212 names[currentport] = LadspaLibrary::dupstr( it->name.c_str() ); 00213 rangehints[currentport].HintDescriptor = 0; 00214 currentport++; 00215 } 00216 00217 //Manage OutPorts (AudioSinks) 00218 for (LADSPAOutPortList::iterator it=mSenderList.begin(); it!=mSenderList.end(); it++) 00219 { 00220 descriptors[currentport] = (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO); 00221 names[currentport] = LadspaLibrary::dupstr( it->name.c_str() ); 00222 rangehints[currentport].HintDescriptor = 0; 00223 currentport++; 00224 } 00225 00226 //Manage InControls (ExternInControls) 00227 for (LADSPAInControlList::iterator it=mInControlList.begin(); it!=mInControlList.end(); it++) 00228 { 00229 descriptors[currentport] = (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL); 00230 names[currentport] = LadspaLibrary::dupstr( it->name.c_str() ); 00231 00232 //Obté processingConfig, i defineix cada param 00233 ControlSourceConfig conf = dynamic_cast<const ControlSourceConfig&>(it->processing->GetConfig() ); 00234 00235 rangehints[currentport].LowerBound=(LADSPA_Data)conf.GetMinValue(); 00236 rangehints[currentport].UpperBound=(LADSPA_Data)conf.GetMaxValue(); 00237 rangehints[currentport].HintDescriptor = (LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_MIDDLE); 00238 currentport++; 00239 } 00240 00241 //Manage OutControls (ExternOutControls) 00242 // (Please note that not all the LADSPA hosts make use of these kind of ports) 00243 for (LADSPAOutControlList::iterator it=mOutControlList.begin(); it!=mOutControlList.end(); it++) 00244 { 00245 descriptors[currentport] = (LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL); 00246 names[currentport] = LadspaLibrary::dupstr( it->name.c_str() ); 00247 rangehints[currentport].LowerBound=(LADSPA_Data)0; 00248 rangehints[currentport].UpperBound=(LADSPA_Data)1000; 00249 rangehints[currentport].HintDescriptor = (LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE); 00250 currentport++; 00251 } 00252 } 00253 00254 void NetworkLADSPAPlugin::Run( unsigned long nsamples ) 00255 { 00256 //Check current buffer size of ports, to make sure everything fits! 00257 // if it isn't so, upgrade Frame and Hop sizes (vital) 00258 if (nsamples!=mExternBufferSize) 00259 { 00260 mExternBufferSize=nsamples; 00261 UpdatePortFrameAndHopSize(); 00262 } 00263 00264 ProcessInControlValues(); 00265 00266 CopyLadspaBuffersToGenerators(nsamples); 00267 00268 //Do() as much as it is needed 00269 for (int stepcount=0; stepcount < (int(mExternBufferSize)/int(mClamBufferSize)); stepcount++) 00270 _network.Do(); 00271 00272 CopySinksToLadspaBuffers(nsamples); 00273 ProcessOutControlValues(); 00274 } 00275 00276 void NetworkLADSPAPlugin::ProcessInControlValues() 00277 { 00278 for (LADSPAInControlList::iterator it=mInControlList.begin(); it!=mInControlList.end(); it++) 00279 it->processing->Do( (float) *(it->dataBuffer) ); 00280 } 00281 00282 void NetworkLADSPAPlugin::ProcessOutControlValues() 00283 { 00284 for (LADSPAOutControlList::iterator it=mOutControlList.begin(); it!=mOutControlList.end(); it++) 00285 *(it->dataBuffer)=it->processing->GetControlValue(); 00286 } 00287 00288 void NetworkLADSPAPlugin::CopyLadspaBuffersToGenerators(const unsigned long nframes) 00289 { 00290 for (LADSPAInPortList::iterator it=mReceiverList.begin(); it!=mReceiverList.end(); it++) 00291 it->processing->SetExternalBuffer(it->dataBuffer, nframes ); 00292 } 00293 00294 void NetworkLADSPAPlugin::CopySinksToLadspaBuffers(const unsigned long nframes) 00295 { 00296 for (LADSPAOutPortList::iterator it=mSenderList.begin(); it!=mSenderList.end(); it++) 00297 it->processing->SetExternalBuffer(it->dataBuffer, nframes ); 00298 } 00299 00300 void NetworkLADSPAPlugin::ConnectTo(unsigned long port, LADSPA_Data * data) 00301 { 00302 if ( port <= mReceiverList.size()-1 ) //Input port 00303 mReceiverList.at( port ).dataBuffer=data; 00304 else if ( port <= mReceiverList.size() + mSenderList.size() -1) //Output port 00305 mSenderList.at( port-mReceiverList.size() ).dataBuffer=data; 00306 else if ( port <= mReceiverList.size() + mSenderList.size() + mInControlList.size() -1) //Input control 00307 mInControlList.at( port-mReceiverList.size()-mSenderList.size() ).dataBuffer=data; 00308 else //Output control 00309 mOutControlList.at( port-mReceiverList.size()-mSenderList.size()-mInControlList.size() ).dataBuffer=data; 00310 } 00311 00312 00313 00314 LADSPA_Descriptor * NetworkLADSPAPlugin::CreateLADSPADescriptor( 00315 const std::string & networkXmlContent, 00316 unsigned id, 00317 const std::string & label, 00318 const std::string & name, 00319 const std::string & maker, 00320 const std::string & copyright 00321 ) 00322 { 00323 CLAM::NetworkLADSPAPlugin plugin(networkXmlContent); 00324 00325 unsigned numports = 00326 plugin.mReceiverList.size() + plugin.mSenderList.size() + 00327 plugin.mInControlList.size() + plugin.mOutControlList.size(); 00328 00329 if (numports == 0) return 0; 00330 00331 LADSPA_Descriptor * descriptor = new LADSPA_Descriptor; 00332 00333 descriptor->UniqueID = id; 00334 descriptor->Label = LadspaLibrary::dupstr(label.c_str()); 00335 descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE; // LADSPA_PROPERTY_REALTIME; 00336 descriptor->Name = LadspaLibrary::dupstr(name.c_str()); 00337 descriptor->Maker = LadspaLibrary::dupstr(maker.c_str()); 00338 descriptor->Copyright = LadspaLibrary::dupstr(copyright.c_str()); 00339 descriptor->ImplementationData = LadspaLibrary::dupstr(networkXmlContent.c_str()); 00340 descriptor->PortCount = numports; 00341 00342 LADSPA_PortDescriptor * piPortDescriptors = new LADSPA_PortDescriptor[ numports ]; 00343 descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)piPortDescriptors; 00344 00345 char ** pcPortNames = new char*[ numports ]; 00346 00347 descriptor->PortNames = (const char **)pcPortNames; 00348 00349 LADSPA_PortRangeHint * psPortRangeHints = new LADSPA_PortRangeHint[ numports ]; 00350 descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)psPortRangeHints; 00351 00352 plugin.FillPortInfo( piPortDescriptors, pcPortNames, psPortRangeHints); 00353 00354 descriptor->instantiate = ::Instantiate; 00355 descriptor->connect_port = ::ConnectTo; 00356 descriptor->activate = ::Activate; 00357 descriptor->run = ::Run; 00358 descriptor->deactivate = ::Deactivate; 00359 descriptor->cleanup = ::CleanUp; 00360 00361 return descriptor; 00362 } 00363 00364 LadspaNetworkExporter::LadspaNetworkExporter( 00365 LadspaLibrary & library, const std::string & networkXmlContent, 00366 unsigned id, 00367 const std::string & label, 00368 const std::string & name, 00369 const std::string & maker, 00370 const std::string & copyright 00371 ) 00372 { 00373 LADSPA_Descriptor * descriptor = NetworkLADSPAPlugin::CreateLADSPADescriptor( 00374 networkXmlContent, id, label, name, 00375 maker, copyright); 00376 if (not descriptor) return; 00377 library.AddPluginType(descriptor); 00378 } 00379 00380 } //end namespace CLAM 00381