2003-06-12 11:10:51 +00:00
|
|
|
<?xml version="1.0" encoding="koi8-r"?>
|
|
|
|
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
|
|
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
|
|
|
|
2004-03-19 11:56:31 +00:00
|
|
|
<!--
|
|
|
|
|
|
|
|
I am currently using 'xsltproc' to generate the HTML files. I use a
|
|
|
|
stylesheet contained in the docbook-xsl-stylesheets Debian package:
|
|
|
|
|
|
|
|
$ xsltproc /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/xtchunk.xsl \
|
|
|
|
fluidsynth-v10-devdoc.xml
|
|
|
|
|
|
|
|
An alternative would be to use the Linux Documentation Project's
|
|
|
|
style sheets. See
|
|
|
|
http://www.tldp.org/LDP/LDP-Author-Guide/usingldpxsl.html.
|
|
|
|
|
|
|
|
Suggestions are welcome!
|
|
|
|
|
|
|
|
[PH]
|
|
|
|
|
|
|
|
-->
|
|
|
|
|
2003-04-11 21:47:12 +00:00
|
|
|
<article>
|
|
|
|
<articleinfo>
|
|
|
|
<title>
|
2003-06-12 11:10:51 +00:00
|
|
|
FluidSynth 1.0 — Developer Documentation
|
2003-04-11 21:47:12 +00:00
|
|
|
</title>
|
|
|
|
|
|
|
|
<author>
|
|
|
|
<firstname>Peter</firstname>
|
|
|
|
<surname>Hanappe</surname>
|
|
|
|
</author>
|
|
|
|
|
2004-03-19 11:56:31 +00:00
|
|
|
<revhistory>
|
|
|
|
<revision>
|
|
|
|
<revnumber>1.0</revnumber>
|
|
|
|
<date>2003-12-11</date>
|
|
|
|
<authorinitials>hanappe</authorinitials>
|
|
|
|
<revremark>First attempt.</revremark>
|
|
|
|
</revision>
|
|
|
|
</revhistory>
|
|
|
|
|
2003-04-11 21:47:12 +00:00
|
|
|
<copyright>
|
|
|
|
<year>2003</year>
|
|
|
|
<holder>Copyright Peter Hanappe</holder>
|
|
|
|
</copyright>
|
|
|
|
|
2004-03-19 11:56:31 +00:00
|
|
|
<legalnotice>
|
|
|
|
<para>All the source code examples in this document are in the
|
|
|
|
public domain; you can use them as you please. This document is
|
|
|
|
licensed under the Creative Commons Attribution License. To view
|
|
|
|
a copy of this license, visit
|
|
|
|
http://creativecommons.org/licenses/by/1.0/ or send a letter to
|
|
|
|
Creative Commons, 559 Nathan Abbott Way, Stanford, California
|
|
|
|
94305, USA. The FluidSynth library is distributed under the GNU
|
|
|
|
Library General Public License. A copy of the GNU Library
|
|
|
|
General Public License is contained in the FluidSynth package;
|
|
|
|
if not, write to the Free Foundation, Inc., 59 Temple Place,
|
|
|
|
Suite 330, Boston, MA 02111-1307 USA.</para> </legalnotice>
|
|
|
|
|
|
|
|
<keywordset>
|
|
|
|
<keyword>FluidSynth</keyword>
|
|
|
|
<keyword>software</keyword>
|
|
|
|
<keyword>synthesizer</keyword>
|
|
|
|
<keyword>SoundFont</keyword>
|
|
|
|
<keyword>Linux</keyword>
|
|
|
|
<keyword>audio</keyword>
|
|
|
|
<keyword>development</keyword>
|
|
|
|
<keyword>documentation</keyword>
|
|
|
|
<keyword>HOWTO</keyword>
|
|
|
|
</keywordset>
|
|
|
|
|
2003-04-11 21:47:12 +00:00
|
|
|
<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
|
2003-04-13 21:01:40 +00:00
|
|
|
basic usage of FluidSynth. Some of the more advanced features
|
|
|
|
are not yet discussed but will be added in future
|
|
|
|
versions.</para>
|
2003-04-11 21:47:12 +00:00
|
|
|
|
|
|
|
</abstract>
|
2003-04-13 21:01:40 +00:00
|
|
|
</articleinfo>
|
2003-04-11 21:47:12 +00:00
|
|
|
|
|
|
|
<sect1>
|
2004-03-19 11:56:31 +00:00
|
|
|
<title>Disclaimer</title>
|
|
|
|
|
|
|
|
<para>This documentation, in its current version, is probably
|
|
|
|
outdated and most certainly incomplete. As always, the source code
|
|
|
|
is the final reference.</para>
|
|
|
|
|
|
|
|
<para>SoundFont(R) is a registered trademark of E-mu Systems, Inc.</para>
|
|
|
|
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1>
|
|
|
|
<title>Introduction</title>
|
2003-04-11 21:47:12 +00:00
|
|
|
|
2003-04-13 21:01:40 +00:00
|
|
|
<para>FluidSynth can easily be embedded in an application. It has
|
|
|
|
a main header file, fluidsynth.h, and one dynamically linkable
|
|
|
|
library. FluidSynth runs on Linux, MacOS 9, MacOS X, and the Win32
|
|
|
|
platforms. It has audio and midi drivers for all mentioned
|
|
|
|
platforms but you can use it with your own drivers if your
|
2004-03-19 11:56:31 +00:00
|
|
|
application already handles audio and MIDI input/output. This
|
|
|
|
document explains the basic usage of FluidSynth and provides
|
|
|
|
examples that you can reuse. </para>
|
2003-04-13 21:01:40 +00:00
|
|
|
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
|
2003-04-11 21:47:12 +00:00
|
|
|
<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
|
2003-04-13 21:01:40 +00:00
|
|
|
current implementation. In future versions, the use of the
|
|
|
|
settings will probably be generalized.</para>
|
2003-04-11 21:47:12 +00:00
|
|
|
|
|
|
|
<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
|
2011-12-18 04:44:14 +00:00
|
|
|
<function>fluid_settings_setint</function> functions. For example:
|
2003-04-11 21:47:12 +00:00
|
|
|
|
|
|
|
<programlisting>
|
2003-04-13 21:01:40 +00:00
|
|
|
#include <fluidsynth.h>
|
|
|
|
|
|
|
|
int main(int argc, char** argv)
|
2003-04-11 21:47:12 +00:00
|
|
|
{
|
2003-04-13 21:01:40 +00:00
|
|
|
fluid_settings_t* settings = new_fluid_settings();
|
|
|
|
|
2011-12-18 04:44:14 +00:00
|
|
|
fluid_settings_setint(settings, "synth.polyphony", 128);
|
2003-04-13 21:01:40 +00:00
|
|
|
|
|
|
|
delete_fluid_settings(settings);
|
|
|
|
return 0;
|
2003-04-11 21:47:12 +00:00
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The API contains the functions to query the type, the current
|
2003-04-13 21:01:40 +00:00
|
|
|
value, the default value, the range and the "hints" of a
|
2003-04-11 21:47:12 +00:00
|
|
|
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>
|
2003-04-13 21:01:40 +00:00
|
|
|
To create the synthesizer, you pass it the settings object, as
|
2003-04-11 21:47:12 +00:00
|
|
|
in the following example:
|
|
|
|
|
|
|
|
<programlisting>
|
2003-04-13 21:01:40 +00:00
|
|
|
#include <fluidsynth.h>
|
|
|
|
|
|
|
|
int main(int argc, char** argv)
|
2003-04-11 21:47:12 +00:00
|
|
|
{
|
|
|
|
fluid_settings_t* settings;
|
|
|
|
fluid_synth_t* synth;
|
2003-04-13 21:01:40 +00:00
|
|
|
|
|
|
|
fluid_settings_t* settings = new_fluid_settings();
|
2003-04-11 21:47:12 +00:00
|
|
|
|
|
|
|
synth = new_fluid_synth(settings);
|
2003-04-13 21:01:40 +00:00
|
|
|
|
|
|
|
/* Do useful things here */
|
|
|
|
|
|
|
|
delete_fluid_synth(synth);
|
|
|
|
delete_fluid_settings(settings);
|
|
|
|
return 0;
|
2003-04-11 21:47:12 +00:00
|
|
|
}
|
|
|
|
</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.
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<table frame="all"><title>Synthesizer settings</title>
|
|
|
|
<tgroup cols="3" colsep="0" rowsep="0" align="left">
|
2003-04-13 21:01:40 +00:00
|
|
|
<tbody>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.gain</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>number</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>0.2</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Min-Max</entry>
|
|
|
|
<entry>0.0-10.0</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>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.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.sample-rate</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>number</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>44100</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Min-Max</entry>
|
|
|
|
<entry>22050-96000</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>The sample rate of the audio generated by the synthesizer.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.polyphony</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>integer</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>256</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Min-Max</entry>
|
|
|
|
<entry>16-4096</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>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.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.midi-channels</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>integer</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>16</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Min-Max</entry>
|
|
|
|
<entry>16-256</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>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.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.reverb.active</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>string</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>"yes"</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>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.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.chorus.active</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>string</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>"yes"</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>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.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.ladspa.active</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>string</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>"no"</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>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.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.audio-groups</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>integer</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>1</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Min-Max</entry>
|
|
|
|
<entry>1-128</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>By default, the synthesizer outputs a single stereo signal. Using this
|
|
|
|
option, the synthesizer can output multichannel audio.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.effects-channels</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>integer</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>2</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Min-Max</entry>
|
|
|
|
<entry>2-2</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry></entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.verbose</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>string</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>"no"</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
|
|
|
|
<entry>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.</entry>
|
|
|
|
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>synth.dump</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>string</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>"no"</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry></entry>
|
|
|
|
</row>
|
|
|
|
|
|
|
|
</tbody>
|
|
|
|
</tgroup>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
</para>
|
2003-06-12 11:10:51 +00:00
|
|
|
</sect1>
|
2003-04-11 21:47:12 +00:00
|
|
|
|
|
|
|
<sect1>
|
|
|
|
<title>Creating the audio driver</title>
|
|
|
|
|
|
|
|
<para>
|
2003-04-13 21:01:40 +00:00
|
|
|
The synthesizer itself does not write any audio to the audio
|
|
|
|
output. This allows application developers to manage the audio
|
|
|
|
output themselves if they wish. The next section describes the use
|
|
|
|
of the synthesizer without an audio driver in more detail.
|
2003-04-11 21:47:12 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Creating the audio driver is straightforward: set the appropriate
|
|
|
|
settings and create the driver object. Because the FluidSynth has
|
2003-04-13 21:01:40 +00:00
|
|
|
support for several audio systems, you may want to change which
|
|
|
|
one you want to use. The list below shows theaudio systems that
|
|
|
|
are currently supported. It displays the name, as used by the
|
|
|
|
fluidsynth library, and a description. </para>
|
2003-04-11 21:47:12 +00:00
|
|
|
|
|
|
|
<para>
|
|
|
|
<itemizedlist>
|
2003-04-13 21:01:40 +00:00
|
|
|
<listitem><para>alsa: Advanced Linux Sound Architecture</para></listitem>
|
|
|
|
<listitem><para>oss: Open Sound System (Linux)</para></listitem>
|
|
|
|
<listitem><para>jack: JACK Audio Connection Kit (Linux, Mac OS X)</para></listitem>
|
|
|
|
<listitem><para>portaudio: Portaudio Library (MacOS 9 & X, Windows, Linux)</para></listitem>
|
|
|
|
<listitem><para>sndmgr: Apple SoundManager (Mac OS Classic)</para></listitem>
|
|
|
|
<listitem><para>coreaudio: Apple CoreAudio (MacOS X, experimental)</para></listitem>
|
|
|
|
<listitem><para>dsound: Microsoft DirectSound (Windows)</para></listitem>
|
2003-04-11 21:47:12 +00:00
|
|
|
</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>
|
|
|
|
|
2003-04-13 21:01:40 +00:00
|
|
|
|
|
|
|
<para>
|
|
|
|
There are a number of general audio driver settings. The
|
|
|
|
audio.driver settings defines the audio subsystem that will be
|
|
|
|
used. The audio.periods and audio.period-size settings define the
|
|
|
|
latency and robustness against scheduling delays. There are
|
|
|
|
additional settings for the audio subsystems used. They will be
|
|
|
|
documented later.
|
|
|
|
</para>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<table frame="all"><title>General audio driver settings</title>
|
|
|
|
<tgroup cols="3" align="left" colsep="0" rowsep="0">
|
2003-04-13 21:01:40 +00:00
|
|
|
<tbody>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>audio.driver</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>string</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>alsa (Linux), dsound (Windows), sndman (MacOS9), coreaudio (MacOS X)</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Options</entry>
|
|
|
|
<entry>alsa, oss, jack, dsound, sndman, coreaudio, portaudio</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>The audio system to be used.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>audio.periods</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>int</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>16 (Linux, MacOS X), 8 (Windows)</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Min-Max</entry>
|
|
|
|
<entry>2-64</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>The number of the audio buffers used by the driver. This
|
|
|
|
number of buffers, multiplied by the buffer size (see setting
|
|
|
|
audio.period-size), determines the maximum latency of the audio
|
|
|
|
driver.</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>audio.period-size</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>int</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>64 (Linux, MacOS X), 512 (Windows)</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Min-Max</entry>
|
|
|
|
<entry>64-8192</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>The size of the audio buffers (in frames).</entry>
|
|
|
|
</row>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<!-- separation line -->
|
2003-04-13 21:01:40 +00:00
|
|
|
<row>
|
|
|
|
<entry>audio.sample-format</entry>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>string</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Default</entry>
|
|
|
|
<entry>"16bits"</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Options</entry>
|
|
|
|
<entry>"16bits", "float"</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry></entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
|
|
|
|
<entry>The format of the audio samples. This is currently only an
|
|
|
|
indication; the audio driver may ignore this setting if it can't
|
|
|
|
handle the specified format.</entry>
|
|
|
|
|
|
|
|
</row>
|
|
|
|
|
|
|
|
</tbody>
|
|
|
|
</tgroup>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
2003-04-11 21:47:12 +00:00
|
|
|
</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>
|
2003-04-13 21:01:40 +00:00
|
|
|
<title>Advanced features, not yet documented</title>
|
|
|
|
|
2003-06-12 11:10:51 +00:00
|
|
|
<itemizedlist mark="opencircle">
|
2003-04-13 21:01:40 +00:00
|
|
|
<listitem><para>Accessing low-level voice parameters</para></listitem>
|
|
|
|
<listitem><para>Reverb settings</para></listitem>
|
|
|
|
<listitem><para>Chorus settings</para></listitem>
|
|
|
|
<listitem><para>Interpolation settings (set_gen, get_gen, NRPN)</para></listitem>
|
|
|
|
<listitem><para>Sequencer</para></listitem>
|
|
|
|
<listitem><para>LADSPA effects unit</para></listitem>
|
|
|
|
<listitem><para>MIDI router</para></listitem>
|
|
|
|
<listitem><para>Multi-channel audio</para></listitem>
|
|
|
|
<listitem><para>MIDI tunings</para></listitem>
|
|
|
|
<listitem><para>MIDI file player</para></listitem>
|
|
|
|
<listitem><para>SoundFont loader</para></listitem>
|
|
|
|
</itemizedlist>
|
2003-04-11 21:47:12 +00:00
|
|
|
|
|
|
|
</sect1>
|
|
|
|
</article>
|