00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00027 #ifndef DSSIPLUGIN_HPP
00028 #define DSSIPLUGIN_HPP
00029
00030 #include <unistd.h>
00031
00032 #include <cstring>
00033 #include <string>
00034 #include <map>
00035 #include <vector>
00036
00037 #include <dssi.h>
00038
00039
00040 extern "C" {
00041
00042
00043
00044
00045
00046 const DSSI_Descriptor* dssi_descriptor(unsigned long index);
00047 }
00048
00049
00050
00051
00052
00053 struct DSSIPort {
00054 DSSIPort(LADSPA_PortDescriptor descriptor, const std::string& name,
00055 const LADSPA_PortRangeHint& hint)
00056 : m_descriptor(descriptor), m_name(name), m_hint(hint) { }
00057 DSSIPort(LADSPA_PortDescriptor descriptor, const std::string& name)
00058 : m_descriptor(descriptor), m_name(name) {
00059 memset(&m_hint, 0, sizeof(LADSPA_PortRangeHint));
00060 }
00061
00062 LADSPA_PortDescriptor m_descriptor;
00063 std::string m_name;
00064 LADSPA_PortRangeHint m_hint;
00065 };
00066
00067
00072 enum DSSIFeatureMask {
00074 DSSI_NO_FEATURES = 0,
00077 DSSI_RECEIVES_MIDI = 1 << 0,
00080 DSSI_HAS_PROGRAMS = 1 << 1,
00085 DSSI_USES_SHM = 1 << 2
00086 };
00087
00088
00090 inline DSSIFeatureMask operator|(const DSSIFeatureMask& m1,
00091 const DSSIFeatureMask& m2) {
00092 return DSSIFeatureMask(static_cast<unsigned>(m1) | static_cast<unsigned>(m2));
00093 }
00094
00095
00099 struct DSSIPortList : public std::vector<DSSIPort> {
00100
00102 int add_port(LADSPA_PortDescriptor descriptor, const std::string& name,
00103 const LADSPA_PortRangeHint& hint) {
00104 push_back(DSSIPort(descriptor, name, hint));
00105 return size() - 1;
00106 }
00107
00109 int add_port(LADSPA_PortDescriptor descriptor, const std::string& name) {
00110 push_back(DSSIPort(descriptor, name));
00111 return size() - 1;
00112 }
00113
00115 int add_port(LADSPA_PortDescriptor descriptor, const std::string name,
00116 LADSPA_PortRangeHintDescriptor rh_desc,
00117 LADSPA_Data lower_bound, LADSPA_Data upper_bound) {
00118 LADSPA_PortRangeHint prh = { rh_desc, lower_bound, upper_bound };
00119 push_back(DSSIPort(descriptor, name, prh));
00120 return size() - 1;
00121 }
00122
00123 };
00124
00125
00126
00145 template <class T>
00146 size_t register_dssi(const std::string& label, LADSPA_Properties properties,
00147 const std::string& name, const std::string& maker,
00148 const std::string& copyright, const DSSIPortList& ports,
00149 DSSIFeatureMask features = DSSI_RECEIVES_MIDI |
00150 DSSI_HAS_PROGRAMS | DSSI_USES_SHM);
00151
00152
00153
00216 class DSSIPlugin {
00217 public:
00218
00220
00221
00223 virtual ~DSSIPlugin();
00224
00226 virtual void activate() { }
00227
00229 virtual void deactivate() { }
00230
00231
00232
00233
00235
00236
00238 virtual char* configure(const char* key, const char* value) { return NULL; }
00239
00243 virtual int get_midi_controller_for_port(unsigned long port) {
00244 return DSSI_NONE;
00245 }
00246
00251 virtual const DSSI_Program_Descriptor* get_program(unsigned long index) {
00252 return NULL;
00253 }
00254
00263 virtual bool shm_attached(void* shm, size_t size) {
00264 return false;
00265 }
00266
00277 virtual void shm_detach_request(void* shm) { shm_detach(shm); }
00278
00279
00280
00281
00283
00284
00290 virtual void run(unsigned long sample_count) {
00291 run_synth(sample_count, NULL, 0);
00292 }
00293
00298 virtual void run_synth(unsigned long sample_count, snd_seq_event_t* events,
00299 unsigned long event_count) { }
00300
00304 virtual void select_program(unsigned long bank, unsigned long program) { }
00305
00308 virtual void connect_port(unsigned long port, LADSPA_Data* data_location) {
00309 m_ports[port] = data_location;
00310 }
00311
00313
00314
00315 friend const DSSI_Descriptor* dssi_descriptor(unsigned long index);
00316 template <class T> friend
00317 size_t register_dssi(const std::string& label, LADSPA_Properties properties,
00318 const std::string& name, const std::string& maker,
00319 const std::string& copyright, const DSSIPortList& ports,
00320 DSSIFeatureMask features);
00321
00322
00323 protected:
00324
00328 void shm_detach(void* shm);
00329
00332 std::vector<LADSPA_Data*> m_ports;
00333
00334
00335 private:
00336
00337
00338
00339 static std::vector<DSSI_Descriptor>& get_dssi_descriptors();
00340
00341
00342 static void _activate(LADSPA_Handle instance);
00343 static void _deactivate(LADSPA_Handle instance);
00344 static void _cleanup(LADSPA_Handle instance);
00345
00346 static char* _configure(LADSPA_Handle instance,
00347 const char* key, const char* value);
00348 static char* _configure_with_shm(LADSPA_Handle instance,
00349 const char* key, const char* value);
00350 static int _get_midi_controller_for_port(LADSPA_Handle instance,
00351 unsigned long port);
00352 static const DSSI_Program_Descriptor* _get_program(LADSPA_Handle instance,
00353 unsigned long index);
00354
00355 static void _run(LADSPA_Handle instance, unsigned long sample_count);
00356 static void _run_synth(LADSPA_Handle instance, unsigned long sample_count,
00357 snd_seq_event_t* events, unsigned long event_count);
00358 static void _select_program(LADSPA_Handle instance,
00359 unsigned long bank, unsigned long program);
00360 static void _connect_port(LADSPA_Handle instance, unsigned long port,
00361 LADSPA_Data* data_location);
00362
00363
00364
00365 template <class T>
00366 static LADSPA_Handle create_plugin_instance(const LADSPA_Descriptor*
00367 descriptor,
00368 unsigned long sample_rate) {
00369 T* t = new T(sample_rate);
00370 t->m_ports.resize(descriptor->PortCount, NULL);
00371 return reinterpret_cast<LADSPA_Handle>(t);
00372 }
00373
00374 std::map<std::string, void*> m_segments;
00375
00376 };
00377
00378
00379
00380 template <class T>
00381 size_t register_dssi(const std::string& label, LADSPA_Properties properties,
00382 const std::string& name, const std::string& maker,
00383 const std::string& copyright, const DSSIPortList& ports,
00384 DSSIFeatureMask features) {
00385
00386 DSSI_Descriptor descriptor;
00387 memset(&descriptor, 0, sizeof(DSSI_Descriptor));
00388 descriptor.DSSI_API_Version = 1;
00389
00390 LADSPA_Descriptor* l_descriptor =
00391 (LADSPA_Descriptor*)calloc(1, sizeof(LADSPA_Descriptor));
00392 descriptor.LADSPA_Plugin = l_descriptor;
00393
00394 l_descriptor->UniqueID = 666;
00395 l_descriptor->Label = strdup(label.c_str());
00396 l_descriptor->Properties = properties;
00397 l_descriptor->Name = strdup(name.c_str());
00398 l_descriptor->Maker = strdup(maker.c_str());
00399 l_descriptor->Copyright = strdup(copyright.c_str());
00400
00401 l_descriptor->PortCount = ports.size();
00402 LADSPA_PortDescriptor* port_desc =
00403 (LADSPA_PortDescriptor*)calloc(ports.size(), sizeof(LADSPA_PortDescriptor));
00404 char** port_name = (char**)calloc(ports.size(), sizeof(const char*));
00405 LADSPA_PortRangeHint* port_hint =
00406 (LADSPA_PortRangeHint*)calloc(ports.size(), sizeof(LADSPA_PortRangeHint));
00407 for (unsigned i = 0; i < ports.size(); ++i) {
00408 port_desc[i] = ports[i].m_descriptor;
00409 port_name[i] = strdup(ports[i].m_name.c_str());
00410 port_hint[i] = ports[i].m_hint;
00411 }
00412 l_descriptor->PortDescriptors = port_desc;
00413 l_descriptor->PortNames = port_name;
00414 l_descriptor->PortRangeHints = port_hint;
00415
00416 l_descriptor->instantiate = &DSSIPlugin::create_plugin_instance<T>;
00417 l_descriptor->cleanup = &DSSIPlugin::_cleanup;
00418 l_descriptor->connect_port = &DSSIPlugin::_connect_port;
00419 l_descriptor->activate = &DSSIPlugin::_activate;
00420 l_descriptor->run = &DSSIPlugin::_run;
00421 l_descriptor->deactivate = &DSSIPlugin::_deactivate;
00422
00423 if (features & DSSI_USES_SHM)
00424 descriptor.configure = &DSSIPlugin::_configure_with_shm;
00425 else
00426 descriptor.configure = &DSSIPlugin::_configure;
00427
00428 if (features & DSSI_RECEIVES_MIDI) {
00429 descriptor.run_synth = &DSSIPlugin::_run_synth;
00430 descriptor.get_midi_controller_for_port =
00431 &DSSIPlugin::_get_midi_controller_for_port;
00432 }
00433 else {
00434 descriptor.run_synth = 0;
00435 descriptor.get_midi_controller_for_port = 0;
00436 }
00437
00438 if (features & DSSI_HAS_PROGRAMS) {
00439 descriptor.get_program = &DSSIPlugin::_get_program;
00440 descriptor.select_program = &DSSIPlugin::_select_program;
00441 }
00442 else {
00443 descriptor.get_program = 0;
00444 descriptor.select_program = 0;
00445 }
00446
00447 DSSIPlugin::get_dssi_descriptors().push_back(descriptor);
00448
00449 return DSSIPlugin::get_dssi_descriptors().size() - 1;
00450 }
00451
00452
00453
00454 #endif
00455
00456