1 #include <stdlib.h>
2 #include <string.h>
3 #ifndef WIN32
4 #include "config.h"
5 #endif
6 
7 #ifdef ENABLE_NLS
8 #include <libintl.h>
9 #endif
10 
11 #define         _ISOC9X_SOURCE  1
12 #define         _ISOC99_SOURCE  1
13 #define         __USE_ISOC99    1
14 #define         __USE_ISOC9X    1
15 
16 #include <math.h>
17 
18 #include "ladspa.h"
19 
20 #ifdef WIN32
21 #define _WINDOWS_DLL_EXPORT_ __declspec(dllexport)
22 int bIsFirstTime = 1;
23 static void __attribute__((constructor)) swh_init(); // forward declaration
24 #else
25 #define _WINDOWS_DLL_EXPORT_
26 #endif
27 
28 
29 #define KARAOKE_GAIN                   0
30 #define KARAOKE_LIN                    1
31 #define KARAOKE_RIN                    2
32 #define KARAOKE_LOUT                   3
33 #define KARAOKE_ROUT                   4
34 
35 static LADSPA_Descriptor *karaokeDescriptor = NULL;
36 
37 typedef struct {
38 	LADSPA_Data *gain;
39 	LADSPA_Data *lin;
40 	LADSPA_Data *rin;
41 	LADSPA_Data *lout;
42 	LADSPA_Data *rout;
43 	LADSPA_Data run_adding_gain;
44 } Karaoke;
45 
46 _WINDOWS_DLL_EXPORT_
ladspa_descriptor(unsigned long index)47 const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) {
48 
49 #ifdef WIN32
50 	if (bIsFirstTime) {
51 		swh_init();
52 		bIsFirstTime = 0;
53 	}
54 #endif
55 	switch (index) {
56 	case 0:
57 		return karaokeDescriptor;
58 	default:
59 		return NULL;
60 	}
61 }
62 
cleanupKaraoke(LADSPA_Handle instance)63 static void cleanupKaraoke(LADSPA_Handle instance) {
64 	free(instance);
65 }
66 
connectPortKaraoke(LADSPA_Handle instance,unsigned long port,LADSPA_Data * data)67 static void connectPortKaraoke(
68  LADSPA_Handle instance,
69  unsigned long port,
70  LADSPA_Data *data) {
71 	Karaoke *plugin;
72 
73 	plugin = (Karaoke *)instance;
74 	switch (port) {
75 	case KARAOKE_GAIN:
76 		plugin->gain = data;
77 		break;
78 	case KARAOKE_LIN:
79 		plugin->lin = data;
80 		break;
81 	case KARAOKE_RIN:
82 		plugin->rin = data;
83 		break;
84 	case KARAOKE_LOUT:
85 		plugin->lout = data;
86 		break;
87 	case KARAOKE_ROUT:
88 		plugin->rout = data;
89 		break;
90 	}
91 }
92 
instantiateKaraoke(const LADSPA_Descriptor * descriptor,unsigned long s_rate)93 static LADSPA_Handle instantiateKaraoke(
94  const LADSPA_Descriptor *descriptor,
95  unsigned long s_rate) {
96 	Karaoke *plugin_data = (Karaoke *)calloc(1, sizeof(Karaoke));
97 	plugin_data->run_adding_gain = 1.0f;
98 
99 	return (LADSPA_Handle)plugin_data;
100 }
101 
102 #undef buffer_write
103 #undef RUN_ADDING
104 #undef RUN_REPLACING
105 
106 #define buffer_write(b, v) (b = v)
107 #define RUN_ADDING    0
108 #define RUN_REPLACING 1
109 
runKaraoke(LADSPA_Handle instance,unsigned long sample_count)110 static void runKaraoke(LADSPA_Handle instance, unsigned long sample_count) {
111 	Karaoke *plugin_data = (Karaoke *)instance;
112 
113 	/* Vocal volume (dB) (float value) */
114 	const LADSPA_Data gain = *(plugin_data->gain);
115 
116 	/* Left in (array of floats of length sample_count) */
117 	const LADSPA_Data * const lin = plugin_data->lin;
118 
119 	/* Right in (array of floats of length sample_count) */
120 	const LADSPA_Data * const rin = plugin_data->rin;
121 
122 	/* Left out (array of floats of length sample_count) */
123 	LADSPA_Data * const lout = plugin_data->lout;
124 
125 	/* Right out (array of floats of length sample_count) */
126 	LADSPA_Data * const rout = plugin_data->rout;
127 
128 #line 17 "karaoke_1409.xml"
129 	unsigned long pos;
130 	float coef = pow(10.0f, gain * 0.05f) * 0.5f;
131 	float m, s;
132 
133 	for (pos = 0; pos < sample_count; pos++) {
134 	  m = lin[pos] + rin[pos];
135 	  s = lin[pos] - rin[pos];
136 	  buffer_write(lout[pos], m * coef + s * 0.5f);
137 	  buffer_write(rout[pos], m * coef - s * 0.5f);
138 	}
139 }
140 #undef buffer_write
141 #undef RUN_ADDING
142 #undef RUN_REPLACING
143 
144 #define buffer_write(b, v) (b += (v) * run_adding_gain)
145 #define RUN_ADDING    1
146 #define RUN_REPLACING 0
147 
setRunAddingGainKaraoke(LADSPA_Handle instance,LADSPA_Data gain)148 static void setRunAddingGainKaraoke(LADSPA_Handle instance, LADSPA_Data gain) {
149 	((Karaoke *)instance)->run_adding_gain = gain;
150 }
151 
runAddingKaraoke(LADSPA_Handle instance,unsigned long sample_count)152 static void runAddingKaraoke(LADSPA_Handle instance, unsigned long sample_count) {
153 	Karaoke *plugin_data = (Karaoke *)instance;
154 	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;
155 
156 	/* Vocal volume (dB) (float value) */
157 	const LADSPA_Data gain = *(plugin_data->gain);
158 
159 	/* Left in (array of floats of length sample_count) */
160 	const LADSPA_Data * const lin = plugin_data->lin;
161 
162 	/* Right in (array of floats of length sample_count) */
163 	const LADSPA_Data * const rin = plugin_data->rin;
164 
165 	/* Left out (array of floats of length sample_count) */
166 	LADSPA_Data * const lout = plugin_data->lout;
167 
168 	/* Right out (array of floats of length sample_count) */
169 	LADSPA_Data * const rout = plugin_data->rout;
170 
171 #line 17 "karaoke_1409.xml"
172 	unsigned long pos;
173 	float coef = pow(10.0f, gain * 0.05f) * 0.5f;
174 	float m, s;
175 
176 	for (pos = 0; pos < sample_count; pos++) {
177 	  m = lin[pos] + rin[pos];
178 	  s = lin[pos] - rin[pos];
179 	  buffer_write(lout[pos], m * coef + s * 0.5f);
180 	  buffer_write(rout[pos], m * coef - s * 0.5f);
181 	}
182 }
183 
swh_init()184 static void __attribute__((constructor)) swh_init() {
185 	char **port_names;
186 	LADSPA_PortDescriptor *port_descriptors;
187 	LADSPA_PortRangeHint *port_range_hints;
188 
189 #ifdef ENABLE_NLS
190 #define D_(s) dgettext(PACKAGE, s)
191 	bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
192 #else
193 #define D_(s) (s)
194 #endif
195 
196 
197 	karaokeDescriptor =
198 	 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
199 
200 	if (karaokeDescriptor) {
201 		karaokeDescriptor->UniqueID = 1409;
202 		karaokeDescriptor->Label = "karaoke";
203 		karaokeDescriptor->Properties =
204 		 LADSPA_PROPERTY_HARD_RT_CAPABLE;
205 		karaokeDescriptor->Name =
206 		 D_("Karaoke");
207 		karaokeDescriptor->Maker =
208 		 "Steve Harris <steve@plugin.org.uk>";
209 		karaokeDescriptor->Copyright =
210 		 "GPL";
211 		karaokeDescriptor->PortCount = 5;
212 
213 		port_descriptors = (LADSPA_PortDescriptor *)calloc(5,
214 		 sizeof(LADSPA_PortDescriptor));
215 		karaokeDescriptor->PortDescriptors =
216 		 (const LADSPA_PortDescriptor *)port_descriptors;
217 
218 		port_range_hints = (LADSPA_PortRangeHint *)calloc(5,
219 		 sizeof(LADSPA_PortRangeHint));
220 		karaokeDescriptor->PortRangeHints =
221 		 (const LADSPA_PortRangeHint *)port_range_hints;
222 
223 		port_names = (char **)calloc(5, sizeof(char*));
224 		karaokeDescriptor->PortNames =
225 		 (const char **)port_names;
226 
227 		/* Parameters for Vocal volume (dB) */
228 		port_descriptors[KARAOKE_GAIN] =
229 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
230 		port_names[KARAOKE_GAIN] =
231 		 D_("Vocal volume (dB)");
232 		port_range_hints[KARAOKE_GAIN].HintDescriptor =
233 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
234 		port_range_hints[KARAOKE_GAIN].LowerBound = -70;
235 		port_range_hints[KARAOKE_GAIN].UpperBound = 0;
236 
237 		/* Parameters for Left in */
238 		port_descriptors[KARAOKE_LIN] =
239 		 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
240 		port_names[KARAOKE_LIN] =
241 		 D_("Left in");
242 		port_range_hints[KARAOKE_LIN].HintDescriptor = 0;
243 
244 		/* Parameters for Right in */
245 		port_descriptors[KARAOKE_RIN] =
246 		 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
247 		port_names[KARAOKE_RIN] =
248 		 D_("Right in");
249 		port_range_hints[KARAOKE_RIN].HintDescriptor = 0;
250 
251 		/* Parameters for Left out */
252 		port_descriptors[KARAOKE_LOUT] =
253 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
254 		port_names[KARAOKE_LOUT] =
255 		 D_("Left out");
256 		port_range_hints[KARAOKE_LOUT].HintDescriptor = 0;
257 
258 		/* Parameters for Right out */
259 		port_descriptors[KARAOKE_ROUT] =
260 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
261 		port_names[KARAOKE_ROUT] =
262 		 D_("Right out");
263 		port_range_hints[KARAOKE_ROUT].HintDescriptor = 0;
264 
265 		karaokeDescriptor->activate = NULL;
266 		karaokeDescriptor->cleanup = cleanupKaraoke;
267 		karaokeDescriptor->connect_port = connectPortKaraoke;
268 		karaokeDescriptor->deactivate = NULL;
269 		karaokeDescriptor->instantiate = instantiateKaraoke;
270 		karaokeDescriptor->run = runKaraoke;
271 		karaokeDescriptor->run_adding = runAddingKaraoke;
272 		karaokeDescriptor->set_run_adding_gain = setRunAddingGainKaraoke;
273 	}
274 }
275 
swh_fini()276 static void __attribute__((destructor)) swh_fini() {
277 	if (karaokeDescriptor) {
278 		free((LADSPA_PortDescriptor *)karaokeDescriptor->PortDescriptors);
279 		free((char **)karaokeDescriptor->PortNames);
280 		free((LADSPA_PortRangeHint *)karaokeDescriptor->PortRangeHints);
281 		free(karaokeDescriptor);
282 	}
283 	karaokeDescriptor = NULL;
284 
285 }
286