Descriptor.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. Descriptor.h
  3. Copyright 2004-10 Tim Goetze <tim@quitte.de>
  4. http://quitte.de/dsp/
  5. Creating a LADSPA_Descriptor for a CAPS plugin via a C++ template,
  6. saving a virtual function call compared to the usual method used
  7. for C++ plugins in a C context.
  8. Descriptor<P> expects P to declare some common methods, like init(),
  9. activate() etc, plus a static port_info[] and LADSPA_Data * ports[]
  10. and adding_gain. (P should derive from Plugin, too.)
  11. */
  12. /*
  13. This program is free software; you can redistribute it and/or
  14. modify it under the terms of the GNU General Public License
  15. as published by the Free Software Foundation; either version 2
  16. of the License, or (at your option) any later version.
  17. This program is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. GNU General Public License for more details.
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  24. 02111-1307, USA or point your web browser to http://www.gnu.org.
  25. */
  26. #ifndef _DESCRIPTOR_H_
  27. #define _DESCRIPTOR_H_
  28. #ifdef __SSE__
  29. #include <xmmintrin.h>
  30. #endif
  31. #ifdef __SSE3__
  32. #include <pmmintrin.h>
  33. #endif
  34. /* common stub for Descriptor makes it possible to delete() without special-
  35. * casing for every plugin class.
  36. */
  37. class DescriptorStub
  38. : public LADSPA_Descriptor
  39. {
  40. public:
  41. DescriptorStub()
  42. {
  43. PortCount = 0;
  44. }
  45. ~DescriptorStub()
  46. {
  47. if (PortCount)
  48. {
  49. delete [] PortNames;
  50. delete [] PortDescriptors;
  51. delete [] PortRangeHints;
  52. }
  53. }
  54. };
  55. inline void
  56. processor_specific_denormal_measures()
  57. {
  58. #ifdef __SSE3__
  59. /* this one works reliably on a 6600 Core2 */
  60. _MM_SET_DENORMALS_ZERO_MODE (_MM_DENORMALS_ZERO_ON);
  61. #endif
  62. #ifdef __SSE__
  63. /* this one doesn't ... */
  64. _MM_SET_FLUSH_ZERO_MODE (_MM_FLUSH_ZERO_ON);
  65. #endif
  66. }
  67. template <class T>
  68. class Descriptor
  69. : public DescriptorStub
  70. {
  71. public:
  72. LADSPA_PortRangeHint * ranges;
  73. public:
  74. Descriptor() { setup(); }
  75. void setup();
  76. void autogen()
  77. {
  78. PortCount = (sizeof (T::port_info) / sizeof (PortInfo));
  79. /* unroll PortInfo members */
  80. const char ** names = new const char * [PortCount];
  81. LADSPA_PortDescriptor * desc = new LADSPA_PortDescriptor [PortCount];
  82. ranges = new LADSPA_PortRangeHint [PortCount];
  83. /* could also assign directly but const_cast is ugly. */
  84. for (int i = 0; i < (int) PortCount; ++i)
  85. {
  86. names[i] = T::port_info[i].name;
  87. desc[i] = T::port_info[i].descriptor;
  88. ranges[i] = T::port_info[i].range;
  89. }
  90. PortNames = names;
  91. PortDescriptors = desc;
  92. PortRangeHints = ranges;
  93. /* LADSPA_Descriptor vtable entries */
  94. instantiate = _instantiate;
  95. connect_port = _connect_port;
  96. activate = _activate;
  97. run = _run;
  98. run_adding = _run_adding;
  99. set_run_adding_gain = _set_run_adding_gain;
  100. deactivate = 0;
  101. cleanup = _cleanup;
  102. }
  103. static LADSPA_Handle _instantiate (
  104. const struct _LADSPA_Descriptor * d, ulong fs)
  105. {
  106. T * plugin = new T();
  107. int n = (int) d->PortCount;
  108. LADSPA_PortRangeHint * ranges = ((Descriptor *) d)->ranges;
  109. plugin->ranges = ranges;
  110. plugin->ports = new sample_t * [n];
  111. /* connect to lower bound as a safety measure */
  112. for (int i = 0; i < n; ++i)
  113. plugin->ports[i] = &(ranges[i].LowerBound);
  114. plugin->fs = fs;
  115. plugin->normal = NOISE_FLOOR;
  116. plugin->init();
  117. return plugin;
  118. }
  119. static void _connect_port (LADSPA_Handle h, ulong i, LADSPA_Data * p)
  120. {
  121. ((T *) h)->ports[i] = p;
  122. }
  123. static void _activate (LADSPA_Handle h)
  124. {
  125. T * plugin = (T *) h;
  126. plugin->first_run = 1;
  127. /* since none of the plugins do any RT-critical work in
  128. * activate(), it's safe to defer the actual call to the
  129. * plugin's activate() method for the first run() after
  130. * the host called in here.
  131. *
  132. * It's the simplest way to prevent a parameter smoothing sweep
  133. * in the first audio block after activation.
  134. plugin->activate();
  135. */
  136. }
  137. static void _run (LADSPA_Handle h, ulong n)
  138. {
  139. T * plugin = (T *) h;
  140. /* We don't reset the processor flags later, it's true. */
  141. processor_specific_denormal_measures();
  142. /* If this is the first audio block after activation,
  143. * initialize the plugin from the current set of parameters. */
  144. if (plugin->first_run)
  145. {
  146. plugin->activate();
  147. plugin->first_run = 0;
  148. }
  149. plugin->run (n);
  150. plugin->normal = -plugin->normal;
  151. }
  152. static void _run_adding (LADSPA_Handle h, ulong n)
  153. {
  154. T * plugin = (T *) h;
  155. /* We don't reset the processor flags later, it's true. */
  156. processor_specific_denormal_measures();
  157. /* If this is the first audio block after activation,
  158. * initialize the plugin from the current set of parameters. */
  159. if (plugin->first_run)
  160. {
  161. plugin->activate();
  162. plugin->first_run = 0;
  163. }
  164. plugin->run_adding (n);
  165. plugin->normal = -plugin->normal;
  166. }
  167. static void _set_run_adding_gain (LADSPA_Handle h, LADSPA_Data g)
  168. {
  169. T * plugin = (T *) h;
  170. plugin->adding_gain = g;
  171. }
  172. static void _cleanup (LADSPA_Handle h)
  173. {
  174. T * plugin = (T *) h;
  175. delete [] plugin->ports;
  176. delete plugin;
  177. }
  178. };
  179. #endif /* _DESCRIPTOR_H_ */