LadspaNetworkExporter.cxx

Go to the documentation of this file.
00001 #include "LadspaNetworkExporter.hxx"
00002 #include "ControlSource.hxx"
00003 #include "ControlSink.hxx"
00004 #include "AudioBufferSource.hxx"
00005 #include "AudioBufferSink.hxx"
00006 #include "NetworkPlayer.hxx"
00007 
00008 namespace CLAM
00009 {
00010 
00011 class LadspaNetworkPlayer : public NetworkPlayer
00012 {
00013         template<class T>
00014         class LADSPAInfo
00015         {
00016         public:
00017                 std::string name;
00018                 T* processing;
00019                 LADSPA_Data *dataBuffer;
00020                 unsigned port;
00021         };
00022 
00023 private:
00024         typedef std::vector< LADSPAInfo<ControlSource> > LADSPAInControlList;
00025         typedef std::vector< LADSPAInfo<ControlSink> > LADSPAOutControlList;
00026         typedef std::vector<LADSPA_Data * > Buffers;
00027 
00028         Network _network;
00029         Buffers _sourceBuffers;
00030         Buffers _sinkBuffers;
00031         Buffers _inControlBuffers;
00032         Buffers _outControlBuffers;
00033         unsigned long mClamBufferSize;
00034         unsigned long mExternBufferSize;
00035 public:
00036         virtual bool IsWorking() { return true; }
00037         virtual std::string NonWorkingReason() { return ""; }
00038         virtual void Start() {}
00039         virtual void Stop() {}
00040 //      virtual void Pause() {}
00041         virtual bool IsRealTime() const { return true; }
00042 //      virtual unsigned BackendBufferSize();
00043 //      virtual unsigned BackendSampleRate();
00044 public:
00045         LadspaNetworkPlayer(const std::string & label, const std::string & networkXmlContent);
00046         ~LadspaNetworkPlayer();
00047 
00048         void Activate();
00049         void Deactivate();
00050         void ConnectTo(unsigned long port, LADSPA_Data * data);
00051         void Run( unsigned long nsamples );
00052 
00053         void LocateConnections();
00054         void ChangeFrameSize(unsigned nFrames);
00055         void FillPortInfo( LADSPA_PortDescriptor* descriptors, char** names, LADSPA_PortRangeHint* rangehints );
00056         void SetAudioSourceBuffers(unsigned long nframes);
00057         void SetAudioSinkBuffers(const unsigned long nframes);
00058         void ProcessInControlValues();
00059         void ProcessOutControlValues();
00060         static LADSPA_Descriptor * CreateLADSPADescriptor(
00061                 const std::string & networkXmlContent,
00062                 unsigned id,
00063                 const std::string & label,
00064                 const std::string & name,
00065                 const std::string & maker,
00066                 const std::string & copyright
00067         );
00068 };
00069 
00070 }
00071 
00072 static CLAM::LadspaNetworkPlayer * AsPlayer(LADSPA_Handle handle)
00073 {
00074         return (CLAM::LadspaNetworkPlayer*) handle;
00075 }
00076 
00077 // Ladspa Callbacks
00078 extern "C"
00079 {
00080         // Construct a new plugin instance.
00081         static LADSPA_Handle Instantiate(const LADSPA_Descriptor * descriptor, unsigned long sampleRate)
00082         {
00083 //              std::cerr << "Network2Ladspa: instantiate" << std::endl;
00084                 return new CLAM::LadspaNetworkPlayer(descriptor->Label, (const char*)descriptor->ImplementationData);
00085         }
00086         // Destruct plugin instance
00087         static void CleanUp(LADSPA_Handle handle)
00088         {
00089 //              std::cerr << "Network2Ladspa: cleanup " << handle << std::endl;
00090                 delete AsPlayer(handle);
00091         }
00092 
00093         // Run the plugin
00094         static void Run(LADSPA_Handle handle, unsigned long sampleCount)
00095         {
00096                 AsPlayer(handle)->Run( sampleCount );
00097         }
00098         // Activate Plugin
00099         static void Activate(LADSPA_Handle handle)
00100         {
00101 //              std::cerr << "Network2Ladspa: activate " << handle << std::endl;
00102                 AsPlayer(handle)->Activate();
00103         }
00104 
00105         static void Deactivate(LADSPA_Handle handle)
00106         {
00107 //              std::cerr << "Network2Ladspa: deactivate " << handle << std::endl;
00108                 AsPlayer(handle)->Deactivate();
00109         }
00110 
00111         // Connect a port to a data location.
00112         static void ConnectTo(LADSPA_Handle handle, unsigned long port, LADSPA_Data * dataLocation)
00113         {
00114 //              std::cerr << "Network2Ladspa: connect " << port << std::endl;
00115                 AsPlayer(handle)->ConnectTo( port, dataLocation );
00116         }
00117 }
00118 
00119 namespace CLAM
00120 {
00121 
00122 
00123 LadspaNetworkPlayer::LadspaNetworkPlayer(const std::string & name, const std::string & networkXmlContent)
00124 {
00125         mClamBufferSize=512;
00126         mExternBufferSize=mClamBufferSize;
00127 
00128         std::istringstream xmlfile(networkXmlContent);
00129         try
00130         {
00131                 XmlStorage::Restore( _network, xmlfile );
00132         }
00133         catch ( XmlStorageErr err)
00134         {
00135                 std::cerr << "CLAM LADSPA: Error while loading CLAM network based plugin '" << name << "'." <<std::endl;
00136                 std::cerr << err.what() << std::endl;
00137                 std::cerr << "Plugin not loaded." << std::endl;
00138                 return;
00139         }
00140         if (_network.HasMisconfiguredProcessings())
00141         {
00142                 std::cerr << "CLAM LADSPA: Error while configuring CLAM network based plugin '" << name << "'." <<std::endl;
00143                 std::cerr << _network.GetConfigurationErrors() << std::endl;
00144                 std::cerr << "Plugin not loaded." << std::endl;
00145                 return;
00146         }
00147         if (_network.HasUnconnectedInPorts())
00148         {
00149                 std::cerr << "CLAM LADSPA: Error loading CLAM network based plugin '" << name << "'." <<std::endl;
00150                 std::cerr << "Plugin not loaded because internal network inports were unconnected." <<std::endl;
00151                 std::cerr << _network.GetUnconnectedInPorts() << std::flush;
00152                 return;
00153         }
00154 
00155         // TOFIX: Should be a full link for the network to obtain parameters 
00156         // but the network adquires the ownership of the player and, in this case,
00157         // the player owns the network.
00158         SetNetworkBackLink(_network);
00159         LocateConnections();
00160 }
00161 
00162 LadspaNetworkPlayer::~LadspaNetworkPlayer()
00163 {
00164 }
00165 
00166 void LadspaNetworkPlayer::Activate()
00167 {
00168         CLAM_WARNING(_network.SupportsVariableAudioSize(), "Network don't support variable audio size");
00169         _network.Start();
00170 }
00171 
00172 void LadspaNetworkPlayer::Deactivate()
00173 {
00174         _network.Stop();
00175 }
00176 
00177 void LadspaNetworkPlayer::LocateConnections()
00178 {
00179         CacheSourcesAndSinks();
00180 
00181         _sourceBuffers.resize(GetNSources());
00182         _sinkBuffers.resize(GetNSinks());
00183         _inControlBuffers.resize(GetNControlSources());
00184         _outControlBuffers.resize(GetNControlSinks());
00185 
00186         ChangeFrameSize(mExternBufferSize);
00187 }
00188 
00189 void LadspaNetworkPlayer::ChangeFrameSize(unsigned frameSize)
00190 {
00191         for (unsigned i=0; i<GetNSources(); i++)
00192                 SetSourceFrameSize(i, frameSize);
00193         for (unsigned i=0; i<GetNSinks(); i++)
00194                 SetSinkFrameSize(i, frameSize);
00195 }
00196 
00197 void LadspaNetworkPlayer::FillPortInfo( LADSPA_PortDescriptor* descriptors, char** names, LADSPA_PortRangeHint* rangehints )
00198 {
00199         int currentport=0;
00200 
00201         //Manage InPorts (AudioSource and AudioBufferSources)
00202         for (unsigned i=0; i<GetNSources(); i++)
00203         {
00204                 descriptors[currentport] = (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO);
00205                 names[currentport] = LadspaLibrary::dupstr( SourceName(i).c_str() );
00206                 rangehints[currentport].HintDescriptor = 0;
00207                 currentport++;
00208         }
00209 
00210         //Manage OutPorts (AudioSink and AudioSinksBuffer)
00211         for (unsigned i=0; i<GetNSinks(); i++)
00212         {
00213                 descriptors[currentport] = (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO);
00214                 names[currentport] = LadspaLibrary::dupstr( SinkName(i).c_str() );
00215                 rangehints[currentport].HintDescriptor = 0;
00216                 currentport++;
00217         }
00218 
00219         //Manage InControls (ExternInControls)
00220         for (unsigned i=0; i<GetNControlSources(); i++)
00221         {
00222                 descriptors[currentport] = (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL);
00223                 names[currentport] = LadspaLibrary::dupstr( ControlSourceName(i).c_str() );
00224 
00225                 //Obté processingConfig, i defineix cada param
00226                 ControlSourceConfig conf = dynamic_cast<const ControlSourceConfig&>(_controlSources[i].processing->GetConfig() );
00227 
00228                 rangehints[currentport].LowerBound=(LADSPA_Data)conf.GetMinValue();
00229                 rangehints[currentport].UpperBound=(LADSPA_Data)conf.GetMaxValue();
00230 
00231                 unsigned defaultHintValue=LADSPA_HINT_DEFAULT_MIDDLE;
00232                 // specific cases when the default value is equal to some of defined LADSPA hints (ugly!):
00233                 if (conf.GetDefaultValue() == conf.GetMinValue() ) defaultHintValue=LADSPA_HINT_DEFAULT_MINIMUM;
00234                 else if (conf.GetDefaultValue() == conf.GetMaxValue() ) defaultHintValue=LADSPA_HINT_DEFAULT_MAXIMUM;
00235                 else if (conf.GetDefaultValue() == 0) defaultHintValue = LADSPA_HINT_DEFAULT_0;
00236                 else if (conf.GetDefaultValue() == 1) defaultHintValue = LADSPA_HINT_DEFAULT_1;
00237                 else if (conf.GetDefaultValue() == 100) defaultHintValue = LADSPA_HINT_DEFAULT_100;
00238                 else if (conf.GetDefaultValue() == 440) defaultHintValue = LADSPA_HINT_DEFAULT_440;
00239 
00240                 rangehints[currentport].HintDescriptor = (LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | defaultHintValue);
00241                 currentport++;
00242         }
00243 
00244         //Manage OutControls (ExternOutControls)
00245         // (Please note that not all the LADSPA hosts make use of these kind of ports)
00246         for (unsigned i=0; i<GetNControlSinks(); i++)
00247         {
00248                 descriptors[currentport] = (LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL);
00249                 names[currentport] = LadspaLibrary::dupstr( ControlSourceName(i).c_str() );
00250                 rangehints[currentport].LowerBound=(LADSPA_Data)0;
00251                 rangehints[currentport].UpperBound=(LADSPA_Data)1000;
00252                 rangehints[currentport].HintDescriptor = (LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE);
00253                 currentport++;
00254         }
00255 }
00256 
00257 void LadspaNetworkPlayer::Run( unsigned long nsamples )
00258 {
00259         //Check current buffer size of ports, to make sure everything fits!
00260         // if it isn't so, upgrade Frame and Hop sizes (vital)
00261         if (nsamples!=mExternBufferSize)
00262         {
00263                 mExternBufferSize=nsamples;
00264                 if (nsamples==0)
00265                         return; // Seems that in Ardour2.8 it does never runs plugins with 0 samples
00266                 ChangeFrameSize(mExternBufferSize);
00267         }
00268 
00269         ProcessInControlValues();
00270         SetAudioSourceBuffers(nsamples);
00271         SetAudioSinkBuffers(nsamples);
00272         _network.Do();
00273         ProcessOutControlValues();
00274 }
00275 
00276 void LadspaNetworkPlayer::ProcessInControlValues()
00277 {
00278         for (unsigned i=0; i<GetNControlSources(); i++)
00279                 ReadControlSource(i,_inControlBuffers[i]);
00280 }
00281 
00282 void LadspaNetworkPlayer::ProcessOutControlValues()
00283 {
00284         for (unsigned i=0; i<GetNControlSinks(); i++)
00285                 FeedControlSink(i, _outControlBuffers[i]);
00286 }
00287 
00288 void LadspaNetworkPlayer::SetAudioSourceBuffers(const unsigned long nframes)
00289 {
00290         for (unsigned i=0; i<GetNSources(); i++)
00291                 SetSourceBuffer(i, _sourceBuffers[i], nframes);
00292 }
00293 
00294 void LadspaNetworkPlayer::SetAudioSinkBuffers(const unsigned long nframes)
00295 {
00296         for (unsigned i=0; i<GetNSinks(); i++)
00297                 SetSinkBuffer(i, _sinkBuffers[i], nframes);
00298 }
00299 
00300 void LadspaNetworkPlayer::ConnectTo(unsigned long port, LADSPA_Data * data)
00301 {
00302         unsigned nSources  = GetNSources();
00303         unsigned nSinks  = GetNSinks();
00304         unsigned nInControls  = GetNControlSources();
00305         unsigned nOutControls  = GetNControlSinks();
00306 
00307         if ( port < nSources ) //Input port
00308         {
00309                 _sourceBuffers[port]=data;
00310                 return;
00311         }
00312         port-=nSources;
00313         if (port < nSinks) //Output port
00314         {
00315                 _sinkBuffers[port]=data;
00316                 return;
00317         }
00318         port-=nSinks;
00319         if ( port < nInControls) //Input control
00320         {
00321                 _inControlBuffers[port]=data;
00322                 return;
00323         }
00324         port-=nInControls;
00325         if (port < nOutControls)
00326         {
00327                 _outControlBuffers[port]=data;
00328                 return;
00329         }
00330 }
00331 
00332 
00333 
00334 LADSPA_Descriptor * LadspaNetworkPlayer::CreateLADSPADescriptor(
00335         const std::string & networkXmlContent,
00336         unsigned id,
00337         const std::string & label,
00338         const std::string & name,
00339         const std::string & maker,
00340         const std::string & copyright
00341         )
00342 {
00343         CLAM::LadspaNetworkPlayer plugin(label, networkXmlContent);
00344 
00345         unsigned numports = plugin.GetNSources() + plugin.GetNSinks() +
00346                 plugin.GetNControlSources() + plugin.GetNControlSinks();
00347 
00348         if (numports == 0) return 0;
00349 
00350         LADSPA_Descriptor * descriptor = new LADSPA_Descriptor;
00351 
00352         descriptor->UniqueID = id;
00353         descriptor->Label = LadspaLibrary::dupstr(label.c_str());
00354         descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE; // LADSPA_PROPERTY_REALTIME;
00355         descriptor->Name = LadspaLibrary::dupstr(name.c_str());
00356         descriptor->Maker = LadspaLibrary::dupstr(maker.c_str());
00357         descriptor->Copyright = LadspaLibrary::dupstr(copyright.c_str());
00358         descriptor->ImplementationData = LadspaLibrary::dupstr(networkXmlContent.c_str());
00359         descriptor->PortCount = numports;
00360 
00361         LADSPA_PortDescriptor * piPortDescriptors = new LADSPA_PortDescriptor[ numports ];
00362         descriptor->PortDescriptors = (const LADSPA_PortDescriptor *)piPortDescriptors;
00363 
00364         char ** pcPortNames = new char*[ numports ];
00365 
00366         descriptor->PortNames = (const char **)pcPortNames;
00367 
00368         LADSPA_PortRangeHint * psPortRangeHints = new LADSPA_PortRangeHint[ numports ];
00369         descriptor->PortRangeHints = (const LADSPA_PortRangeHint *)psPortRangeHints;
00370 
00371         plugin.FillPortInfo( piPortDescriptors, pcPortNames, psPortRangeHints);
00372 
00373         descriptor->instantiate = ::Instantiate;
00374         descriptor->connect_port = ::ConnectTo;
00375         descriptor->activate = ::Activate;
00376         descriptor->run = ::Run;
00377         descriptor->deactivate = ::Deactivate;
00378         descriptor->cleanup = ::CleanUp;
00379 
00380         return descriptor;
00381 }
00382 
00383 LadspaNetworkExporter::LadspaNetworkExporter(
00384         LadspaLibrary & library, const std::string & networkXmlContent,
00385         unsigned id,
00386         const std::string & label,
00387         const std::string & name,
00388         const std::string & maker,
00389         const std::string & copyright
00390         )
00391 {
00392         LADSPA_Descriptor * descriptor = LadspaNetworkPlayer::CreateLADSPADescriptor(
00393                 networkXmlContent, id, label, name,
00394                 maker, copyright);
00395         if (not descriptor) return;
00396         library.AddPluginType(descriptor);
00397 }
00398 
00399 } //end namespace CLAM
00400 
Generated by  doxygen 1.6.3