]> git.sesse.net Git - mlt/blob - src/modules/jackrack/jack_rack.c
Fix getting LADSPA include dir from listplugins.
[mlt] / src / modules / jackrack / jack_rack.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 <stdio.h>
27 #include <stdlib.h>
28 #include <strings.h>
29 #include <string.h>
30 #include <ctype.h>
31
32 #include <ladspa.h>
33 #include <libxml/tree.h>
34
35 #include "jack_rack.h"
36 #include "lock_free_fifo.h"
37 #include "plugin_settings.h"
38
39 #ifndef _
40 #define _(x) x
41 #endif
42 #define _x (const xmlChar*)
43 #define _s (const char*)
44
45 jack_rack_t *
46 jack_rack_new (const char * client_name, unsigned long channels)
47 {
48   jack_rack_t *rack;
49
50   rack = g_malloc (sizeof (jack_rack_t));
51   rack->saved_plugins  = NULL;
52   rack->channels       = channels;
53   rack->procinfo = process_info_new (client_name, channels, FALSE, FALSE);
54   if (!rack->procinfo) {
55     g_free (rack);
56     return NULL;
57   }
58   rack->plugin_mgr = plugin_mgr_new ();
59   plugin_mgr_set_plugins (rack->plugin_mgr, channels);
60
61   return rack;
62 }
63
64
65 void
66 jack_rack_destroy (jack_rack_t * jack_rack)
67 {
68   process_quit (jack_rack->procinfo);
69   plugin_mgr_destroy (jack_rack->plugin_mgr);
70   process_info_destroy (jack_rack->procinfo);
71   g_slist_free (jack_rack->saved_plugins);
72   g_free (jack_rack);
73 }
74
75 plugin_t *
76 jack_rack_instantiate_plugin (jack_rack_t * jack_rack, plugin_desc_t * desc)
77 {
78   plugin_t * plugin;
79   
80   /* check whether or not the plugin is RT capable and confirm with the user if it isn't */
81   if (!LADSPA_IS_HARD_RT_CAPABLE(desc->properties)) {
82     fprintf (stderr, "Plugin not RT capable. The plugin '%s' does not describe itself as being capable of real-time operation. You may experience drop outs or jack may even kick us out if you use it.\n",
83                desc->name);
84   }
85
86   /* create the plugin */
87   plugin = plugin_new (desc, jack_rack);
88
89   if (!plugin) {
90    fprintf (stderr, "Error loading file plugin '%s' from file '%s'\n",
91                desc->name, desc->object_file);
92   }
93   
94   return plugin;
95 }
96
97
98 void
99 jack_rack_add_saved_plugin (jack_rack_t * jack_rack, saved_plugin_t * saved_plugin)
100 {
101   plugin_t * plugin = jack_rack_instantiate_plugin (jack_rack, saved_plugin->settings->desc);
102   if (!plugin)
103     return;
104   jack_rack->saved_plugins = g_slist_append (jack_rack->saved_plugins, saved_plugin);
105   process_add_plugin (jack_rack->procinfo, plugin);
106   jack_rack_add_plugin (jack_rack, plugin);
107 }
108
109
110 void
111 jack_rack_add_plugin (jack_rack_t * jack_rack, plugin_t * plugin)
112 {
113   saved_plugin_t * saved_plugin = NULL;
114   GSList * list;
115   unsigned long control, channel;
116   LADSPA_Data value;
117   guint copy;
118   
119   /* see if there's any saved settings that match the plugin id */
120   for (list = jack_rack->saved_plugins; list; list = g_slist_next (list))
121     {
122       saved_plugin = list->data;
123       
124       if (saved_plugin->settings->desc->id == plugin->desc->id)
125         {
126           /* process the settings! */
127           jack_rack->saved_plugins = g_slist_remove (jack_rack->saved_plugins, saved_plugin);
128           break;
129         }
130       saved_plugin = NULL;
131     }
132         
133   /* initialize plugin parameters */
134   plugin->enabled = settings_get_enabled (saved_plugin->settings);
135   plugin->wet_dry_enabled = settings_get_wet_dry_enabled (saved_plugin->settings);
136         
137   for (control = 0; control < saved_plugin->settings->desc->control_port_count; control++)
138     for (copy = 0; copy < plugin->copies; copy++)
139       {
140         value = settings_get_control_value (saved_plugin->settings, copy, control);
141         plugin->holders[copy].control_memory[control] = value;
142 //printf("setting control value %s (%d) = %f\n", saved_plugin->settings->desc->port_names[control], copy, value);
143 //        lff_write (plugin->holders[copy].ui_control_fifos + control, &value);
144       }
145   if (plugin->wet_dry_enabled)
146     for (channel = 0; channel < jack_rack->channels; channel++)
147       {
148         value = settings_get_wet_dry_value (saved_plugin->settings, channel);
149         plugin->wet_dry_values[channel] = value;
150 //printf("setting wet/dry value %d = %f\n", channel, value);
151 //        lff_write (plugin->wet_dry_fifos + channel, &value);
152       }
153 }
154
155
156 static void
157 saved_rack_parse_plugin (jack_rack_t * jack_rack, saved_rack_t * saved_rack, saved_plugin_t * saved_plugin,
158                          const char * filename, xmlNodePtr plugin)
159 {
160   plugin_desc_t * desc;
161   settings_t * settings = NULL;
162   xmlNodePtr node;
163   xmlNodePtr sub_node;
164   xmlChar *content;
165   unsigned long num;
166   unsigned long control = 0;
167 #ifdef WIN32
168   xmlFreeFunc xmlFree = NULL;
169   xmlMemGet( &xmlFree, NULL, NULL, NULL);
170 #endif
171
172   for (node = plugin->children; node; node = node->next)
173     {
174       if (xmlStrcmp (node->name, _x("id")) == 0)
175         {
176           content = xmlNodeGetContent (node);
177           num = strtoul (_s(content), NULL, 10);
178           xmlFree (content);
179
180           desc = plugin_mgr_get_any_desc (jack_rack->plugin_mgr, num);
181           if (!desc)
182             {
183               fprintf (stderr, _("The file '%s' contains an unknown plugin with ID '%ld'; skipping\n"), filename, num);
184               return;
185             }
186           
187           settings = settings_new (desc, saved_rack->channels, saved_rack->sample_rate);
188         }
189       else if (xmlStrcmp (node->name, _x("enabled")) == 0)
190         {
191           content = xmlNodeGetContent (node);
192           settings_set_enabled (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
193           xmlFree (content);
194         }
195       else if (xmlStrcmp (node->name, _x("wet_dry_enabled")) == 0)
196         {
197           content = xmlNodeGetContent (node);
198           settings_set_wet_dry_enabled (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
199           xmlFree (content);
200         }
201       else if (xmlStrcmp (node->name, _x("wet_dry_locked")) == 0)
202         {
203           content = xmlNodeGetContent (node);
204           settings_set_wet_dry_locked (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
205           xmlFree (content);
206         }
207       else if (xmlStrcmp (node->name, _x("wet_dry_values")) == 0)
208         {
209           unsigned long channel = 0;
210           
211           for (sub_node = node->children; sub_node; sub_node = sub_node->next)
212             {
213               if (xmlStrcmp (sub_node->name, _x("value")) == 0)
214                 {
215                   content = xmlNodeGetContent (sub_node);
216                   settings_set_wet_dry_value (settings, channel, strtod (_s(content), NULL));
217                   xmlFree (content);
218                   
219                   channel++;
220                 }
221             }
222         }
223       else if (xmlStrcmp (node->name, _x("lockall")) == 0)
224         {
225           content = xmlNodeGetContent (node);
226           settings_set_lock_all (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
227           xmlFree (content);
228         }
229       else if (xmlStrcmp (node->name, _x("controlrow")) == 0)
230         {
231           gint copy = 0;
232
233           for (sub_node = node->children; sub_node; sub_node = sub_node->next)
234             {
235               if (xmlStrcmp (sub_node->name, _x("lock")) == 0)
236                 {
237                   content = xmlNodeGetContent (sub_node);
238                   settings_set_lock (settings, control, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
239                   xmlFree (content);
240                 }
241               else if (xmlStrcmp (sub_node->name, _x("value")) == 0)
242                 {
243                   content = xmlNodeGetContent (sub_node);
244                   settings_set_control_value (settings, copy, control, strtod (_s(content), NULL));
245                   xmlFree (content);
246                   copy++;
247                 }
248             }
249           
250           control++;
251         }
252     }
253   
254   if (settings)
255     saved_plugin->settings = settings;
256 }
257
258 static void
259 saved_rack_parse_jackrack (jack_rack_t * jack_rack, saved_rack_t * saved_rack, const char * filename, xmlNodePtr jackrack)
260 {
261   xmlNodePtr node;
262   xmlChar *content;
263   saved_plugin_t * saved_plugin;
264 #ifdef WIN32
265   xmlFreeFunc xmlFree = NULL;
266   xmlMemGet( &xmlFree, NULL, NULL, NULL);
267 #endif
268
269   for (node = jackrack->children; node; node = node->next)
270     {
271       if (xmlStrcmp (node->name, _x("channels")) == 0)
272         {
273           content = xmlNodeGetContent (node);
274           saved_rack->channels = strtoul (_s(content), NULL, 10);
275           xmlFree (content);
276         }
277       else if (xmlStrcmp (node->name, _x("samplerate")) == 0)
278         {
279           content = xmlNodeGetContent (node);
280           saved_rack->sample_rate = strtoul (_s(content), NULL, 10);
281           xmlFree (content);
282         }
283       else if (xmlStrcmp (node->name, _x("plugin")) == 0)
284         {
285           saved_plugin = g_malloc0 (sizeof (saved_plugin_t));
286           saved_rack->plugins = g_slist_append (saved_rack->plugins, saved_plugin);
287           saved_rack_parse_plugin (jack_rack, saved_rack, saved_plugin, filename, node);
288         }
289     }
290 }
291
292 static saved_rack_t *
293 saved_rack_new (jack_rack_t * jack_rack, const char * filename, xmlDocPtr doc)
294 {
295   xmlNodePtr node;
296   saved_rack_t *saved_rack;
297   
298   /* create the saved rack */
299   saved_rack = g_malloc (sizeof (saved_rack_t));
300   saved_rack->plugins = NULL;
301   saved_rack->sample_rate = 48000;
302   saved_rack->channels = 2;
303   
304   for (node = doc->children; node; node = node->next)
305     {
306       if (xmlStrcmp (node->name, _x("jackrack")) == 0)
307         saved_rack_parse_jackrack (jack_rack, saved_rack, filename, node);
308     }
309   
310   return saved_rack;
311 }
312
313 static void
314 saved_rack_destroy (saved_rack_t * saved_rack)
315 {
316   GSList * list;
317   
318   for (list = saved_rack->plugins; list; list = g_slist_next (list))
319     settings_destroy (((saved_plugin_t *) list->data)->settings);
320   g_slist_free (saved_rack->plugins);
321   g_free (saved_rack);
322 }
323
324
325 int
326 jack_rack_open_file (jack_rack_t * jack_rack, const char * filename)
327 {
328   xmlDocPtr doc;
329   saved_rack_t * saved_rack;
330   GSList * list;
331   saved_plugin_t * saved_plugin;
332
333   doc = xmlParseFile (filename);
334   if (!doc)
335     {
336       fprintf (stderr, _("Could not parse file '%s'\n"), filename);
337       return 1;
338     }
339   
340   if (xmlStrcmp ( ((xmlDtdPtr)doc->children)->name, _x("jackrack")) != 0)
341     {
342       fprintf (stderr, _("The file '%s' is not a JACK Rack settings file\n"), filename);
343       return 1;
344     }
345   
346   saved_rack = saved_rack_new (jack_rack, filename, doc);
347   xmlFreeDoc (doc);
348   
349   if (!saved_rack)
350     return 1;
351
352   for (list = saved_rack->plugins; list; list = g_slist_next (list))
353     {
354       saved_plugin = list->data;
355       
356       settings_set_sample_rate (saved_plugin->settings, sample_rate);
357       
358       jack_rack_add_saved_plugin (jack_rack, saved_plugin);
359     }
360   
361   saved_rack_destroy (saved_rack);
362   
363   return 0;
364 }
365
366
367 /* EOF */