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: This handles the effects in the per vtt fx chain. Supports the
22 buitlin echo/lowpass effects and ladspa plugins.
29 #define myvtt ((vtt_class *) vtt)
30 #include "tX_global.h"
32 float ladspa_dummy_output_port;
34 void vtt_fx :: reconnect_buffer()
39 vtt_fx :: ~vtt_fx() {}
41 /******************* builtin fx ***/
44 void vtt_fx_lp :: activate() { myvtt->lp_reset(); }
45 void vtt_fx_lp :: deactivate() { /* NOP */ }
46 void vtt_fx_lp :: run() { myvtt->render_lp(); }
47 int vtt_fx_lp :: isEnabled() { return myvtt->lp_enable; }
49 void vtt_fx_lp :: save (FILE *rc, gzFile rz, char *indent) {
50 tX_store("%s<cutoff/>\n", indent);
53 const char *vtt_fx_lp :: get_info_string()
55 return "TerminatorX built-in resonant lowpass filter.";
60 void vtt_fx_ec :: activate() { /* NOP */ }
61 void vtt_fx_ec :: deactivate() { myvtt->ec_clear_buffer(); }
62 void vtt_fx_ec :: run() { myvtt->render_ec(); }
63 int vtt_fx_ec :: isEnabled() { return myvtt->ec_enable; }
65 void vtt_fx_ec :: save (FILE *rc, gzFile rz, char *indent) {
66 tX_store("%s<lowpass/>\n", indent);
69 const char *vtt_fx_ec :: get_info_string()
71 return "TerminatorX built-in echo effect.";
75 /******************** LADSPA fx ***/
76 /* short cut "cpd" macro to current port descriptor */
78 #define cpd plugin->getDescriptor()->PortDescriptors[port]
79 #define cpn plugin->getDescriptor()->PortNames[port]
80 #define cph plugin->getDescriptor()->PortRangeHints[port]
82 void vtt_fx_ladspa :: reconnect_buffer()
84 plugin->getDescriptor()->connect_port(instance, input_port, myvtt->output_buffer);
85 plugin->getDescriptor()->connect_port(instance, output_port, myvtt->output_buffer);
88 static void wrapstr(char *str)
94 token=strtok(str, " ");
98 if (strlen(token)+strlen(temp)<10)
100 if (strlen(temp)) strcat(temp, " ");
107 if(strlen(target)) strcat(target, "\n");
115 strcat(target, temp);
119 token=strtok(NULL, " ");
124 if(strlen(target)) strcat(target, "\n");
125 strcat(target, temp);
131 vtt_fx_ladspa :: vtt_fx_ladspa(LADSPA_Plugin *p, void *v)
142 instance=(LADSPA_Handle *) plugin->getDescriptor()->instantiate(plugin->getDescriptor(), 44100);
146 fprintf (stderr, "tX: Fatal Error: failed to instantiate plugin \"%s\".\n", plugin->getDescriptor()->Name);
147 /* How to handle this ? */
150 sp = sp_enable = new tX_seqpar_vttfx_bool();
151 sp->set_mapping_parameters(1, 0, 0, 0);
152 sprintf(buffer, "%s: Enable", plugin->getName());
153 sp->set_name(buffer, "Enable");
155 controls.push_back(sp);
157 /* if (plugin->getDescriptor()->run_adding && plugin->getDescriptor()->set_run_adding_gain) {
158 sp = sp_outgain = new tX_seqpar_vttfx_float();
159 sp->set_mapping_parameters(3, 0, 0.01, 1);
160 sprintf(buffer, "%s: Out Gain", plugin->getName());
161 sp->set_name(buffer, "Out Gain");
163 controls.push_back(sp);
170 /* connecting ports */
171 for (port=0; port < plugin->getPortCount(); port++) {
172 if (LADSPA_IS_PORT_AUDIO(cpd)) {
173 if (LADSPA_IS_PORT_INPUT(cpd)) input_port=port;
174 else if (LADSPA_IS_PORT_OUTPUT(cpd)) output_port=port;
175 } else if ((LADSPA_IS_PORT_CONTROL(cpd)) && (LADSPA_IS_PORT_INPUT(cpd))) {
179 if (LADSPA_IS_HINT_BOUNDED_BELOW(cph.HintDescriptor)) min=cph.LowerBound;
180 if (LADSPA_IS_HINT_BOUNDED_ABOVE(cph.HintDescriptor)) max=cph.UpperBound;
182 if (LADSPA_IS_HINT_SAMPLE_RATE(cph.HintDescriptor)) {
183 min*=44100; max*=44100;
186 if (LADSPA_IS_HINT_TOGGLED(cph.HintDescriptor)) {
187 sp=new tX_seqpar_vttfx_bool();
188 sp->set_mapping_parameters(max, min, 0, 0);
189 } else if (LADSPA_IS_HINT_INTEGER(cph.HintDescriptor)) {
190 sp=new tX_seqpar_vttfx_int();
191 sp->set_mapping_parameters(max, min, 0, 0);
193 sp=new tX_seqpar_vttfx_float();
194 sp->set_mapping_parameters(max, min, (max-min)/100.0, 1);
197 sprintf(buffer, "%s: %s", plugin->getLabel(), cpn);
198 strcpy(buffer2, cpn);
201 sp->set_name(buffer, buffer2);
203 plugin->getDescriptor()->connect_port(instance, port, sp->get_value_ptr());
204 controls.push_back(sp);
205 } else if ((LADSPA_IS_PORT_CONTROL(cpd)) && (LADSPA_IS_PORT_OUTPUT(cpd))) {
206 plugin->getDescriptor()->connect_port(instance, port, &ladspa_dummy_output_port);
212 void vtt_fx_ladspa :: activate()
214 if (plugin->getDescriptor()->activate) plugin->getDescriptor()->activate(instance);
217 void vtt_fx_ladspa :: deactivate()
219 if (plugin->getDescriptor()->deactivate) plugin->getDescriptor()->deactivate(instance);
222 void vtt_fx_ladspa :: run()
225 plugin->getDescriptor()->set_run_adding_gain(instance, sp_outgain->get_value());
226 plugin->getDescriptor()->run_adding(instance, (vtt_class :: samples_in_mix_buffer)>>1);
228 plugin->getDescriptor()->run(instance, (vtt_class :: samples_in_mix_buffer)>>1);
232 int vtt_fx_ladspa :: isEnabled()
234 return (int) sp_enable->get_value();
237 const char *vtt_fx_ladspa :: get_info_string()
239 return plugin->get_info_string();
242 vtt_fx_ladspa :: ~vtt_fx_ladspa()
244 list <tX_seqpar_vttfx *> :: iterator sp;
246 while (controls.size()) {
248 controls.remove((*sp));
252 plugin->getDescriptor()->cleanup(instance);
257 void vtt_fx_ladspa :: save (FILE *rc, gzFile rz, char *indent) {
258 long ID=plugin->getUniqueID();
259 list <tX_seqpar_vttfx *> :: iterator sp;
261 tX_store("%s<ladspa_plugin>\n", indent);
262 strcat (indent, "\t");
264 store_int("ladspa_id", ID);
266 for (sp=controls.begin(); sp!=controls.end(); sp++) {
267 store_float_sp("param", (*sp)->get_value(), (*(*sp)));
270 store_bool("panel_hidden", panel->is_hidden());
272 indent[strlen(indent)-1]=0;
273 tX_store("%s</ladspa_plugin>\n", indent);
276 void vtt_fx_ladspa :: load(xmlDocPtr doc, xmlNodePtr node) {
279 list <tX_seqpar_vttfx *> :: iterator sp=controls.begin();
283 for (xmlNodePtr cur=node->xmlChildrenNode; cur!=NULL; cur=cur->next) {
284 if (cur->type == XML_ELEMENT_NODE) {
287 restore_int("ladspa_id", dummy);
288 restore_bool("panel_hidden", hidden);
290 if ((!elementFound) && (xmlStrcmp(cur->name, (xmlChar *) "param")==0)) {
295 if (sp==controls.end()) {
296 tX_warning("found unexpected parameters for ladspa plugin [%i].", dummy);
298 restore_float_id("param", val, (*(*sp)), (*sp)->do_exec(val));
299 (*sp)->do_update_graphics();
305 tX_warning("unhandled ladspa_plugin element %s.", cur->name);