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 MATRIXMSST_WIDTH               0
30 #define MATRIXMSST_MID                 1
31 #define MATRIXMSST_SIDE                2
32 #define MATRIXMSST_LEFT                3
33 #define MATRIXMSST_RIGHT               4
34 
35 static LADSPA_Descriptor *matrixMSStDescriptor = NULL;
36 
37 typedef struct {
38 	LADSPA_Data *width;
39 	LADSPA_Data *mid;
40 	LADSPA_Data *side;
41 	LADSPA_Data *left;
42 	LADSPA_Data *right;
43 	LADSPA_Data run_adding_gain;
44 } MatrixMSSt;
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 matrixMSStDescriptor;
58 	default:
59 		return NULL;
60 	}
61 }
62 
cleanupMatrixMSSt(LADSPA_Handle instance)63 static void cleanupMatrixMSSt(LADSPA_Handle instance) {
64 	free(instance);
65 }
66 
connectPortMatrixMSSt(LADSPA_Handle instance,unsigned long port,LADSPA_Data * data)67 static void connectPortMatrixMSSt(
68  LADSPA_Handle instance,
69  unsigned long port,
70  LADSPA_Data *data) {
71 	MatrixMSSt *plugin;
72 
73 	plugin = (MatrixMSSt *)instance;
74 	switch (port) {
75 	case MATRIXMSST_WIDTH:
76 		plugin->width = data;
77 		break;
78 	case MATRIXMSST_MID:
79 		plugin->mid = data;
80 		break;
81 	case MATRIXMSST_SIDE:
82 		plugin->side = data;
83 		break;
84 	case MATRIXMSST_LEFT:
85 		plugin->left = data;
86 		break;
87 	case MATRIXMSST_RIGHT:
88 		plugin->right = data;
89 		break;
90 	}
91 }
92 
instantiateMatrixMSSt(const LADSPA_Descriptor * descriptor,unsigned long s_rate)93 static LADSPA_Handle instantiateMatrixMSSt(
94  const LADSPA_Descriptor *descriptor,
95  unsigned long s_rate) {
96 	MatrixMSSt *plugin_data = (MatrixMSSt *)calloc(1, sizeof(MatrixMSSt));
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 
runMatrixMSSt(LADSPA_Handle instance,unsigned long sample_count)110 static void runMatrixMSSt(LADSPA_Handle instance, unsigned long sample_count) {
111 	MatrixMSSt *plugin_data = (MatrixMSSt *)instance;
112 
113 	/* Width (float value) */
114 	const LADSPA_Data width = *(plugin_data->width);
115 
116 	/* Mid (array of floats of length sample_count) */
117 	const LADSPA_Data * const mid = plugin_data->mid;
118 
119 	/* Side (array of floats of length sample_count) */
120 	const LADSPA_Data * const side = plugin_data->side;
121 
122 	/* Left (array of floats of length sample_count) */
123 	LADSPA_Data * const left = plugin_data->left;
124 
125 	/* Right (array of floats of length sample_count) */
126 	LADSPA_Data * const right = plugin_data->right;
127 
128 #line 16 "matrix_ms_st_1421.xml"
129 	unsigned long pos;
130 
131 	for (pos = 0; pos < sample_count; pos++) {
132 	  buffer_write(left[pos], mid[pos] + side[pos] * width);
133 	  buffer_write(right[pos], mid[pos] - side[pos] * width);
134 	}
135 }
136 #undef buffer_write
137 #undef RUN_ADDING
138 #undef RUN_REPLACING
139 
140 #define buffer_write(b, v) (b += (v) * run_adding_gain)
141 #define RUN_ADDING    1
142 #define RUN_REPLACING 0
143 
setRunAddingGainMatrixMSSt(LADSPA_Handle instance,LADSPA_Data gain)144 static void setRunAddingGainMatrixMSSt(LADSPA_Handle instance, LADSPA_Data gain) {
145 	((MatrixMSSt *)instance)->run_adding_gain = gain;
146 }
147 
runAddingMatrixMSSt(LADSPA_Handle instance,unsigned long sample_count)148 static void runAddingMatrixMSSt(LADSPA_Handle instance, unsigned long sample_count) {
149 	MatrixMSSt *plugin_data = (MatrixMSSt *)instance;
150 	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;
151 
152 	/* Width (float value) */
153 	const LADSPA_Data width = *(plugin_data->width);
154 
155 	/* Mid (array of floats of length sample_count) */
156 	const LADSPA_Data * const mid = plugin_data->mid;
157 
158 	/* Side (array of floats of length sample_count) */
159 	const LADSPA_Data * const side = plugin_data->side;
160 
161 	/* Left (array of floats of length sample_count) */
162 	LADSPA_Data * const left = plugin_data->left;
163 
164 	/* Right (array of floats of length sample_count) */
165 	LADSPA_Data * const right = plugin_data->right;
166 
167 #line 16 "matrix_ms_st_1421.xml"
168 	unsigned long pos;
169 
170 	for (pos = 0; pos < sample_count; pos++) {
171 	  buffer_write(left[pos], mid[pos] + side[pos] * width);
172 	  buffer_write(right[pos], mid[pos] - side[pos] * width);
173 	}
174 }
175 
swh_init()176 static void __attribute__((constructor)) swh_init() {
177 	char **port_names;
178 	LADSPA_PortDescriptor *port_descriptors;
179 	LADSPA_PortRangeHint *port_range_hints;
180 
181 #ifdef ENABLE_NLS
182 #define D_(s) dgettext(PACKAGE, s)
183 	bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
184 #else
185 #define D_(s) (s)
186 #endif
187 
188 
189 	matrixMSStDescriptor =
190 	 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
191 
192 	if (matrixMSStDescriptor) {
193 		matrixMSStDescriptor->UniqueID = 1421;
194 		matrixMSStDescriptor->Label = "matrixMSSt";
195 		matrixMSStDescriptor->Properties =
196 		 LADSPA_PROPERTY_HARD_RT_CAPABLE;
197 		matrixMSStDescriptor->Name =
198 		 D_("Matrix: MS to Stereo");
199 		matrixMSStDescriptor->Maker =
200 		 "Steve Harris <steve@plugin.org.uk>";
201 		matrixMSStDescriptor->Copyright =
202 		 "GPL";
203 		matrixMSStDescriptor->PortCount = 5;
204 
205 		port_descriptors = (LADSPA_PortDescriptor *)calloc(5,
206 		 sizeof(LADSPA_PortDescriptor));
207 		matrixMSStDescriptor->PortDescriptors =
208 		 (const LADSPA_PortDescriptor *)port_descriptors;
209 
210 		port_range_hints = (LADSPA_PortRangeHint *)calloc(5,
211 		 sizeof(LADSPA_PortRangeHint));
212 		matrixMSStDescriptor->PortRangeHints =
213 		 (const LADSPA_PortRangeHint *)port_range_hints;
214 
215 		port_names = (char **)calloc(5, sizeof(char*));
216 		matrixMSStDescriptor->PortNames =
217 		 (const char **)port_names;
218 
219 		/* Parameters for Width */
220 		port_descriptors[MATRIXMSST_WIDTH] =
221 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
222 		port_names[MATRIXMSST_WIDTH] =
223 		 D_("Width");
224 		port_range_hints[MATRIXMSST_WIDTH].HintDescriptor =
225 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_1;
226 		port_range_hints[MATRIXMSST_WIDTH].LowerBound = 0;
227 		port_range_hints[MATRIXMSST_WIDTH].UpperBound = 2;
228 
229 		/* Parameters for Mid */
230 		port_descriptors[MATRIXMSST_MID] =
231 		 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
232 		port_names[MATRIXMSST_MID] =
233 		 D_("Mid");
234 		port_range_hints[MATRIXMSST_MID].HintDescriptor = 0;
235 
236 		/* Parameters for Side */
237 		port_descriptors[MATRIXMSST_SIDE] =
238 		 LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
239 		port_names[MATRIXMSST_SIDE] =
240 		 D_("Side");
241 		port_range_hints[MATRIXMSST_SIDE].HintDescriptor = 0;
242 
243 		/* Parameters for Left */
244 		port_descriptors[MATRIXMSST_LEFT] =
245 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
246 		port_names[MATRIXMSST_LEFT] =
247 		 D_("Left");
248 		port_range_hints[MATRIXMSST_LEFT].HintDescriptor = 0;
249 
250 		/* Parameters for Right */
251 		port_descriptors[MATRIXMSST_RIGHT] =
252 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
253 		port_names[MATRIXMSST_RIGHT] =
254 		 D_("Right");
255 		port_range_hints[MATRIXMSST_RIGHT].HintDescriptor = 0;
256 
257 		matrixMSStDescriptor->activate = NULL;
258 		matrixMSStDescriptor->cleanup = cleanupMatrixMSSt;
259 		matrixMSStDescriptor->connect_port = connectPortMatrixMSSt;
260 		matrixMSStDescriptor->deactivate = NULL;
261 		matrixMSStDescriptor->instantiate = instantiateMatrixMSSt;
262 		matrixMSStDescriptor->run = runMatrixMSSt;
263 		matrixMSStDescriptor->run_adding = runAddingMatrixMSSt;
264 		matrixMSStDescriptor->set_run_adding_gain = setRunAddingGainMatrixMSSt;
265 	}
266 }
267 
swh_fini()268 static void __attribute__((destructor)) swh_fini() {
269 	if (matrixMSStDescriptor) {
270 		free((LADSPA_PortDescriptor *)matrixMSStDescriptor->PortDescriptors);
271 		free((char **)matrixMSStDescriptor->PortNames);
272 		free((LADSPA_PortRangeHint *)matrixMSStDescriptor->PortRangeHints);
273 		free(matrixMSStDescriptor);
274 	}
275 	matrixMSStDescriptor = NULL;
276 
277 }
278