mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-02-21 03:11:13 +00:00
Merge pull request #283 from FluidSynth/ladspa
Polishing of LADSPA subsystem
This commit is contained in:
commit
a7fe5c4257
20 changed files with 1620 additions and 1113 deletions
|
@ -52,7 +52,6 @@ set ( LIB_VERSION_INFO
|
|||
# Options disabled by default
|
||||
option ( enable-floats "enable type float instead of double for DSP samples" off )
|
||||
option ( enable-profiling "profile the dsp code" off )
|
||||
option ( enable-ladspa "enable LADSPA effect units" off )
|
||||
option ( enable-portaudio "compile PortAudio support" off )
|
||||
option ( enable-trap-on-fpe "enable SIGFPE trap on Floating Point Exceptions" off )
|
||||
option ( enable-fpe-check "enable Floating Point Exception checks and debug messages" off )
|
||||
|
@ -68,6 +67,7 @@ option ( enable-midishare "compile MidiShare support (if it is available)" on )
|
|||
option ( enable-readline "compile readline lib line editing (if it is available)" on )
|
||||
option ( enable-dbus "compile DBUS support (if it is available)" on )
|
||||
option ( BUILD_SHARED_LIBS "Build a shared object or DLL" on )
|
||||
option ( enable-ladspa "enable LADSPA effect units" on )
|
||||
option ( enable-ipv6 "enable ipv6 support " on )
|
||||
|
||||
# Platform specific options
|
||||
|
@ -260,19 +260,6 @@ if ( enable-profiling )
|
|||
set ( WITH_PROFILING 1 )
|
||||
endif ( enable-profiling )
|
||||
|
||||
unset ( HAVE_LIBDL CACHE )
|
||||
unset ( LADSPA_SUPPORT CACHE )
|
||||
if ( enable-ladspa )
|
||||
check_include_file ( ladspa.h LADSPA_SUPPORT )
|
||||
if ( LADSPA_SUPPORT )
|
||||
set ( LADSPA 1 )
|
||||
if ( CMAKE_DL_LIBS )
|
||||
set ( HAVE_LIBDL 1 )
|
||||
set ( LIBFLUID_LIBS "${LIBFLUID_LIBS};${CMAKE_DL_LIBS}" )
|
||||
endif ( CMAKE_DL_LIBS )
|
||||
endif ( LADSPA_SUPPORT )
|
||||
endif ( enable-ladspa )
|
||||
|
||||
unset ( ENABLE_TRAPONFPE CACHE )
|
||||
unset ( TRAP_ON_FPE CACHE )
|
||||
if ( enable-trap-on-fpe AND NOT APPLE AND NOT WIN32 )
|
||||
|
@ -307,10 +294,10 @@ endif ( CMAKE_BUILD_TYPE MATCHES "Debug" )
|
|||
|
||||
if(NOT enable-pkgconfig)
|
||||
|
||||
FIND_LIBRARY( GLIB_LIB NAMES glib glib-2.0 PATH GLIB_LIBRARY_DIR NO_DEFAULT_PATH)
|
||||
FIND_LIBRARY( GTHREAD_LIB NAMES gthread gthread-2.0 PATH GTHREAD_LIBRARY_DIR NO_DEFAULT_PATH )
|
||||
FIND_PATH( GLIBH_DIR glib.h PATH GLIB_INCLUDE_DIR NO_DEFAULT_PATH )
|
||||
FIND_PATH( GLIBCONF_DIR glibconfig.h PATH GLIBCONF_INCLUDE_DIR NO_DEFAULT_PATH )
|
||||
FIND_LIBRARY( GLIB_LIB NAMES glib glib-2.0 PATH GLIB_LIBRARY_DIR )
|
||||
FIND_LIBRARY( GTHREAD_LIB NAMES gthread gthread-2.0 PATH GTHREAD_LIBRARY_DIR )
|
||||
FIND_PATH( GLIBH_DIR glib.h PATH GLIB_INCLUDE_DIR )
|
||||
FIND_PATH( GLIBCONF_DIR glibconfig.h PATH GLIBCONF_INCLUDE_DIR )
|
||||
|
||||
IF( GLIB_LIB MATCHES "GLIB_LIB-NOTFOUND" OR
|
||||
GTHREAD_LIB MATCHES "GTHREAD_LIB-NOTFOUND" OR
|
||||
|
@ -400,6 +387,15 @@ else(NOT enable-pkgconfig)
|
|||
else ( enable-dbus )
|
||||
unset_pkg_config ( DBUS )
|
||||
endif ( enable-dbus )
|
||||
|
||||
unset ( LADSPA_SUPPORT CACHE )
|
||||
if ( enable-ladspa )
|
||||
check_include_file ( ladspa.h LADSPA_SUPPORT )
|
||||
if ( LADSPA_SUPPORT )
|
||||
pkg_check_modules ( GMODULE REQUIRED gmodule-2.0>=2.6.5 )
|
||||
set ( LADSPA 1 )
|
||||
endif ( LADSPA_SUPPORT )
|
||||
endif ( enable-ladspa )
|
||||
|
||||
endif(NOT enable-pkgconfig)
|
||||
|
||||
|
|
Binary file not shown.
489
doc/ladspa.md
489
doc/ladspa.md
|
@ -1,18 +1,18 @@
|
|||
# FluidSynth LADSPA Interface
|
||||
|
||||
The [LADSPA](http://ladspa.org/) (Linux Audio Developer's Simple Plugin API)
|
||||
binding can be used to route the FluidSynth audio output through any number
|
||||
of LADSPA plugins. As the name implies, it is only available on Linux.
|
||||
binding can be used to route the FluidSynth audio output through any number of
|
||||
LADSPA plugins. Please note that even though the "L" in LADSPA stands for
|
||||
"Linux", it can also be used on different platforms, for example Windows or
|
||||
MacOS. Check the "LADSPA on other Platforms" section at the end of this guide
|
||||
for more information.
|
||||
|
||||
## Configuration
|
||||
|
||||
To configure and compile FluidSynth with LADSPA support, make sure you have
|
||||
the LADSPA SDK (basically the ladspa.h header file) installed. Then enable
|
||||
LADSPA when calling cmake:
|
||||
|
||||
cmake -Denable-ladspa=1 <path-to-source>
|
||||
|
||||
You should see `LADSPA support: yes` in the cmake output.
|
||||
To configure and compile FluidSynth with LADSPA support, make sure you have the
|
||||
LADSPA SDK installed (or at least the ladspa.h header file available in an
|
||||
include path). Then compile FluidSynth in the usual way. You should see
|
||||
`LADSPA support: yes` in the cmake output.
|
||||
|
||||
To enable the LADSPA engine, use the `synth.ladspa.active` setting when
|
||||
starting FluidSynth:
|
||||
|
@ -20,45 +20,464 @@ starting FluidSynth:
|
|||
fluidsynth -o synth.ladspa.active=1 ...
|
||||
|
||||
|
||||
# Quickstart Tutorial
|
||||
|
||||
The following walks you through the process of adding a LADSPA plugin into your
|
||||
FluidSynth configuration. It assumes that you are running FluidSynth on Linux,
|
||||
that you have some experience with running Linux shell commands and that you
|
||||
know how to start FluidSynth from the command line and use it to play a MIDI
|
||||
file.
|
||||
|
||||
## Introduction to LADSPA
|
||||
|
||||
You don't need to to have detailed knowledge of LADSPA to use effects with
|
||||
FluidSynth, but knowing some of it's concepts will help if you want to make the
|
||||
best use of it.
|
||||
|
||||
If you have the LADSPA SDK installed you should be able to use the `listplugins`
|
||||
Linux command to list all plugins installed in your LADSPA path. And to show
|
||||
more details about a particular plugin library, you can use the `analyseplugin`
|
||||
Linux command. Here is an example showing the details of the `delay.so` plugin
|
||||
from the LADSPA SDK:
|
||||
|
||||
```
|
||||
user@host:$ analyseplugin /usr/lib/ladspa/delay.so
|
||||
|
||||
Plugin Name: "Simple Delay Line"
|
||||
Plugin Label: "delay_5s"
|
||||
Plugin Unique ID: 1043
|
||||
Maker: "Richard Furse (LADSPA example plugins)"
|
||||
Copyright: "None"
|
||||
Must Run Real-Time: No
|
||||
Has activate() Function: Yes
|
||||
Has deactivate() Function: No
|
||||
Has run_adding() Function: No
|
||||
Environment: Normal or Hard Real-Time
|
||||
Ports: "Delay (Seconds)" input, control, 0 to 5, default 1
|
||||
"Dry/Wet Balance" input, control, 0 to 1, default 0.5
|
||||
"Input" input, audio
|
||||
"Output" output, audio
|
||||
```
|
||||
|
||||
This output tells you that the `delay.so` library contains only a single plugin
|
||||
called "Simple Delay Line". Most importantly it lists the input and output
|
||||
ports, which can be used to set plugin parameters and connect the audio input
|
||||
and output to FluidSynth.
|
||||
|
||||
"Delay (Seconds)" and "Dry/Wet Balance" are input controls. They are the
|
||||
parameters that a user can set to affect the way the plugin works. They control
|
||||
how long the delay should be and how the dry and wet signals should be mixed
|
||||
before writing them to the output.
|
||||
|
||||
"Input" and "Output" are audio ports which carry samples into the plugin and out
|
||||
again after it has run. Mono plugins usually provide one set of input and output
|
||||
audio ports, stereo plugins usually provide two sets. But there are even plugins
|
||||
that only have a single output port and no input at all (think of noise
|
||||
generators...)
|
||||
|
||||
Also note the line `Has run_adding() Function: No`. This specifies that this
|
||||
plugin can not mix it's audio output into an output buffer, but will always
|
||||
replace anything that is already there. This will become important again later
|
||||
on.
|
||||
|
||||
## FluidSynth Host Ports
|
||||
|
||||
Just as LADSPA plugins have input and output ports, FluidSynth provides it's
|
||||
own audio ports that can be connected to plugins. On a standard stereo setup,
|
||||
the following four ports are automatically created:
|
||||
|
||||
- Main:L
|
||||
- Main:R
|
||||
- Reverb:Send
|
||||
- Chorus:Send
|
||||
|
||||
The "Main:L" and "Main:R" ports can be connected to effect input and output
|
||||
ports. They carry the main audio signals into the LADSPA effects and the
|
||||
modified signals back into FluidSynth.
|
||||
|
||||
"Reverb:Send" and "Chorus:Send" can be used as effect inputs. They carry the
|
||||
mono effect send signals (as determined by the reverb and chorus send
|
||||
generators for each voice) into the LADSPA effects.
|
||||
|
||||
Please note that if you run FluidSynth with the internal reverb and chorus
|
||||
effects active (which is the default), then those effects are already mixed
|
||||
into the Main:L and Main:R channels. Fore more details, please see the "Signal
|
||||
Flow" section below.
|
||||
|
||||
For host port setups in multi-channel configurations, please see the
|
||||
"Multi-Channel Output" section below.
|
||||
|
||||
## Creating a Configuration File
|
||||
|
||||
You can configure LADSPA effects using the FluidSynth shell, but writing the
|
||||
commands into a file and loading it at startup is much more comfortable. So
|
||||
let's create a file `effects.txt` with the following contents:
|
||||
|
||||
effects.txt
|
||||
```
|
||||
ladspa_effect e1 /usr/lib/ladspa/delay.so
|
||||
ladspa_link e1 Input Main:L
|
||||
ladspa_link e1 Output Main:L
|
||||
|
||||
ladspa_effect e2 /usr/lib/ladspa/delay.so delay_5s
|
||||
ladspa_link e2 Input Main:R
|
||||
ladspa_link e2 Output Main:R
|
||||
|
||||
ladspa_start
|
||||
```
|
||||
|
||||
As the "Simple Delay Line" plugin only works on a mono signal, the configuration
|
||||
above creates two effects: the one we named "e1" reads from and writes to the
|
||||
left FluidSynth audio channel "Main:L", the "e2" effect reads from and
|
||||
writes to the right channel "Main:R".
|
||||
|
||||
Please note that we only specified the path to the library
|
||||
`/usr/lib/ladspa/delay.so` when creating the "e1" effect, but not which plugin
|
||||
from the library to use. This is possible because the delay.so library contains
|
||||
only a single plugin. If you want to use a library that contains more than one
|
||||
plugin, you would need to give the plugin name as well, as we've done when
|
||||
creating the "e2" effect. The string to use here is what is called "Plugin
|
||||
Label" in the `analyseplugin` output.
|
||||
|
||||
## Using the Configuration File
|
||||
|
||||
Lets start FluidSynth with ALSA output and the standard SoundFont, enable LADSPA
|
||||
effects, load the effects.txt config file and give it a test MIDI file to play:
|
||||
(You will need to replace the `test.mid` with your own MIDI file and maybe
|
||||
change the paths to the effects.txt file and the SoundFont)
|
||||
|
||||
```
|
||||
user@host:$ fluidsynth -a alsa -o synth.ladspa.active=1 -f effects.txt FluidR3_GM.sf2 test.mid
|
||||
```
|
||||
|
||||
You should now hear the MIDI file played at a slightly lower volume with a one
|
||||
second delay effect added on both left and right channel. If not, please check
|
||||
the FluidSynth output for any error messages.
|
||||
|
||||
## Changing Parameters
|
||||
|
||||
You probably noticed that we did not set any values for the "Delay (Seconds)"
|
||||
and "Dry/Wet Balance" control ports. The delay plugin specifies default
|
||||
values for these parameters: 1 second delay and a dry/wet balance of 0.5 (check
|
||||
the `analyseplugin` output above). So when you don't override them, the defaults
|
||||
are automatically used for rendering.
|
||||
|
||||
Let's set different values now and set the delay time on the left channel to
|
||||
half a second and to 1.5 seconds on the right channel:
|
||||
|
||||
```
|
||||
ladspa_effect e1 /usr/lib/ladspa/delay.so
|
||||
ladspa_link e1 Input Main:L
|
||||
ladspa_link e1 Output Main:L
|
||||
ladspa_set e1 Delay 0.5
|
||||
|
||||
ladspa_effect e2 /usr/lib/ladspa/delay.so
|
||||
ladspa_link e2 Input Main:R
|
||||
ladspa_link e2 Output Main:R
|
||||
ladspa_set e2 Delay 1.5
|
||||
|
||||
ladspa_start
|
||||
```
|
||||
|
||||
Start FluidSynth again and you should hear that the delay is shorter on the
|
||||
left channel, longer on the right. You can even change control parameters while
|
||||
FluidSynth is running. Just type the `ladspa_set ...` commands into the
|
||||
FluidSynth shell.
|
||||
|
||||
And to check the difference that the LADSPA effects have on the sound output,
|
||||
you can turn them off and on again during run-time. Just type in `ladspa_stop`
|
||||
and `ladspa_start` into the FluidSynth shell.
|
||||
|
||||
### Port Name Matching
|
||||
|
||||
Plugin port names are sometimes very long, because the plugin writers want them
|
||||
to be self-documenting. But note that we didn't need to give the complete port
|
||||
name "Delay (Seconds)" in the `ladspa_set` commands, but chose to use a much
|
||||
shorter version: "Delay".
|
||||
|
||||
When specifying a port name for the `ladspa_link` and `ladspa_set` commands,
|
||||
the system will look for any port that *starts with* the name you gave it. If
|
||||
there is only one match, then that port is chosen. If there are multiple
|
||||
matches (meaning your port name is ambiguous), you will see an error asking
|
||||
you to be more specific. So the configuration for the "e1" effect could also
|
||||
have been written with much shorter port names:
|
||||
```
|
||||
ladspa_effect e1 /usr/lib/ladspa/delay.so
|
||||
ladspa_link e1 In Main:L
|
||||
ladspa_link e1 Out Main:L
|
||||
ladspa_set e1 Del 0.5
|
||||
```
|
||||
|
||||
# Signal Flow
|
||||
|
||||
The LADSPA effects unit runs immediately after the internal reverb and chorus
|
||||
effects have been processed. When no plugins have been configured, the
|
||||
effects unit is dormant and uses no additional system resources.
|
||||
effects have been processed. When no effects have been configured, the LADSPA
|
||||
engine is dormant and uses no additional system resources.
|
||||
|
||||
When at least one plugin is configured and the engine is activated, the
|
||||
rendered audio is passed into the LADSPA effects unit, each plugin is
|
||||
run in the order that they were created and the resulting audio is
|
||||
passed back into FluidSynth (and from there to the sound card or other
|
||||
output).
|
||||
When at least one effect is configured and the engine is activated, the rendered
|
||||
audio is passed into the LADSPA effects engine, the effects are run in the order
|
||||
that they were created and the resulting audio is passed back into FluidSynth
|
||||
(and from there to the sound card or other output).
|
||||
|
||||
## Effect Sends
|
||||
|
||||
Please note that SoundFont designers can specify how much signal each
|
||||
instrument should add to the reverb and chorus effect sends. When FluidSynth
|
||||
renders a block of audio, all currently sounding instruments are mixed into the
|
||||
`Main` output channels. In addition, all instruments add their signal to the
|
||||
effect send ports (`Reverb:Send` and `Chorus:Send`) according to the effect
|
||||
send amount specified in the SoundFont.
|
||||
|
||||
If you want to replace the internal reverb or chorus effects with a LADSPA
|
||||
plugin and you want to honour the decisions made by the SoundFont designer, you
|
||||
should use the `Reverb:Send` or `Chorus:Send` ports as effect input and
|
||||
`Main:L` and `Main:R` ports as effect outputs. (See the "Example Setups" section
|
||||
below for an example on how to replace the internal reverb with a LADSPA plugin.)
|
||||
|
||||
Please note that FluidSynth uses a mono signal for both effects, that is why
|
||||
there is only a single send port for reverb and chorus.
|
||||
|
||||
|
||||
# Loading and Connecting Plugins
|
||||
# LADSPA Command Reference
|
||||
|
||||
Currently the only way to configure the effects unit is via the FluidSynth
|
||||
shell or via a config file.
|
||||
The following is a description of all LADSPA-related commands that are
|
||||
available in the FluidSynth shell if it has been compiled with LADSPA
|
||||
support.
|
||||
|
||||
## Example Setups
|
||||
- `ladspa_effect`: Create a new effect from a plugin library
|
||||
- `ladspa_buffer`: Create a new buffer
|
||||
- `ladspa_link`: Link an effect port to a host port or a buffer
|
||||
- `ladspa_set`: Set the value of an effect control
|
||||
- `ladspa_check`: Check the effect setup for any problems
|
||||
- `ladspa_start`: Start the effects unit
|
||||
- `ladspa_stop`: Stop the effects unit
|
||||
- `ladspa_reset`: Reset the effects unit
|
||||
|
||||
All examples assume that your `LADSPA_PATH` environment variable points
|
||||
to the directory containing the plugin libraries (e.g. /usr/lib/ladspa).
|
||||
## ladspa_effect
|
||||
|
||||
### Single Plugin
|
||||
```
|
||||
ladspa_effect <effect-name> <library-path> [plugin-name] [--mix [gain]]
|
||||
```
|
||||
|
||||
Load the LADSPA plugin library given by `<library-path>` and create a new effect
|
||||
(i.e. an instance of a plugin). `<effect-name>` can be chosen by the user and must
|
||||
unique. `<plugin-name>` is optional if the library contains only one plugin.
|
||||
|
||||
If the optional `--mix` parameter is given, then the LADSPA engine will call the
|
||||
`run_adding` interface of the plugin. This will make the effect add it's output
|
||||
to the output buffers instead of replacing them. The `--mix` parameter takes an
|
||||
optional float value `gain`, which will be multiplied with each sample before
|
||||
adding to the output buffers.
|
||||
|
||||
Please note that there is no command to delete a single effect once created. To
|
||||
remove effects, please use `ladspa_reset` to clear everything start from
|
||||
scratch.
|
||||
|
||||
Can only be called when the effect unit is not active.
|
||||
|
||||
## ladspa_buffer
|
||||
|
||||
```
|
||||
ladspa_buffer <buffer-name>
|
||||
```
|
||||
|
||||
Create a new audio buffer called `<buffer-name>`. The buffer is able to be used as
|
||||
mono output or mono input to an effect. Buffers can be used to connect plugins
|
||||
between each other without overwriting the host ports with temporary data.
|
||||
|
||||
Please note that there is no command to delete a buffer. To remove buffers,
|
||||
please use `ladspa_reset` to clear everything and start from scratch.
|
||||
|
||||
Can only be used when the effect unit is not active.
|
||||
|
||||
## ladspa_link
|
||||
|
||||
```
|
||||
ladspa_link <effect-name> <audio-port-name> <buffer-or-host-port-name>
|
||||
```
|
||||
|
||||
Connects an effect input or output port with a buffer or a host port. This
|
||||
command can be called multiple times and will overwrite the previous connection
|
||||
made on that effect port.
|
||||
|
||||
Please note that there is no command to unlink an effect port. Use
|
||||
`ladspa_reset` to clear everything and start from scratch.
|
||||
|
||||
Can only be used when the effect unit is not active.
|
||||
|
||||
## ladspa_set
|
||||
|
||||
```
|
||||
ladspa_set <effect-name> <control-port-name> <float-value>
|
||||
```
|
||||
|
||||
Sets a control port of an effect to a float value. Can be used at any time,
|
||||
even when the effect unit is active.
|
||||
|
||||
## ladspa_check
|
||||
|
||||
```
|
||||
ladspa_check
|
||||
```
|
||||
|
||||
Checks the LADSPA effect configuration for errors. This command is also
|
||||
implicitly called when executing `ladspa_start`.
|
||||
|
||||
## ladspa_start
|
||||
|
||||
```
|
||||
ladspa_start
|
||||
```
|
||||
|
||||
Activates the effects unit and inserts the configured effects into FluidSynth's
|
||||
audio rendering pipeline.
|
||||
|
||||
## ladspa_stop
|
||||
|
||||
```
|
||||
ladspa_stop
|
||||
```
|
||||
|
||||
Deactivates the effects unit and removes the configured effects from
|
||||
FluidSynth's audio rendering pipeline. The configuration is left untouched, so
|
||||
it can be started again with `ladspa_start`.
|
||||
|
||||
## ladspa_reset
|
||||
|
||||
```
|
||||
ladspa_reset
|
||||
```
|
||||
|
||||
Deactivates the effects unit if active and clears all configuration and loaded
|
||||
plugins.
|
||||
|
||||
|
||||
# Example Setups
|
||||
|
||||
All examples assume that your `LADSPA_PATH` environment variable points to the
|
||||
directory containing the plugin libraries (e.g. /usr/lib/ladspa).
|
||||
|
||||
## Single Plugin
|
||||
|
||||
The following loads the delay.so plugin library from the LADSPA SDK and
|
||||
instantiates the `delay_5s` plugin from that library. It connects the
|
||||
main left channel output from FluidSynth with the plugin input, the
|
||||
main left channel input to FluidSynth with the plugin output. It also
|
||||
sets the two control ports of the plugin to example values and starts
|
||||
the engine.
|
||||
instantiates the delay effect under the name "e1". It connects the main left
|
||||
audio channel from FluidSynth with the plugin input and output and starts the
|
||||
effects engine.
|
||||
|
||||
ladspa_plugin delay.so delay_5s
|
||||
ladspa_port Input < in1_L
|
||||
ladspa_port Output > out1_L
|
||||
ladspa_port Delay = 1.0
|
||||
ladspa_port Dry/Wet = 0.5
|
||||
|
||||
ladspa_start
|
||||
```
|
||||
ladspa_effect e1 delay.so
|
||||
ladspa_link e1 Input Main:L
|
||||
ladspa_link e1 Output Main:L
|
||||
ladspa_start
|
||||
```
|
||||
|
||||
The audible effect should be an untouched right channel and a slightly
|
||||
lower volume on the left with a delay effect of 1 second on top.
|
||||
|
||||
## Replacing the FluidSynth Reverb Effect
|
||||
|
||||
If you would like a different reverb implementation than the one built-in to
|
||||
FluidSynth, you can use a LADSPA reverb plugin like the "TAP Reverb" from
|
||||
[Tom's Audio Processing plugins](http://tap-plugins.sourceforge.net/ladspa.html).
|
||||
|
||||
Here is the analyseplugin output for the `tap_reverb.so` plugin:
|
||||
```
|
||||
user@host:$ analyseplugin /usr/lib/ladspa/tap_reverb.so
|
||||
|
||||
Plugin Name: "TAP Reverberator"
|
||||
Plugin Label: "tap_reverb"
|
||||
Plugin Unique ID: 2142
|
||||
Maker: "Tom Szilagyi"
|
||||
Copyright: "GPL"
|
||||
Must Run Real-Time: No
|
||||
Has activate() Function: Yes
|
||||
Has deactivate() Function: No
|
||||
Has run_adding() Function: Yes
|
||||
Environment: Normal
|
||||
Ports: "Decay [ms]" input, control, 0 to 10000, default 2500
|
||||
"Dry Level [dB]" input, control, -70 to 10, default 0
|
||||
"Wet Level [dB]" input, control, -70 to 10, default 0
|
||||
"Comb Filters" input, control, toggled, default 1
|
||||
"Allpass Filters" input, control, toggled, default 1
|
||||
"Bandpass Filter" input, control, toggled, default 1
|
||||
"Enhanced Stereo" input, control, toggled, default 1
|
||||
"Reverb Type" input, control, 0 to 42.1, default 0, integer
|
||||
"Input Left" input, audio
|
||||
"Output Left" output, audio
|
||||
"Input Right" input, audio
|
||||
"Output Right" output, audio
|
||||
```
|
||||
|
||||
Using this information we can create a LADSPA configuration:
|
||||
|
||||
effects.txt
|
||||
```
|
||||
ladspa_effect e1 /usr/lib/ladspa/tap_reverb.so
|
||||
ladspa_link e1 "Input Left" Reverb:Send
|
||||
ladspa_link e1 "Input Right" Reverb:Send
|
||||
ladspa_link e1 "Output Left" Main:L
|
||||
ladspa_link e1 "Output Right" Main:R
|
||||
ladspa_start
|
||||
```
|
||||
|
||||
Start FluidSynth with the internal reverb disabled. (You will need to replace
|
||||
the `test.mid` with your own MIDI file and maybe change the paths to the
|
||||
effects.txt file and the SoundFont)
|
||||
|
||||
```
|
||||
user@host:$ fluidsynth -a alsa -R0 -o synth.ladspa.active=1 -f effects.txt FluidR3_GM.sf2 test.mid
|
||||
```
|
||||
|
||||
You will hear the output with a reverb effect from the plugin. And you can
|
||||
change the reverb control ports with the `ladspa_set` command while the MIDI
|
||||
file is playing.
|
||||
|
||||
# Multi-Channel Output
|
||||
|
||||
FluidSynth is capable of generating multi-channel output by specifying the
|
||||
`synth.audio-groups` and `synth.audio-channels` configuration settings.
|
||||
Explaining multi-channel output in detail is out of scope for this guide. But
|
||||
using multiple output channels has an effect on the host ports that are
|
||||
available to LADSPA plugins.
|
||||
|
||||
As soon as you configure more than one audio-channel, the main audio ports will
|
||||
not be called "Main:L" and "Main:R" anymore, but will have indices added to
|
||||
their name. So if you start FluidSynth with `-o synth.audio-groups=2`, then the
|
||||
following ports will be created:
|
||||
|
||||
- Main:L1
|
||||
- Main:R1
|
||||
- Main:L2
|
||||
- Main:R2
|
||||
- Reverb:Send
|
||||
- Chorus:Send
|
||||
|
||||
If you want all main ports to act as outputs as well as inputs to the effects,
|
||||
then you also need to increase the `synth.audio-channels` setting.
|
||||
|
||||
|
||||
# LADSPA on other Platforms
|
||||
|
||||
LADSPA is a very simple plugin architecture and only requires the ladspa.h
|
||||
header file as compile-time dependency. To build FluidSynth on non-Linux
|
||||
platform with LADSPA support, download the ladspa.h file from
|
||||
http://www.ladspa.org and place it somewhere in your compiler include path. Then
|
||||
configure and build LADSPA as you normally would.
|
||||
|
||||
All information in the above documentation is valid for all other platforms as
|
||||
well. Just make sure you use the file path format specific to your platform in
|
||||
the `ladspa_effect` calls. For example, on Windows you should use
|
||||
```
|
||||
ladspa_effect c:\path\to\ladspa\plugin.dll
|
||||
```
|
||||
instead of
|
||||
```
|
||||
ladspa_effect /path/to/ladspa/plugin.so
|
||||
```
|
||||
|
||||
Audacity provides a large number of precompiled LADSPA plugins for Windows and
|
||||
MacOS: http://www.audacityteam.org/download/plug-ins/
|
||||
|
||||
To get the `analyseplugin` and `listplugins` commands on Windows, you can either
|
||||
compile them yourself using the LADSPA-SDK source code from ladspa.org or install
|
||||
ladspa-sdk via Cygwin.
|
||||
|
|
|
@ -104,6 +104,7 @@ extern "C" {
|
|||
#include "fluidsynth/gen.h"
|
||||
#include "fluidsynth/voice.h"
|
||||
#include "fluidsynth/version.h"
|
||||
#include "fluidsynth/ladspa.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -27,6 +27,7 @@ if ( NOT MACOSX_FRAMEWORK )
|
|||
audio.h
|
||||
event.h
|
||||
gen.h
|
||||
ladspa.h
|
||||
log.h
|
||||
midi.h
|
||||
misc.h
|
||||
|
|
54
include/fluidsynth/ladspa.h
Normal file
54
include/fluidsynth/ladspa.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _FLUIDSYNTH_LADSPA_H
|
||||
#define _FLUIDSYNTH_LADSPA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_is_active(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_activate(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_deactivate(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_reset(fluid_ladspa_fx_t *fx);
|
||||
FLUIDSYNTH_API int fluid_ladspa_check(fluid_ladspa_fx_t *fx, char *err, int err_size);
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_host_port_exists(fluid_ladspa_fx_t *fx, const char *name);
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_add_buffer(fluid_ladspa_fx_t *fx, const char *name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_buffer_exists(fluid_ladspa_fx_t *fx, const char *name);
|
||||
|
||||
FLUIDSYNTH_API int fluid_ladspa_add_effect(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *lib_name, const char *plugin_name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_can_mix(fluid_ladspa_fx_t *fx, const char *name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_set_mix(fluid_ladspa_fx_t *fx, const char *name, int mix, float gain);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_port_exists(fluid_ladspa_fx_t *fx, const char *effect_name, const char *port_name);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_set_control(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *port_name, float val);
|
||||
FLUIDSYNTH_API int fluid_ladspa_effect_link(fluid_ladspa_fx_t *fx, const char *effect_name,
|
||||
const char *port_name, const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLUIDSYNTH_LADSPA_H */
|
||||
|
|
@ -347,6 +347,10 @@ FLUIDSYNTH_API
|
|||
FLUID_DEPRECATED
|
||||
void fluid_synth_set_midi_router(fluid_synth_t* synth, fluid_midi_router_t* router);
|
||||
|
||||
/* LADSPA */
|
||||
|
||||
FLUIDSYNTH_API fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,8 @@ typedef struct _fluid_sequencer_t fluid_sequencer_t; /**< Sequencer i
|
|||
typedef struct _fluid_ramsfont_t fluid_ramsfont_t; /**< RAM SoundFont */
|
||||
typedef struct _fluid_rampreset_t fluid_rampreset_t; /**< RAM SoundFont preset */
|
||||
typedef struct _fluid_cmd_handler_t fluid_cmd_handler_t; /**< Shell Command Handler */
|
||||
typedef struct _fluid_ladspa_fx_t fluid_ladspa_fx_t; /**< LADSPA effects instance */
|
||||
|
||||
|
||||
typedef int fluid_istream_t; /**< Input stream descriptor */
|
||||
typedef int fluid_ostream_t; /**< Output stream descriptor */
|
||||
|
|
|
@ -102,10 +102,6 @@ if ( LIBSNDFILE_SUPPORT )
|
|||
include_directories ( ${LIBSNDFILE_INCLUDEDIR} ${LIBSNDFILE_INCLUDE_DIRS} )
|
||||
endif ( LIBSNDFILE_SUPPORT )
|
||||
|
||||
if ( LADSPA_SUPPORT )
|
||||
set ( fluid_ladspa_SOURCES bindings/fluid_ladspa.c bindings/fluid_ladspa.h )
|
||||
endif ( LADSPA_SUPPORT )
|
||||
|
||||
if ( MIDISHARE_SUPPORT )
|
||||
set ( fluid_midishare_SOURCES drivers/fluid_midishare.c )
|
||||
include_directories ( ${MidiShare_INCLUDE_DIRS} )
|
||||
|
@ -178,12 +174,15 @@ set ( libfluidsynth_SOURCES
|
|||
bindings/fluid_cmd.c
|
||||
bindings/fluid_cmd.h
|
||||
bindings/fluid_filerenderer.c
|
||||
bindings/fluid_ladspa.c
|
||||
bindings/fluid_ladspa.h
|
||||
)
|
||||
|
||||
set ( public_HEADERS
|
||||
${CMAKE_SOURCE_DIR}/include/fluidsynth/audio.h
|
||||
${CMAKE_SOURCE_DIR}/include/fluidsynth/event.h
|
||||
${CMAKE_SOURCE_DIR}/include/fluidsynth/gen.h
|
||||
${CMAKE_SOURCE_DIR}/include/fluidsynth/ladspa.h
|
||||
${CMAKE_SOURCE_DIR}/include/fluidsynth/log.h
|
||||
${CMAKE_SOURCE_DIR}/include/fluidsynth/midi.h
|
||||
${CMAKE_SOURCE_DIR}/include/fluidsynth/misc.h
|
||||
|
@ -235,7 +234,6 @@ add_library ( libfluidsynth
|
|||
${fluid_dbus_SOURCES}
|
||||
${fluid_jack_SOURCES}
|
||||
${fluid_lash_SOURCES}
|
||||
${fluid_ladspa_SOURCES}
|
||||
${fluid_midishare_SOURCES}
|
||||
${fluid_oss_SOURCES}
|
||||
${fluid_portaudio_SOURCES}
|
||||
|
@ -293,6 +291,7 @@ endif ( LIBFLUID_CPPFLAGS )
|
|||
|
||||
target_link_libraries ( libfluidsynth
|
||||
${GLIB_LIBRARIES}
|
||||
${GMODULE_LIBRARIES}
|
||||
${LASH_LIBRARIES}
|
||||
${JACK_LIBRARIES}
|
||||
${ALSA_LIBRARIES}
|
||||
|
|
|
@ -33,9 +33,11 @@
|
|||
#include <readline/history.h>
|
||||
#endif
|
||||
|
||||
#define MAX_TOKENS 100 /* LADSPA plugins need lots of parameters */
|
||||
/* FIXME: LADSPA used to need a lot of parameters on a single line. This is not
|
||||
* necessary anymore, so the limits below could probably be reduced */
|
||||
#define MAX_TOKENS 100
|
||||
#define MAX_COMMAND_LEN 1024 /* max command length accepted by fluid_command() */
|
||||
#define FLUID_WORKLINELENGTH 1024 /* LADSPA plugins use long command lines */
|
||||
#define FLUID_WORKLINELENGTH 1024
|
||||
|
||||
#define FLUID_ENTRY_COMMAND(data) fluid_cmd_handler_t* handler=(fluid_cmd_handler_t*)(data)
|
||||
|
||||
|
@ -47,11 +49,6 @@ struct _fluid_cmd_handler_t {
|
|||
|
||||
fluid_midi_router_rule_t *cmd_rule; /* Rule currently being processed by shell command handler */
|
||||
int cmd_rule_type; /* Type of the rule (#fluid_midi_router_rule_type) */
|
||||
|
||||
#ifdef LADSPA
|
||||
/* Instance id of the LADSPA plugin currently being processed by shell command handler */
|
||||
int ladspa_plugin_id;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -180,16 +177,14 @@ static const fluid_cmd_int_t fluid_commands[] = {
|
|||
"echo arg Print arg" },
|
||||
/* LADSPA-related commands */
|
||||
#ifdef LADSPA
|
||||
{ "ladspa_plugin", "ladspa", fluid_handle_ladspa_plugin,
|
||||
"ladspa_plugin Instantiate a new LADSPA plugin"},
|
||||
{ "ladspa_port", "ladspa", fluid_handle_ladspa_port,
|
||||
"ladspa_port Connect a LADSPA plugin port"},
|
||||
{ "ladspa_node", "ladspa", fluid_handle_ladspa_node,
|
||||
"ladspa_node Create a LADSPA audio or control node"},
|
||||
{ "ladspa_control", "ladspa", fluid_handle_ladspa_control,
|
||||
"ladspa_control Set the value of a LADSPA control node"},
|
||||
{ "ladspa_control_defaults", "ladspa", fluid_handle_ladspa_control_defaults,
|
||||
"ladspa_control_defaults Assign all unconnected controls on all plugins their default value"},
|
||||
{ "ladspa_effect", "ladspa", fluid_handle_ladspa_effect,
|
||||
"ladspa_effect Create a new effect from a LADSPA plugin"},
|
||||
{ "ladspa_link", "ladspa", fluid_handle_ladspa_link,
|
||||
"ladspa_link Connect an effect port to a host port or buffer"},
|
||||
{ "ladspa_buffer", "ladspa", fluid_handle_ladspa_buffer,
|
||||
"ladspa_buffer Create a LADSPA buffer"},
|
||||
{ "ladspa_set", "ladspa", fluid_handle_ladspa_set,
|
||||
"ladspa_set Set the value of an effect control port"},
|
||||
{ "ladspa_check", "ladspa", fluid_handle_ladspa_check,
|
||||
"ladspa_check Check LADSPA configuration"},
|
||||
{ "ladspa_start", "ladspa", fluid_handle_ladspa_start,
|
||||
|
@ -1893,26 +1888,36 @@ int fluid_handle_router_par2(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
return FLUID_FAILED; \
|
||||
}
|
||||
|
||||
#define CHECK_LADSPA_INACTIVE(_fx, _out) \
|
||||
if (fluid_ladspa_is_active(_fx)) \
|
||||
{ \
|
||||
fluid_ostream_printf(_out, "LADSPA already started.\n"); \
|
||||
return FLUID_FAILED; \
|
||||
}
|
||||
|
||||
#define LADSPA_ERR_LEN (1024)
|
||||
|
||||
/**
|
||||
* ladspa_start
|
||||
*/
|
||||
int fluid_handle_ladspa_start(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_ladspa_fx_t *fx = handler->synth->ladspa_fx;
|
||||
char error[LADSPA_ERR_LEN];
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
|
||||
if (fluid_ladspa_is_active(fx))
|
||||
if (ac != 0)
|
||||
{
|
||||
fluid_ostream_printf(out, "LADSPA already started.\n");
|
||||
fluid_ostream_printf(out, "ladspa_start does not accept any arguments\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
CHECK_LADSPA_INACTIVE(fx, out);
|
||||
|
||||
if (fluid_ladspa_check(fx, error, LADSPA_ERR_LEN) != FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out, "LADSPA check failed: %s", error);
|
||||
fluid_ostream_printf(out, "LADSPA not started.\n");
|
||||
fluid_ostream_printf(out, "Unable to start LADSPA: %s", error);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1925,11 +1930,20 @@ int fluid_handle_ladspa_start(void* data, int ac, char **av, fluid_ostream_t out
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* ladspa_stop
|
||||
*/
|
||||
int fluid_handle_ladspa_stop(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_ladspa_fx_t *fx = handler->synth->ladspa_fx;
|
||||
|
||||
if (ac != 0)
|
||||
{
|
||||
fluid_ostream_printf(out, "ladspa_stop does not accept any arguments\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
|
||||
if (!fluid_ladspa_is_active(fx))
|
||||
|
@ -1946,11 +1960,20 @@ int fluid_handle_ladspa_stop(void* data, int ac, char **av, fluid_ostream_t out)
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* ladspa_reset
|
||||
*/
|
||||
int fluid_handle_ladspa_reset(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_ladspa_fx_t *fx = handler->synth->ladspa_fx;
|
||||
|
||||
if (ac != 0)
|
||||
{
|
||||
fluid_ostream_printf(out, "ladspa_reset does not accept any arguments\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
|
||||
fluid_ladspa_reset(fx);
|
||||
|
@ -1958,30 +1981,21 @@ int fluid_handle_ladspa_reset(void* data, int ac, char **av, fluid_ostream_t out
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
int fluid_handle_ladspa_control_defaults(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_ladspa_fx_t *fx = handler->synth->ladspa_fx;
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
|
||||
if (fluid_ladspa_control_defaults(fx) != FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out, "Error while setting default values for control ports\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
fluid_ostream_printf(out, "Control port defaults set\n");
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* ladspa_check
|
||||
*/
|
||||
int fluid_handle_ladspa_check(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_ladspa_fx_t *fx = handler->synth->ladspa_fx;
|
||||
char error[LADSPA_ERR_LEN];
|
||||
|
||||
if (ac != 0)
|
||||
{
|
||||
fluid_ostream_printf(out, "ladspa_reset does not accept any arguments\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
|
||||
if (fluid_ladspa_check(fx, error, LADSPA_ERR_LEN) != FLUID_OK)
|
||||
|
@ -1995,173 +2009,163 @@ int fluid_handle_ladspa_check(void* data, int ac, char **av, fluid_ostream_t out
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
int fluid_handle_ladspa_control(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
/**
|
||||
* ladspa_set <effect> <port> <value>
|
||||
*/
|
||||
int fluid_handle_ladspa_set(void *data, int ac, char **av, fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_ladspa_fx_t *fx = handler->synth->ladspa_fx;
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
|
||||
if (ac != 2)
|
||||
if (ac != 3)
|
||||
{
|
||||
fluid_ostream_printf(out, "ladspa_control needs two arguments: node name and value.\n");
|
||||
fluid_ostream_printf(out, "ladspa_set needs three arguments: <effect> <port> <value>\n");
|
||||
return FLUID_FAILED;
|
||||
};
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
|
||||
/* Redundant check, just here to give a more detailed error message */
|
||||
if (!fluid_ladspa_node_exists(fx, av[0]))
|
||||
if (!fluid_ladspa_effect_port_exists(fx, av[0], av[1]))
|
||||
{
|
||||
fluid_ostream_printf(out, "Node '%s' not found.\n", av[0]);
|
||||
fluid_ostream_printf(out, "Port '%s' not found on effect '%s'\n", av[1], av[0]);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (fluid_ladspa_set_control_node(fx, av[0], atof(av[1])) != FLUID_OK)
|
||||
if (fluid_ladspa_effect_set_control(fx, av[0], av[1], atof(av[2])) != FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out, "Failed to set node '%s', maybe it's not a control node?\n",
|
||||
av[0]);
|
||||
fluid_ostream_printf(out, "Failed to set port '%s' on effect '%s', "
|
||||
"maybe it is not a control port?\n", av[1], av[0]);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
};
|
||||
|
||||
int fluid_handle_ladspa_node(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
/**
|
||||
* ladspa_buffer <name>
|
||||
*/
|
||||
int fluid_handle_ladspa_buffer(void *data, int ac, char **av, fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_ladspa_fx_t *fx = handler->synth->ladspa_fx;
|
||||
char *name;
|
||||
char *type;
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
|
||||
if (ac < 2)
|
||||
if (ac != 1)
|
||||
{
|
||||
fluid_ostream_printf(out, "ladspa_node needs at least two arguments: node name and type.\n");
|
||||
fluid_ostream_printf(out, "ladspa_buffer needs one argument: <name>\n");
|
||||
return FLUID_FAILED;
|
||||
};
|
||||
|
||||
name = av[0];
|
||||
type = av[1];
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
CHECK_LADSPA_INACTIVE(fx, out);
|
||||
|
||||
/* audio node - additional no arguments */
|
||||
if (FLUID_STRCMP(type, "audio") == 0)
|
||||
if (fluid_ladspa_add_buffer(fx, av[0]) != FLUID_OK)
|
||||
{
|
||||
if (fluid_ladspa_add_audio_node(fx, name) != FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out, "Failed to add audio node.\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
/* control node - arguments: <val> */
|
||||
else if (FLUID_STRCMP(type, "control") == 0)
|
||||
{
|
||||
if (ac != 3)
|
||||
{
|
||||
fluid_ostream_printf(out, "Control nodes need 3 arguments.\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (fluid_ladspa_add_control_node(fx, name, atof(av[2])) != FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out, "Failed to add contrl node.\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fluid_ostream_printf(out, "Invalid node type.\n");
|
||||
return FLUID_FAILED;
|
||||
fluid_ostream_printf(out, "Failed to add buffer\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
};
|
||||
|
||||
int fluid_handle_ladspa_plugin(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
/**
|
||||
* ladspa_effect <name> <library> [plugin] [--mix [gain]]
|
||||
*/
|
||||
int fluid_handle_ladspa_effect(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_ladspa_fx_t *fx = handler->synth->ladspa_fx;
|
||||
int plugin_id;
|
||||
char *plugin_name = NULL;
|
||||
int pos;
|
||||
int mix = FALSE;
|
||||
float gain = 1.0f;
|
||||
|
||||
if (ac < 2 || ac > 5)
|
||||
{
|
||||
fluid_ostream_printf(out, "ladspa_effect invalid arguments: "
|
||||
"<name> <library> [plugin] [--mix [gain]]\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
pos = 2;
|
||||
/* If the first optional arg is not --mix, then it must be the plugin label */
|
||||
if ((pos < ac) && (FLUID_STRCMP(av[pos], "--mix") != 0))
|
||||
{
|
||||
plugin_name = av[pos];
|
||||
pos++;
|
||||
}
|
||||
|
||||
/* If this optional arg is --mix and there's an argument after it, that that
|
||||
* must be the gain */
|
||||
if ((pos < ac) && (FLUID_STRCMP(av[pos], "--mix") == 0))
|
||||
{
|
||||
mix = TRUE;
|
||||
if (pos + 1 < ac)
|
||||
{
|
||||
gain = atof(av[pos + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
CHECK_LADSPA_INACTIVE(fx, out);
|
||||
|
||||
if (ac != 2)
|
||||
if (fluid_ladspa_add_effect(fx, av[0], av[1], plugin_name) != FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out, "ladspa_plugin needs 2 arguments: library and plugin id.\n");
|
||||
fluid_ostream_printf(out, "Failed to create effect\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
plugin_id = fluid_ladspa_add_plugin(fx, av[0], av[1]);
|
||||
if (plugin_id < 0)
|
||||
if (mix)
|
||||
{
|
||||
fluid_ostream_printf(out, "Failed to add plugin.\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
if (!fluid_ladspa_effect_can_mix(fx, av[0]))
|
||||
{
|
||||
fluid_ostream_printf(out, "Effect '%s' does not support --mix mode\n", av[0]);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
/* store current plugin in the handler, so that subsequent ladspa_port
|
||||
* commands know which plugin to configure */
|
||||
handler->ladspa_plugin_id = plugin_id;
|
||||
if (fluid_ladspa_effect_set_mix(fx, av[0], mix, gain) != FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out, "Failed to set --mix mode\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
int fluid_handle_ladspa_port(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
/*
|
||||
* ladspa_link <effect> <port> <buffer or host port>
|
||||
*/
|
||||
int fluid_handle_ladspa_link(void* data, int ac, char **av, fluid_ostream_t out)
|
||||
{
|
||||
FLUID_ENTRY_COMMAND(data);
|
||||
fluid_ladspa_fx_t *fx = handler->synth->ladspa_fx;
|
||||
int dir;
|
||||
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
|
||||
if (ac != 3)
|
||||
{
|
||||
fluid_ostream_printf(out, "ladspa_port needs 3 arguments: "
|
||||
"port name, direction and node name.\n");
|
||||
fluid_ostream_printf(out, "ladspa_link needs 3 arguments: "
|
||||
"<effect> <port> <buffer or host name>\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (handler->ladspa_plugin_id == -1)
|
||||
CHECK_LADSPA_ENABLED(fx, out);
|
||||
CHECK_LADSPA_INACTIVE(fx, out);
|
||||
|
||||
if (!fluid_ladspa_effect_port_exists(fx, av[0], av[1]))
|
||||
{
|
||||
fluid_ostream_printf(out, "Please choose a plugin with ladspa_plugin first.\n");
|
||||
fluid_ostream_printf(out, "Port '%s' not found on effect '%s'\n", av[1], av[0]);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (FLUID_STRCMP(av[1], "<") == 0)
|
||||
if (!fluid_ladspa_host_port_exists(fx, av[2]) && !fluid_ladspa_buffer_exists(fx, av[2]))
|
||||
{
|
||||
dir = FLUID_LADSPA_INPUT;
|
||||
}
|
||||
else if (FLUID_STRCMP(av[1], ">") == 0)
|
||||
{
|
||||
dir = FLUID_LADSPA_OUTPUT;
|
||||
}
|
||||
else if (FLUID_STRCMP(av[1], "=") == 0)
|
||||
{
|
||||
dir = FLUID_LADSPA_FIXED;
|
||||
}
|
||||
else
|
||||
{
|
||||
fluid_ostream_printf(out, "Invalid direction, please use <, > or =\n");
|
||||
fluid_ostream_printf(out, "Host port or buffer '%s' not found.\n", av[2]);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
/* Check port and node name before trying to connect them by name. This is
|
||||
* redundant, as fluid_ladspa_connect checks them as well, but we do it
|
||||
* here anyway to give the user better feedback in case a port or node
|
||||
* could not be found.
|
||||
*/
|
||||
if (!fluid_ladspa_port_exists(fx, handler->ladspa_plugin_id, av[0]))
|
||||
if (fluid_ladspa_effect_link(fx, av[0], av[1], av[2]) != FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out, "Port '%s' not found.\n", av[0]);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (dir != FLUID_LADSPA_FIXED && !fluid_ladspa_node_exists(fx, av[2]))
|
||||
{
|
||||
fluid_ostream_printf(out, "Node '%s' not found.\n", av[2]);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (fluid_ladspa_connect(fx, handler->ladspa_plugin_id, dir, av[0], av[2]) != FLUID_OK)
|
||||
{
|
||||
fluid_ostream_printf(out, "Failed to connect plugin port.\n");
|
||||
fluid_ostream_printf(out, "Failed to link port\n");
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
|
@ -2285,10 +2289,6 @@ fluid_cmd_handler_t* new_fluid_cmd_handler(fluid_synth_t* synth, fluid_midi_rout
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef LADSPA
|
||||
handler->ladspa_plugin_id = -1;
|
||||
#endif
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,15 +85,14 @@ int fluid_handle_router_par1(void* data, int ac, char** av, fluid_ostream_t out)
|
|||
int fluid_handle_router_par2(void* data, int ac, char** av, fluid_ostream_t out);
|
||||
|
||||
#ifdef LADSPA
|
||||
int fluid_handle_ladspa_plugin(void* data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_port(void* data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_node(void* data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_control(void* data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_control_defaults(void* data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_check(void* data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_start(void* data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_stop(void* data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_reset(void* data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_effect(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_link(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_buffer(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_set(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_check(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_start(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_stop(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
int fluid_handle_ladspa_reset(void *data, int ac, char **av, fluid_ostream_t out);
|
||||
#endif
|
||||
|
||||
fluid_cmd_t* fluid_cmd_copy(fluid_cmd_t* cmd);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,51 +18,19 @@
|
|||
* 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* Author: Markus Nentwig, nentwig@users.sourceforge.net
|
||||
*/
|
||||
|
||||
#ifndef _FLUID_LADSPA_H
|
||||
#define _FLUID_LADSPA_H
|
||||
|
||||
#include "fluid_sys.h"
|
||||
#include "fluidsynth_priv.h"
|
||||
|
||||
#ifdef LADSPA
|
||||
|
||||
typedef enum _fluid_ladspa_dir_t {
|
||||
FLUID_LADSPA_INPUT,
|
||||
FLUID_LADSPA_OUTPUT,
|
||||
FLUID_LADSPA_FIXED
|
||||
|
||||
} fluid_ladspa_dir_t;
|
||||
|
||||
typedef struct _fluid_ladspa_fx_t fluid_ladspa_fx_t;
|
||||
|
||||
|
||||
fluid_ladspa_fx_t *new_fluid_ladspa_fx(fluid_real_t sample_rate, int audio_groups, int effects_channels, int audio_channels, int buffer_size);
|
||||
fluid_ladspa_fx_t *new_fluid_ladspa_fx(fluid_real_t sample_rate, int buffer_size);
|
||||
void delete_fluid_ladspa_fx(fluid_ladspa_fx_t *fx);
|
||||
|
||||
int fluid_ladspa_set_sample_rate(fluid_ladspa_fx_t *fx, fluid_real_t sample_rate);
|
||||
|
||||
int fluid_ladspa_is_active(fluid_ladspa_fx_t *fx);
|
||||
int fluid_ladspa_activate(fluid_ladspa_fx_t *fx);
|
||||
int fluid_ladspa_deactivate(fluid_ladspa_fx_t *fx);
|
||||
int fluid_ladspa_reset(fluid_ladspa_fx_t *fx);
|
||||
void fluid_ladspa_run(fluid_ladspa_fx_t *fx, int block_count, int block_size);
|
||||
|
||||
void fluid_ladspa_run(fluid_ladspa_fx_t *fx, fluid_real_t *left_buf[], fluid_real_t *right_buf[],
|
||||
fluid_real_t *fx_left_buf[], fluid_real_t *fx_right_buf[], int block_count, int block_size);
|
||||
int fluid_ladspa_add_host_ports(fluid_ladspa_fx_t *fx, const char *prefix,
|
||||
int num_buffers, fluid_real_t *buffers[]);
|
||||
|
||||
int fluid_ladspa_add_plugin(fluid_ladspa_fx_t *fx, const char *lib_name, const char *plugin_name);
|
||||
int fluid_ladspa_port_exists(fluid_ladspa_fx_t *fx, int plugin_id, const char *name);
|
||||
|
||||
int fluid_ladspa_add_audio_node(fluid_ladspa_fx_t *fx, const char *name);
|
||||
int fluid_ladspa_add_control_node(fluid_ladspa_fx_t *fx, const char *name, fluid_real_t val);
|
||||
int fluid_ladspa_set_control_node(fluid_ladspa_fx_t *fx, const char *name, fluid_real_t val);
|
||||
int fluid_ladspa_node_exists(fluid_ladspa_fx_t *fx, const char *name);
|
||||
|
||||
int fluid_ladspa_connect(fluid_ladspa_fx_t *fx, int plugin_id, fluid_ladspa_dir_t dir,
|
||||
const char *port_name, const char *node_name);
|
||||
int fluid_ladspa_check(fluid_ladspa_fx_t *fx, char *err, int err_size);
|
||||
int fluid_ladspa_control_defaults(fluid_ladspa_fx_t *fx);
|
||||
|
||||
#endif /* LADSPA */
|
||||
#endif /* _FLUID_LADSPA_H */
|
||||
|
|
|
@ -49,9 +49,6 @@
|
|||
/* whether or not we are supporting lash */
|
||||
#cmakedefine HAVE_LASH @HAVE_LASH@
|
||||
|
||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||
#cmakedefine HAVE_LIBDL @HAVE_LIBDL@
|
||||
|
||||
/* Define to 1 if you have the `MidiShare' library (-lMidiShare). */
|
||||
#cmakedefine HAVE_LIBMIDISHARE @HAVE_LIBMIDISHARE@
|
||||
|
||||
|
|
|
@ -141,12 +141,10 @@ fluid_rvoice_mixer_process_fx(fluid_rvoice_mixer_t* mixer)
|
|||
}
|
||||
|
||||
#ifdef LADSPA
|
||||
/* Run the signal through the LADSPA Fx unit */
|
||||
/* Run the signal through the LADSPA Fx unit. The buffers have already been
|
||||
* set up in fluid_rvoice_mixer_set_ladspa. */
|
||||
if (mixer->ladspa_fx) {
|
||||
fluid_ladspa_run(mixer->ladspa_fx,
|
||||
mixer->buffers.left_buf, mixer->buffers.right_buf,
|
||||
mixer->buffers.fx_left_buf, mixer->buffers.fx_right_buf,
|
||||
mixer->current_blockcount, FLUID_BUFSIZE);
|
||||
fluid_ladspa_run(mixer->ladspa_fx, mixer->current_blockcount, FLUID_BUFSIZE);
|
||||
fluid_check_fpe("LADSPA");
|
||||
}
|
||||
#endif
|
||||
|
@ -203,15 +201,21 @@ fluid_mix_one(fluid_rvoice_t* rvoice, fluid_real_t** bufs, unsigned int bufcount
|
|||
static FLUID_INLINE int
|
||||
fluid_mixer_buffers_prepare(fluid_mixer_buffers_t* buffers, fluid_real_t** outbufs)
|
||||
{
|
||||
fluid_real_t* reverb_buf, *chorus_buf;
|
||||
fluid_real_t *reverb_buf, *chorus_buf;
|
||||
int i;
|
||||
int with_reverb = buffers->mixer->fx.with_reverb;
|
||||
int with_chorus = buffers->mixer->fx.with_chorus;
|
||||
|
||||
/* Set up the reverb / chorus buffers only, when the effect is
|
||||
* enabled on synth level. Nonexisting buffers are detected in the
|
||||
* DSP loop. Not sending the reverb / chorus signal saves some time
|
||||
* in that case. */
|
||||
reverb_buf = buffers->mixer->fx.with_reverb ? buffers->fx_left_buf[SYNTH_REVERB_CHANNEL] : NULL;
|
||||
chorus_buf = buffers->mixer->fx.with_chorus ? buffers->fx_left_buf[SYNTH_CHORUS_CHANNEL] : NULL;
|
||||
/* Set up the reverb and chorus buffers only when the effect is enabled or
|
||||
* when LADSPA is active. Nonexisting buffers are detected in the DSP loop.
|
||||
* Not sending the effect signals saves some time in that case. */
|
||||
#ifdef LADSPA
|
||||
int with_ladspa = (buffers->mixer->ladspa_fx != NULL);
|
||||
with_reverb = (with_reverb | with_ladspa);
|
||||
with_chorus = (with_chorus | with_ladspa);
|
||||
#endif
|
||||
reverb_buf = (with_reverb) ? buffers->fx_left_buf[SYNTH_REVERB_CHANNEL] : NULL;
|
||||
chorus_buf = (with_chorus) ? buffers->fx_left_buf[SYNTH_CHORUS_CHANNEL] : NULL;
|
||||
outbufs[buffers->buf_count*2 + SYNTH_REVERB_CHANNEL] = reverb_buf;
|
||||
outbufs[buffers->buf_count*2 + SYNTH_CHORUS_CHANNEL] = chorus_buf;
|
||||
|
||||
|
@ -627,9 +631,29 @@ void delete_fluid_rvoice_mixer(fluid_rvoice_mixer_t* mixer)
|
|||
|
||||
|
||||
#ifdef LADSPA
|
||||
void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer, fluid_ladspa_fx_t *ladspa_fx)
|
||||
/**
|
||||
* Set a LADSPS fx instance to be used by the mixer and assign the mixer buffers
|
||||
* as LADSPA host buffers with sensible names */
|
||||
void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer,
|
||||
fluid_ladspa_fx_t *ladspa_fx, int audio_groups)
|
||||
{
|
||||
mixer->ladspa_fx = ladspa_fx;
|
||||
mixer->ladspa_fx = ladspa_fx;
|
||||
if (ladspa_fx == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fluid_ladspa_add_host_ports(ladspa_fx, "Main:L", audio_groups,
|
||||
mixer->buffers.left_buf);
|
||||
|
||||
fluid_ladspa_add_host_ports(ladspa_fx, "Main:R", audio_groups,
|
||||
mixer->buffers.right_buf);
|
||||
|
||||
fluid_ladspa_add_host_ports(ladspa_fx, "Reverb:Send", 1,
|
||||
&mixer->buffers.fx_left_buf[SYNTH_REVERB_CHANNEL]);
|
||||
|
||||
fluid_ladspa_add_host_ports(ladspa_fx, "Chorus:Send", 1,
|
||||
&mixer->buffers.fx_left_buf[SYNTH_REVERB_CHANNEL]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -69,7 +69,8 @@ void fluid_rvoice_mixer_set_threads(fluid_rvoice_mixer_t* mixer, int thread_coun
|
|||
int prio_level);
|
||||
|
||||
#ifdef LADSPA
|
||||
void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer, fluid_ladspa_fx_t* ladspa_fx);
|
||||
void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t* mixer,
|
||||
fluid_ladspa_fx_t *ladspa_fx, int audio_groups);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -711,14 +711,14 @@ new_fluid_synth(fluid_settings_t *settings)
|
|||
fluid_settings_getint(settings, "synth.ladspa.active", &with_ladspa);
|
||||
if (with_ladspa) {
|
||||
#ifdef LADSPA
|
||||
synth->ladspa_fx = new_fluid_ladspa_fx(synth->sample_rate, synth->audio_groups,
|
||||
synth->effects_channels, synth->audio_channels,
|
||||
synth->ladspa_fx = new_fluid_ladspa_fx(synth->sample_rate,
|
||||
FLUID_MIXER_MAX_BUFFERS_DEFAULT * FLUID_BUFSIZE);
|
||||
if(synth->ladspa_fx == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
goto error_recovery;
|
||||
}
|
||||
fluid_rvoice_mixer_set_ladspa(synth->eventhandler->mixer, synth->ladspa_fx);
|
||||
fluid_rvoice_mixer_set_ladspa(synth->eventhandler->mixer, synth->ladspa_fx,
|
||||
synth->audio_groups);
|
||||
#else /* LADSPA */
|
||||
FLUID_LOG(FLUID_WARN, "FluidSynth has not been compiled with LADSPA support");
|
||||
#endif /* LADSPA */
|
||||
|
@ -5288,3 +5288,16 @@ int fluid_synth_set_channel_type(fluid_synth_t* synth, int chan, int type)
|
|||
|
||||
FLUID_API_RETURN(FLUID_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the LADSPA effects instance used by FluidSynth
|
||||
*
|
||||
* @param synth FluidSynth instance
|
||||
* @return pointer to LADSPA fx or NULL if compiled without LADSPA support or LADSPA is not active
|
||||
*/
|
||||
fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth)
|
||||
{
|
||||
fluid_return_val_if_fail(synth != NULL, NULL);
|
||||
|
||||
return synth->ladspa_fx;
|
||||
}
|
||||
|
|
|
@ -169,9 +169,7 @@ struct _fluid_synth_t
|
|||
|
||||
fluid_mod_t* default_mod; /**< the (dynamic) list of default modulators */
|
||||
|
||||
#ifdef LADSPA
|
||||
fluid_ladspa_fx_t* ladspa_fx; /**< Effects unit for LADSPA support */
|
||||
#endif
|
||||
fluid_ladspa_fx_t* ladspa_fx; /**< Effects unit for LADSPA support */
|
||||
};
|
||||
|
||||
fluid_preset_t* fluid_synth_find_preset(fluid_synth_t* synth,
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#include <glib.h>
|
||||
#include "fluidsynth_priv.h"
|
||||
|
||||
#ifdef LADSPA
|
||||
#include <gmodule.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Macro used for safely accessing a message from a GError and using a default
|
||||
|
@ -320,6 +323,19 @@ void delete_fluid_thread(fluid_thread_t* thread);
|
|||
void fluid_thread_self_set_prio (int prio_level);
|
||||
int fluid_thread_join(fluid_thread_t* thread);
|
||||
|
||||
/* Dynamic Module Loading, currently only used by LADSPA subsystem */
|
||||
#ifdef LADSPA
|
||||
|
||||
typedef GModule fluid_module_t;
|
||||
|
||||
#define fluid_module_open(_name) g_module_open((_name), G_MODULE_BIND_LOCAL)
|
||||
#define fluid_module_close(_mod) g_module_close(_mod)
|
||||
#define fluid_module_error() g_module_error()
|
||||
#define fluid_module_name(_mod) g_module_name(_mod)
|
||||
#define fluid_module_symbol(_mod, _name, _ptr) g_module_symbol((_mod), (_name), (_ptr))
|
||||
|
||||
#endif /* LADSPA */
|
||||
|
||||
/* Sockets and I/O */
|
||||
|
||||
fluid_istream_t fluid_get_stdin (void);
|
||||
|
|
|
@ -275,7 +275,7 @@ do { strncpy(_dst,_src,_n); \
|
|||
#endif
|
||||
|
||||
#if defined(WIN32) && !defined(MINGW32)
|
||||
#define FLUID_STRNCASECMP _strincmp
|
||||
#define FLUID_STRNCASECMP _strnicmp
|
||||
#else
|
||||
#define FLUID_STRNCASECMP strncasecmp
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue