added jackrack filter
[melted] / src / modules / jackrack / plugin_desc.c
1 /*
2 * JACK Rack
3 *
4 * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <math.h>
21 #include <float.h>
22 #include <string.h>
23
24 #include "plugin_desc.h"
25 #include "plugin.h"
26
27 #define set_string_property(property, value) \
28 \
29 if (property) \
30 g_free (property); \
31 \
32 if (value) \
33 (property) = g_strdup (value); \
34 else \
35 (property) = NULL;
36
37
38 void
39 plugin_desc_set_ports (plugin_desc_t * pd,
40 unsigned long port_count,
41 const LADSPA_PortDescriptor * port_descriptors,
42 const LADSPA_PortRangeHint * port_range_hints,
43 const char * const * port_names);
44
45
46
47 static void
48 plugin_desc_init (plugin_desc_t * pd)
49 {
50 pd->object_file = NULL;
51 pd->id = 0;
52 pd->name = NULL;
53 pd->properties = 0;
54 pd->channels = 0;
55 pd->port_count = 0;
56 pd->port_descriptors = NULL;
57 pd->port_range_hints = NULL;
58 pd->audio_input_port_indicies = NULL;
59 pd->audio_output_port_indicies = NULL;
60 pd->audio_aux_port_indicies = NULL;
61 pd->control_port_count = 0;
62 pd->control_port_indicies = NULL;
63 pd->aux_channels = 0;
64 pd->aux_are_input = TRUE;
65 }
66
67 static void
68 plugin_desc_free_ports (plugin_desc_t * pd)
69 {
70 if (pd->port_count)
71 {
72 g_free (pd->port_descriptors);
73 g_free (pd->port_range_hints);
74 pd->port_descriptors = NULL;
75 pd->port_range_hints = NULL;
76 pd->port_count = 0;
77 }
78 }
79
80 static void
81 plugin_desc_free (plugin_desc_t * pd)
82 {
83 plugin_desc_set_object_file (pd, NULL);
84 plugin_desc_set_name (pd, NULL);
85 plugin_desc_free_ports (pd);
86 }
87
88 plugin_desc_t *
89 plugin_desc_new ()
90 {
91 plugin_desc_t * pd;
92 pd = g_malloc (sizeof (plugin_desc_t));
93 plugin_desc_init (pd);
94 return pd;
95 }
96
97 plugin_desc_t *
98 plugin_desc_new_with_descriptor (const char * object_file,
99 unsigned long index,
100 const LADSPA_Descriptor * descriptor)
101 {
102 plugin_desc_t * pd;
103 pd = plugin_desc_new ();
104
105 plugin_desc_set_object_file (pd, object_file);
106 plugin_desc_set_index (pd, index);
107 plugin_desc_set_id (pd, descriptor->UniqueID);
108 plugin_desc_set_name (pd, descriptor->Name);
109 plugin_desc_set_properties (pd, descriptor->Properties);
110 plugin_desc_set_ports (pd,
111 descriptor->PortCount,
112 descriptor->PortDescriptors,
113 descriptor->PortRangeHints,
114 descriptor->PortNames);
115
116 pd->rt = LADSPA_IS_HARD_RT_CAPABLE(pd->properties) ? TRUE : FALSE;
117
118 return pd;
119 }
120
121 void
122 plugin_desc_destroy (plugin_desc_t * pd)
123 {
124 plugin_desc_free (pd);
125 g_free (pd);
126 }
127
128 void
129 plugin_desc_set_object_file (plugin_desc_t * pd, const char * object_file)
130 {
131 set_string_property (pd->object_file, object_file);
132 }
133
134 void
135 plugin_desc_set_index (plugin_desc_t * pd, unsigned long index)
136 {
137 pd->index = index;
138 }
139
140
141 void
142 plugin_desc_set_id (plugin_desc_t * pd, unsigned long id)
143 {
144 pd->id = id;
145 }
146
147 void
148 plugin_desc_set_name (plugin_desc_t * pd, const char * name)
149 {
150 set_string_property (pd->name, name);
151 }
152
153 void
154 plugin_desc_set_properties (plugin_desc_t * pd, LADSPA_Properties properties)
155 {
156 pd->properties = properties;
157 }
158
159 static void
160 plugin_desc_add_audio_port_index (unsigned long ** indicies,
161 unsigned long * current_port_count,
162 unsigned long index)
163 {
164 (*current_port_count)++;
165
166 if (*current_port_count == 1)
167 *indicies = g_malloc (sizeof (unsigned long) * *current_port_count);
168 else
169 *indicies = g_realloc (*indicies, sizeof (unsigned long) * *current_port_count);
170
171 (*indicies)[*current_port_count - 1] = index;
172 }
173
174 static void
175 plugin_desc_set_port_counts (plugin_desc_t * pd)
176 {
177 unsigned long i;
178 unsigned long icount = 0;
179 unsigned long ocount = 0;
180
181 for (i = 0; i < pd->port_count; i++)
182 {
183 if (LADSPA_IS_PORT_AUDIO (pd->port_descriptors[i]))
184 {
185 if (LADSPA_IS_PORT_INPUT (pd->port_descriptors[i]))
186 plugin_desc_add_audio_port_index (&pd->audio_input_port_indicies, &icount, i);
187 else
188 plugin_desc_add_audio_port_index (&pd->audio_output_port_indicies, &ocount, i);
189 }
190 else
191 {
192 if (LADSPA_IS_PORT_OUTPUT (pd->port_descriptors[i]))
193 continue;
194
195 pd->control_port_count++;
196 if (pd->control_port_count == 1)
197 pd->control_port_indicies = g_malloc (sizeof (unsigned long) * pd->control_port_count);
198 else
199 pd->control_port_indicies = g_realloc (pd->control_port_indicies,
200 sizeof (unsigned long) * pd->control_port_count);
201
202 pd->control_port_indicies[pd->control_port_count - 1] = i;
203 }
204 }
205
206 if (icount == ocount)
207 pd->channels = icount;
208 else
209 { /* deal with auxilliary ports */
210 unsigned long ** port_indicies;
211 unsigned long port_count;
212 unsigned long i, j;
213
214 if (icount > ocount)
215 {
216 pd->channels = ocount;
217 pd->aux_channels = icount - ocount;
218 pd->aux_are_input = TRUE;
219 port_indicies = &pd->audio_input_port_indicies;
220 port_count = icount;
221 }
222 else
223 {
224 pd->channels = icount;
225 pd->aux_channels = ocount - icount;
226 pd->aux_are_input = FALSE;
227 port_indicies = &pd->audio_output_port_indicies;
228 port_count = ocount;
229 }
230
231 /* allocate indicies */
232 pd->audio_aux_port_indicies = g_malloc (sizeof (unsigned long) * pd->aux_channels);
233
234 /* copy indicies */
235 for (i = pd->channels, j = 0; i < port_count; i++, j++)
236 pd->audio_aux_port_indicies[j] = (*port_indicies)[i];
237
238 /* shrink the main indicies to only have channels indicies */
239 *port_indicies = g_realloc (*port_indicies, sizeof (unsigned long) * pd->channels);
240 }
241 }
242
243 void
244 plugin_desc_set_ports (plugin_desc_t * pd,
245 unsigned long port_count,
246 const LADSPA_PortDescriptor * port_descriptors,
247 const LADSPA_PortRangeHint * port_range_hints,
248 const char * const * port_names)
249 {
250 unsigned long i;
251
252 plugin_desc_free_ports (pd);
253
254 if (!port_count)
255 return;
256
257 pd->port_count = port_count;
258 pd->port_descriptors = g_malloc (sizeof (LADSPA_PortDescriptor) * port_count);
259 pd->port_range_hints = g_malloc (sizeof (LADSPA_PortRangeHint) * port_count);
260 pd->port_names = g_malloc (sizeof (char *) * port_count);
261
262 memcpy (pd->port_descriptors, port_descriptors, sizeof (LADSPA_PortDescriptor) * port_count);
263 memcpy (pd->port_range_hints, port_range_hints, sizeof (LADSPA_PortRangeHint) * port_count);
264
265 for (i = 0; i < port_count; i++)
266 pd->port_names[i] = g_strdup (port_names[i]);
267
268 plugin_desc_set_port_counts (pd);
269 }
270
271
272 LADSPA_Data
273 plugin_desc_get_default_control_value (plugin_desc_t * pd, unsigned long port_index, guint32 sample_rate)
274 {
275 LADSPA_Data upper, lower;
276 LADSPA_PortRangeHintDescriptor hint_descriptor;
277
278 hint_descriptor = pd->port_range_hints[port_index].HintDescriptor;
279
280 /* set upper and lower, possibly adjusted to the sample rate */
281 if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) {
282 upper = pd->port_range_hints[port_index].UpperBound * (LADSPA_Data) sample_rate;
283 lower = pd->port_range_hints[port_index].LowerBound * (LADSPA_Data) sample_rate;
284 } else {
285 upper = pd->port_range_hints[port_index].UpperBound;
286 lower = pd->port_range_hints[port_index].LowerBound;
287 }
288
289 if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor))
290 {
291 if (lower < FLT_EPSILON)
292 lower = FLT_EPSILON;
293 }
294
295
296 if (LADSPA_IS_HINT_HAS_DEFAULT(hint_descriptor)) {
297
298 if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) {
299
300 return lower;
301
302 } else if (LADSPA_IS_HINT_DEFAULT_LOW(hint_descriptor)) {
303
304 if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) {
305 return exp(log(lower) * 0.75 + log(upper) * 0.25);
306 } else {
307 return lower * 0.75 + upper * 0.25;
308 }
309
310 } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) {
311
312 if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) {
313 return exp(log(lower) * 0.5 + log(upper) * 0.5);
314 } else {
315 return lower * 0.5 + upper * 0.5;
316 }
317
318 } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint_descriptor)) {
319
320 if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) {
321 return exp(log(lower) * 0.25 + log(upper) * 0.75);
322 } else {
323 return lower * 0.25 + upper * 0.75;
324 }
325
326 } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) {
327
328 return upper;
329
330 } else if (LADSPA_IS_HINT_DEFAULT_0(hint_descriptor)) {
331
332 return 0.0;
333
334 } else if (LADSPA_IS_HINT_DEFAULT_1(hint_descriptor)) {
335
336 if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) {
337 return (LADSPA_Data) sample_rate;
338 } else {
339 return 1.0;
340 }
341
342 } else if (LADSPA_IS_HINT_DEFAULT_100(hint_descriptor)) {
343
344 if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) {
345 return 100.0 * (LADSPA_Data) sample_rate;
346 } else {
347 return 100.0;
348 }
349
350 } else if (LADSPA_IS_HINT_DEFAULT_440(hint_descriptor)) {
351
352 if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) {
353 return 440.0 * (LADSPA_Data) sample_rate;
354 } else {
355 return 440.0;
356 }
357
358 }
359
360 } else { /* try and find a reasonable default */
361
362 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint_descriptor)) {
363 return lower;
364 } else if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) {
365 return upper;
366 }
367 }
368
369 return 0.0;
370 }
371
372 LADSPA_Data
373 plugin_desc_change_control_value (plugin_desc_t * pd,
374 unsigned long control_index,
375 LADSPA_Data value,
376 guint32 old_sample_rate,
377 guint32 new_sample_rate)
378 {
379
380 if (LADSPA_IS_HINT_SAMPLE_RATE (pd->port_range_hints[control_index].HintDescriptor))
381 {
382 LADSPA_Data old_sr, new_sr;
383
384 old_sr = (LADSPA_Data) old_sample_rate;
385 new_sr = (LADSPA_Data) new_sample_rate;
386
387 value /= old_sr;
388 value *= new_sr;
389 }
390
391 return value;
392 }
393
394 gint
395 plugin_desc_get_copies (plugin_desc_t * pd, unsigned long rack_channels)
396 {
397 gint copies = 1;
398
399 if (pd->channels > rack_channels)
400 return 0;
401
402 while (pd->channels * copies < rack_channels)
403 copies++;
404
405 if (pd->channels * copies > rack_channels)
406 return 0;
407
408 return copies;
409 }
410
411 /* EOF */