5 * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net)
7 * Modification for MLT:
8 * Copyright (C) 2004 Ushodaya Enterprises Limited
9 * Author: Dan Dennedy <dan@dennedy.org>
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.
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.
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.
33 #include <libxml/tree.h>
35 #include "jack_rack.h"
36 #include "lock_free_fifo.h"
37 #include "plugin_settings.h"
38 #include "framework/mlt_log.h"
43 #define _x (const xmlChar*)
44 #define _s (const char*)
46 extern plugin_mgr_t *g_jackrack_plugin_mgr;
49 jack_rack_new (const char * client_name, unsigned long channels)
53 rack = g_malloc (sizeof (jack_rack_t));
54 rack->saved_plugins = NULL;
55 rack->channels = channels;
56 rack->procinfo = process_info_new (client_name, channels, FALSE, FALSE);
57 if (!rack->procinfo) {
61 rack->plugin_mgr = g_jackrack_plugin_mgr;
62 plugin_mgr_set_plugins (rack->plugin_mgr, channels);
69 jack_rack_destroy (jack_rack_t * jack_rack)
71 process_quit (jack_rack->procinfo);
72 // plugin_mgr is shared and global now, so we do not destroy it with each instance
73 // plugin_mgr_destroy (jack_rack->plugin_mgr);
74 process_info_destroy (jack_rack->procinfo);
75 g_slist_free (jack_rack->saved_plugins);
80 jack_rack_instantiate_plugin (jack_rack_t * jack_rack, plugin_desc_t * desc)
84 /* check whether or not the plugin is RT capable and confirm with the user if it isn't */
85 if (!LADSPA_IS_HARD_RT_CAPABLE(desc->properties)) {
86 mlt_log_info( NULL, "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",
90 /* create the plugin */
91 plugin = plugin_new (desc, jack_rack);
94 mlt_log_error( NULL, "Error loading file plugin '%s' from file '%s'\n",
95 desc->name, desc->object_file);
103 jack_rack_add_saved_plugin (jack_rack_t * jack_rack, saved_plugin_t * saved_plugin)
105 plugin_t * plugin = jack_rack_instantiate_plugin (jack_rack, saved_plugin->settings->desc);
108 jack_rack->saved_plugins = g_slist_append (jack_rack->saved_plugins, saved_plugin);
109 process_add_plugin (jack_rack->procinfo, plugin);
110 jack_rack_add_plugin (jack_rack, plugin);
115 jack_rack_add_plugin (jack_rack_t * jack_rack, plugin_t * plugin)
117 saved_plugin_t * saved_plugin = NULL;
119 unsigned long control, channel;
123 /* see if there's any saved settings that match the plugin id */
124 for (list = jack_rack->saved_plugins; list; list = g_slist_next (list))
126 saved_plugin = list->data;
128 if (saved_plugin->settings->desc->id == plugin->desc->id)
130 /* process the settings! */
131 jack_rack->saved_plugins = g_slist_remove (jack_rack->saved_plugins, saved_plugin);
137 /* initialize plugin parameters */
138 plugin->enabled = settings_get_enabled (saved_plugin->settings);
139 plugin->wet_dry_enabled = settings_get_wet_dry_enabled (saved_plugin->settings);
141 for (control = 0; control < saved_plugin->settings->desc->control_port_count; control++)
142 for (copy = 0; copy < plugin->copies; copy++)
144 value = settings_get_control_value (saved_plugin->settings, copy, control);
145 plugin->holders[copy].control_memory[control] = value;
146 //mlt_log_debug( NULL, "setting control value %s (%d) = %f\n", saved_plugin->settings->desc->port_names[control], copy, value);
147 // lff_write (plugin->holders[copy].ui_control_fifos + control, &value);
149 if (plugin->wet_dry_enabled)
150 for (channel = 0; channel < jack_rack->channels; channel++)
152 value = settings_get_wet_dry_value (saved_plugin->settings, channel);
153 plugin->wet_dry_values[channel] = value;
154 //mlt_log_debug( NULL, "setting wet/dry value %d = %f\n", channel, value);
155 // lff_write (plugin->wet_dry_fifos + channel, &value);
161 saved_rack_parse_plugin (jack_rack_t * jack_rack, saved_rack_t * saved_rack, saved_plugin_t * saved_plugin,
162 const char * filename, xmlNodePtr plugin)
164 plugin_desc_t * desc;
165 settings_t * settings = NULL;
170 unsigned long control = 0;
172 xmlFreeFunc xmlFree = NULL;
173 xmlMemGet( &xmlFree, NULL, NULL, NULL);
176 for (node = plugin->children; node; node = node->next)
178 if (xmlStrcmp (node->name, _x("id")) == 0)
180 content = xmlNodeGetContent (node);
181 num = strtoul (_s(content), NULL, 10);
184 desc = plugin_mgr_get_any_desc (jack_rack->plugin_mgr, num);
187 mlt_log_verbose( NULL, _("The file '%s' contains an unknown plugin with ID '%ld'; skipping\n"), filename, num);
191 settings = settings_new (desc, saved_rack->channels, saved_rack->sample_rate);
193 else if (xmlStrcmp (node->name, _x("enabled")) == 0)
195 content = xmlNodeGetContent (node);
196 settings_set_enabled (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
199 else if (xmlStrcmp (node->name, _x("wet_dry_enabled")) == 0)
201 content = xmlNodeGetContent (node);
202 settings_set_wet_dry_enabled (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
205 else if (xmlStrcmp (node->name, _x("wet_dry_locked")) == 0)
207 content = xmlNodeGetContent (node);
208 settings_set_wet_dry_locked (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
211 else if (xmlStrcmp (node->name, _x("wet_dry_values")) == 0)
213 unsigned long channel = 0;
215 for (sub_node = node->children; sub_node; sub_node = sub_node->next)
217 if (xmlStrcmp (sub_node->name, _x("value")) == 0)
219 content = xmlNodeGetContent (sub_node);
220 settings_set_wet_dry_value (settings, channel, strtod (_s(content), NULL));
227 else if (xmlStrcmp (node->name, _x("lockall")) == 0)
229 content = xmlNodeGetContent (node);
230 settings_set_lock_all (settings, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
233 else if (xmlStrcmp (node->name, _x("controlrow")) == 0)
237 for (sub_node = node->children; sub_node; sub_node = sub_node->next)
239 if (xmlStrcmp (sub_node->name, _x("lock")) == 0)
241 content = xmlNodeGetContent (sub_node);
242 settings_set_lock (settings, control, xmlStrcmp (content, _x("true")) == 0 ? TRUE : FALSE);
245 else if (xmlStrcmp (sub_node->name, _x("value")) == 0)
247 content = xmlNodeGetContent (sub_node);
248 settings_set_control_value (settings, copy, control, strtod (_s(content), NULL));
259 saved_plugin->settings = settings;
263 saved_rack_parse_jackrack (jack_rack_t * jack_rack, saved_rack_t * saved_rack, const char * filename, xmlNodePtr jackrack)
267 saved_plugin_t * saved_plugin;
269 xmlFreeFunc xmlFree = NULL;
270 xmlMemGet( &xmlFree, NULL, NULL, NULL);
273 for (node = jackrack->children; node; node = node->next)
275 if (xmlStrcmp (node->name, _x("channels")) == 0)
277 content = xmlNodeGetContent (node);
278 saved_rack->channels = strtoul (_s(content), NULL, 10);
281 else if (xmlStrcmp (node->name, _x("samplerate")) == 0)
283 content = xmlNodeGetContent (node);
284 saved_rack->sample_rate = strtoul (_s(content), NULL, 10);
287 else if (xmlStrcmp (node->name, _x("plugin")) == 0)
289 saved_plugin = g_malloc0 (sizeof (saved_plugin_t));
290 saved_rack->plugins = g_slist_append (saved_rack->plugins, saved_plugin);
291 saved_rack_parse_plugin (jack_rack, saved_rack, saved_plugin, filename, node);
296 static saved_rack_t *
297 saved_rack_new (jack_rack_t * jack_rack, const char * filename, xmlDocPtr doc)
300 saved_rack_t *saved_rack;
302 /* create the saved rack */
303 saved_rack = g_malloc (sizeof (saved_rack_t));
304 saved_rack->plugins = NULL;
305 saved_rack->sample_rate = 48000;
306 saved_rack->channels = 2;
308 for (node = doc->children; node; node = node->next)
310 if (xmlStrcmp (node->name, _x("jackrack")) == 0)
311 saved_rack_parse_jackrack (jack_rack, saved_rack, filename, node);
318 saved_rack_destroy (saved_rack_t * saved_rack)
322 for (list = saved_rack->plugins; list; list = g_slist_next (list))
323 settings_destroy (((saved_plugin_t *) list->data)->settings);
324 g_slist_free (saved_rack->plugins);
330 jack_rack_open_file (jack_rack_t * jack_rack, const char * filename)
333 saved_rack_t * saved_rack;
335 saved_plugin_t * saved_plugin;
337 doc = xmlParseFile (filename);
340 mlt_log_error( NULL, _("Could not parse file '%s'\n"), filename);
344 if (xmlStrcmp ( ((xmlDtdPtr)doc->children)->name, _x("jackrack")) != 0)
346 mlt_log_error( NULL, _("The file '%s' is not a JACK Rack settings file\n"), filename);
350 saved_rack = saved_rack_new (jack_rack, filename, doc);
356 for (list = saved_rack->plugins; list; list = g_slist_next (list))
358 saved_plugin = list->data;
360 settings_set_sample_rate (saved_plugin->settings, sample_rate);
362 jack_rack_add_saved_plugin (jack_rack, saved_plugin);
365 saved_rack_destroy (saved_rack);