]> git.sesse.net Git - mlt/blob - src/modules/jackrack/plugin_desc.c
1dfea31a4b2def7092c1860728a9d4774d0cb153
[mlt] / 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 */