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 SPLIT_INPUT                    0
30 #define SPLIT_OUT2                     1
31 #define SPLIT_OUT1                     2
32 
33 static LADSPA_Descriptor *splitDescriptor = NULL;
34 
35 typedef struct {
36 	LADSPA_Data *input;
37 	LADSPA_Data *out2;
38 	LADSPA_Data *out1;
39 	LADSPA_Data run_adding_gain;
40 } Split;
41 
42 _WINDOWS_DLL_EXPORT_
ladspa_descriptor(unsigned long index)43 const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) {
44 
45 #ifdef WIN32
46 	if (bIsFirstTime) {
47 		swh_init();
48 		bIsFirstTime = 0;
49 	}
50 #endif
51 	switch (index) {
52 	case 0:
53 		return splitDescriptor;
54 	default:
55 		return NULL;
56 	}
57 }
58 
cleanupSplit(LADSPA_Handle instance)59 static void cleanupSplit(LADSPA_Handle instance) {
60 	free(instance);
61 }
62 
connectPortSplit(LADSPA_Handle instance,unsigned long port,LADSPA_Data * data)63 static void connectPortSplit(
64  LADSPA_Handle instance,
65  unsigned long port,
66  LADSPA_Data *data) {
67 	Split *plugin;
68 
69 	plugin = (Split *)instance;
70 	switch (port) {
71 	case SPLIT_INPUT:
72 		plugin->input = data;
73 		break;
74 	case SPLIT_OUT2:
75 		plugin->out2 = data;
76 		break;
77 	case SPLIT_OUT1:
78 		plugin->out1 = data;
79 		break;
80 	}
81 }
82 
instantiateSplit(const LADSPA_Descriptor * descriptor,unsigned long s_rate)83 static LADSPA_Handle instantiateSplit(
84  const LADSPA_Descriptor *descriptor,
85  unsigned long s_rate) {
86 	Split *plugin_data = (Split *)calloc(1, sizeof(Split));
87 	plugin_data->run_adding_gain = 1.0f;
88 
89 	return (LADSPA_Handle)plugin_data;
90 }
91 
92 #undef buffer_write
93 #undef RUN_ADDING
94 #undef RUN_REPLACING
95 
96 #define buffer_write(b, v) (b = v)
97 #define RUN_ADDING    0
98 #define RUN_REPLACING 1
99 
runSplit(LADSPA_Handle instance,unsigned long sample_count)100 static void runSplit(LADSPA_Handle instance, unsigned long sample_count) {
101 	Split *plugin_data = (Split *)instance;
102 
103 	/* Input (array of floats of length sample_count) */
104 	const LADSPA_Data * const input = plugin_data->input;
105 
106 	/* Output 1 (array of floats of length sample_count) */
107 	LADSPA_Data * const out2 = plugin_data->out2;
108 
109 	/* Output 2 (array of floats of length sample_count) */
110 	LADSPA_Data * const out1 = plugin_data->out1;
111 
112 #line 16 "split_1406.xml"
113 	unsigned long pos;
114 
115 	for (pos = 0; pos < sample_count; pos++) {
116 	        const LADSPA_Data in = input[pos];
117 
118 	        buffer_write(out1[pos], in);
119 	        buffer_write(out2[pos], in);
120 	}
121 }
122 #undef buffer_write
123 #undef RUN_ADDING
124 #undef RUN_REPLACING
125 
126 #define buffer_write(b, v) (b += (v) * run_adding_gain)
127 #define RUN_ADDING    1
128 #define RUN_REPLACING 0
129 
setRunAddingGainSplit(LADSPA_Handle instance,LADSPA_Data gain)130 static void setRunAddingGainSplit(LADSPA_Handle instance, LADSPA_Data gain) {
131 	((Split *)instance)->run_adding_gain = gain;
132 }
133 
runAddingSplit(LADSPA_Handle instance,unsigned long sample_count)134 static void runAddingSplit(LADSPA_Handle instance, unsigned long sample_count) {
135 	Split *plugin_data = (Split *)instance;
136 	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;
137 
138 	/* Input (array of floats of length sample_count) */
139 	const LADSPA_Data * const input = plugin_data->input;
140 
141 	/* Output 1 (array of floats of length sample_count) */
142 	LADSPA_Data * const out2 = plugin_data->out2;
143 
144 	/* Output 2 (array of floats of length sample_count) */
145 	LADSPA_Data * const out1 = plugin_data->out1;
146 
147 #line 16 "split_1406.xml"
148 	unsigned long pos;
149 
150 	for (pos = 0; pos < sample_count; pos++) {
151 	        const LADSPA_Data in = input[pos];
152 
153 	        buffer_write(out1[pos], in);
154 	        buffer_write(out2[pos], in);
155 	}
156 }
157 
swh_init()158 static void __attribute__((constructor)) swh_init() {
159 	char **port_names;
160 	LADSPA_PortDescriptor *port_descriptors;
161 	LADSPA_PortRangeHint *port_range_hints;
162 
163 #ifdef ENABLE_NLS
164 #define D_(s) dgettext(PACKAGE, s)
165 	bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
166 #else
167 #define D_(s) (s)
168 #endif
169 
170 
171 	splitDescriptor =
172 	 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
173 
174 	if (splitDescriptor) {
175 		splitDescriptor->UniqueID = 1406;
176 		splitDescriptor->Label = "split";
177 		splitDescriptor->Properties =
178 		 LADSPA_PROPERTY_HARD_RT_CAPABLE;
179 		splitDescriptor->Name =
180 		 D_("Mono to Stereo splitter");
181 		splitDescriptor->Maker =
182 		 "Frank Neumann <franky@users.sourceforge.net>";
183 		splitDescriptor->Copyright =
184 		 "GPL";
185 		splitDescriptor->PortCount = 3;
186 
187 		port_descriptors = (LADSPA_PortDescriptor *)calloc(3,
188 		 sizeof(LADSPA_PortDescriptor));
189 		splitDescriptor->PortDescriptors =
190 		 (const LADSPA_PortDescriptor *)port_descriptors;
191 
192 		port_range_hints = (LADSPA_PortRangeHint *)calloc(3,
193 		 sizeof(LADSPA_PortRangeHint));
194 		splitDescriptor->PortRangeHints =
195 		 (const LADSPA_PortRangeHint *)port_range_hints;
196 
197 		port_names = (char **)calloc(3, sizeof(char*));
198 		splitDescriptor->PortNames =
199 		 (const char **)port_names;
200 
201 		/* Parameters for Input */
202 		port_descriptors[SPLIT_INPUT] =
203 		 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
204 		port_names[SPLIT_INPUT] =
205 		 D_("Input");
206 		port_range_hints[SPLIT_INPUT].HintDescriptor =
207 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
208 		port_range_hints[SPLIT_INPUT].LowerBound = -1;
209 		port_range_hints[SPLIT_INPUT].UpperBound = +1;
210 
211 		/* Parameters for Output 1 */
212 		port_descriptors[SPLIT_OUT2] =
213 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
214 		port_names[SPLIT_OUT2] =
215 		 D_("Output 1");
216 		port_range_hints[SPLIT_OUT2].HintDescriptor =
217 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
218 		port_range_hints[SPLIT_OUT2].LowerBound = -1;
219 		port_range_hints[SPLIT_OUT2].UpperBound = +1;
220 
221 		/* Parameters for Output 2 */
222 		port_descriptors[SPLIT_OUT1] =
223 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
224 		port_names[SPLIT_OUT1] =
225 		 D_("Output 2");
226 		port_range_hints[SPLIT_OUT1].HintDescriptor =
227 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
228 		port_range_hints[SPLIT_OUT1].LowerBound = -1;
229 		port_range_hints[SPLIT_OUT1].UpperBound = +1;
230 
231 		splitDescriptor->activate = NULL;
232 		splitDescriptor->cleanup = cleanupSplit;
233 		splitDescriptor->connect_port = connectPortSplit;
234 		splitDescriptor->deactivate = NULL;
235 		splitDescriptor->instantiate = instantiateSplit;
236 		splitDescriptor->run = runSplit;
237 		splitDescriptor->run_adding = runAddingSplit;
238 		splitDescriptor->set_run_adding_gain = setRunAddingGainSplit;
239 	}
240 }
241 
swh_fini()242 static void __attribute__((destructor)) swh_fini() {
243 	if (splitDescriptor) {
244 		free((LADSPA_PortDescriptor *)splitDescriptor->PortDescriptors);
245 		free((char **)splitDescriptor->PortNames);
246 		free((LADSPA_PortRangeHint *)splitDescriptor->PortRangeHints);
247 		free(splitDescriptor);
248 	}
249 	splitDescriptor = NULL;
250 
251 }
252