Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ladspaplugin.hpp

00001 /****************************************************************************
00002     
00003     ladspaplugin.hpp - support file for writing LADSPA plugins in C++
00004     
00005     Copyright (C) 2005  Lars Luthman <larsl@users.sourceforge.net>
00006     
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011     
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016     
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307  USA
00020 
00021 ****************************************************************************/
00022 
00023 #ifndef LADSPAPLUGIN_HPP
00024 #define LADSPAPLUGIN_HPP
00025 
00026 #include <unistd.h>
00027 
00028 #include <cstring>
00029 #include <string>
00030 #include <vector>
00031 
00032 #include <ladspa.h>
00033 
00034 
00035 /* This struct contains data for a single port. You should not have
00036    to use it directly, use the LADSPAPortList::add_port() functions
00037    instead. */
00038 struct LADSPAPort {
00039   LADSPAPort(LADSPA_PortDescriptor descriptor, const std::string& name, 
00040              const LADSPA_PortRangeHint& hint)
00041     : m_descriptor(descriptor), m_name(name), m_hint(hint) { }
00042   LADSPAPort(LADSPA_PortDescriptor descriptor, const std::string& name)
00043     : m_descriptor(descriptor), m_name(name) {
00044     memset(&m_hint, 0, sizeof(LADSPA_PortRangeHint));
00045   }
00046 
00047   LADSPA_PortDescriptor m_descriptor;
00048   std::string m_name;
00049   LADSPA_PortRangeHint m_hint;
00050 };
00051 
00052 
00055 struct LADSPAPortList : public std::vector<LADSPAPort> {
00056   
00058   void add_port(LADSPA_PortDescriptor descriptor, const std::string& name,
00059                 const LADSPA_PortRangeHint& hint) {
00060     push_back(LADSPAPort(descriptor, name, hint));
00061   }
00062   
00065   void add_port(LADSPA_PortDescriptor descriptor, const std::string& name) {
00066     push_back(LADSPAPort(descriptor, name));
00067   }
00068   
00071   void add_port(LADSPA_PortDescriptor descriptor, const std::string name,
00072                 LADSPA_PortRangeHintDescriptor rh_desc,
00073                 LADSPA_Data lower_bound, LADSPA_Data upper_bound) {
00074     LADSPA_PortRangeHint prh = { rh_desc, lower_bound, upper_bound };
00075     push_back(LADSPAPort(descriptor, name, prh));
00076   }
00077 };
00078 
00079 
00137 class LADSPAPlugin {
00138 public:
00139   
00141   virtual ~LADSPAPlugin() { }
00142   
00145   virtual void connect_port(unsigned long port, LADSPA_Data* data_location) {
00146     m_ports[port] = data_location;
00147   }
00148   
00152   virtual void activate() { }
00153   
00156   virtual void run(unsigned long sample_count) { }
00157   
00161   virtual void deactivate() { }
00162   
00163 protected:
00164   
00165   /* This needs to be a friend since it resizes the m_ports vector. */
00166   template <class T> friend
00167   LADSPA_Handle create_plugin_instance(const LADSPA_Descriptor* descriptor,
00168                                        unsigned long sample_rate);
00169   template <class T> friend
00170   size_t register_ladspa(unsigned long uid, const std::string& label, 
00171                          LADSPA_Properties properties, const std::string& name,
00172                          const std::string& maker, const std::string& copyright,
00173                          const LADSPAPortList& ports);
00174   
00175 
00176 
00179   std::vector<LADSPA_Data*> m_ports;
00180   
00181 };
00182 
00183 
00184 /* These functions are C wrappers for the C++ member functions. You should not
00185    use them directly. */
00186 void connect_port(LADSPA_Handle instance, unsigned long port, 
00187                   LADSPA_Data* data_location);
00188 void activate(LADSPA_Handle instance);
00189 void run(LADSPA_Handle instance, unsigned long sample_count);
00190 void deactivate(LADSPA_Handle instance);
00191 
00192 
00193 /* This template function creates an instance of a plugin. It is used as
00194    the instantiate() callback in the LADSPA descriptor. You should not use
00195    it directly. */
00196 template <class T>
00197 LADSPA_Handle create_plugin_instance(const LADSPA_Descriptor* descriptor,
00198                                      unsigned long sample_rate) {
00199   T* t = new T(sample_rate);
00200   t->m_ports.resize(descriptor->PortCount, NULL);
00201   return reinterpret_cast<LADSPA_Descriptor*>(t);
00202 }
00203 
00204 
00205 /* This template function destroys an instance of a plugin. It is used as
00206    the cleanup() callback in the LADSPA descriptor. You should not use it
00207    directly. */
00208 template <class T>
00209 void delete_plugin_instance(LADSPA_Handle instance) {
00210   delete reinterpret_cast<LADSPAPlugin*>(instance);
00211 }
00212 
00213 
00214 /* This function returns the list of LADSPA descriptors. It should only be used
00215    internally. */
00216 std::vector<LADSPA_Descriptor>& get_ladspa_descriptors();
00217 
00218 
00239 template <class T>
00240 size_t register_ladspa(unsigned long uid, const std::string& label, 
00241                        LADSPA_Properties properties, const std::string& name,
00242                        const std::string& maker, const std::string& copyright,
00243                        const LADSPAPortList& ports) {
00244   
00245   LADSPA_Descriptor l_descriptor;
00246   memset(&l_descriptor, 0, sizeof(LADSPA_Descriptor));
00247   
00248   l_descriptor.UniqueID = uid;
00249   l_descriptor.Label = strdup(label.c_str());
00250   l_descriptor.Properties = properties;
00251   l_descriptor.Name = strdup(name.c_str());
00252   l_descriptor.Maker = strdup(maker.c_str());
00253   l_descriptor.Copyright = strdup(copyright.c_str());
00254   
00255   l_descriptor.PortCount = ports.size();
00256   LADSPA_PortDescriptor* port_desc = 
00257     (LADSPA_PortDescriptor*)calloc(ports.size(), sizeof(LADSPA_PortDescriptor));
00258   char** port_name = (char**)calloc(ports.size(), sizeof(const char*));
00259   LADSPA_PortRangeHint* port_hint = 
00260     (LADSPA_PortRangeHint*)calloc(ports.size(), sizeof(LADSPA_PortRangeHint));
00261   for (unsigned i = 0; i < ports.size(); ++i) {
00262     port_desc[i] = ports[i].m_descriptor;
00263     port_name[i] = strdup(ports[i].m_name.c_str());
00264     port_hint[i] = ports[i].m_hint;
00265   }
00266   l_descriptor.PortDescriptors = port_desc;
00267   l_descriptor.PortNames = port_name;
00268   l_descriptor.PortRangeHints = port_hint;
00269   
00270   l_descriptor.instantiate = &create_plugin_instance<T>;
00271   l_descriptor.cleanup = &delete_plugin_instance<T>;
00272   l_descriptor.connect_port = &connect_port;
00273   l_descriptor.activate = &activate;
00274   l_descriptor.run = &run;
00275   l_descriptor.deactivate = &deactivate;
00276   
00277   get_ladspa_descriptors().push_back(l_descriptor);
00278   
00279   return get_ladspa_descriptors().size() - 1;
00280 }
00281 
00282 
00283 #endif

Generated on Wed Mar 1 17:12:44 2006 for DSSI support libraries by  doxygen 1.4.4