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