00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef LV2PLUGIN_HPP
00025 #define LV2PLUGIN_HPP
00026
00027 #include <cstdarg>
00028
00029 #include <cstring>
00030 #include <string>
00031 #include <vector>
00032
00033 #include <lv2.h>
00034 #include <lv2_uri_map.h>
00035 #include <lv2_saverestore.h>
00036 #include <lv2_event.h>
00037 #include <lv2_contexts.h>
00038 #include <lv2types.hpp>
00039
00040
00073 namespace LV2 {
00074
00075
00079 class DescList : public std::vector<LV2_Descriptor> {
00080 public:
00081 ~DescList();
00082 };
00083
00084
00088 DescList& get_lv2_descriptors();
00089
00090
00131 template <class Derived,
00132 class Ext1 = End, class Ext2 = End, class Ext3 = End,
00133 class Ext4 = End, class Ext5 = End, class Ext6 = End,
00134 class Ext7 = End, class Ext8 = End, class Ext9 = End>
00135 class Plugin : public MixinTree<Derived,
00136 Ext1, Ext2, Ext3, Ext4, Ext5,
00137 Ext6, Ext7, Ext8, Ext9> {
00138 public:
00139
00146 Plugin(uint32_t ports)
00147 : m_ports(ports, 0),
00148 m_ok(true) {
00149 m_features = s_features;
00150 m_bundle_path = s_bundle_path;
00151 s_features = 0;
00152 s_bundle_path = 0;
00153 if (m_features) {
00154 FeatureHandlerMap hmap;
00155 Derived::map_feature_handlers(hmap);
00156 for (const Feature* const* iter = m_features; *iter != 0; ++iter) {
00157 FeatureHandlerMap::iterator miter;
00158 miter = hmap.find((*iter)->URI);
00159 if (miter != hmap.end())
00160 miter->second(static_cast<Derived*>(this), (*iter)->data);
00161 }
00162 }
00163 }
00164
00174 void connect_port(uint32_t port, void* data_location) {
00175 m_ports[port] = data_location;
00176 }
00177
00181 void activate() { }
00182
00193 void run(uint32_t sample_count) { }
00194
00199 void deactivate() { }
00200
00213 static unsigned register_class(const std::string& uri) {
00214 LV2_Descriptor desc;
00215 std::memset(&desc, 0, sizeof(LV2_Descriptor));
00216 char* c_uri = new char[uri.size() + 1];
00217 std::memcpy(c_uri, uri.c_str(), uri.size() + 1);
00218 desc.URI = c_uri;
00219 desc.instantiate = &Derived::_create_plugin_instance;
00220 desc.connect_port = &Derived::_connect_port;
00221 desc.activate = &Derived::_activate;
00222 desc.run = &Derived::_run;
00223 desc.deactivate = &Derived::_deactivate;
00224 desc.cleanup = &Derived::_delete_plugin_instance;
00225 desc.extension_data = &Derived::extension_data;
00226 get_lv2_descriptors().push_back(desc);
00227 return get_lv2_descriptors().size() - 1;
00228 }
00229
00238 bool check_ok() {
00239 return m_ok && MixinTree<Derived,
00240 Ext1, Ext2, Ext3, Ext4, Ext5,
00241 Ext6, Ext7, Ext8, Ext9>::check_ok();
00242 }
00243
00244 protected:
00245
00257 template <typename T> T*& p(uint32_t port) {
00258 return reinterpret_cast<T*&>(m_ports[port]);
00259 }
00260
00264 float*& p(uint32_t port) {
00265 return reinterpret_cast<float*&>(m_ports[port]);
00266 }
00267
00271 const char* bundle_path() const {
00272 return m_bundle_path;
00273 }
00274
00283 void set_ok(bool ok) {
00284 m_ok = ok;
00285 }
00286
00290 std::vector<void*> m_ports;
00291
00292 private:
00293
00297 static void _connect_port(LV2_Handle instance, uint32_t port,
00298 void* data_location) {
00299 reinterpret_cast<Derived*>(instance)->connect_port(port, data_location);
00300 }
00301
00305 static void _activate(LV2_Handle instance) {
00306 reinterpret_cast<Derived*>(instance)->activate();
00307 }
00308
00312 static void _run(LV2_Handle instance, uint32_t sample_count) {
00313 reinterpret_cast<Derived*>(instance)->run(sample_count);
00314 }
00315
00319 static void _deactivate(LV2_Handle instance) {
00320 reinterpret_cast<Derived*>(instance)->deactivate();
00321 }
00322
00327 static LV2_Handle _create_plugin_instance(const LV2_Descriptor* descriptor,
00328 double sample_rate,
00329 const char* bundle_path,
00330 const Feature* const*
00331 features) {
00332
00333
00334
00335 s_features = features;
00336 s_bundle_path = bundle_path;
00337
00338 Derived* t = new Derived(sample_rate);
00339 if (t->check_ok())
00340 return reinterpret_cast<LV2_Handle>(t);
00341 delete t;
00342 return 0;
00343 }
00344
00349 static void _delete_plugin_instance(LV2_Handle instance) {
00350 delete reinterpret_cast<Derived*>(instance);
00351 }
00352
00353
00354 private:
00355
00360 LV2::Feature const* const* m_features;
00361
00366 char const* m_bundle_path;
00367
00372 static LV2::Feature const* const* s_features;
00373
00378 static char const* s_bundle_path;
00379
00385 bool m_ok;
00386
00387 };
00388
00389
00390
00391 template<class Derived, class Ext1, class Ext2, class Ext3, class Ext4,
00392 class Ext5, class Ext6, class Ext7, class Ext8, class Ext9>
00393 LV2::Feature const* const*
00394 Plugin<Derived, Ext1, Ext2, Ext3, Ext4,
00395 Ext5, Ext6, Ext7, Ext8, Ext9>::s_features = 0;
00396
00397 template<class Derived, class Ext1, class Ext2, class Ext3, class Ext4,
00398 class Ext5, class Ext6, class Ext7, class Ext8, class Ext9>
00399 char const*
00400 Plugin<Derived, Ext1, Ext2, Ext3, Ext4,
00401 Ext5, Ext6, Ext7, Ext8, Ext9>::s_bundle_path = 0;
00402
00403
00429 template <bool Required = true>
00430 struct FixedBufSize {
00431
00436 template <class Derived> struct I : Extension<Required> {
00437
00439 I() : m_buffer_size(0) { }
00440
00442 static void map_feature_handlers(FeatureHandlerMap& hmap) {
00443 hmap["http://tapas.affenbande.org/lv2/ext/fixed-buffersize"] =
00444 &I<Derived>::handle_feature;
00445 }
00446
00448 static void handle_feature(void* instance, void* data) {
00449 Derived* d = reinterpret_cast<Derived*>(instance);
00450 I<Derived>* fe = static_cast<I<Derived>*>(d);
00451 fe->m_buffer_size = *reinterpret_cast<uint32_t*>(data);
00452 fe->m_ok = true;
00453 }
00454
00455 protected:
00456
00460 uint32_t get_buffer_size() const { return m_buffer_size; }
00461
00462 uint32_t m_buffer_size;
00463
00464 };
00465
00466 };
00467
00476 template <bool Required = true>
00477 struct FixedP2BufSize {
00478
00483 template <class Derived> struct I : Extension<Required> {
00484
00486 I() : m_buffer_size(0) { }
00487
00489 static void map_feature_handlers(FeatureHandlerMap& hmap) {
00490 hmap["http://tapas.affenbande.org/lv2/ext/power-of-two-buffersize"] =
00491 &I<Derived>::handle_feature;
00492 }
00493
00495 static void handle_feature(void* instance, void* data) {
00496 Derived* d = reinterpret_cast<Derived*>(instance);
00497 I<Derived>* fe = static_cast<I<Derived>*>(d);
00498 fe->m_buffer_size = *reinterpret_cast<uint32_t*>(data);
00499 fe->m_ok = true;
00500 }
00501
00502 protected:
00503
00507 uint32_t get_buffer_size() const { return m_buffer_size; }
00508
00509 uint32_t m_buffer_size;
00510
00511 };
00512
00513 };
00514
00515
00522 template <bool Required = true>
00523 struct SaveRestore {
00524
00529 template <class Derived> struct I : Extension<Required> {
00530
00532 I() { }
00533
00535 static void map_feature_handlers(FeatureHandlerMap& hmap) {
00536 hmap[LV2_SAVERESTORE_URI] = &I<Derived>::handle_feature;
00537 }
00538
00540 static void handle_feature(void* instance, void* data) {
00541 Derived* d = reinterpret_cast<Derived*>(instance);
00542 I<Derived>* fe = static_cast<I<Derived>*>(d);
00543 fe->m_ok = true;
00544 }
00545
00547 static const void* extension_data(const char* uri) {
00548 if (!std::strcmp(uri, LV2_SAVERESTORE_URI)) {
00549 static LV2SR_Descriptor srdesc = { &I<Derived>::_save,
00550 &I<Derived>::_restore };
00551 return &srdesc;
00552 }
00553 return 0;
00554 }
00555
00568 char* save(const char* directory, LV2SR_File*** files) { return 0; }
00569
00576 char* restore(const LV2SR_File** files) { return 0; }
00577
00578 protected:
00579
00582 static char* _save(LV2_Handle h,
00583 const char* directory, LV2SR_File*** files) {
00584 return reinterpret_cast<Derived*>(h)->save(directory, files);
00585 }
00586
00589 static char* _restore(LV2_Handle h, const LV2SR_File** files) {
00590 return reinterpret_cast<Derived*>(h)->restore(files);
00591 }
00592
00593 };
00594 };
00595
00596
00603 template <bool Required = true>
00604 struct EventRef {
00605
00610 template <class Derived> struct I : Extension<Required> {
00611
00613 I() : m_callback_data(0), m_ref_func(0), m_unref_func(0) { }
00614
00616 static void map_feature_handlers(FeatureHandlerMap& hmap) {
00617 hmap[LV2_EVENT_URI] = &I<Derived>::handle_feature;
00618 }
00619
00621 static void handle_feature(void* instance, void* data) {
00622 Derived* d = reinterpret_cast<Derived*>(instance);
00623 I<Derived>* fe = static_cast<I<Derived>*>(d);
00624 LV2_Event_Feature* ef = reinterpret_cast<LV2_Event_Feature*>(data);
00625 fe->m_callback_data = ef->callback_data;
00626 fe->m_ref_func = ef->lv2_event_ref;
00627 fe->m_unref_func = ef->lv2_event_unref;
00628 fe->m_ok = true;
00629 }
00630
00631 protected:
00632
00642 uint32_t event_ref(LV2_Event* event) {
00643 return m_ref_func(m_callback_data, event);
00644 }
00645
00650 uint32_t event_unref(LV2_Event* event) {
00651 return m_unref_func(m_callback_data, event);
00652 }
00653
00654 LV2_Event_Callback_Data m_callback_data;
00655 uint32_t (*m_ref_func)(LV2_Event_Callback_Data, LV2_Event*);
00656 uint32_t (*m_unref_func)(LV2_Event_Callback_Data, LV2_Event*);
00657
00658 };
00659
00660 };
00661
00662
00670 template <bool Required = true>
00671 struct MsgContext {
00672
00677 template <class Derived> struct I : Extension<Required> {
00678
00680 I() { }
00681
00683 static void map_feature_handlers(FeatureHandlerMap& hmap) {
00684 hmap[LV2_CONTEXT_MESSAGE] = &I<Derived>::handle_feature;
00685 }
00686
00688 static void handle_feature(void* instance, void* data) {
00689 Derived* d = reinterpret_cast<Derived*>(instance);
00690 I<Derived>* fe = static_cast<I<Derived>*>(d);
00691 fe->m_ok = true;
00692 }
00693
00695 static const void* extension_data(const char* uri) {
00696 if (!std::strcmp(uri, LV2_CONTEXT_MESSAGE)) {
00697 static LV2_Blocking_Context desc = { &I<Derived>::_blocking_run,
00698 &I<Derived>::_connect_port };
00699 return &desc;
00700 }
00701 return 0;
00702 }
00703
00708 bool blocking_run(uint8_t* outputs_written) { return false; }
00709
00710 protected:
00711
00714 static bool _blocking_run(LV2_Handle h, uint8_t* outputs_written) {
00715 return reinterpret_cast<Derived*>(h)->blocking_run(outputs_written);
00716 }
00717
00720 static void _connect_port(LV2_Handle h, uint32_t port, void* buffer) {
00721 reinterpret_cast<Derived*>(h)->connect_port(port, buffer);
00722 }
00723
00724 };
00725 };
00726
00727
00728 }
00729
00730
00731 #endif