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.
21 Description: LADSPA_Plugin takes care of loading LADSPA plugins.
22 Most of this code is based on the LADSPA SDK code by
23 Richard W.E. Furse. For more information about ladspa
24 checkout http://www.ladspa.org
27 #include <tX_ladspa.h>
28 #include <tX_ladspa_class.h>
35 std::list <LADSPA_Plugin *> LADSPA_Plugin :: plugin_list;
37 void LADSPA_Plugin :: init ()
39 char *ladspa_path_ptr;
40 char ladspa_path[PATH_MAX];
41 char *start, *end, *buffer;
43 /* Finding the LADSPA Path */
44 ladspa_path_ptr=getenv("LADSPA_PATH");
46 if (!ladspa_path_ptr) {
47 tX_warning("LADSPA_PATH not set. Trying /usr/lib/ladspa:/usr/local/lib/ladspa");
48 strcpy(ladspa_path, "/usr/lib/ladspa:/usr/local/lib/ladspa");
50 else strcpy(ladspa_path, ladspa_path_ptr);
52 /* Scanning every dir in path */
55 while (*start != '\0')
58 while (*end != ':' && *end != '\0') end++;
60 buffer = (char *) malloc(1 + end - start);
61 if (end > start) strncpy(buffer, start, end - start);
63 buffer[end - start] = '\0';
64 LADSPA_Plugin::scandir(buffer);
68 if (*start == ':') start++;
72 /* This routine expects to get *valid* port descriptors.
73 There's no error checking as in the LADSPA SDK's "analyseplugin".
76 void LADSPA_Plugin :: handlelib(void *lib, LADSPA_Descriptor_Function desc_func, char *filename)
80 const LADSPA_Descriptor *descriptor;
81 int in_audio, out_audio, in_ctrl;
83 for (i=0; (descriptor = desc_func(i)) != NULL; i++) {
84 if (LADSPA_IS_INPLACE_BROKEN(descriptor->Properties)) {
85 tX_warning("Plugin \"%s\" disabled. No in-place processing support.", descriptor->Name);
87 in_audio=0; out_audio=0; in_ctrl=0;
89 for (port = 0; port<descriptor->PortCount; port++) {
90 if (LADSPA_IS_PORT_AUDIO(descriptor->PortDescriptors[port])) {
91 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[port])) in_audio++;
93 if (LADSPA_IS_PORT_OUTPUT(descriptor->PortDescriptors[port])) out_audio++;
95 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[port]) && LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[port])) in_ctrl++;
98 if ((in_audio == 1) && (out_audio == 1)) {
99 new LADSPA_Plugin(descriptor, filename);
101 else { tX_warning("Plugin \"%s\" disabled. Not a 1-in/1-out plugin.", descriptor->Name); }
106 void LADSPA_Plugin :: scandir(char *dirname)
108 int dirlen=strlen(dirname);
111 struct dirent * entry;
114 LADSPA_Descriptor_Function desc_func;
116 if (!dirlen) { tX_error("tX: Error: empty directory name?"); return; };
118 if (dirname[dirlen - 1] != '/') needslash=1;
120 dir = opendir(dirname);
122 if (!dir) { tX_error("tX: Error: couldn't access directory \"%s\".", dirname); return; };
126 if (!entry) { closedir(dir); return; }
128 filename = (char *) malloc (dirlen + strlen(entry->d_name) + 1 + needslash);
130 strcpy(filename, dirname);
131 if (needslash) strcat(filename, "/");
132 strcat(filename, entry->d_name);
134 handle = dlopen(filename, RTLD_LAZY);
140 /* check wether this is a LADSPA lib */
141 desc_func = (LADSPA_Descriptor_Function) dlsym(handle, "ladspa_descriptor");
143 if (dlerror() == NULL && desc_func) {
144 LADSPA_Plugin :: handlelib(handle, desc_func, entry->d_name);
146 tX_error("tX: Error: %s is not a LADSPA plugin library.", filename);
155 void LADSPA_Plugin :: status ()
157 printf ("tX: %i LADSPA plugins available\n", plugin_list.size());
161 void LADSPA_Plugin :: debug_display()
163 std::list <LADSPA_Plugin *> :: iterator plugin;
165 for (plugin=plugin_list.begin(); plugin != plugin_list.end(); plugin++) {
166 printf("plugin: %60s | id: %5li | ports: %2li\n", (*plugin)->getName(), (*plugin)->getUniqueID(), (*plugin)->getPortCount());
170 LADSPA_Plugin :: LADSPA_Plugin (const LADSPA_Descriptor *ld, char *filename)
172 ladspa_descriptor = ld;
174 plugin_list.push_back(this);
175 strcpy(file, filename);
176 sprintf(info_string, "LADSPA-Plugin: %s\nLabel: %s\nFile: %s\nUnique ID: %li\nMaker: %s\nCopyright: %s", ld->Name, ld->Label, file, ld->UniqueID, ld->Maker, ld->Copyright);
177 LADSPA_Class::add_plugin(this);
180 LADSPA_Plugin * LADSPA_Plugin :: getPluginByIndex(int i)
182 std::list <LADSPA_Plugin *> :: iterator plugin;
185 plugin = plugin_list.begin();
186 for (p=0; (p<i) && (plugin != plugin_list.end()); p++, plugin++);
188 if (plugin==plugin_list.end()) return NULL;
190 else return (*plugin);
193 LADSPA_Plugin * LADSPA_Plugin :: getPluginByUniqueID(long ID)
195 std::list <LADSPA_Plugin *> :: iterator plugin;
197 for (plugin=plugin_list.begin(); plugin != plugin_list.end(); plugin++) {
198 if ((*plugin)->getUniqueID()==ID) return (*plugin);