1 /* sledgehammer.cpp
2 
3    "Dynamic Sledgehammer" - a thing to brutally mangle the dynamics of
4    a sound.
5 
6    (c) 2002 Nathaniel Virgo
7 
8    Computer Music Toolkit - a library of LADSPA plugins. Copyright (C)
9    2000-2002 Richard W.E. Furse. The author may be contacted at
10    richard@muse.demon.co.uk.
11 
12    This library is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public Licence as
14    published by the Free Software Foundation; either version 2 of the
15    Licence, or (at your option) any later version.
16 
17    This library is distributed in the hope that it will be useful, but
18    WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    General Public License for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this library; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25    02111-1307, USA. */
26 
27 /*****************************************************************************/
28 
29 #include <math.h>
30 #include <stdlib.h>
31 
32 /*****************************************************************************/
33 
34 #include "cmt.h"
35 #include "run_adding.h"
36 
37 /*****************************************************************************/
38 
39 namespace sledgehammer {
40 
41     enum {
42 	port_rate      = 0,
43 	port_mod_infl  = 1, // modulator influence
44 	port_car_infl  = 2, // carrier influence (0 to 1 for compression)
45 	port_modulator = 3,
46 	port_carrier   = 4,
47 	port_output    = 5,
48 	n_ports        = 6
49     };
50 
51 /** This plugin imposes the dynamics of one sound onto another.
52     It can be seen as a brutal compressor with a sidechain, or
53     as a kind of one-band vocoder. */
54     class Plugin : public CMT_PluginInstance {
55 	LADSPA_Data run_adding_gain;
56 	LADSPA_Data running_ms_mod;
57 	LADSPA_Data running_ms_car; // current mean square average
58     public:
Plugin(const LADSPA_Descriptor *,unsigned long)59 	Plugin(const LADSPA_Descriptor *,
60 	       unsigned long)
61 	    : CMT_PluginInstance(n_ports) {}
62 
63 	friend void activate(LADSPA_Handle instance);
64 
65 	template<OutputFunction write_output>
66 	friend void run(LADSPA_Handle instance,
67 			unsigned long sample_count);
68 
69 	friend void set_run_adding_gain(LADSPA_Handle instance,
70 					LADSPA_Data new_gain);
71     };
72 
activate(LADSPA_Handle instance)73     void activate(LADSPA_Handle instance) {
74 	Plugin *pp = (Plugin *) instance;
75 	Plugin &p  = *pp;
76 
77 	p.running_ms_mod = 0;
78 	p.running_ms_car = 0;
79     }
80 
81     template<OutputFunction write_output>
run(LADSPA_Handle instance,unsigned long sample_count)82     void run(LADSPA_Handle instance,
83 	     unsigned long sample_count) {
84 
85 	Plugin *pp = (Plugin *) instance;
86 	Plugin &p  = *pp;
87 
88 	LADSPA_Data   rate      = *pp->m_ppfPorts[port_rate];
89 	LADSPA_Data   mod_infl  = *pp->m_ppfPorts[port_mod_infl];
90 	LADSPA_Data   car_infl  = *pp->m_ppfPorts[port_car_infl];
91 	LADSPA_Data * modptr    =  pp->m_ppfPorts[port_modulator];
92 	LADSPA_Data * carptr    =  pp->m_ppfPorts[port_carrier];
93 	LADSPA_Data * out       =  pp->m_ppfPorts[port_output];
94 
95 	for ( unsigned long i = 0; i < sample_count ; ++i ) {
96 	    LADSPA_Data mod = *(modptr++);
97 	    LADSPA_Data car = *(carptr++);
98 
99 	    p.running_ms_mod = p.running_ms_mod*(1-rate) + (mod*mod)*rate;
100 	    p.running_ms_car = p.running_ms_car*(1-rate) + (car*car)*rate;
101 
102 	    LADSPA_Data rms_mod = sqrt(p.running_ms_mod);
103 	    LADSPA_Data rms_car = sqrt(p.running_ms_car);
104 
105 	    LADSPA_Data outsig = car;
106 
107 	    if (rms_car>0)
108 		outsig *= ((rms_car-0.5)*car_infl+0.5)/rms_car;
109 
110 	    outsig *= ((rms_mod-0.5)*mod_infl+0.5);
111 
112 	    write_output(out, outsig ,p.run_adding_gain);
113 	}
114     }
115 
set_run_adding_gain(LADSPA_Handle instance,LADSPA_Data new_gain)116     void set_run_adding_gain(LADSPA_Handle instance,
117 			     LADSPA_Data new_gain) {
118 	((Plugin *) instance)->run_adding_gain = new_gain;
119     }
120 
121     void
initialise()122     initialise() {
123 
124 	CMT_Descriptor * d = new CMT_Descriptor
125 	    (1848,
126 	     "sledgehammer",
127 	     LADSPA_PROPERTY_HARD_RT_CAPABLE,
128 	     "Dynamic Sledgehammer",
129 	     CMT_MAKER("Nathaniel Virgo"),
130 	     CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
131 	     NULL,
132 	     CMT_Instantiate<Plugin>,
133 	     activate,
134 	     run<write_output_normal>,
135 	     run<write_output_adding>,
136 	     set_run_adding_gain,
137 	     NULL);
138 
139 	d->addPort
140 	    (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
141 	     "Rate",
142 	     (LADSPA_HINT_BOUNDED_BELOW
143 	      | LADSPA_HINT_BOUNDED_ABOVE
144 	      | LADSPA_HINT_DEFAULT_MIDDLE),
145 	     0.00001,
146  	     0.001);
147 	d->addPort
148 	    (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
149 	     "Modulator influence",
150 	     (LADSPA_HINT_BOUNDED_BELOW
151 	      | LADSPA_HINT_BOUNDED_ABOVE
152 	      | LADSPA_HINT_DEFAULT_0),
153 	     -1,
154 	     1);
155 	d->addPort
156 	    (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
157 	     "Carrier influence",
158 	     (LADSPA_HINT_BOUNDED_BELOW
159 	      | LADSPA_HINT_BOUNDED_ABOVE
160 	      | LADSPA_HINT_DEFAULT_1),
161 	     -1,
162 	     1);
163 	d->addPort
164 	    (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
165 	     "Modulator");
166 	d->addPort
167 	    (LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
168 	     "Carrier");
169 	d->addPort
170 	    (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
171 	     "Output");
172 
173 	registerNewPluginDescriptor(d);
174 
175     }
176 
177 } // end of namespace
178 
179 /*****************************************************************************/
180 
181 /* EOF */
182 
183 
184 
185 
186 
187