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 #line 10 "sin_cos_1881.xml"
29 
30 #include "ladspa-util.h"
31 
32 #define SINCOS_FREQ                    0
33 #define SINCOS_PITCH                   1
34 #define SINCOS_SINE                    2
35 #define SINCOS_COSINE                  3
36 
37 static LADSPA_Descriptor *sinCosDescriptor = NULL;
38 
39 typedef struct {
40 	LADSPA_Data *freq;
41 	LADSPA_Data *pitch;
42 	LADSPA_Data *sine;
43 	LADSPA_Data *cosine;
44 	float        fs;
45 	double       last_om;
46 	double       phi;
47 	LADSPA_Data run_adding_gain;
48 } SinCos;
49 
50 _WINDOWS_DLL_EXPORT_
ladspa_descriptor(unsigned long index)51 const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) {
52 
53 #ifdef WIN32
54 	if (bIsFirstTime) {
55 		swh_init();
56 		bIsFirstTime = 0;
57 	}
58 #endif
59 	switch (index) {
60 	case 0:
61 		return sinCosDescriptor;
62 	default:
63 		return NULL;
64 	}
65 }
66 
cleanupSinCos(LADSPA_Handle instance)67 static void cleanupSinCos(LADSPA_Handle instance) {
68 	free(instance);
69 }
70 
connectPortSinCos(LADSPA_Handle instance,unsigned long port,LADSPA_Data * data)71 static void connectPortSinCos(
72  LADSPA_Handle instance,
73  unsigned long port,
74  LADSPA_Data *data) {
75 	SinCos *plugin;
76 
77 	plugin = (SinCos *)instance;
78 	switch (port) {
79 	case SINCOS_FREQ:
80 		plugin->freq = data;
81 		break;
82 	case SINCOS_PITCH:
83 		plugin->pitch = data;
84 		break;
85 	case SINCOS_SINE:
86 		plugin->sine = data;
87 		break;
88 	case SINCOS_COSINE:
89 		plugin->cosine = data;
90 		break;
91 	}
92 }
93 
instantiateSinCos(const LADSPA_Descriptor * descriptor,unsigned long s_rate)94 static LADSPA_Handle instantiateSinCos(
95  const LADSPA_Descriptor *descriptor,
96  unsigned long s_rate) {
97 	SinCos *plugin_data = (SinCos *)calloc(1, sizeof(SinCos));
98 	float fs;
99 	double last_om;
100 	double phi;
101 
102 #line 21 "sin_cos_1881.xml"
103 	fs = (float)s_rate;
104 	phi = 0.0;
105 	last_om = 0.0;
106 
107 	plugin_data->fs = fs;
108 	plugin_data->last_om = last_om;
109 	plugin_data->phi = phi;
110 
111 	return (LADSPA_Handle)plugin_data;
112 }
113 
114 #undef buffer_write
115 #undef RUN_ADDING
116 #undef RUN_REPLACING
117 
118 #define buffer_write(b, v) (b = v)
119 #define RUN_ADDING    0
120 #define RUN_REPLACING 1
121 
runSinCos(LADSPA_Handle instance,unsigned long sample_count)122 static void runSinCos(LADSPA_Handle instance, unsigned long sample_count) {
123 	SinCos *plugin_data = (SinCos *)instance;
124 
125 	/* Base frequency (Hz) (float value) */
126 	const LADSPA_Data freq = *(plugin_data->freq);
127 
128 	/* Pitch offset (float value) */
129 	const LADSPA_Data pitch = *(plugin_data->pitch);
130 
131 	/* Sine output (array of floats of length sample_count) */
132 	LADSPA_Data * const sine = plugin_data->sine;
133 
134 	/* Cosine output (array of floats of length sample_count) */
135 	LADSPA_Data * const cosine = plugin_data->cosine;
136 	float fs = plugin_data->fs;
137 	double last_om = plugin_data->last_om;
138 	double phi = plugin_data->phi;
139 
140 #line 27 "sin_cos_1881.xml"
141 	unsigned long pos;
142 	const double target_om = 2.0 * M_PI * f_clamp(freq, 0.0f, 0.5f) * pow(2.0, f_clamp(pitch, 0.0f, 16.0f)) / fs;
143 	const double om_d = (target_om - last_om) / (double)sample_count;
144 	double om = last_om;
145 
146 	for (pos = 0; pos < sample_count; pos++) {
147 	  buffer_write(sine[pos], sin(phi));
148 	  buffer_write(cosine[pos], cos(phi));
149 	  om += om_d;
150 	  phi += om;
151 	}
152 	while (phi > 2.0 * M_PI) {
153 	  phi -= 2.0 * M_PI;
154 	}
155 
156 	plugin_data->phi = phi;
157 	plugin_data->last_om = target_om;
158 }
159 #undef buffer_write
160 #undef RUN_ADDING
161 #undef RUN_REPLACING
162 
163 #define buffer_write(b, v) (b += (v) * run_adding_gain)
164 #define RUN_ADDING    1
165 #define RUN_REPLACING 0
166 
setRunAddingGainSinCos(LADSPA_Handle instance,LADSPA_Data gain)167 static void setRunAddingGainSinCos(LADSPA_Handle instance, LADSPA_Data gain) {
168 	((SinCos *)instance)->run_adding_gain = gain;
169 }
170 
runAddingSinCos(LADSPA_Handle instance,unsigned long sample_count)171 static void runAddingSinCos(LADSPA_Handle instance, unsigned long sample_count) {
172 	SinCos *plugin_data = (SinCos *)instance;
173 	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;
174 
175 	/* Base frequency (Hz) (float value) */
176 	const LADSPA_Data freq = *(plugin_data->freq);
177 
178 	/* Pitch offset (float value) */
179 	const LADSPA_Data pitch = *(plugin_data->pitch);
180 
181 	/* Sine output (array of floats of length sample_count) */
182 	LADSPA_Data * const sine = plugin_data->sine;
183 
184 	/* Cosine output (array of floats of length sample_count) */
185 	LADSPA_Data * const cosine = plugin_data->cosine;
186 	float fs = plugin_data->fs;
187 	double last_om = plugin_data->last_om;
188 	double phi = plugin_data->phi;
189 
190 #line 27 "sin_cos_1881.xml"
191 	unsigned long pos;
192 	const double target_om = 2.0 * M_PI * f_clamp(freq, 0.0f, 0.5f) * pow(2.0, f_clamp(pitch, 0.0f, 16.0f)) / fs;
193 	const double om_d = (target_om - last_om) / (double)sample_count;
194 	double om = last_om;
195 
196 	for (pos = 0; pos < sample_count; pos++) {
197 	  buffer_write(sine[pos], sin(phi));
198 	  buffer_write(cosine[pos], cos(phi));
199 	  om += om_d;
200 	  phi += om;
201 	}
202 	while (phi > 2.0 * M_PI) {
203 	  phi -= 2.0 * M_PI;
204 	}
205 
206 	plugin_data->phi = phi;
207 	plugin_data->last_om = target_om;
208 }
209 
swh_init()210 static void __attribute__((constructor)) swh_init() {
211 	char **port_names;
212 	LADSPA_PortDescriptor *port_descriptors;
213 	LADSPA_PortRangeHint *port_range_hints;
214 
215 #ifdef ENABLE_NLS
216 #define D_(s) dgettext(PACKAGE, s)
217 	bindtextdomain(PACKAGE, PACKAGE_LOCALE_DIR);
218 #else
219 #define D_(s) (s)
220 #endif
221 
222 
223 	sinCosDescriptor =
224 	 (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
225 
226 	if (sinCosDescriptor) {
227 		sinCosDescriptor->UniqueID = 1881;
228 		sinCosDescriptor->Label = "sinCos";
229 		sinCosDescriptor->Properties =
230 		 LADSPA_PROPERTY_HARD_RT_CAPABLE;
231 		sinCosDescriptor->Name =
232 		 D_("Sine + cosine oscillator");
233 		sinCosDescriptor->Maker =
234 		 "Steve Harris <steve@plugin.org.uk>";
235 		sinCosDescriptor->Copyright =
236 		 "GPL";
237 		sinCosDescriptor->PortCount = 4;
238 
239 		port_descriptors = (LADSPA_PortDescriptor *)calloc(4,
240 		 sizeof(LADSPA_PortDescriptor));
241 		sinCosDescriptor->PortDescriptors =
242 		 (const LADSPA_PortDescriptor *)port_descriptors;
243 
244 		port_range_hints = (LADSPA_PortRangeHint *)calloc(4,
245 		 sizeof(LADSPA_PortRangeHint));
246 		sinCosDescriptor->PortRangeHints =
247 		 (const LADSPA_PortRangeHint *)port_range_hints;
248 
249 		port_names = (char **)calloc(4, sizeof(char*));
250 		sinCosDescriptor->PortNames =
251 		 (const char **)port_names;
252 
253 		/* Parameters for Base frequency (Hz) */
254 		port_descriptors[SINCOS_FREQ] =
255 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
256 		port_names[SINCOS_FREQ] =
257 		 D_("Base frequency (Hz)");
258 		port_range_hints[SINCOS_FREQ].HintDescriptor =
259 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_440 | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_LOGARITHMIC;
260 		port_range_hints[SINCOS_FREQ].LowerBound = 0.000001;
261 		port_range_hints[SINCOS_FREQ].UpperBound = 0.5;
262 
263 		/* Parameters for Pitch offset */
264 		port_descriptors[SINCOS_PITCH] =
265 		 LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
266 		port_names[SINCOS_PITCH] =
267 		 D_("Pitch offset");
268 		port_range_hints[SINCOS_PITCH].HintDescriptor =
269 		 LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0;
270 		port_range_hints[SINCOS_PITCH].LowerBound = 0;
271 		port_range_hints[SINCOS_PITCH].UpperBound = 8;
272 
273 		/* Parameters for Sine output */
274 		port_descriptors[SINCOS_SINE] =
275 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
276 		port_names[SINCOS_SINE] =
277 		 D_("Sine output");
278 		port_range_hints[SINCOS_SINE].HintDescriptor = 0;
279 
280 		/* Parameters for Cosine output */
281 		port_descriptors[SINCOS_COSINE] =
282 		 LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
283 		port_names[SINCOS_COSINE] =
284 		 D_("Cosine output");
285 		port_range_hints[SINCOS_COSINE].HintDescriptor = 0;
286 
287 		sinCosDescriptor->activate = NULL;
288 		sinCosDescriptor->cleanup = cleanupSinCos;
289 		sinCosDescriptor->connect_port = connectPortSinCos;
290 		sinCosDescriptor->deactivate = NULL;
291 		sinCosDescriptor->instantiate = instantiateSinCos;
292 		sinCosDescriptor->run = runSinCos;
293 		sinCosDescriptor->run_adding = runAddingSinCos;
294 		sinCosDescriptor->set_run_adding_gain = setRunAddingGainSinCos;
295 	}
296 }
297 
swh_fini()298 static void __attribute__((destructor)) swh_fini() {
299 	if (sinCosDescriptor) {
300 		free((LADSPA_PortDescriptor *)sinCosDescriptor->PortDescriptors);
301 		free((char **)sinCosDescriptor->PortNames);
302 		free((LADSPA_PortRangeHint *)sinCosDescriptor->PortRangeHints);
303 		free(sinCosDescriptor);
304 	}
305 	sinCosDescriptor = NULL;
306 
307 }
308