4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "filesystem.h"
28 #include "pluginaclientlad.h"
29 #include "pluginserver.h"
38 PluginAClientConfig::PluginAClientConfig()
43 PluginAClientConfig::~PluginAClientConfig()
48 void PluginAClientConfig::reset()
55 void PluginAClientConfig::delete_objects()
57 delete [] port_data; port_data = 0;
58 delete [] port_type; port_type = 0;
63 int PluginAClientConfig::equivalent(PluginAClientConfig &that)
65 if(that.total_ports != total_ports) return 0;
66 for(int i = 0; i < total_ports; i++)
67 if(!EQUIV(port_data[i], that.port_data[i])) return 0;
71 // Need PluginServer to do this.
72 void PluginAClientConfig::copy_from(PluginAClientConfig &that)
74 if( total_ports != that.total_ports ) {
76 total_ports = that.total_ports;
77 port_data = new LADSPA_Data[total_ports];
78 port_type = new int[total_ports];
80 for( int i=0; i<total_ports; ++i ) {
81 port_type[i] = that.port_type[i];
82 port_data[i] = that.port_data[i];
86 void PluginAClientConfig::interpolate(PluginAClientConfig &prev, PluginAClientConfig &next,
87 int64_t prev_frame, int64_t next_frame, int64_t current_frame)
92 void PluginAClientConfig::initialize(PluginServer *server)
96 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
97 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
98 int port_count = lad_desc->PortCount;
99 for(int i = 0; i < port_count; i++) {
100 if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue;
101 if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue;
105 port_data = new LADSPA_Data[total_ports];
106 port_type = new int[total_ports];
108 for(int port = 0, i = 0; i < port_count; i++) {
109 if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue;
110 if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue;
111 const LADSPA_PortRangeHint *lad_hint = &lad_desc->PortRangeHints[i];
112 LADSPA_PortRangeHintDescriptor hint_desc = lad_hint->HintDescriptor;
113 // Convert LAD default to default value
116 // Store type of port for GUI use
117 port_type[port] = PORT_NORMAL;
118 if( LADSPA_IS_HINT_SAMPLE_RATE(hint_desc) )
119 port_type[port] = PORT_FREQ_INDEX;
120 else if(LADSPA_IS_HINT_TOGGLED(hint_desc))
121 port_type[port] = PORT_TOGGLE;
122 else if(LADSPA_IS_HINT_INTEGER(hint_desc))
123 port_type[port] = PORT_INTEGER;
125 // Get default of port using crazy hinting system
126 if( LADSPA_IS_HINT_DEFAULT_0(hint_desc) )
128 else if( LADSPA_IS_HINT_DEFAULT_1(hint_desc) )
130 else if( LADSPA_IS_HINT_DEFAULT_100(hint_desc) )
132 else if( LADSPA_IS_HINT_DEFAULT_440(hint_desc) )
134 else if( LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint_desc) )
135 value = lad_hint->UpperBound;
136 else if( LADSPA_IS_HINT_DEFAULT_MINIMUM(hint_desc) )
137 value = lad_hint->LowerBound;
138 else if( LADSPA_IS_HINT_DEFAULT_LOW(hint_desc) )
139 value = LADSPA_IS_HINT_LOGARITHMIC(hint_desc) ?
140 exp(log(lad_hint->LowerBound) * 0.25 +
141 log(lad_hint->UpperBound) * 0.75) :
142 lad_hint->LowerBound * 0.25 +
143 lad_hint->UpperBound * 0.75;
144 else if( LADSPA_IS_HINT_DEFAULT_MIDDLE(hint_desc) )
145 value = LADSPA_IS_HINT_LOGARITHMIC(hint_desc) ?
146 exp(log(lad_hint->LowerBound) * 0.5 +
147 log(lad_hint->UpperBound) * 0.5) :
148 lad_hint->LowerBound * 0.5 +
149 lad_hint->UpperBound * 0.5;
150 else if( LADSPA_IS_HINT_DEFAULT_HIGH(hint_desc) )
151 value = LADSPA_IS_HINT_LOGARITHMIC(hint_desc) ?
152 exp(log(lad_hint->LowerBound) * 0.75 +
153 log(lad_hint->UpperBound) * 0.25) :
154 lad_hint->LowerBound * 0.75 +
155 lad_hint->UpperBound * 0.25;
157 port_data[port] = value;
163 PluginACLientToggle::PluginACLientToggle(PluginAClientLAD *plugin,
167 : BC_CheckBox(x, y, (int)(*output))
169 this->plugin = plugin;
170 this->output = output;
173 int PluginACLientToggle::handle_event()
175 *output = get_value();
176 plugin->send_configure_change();
181 PluginACLientILinear::PluginACLientILinear(PluginAClientLAD *plugin,
187 : BC_IPot(x, y, (int)(*output), min, max)
189 this->plugin = plugin;
190 this->output = output;
193 int PluginACLientILinear::handle_event()
195 *output = get_value();
196 plugin->send_configure_change();
201 PluginACLientFLinear::PluginACLientFLinear(PluginAClientLAD *plugin,
207 : BC_FPot(x, y, *output, min, max)
209 this->plugin = plugin;
210 this->output = output;
214 int PluginACLientFLinear::handle_event()
216 *output = get_value();
217 plugin->send_configure_change();
222 PluginACLientFreq::PluginACLientFreq(PluginAClientLAD *plugin,
223 int x, int y, LADSPA_Data *output, int translate_linear)
224 : BC_QPot(x, y, translate_linear ?
225 (int)(*output * plugin->PluginAClient::project_sample_rate) :
228 this->plugin = plugin;
229 this->output = output;
230 this->translate_linear = translate_linear;
233 int PluginACLientFreq::handle_event()
235 *output = translate_linear ?
236 (float)get_value() / plugin->PluginAClient::project_sample_rate :
238 plugin->send_configure_change();
244 PluginAClientWindow::PluginAClientWindow(PluginAClientLAD *plugin)
245 : PluginClientWindow(plugin, 500, plugin->config.total_ports * 30 + 60,
246 500, plugin->config.total_ports * 30 + 60, 0)
248 this->plugin = plugin;
251 PluginAClientWindow::~PluginAClientWindow()
256 void PluginAClientWindow::create_objects()
258 PluginServer *server = plugin->server;
259 char string[BCTEXTLEN];
260 int current_port = 0;
265 int title_vmargin = 5;
267 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
268 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
269 int port_count = lad_desc->PortCount;
270 for(int i = 0; i < port_count; i++) {
271 if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue;
272 if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue;
273 int w = get_text_width(MEDIUMFONT, (char*)lad_desc->PortNames[i]);
274 if(w > max_w) max_w = w;
279 for(int i = 0; i < port_count; i++) {
280 if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue;
281 if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue;
282 const LADSPA_PortRangeHint *lad_hint = &lad_desc->PortRangeHints[i];
283 LADSPA_PortRangeHintDescriptor hint_desc = lad_hint->HintDescriptor;
284 int use_min = LADSPA_IS_HINT_BOUNDED_BELOW(hint_desc);
285 int use_max = LADSPA_IS_HINT_BOUNDED_ABOVE(hint_desc);
286 sprintf(string, "%s:", lad_desc->PortNames[i]);
287 // printf("PluginAClientWindow::create_objects 1 %s type=%d lower: %d %f upper: %d %f\n",
288 // string, plugin->config.port_type[current_port],
289 // use_min, lad_hint->LowerBound, use_max, lad_hint->UpperBound);
291 switch(plugin->config.port_type[current_port]) {
292 case PluginAClientConfig::PORT_NORMAL: {
293 PluginACLientFLinear *flinear;
294 float min = use_min ? lad_hint->LowerBound : 0;
295 float max = use_max ? lad_hint->UpperBound : 100;
296 add_subwindow(new BC_Title(x, y + title_vmargin, string));
297 add_subwindow(flinear = new PluginACLientFLinear(
298 plugin, (current_port % 2) ? x2 : x3, y,
299 &plugin->config.port_data[current_port],
301 fpots.append(flinear);
303 case PluginAClientConfig::PORT_FREQ_INDEX: {
304 PluginACLientFreq *freq;
305 add_subwindow(new BC_Title(x, y + title_vmargin, string));
306 add_subwindow(freq = new PluginACLientFreq(plugin,
307 (current_port % 2) ? x2 : x3, y,
308 &plugin->config.port_data[current_port], 0
309 /* (plugin->config.port_type[current_port] ==
310 PluginAClientConfig::PORT_FREQ_INDEX */));
313 case PluginAClientConfig::PORT_TOGGLE: {
314 PluginACLientToggle *toggle;
315 add_subwindow(new BC_Title(x, y + title_vmargin, string));
316 add_subwindow(toggle = new PluginACLientToggle(plugin,
317 (current_port % 2) ? x2 : x3, y,
318 &plugin->config.port_data[current_port]));
319 toggles.append(toggle);
321 case PluginAClientConfig::PORT_INTEGER: {
322 PluginACLientILinear *ilinear;
323 float min = use_min ? lad_hint->LowerBound : 0;
324 float max = use_max ? lad_hint->UpperBound : 100;
325 add_subwindow(new BC_Title(x, y + title_vmargin, string));
326 add_subwindow(ilinear = new PluginACLientILinear( plugin,
327 (current_port % 2) ? x2 : x3, y,
328 &plugin->config.port_data[current_port],
329 (int)min, (int)max));
330 ipots.append(ilinear);
335 //printf("PluginAClientWindow::create_objects 2\n");
339 sprintf(string, _("Author: %s"), lad_desc->Maker);
340 add_subwindow(new BC_Title(x, y, string));
342 sprintf(string, _("License: %s"), lad_desc->Copyright);
343 add_subwindow(new BC_Title(x, y, string));
349 PluginAClientLAD::PluginAClientLAD(PluginServer *server)
350 : PluginAClient(server)
355 total_outbuffers = 0;
356 buffer_allocation = 0;
358 snprintf(title, sizeof(title), "L_%s", server->lad_descriptor->Name);
361 PluginAClientLAD::~PluginAClientLAD()
367 NEW_WINDOW_MACRO(PluginAClientLAD, PluginAClientWindow)
369 int PluginAClientLAD::is_realtime()
374 int PluginAClientLAD::is_multichannel()
376 if(get_inchannels() > 1 || get_outchannels() > 1) return 1;
380 int PluginAClientLAD::get_inchannels()
383 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
384 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
385 int port_count = lad_desc->PortCount;
386 for( int i = 0; i < port_count; ++i ) {
387 if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue;
388 if( !LADSPA_IS_PORT_AUDIO(port_desc[i]) ) continue;
394 int PluginAClientLAD::get_outchannels()
397 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
398 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
399 int port_count = lad_desc->PortCount;
400 for( int i = 0; i < port_count; ++i ) {
401 if( !LADSPA_IS_PORT_OUTPUT(port_desc[i]) ) continue;
402 if( !LADSPA_IS_PORT_AUDIO(port_desc[i]) ) continue;
409 const char* PluginAClientLAD::plugin_title()
414 int PluginAClientLAD::uses_gui()
419 int PluginAClientLAD::is_synthesis()
424 LOAD_CONFIGURATION_MACRO(PluginAClientLAD, PluginAClientConfig)
426 void PluginAClientLAD::update_gui()
430 char* PluginAClientLAD::lad_to_string(char *string, const char *input)
432 strcpy(string, input);
433 int len = strlen(string);
434 for(int j = 0; j < len; j++)
436 if(string[j] == ' ' ||
438 string[j] == '>') string[j] = '_';
443 char* PluginAClientLAD::lad_to_upper(char *string, const char *input)
445 lad_to_string(string, input);
446 int len = strlen(string);
447 for(int j = 0; j < len; j++)
448 string[j] = toupper(string[j]);
453 void PluginAClientLAD::save_data(KeyFrame *keyframe)
455 if( !config.port_data ) config.initialize(server);
457 // cause data to be stored directly in text
458 output.set_shared_output(keyframe->xbuf);
459 char string[BCTEXTLEN];
460 output.tag.set_title(lad_to_upper(string, plugin_title()));
462 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
463 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
464 //printf("PluginAClientLAD::save_data %d\n", lad_desc->PortCount);
465 int port_count = lad_desc->PortCount;
466 for(int port = 0, i = 0; i < port_count; i++) {
467 if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue;
468 if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue;
469 // Convert LAD port name to default title
470 PluginAClientLAD::lad_to_upper(string,
471 (char*)lad_desc->PortNames[i]);
472 output.tag.set_property(string, config.port_data[port]);
473 //printf("PluginAClientLAD::save_data %d %f\n", port, config.port_data[port]);
478 output.terminate_string();
481 void PluginAClientLAD::read_data(KeyFrame *keyframe)
483 if( !config.port_data ) config.initialize(server);
485 input.set_shared_input(keyframe->xbuf);
487 while(! input.read_tag() ) {
488 //printf("PluginAClientLAD::read_data %s\n", input.tag.get_title());
489 char string[BCTEXTLEN];
490 if(! input.tag.title_is(lad_to_upper(string, plugin_title())) ) continue;
491 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
492 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
493 int port_count = lad_desc->PortCount;
494 for(int port = 0, i = 0; i < port_count; i++) {
495 if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue;
496 if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue;
497 PluginAClientLAD::lad_to_upper(string, (char*)lad_desc->PortNames[i]);
498 config.port_data[port] =
499 input.tag.get_property(string, config.port_data[port]);
500 //printf("PluginAClientLAD::read_data %d %f\n", port, config.port_data[port]);
506 void PluginAClientLAD::delete_buffers()
509 for( int i=0; i<total_inbuffers; ++i ) delete [] in_buffers[i];
510 delete [] in_buffers; in_buffers = 0;
513 for( int i=0; i<total_outbuffers; ++i ) delete [] out_buffers[i];
514 delete [] out_buffers; out_buffers = 0;
517 total_outbuffers = 0;
518 buffer_allocation = 0;
521 void PluginAClientLAD::delete_plugin()
524 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
525 if( lad_desc->deactivate ) lad_desc->deactivate(lad_instance);
526 lad_desc->cleanup(lad_instance);
531 void PluginAClientLAD::init_plugin(int total_in, int total_out, int size)
533 int need_reconfigure = !lad_instance ? 1 : 0;
534 if( !config.port_data ) {
535 config.initialize(server);
536 need_reconfigure = 1;
538 if(buffer_allocation && buffer_allocation < size) {
540 need_reconfigure = 1;
543 buffer_allocation = MAX(size, buffer_allocation);
545 total_inbuffers = total_in;
546 in_buffers = new LADSPA_Data*[total_inbuffers];
547 for(int i = 0; i < total_inbuffers; i++)
548 in_buffers[i] = new LADSPA_Data[buffer_allocation];
549 need_reconfigure = 1;
553 total_outbuffers = total_out;
554 out_buffers = new LADSPA_Data*[total_outbuffers];
555 for(int i = 0; i < total_outbuffers; i++)
556 out_buffers[i] = new LADSPA_Data[buffer_allocation];
557 need_reconfigure = 1;
560 if( load_configuration() )
561 need_reconfigure = 1;
563 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
564 if( need_reconfigure ) {
565 need_reconfigure = 0;
567 lad_instance = lad_desc->instantiate(
568 lad_desc,PluginAClient::project_sample_rate);
569 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
570 int port_count = lad_desc->PortCount;
572 for(int port = 0, i = 0; i < port_count; i++) {
573 if( LADSPA_IS_PORT_INPUT(port_desc[i]) &&
574 LADSPA_IS_PORT_CONTROL(port_desc[i]) ) {
575 lad_desc->connect_port(lad_instance, i,
576 config.port_data + port);
579 else if( LADSPA_IS_PORT_OUTPUT(port_desc[i]) &&
580 LADSPA_IS_PORT_CONTROL(port_desc[i]) ) {
581 lad_desc->connect_port(lad_instance, i,
582 &dummy_control_output);
585 if(lad_desc->activate) lad_desc->activate(lad_instance);
588 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
589 int port_count = lad_desc->PortCount;
590 for(int port = 0, i = 0; i < port_count; i++) {
591 if( LADSPA_IS_PORT_INPUT(port_desc[i]) &&
592 LADSPA_IS_PORT_AUDIO(port_desc[i]) )
593 lad_desc->connect_port(lad_instance, i, in_buffers[port++]);
596 for(int port = 0, i = 0; i < port_count; i++) {
597 if( LADSPA_IS_PORT_OUTPUT(port_desc[i]) &&
598 LADSPA_IS_PORT_AUDIO(port_desc[i]) )
599 lad_desc->connect_port(lad_instance, i, out_buffers[port++]);
603 int PluginAClientLAD::process_realtime(int64_t size,
607 int in_channels = get_inchannels();
608 int out_channels = get_outchannels();
609 init_plugin(in_channels, out_channels, size);
611 double *input_samples = input_ptr->get_data();
612 for(int i = 0; i < in_channels; i++) {
613 LADSPA_Data *in_buffer = in_buffers[i];
614 for(int j = 0; j < size; j++) in_buffer[j] = input_samples[j];
616 for(int i = 0; i < out_channels; i++)
617 bzero(out_buffers[i], sizeof(float) * size);
619 server->lad_descriptor->run(lad_instance, size);
621 double *output_samples = output_ptr->get_data();
622 LADSPA_Data *out_buffer = out_buffers[0];
623 for(int i = 0; i < size; i++) output_samples[i] = out_buffer[i];
627 int PluginAClientLAD::process_realtime(int64_t size,
628 Samples **input_ptr, Samples **output_ptr)
630 int in_channels = get_inchannels();
631 int out_channels = get_outchannels();
632 init_plugin(in_channels, out_channels, size);
634 for(int i = 0; i < in_channels; i++) {
635 float *in_buffer = in_buffers[i];
636 int k = i < PluginClient::total_in_buffers ? i : 0;
637 double *in_ptr = input_ptr[k]->get_data();
638 for(int j = 0; j < size; j++) in_buffer[j] = in_ptr[j];
640 for(int i = 0; i < out_channels; i++)
641 bzero(out_buffers[i], sizeof(float) * size);
643 server->lad_descriptor->run(lad_instance, size);
645 int nbfrs = PluginClient::total_out_buffers;
646 if( out_channels < nbfrs ) nbfrs = out_channels;
647 for(int i = 0; i < nbfrs; i++) {
648 LADSPA_Data *out_buffer = out_buffers[i];
649 double *out_ptr = output_ptr[i]->get_data();
650 for(int j = 0; j < size; j++) out_ptr[j] = out_buffer[j];
655 int MWindow::init_ladspa_index(MWindow *mwindow, Preferences *preferences,
656 FILE *fp, const char *plugin_dir)
658 char plugin_path[BCTEXTLEN], *path = FileSystem::basepath(plugin_dir);
659 strcpy(plugin_path, path); delete [] path;
660 printf("init ladspa index: %s\n", plugin_dir);
661 fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
662 fprintf(fp, "%s\n", plugin_dir);
663 init_plugin_index(mwindow, preferences, fp, plugin_path);