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