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