added jackrack filter
[melted] / 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 "control_message.h"
33 #include "ui.h"
34 #include "plugin_settings.h"
35
36 #ifndef _
37 #define _(x) x
38 #endif
39
40 jack_rack_t *
41 jack_rack_new (ui_t * ui, unsigned long channels)
42 {
43 jack_rack_t *rack;
44
45 rack = g_malloc (sizeof (jack_rack_t));
46 rack->saved_plugins = NULL;
47 rack->ui = ui;
48 rack->channels = channels;
49
50 return rack;
51 }
52
53
54 void
55 jack_rack_destroy (jack_rack_t * jack_rack)
56 {
57 g_free (jack_rack);
58 }
59
60 plugin_t *
61 jack_rack_instantiate_plugin (jack_rack_t * jack_rack, plugin_desc_t * desc)
62 {
63 plugin_t * plugin;
64
65 /* check whether or not the plugin is RT capable and confirm with the user if it isn't */
66 if (!LADSPA_IS_HARD_RT_CAPABLE(desc->properties)) {
67 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",
68 desc->name);
69 }
70
71 /* create the plugin */
72 plugin = plugin_new (desc, jack_rack);
73
74 if (!plugin) {
75 fprintf (stderr, "Error loading file plugin '%s' from file '%s'\n",
76 desc->name, desc->object_file);
77 }
78
79 return plugin;
80 }
81
82 void
83 jack_rack_send_add_plugin (jack_rack_t * jack_rack, plugin_desc_t * desc)
84 {
85 plugin_t * plugin;
86 ctrlmsg_t ctrlmsg;
87
88 plugin = jack_rack_instantiate_plugin (jack_rack, desc);
89
90 if (!plugin)
91 return;
92
93 /* send the chain link off to the process() callback */
94 ctrlmsg.type = CTRLMSG_ADD;
95 ctrlmsg.data.add.plugin = plugin;
96 lff_write (jack_rack->ui->ui_to_process, &ctrlmsg);
97 }
98
99 void
100 jack_rack_add_saved_plugin (jack_rack_t * jack_rack, saved_plugin_t * saved_plugin)
101 {
102 jack_rack->saved_plugins = g_slist_append (jack_rack->saved_plugins, saved_plugin);
103
104 jack_rack_send_add_plugin (jack_rack, saved_plugin->settings->desc);
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 (saved_rack_t * saved_rack, saved_plugin_t * saved_plugin,
156 ui_t * ui, 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 (ui->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 (saved_rack_t * saved_rack, ui_t * ui, 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 (saved_rack, saved_plugin, ui, filename, node);
278 }
279 }
280 }
281
282 static saved_rack_t *
283 saved_rack_new (ui_t * ui, 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 (saved_rack, ui, 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->settings; list; list = g_slist_next (list))
309 settings_destroy ((settings_t *) list->data); */
310 /* g_slist_free (saved_rack->settings); */
311
312 g_free (saved_rack);
313 }
314
315
316 int
317 jack_rack_open_file (ui_t * ui, const char * filename)
318 {
319 xmlDocPtr doc;
320 saved_rack_t * saved_rack;
321 GSList * list;
322 saved_plugin_t * saved_plugin;
323
324 doc = xmlParseFile (filename);
325 if (!doc)
326 {
327 fprintf (stderr, _("Could not parse file '%s'\n"), filename);
328 return 1;
329 }
330
331 if (strcmp ( ((xmlDtdPtr)doc->children)->name, "jackrack") != 0)
332 {
333 fprintf (stderr, _("The file '%s' is not a JACK Rack settings file\n"), filename);
334 return 1;
335 }
336
337 saved_rack = saved_rack_new (ui, filename, doc);
338 xmlFreeDoc (doc);
339
340 if (!saved_rack)
341 return 1;
342
343 for (list = saved_rack->plugins; list; list = g_slist_next (list))
344 {
345 saved_plugin = list->data;
346
347 settings_set_sample_rate (saved_plugin->settings, sample_rate);
348
349 jack_rack_add_saved_plugin (ui->jack_rack, saved_plugin);
350 }
351
352 g_slist_free (saved_rack->plugins);
353 g_free (saved_rack);
354
355 return 0;
356 }
357
358
359 /* EOF */