123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- /*
- Descriptor.h
-
- Copyright 2004-10 Tim Goetze <tim@quitte.de>
-
- http://quitte.de/dsp/
- Creating a LADSPA_Descriptor for a CAPS plugin via a C++ template,
- saving a virtual function call compared to the usual method used
- for C++ plugins in a C context.
- Descriptor<P> expects P to declare some common methods, like init(),
- activate() etc, plus a static port_info[] and LADSPA_Data * ports[]
- and adding_gain. (P should derive from Plugin, too.)
-
- */
- /*
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA or point your web browser to http://www.gnu.org.
- */
- #ifndef _DESCRIPTOR_H_
- #define _DESCRIPTOR_H_
- #ifdef __SSE__
- #include <xmmintrin.h>
- #endif
- #ifdef __SSE3__
- #include <pmmintrin.h>
- #endif
- /* common stub for Descriptor makes it possible to delete() without special-
- * casing for every plugin class.
- */
- class DescriptorStub
- : public LADSPA_Descriptor
- {
- public:
- DescriptorStub()
- {
- PortCount = 0;
- }
- ~DescriptorStub()
- {
- if (PortCount)
- {
- delete [] PortNames;
- delete [] PortDescriptors;
- delete [] PortRangeHints;
- }
- }
- };
- inline void
- processor_specific_denormal_measures()
- {
- #ifdef __SSE3__
- /* this one works reliably on a 6600 Core2 */
- _MM_SET_DENORMALS_ZERO_MODE (_MM_DENORMALS_ZERO_ON);
- #endif
- #ifdef __SSE__
- /* this one doesn't ... */
- _MM_SET_FLUSH_ZERO_MODE (_MM_FLUSH_ZERO_ON);
- #endif
- }
- template <class T>
- class Descriptor
- : public DescriptorStub
- {
- public:
- LADSPA_PortRangeHint * ranges;
- public:
- Descriptor() { setup(); }
- void setup();
- void autogen()
- {
- PortCount = (sizeof (T::port_info) / sizeof (PortInfo));
- /* unroll PortInfo members */
- const char ** names = new const char * [PortCount];
- LADSPA_PortDescriptor * desc = new LADSPA_PortDescriptor [PortCount];
- ranges = new LADSPA_PortRangeHint [PortCount];
- /* could also assign directly but const_cast is ugly. */
- for (int i = 0; i < (int) PortCount; ++i)
- {
- names[i] = T::port_info[i].name;
- desc[i] = T::port_info[i].descriptor;
- ranges[i] = T::port_info[i].range;
- }
- PortNames = names;
- PortDescriptors = desc;
- PortRangeHints = ranges;
-
- /* LADSPA_Descriptor vtable entries */
- instantiate = _instantiate;
- connect_port = _connect_port;
- activate = _activate;
- run = _run;
- run_adding = _run_adding;
- set_run_adding_gain = _set_run_adding_gain;
- deactivate = 0;
- cleanup = _cleanup;
- }
- static LADSPA_Handle _instantiate (
- const struct _LADSPA_Descriptor * d, ulong fs)
- {
- T * plugin = new T();
- int n = (int) d->PortCount;
- LADSPA_PortRangeHint * ranges = ((Descriptor *) d)->ranges;
- plugin->ranges = ranges;
- plugin->ports = new sample_t * [n];
- /* connect to lower bound as a safety measure */
- for (int i = 0; i < n; ++i)
- plugin->ports[i] = &(ranges[i].LowerBound);
- plugin->fs = fs;
- plugin->normal = NOISE_FLOOR;
- plugin->init();
- return plugin;
- }
-
- static void _connect_port (LADSPA_Handle h, ulong i, LADSPA_Data * p)
- {
- ((T *) h)->ports[i] = p;
- }
- static void _activate (LADSPA_Handle h)
- {
- T * plugin = (T *) h;
- plugin->first_run = 1;
- /* since none of the plugins do any RT-critical work in
- * activate(), it's safe to defer the actual call to the
- * plugin's activate() method for the first run() after
- * the host called in here.
- *
- * It's the simplest way to prevent a parameter smoothing sweep
- * in the first audio block after activation.
- plugin->activate();
- */
- }
- static void _run (LADSPA_Handle h, ulong n)
- {
- T * plugin = (T *) h;
- /* We don't reset the processor flags later, it's true. */
- processor_specific_denormal_measures();
- /* If this is the first audio block after activation,
- * initialize the plugin from the current set of parameters. */
- if (plugin->first_run)
- {
- plugin->activate();
- plugin->first_run = 0;
- }
- plugin->run (n);
- plugin->normal = -plugin->normal;
- }
-
- static void _run_adding (LADSPA_Handle h, ulong n)
- {
- T * plugin = (T *) h;
- /* We don't reset the processor flags later, it's true. */
- processor_specific_denormal_measures();
- /* If this is the first audio block after activation,
- * initialize the plugin from the current set of parameters. */
- if (plugin->first_run)
- {
- plugin->activate();
- plugin->first_run = 0;
- }
- plugin->run_adding (n);
- plugin->normal = -plugin->normal;
- }
-
- static void _set_run_adding_gain (LADSPA_Handle h, LADSPA_Data g)
- {
- T * plugin = (T *) h;
- plugin->adding_gain = g;
- }
- static void _cleanup (LADSPA_Handle h)
- {
- T * plugin = (T *) h;
- delete [] plugin->ports;
- delete plugin;
- }
- };
- #endif /* _DESCRIPTOR_H_ */
|