2 terminatorX - realtime audio scratching software
3 Copyright (C) 1999-2003 Alexander König
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 File: tX_ladspa_class.cc
22 #include "tX_ladspa_class.h"
23 #include "tX_global.h"
34 LADSPA_Class * LADSPA_Class::root=NULL;
35 LADSPA_Class * LADSPA_Class::unclassified=NULL;
36 std::list <char *> LADSPA_Class::rdf_files;
37 vtt_class *LADSPA_Class::current_vtt;
38 bool LADSPA_Class::liblrdf_error=false;
40 /* Why do have to code this myself? */
41 static int compare(const char *a, const char *b)
45 if (!a && !b) return 0;
52 for (i=0; (i<lena) && (i<lenb); i++) {
55 } else if (a[i]<b[i]) {
60 if (lena>lenb) return 1;
61 else if (lenb>lena) return 2;
65 void LADSPA_Class::init() {
66 char *start, *end, *buffer;
69 /* Scanning every dir in path */
70 start = globals.lrdf_path;
72 while (*start != '\0') {
74 while (*end != ':' && *end != '\0') end++;
76 buffer = (char *) malloc(1 + end - start);
77 if (end > start) strncpy(buffer, start, end - start);
79 buffer[end - start] = '\0';
80 LADSPA_Class::scandir(buffer);
84 if (*start == ':') start++;
87 if (rdf_files.size() > 0) {
88 char *uris[rdf_files.size()+1];
89 std::list <char *> :: iterator i;
92 for (i=rdf_files.begin(), t=0; i!=rdf_files.end(); i++, t++) {
99 if (lrdf_read_files((const char **) uris)) {
100 tX_error("liblrdf had problems reading the rdf files - cannot provide structured menu");
104 root=new LADSPA_Class("http://ladspa.org/ontology#Plugin");
108 tX_error("No RDF files found");
112 unclassified=new LADSPA_Class();
113 /* This is the last class to accpet all plugins not accepted by other classes. */
114 root->subclasses.push_back(unclassified);
117 void LADSPA_Class::scandir(char *dirname) {
118 int dirlen=strlen(dirname);
121 struct dirent * entry;
124 if (!dirlen) { tX_error("LADSPA_Class::scandir() Empty directory name"); return; };
126 if (dirname[dirlen - 1] != '/') needslash=1;
128 dir = opendir(dirname);
130 if (!dir) { tX_error("LADSPA_Class::scandir() couldn't access directory \"%s\"", dirname); return; };
134 if (!entry) { closedir(dir); return; }
136 if ((strcmp(entry->d_name, ".")==0) ||
137 (strcmp(entry->d_name, "..")==0)) continue;
139 filename = (char *) malloc (dirlen + strlen(entry->d_name) + 10 + needslash);
141 strcpy(filename, "file:");
142 strcat(filename, dirname);
143 if (needslash) strcat(filename, "/");
144 strcat(filename, entry->d_name);
146 tX_debug("Found RDF file: %s", filename);
147 rdf_files.push_back(filename);
151 void LADSPA_Class::insert_class(LADSPA_Class *cls) {
152 std::list <LADSPA_Class *> :: iterator i;
154 for (i=subclasses.begin(); i!=subclasses.end(); i++) {
155 LADSPA_Class *a_class=(*i);
156 int res=compare(cls->label, a_class->label);
159 subclasses.insert(i, cls);
164 subclasses.push_back(cls);
167 LADSPA_Class :: LADSPA_Class (char *uri) : label(NULL), accept_all(false) {
173 if (!liblrdf_error) {
174 urilabel=lrdf_get_label(uri);
177 label=strdup(urilabel);
180 /* Finding subclasses... */
181 ulist = lrdf_get_subclasses(uri);
183 for (i = 0; ulist && i < ulist->count; i++) {
184 insert_class(new LADSPA_Class(ulist->items[i]));
187 lrdf_free_uris(ulist);
189 /* Finding instances... */
190 ulist=lrdf_get_instances(uri);
192 for (i = 0; ulist && i < ulist->count; i++) {
193 registered_ids.push_back(lrdf_get_uid(ulist->items[i]));
196 lrdf_free_uris(ulist);
201 LADSPA_Class :: LADSPA_Class() : label("Unclassified"), accept_all(true) {
204 bool LADSPA_Class :: add_plugin(LADSPA_Plugin *plugin) {
205 return root->add_plugin_instance(plugin, MONO);
208 bool LADSPA_Class :: add_stereo_plugin(LADSPA_Stereo_Plugin *plugin) {
209 return root->add_plugin_instance(plugin, STEREO);
212 bool LADSPA_Class :: add_plugin_instance(LADSPA_Plugin *plugin, LADSPA_Plugin_Type type) {
214 insert_plugin(plugin, type);
218 long id=plugin->getUniqueID();
219 std::list <long> :: iterator i;
221 /* Is this plugin an instance of this class? */
223 for (i=registered_ids.begin(); i!=registered_ids.end(); i++) {
225 /* The plugin belongs to this class... */
226 insert_plugin(plugin, type);
231 /* Try to insert the plugin in subclasses */
232 std::list <LADSPA_Class *> :: iterator cls;
234 for (cls=subclasses.begin(); cls!=subclasses.end(); cls++) {
235 LADSPA_Class *lrdf_class=(*cls);
237 if (lrdf_class->add_plugin_instance(plugin, type)) return true;
245 void LADSPA_Class::insert_plugin(LADSPA_Plugin *plugin, LADSPA_Plugin_Type type) {
246 std::list <LADSPA_Plugin *> :: iterator i;
247 std::list <LADSPA_Plugin *> *list;
252 list=(std::list <LADSPA_Plugin *> *) &stereo_plugins;
255 for (i=list->begin(); i!=list->end(); i++) {
256 LADSPA_Plugin *a_plug=(*i);
257 int res=compare(plugin->getName(), a_plug->getName());
260 list->insert(i, plugin);
265 list->push_back(plugin);
268 void LADSPA_Class::list(char *buffer) {
269 strcat(buffer, "\t");
271 printf("%s class %s {\n", buffer, label);
273 std::list <LADSPA_Plugin *> :: iterator i;
275 for (i=plugins.begin(); i!=plugins.end(); i++) {
276 printf("%s - plugin: %s\n", buffer, (*i)->getName());
279 std::list <LADSPA_Stereo_Plugin *> :: iterator s;
280 for (s=stereo_plugins.begin(); s!=stereo_plugins.end(); s++) {
281 printf("%s - stereo plugin: %s\n", buffer, (*s)->getName());
284 std::list <LADSPA_Class *> :: iterator c;
286 for (c=subclasses.begin(); c!=subclasses.end(); c++) (*c)->list(buffer);
288 printf("%s}\n", buffer);
290 buffer[strlen(buffer)-1]=0;
293 void LADSPA_Class::dump() {
298 static void menu_callback(GtkWidget *wid, LADSPA_Plugin *plugin) {
299 vtt_class *vtt=LADSPA_Class::get_current_vtt();
302 vtt->add_effect(plugin);
304 tX_error("LADSPA_Class::menu_callback() no vtt");
308 static void stereo_menu_callback(GtkWidget *wid, LADSPA_Stereo_Plugin *plugin) {
309 vtt_class *vtt=LADSPA_Class::get_current_vtt();
312 vtt->add_stereo_effect(plugin);
314 tX_error("LADSPA_Class::menu_callback() no vtt");
318 int LADSPA_Class :: plugins_in_class(LADSPA_Plugin_Type type) {
319 std::list <LADSPA_Class *> :: iterator cls;
320 std::list <LADSPA_Plugin *> *list;
326 list=(std::list <LADSPA_Plugin *> *) &stereo_plugins;
328 counter=list->size();
330 for (cls=subclasses.begin(); cls!=subclasses.end(); cls++) {
331 counter+=(*cls)->plugins_in_class(type);
337 GtkWidget * LADSPA_Class :: get_menu(LADSPA_Plugin_Type type) {
338 std::list <LADSPA_Class *> :: iterator cls;
339 GtkWidget *menu=gtk_menu_new();
341 bool need_separator=false;
343 for (cls=subclasses.begin(); cls!=subclasses.end(); cls++) {
344 LADSPA_Class *c=(*cls);
346 if (c->plugins_in_class(type)>0) {
347 item=gtk_menu_item_new_with_label(c->label);
348 GtkWidget *submenu=c->get_menu(type);
349 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
350 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
351 gtk_widget_show(item);
356 std::list <LADSPA_Plugin *> *list;
361 list=(std::list <LADSPA_Plugin *> *) &stereo_plugins;
364 if (need_separator && list->size()) {
365 item = gtk_menu_item_new();
366 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
367 gtk_widget_set_sensitive (item, FALSE);
368 gtk_widget_show (item);
371 std::list <LADSPA_Plugin *> :: iterator plugin;
373 for (plugin=list->begin(); plugin!=list->end(); plugin++) {
375 LADSPA_Plugin *p=(*plugin);
377 sprintf(buffer, "%s - (%s, %li)", p->getName(), p->getLabel(), p->getUniqueID());
378 item=gtk_menu_item_new_with_label(buffer);
379 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
380 g_signal_connect(G_OBJECT(item), "activate", (type == MONO) ? G_CALLBACK(menu_callback) : G_CALLBACK(stereo_menu_callback), p);
381 gtk_widget_show(item);
387 GtkWidget * LADSPA_Class :: get_ladspa_menu() {
388 return root->get_menu(MONO);
391 GtkWidget * LADSPA_Class :: get_stereo_ladspa_menu() {
392 return root->get_menu(STEREO);