1/* FluidSynth - A Software Synthesizer
2 *
3 * Copyright (C) 2003  Peter Hanappe and others.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public License
7 * as published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307, USA
19 */
20
21/* This module: 3/2002
22 * Author: Markus Nentwig, nentwig@users.sourceforge.net
23 */
24
25#define PrintErrorMessage -1
26
27#include "fluidsynth_priv.h"
28
29#ifdef LADSPA
30#include <assert.h>
31
32/* Dynamic library functions */
33#include <dlfcn.h>
34
35#include "fluid_ladspa.h"
36#include "fluid_synth.h"
37#include "fluid_io.h"
38
39/* Logging to stdout. */
40//#define L(x) x;printf("\n");
41#define L(x);
42
43fluid_LADSPA_FxUnit_t* new_fluid_LADSPA_FxUnit(fluid_synth_t* synth){
44  fluid_LADSPA_FxUnit_t* FxUnit=FLUID_NEW(fluid_LADSPA_FxUnit_t);
45  assert(FxUnit);
46  assert(synth);
47  /* The default state is 'bypassed'. The Fx unit has to be turned on explicitly by the user. */
48  /* Those settings have to be done in order to allow fluid_LADSPA_clean. */
49  FxUnit->Bypass=fluid_LADSPA_Bypassed;
50  FxUnit->NumberNodes=0;
51  FxUnit->NumberPlugins=0;
52  FxUnit->NumberLibs=0;
53  FxUnit->NumberCommands=0;
54  FxUnit->NumberUserControlNodes=0;
55  FxUnit->synth=synth;
56  pthread_cond_init(&FxUnit->cond,NULL);
57  return FxUnit;
58};
59
60/* Purpose:
61 * Creates the system nodes to get data into and out of the Fx unit.
62 */
63void fluid_LADSPA_CreateSystemNodes(fluid_LADSPA_FxUnit_t* FxUnit){
64  char str[99];
65  int nr_input_nodes;
66  int nr_fx_input_nodes;
67  int nr_output_nodes;
68  int temp;
69  int i;
70
71  /* Retrieve the number of synth / audio out / Fx send nodes */
72  assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-groups", &temp));
73  nr_input_nodes=(int) temp;
74  printf("%i audio groups\n", nr_input_nodes);
75
76  assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-channels", &temp));
77  nr_output_nodes=temp;
78
79  assert(fluid_settings_getint(FxUnit->synth->settings, "synth.effects-channels", &temp));
80  nr_fx_input_nodes=temp;
81
82  /* Create regular input nodes (associated with audio groups) */
83  for (i=0; i < nr_input_nodes; i++){
84      sprintf(str, "in%i_L",(i+1));
85      fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_source);
86      sprintf(str, "in%i_R",(i+1));
87      fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_source);
88  };
89
90  /* Create effects send nodes (for example reverb, chorus send) */
91  for (i=0; i < nr_fx_input_nodes; i++){
92      sprintf(str, "send%i_L",(i+1));
93      fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_source);
94      sprintf(str, "send%i_R",(i+1));
95      fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_source);
96  };
97
98  /* Create output nodes (usually towards the sound card) */
99  for (i=0; i < nr_input_nodes; i++){
100      sprintf(str, "out%i_L",(i+1));
101      fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_sink);
102      sprintf(str, "out%i_R",(i+1));
103      fluid_LADSPA_CreateNode(FxUnit, str, fluid_LADSPA_node_is_audio | fluid_LADSPA_node_is_sink);
104  };
105};
106
107/* Purpose:
108 * Creates predeclared nodes for control of the Fx unit during operation.
109 */
110void fluid_LADSPA_CreateUserControlNodes(fluid_LADSPA_FxUnit_t* FxUnit){
111  int i;
112  fluid_LADSPA_Node_t* CurrentNode;
113
114  for (i=0; i<FxUnit->NumberUserControlNodes; i++){
115    CurrentNode=fluid_LADSPA_CreateNode(FxUnit,FxUnit->UserControlNodeNames[i],fluid_LADSPA_node_is_control);
116    assert(CurrentNode);
117    CurrentNode->buf[0]=FxUnit->UserControlNodeValues[i];
118    CurrentNode->InCount++; /* The constant counts as input */
119    CurrentNode->flags=fluid_LADSPA_node_is_source | fluid_LADSPA_node_is_user_ctrl; /* It is a user control node */
120  };
121};
122
123/* Purpose:
124 * Returns the pointer to the shared library loaded using 'LibraryFilename' (if it has been loaded).
125 * Return NULL otherwise.
126 * If not: Clear Fx and abort.
127 */
128void * fluid_LADSPA_RetrieveSharedLibrary(fluid_LADSPA_FxUnit_t* FxUnit, char * LibraryFilename){
129  void * CurrentLib=NULL;
130  int LibCount;
131  for (LibCount=0; LibCount<FxUnit->NumberLibs; LibCount++){
132    assert(FxUnit->ppvPluginLibNames[LibCount]);
133    if (FLUID_STRCMP(FxUnit->ppvPluginLibNames[LibCount],LibraryFilename)==0){
134      CurrentLib=FxUnit->ppvPluginLibs[LibCount];
135    };
136  };
137  return CurrentLib;
138};
139
140/* Purpose:
141 * Loads a shared LADSPA library.
142 * Return NULL, if failed.
143 * TODO: use LADSPA_PATH
144 */
145void * fluid_LADSPA_LoadSharedLibrary(fluid_LADSPA_FxUnit_t* FxUnit, char * LibraryFilename){
146  void * LoadedLib;
147  assert(LibraryFilename);
148  LoadedLib=dlopen(LibraryFilename,RTLD_NOW);
149  if (!LoadedLib){
150    return NULL;
151  };
152  FxUnit->ppvPluginLibs[FxUnit->NumberLibs]=LoadedLib;
153  FxUnit->ppvPluginLibNames[FxUnit->NumberLibs]=FLUID_STRDUP(LibraryFilename);
154  FxUnit->NumberLibs++;
155  return LoadedLib;
156};
157
158/* Purpose:
159 * Retrieves a descriptor to the plugin labeled 'PluginLabel' from the shared library.
160 */
161const LADSPA_Descriptor * fluid_LADSPA_Retrieve_Plugin_Descriptor(void * CurrentLib, char * PluginLabel){
162  LADSPA_Descriptor_Function pfDescriptorFunction;
163  unsigned long lPluginIndex=0;
164  const LADSPA_Descriptor * psDescriptor;
165  pfDescriptorFunction = (LADSPA_Descriptor_Function)dlsym(CurrentLib,"ladspa_descriptor");
166  while (pfDescriptorFunction(lPluginIndex)){
167    psDescriptor = pfDescriptorFunction(lPluginIndex);
168    if (FLUID_STRCMP(psDescriptor->Label, PluginLabel) == 0){
169      return psDescriptor;
170    };
171    lPluginIndex++;
172  };
173  return NULL;
174};
175
176/* Purpose:
177 * Finds out, if 'PortName' starts with 'PluginPort'.
178 * Spaces and underscore mean the same.
179 * The comparison is not case sensitive.
180 * The result distinguishes between a full match (strings are equal), and a partial match (PortName starts with Plugin_Port, but is longer).
181 */
182
183fluid_LADSPA_Stringmatch_t fluid_LADSPA_Check_SubString_Match(const char * Plugin_Port, const char * PortName){
184  unsigned int CharCount;
185  char a;
186  char b;
187  for(CharCount=0; CharCount<FLUID_STRLEN(Plugin_Port); CharCount++){
188    a=PortName[CharCount];
189    b=Plugin_Port[CharCount];
190    if (a>='a' && a <='z'){a-=32;}
191    if (b>='a' && b <='z'){b-=32;}
192    if (a == ' '){a='_';};
193    if (b == ' '){b='_';};
194    if ( a != b){
195      return fluid_LADSPA_NoMatch;
196    };
197  };
198  if (FLUID_STRLEN(Plugin_Port) == FLUID_STRLEN(PortName)){
199    return fluid_LADSPA_FullMatch;
200  };
201  return fluid_LADSPA_PartialMatch;
202
203};
204
205/* Purpose:
206 * Load the plugins added with 'ladspa_add' and then start the Fx unit.
207 */
208
209int
210fluid_LADSPA_handle_start(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){
211  fluid_LADSPA_FxUnit_t* FxUnit;
212  int CommandLineCount;
213  char * LibraryFilename;
214  char * PluginLabel;
215  char ** TokenSequence;
216  void * CurrentLib;
217  int NodeCount; //x
218  int IngoingSignalCount; // Count signals going into LADSPA Fx section
219  int OutgoingSignalCount; // Count signals going out of LADSPA Fx section
220  int ReturnVal=FLUID_OK; /* If warnings occur, this is set to -1. */
221  char * LADSPA_Path = getenv("LADSPA_PATH");
222
223  L(fluid_ostream_printf(out,"ladspa_start: starting..."));
224  assert(synth);
225  FxUnit=synth->LADSPA_FxUnit; assert(FxUnit);
226
227  /* When calling fluid_ladspastart, the Fx unit must be 'cleared' (no plugins, no libs, no nodes). Verify this here. */
228  if (FxUnit->NumberPlugins || FxUnit->NumberLibs){
229    fluid_ostream_printf(out, "***Error006***\n"
230	     "Fx unit is currently in use!\n"
231	     "Please run the ladspa_clear command before attempting to use ladspa_add!\n");
232    /* In this case do _not_ clear the Fx unit. */
233    return(PrintErrorMessage);
234  };
235  if (!FxUnit->NumberCommands){
236    fluid_ostream_printf(out, "***Error007***\n"
237	     "Refusing to start the Fx unit without any plugin.\n"
238	     "Use ladspa_add first!\n");
239    fluid_LADSPA_clear(FxUnit);
240    return(PrintErrorMessage);
241  };
242
243  /* Create predefined nodes */
244  L(fluid_ostream_printf(out,"ladspa_start: creating predefined nodes..."));
245  fluid_LADSPA_CreateSystemNodes(FxUnit);
246
247  /* Create predeclared nodes, that will allow to control the Fx unit during operation */
248  L(fluid_ostream_printf(out,"ladspa_start: creating user control nodes..."));
249  fluid_LADSPA_CreateUserControlNodes(FxUnit);
250
251  L(fluid_ostream_printf(out,"ladspa_start: Processing command lines..."));
252  for (CommandLineCount=0; CommandLineCount<FxUnit->NumberCommands; CommandLineCount++){
253    int CurrentPlugin_PortConnected[FLUID_LADSPA_MaxTokens/3]; /* For example: 100 tokens corresponds to roughly 30 ports. */
254    char LibFullPath[FLUID_LADSPA_MaxPathLength];
255    const LADSPA_Descriptor * CurrentPluginDescriptor;
256    LADSPA_Handle CurrentPlugin;
257    unsigned long PortCount;
258    int TokenCount=0;
259    char * Search;
260    int HasASlash=0;
261
262    if (FxUnit->NumberPlugins>=FLUID_LADSPA_MaxPlugins){
263    fluid_ostream_printf(out, "***Error003***\n"
264	       "Too many plugins at the same time (%i).\n"
265	       "Change FLUID_LADSPA_MaxPlugins!\n",
266	       FxUnit->NumberPlugins);
267      fluid_LADSPA_clear(FxUnit);
268      return(PrintErrorMessage);
269    };
270
271    L(fluid_ostream_printf(out,"Processing plugin nr. %i",FxUnit->NumberPlugins));
272
273    TokenSequence=FxUnit->LADSPA_Command_Sequence[CommandLineCount];
274    assert(TokenSequence);
275
276    /* Check, if the library is already loaded. If not, load. */
277    LibraryFilename=TokenSequence[TokenCount++]; assert(LibraryFilename);
278
279    L(fluid_ostream_printf(out,"Library name from ladspa_add: %s",LibraryFilename));
280    /* A slash-free filename refers to the LADSPA_PATH directory. Add that path, if needed. */
281
282
283
284    /* Determine, if the library filename contains a slash.
285     * If no, try to retrieve the environment variable LADSPA_PATH.
286     * If that fails, signal error.
287     * Otherwise leave the filename as it is.
288     */;
289
290    /* Determine, if the library name is just the filename, or a path (including a slash) */
291    Search=LibraryFilename;
292    while (*Search != '\0') {
293      if ((*Search)== '/'){
294	HasASlash=1;
295      };
296      Search++;
297    };
298
299    if (!HasASlash){
300      if (!LADSPA_Path){
301    fluid_ostream_printf(out, "***Error018***\n"
302		 "The library file name %s does not include a path.\n"
303		 "The environment variable LADSPA_PATH is not set.\n"
304		 "- Use an absolute path (i.e. /home/myself/mylib.so)\n"
305		 "- For the current directory use ./mylib.so\n"
306		 "- set the environment variable LADSPA_PATH (export LADSPA_PATH=/usr/lib/ladspa)\n"
307		 "- depending on your shell, try 'setenv' instead of 'export'\n",
308		 LibraryFilename);
309	fluid_LADSPA_clear(FxUnit);
310	return(PrintErrorMessage);
311      }; /* if no LADSPA_PATH */
312      snprintf(LibFullPath,FLUID_LADSPA_MaxPathLength,"%s/%s",LADSPA_Path,LibraryFilename);
313      /* If no slash in filename */
314    } else {
315	snprintf(LibFullPath,FLUID_LADSPA_MaxPathLength,"%s",LibraryFilename);
316    };
317
318    L(fluid_ostream_printf(out,"Full Library path name: %s",LibFullPath));
319
320    CurrentLib=fluid_LADSPA_RetrieveSharedLibrary(FxUnit, LibFullPath);
321    if (!CurrentLib){
322      LADSPA_Descriptor_Function pfDescriptorFunction;
323
324      L(fluid_ostream_printf(out,"Library %s not yet loaded. Loading.",LibFullPath));
325
326      if (FxUnit->NumberLibs>=FLUID_LADSPA_MaxLibs){
327    fluid_ostream_printf(out, "***Error004***\n"
328		 "Too many libraries open (%i)\n"
329		 "Change FLUID_LADSPA_MaxLibs",FxUnit->NumberPlugins);
330	fluid_LADSPA_clear(FxUnit);
331	return(PrintErrorMessage);
332      };
333
334      /* Load a LADSPA plugin library and store it for future use.*/
335      CurrentLib=fluid_LADSPA_LoadSharedLibrary(FxUnit, LibFullPath);
336
337      if (!CurrentLib){
338    fluid_ostream_printf(out, "***Error008***\n"
339		 "Failed to load plugin library %s.",
340		 LibraryFilename);
341	fluid_LADSPA_clear(FxUnit);
342	return(PrintErrorMessage);
343      };
344
345
346      dlerror();
347      pfDescriptorFunction = (LADSPA_Descriptor_Function)dlsym(CurrentLib,"ladspa_descriptor");
348      if (!pfDescriptorFunction) {
349	const char * pcError = dlerror();
350	if (!pcError) {pcError="Huh?! No error from lib!";};
351    fluid_ostream_printf(out, "***Error015***\n"
352		 "Unable to find ladspa_descriptor() function in plugin library file \"%s\": %s.\n"
353		 "Are you sure this is a LADSPA plugin file?\n",
354		 LibraryFilename,
355		 pcError);
356	fluid_LADSPA_clear(FxUnit);
357	return(PrintErrorMessage);
358      };
359
360      L(fluid_ostream_printf(out,"Library loaded."));
361    };
362
363    PluginLabel=TokenSequence[TokenCount++]; assert(PluginLabel);
364    L(fluid_ostream_printf(out,"Plugin Label from ladspa_add: %s",PluginLabel));
365    /* Retrieve a 'plugin descriptor' from the library. */
366    L(fluid_ostream_printf(out,"Looking for the plugin labeled %s",PluginLabel));
367
368    CurrentPluginDescriptor=fluid_LADSPA_Retrieve_Plugin_Descriptor(CurrentLib, PluginLabel);
369
370
371    /* Check, that the plugin was actually found.*/
372    if (CurrentPluginDescriptor==NULL){
373    fluid_ostream_printf(out, "***Error016***\n"
374	       "Unable to find the plugin labeled \"%s\" in plugin library file \"%s\".\n"
375	       "Hint: run analyzeplugin %s from the command line to get a list of valid plugin labels.\n",
376	       PluginLabel,
377	       LibraryFilename,
378	       LibraryFilename);
379      fluid_LADSPA_clear(FxUnit);
380      return(PrintErrorMessage);
381    };
382
383    /* Create an instance of the plugin type from the descriptor */
384    L(fluid_ostream_printf(out,"instantiating plugin %s",PluginLabel));
385    CurrentPlugin=CurrentPluginDescriptor
386      ->instantiate(CurrentPluginDescriptor,44100); /* Sample rate hardcoded */
387    assert(CurrentPlugin);
388
389    /* The descriptor ("type of plugin") and the instance are stored for each plugin instantiation.
390       If one plugin type is instantiated several times, they will have the same descriptor, only
391       different instances.*/
392    FxUnit->PluginDescriptorTable[FxUnit->NumberPlugins]=CurrentPluginDescriptor;
393    FxUnit->PluginInstanceTable[FxUnit->NumberPlugins]=CurrentPlugin;
394
395    /*
396     *
397     * Wire up the inputs and outputs
398     *
399     */
400
401    /* List for checking, that each plugin port is exactly connected once */
402    for (PortCount=0; PortCount<CurrentPluginDescriptor->PortCount; PortCount++){
403      CurrentPlugin_PortConnected[PortCount]=0;
404    };
405
406    /* Note: There are three NULL tokens at the end. The last condition may be evaluated even if the first one already detects the end. */
407    while (TokenSequence[TokenCount] && TokenSequence[TokenCount+1] && TokenSequence[TokenCount+2]){
408      int CurrentPort_StringMatchCount;
409      LADSPA_PortDescriptor CurrentPort_Descriptor;
410      char * Plugin_Port=TokenSequence[TokenCount++];
411      char * Direction=TokenSequence[TokenCount++];
412      char * FLUID_Node=TokenSequence[TokenCount++];
413      fluid_LADSPA_Node_t* Current_Node;
414      const char * PortName=NULL;
415      int CurrentPort_Index=-1;
416      fluid_LADSPA_Stringmatch_t StringMatchType=fluid_LADSPA_NoMatch;
417      fluid_LADSPA_Stringmatch_t CurrentPort_StringMatchType=fluid_LADSPA_NoMatch;
418      CurrentPort_StringMatchCount=0;
419
420      L(fluid_ostream_printf(out,"Wiring %s %s %s",Plugin_Port, Direction, FLUID_Node));
421
422      /* Find the port number on the plugin, that belongs to "Plugin_Port".
423       * Match the identifier specified by the user against the first characters
424       * of the port name.
425       *
426       * If the given identifier matches several port names only partly, then the input is ambiguous, an error
427       * message results.
428       *
429       * Example: cmt.so, limit_peak: This plugin uses the labels
430       * -  Output Envelope Attack (s)
431       * -  Output Envelope Decay (s)
432       * -  Output
433       *
434       * The user input 'Output' matches the first two labels partly, the third fully. This will be accepted.
435       * The user input 'Out' matches all three only partly, this results in an error message.
436       */
437
438      for (PortCount=0; PortCount<CurrentPluginDescriptor->PortCount; PortCount++){
439	PortName=CurrentPluginDescriptor->PortNames[PortCount];
440
441	StringMatchType=fluid_LADSPA_Check_SubString_Match(Plugin_Port, PortName);
442	/* If a full-string match has been found earlier, reject all partial matches. */
443	if (StringMatchType==fluid_LADSPA_FullMatch ||
444	    (StringMatchType==fluid_LADSPA_PartialMatch && CurrentPort_StringMatchType != fluid_LADSPA_FullMatch)){
445
446	  if(StringMatchType==fluid_LADSPA_FullMatch && CurrentPort_StringMatchType==fluid_LADSPA_FullMatch){
447    fluid_ostream_printf(out, "***Error027***\n"
448		     "While processing plugin %s: The port label %s appears more than once!\n"
449		     "This is an error in the plugin itself. Please correct it or use another plugin.",PluginLabel, Plugin_Port);
450	    fluid_LADSPA_clear(FxUnit);
451	    return(PrintErrorMessage);
452	  };
453
454	  CurrentPort_Index=PortCount;
455	  CurrentPort_StringMatchType=StringMatchType;
456	  CurrentPort_StringMatchCount++;
457
458	}; /* if suitable match */
459      }; /* For port count */
460
461      /* Several partial matches? Then the identifier is not unique. */
462      if (CurrentPort_StringMatchCount > 1 && CurrentPort_StringMatchType == fluid_LADSPA_PartialMatch){
463    fluid_ostream_printf(out, "***Error019***\n"
464		 "While processing plugin %s: The identifier %s matches more than one plugin port.\n"
465		 "Please use more letters for the port name. If needed, replace spaces with underscores (_).\n"
466		 "This error will not occur, if you use the full name of a port.\n",PluginLabel, Plugin_Port);
467	fluid_LADSPA_clear(FxUnit);
468	return(PrintErrorMessage);
469      };
470
471      if (CurrentPort_Index<0){
472    fluid_ostream_printf(out, "***Error017***\n"
473		 "Unable to find port '%s' on plugin %s\n"
474		 "Port names are:\n",Plugin_Port,PluginLabel);
475	for (PortCount=0; PortCount<CurrentPluginDescriptor->PortCount; PortCount++){
476	  printf("- `%s'\n",CurrentPluginDescriptor->PortNames[PortCount]);
477	};
478
479	fluid_LADSPA_clear(FxUnit);
480	return(PrintErrorMessage);
481      };
482      CurrentPort_Descriptor=CurrentPluginDescriptor->PortDescriptors[CurrentPort_Index];
483      assert(CurrentPort_Descriptor);
484
485      /* Retrieve the node with the right name. */
486      Current_Node=fluid_LADSPA_RetrieveNode(FxUnit,FLUID_Node);
487#define PortIsAudio LADSPA_IS_PORT_AUDIO(CurrentPort_Descriptor) && !(LADSPA_IS_PORT_CONTROL(CurrentPort_Descriptor))
488#define PortIsControl LADSPA_IS_PORT_CONTROL(CurrentPort_Descriptor) && !(LADSPA_IS_PORT_AUDIO(CurrentPort_Descriptor))
489      if (!Current_Node){
490	/* Doesn't exist? Then create it. */
491	if (FxUnit->NumberNodes>=FLUID_LADSPA_MaxNodes){
492    fluid_ostream_printf(out, "***Error005***\n"
493		   "Too many nodes (%i)\n"
494		   "Change FLUID_LADSPA_MaxNodes",FxUnit->NumberNodes);
495	  fluid_LADSPA_clear(FxUnit);
496	  return(PrintErrorMessage);
497	};
498	if (PortIsAudio){
499	  Current_Node=fluid_LADSPA_CreateNode(FxUnit,FLUID_Node,fluid_LADSPA_node_is_audio);
500	} else if (PortIsControl){
501	  Current_Node=fluid_LADSPA_CreateNode(FxUnit,FLUID_Node,fluid_LADSPA_node_is_control);
502	} else {
503    fluid_ostream_printf(out, "***Error025***\n"
504		   "Plugin port number %i is neither input nor output!\n"
505		   "This is an error in the plugin.\n"
506		   "Please check plugin sourcecode.\n",
507		   CurrentPort_Index);
508	  fluid_LADSPA_clear(FxUnit);
509	  return(PrintErrorMessage);
510	};
511      };
512      assert(Current_Node);
513
514      /*
515       *
516       * Check flowgraph for some possible errors.
517       *
518       */
519
520      if (FLUID_STRCMP(Direction,"->")==0){
521	/* Data from plugin to FLUID, into node
522	 *
523	 * *** Rule: ****
524	 * A node may not have more than one data source.*/
525	if (Current_Node->InCount !=0){
526    fluid_ostream_printf(out, "***Error009***\n"
527		   "Plugin %s tries to feed data from output %s into node %s, which is already connected to a data source.\n",PluginLabel,Plugin_Port,FLUID_Node);
528	  fluid_LADSPA_clear(FxUnit);
529	  return(PrintErrorMessage);
530	};
531	Current_Node->InCount++;
532      } else if (FLUID_STRCMP(Direction,"<-")==0){
533	/* Data from FLUID to plugin, out of node
534	 *
535	 * This check verifies the integrity of the flow graph:
536	 * *** Rule ***
537	 * The execution order of the plugins is the order, in which they are programmed.
538	 * The plugins must be ordered so, that the input of a plugin is already computed at the time of its execution.
539	 * If the user tries to read data out of a node that has not yet an input, then something is wrong.*/
540	assert(Current_Node->InCount<=1);
541	if (Current_Node->InCount !=1){
542    fluid_ostream_printf(out, "***Error010***\n"
543		   "Plugin %s tries to read data through input %s from node %s.\n"
544		   "But at this point there is no valid data at that node.\n"
545		   "Please check the flowgraph and especially the execution order!\n",PluginLabel,Plugin_Port,FLUID_Node);
546	  fluid_LADSPA_clear(FxUnit);
547	  return(PrintErrorMessage);
548	};
549	Current_Node->OutCount++;
550      } else {
551	fluid_ostream_printf(out, "***Error024***\n"
552	       "Syntax error: Illegal `arrow' `%s', expecting -> or <-\n",
553	       Direction);
554	fluid_LADSPA_clear(FxUnit);
555	return(PrintErrorMessage);
556      };
557
558      /* In any case, there must be a valid data source for the port at this time. */
559      assert(Current_Node->InCount==1);
560
561      /* Keep track on the number of connections to each port.
562       * This error occurs only, if an attempt is made to connect one port twice (i.e. ladspa_add libname pluginname port <- nodex port <- nodey) */
563      if (CurrentPlugin_PortConnected[CurrentPort_Index]){
564    fluid_ostream_printf(out, "***Error011***\n"
565		 "Refusing to connect twice to port %s on plugin %s.\n",CurrentPluginDescriptor->PortNames[CurrentPort_Index], PluginLabel);
566	fluid_LADSPA_clear(FxUnit);
567	return(PrintErrorMessage);
568      };
569
570      /*
571       *
572       * Connect the port
573       *
574       */
575
576      L(fluid_ostream_printf(out,"Connecting %i",CurrentPort_Index));
577      CurrentPluginDescriptor->connect_port
578	(CurrentPlugin,
579	 CurrentPort_Index,
580	 Current_Node->buf
581	 );
582      CurrentPlugin_PortConnected[CurrentPort_Index]++;
583
584    }; /* While Tokensequence (more connections) */
585
586    /*
587     *
588     * Check for left-over tokens
589     *
590     */
591
592    if (TokenSequence[TokenCount]){
593      char * T1="";char * T2="";char * T3="";
594      if (TokenSequence[TokenCount]){T1=TokenSequence[TokenCount];};
595      if (TokenSequence[TokenCount+1]){T2=TokenSequence[TokenCount+1];};
596      if (TokenSequence[TokenCount+2]){T3=TokenSequence[TokenCount+2];};
597    fluid_ostream_printf(out, "***Error012***\n"
598	       "Leftover tokens: %s %s %s...\n",T1,T2,T3);
599      fluid_LADSPA_clear(FxUnit);
600      return(PrintErrorMessage);
601    };
602
603    /*
604     *
605     * Check, that all plugin ports are connected
606     *
607     */
608    L(fluid_ostream_printf(out,"Checking left-over ports"));
609    assert(CurrentPluginDescriptor);
610    for (PortCount=0; PortCount<CurrentPluginDescriptor->PortCount; PortCount++){
611      assert(CurrentPlugin_PortConnected[PortCount] <=1);
612      if (CurrentPlugin_PortConnected[PortCount] !=1){
613    fluid_ostream_printf(out, "***Error013***\nPlugin: %s. Port %s is unconnected!\n",PluginLabel, CurrentPluginDescriptor->PortNames[PortCount]);
614	fluid_LADSPA_clear(FxUnit);
615	return(PrintErrorMessage);
616      };
617    };
618
619    /*
620     *
621     *Run activate function on plugin, where possible
622     *
623     */
624
625    if (CurrentPluginDescriptor->activate !=NULL){
626      CurrentPluginDescriptor->activate(CurrentPlugin);
627    };
628
629    FxUnit->NumberPlugins++;
630  }; /* For CommandLineCount: once for each new command (i.e. plugin instantiation request from user */
631
632  /*
633   *
634   * Further flow graph checks
635   *
636   */
637
638  L(fluid_ostream_printf(out,"Checking flow graph"));
639
640  IngoingSignalCount=0;
641  OutgoingSignalCount=0;
642
643  for (NodeCount=0; NodeCount<FxUnit->NumberNodes; NodeCount++){
644    fluid_LADSPA_Node_t* Current_Node;
645    Current_Node=FxUnit->Nodelist[NodeCount];
646    assert(Current_Node);
647    if (Current_Node->flags & fluid_LADSPA_node_is_source){
648      IngoingSignalCount+=Current_Node->OutCount;
649    } else if (Current_Node->flags & fluid_LADSPA_node_is_sink){
650      OutgoingSignalCount+=Current_Node->InCount;
651    } else {
652
653      /* A node without any input doesn't make sense.
654       * The flow graph check aborts with an error. This case cannot happen.
655       */
656      if (Current_Node->InCount==0 && !Current_Node->flags & fluid_LADSPA_node_is_dummy){ /* There can only be one warning at a time. */
657    fluid_ostream_printf(out, "***Warning020***"
658		   "No input into node %s.\n"
659		   "Use '_' as first char in nodename to suppress this warning.\n"
660		   "Hint: Check for typos in the node name.\n",Current_Node->Name);
661	  /* A warning can also be printed as an error message (check fluid_cmd.c). The only difference between
662	     the return values -1 and 0 is, that -1 prints the result. */
663      };
664      ReturnVal=PrintErrorMessage;
665    };
666
667    /* A node without any output doesn't make sense. */
668    if (Current_Node->OutCount==0 && !Current_Node->flags & fluid_LADSPA_node_is_dummy){
669    fluid_ostream_printf(out, "***Warning021***\n"
670		 "No output from node %s.\n"
671		 "Use '_' as first char in nodename to suppress this warning.\n"
672		 "Hint: Check for typos in the node name.\n",Current_Node->Name);
673      ReturnVal=PrintErrorMessage;
674    };
675    /* A free-flying node simply cannot happen. */
676    assert(Current_Node->OutCount+Current_Node->InCount);
677  }; /* Foreach node */
678
679  /* Issue a warning, if no signal goes into the Fx section. */
680  if (IngoingSignalCount==0){
681    fluid_ostream_printf(out, "***Warning022***\n"
682	       "You have not connected anything to the synthesizer section (in1_L, in1_R).\n");
683    ReturnVal=PrintErrorMessage;
684  };
685
686  /* Issue a warning, if no signal leaves the Fx section. */
687  if (OutgoingSignalCount==0){
688    fluid_ostream_printf(out, "***Warning023***\n"
689	       "You have not connected anything to the output (out1_L, out1_R).\n");
690  };
691
692  /* Finally turn on the Fx unit. */
693  FxUnit->Bypass=fluid_LADSPA_Active;
694  L(fluid_ostream_printf(out,"LADSPA Init OK"));
695  return(ReturnVal);
696};
697
698void
699fluid_LADSPA_run(fluid_LADSPA_FxUnit_t* FxUnit, fluid_real_t* left_buf[], fluid_real_t* right_buf[], fluid_real_t* fx_left_buf[], fluid_real_t* fx_right_buf[]){
700  int i;
701  int ii;
702
703
704  int nr_audio_channels;
705  int nr_fx_sends;
706  int nr_groups;
707  int byte_size = FLUID_BUFSIZE * sizeof(fluid_real_t);
708  char str[99];
709  fluid_LADSPA_Node_t* n;
710  int temp;
711
712  /* Retrieve the number of synth / audio out / Fx send nodes */
713  assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-groups", &temp));
714  nr_groups=(int) temp;
715
716  assert(fluid_settings_getint(FxUnit->synth->settings, "synth.audio-channels", &temp));
717  nr_audio_channels=temp;
718
719  assert(fluid_settings_getint(FxUnit->synth->settings, "synth.effects-channels", &temp));
720  nr_fx_sends=temp;
721
722  /* Fixme: Retrieving nodes via names is inefficient
723   * (but not that bad, because the interesting nodes are always at the start of the list).
724   */
725
726  /* Input and output are processed via the same buffers. Therefore the effect is bypassed by just skipping everything else. */
727  if (FxUnit->Bypass==fluid_LADSPA_Bypassed){
728    return;
729  };
730
731  if (FxUnit->Bypass==fluid_LADSPA_BypassRequest){
732    FxUnit->Bypass=fluid_LADSPA_Bypassed;
733    pthread_mutex_lock(&FxUnit->mutex);
734    pthread_cond_broadcast(&FxUnit->cond);
735    pthread_mutex_unlock(&FxUnit->mutex);
736    L(printf("LADSPA_Run: Command line asked for bypass of Fx unit. Acknowledged."));
737    return;
738  };
739
740  assert(FxUnit);
741
742  /* Clear the output buffers, if they are not connected anywhere */
743  for (ii=0; ii < nr_audio_channels; ii++){
744
745      sprintf(str, "out%i_L",(ii+1));
746      n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n);
747      if (n->InCount == 0){
748/*	  printf("Output node %s is not connected -> clear buffer\n", str); */
749	  FLUID_MEMSET(n->buf, 0, byte_size);
750      };
751
752      sprintf(str, "out%i_R",(ii+1));
753      n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n);
754      if (n->InCount == 0){
755/*	  printf("Output node %s is not connected -> clear buffer\n", str); */
756	  FLUID_MEMSET(n->buf, 0, byte_size);
757      };
758  };
759
760  /* Prepare the incoming data:
761   * Convert fluid_real_t data type to LADSPA_Data type */
762  for (ii=0; ii < nr_groups; ii++){
763      fluid_real_t* src_buf=left_buf[ii];
764      sprintf(str, "in%i_L",(ii+1));
765      n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n);
766
767      assert(FLUID_BUFSIZE % 2 == 0);
768
769      /* Add a very small high frequency signal. This avoids denormal number problems. */
770      for (i=0; i<FLUID_BUFSIZE;){
771	  n->buf[i]=(LADSPA_Data)(src_buf[i]+1.e-15);
772	  i++;
773	  n->buf[i]=(LADSPA_Data)(src_buf[i]);
774	  i++;
775      };
776
777      src_buf=right_buf[ii];
778      sprintf(str, "in%i_R",(ii+1));
779      n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n);
780
781      /* Add a very small high frequency signal. This avoids denormal number problems. */
782      for (i=0; i<FLUID_BUFSIZE;){
783	  n->buf[i]=(LADSPA_Data)(src_buf[i]+1.e-15);
784	  i++;
785	  n->buf[i]=(LADSPA_Data)(src_buf[i]);
786	  i++;
787      };
788  };
789
790  /* Effect send paths */
791  for (ii=0; ii < nr_fx_sends; ii++){
792      sprintf(str, "send%i_L",(ii+1));
793      n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n);
794      for (i=0; i<FLUID_BUFSIZE; i++){
795	  n->buf[i]=(LADSPA_Data)(fx_left_buf[ii][i]);
796      };
797
798      sprintf(str, "send%i_R",(ii+1));
799      n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n);
800      for (i=0; i<FLUID_BUFSIZE; i++){
801	  n->buf[i]=(LADSPA_Data)(fx_right_buf[ii][i]);
802      };
803  };
804
805  /* Run each plugin on a block of data.
806   * The execution order has been checked during setup.*/
807  for (i=0; i<FxUnit->NumberPlugins; i++){
808    FxUnit->PluginDescriptorTable[i]->run(FxUnit->PluginInstanceTable[i],FLUID_BUFSIZE);
809  };
810
811  /* Copy the data from the output nodes back to the synth. */
812  for (ii=0; ii < nr_audio_channels; ii++){
813      fluid_real_t* dest_buf=left_buf[ii];
814      sprintf(str, "out%i_L",(ii+1));
815      n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n);
816      for (i=0; i<FLUID_BUFSIZE; i++){
817	  dest_buf[i]=(fluid_real_t)n->buf[i];
818      };
819
820      dest_buf=right_buf[ii];
821      sprintf(str, "out%i_R",(ii+1));
822      n=fluid_LADSPA_RetrieveNode(FxUnit, str); assert(n);
823      for (i=0; i<FLUID_BUFSIZE; i++){
824	  dest_buf[i]=(fluid_real_t)n->buf[i];
825      };
826  };
827};
828
829fluid_LADSPA_Node_t*
830fluid_LADSPA_RetrieveNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name){
831  int i=0;
832  assert(FxUnit);assert(Name);
833  for (i=0; i<FxUnit->NumberNodes; i++){
834    assert(FxUnit->Nodelist[i]);
835    if (FLUID_STRCMP(FxUnit->Nodelist[i]->Name,Name)==0){
836      return FxUnit->Nodelist[i];
837    };
838  };
839  return NULL;
840};
841
842
843/* Purpose:
844 * Creates a new node from the node name given by the user.
845 */
846fluid_LADSPA_Node_t*
847fluid_LADSPA_CreateNode(fluid_LADSPA_FxUnit_t* FxUnit, char * Name, int flags){
848  int Dummy=0;
849  fluid_LADSPA_Node_t* NewNode;
850  assert(FxUnit);
851  assert(Name);
852//  printf("Flags is %i\n",flags);
853  L(printf("Create node: %s",Name));
854  if (FxUnit->NumberNodes>=FLUID_LADSPA_MaxNodes){
855    printf( "***Error014***\n"
856	    "Too many nodes (%i)\n"
857	    "Change FLUID_LADSPA_MaxNodes.\n",FxUnit->NumberNodes);
858    fluid_LADSPA_clear(FxUnit);
859    return NULL;
860  };
861
862  /* Don't allow node names, which start with -, 0..9 */
863  if (Name[0] == '-' || (Name[0]>='0' && Name[0]<='9')){
864    printf( "***Error026***\n"
865	    "The node name %s starts with a digit / minus sign!\n"
866	    "Please use a letter to start a node name.\n"
867	    "A constant node is created by using `#' as first character,\n"
868	    "for example #-2.5.\n",
869	    Name);
870    fluid_LADSPA_clear(FxUnit);
871    return NULL;
872  };
873
874  /* A nodename starting with "_" is a possible dummy node, which may (but need not) act as a data sink or source (dummy node). */
875  if (Name[0] == ' '){ /* ??? Should be '_' ??? */
876    Dummy=1;
877  };
878  NewNode=FLUID_NEW(fluid_LADSPA_Node_t);assert(NewNode);
879  if (flags && fluid_LADSPA_node_is_audio){
880    /* Audio node contains buffer. */
881    NewNode->buf=FLUID_ARRAY(LADSPA_Data, (FLUID_BUFSIZE));assert(NewNode->buf);
882    /* It is permitted to use a dummy node without input. Therefore clear all node buffers at startup. */
883    FLUID_MEMSET(NewNode->buf, 0, (FLUID_BUFSIZE*sizeof(LADSPA_Data)));
884  } else if (flags & fluid_LADSPA_node_is_control){
885    /* Control node contains single value. */
886    NewNode->buf=FLUID_ARRAY(LADSPA_Data, 1);assert(NewNode->buf);
887  } else {
888    assert(0);
889  };
890  NewNode->Name=FLUID_STRDUP(Name);assert(NewNode->Name);
891  if (Dummy){
892      flags |= fluid_LADSPA_node_is_dummy;
893  };
894  NewNode->InCount=0;
895  NewNode->OutCount=0;
896  NewNode->flags=flags;
897
898  /* A nodename starting with "#" means that the node holds a constant value. */
899  if (NewNode->Name[0] == '#'){
900    assert(flags & fluid_LADSPA_node_is_control);
901    /* Skip the first character => +1 */
902    NewNode->buf[0]=(LADSPA_Data)atof(NewNode->Name+1);
903    NewNode->InCount++;
904  };
905  if (flags & fluid_LADSPA_node_is_source){
906    NewNode->InCount++;
907//    printf("****************************** Source!\n");
908  } else if (flags & fluid_LADSPA_node_is_sink){
909    NewNode->OutCount++;
910  };
911  FxUnit->Nodelist[FxUnit->NumberNodes++]=NewNode;
912
913  L(printf("Node %s created.",Name));
914  return NewNode;
915};
916
917void fluid_LADSPA_clear(fluid_LADSPA_FxUnit_t* FxUnit){
918  int i;
919  int ii;
920  L(printf("ladspa_clear"));
921  assert(FxUnit);
922
923  if (FxUnit->Bypass==fluid_LADSPA_Active){
924    L(printf("clear: Requesting bypass from synthesis thread"));
925    /* Bypass the Fx unit before anything else.
926     * Reason: Not a good idea to release plugins, while another thread runs them.
927     */
928    FxUnit->Bypass=fluid_LADSPA_BypassRequest;
929    pthread_mutex_lock(&FxUnit->mutex);
930    pthread_cond_wait(&FxUnit->cond,&FxUnit->mutex);
931    pthread_mutex_unlock(&FxUnit->mutex);
932    L(printf("clear: Synthesis thread has switched to bypass."));
933  } else {
934    L(printf("clear: Fx unit was already bypassed. No action needed."));
935  };
936
937  L(printf("Clear all user control node declarations"));
938  for (i=0; i<FxUnit->NumberUserControlNodes; i++){
939    FLUID_FREE(FxUnit->UserControlNodeNames[i]);
940  };
941  FxUnit->NumberUserControlNodes=0;
942
943  L(printf("Clear all plugin instances"));
944  for (i=0; i<FxUnit->NumberPlugins; i++){
945    assert(FxUnit->PluginDescriptorTable[i]);
946    assert(FxUnit->PluginInstanceTable[i]);
947
948    /* Run deactivate function on plugin, if possible */
949    if (FxUnit->PluginDescriptorTable[i]->deactivate){
950      FxUnit->PluginDescriptorTable[i]->deactivate(FxUnit->PluginInstanceTable[i]);
951    };
952    FxUnit->PluginDescriptorTable[i]->cleanup(FxUnit->PluginInstanceTable[i]);
953  };
954  FxUnit->NumberPlugins=0;
955
956  L(printf("Clear all nodes")); /* Only after removing plugins! */
957  for (i=0; i<FxUnit->NumberNodes; i++){
958    FLUID_FREE(FxUnit->Nodelist[i]->buf);
959    FLUID_FREE(FxUnit->Nodelist[i]);
960  };
961  FxUnit->NumberNodes=0;
962
963
964  L(printf("Clear all plugin libraries"));
965  for (i=0; i<FxUnit->NumberLibs; i++){
966
967    assert(FxUnit->ppvPluginLibs[i]);
968    dlclose(FxUnit->ppvPluginLibs[i]);
969
970    assert(FxUnit->ppvPluginLibNames[i]);
971    FLUID_FREE(FxUnit->ppvPluginLibNames[i]);
972  };
973  FxUnit->NumberLibs=0;
974
975  L(printf("Clear all command lines"));
976  for (i=0; i<FxUnit->NumberCommands;i++){
977    ii=0;
978    assert(FxUnit->LADSPA_Command_Sequence[i]);
979    while (FxUnit->LADSPA_Command_Sequence[i][ii]){
980      FLUID_FREE(FxUnit->LADSPA_Command_Sequence[i][ii]);
981      ii++;
982    };
983    FLUID_FREE(FxUnit->LADSPA_Command_Sequence[i]);
984  };
985  FxUnit->NumberCommands=0;
986};
987
988int fluid_LADSPA_handle_add(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){
989  int i;
990  char * Token;
991  char ** CommandLine;
992  fluid_LADSPA_FxUnit_t* FxUnit;
993  assert(synth);
994  FxUnit=synth->LADSPA_FxUnit; assert(FxUnit);
995  if (ac>=FLUID_LADSPA_MaxTokens){
996    /* Can't be tested. fluidsynth limits the number of tokens. */
997    printf("***Error001***\n"
998	     "Too many ports.\nChange FLUID_LADSPA_MaxTokens!");
999    fluid_LADSPA_clear(FxUnit);
1000    return(PrintErrorMessage);
1001  };
1002  if (ac<2){
1003    printf("***Error002***\n"
1004	     "ladspa_add needs at least two arguments - libname and plugin name!");
1005    fluid_LADSPA_clear(FxUnit);
1006    return(PrintErrorMessage);
1007  };
1008
1009  if (FxUnit->NumberCommands>=FLUID_LADSPA_MaxPlugins){
1010    printf("***Error032***\n"
1011	     "Too many plugins.\nChange FLUID_LADSPA_MaxPlugins!");
1012    fluid_LADSPA_clear(FxUnit);
1013    return(PrintErrorMessage);
1014  };
1015
1016  /* CommandLine (token sequence) is terminated with NULL.
1017   * Add two more NULLs, so that a chunk of three tokens can be checked later without risk.*/
1018
1019  CommandLine=FLUID_ARRAY(char*, (ac+3));assert(CommandLine);
1020  for (i=0; i<ac; i++){
1021    CommandLine[i]=FLUID_STRDUP(av[i]);assert(CommandLine[i]);
1022  };
1023  CommandLine[ac]=NULL;
1024  CommandLine[ac+1]=NULL;
1025  CommandLine[ac+2]=NULL;
1026
1027  FxUnit->LADSPA_Command_Sequence[FxUnit->NumberCommands]=CommandLine;
1028  FxUnit->NumberCommands++;
1029  return(FLUID_OK);
1030};
1031
1032int fluid_LADSPA_handle_declnode(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){
1033  int i;
1034  char * Token;
1035  char ** CommandLine;
1036  char * NodeName;
1037  fluid_real_t NodeValue;
1038  fluid_LADSPA_FxUnit_t* FxUnit;
1039  assert(synth);
1040  FxUnit=synth->LADSPA_FxUnit; assert(FxUnit);
1041
1042  if (ac<2){
1043    printf("***Error028***\n"
1044	   "ladspa_declnode needs two arguments - node name and value!\n");
1045    fluid_LADSPA_clear(FxUnit);
1046    return(PrintErrorMessage);
1047  };
1048
1049  if (FxUnit->NumberUserControlNodes>=FLUID_LADSPA_MaxNodes){
1050    printf("***Error033***\n"
1051	     "Too many user-control nodes.\nChange FLUID_LADSPA_MaxNodes!");
1052    fluid_LADSPA_clear(FxUnit);
1053    return(PrintErrorMessage);
1054  };
1055
1056  NodeName=FLUID_STRDUP(av[0]); assert(NodeName);
1057  NodeValue=atof(av[1]);
1058  FxUnit->UserControlNodeNames[FxUnit->NumberUserControlNodes]=NodeName;
1059  FxUnit->UserControlNodeValues[FxUnit->NumberUserControlNodes]=NodeValue;
1060  FxUnit->NumberUserControlNodes++;
1061  return(FLUID_OK);
1062};
1063int fluid_LADSPA_handle_setnode(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){
1064  int i;
1065  char * Token;
1066  char * NodeName;
1067  fluid_real_t NodeValue;
1068  fluid_LADSPA_FxUnit_t* FxUnit;
1069  fluid_LADSPA_Node_t* CurrentNode;
1070  assert(synth);
1071  FxUnit=synth->LADSPA_FxUnit; assert(FxUnit);
1072
1073  if (ac!=2){
1074    printf("***Error029***\n"
1075	   "ladspa_setnode needs two arguments - node name and value!\n");
1076    /* Do not clear the Fx unit (no fluid_LADSPA_clear). */
1077    return(PrintErrorMessage);
1078  };
1079
1080  NodeName=av[0]; assert(NodeName);
1081  NodeValue=atof(av[1]);
1082
1083  CurrentNode=fluid_LADSPA_RetrieveNode(FxUnit,NodeName);
1084  if (!CurrentNode){
1085    printf("***Error030***\n"
1086	   "The node %s was not found. Please use the full name of a node, that was\n"
1087	   "previously declared with ladspa_declnode.\n",NodeName);
1088    /* Do not clear the Fx unit (no fluid_LADSPA_clear). */
1089    return(PrintErrorMessage);
1090  };
1091  if (!(CurrentNode->flags & fluid_LADSPA_node_is_user_ctrl)){
1092    printf("***Error031***\n"
1093	   "The node %s is an ordinary control node.\n"
1094	   "Only user control nodes can be modified with ladspa_setnode.\n",NodeName);
1095    /* Do not clear the Fx unit (no fluid_LADSPA_clear). */
1096    return(PrintErrorMessage);
1097  };
1098  L(printf("ladspa_setnode: Assigning value %f",NodeValue));
1099  CurrentNode->buf[0]=NodeValue;
1100  return(FLUID_OK);
1101};
1102
1103int fluid_LADSPA_handle_clear(fluid_synth_t* synth, int ac, char** av, fluid_ostream_t out){
1104  fluid_LADSPA_FxUnit_t* FxUnit;
1105  assert(synth);
1106  FxUnit=synth->LADSPA_FxUnit; assert(FxUnit);
1107  fluid_LADSPA_clear(FxUnit);
1108  return(FLUID_OK);
1109};
1110
1111void fluid_LADSPA_shutdown(fluid_LADSPA_FxUnit_t* FxUnit){
1112  /* The synthesis thread is not running anymore.
1113   * Set the bypass switch, so that fluid_LADSPA_clear can proceed.*/
1114  FxUnit->Bypass=fluid_LADSPA_Bypassed;
1115  fluid_LADSPA_clear(FxUnit);
1116  pthread_cond_destroy(&FxUnit->cond); /* pro forma */
1117};
1118#endif /*LADSPA*/
1119