LV2 Toolkit  1.1.1
 All Classes Namespaces Functions Typedefs Enumerations Enumerator Groups Pages
extra.hpp
1 
31 #ifndef LVTK_LV2_EXTRA_HPP
32 #define LVTK_LV2_EXTRA_HPP
33 
34 #if defined (LVTK_EXTRA_ENABLED)
35 
36 #include <lvtk/types.hpp>
37 
38 namespace lvtk {
39 
40 
50  LVTK_MIXIN_CLASS NoUserResize {
51 
56  LVTK_MIXIN_DERIVED {
57 
59  static void map_feature_handlers(feature_handler_map& hmap) {
60  hmap["http://ll-plugins.nongnu.org/lv2/dev/ui#noUserResize"] =
61  &I<Derived>::handle_feature;
62  }
63 
65  static void handle_feature(void* instance, void* data) {
66  Derived* d = reinterpret_cast<Derived*>(instance);
67  I<Derived>* e = static_cast<I<Derived>*>(d);
68  e->m_ok = true;
69  }
70 
71  bool check_ok() {
72  if (LVTK_DEBUG) {
73  std::clog<<" [LV2::NoUserResize] Validation "
74  <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
75  }
76  return this->m_ok;
77  }
78  };
79 
80  };
81 
82 
92  LVTK_MIXIN_CLASS FixedSize {
93 
98  LVTK_MIXIN_DERIVED {
99 
101  static void map_feature_handlers(feature_handler_map& hmap) {
102  hmap["http://ll-plugins.nongnu.org/lv2/dev/ui#fixedSize"] =
103  &I<Derived>::handle_feature;
104  }
105 
107  static void handle_feature(void* instance, void* data) {
108  Derived* d = reinterpret_cast<Derived*>(instance);
109  I<Derived>* e = static_cast<I<Derived>*>(d);
110  e->m_ok = true;
111  }
112 
113  bool check_ok() {
114  if (LVTK_DEBUG) {
115  std::clog<<" [LV2::FixedSize] Validation "
116  <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
117  }
118  return this->m_ok;
119  }
120 
121  };
122 
123  };
124 
125 
135  LVTK_MIXIN_CLASS WriteOSC {
136 
141  LVTK_MIXIN_DERIVED {
142 
143  I() : m_osc_type(0) {
144  m_buffer = lv2_event_buffer_new(sizeof(LV2_Event) + 256, 0);
145  }
146 
147  bool check_ok() {
148  Derived* d = static_cast<Derived*>(this);
149  m_osc_type = d->
150  uri_to_id(LVTK_EVENT_URI, "http://lv2plug.in/ns/ext/osc#OscEvent");
151  m_event_buffer_format = d->
152  uri_to_id(LVTK_UI_URI, "http://lv2plug.in/ns/extensions/ui#Events");
153  return !Required || (m_osc_type && m_event_buffer_format);
154  }
155 
156  protected:
157 
158  bool write_osc(uint32_t port, const char* path, const char* types, ...) {
159  if (m_osc_type == 0)
160  return false;
161  // XXX handle all sizes here - this is dangerous
162  lv2_event_buffer_reset(m_buffer, 0, m_buffer->data);
163  LV2_Event_Iterator iter;
164  lv2_event_begin(&iter, m_buffer);
165  va_list ap;
166  va_start(ap, types);
167  uint32_t size = lv2_osc_event_vsize(path, types, ap);
168  va_end(ap);
169  if (!size)
170  return false;
171  va_start(ap, types);
172  bool success = lv2_osc_buffer_vappend(&iter, 0, 0, m_osc_type,
173  path, types, size, ap);
174  va_end(ap);
175  if (success) {
176  static_cast<Derived*>(this)->
177  write(port, m_buffer->header_size + m_buffer->capacity,
178  m_event_buffer_format, m_buffer);
179  return true;
180  }
181  return false;
182  }
183 
184  uint32_t m_osc_type;
185  uint32_t m_event_buffer_format;
186  LV2_Event_Buffer* m_buffer;
187 
188  };
189 
190  };
191 
200  LVTK_MIXIN_CLASS Presets {
201 
206  LVTK_MIXIN_DERIVED {
207 
208  I() : m_hdesc(0), m_host_support(false) { }
209 
211  static void map_feature_handlers(feature_handler_map& hmap) {
212  hmap[LVTK_UI_PRESETS_URI] = &I<Derived>::handle_feature;
213  }
214 
216  static void handle_feature(void* instance, void* data) {
217  Derived* d = reinterpret_cast<Derived*>(instance);
218  I<Derived>* e = static_cast<I<Derived>*>(d);
219  e->m_hdesc = static_cast<LV2UI_Presets_Feature*>(data);
220  e->m_ok = (e->m_hdesc != 0);
221  e->m_host_support = (e->m_hdesc != 0);
222  }
223 
224  bool check_ok() {
225  if (LVTK_DEBUG) {
226  std::clog<<" [LV2::Presets] Validation "
227  <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
228  }
229  return this->m_ok;
230  }
231 
237  void preset_added(uint32_t number,
238  char const* name) {
239 
240  }
241 
246  void preset_removed(uint32_t number) {
247 
248  }
249 
253  void presets_cleared() {
254 
255  }
256 
263  void current_preset_changed(uint32_t number) {
264 
265  }
266 
270  static void const* extension_data(char const* uri) {
271  static LV2UI_Presets_GDesc desc = { &_preset_added,
272  &_preset_removed,
273  &_presets_cleared,
274  &_current_preset_changed };
275  if (!std::strcmp(uri, LVTK_UI_PRESETS_URI))
276  return &desc;
277  return 0;
278  }
279 
280  protected:
281 
284  void change_preset(uint32_t preset) {
285  if (m_hdesc) {
286  if (LVTK_DEBUG) {
287  std::clog<<"[LV2::Presets] change_preset("<<preset<<")"
288  <<std::endl;
289  }
290  m_hdesc->change_preset(static_cast<Derived*>(this)->controller(),
291  preset);
292  }
293  else if (LVTK_DEBUG) {
294  std::clog<<"[LV2::Presets] change_preset("<<preset<<")"
295  <<" --- Function not provided by host!"<<std::endl;
296  }
297  }
298 
302  void save_preset(uint32_t preset, char const* name) {
303  if (m_hdesc) {
304  if (LVTK_DEBUG) {
305  std::clog<<"[LV2::Presets] save_preset("<<preset<<", \""
306  <<name<<"\")"<<std::endl;
307  }
308  m_hdesc->save_preset(static_cast<Derived*>(this)->controller(),
309  preset, name);
310  }
311  else if (LVTK_DEBUG) {
312  std::clog<<"[LV2::Presets] save_preset("<<preset<<", \""
313  <<name<<"\")"
314  <<" --- Function not provided by host!"<<std::endl;
315  }
316  }
317 
320  bool host_supports_presets() const {
321  return m_host_support;
322  }
323 
324  private:
325 
326  static void _preset_added(LV2UI_Handle gui,
327  uint32_t number,
328  char const* name) {
329  if (LVTK_DEBUG) {
330  std::clog<<"[LV2::Presets] Host called preset_added("
331  <<number<<", \""<<name<<"\")."<<std::endl;
332  }
333  static_cast<Derived*>(gui)->preset_added(number, name);
334  }
335 
336  static void _preset_removed(LV2UI_Handle gui,
337  uint32_t number) {
338  if (LVTK_DEBUG) {
339  std::clog<<"[LV2::Presets] Host called preset_removed("
340  <<number<<")."<<std::endl;
341  }
342  static_cast<Derived*>(gui)->preset_removed(number);
343  }
344 
345  static void _presets_cleared(LV2UI_Handle gui) {
346  if (LVTK_DEBUG) {
347  std::clog<<"[LV2::Presets] Host called presets_cleared()."
348  <<std::endl;
349  }
350  static_cast<Derived*>(gui)->presets_cleared();
351  }
352 
353  static void _current_preset_changed(LV2UI_Handle gui,
354  uint32_t number) {
355  if (LVTK_DEBUG) {
356  std::clog<<"[LV2::Presets] Host called current_preset_changed("
357  <<number<<")."<<std::endl;
358  }
359  static_cast<Derived*>(gui)->current_preset_changed(number);
360  }
361 
362  LV2UI_Presets_Feature* m_hdesc;
363  bool m_host_support;
364 
365  };
366 
367  };
368 
377  LVTK_MIXIN_CLASS FixedBufSize {
378 
383  LVTK_MIXIN_DERIVED {
384 
385  I() : m_buffer_size(0) { }
386 
388  static void map_feature_handlers(feature_handler_map& hmap) {
389  hmap["http://tapas.affenbande.org/lv2/ext/fixed-buffersize"] =
390  &I<Derived>::handle_feature;
391  }
392 
394  static void handle_feature(void* instance, void* data) {
395  Derived* d = reinterpret_cast<Derived*>(instance);
396  I<Derived>* fe = static_cast<I<Derived>*>(d);
397  fe->m_buffer_size = *reinterpret_cast<uint32_t*>(data);
398  if (LVTK_DEBUG) {
399  std::clog<<" [LV2::FixedBufSize] Host set buffer size to "
400  <<fe->m_buffer_size<<std::endl;
401  }
402  fe->m_ok = true;
403  }
404 
405  bool check_ok() {
406  if (LVTK_DEBUG) {
407  std::clog<<" [LV2::FixedBufSize] Validation "
408  <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
409  }
410  return this->m_ok;
411  }
412 
413  protected:
414 
418  uint32_t get_buffer_size() const { return m_buffer_size; }
419 
420  uint32_t m_buffer_size;
421 
422  };
423  };
424 
433  LVTK_MIXIN_CLASS FixedP2BufSize {
434 
439  LVTK_MIXIN_DERIVED {
440 
441  I() : m_buffer_size(0) { }
442 
444  static void map_feature_handlers(feature_handler_map& hmap) {
445  hmap["http://tapas.affenbande.org/lv2/ext/power-of-two-buffersize"] =
446  &I<Derived>::handle_feature;
447  }
448 
450  static void handle_feature(void* instance, void* data) {
451  Derived* d = reinterpret_cast<Derived*>(instance);
452  I<Derived>* fe = static_cast<I<Derived>*>(d);
453  fe->m_buffer_size = *reinterpret_cast<uint32_t*>(data);
454  if (LVTK_DEBUG) {
455  std::clog<<" [LV2::FixedP2BufSize] Host set buffer size to "
456  <<fe->m_buffer_size<<std::endl;
457  }
458  fe->m_ok = true;
459  }
460 
461  bool check_ok() {
462  if (LVTK_DEBUG) {
463  std::clog<<" [LV2::FixedP2BufSize] Validation "
464  <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
465  }
466  return this->m_ok;
467  }
468 
469  protected:
470 
474  uint32_t get_buffer_size() const { return m_buffer_size; }
475 
476  uint32_t m_buffer_size;
477 
478  };
479 
480  };
481 
482 
489  LVTK_MIXIN_CLASS SaveRestore {
490 
495  LVTK_MIXIN_DERIVED {
496 
498  static void map_feature_handlers(feature_handler_map& hmap) {
499  hmap[LVTK_SAVERESTORE_URI] = &I<Derived>::handle_feature;
500  }
501 
503  static void handle_feature(void* instance, void* data) {
504  Derived* d = reinterpret_cast<Derived*>(instance);
505  I<Derived>* fe = static_cast<I<Derived>*>(d);
506  fe->m_ok = true;
507  }
508 
509  bool check_ok() {
510  if (LVTK_DEBUG) {
511  std::clog<<" [LV2::SaveRestore] Validation "
512  <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
513  }
514  return this->m_ok;
515  }
516 
518  static const void* extension_data(const char* uri) {
519  if (!std::strcmp(uri, LVTK_SAVERESTORE_URI)) {
520  static LV2SR_Descriptor srdesc = { &I<Derived>::_save,
521  &I<Derived>::_restore };
522  return &srdesc;
523  }
524  return 0;
525  }
526 
539  char* save(const char* directory, LV2SR_File*** files) { return 0; }
540 
547  char* restore(const LV2SR_File** files) { return 0; }
548 
549  protected:
550 
553  static char* _save(LV2_Handle h,
554  const char* directory, LV2SR_File*** files) {
555  if (LVTK_DEBUG) {
556  std::clog<<"[LV2::SaveRestore] Host called save().\n"
557  <<" directory: \""<<directory<<"\""<<std::endl;
558  }
559  return reinterpret_cast<Derived*>(h)->save(directory, files);
560  }
561 
564  static char* _restore(LV2_Handle h, const LV2SR_File** files) {
565  if (LVTK_DEBUG) {
566  std::clog<<"[LV2::SaveRestore] Host called restore().\n"
567  <<" Files:\n";
568  for (LV2SR_File const** f = files; (*f) != 0; ++f)
569  std::clog<<" \""<<(*f)->name<<"\" -> \""<<(*f)->path<<"\"\n";
570  std::clog<<std::flush;
571  }
572  return reinterpret_cast<Derived*>(h)->restore(files);
573  }
574 
575  };
576  };
577 
578 
586  LVTK_MIXIN_CLASS MsgContext {
587 
592  LVTK_MIXIN_DERIVED {
593 
595  static void map_feature_handlers(feature_handler_map& hmap) {
596  hmap[LVTK_CONTEXT_MESSAGE] = &I<Derived>::handle_feature;
597  }
598 
600  static void handle_feature(void* instance, void* data) {
601  Derived* d = reinterpret_cast<Derived*>(instance);
602  I<Derived>* fe = static_cast<I<Derived>*>(d);
603  fe->m_ok = true;
604  }
605 
606  bool check_ok() {
607  if (LVTK_DEBUG) {
608  std::clog<<" [LV2::MsgContext] Validation "
609  <<(this->m_ok ? "succeeded" : "failed")<<"."<<std::endl;
610  }
611  return this->m_ok;
612  }
613 
615  static const void* extension_data(const char* uri) {
616  if (!std::strcmp(uri, LVTK_CONTEXT_MESSAGE)) {
617  static LVTK_Blocking_Context desc = { &I<Derived>::_blocking_run,
618  &I<Derived>::_connect_port };
619  return &desc;
620  }
621  return 0;
622  }
623 
628  bool blocking_run(uint8_t* outputs_written) { return false; }
629 
630  protected:
631 
634  static bool _blocking_run(LV2_Handle h, uint8_t* outputs_written) {
635  if (LVTK_DEBUG)
636  std::clog<<"[LV2::MsgContext] Host called blocking_run()."<<std::endl;
637  return reinterpret_cast<Derived*>(h)->blocking_run(outputs_written);
638  }
639 
642  static void _connect_port(LV2_Handle h, uint32_t port, void* buffer) {
643  reinterpret_cast<Derived*>(h)->connect_port(port, buffer);
644  }
645 
646  };
647  };
648 
649 } /* namespace lvtk */
650 
651 
652 #endif
653 
654 #endif /* LVTK_LV2_EXTRA_HPP */