bsd lang segv fix, enable bsd lv2, lv2 gui enable fix, proxy/ffmpeg toggle resize...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / pluginaclientlad.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "clip.h"
23 #include "bchash.h"
24 #include "filesystem.h"
25 #include "filexml.h"
26 #include "language.h"
27 #include "mwindow.h"
28 #include "pluginaclientlad.h"
29 #include "pluginserver.h"
30 #include "samples.h"
31 #include "vframe.h"
32
33 #include <ctype.h>
34 #include <string.h>
35
36
37
38 PluginAClientConfig::PluginAClientConfig()
39 {
40         reset();
41 }
42
43 PluginAClientConfig::~PluginAClientConfig()
44 {
45         delete_objects();
46 }
47
48 void PluginAClientConfig::reset()
49 {
50         total_ports = 0;
51         port_data = 0;
52         port_type = 0;
53 }
54
55 void PluginAClientConfig::delete_objects()
56 {
57         delete [] port_data;  port_data = 0;
58         delete [] port_type;  port_type = 0;
59         reset();
60 }
61
62
63 int PluginAClientConfig::equivalent(PluginAClientConfig &that)
64 {
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;
68         return 1;
69 }
70
71 // Need PluginServer to do this.
72 void PluginAClientConfig::copy_from(PluginAClientConfig &that)
73 {
74         if( total_ports != that.total_ports ) {
75                 delete_objects();
76                 total_ports = that.total_ports;
77                 port_data = new LADSPA_Data[total_ports];
78                 port_type = new int[total_ports];
79         }
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];
83         }
84 }
85
86 void PluginAClientConfig::interpolate(PluginAClientConfig &prev, PluginAClientConfig &next,
87         int64_t prev_frame, int64_t next_frame, int64_t current_frame)
88 {
89         copy_from(prev);
90 }
91
92 void PluginAClientConfig::initialize(PluginServer *server)
93 {
94         delete_objects();
95
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;
102                 ++total_ports;
103         }
104
105         port_data = new LADSPA_Data[total_ports];
106         port_type = new int[total_ports];
107
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
114                 float value = 0.0;
115
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;
124
125 // Get default of port using crazy hinting system
126                 if( LADSPA_IS_HINT_DEFAULT_0(hint_desc) )
127                         value = 0.0;
128                 else if( LADSPA_IS_HINT_DEFAULT_1(hint_desc) )
129                         value = 1.0;
130                 else if( LADSPA_IS_HINT_DEFAULT_100(hint_desc) )
131                         value = 100.0;
132                 else if( LADSPA_IS_HINT_DEFAULT_440(hint_desc) )
133                         value = 440.0;
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;
156
157                 port_data[port] = value;
158                 ++port;
159         }
160 }
161
162
163 PluginACLientToggle::PluginACLientToggle(PluginAClientLAD *plugin,
164         int x,
165         int y,
166         LADSPA_Data *output)
167  : BC_CheckBox(x, y, (int)(*output))
168 {
169         this->plugin = plugin;
170         this->output = output;
171 }
172
173 int PluginACLientToggle::handle_event()
174 {
175         *output = get_value();
176         plugin->send_configure_change();
177         return 1;
178 }
179
180
181 PluginACLientILinear::PluginACLientILinear(PluginAClientLAD *plugin,
182         int x,
183         int y,
184         LADSPA_Data *output,
185         int min,
186         int max)
187  : BC_IPot(x, y, (int)(*output), min, max)
188 {
189         this->plugin = plugin;
190         this->output = output;
191 }
192
193 int PluginACLientILinear::handle_event()
194 {
195         *output = get_value();
196         plugin->send_configure_change();
197         return 1;
198 }
199
200
201 PluginACLientFLinear::PluginACLientFLinear(PluginAClientLAD *plugin,
202         int x,
203         int y,
204         LADSPA_Data *output,
205         float min,
206         float max)
207  : BC_FPot(x, y, *output, min, max)
208 {
209         this->plugin = plugin;
210         this->output = output;
211         set_precision(0.01);
212 }
213
214 int PluginACLientFLinear::handle_event()
215 {
216         *output = get_value();
217         plugin->send_configure_change();
218         return 1;
219 }
220
221
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) :
226                 (int)*output)
227 {
228         this->plugin = plugin;
229         this->output = output;
230         this->translate_linear = translate_linear;
231 }
232
233 int PluginACLientFreq::handle_event()
234 {
235         *output = translate_linear ?
236                 (float)get_value() / plugin->PluginAClient::project_sample_rate :
237                 get_value();
238         plugin->send_configure_change();
239         return 1;
240 }
241
242
243
244 PluginAClientWindow::PluginAClientWindow(PluginAClientLAD *plugin)
245  : PluginClientWindow(plugin, 500, plugin->config.total_ports * 30 + 60,
246         500, plugin->config.total_ports * 30 + 60, 0)
247 {
248         this->plugin = plugin;
249 }
250
251 PluginAClientWindow::~PluginAClientWindow()
252 {
253 }
254
255
256 void PluginAClientWindow::create_objects()
257 {
258         PluginServer *server = plugin->server;
259         char string[BCTEXTLEN];
260         int current_port = 0;
261         int x = 10;
262         int y = 10;
263         int x2 = 300;
264         int x3 = 335;
265         int title_vmargin = 5;
266         int max_w = 0;
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;
275         }
276
277         x2 = max_w + 20;
278         x3 = max_w + 55;
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);
290
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],
300                                         min, max));
301                         fpots.append(flinear);
302                         break; }
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 */));
311                         freqs.append(freq);
312                         break; }
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);
320                         break; }
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);
331                         break; }
332                 }
333                 current_port++;
334                 y += 30;
335 //printf("PluginAClientWindow::create_objects 2\n");
336         }
337
338         y += 10;
339         sprintf(string, _("Author: %s"), lad_desc->Maker);
340         add_subwindow(new BC_Title(x, y, string));
341         y += 20;
342         sprintf(string, _("License: %s"), lad_desc->Copyright);
343         add_subwindow(new BC_Title(x, y, string));
344         show_window(1);
345 }
346
347
348
349 PluginAClientLAD::PluginAClientLAD(PluginServer *server)
350  : PluginAClient(server)
351 {
352         in_buffers = 0;
353         total_inbuffers = 0;
354         out_buffers = 0;
355         total_outbuffers = 0;
356         buffer_allocation = 0;
357         lad_instance = 0;
358         snprintf(title, sizeof(title), "L_%s", server->lad_descriptor->Name);
359 }
360
361 PluginAClientLAD::~PluginAClientLAD()
362 {
363         delete_buffers();
364         delete_plugin();
365 }
366
367 NEW_WINDOW_MACRO(PluginAClientLAD, PluginAClientWindow)
368
369 int PluginAClientLAD::is_realtime()
370 {
371         return 1;
372 }
373
374 int PluginAClientLAD::is_multichannel()
375 {
376         if(get_inchannels() > 1 || get_outchannels() > 1) return 1;
377         return 0;
378 }
379
380 int PluginAClientLAD::get_inchannels()
381 {
382         int result = 0;
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;
389                 ++result;
390         }
391         return result;
392 }
393
394 int PluginAClientLAD::get_outchannels()
395 {
396         int result = 0;
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;
403                 ++result;
404         }
405         return result;
406 }
407
408
409 const char* PluginAClientLAD::plugin_title()
410 {
411         return title;
412 }
413
414 int PluginAClientLAD::uses_gui()
415 {
416         return 1;
417 }
418
419 int PluginAClientLAD::is_synthesis()
420 {
421         return 1;
422 }
423
424 LOAD_CONFIGURATION_MACRO(PluginAClientLAD, PluginAClientConfig)
425
426 void PluginAClientLAD::update_gui()
427 {
428 }
429
430 char* PluginAClientLAD::lad_to_string(char *string, const char *input)
431 {
432         strcpy(string, input);
433         int len = strlen(string);
434         for(int j = 0; j < len; j++)
435         {
436                 if(string[j] == ' ' ||
437                         string[j] == '<' ||
438                         string[j] == '>') string[j] = '_';
439         }
440         return string;
441 }
442
443 char* PluginAClientLAD::lad_to_upper(char *string, const char *input)
444 {
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]);
449         return string;
450 }
451
452
453 void PluginAClientLAD::save_data(KeyFrame *keyframe)
454 {
455         FileXML output;
456         char string[BCTEXTLEN];
457         if( !config.port_data ) config.initialize(server);
458
459 // cause data to be stored directly in text
460         output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
461         output.tag.set_title(lad_to_upper(string, plugin_title()));
462
463         const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
464         const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
465 //printf("PluginAClientLAD::save_data %d\n", lad_desc->PortCount);
466         int port_count = lad_desc->PortCount;
467         for(int port = 0, i = 0; i < port_count; i++) {
468                 if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue;
469                 if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue;
470 // Convert LAD port name to default title
471                 PluginAClientLAD::lad_to_upper(string,
472                         (char*)lad_desc->PortNames[i]);
473                 output.tag.set_property(string, config.port_data[port]);
474 //printf("PluginAClientLAD::save_data %d %f\n", port, config.port_data[port]);
475                 ++port;
476         }
477
478         output.append_tag();
479         output.terminate_string();
480 }
481
482 void PluginAClientLAD::read_data(KeyFrame *keyframe)
483 {
484         FileXML input;
485         char string[BCTEXTLEN];
486
487         input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
488         if( !config.port_data ) config.initialize(server);
489
490         while(! input.read_tag() ) {
491 //printf("PluginAClientLAD::read_data %s\n", input.tag.get_title());
492                 if(! input.tag.title_is(lad_to_upper(string, plugin_title())) ) continue;
493                 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
494                 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
495                 int port_count = lad_desc->PortCount;
496                 for(int port = 0, i = 0; i < port_count; i++) {
497                         if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue;
498                         if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue;
499                         PluginAClientLAD::lad_to_upper(string, (char*)lad_desc->PortNames[i]);
500                         config.port_data[port] =
501                                 input.tag.get_property(string, config.port_data[port]);
502 //printf("PluginAClientLAD::read_data %d %f\n", port, config.port_data[port]);
503                         port++;
504                 }
505         }
506 }
507
508 void PluginAClientLAD::delete_buffers()
509 {
510         if( in_buffers ) {
511                 for( int i=0; i<total_inbuffers; ++i ) delete [] in_buffers[i];
512                 delete [] in_buffers;  in_buffers = 0;
513         }
514         if( out_buffers ) {
515                 for( int i=0; i<total_outbuffers; ++i ) delete [] out_buffers[i];
516                 delete [] out_buffers;  out_buffers = 0;
517         }
518         total_inbuffers = 0;
519         total_outbuffers = 0;
520         buffer_allocation = 0;
521 }
522
523 void PluginAClientLAD::delete_plugin()
524 {
525         if(lad_instance) {
526                 const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
527                 if( lad_desc->deactivate ) lad_desc->deactivate(lad_instance);
528                 lad_desc->cleanup(lad_instance);
529         }
530         lad_instance = 0;
531 }
532
533 void PluginAClientLAD::init_plugin(int total_in, int total_out, int size)
534 {
535         int need_reconfigure = !lad_instance ? 1 : 0;
536         if( !config.port_data ) {
537                 config.initialize(server);
538                 need_reconfigure = 1;
539         }
540         if(buffer_allocation && buffer_allocation < size) {
541                 delete_buffers();
542                 need_reconfigure = 1;
543         }
544
545         buffer_allocation = MAX(size, buffer_allocation);
546         if(!in_buffers) {
547                 total_inbuffers = total_in;
548                 in_buffers = new LADSPA_Data*[total_inbuffers];
549                 for(int i = 0; i < total_inbuffers; i++)
550                         in_buffers[i] = new LADSPA_Data[buffer_allocation];
551                 need_reconfigure = 1;
552         }
553
554         if(!out_buffers) {
555                 total_outbuffers = total_out;
556                 out_buffers = new LADSPA_Data*[total_outbuffers];
557                 for(int i = 0; i < total_outbuffers; i++)
558                         out_buffers[i] = new LADSPA_Data[buffer_allocation];
559                 need_reconfigure = 1;
560         }
561
562         if( load_configuration() )
563                 need_reconfigure = 1;
564
565         const LADSPA_Descriptor *lad_desc = server->lad_descriptor;
566         if( need_reconfigure ) {
567                 need_reconfigure = 0;
568                 delete_plugin();
569                 lad_instance = lad_desc->instantiate(
570                                 lad_desc,PluginAClient::project_sample_rate);
571                 const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
572                 int port_count = lad_desc->PortCount;
573
574                 for(int port = 0, i = 0; i < port_count; i++) {
575                         if( LADSPA_IS_PORT_INPUT(port_desc[i]) &&
576                             LADSPA_IS_PORT_CONTROL(port_desc[i]) ) {
577                                 lad_desc->connect_port(lad_instance, i,
578                                         config.port_data + port);
579                                 port++;
580                         }
581                         else if( LADSPA_IS_PORT_OUTPUT(port_desc[i]) &&
582                                  LADSPA_IS_PORT_CONTROL(port_desc[i]) ) {
583                                 lad_desc->connect_port(lad_instance, i,
584                                         &dummy_control_output);
585                         }
586                 }
587                 if(lad_desc->activate) lad_desc->activate(lad_instance);
588         }
589
590         const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors;
591         int port_count = lad_desc->PortCount;
592         for(int port = 0, i = 0; i < port_count; i++) {
593                 if( LADSPA_IS_PORT_INPUT(port_desc[i]) &&
594                     LADSPA_IS_PORT_AUDIO(port_desc[i]) )
595                         lad_desc->connect_port(lad_instance, i, in_buffers[port++]);
596         }
597
598         for(int port = 0, i = 0; i < port_count; i++) {
599                 if( LADSPA_IS_PORT_OUTPUT(port_desc[i]) &&
600                     LADSPA_IS_PORT_AUDIO(port_desc[i]) )
601                         lad_desc->connect_port(lad_instance, i, out_buffers[port++]);
602         }
603 }
604
605 int PluginAClientLAD::process_realtime(int64_t size,
606         Samples *input_ptr,
607         Samples *output_ptr)
608 {
609         int in_channels = get_inchannels();
610         int out_channels = get_outchannels();
611         init_plugin(in_channels, out_channels, size);
612
613         double *input_samples = input_ptr->get_data();
614         for(int i = 0; i < in_channels; i++) {
615                 LADSPA_Data *in_buffer = in_buffers[i];
616                 for(int j = 0; j < size; j++) in_buffer[j] = input_samples[j];
617         }
618         for(int i = 0; i < out_channels; i++)
619                 bzero(out_buffers[i], sizeof(float) * size);
620
621         server->lad_descriptor->run(lad_instance, size);
622
623         double *output_samples = output_ptr->get_data();
624         LADSPA_Data *out_buffer = out_buffers[0];
625         for(int i = 0; i < size; i++) output_samples[i] = out_buffer[i];
626         return size;
627 }
628
629 int PluginAClientLAD::process_realtime(int64_t size,
630         Samples **input_ptr, Samples **output_ptr)
631 {
632         int in_channels = get_inchannels();
633         int out_channels = get_outchannels();
634         init_plugin(in_channels, out_channels, size);
635
636         for(int i = 0; i < in_channels; i++) {
637                 float *in_buffer = in_buffers[i];
638                 int k = i < PluginClient::total_in_buffers ? i : 0;
639                 double *in_ptr = input_ptr[k]->get_data();
640                 for(int j = 0; j < size; j++) in_buffer[j] = in_ptr[j];
641         }
642         for(int i = 0; i < out_channels; i++)
643                 bzero(out_buffers[i], sizeof(float) * size);
644
645         server->lad_descriptor->run(lad_instance, size);
646
647         int nbfrs = PluginClient::total_out_buffers;
648         if( out_channels < nbfrs ) nbfrs = out_channels;
649         for(int i = 0; i < nbfrs; i++) {
650                 LADSPA_Data *out_buffer = out_buffers[i];
651                 double *out_ptr = output_ptr[i]->get_data();
652                 for(int j = 0; j < size; j++) out_ptr[j] = out_buffer[j];
653         }
654         return size;
655 }
656
657 int MWindow::init_ladspa_index(MWindow *mwindow, Preferences *preferences,
658         const char *index_path, const char *plugin_dir)
659 {
660         char plugin_path[BCTEXTLEN], *path = FileSystem::basepath(plugin_dir);
661         strcpy(plugin_path, path);  delete [] path;
662         printf("init ladspa index: %s\n", plugin_dir);
663         FILE *fp = fopen(index_path,"w");
664         if( !fp ) {
665                 fprintf(stderr,_("MWindow::init_ladspa_index: "
666                         "can't create plugin index: %s\n"), index_path);
667                 return 1;
668         }
669         fprintf(fp, "%d\n", PLUGIN_FILE_VERSION);
670         fprintf(fp, "%s\n", plugin_dir);
671         init_plugin_index(mwindow, preferences, fp, plugin_path);
672         fclose(fp);
673         return 0;
674 }
675