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