mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-12-01 00:21:14 +00:00
Imported first version of devdoc
This commit is contained in:
parent
e6f423d593
commit
8ec42b17b7
1 changed files with 502 additions and 0 deletions
502
fluidsynth/doc/fluidsynth-v10-devdoc.xml
Normal file
502
fluidsynth/doc/fluidsynth-v10-devdoc.xml
Normal file
|
@ -0,0 +1,502 @@
|
|||
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
|
||||
<article>
|
||||
<articleinfo>
|
||||
<title>
|
||||
FluidSynth
|
||||
Developer Documentation
|
||||
</title>
|
||||
|
||||
<author>
|
||||
<firstname>Peter</firstname>
|
||||
<surname>Hanappe</surname>
|
||||
<!-- affiliation>
|
||||
<address><email>peter-REMOVE-THIS-@hanappe.com</email></address>
|
||||
</affiliation -->
|
||||
</author>
|
||||
|
||||
<copyright>
|
||||
<year>2003</year>
|
||||
<holder>Copyright Peter Hanappe</holder>
|
||||
</copyright>
|
||||
|
||||
<abstract>
|
||||
|
||||
<para>FluidSynth is a software synthesizer based on the
|
||||
SoundFont 2 specifications. The synthesizer is available as a
|
||||
shared object that can easily be reused in any application that
|
||||
wants to use wavetable synthesis. This documents explains the
|
||||
nitty-gritty.</para>
|
||||
|
||||
</abstract>
|
||||
</articleinfo>
|
||||
|
||||
<sect1>
|
||||
<title>Using the synthesizer as a plugin</title>
|
||||
|
||||
<para>FluidSynth can easily be embedded in an application.</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Creating and changing the settings</title>
|
||||
|
||||
<para>
|
||||
Before you can use the synthesizer, you have to create a settings
|
||||
object. The settings objects is used by all components of the
|
||||
FluidSynth library. It gives a unified API to set the parameters
|
||||
of the audio drivers, the midi drivers, the synthesizer,
|
||||
andsoforth. A number of default settings are defined by the
|
||||
current implementation. In future versions the use of the settings
|
||||
will probably be generalized and used also for LADSPA plugins.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All settings have a name that follows the "dotted-name"
|
||||
notation. For example, "synth.polyphony" refers to the number of
|
||||
voices (polyphony) preallocated by the synthesizer. The settings
|
||||
also have a type. There are currently three types: strings,
|
||||
numbers (double floats), and integers. You can change the values
|
||||
of a setting using the <function>fluid_settings_setstr</function>,
|
||||
<function>fluid_settings_setnum</function>, and
|
||||
<function>fluid_synth_setint</function> functions. For example:
|
||||
|
||||
<programlisting>
|
||||
void init()
|
||||
{
|
||||
fluid_settings_t* settings;
|
||||
|
||||
settings = new_fluid_settings();
|
||||
fluid_synth_setint(settings, "synth.polyphony", 128);
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The API contains the functions to query the type, the current
|
||||
value, the default value, the range and and the "hints" of a
|
||||
setting. The range is the minumum and maximum value of the
|
||||
setting. The hints gives additional information about a
|
||||
setting. For example, whether a string represents a filename. Or
|
||||
whether a number should be interpreted on on a logarithmic
|
||||
scale. Check the API documentation for a description of all
|
||||
functions.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Creating the synthesizer</title>
|
||||
|
||||
<para>
|
||||
To create the synthesizer, you pass it the settings object, like
|
||||
in the following example:
|
||||
|
||||
<programlisting>
|
||||
void init()
|
||||
{
|
||||
fluid_settings_t* settings;
|
||||
fluid_synth_t* synth;
|
||||
|
||||
settings = new_fluid_settings();
|
||||
|
||||
/* Set the settings, if necessary */
|
||||
|
||||
synth = new_fluid_synth(settings);
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The default settings should be fine for most uses. A detailed
|
||||
description of all the settings used by the synthesizer described
|
||||
below.
|
||||
</para>
|
||||
|
||||
|
||||
<sect1>
|
||||
<title>Creating the audio driver</title>
|
||||
|
||||
<para>
|
||||
The synthesizer itself does not send any audio to the audio
|
||||
output. This allows application developers who want to integrate
|
||||
the synthesizer in their application to manage the audio output
|
||||
themselves. The following sections describes the use of the
|
||||
synthesizer without an audio driver in more detail.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Creating the audio driver is straightforward: set the appropriate
|
||||
settings and create the driver object. Because the FluidSynth has
|
||||
support for several audio libraries, you may want to change what
|
||||
audio subsystem you want to use. Currently the following audio
|
||||
systems are supported:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Linux: OSS, ALSA, Jack, PortAudio (not tested)</para></listitem>
|
||||
<listitem><para>MacOS Classic: SoundManager, PortAudio</para></listitem>
|
||||
<listitem><para>MacOS X: PortAudio, CoreAudio (experimental)</para></listitem>
|
||||
<listitem><para>Windows: DirectSound, PortAudio (not tested)</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The default audio driver depends on the settings with which
|
||||
FluidSynth was compiled. You can get the default driver with
|
||||
fluid_settings_getstr_default(settings, "audio.driver"). To get
|
||||
the list of available drivers use the
|
||||
<function>fluid_settings_foreach_option</function>
|
||||
function. Finally, you can set the driver with
|
||||
<function>fluid_settings_setstr</function>. In most cases, the
|
||||
default driver should work out of the box. </para>
|
||||
|
||||
<para>
|
||||
Additional options that define the audio quality and latency are
|
||||
"audio.sample-format", "audio.period-size", and
|
||||
"audio.periods". The details are described later.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You create the audio driver with the
|
||||
<function>new_fluid_audio_driver</function> function. This
|
||||
function takes the settings and synthesizer object as
|
||||
arguments. For example:
|
||||
|
||||
<programlisting>
|
||||
void init()
|
||||
{
|
||||
fluid_settings_t* settings;
|
||||
fluid_synth_t* synth;
|
||||
fluid_audio_driver_t* adriver;
|
||||
|
||||
settings = new_fluid_settings();
|
||||
|
||||
/* Set the synthesizer settings, if necessary */
|
||||
|
||||
synth = new_fluid_synth(settings);
|
||||
|
||||
fluid_settings_setstr(settings, "audio.driver", "jack");
|
||||
adriver = new_fluid_audio_driver(settings, synth);
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As soon as the audio driver is created, it will start playing. The
|
||||
audio driver creates a separate thread that runs in real-time mode
|
||||
(is the application has sufficient privileges) and call the
|
||||
synthesizer object to generate the audio.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Using the synthesizer without an audio driver</title>
|
||||
|
||||
<para>
|
||||
It is possible to use the synthesizer object without creating an
|
||||
audio driver. This is desirable if the application using
|
||||
FluidSynth manages the audio output itself. The synthesizer has
|
||||
several API functions that can be used to obtain the audio output:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<function>fluid_synth_write_s16</function> fills two buffers (left
|
||||
and right channel) with samples coded as signed 16 bits (the
|
||||
endian-ness is machine
|
||||
dependent). <function>fluid_synth_write_float</function> fills a
|
||||
left and right audio buffer with 32 bits floating point
|
||||
samples. For multi channel audio output, the function
|
||||
<function>fluid_synth_nwrite_float</function> has to be used.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The function <function>fluid_synth_process</function> is still
|
||||
experimental and its use is therefore not recommended but it will
|
||||
probably become the generic interface in future versions.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Loading and managing SoundFonts</title>
|
||||
|
||||
<para>
|
||||
Before any sound can be produced, the synthesizer needs a
|
||||
SoundFont. For a discussion on SoundFont please refer to some
|
||||
other, not yet existing, therefore virtual document.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
SoundFonts are loaded with the
|
||||
<function>fluid_synth_sfload</function> function. The function
|
||||
takes the path to a SoundFont file as argument and a boolean to
|
||||
indicate whether the presets of the MIDI channels should be
|
||||
updated after the SoundFont is loaded. More on the preset updates
|
||||
below.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The synthesizer can load any number of SoundFonts. This is an
|
||||
advantage, of course, but there are some issues that you must be
|
||||
aware of. The presets in a SoundFont are identified by their bank
|
||||
and preset number. The MIDI specifications allows the change of a
|
||||
preset on a MIDI channel using the combination of "bank select"
|
||||
and the "program change" messages. An ambiguity arrizes when a
|
||||
preset with a specific bank and preset number is defined in
|
||||
multiple loaded SoundFonts. This is solved by searching the
|
||||
SoundFonts in the inverse order they were loaded, i.e. the lastly
|
||||
loaded SoundFont is searched first for the request preset
|
||||
(identified by bank and preset number) then the on but last loaded
|
||||
SoundFont, and so on until. The first preset found is then
|
||||
used. You can somehow consider the SoundFonts placed on a
|
||||
stack. The SoundFont on top of the stack is inspected first,
|
||||
followed by the SoundFont down on the stack. Newly loaded
|
||||
SoundFonts are always placed on top of the stack. This is how
|
||||
commercial, hardware synthesizers work. The inconvenience is that
|
||||
a preset in a SoundFont at the bottom end of the stack may be
|
||||
masked by a preset in a SoundFont at the top of the stack. Using
|
||||
the standard MIDI messages, bank select and program change, there
|
||||
is no way to select a masked preset. However, FluidSynth has an
|
||||
API function to unambiguously select a preset
|
||||
(<function>fluid_synth_program_select</function>). This function
|
||||
is not invokeable through MIDI messages, though.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <function>fluid_synth_sfload</function> function returns the
|
||||
unique identifier of the loaded SoundFont, or -1 in case of an
|
||||
error. This identifier is used in subsequent management functions:
|
||||
<function>fluid_synth_sfunload</function> removes the SoundFont,
|
||||
<function>fluid_synth_sfreload</function> reloads the
|
||||
SoundFont. When a SoundFont is reloaded, it retains it's ID and
|
||||
position on the SoundFont stack.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Additional API functions are provided to get the number of loaded
|
||||
SoundFonts ot to get a pointer to the SoundFont.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another issue that needs some explanation is the reprogramming of
|
||||
the presets after a SoundFont load or unload. The default behavior
|
||||
of commercial synthesizers is to reset all the preset that are
|
||||
programmed on the MIDI channels when a SoundFont is loaded or
|
||||
unloaded. Consider the case where MIDI channel 1 uses preset (0,
|
||||
0) (the couple indicates the bank and program number). This preset
|
||||
was found in the SoundFont with ID 3, for example. When a new
|
||||
SoundFont is loaded that also contains a preset with bank number 0
|
||||
and program number 0, then the newly loaded preset will be used on
|
||||
channel 1 for future events. This behavior is as if a bank select
|
||||
and program change message is send to all channels after a
|
||||
load/unload using the channel's bank and program number. This may
|
||||
be sometimes confusing or unwanted. A user may not want to loose
|
||||
its preset setup when a new SoundFont is loaded. To avoid the
|
||||
reprogramming of the presets, the third parameter to the
|
||||
<function>fluid_synth_sfload</function> and
|
||||
<function>fluid_synth_sfunload</function> functions should be set
|
||||
to zero.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Sending MIDI events</title>
|
||||
|
||||
<para>
|
||||
Once the synthesizer is up and running and a SoundFont is loaded,
|
||||
most people will want to do something usefull with it. Make noise,
|
||||
for example. The synthesizer aims to be compatible with the MIDI
|
||||
standard, so it accepts almost all MIDI messages (details on the
|
||||
MIDI compatibility elsewhere). The MIDI channel messages can be
|
||||
send using the <function>fluid_synth_noteon</function>,
|
||||
<function>fluid_synth_noteoff</function>,
|
||||
<function>fluid_synth_cc</function>,
|
||||
<function>fluid_synth_pitch_bend</function>,
|
||||
<function>fluid_synth_pitch_wheel_sens</function>, and
|
||||
<function>fluid_synth_program_change</function> functions. For
|
||||
convenience, there's also a
|
||||
<function>fluid_synth_bank_select</function> function (the bank
|
||||
select message is normally sent using a control change message).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following example show a generic graphical button that plays a
|
||||
not when clicked:
|
||||
|
||||
<programlisting>
|
||||
class SoundButton : public SomeButton
|
||||
{
|
||||
public:
|
||||
|
||||
SoundButton() : SomeButton() {
|
||||
if (!_synth) {
|
||||
initSynth();
|
||||
}
|
||||
}
|
||||
|
||||
static void initSynth() {
|
||||
_settings = new_fluid_settings();
|
||||
_synth = new_fluid_synth(_settings);
|
||||
_adriver = new_fluid_audio_driver(_settings, _synth);
|
||||
}
|
||||
|
||||
/* ... */
|
||||
|
||||
virtual int handleMouseDown(int x, int y) {
|
||||
/* Play a note on key 60 with velocity 100 on MIDI channel 0 */
|
||||
fluid_synth_noteon(_synth, 0, 60, 100);
|
||||
}
|
||||
|
||||
virtual int handleMouseUp(int x, int y) {
|
||||
/* Release the note on key 60 */
|
||||
fluid_synth_noteoff(_synth, 0, 60);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
static fluid_settings_t* _settings;
|
||||
static fluid_synth_t* _synth;
|
||||
static fluid_audio_driver_t* _adriver;
|
||||
};
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Advanced control features</title>
|
||||
<para></para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>MIDI tunings</title>
|
||||
<para></para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Multi channel audio output</title>
|
||||
<para></para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Overview of all settings</title>
|
||||
|
||||
<para>
|
||||
The settings for the synthesizer
|
||||
</para>
|
||||
|
||||
<para>
|
||||
synth.verbose: type string, default "no"
|
||||
|
||||
When set to "yes" the synthesizer will print out information about the
|
||||
received MIDI events to the stdout. This can be helpful for
|
||||
debugging. This setting can not be changed after the synthesizer has
|
||||
started.
|
||||
|
||||
synth.dump: type string, default "no"
|
||||
|
||||
???
|
||||
|
||||
|
||||
synth.reverb.active: type string, default "yes"
|
||||
|
||||
When set to "yes" the reverb effects module is activated. Otherwise,
|
||||
no reverb will be added to the output signal. Note that when the
|
||||
reverb module is active, the amount of signal send to the reverb
|
||||
module depends on the "reverb send" generator defined in the
|
||||
SoundFont.
|
||||
|
||||
synth.chorus.active: type string, default "yes"
|
||||
|
||||
When set to "yes" the chorus effects module is activated. Otherwise,
|
||||
no chorus will be added to the output signal. Note that when the
|
||||
reverb module is active, the amount of signal send to the chorus
|
||||
module depends on the "chorus send" generator defined in the
|
||||
SoundFont.
|
||||
|
||||
|
||||
synth.ladspa.active: type string, default no
|
||||
|
||||
When set to "yes" the LADSPA subsystem will be called. This subsystem
|
||||
allows to load and interconnect LADSPA plugins. The output of the
|
||||
synthesizer is processed by the LADSPA subsystem. Note that the
|
||||
synthesizer has to be compiled with LADSPA support. More information
|
||||
about the LADSPA subsystem later.
|
||||
|
||||
|
||||
synth.polyphony: type integer, default 256, min. 16, max. 4096
|
||||
|
||||
The polyphony defines how many voices can be played in parallel. The
|
||||
number of voices is not necessarily equivalent to the number of notes
|
||||
played simultaniously. Indeed, when a note is struck on a specific
|
||||
MIDI channel, the preset on that channel may created several voices,
|
||||
for example, one for the left audio channel and one for the right
|
||||
audio channels. The number of voices activated depends on the number
|
||||
of instrument zones that fall in the correspond to the velocity and
|
||||
key of the played note.
|
||||
|
||||
synth.midi-channels: type integer, default 16, min. 16, max. 256
|
||||
|
||||
This setting defines the number of MIDI channels of the
|
||||
synthesizer. The MIDI standard defines 16 channels, so most hardware
|
||||
keyboards are limited to 16. If you plan to use the synthesizer as a
|
||||
plugin in an application, it might be interesting to set the number of
|
||||
channels to a larger value. In this case you can program a greater
|
||||
number of presets.
|
||||
|
||||
synth.gain: type number, default 0.2, min. 0.0, max. 10.0
|
||||
|
||||
The gain is applied to the final or master output of the
|
||||
synthesizer. It is set to a low value by default to avoid the
|
||||
saturation of the output when random MIDI files are played.
|
||||
|
||||
synth.audio-channels: type integer, default 1, min. 1, max. 128
|
||||
|
||||
By default, the synthesizer outputs a single stereo signal. Using this
|
||||
option, the synthesizer can output multichannel audio.
|
||||
|
||||
synth.audio-groups", 1, 1, 128, 0, NULL, NULL);
|
||||
synth.effects-channels", 2, 2, 2, 0, NULL, NULL);
|
||||
synth.sample-rate", 44100.0f, 22050.0f, 96000.0f,
|
||||
|
||||
|
||||
The settings for the audio driver
|
||||
|
||||
audio.sample-format: type string, default "16bits", options ("16bits", "float")
|
||||
|
||||
audio.period-size: type integer, default 512, min. 64, max. 8192
|
||||
|
||||
audio.periods: type integer, default 8, min. 2, max. 64
|
||||
|
||||
audio.output-channels: type integer, default 2, min. 2, max. 32
|
||||
|
||||
audio.input-channels: type integer, default 0, min. 0, max. 2
|
||||
|
||||
audio.driver: type string, default platform and compilation dependent
|
||||
|
||||
|
||||
|
||||
SoundFont:
|
||||
|
||||
Preset:
|
||||
|
||||
Preset Zone:
|
||||
|
||||
Instrument:
|
||||
|
||||
Instrument Zone:
|
||||
|
||||
Program:
|
||||
|
||||
MIDI Channel:
|
||||
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
</article>
|
Loading…
Reference in a new issue