Commit f768d6b3 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dmsynth: Import and use FluidSynth 2.3.3.

parent d0c3a0e0
......@@ -740,6 +740,8 @@ JPEG_PE_LIBS
JPEG_PE_CFLAGS
GSM_PE_LIBS
GSM_PE_CFLAGS
FLUIDSYNTH_PE_LIBS
FLUIDSYNTH_PE_CFLAGS
FAUDIO_PE_LIBS
FAUDIO_PE_CFLAGS
MINGW_PKG_CONFIG
......@@ -1591,6 +1593,7 @@ enable_dxerr8
enable_dxerr9
enable_dxguid
enable_faudio
enable_fluidsynth
enable_gsm
enable_jpeg
enable_jxr
......@@ -1746,6 +1749,8 @@ OBJC
OBJCFLAGS
FAUDIO_PE_CFLAGS
FAUDIO_PE_LIBS
FLUIDSYNTH_PE_CFLAGS
FLUIDSYNTH_PE_LIBS
GSM_PE_CFLAGS
GSM_PE_LIBS
JPEG_PE_CFLAGS
......@@ -2528,6 +2533,12 @@ Some influential environment variables:
version
FAUDIO_PE_LIBS
Linker flags for the PE faudio, overriding the bundled version
FLUIDSYNTH_PE_CFLAGS
C compiler flags for the PE fluidsynth, overriding the bundled
version
FLUIDSYNTH_PE_LIBS
Linker flags for the PE fluidsynth, overriding the bundled
version
GSM_PE_CFLAGS
C compiler flags for the PE gsm, overriding the bundled version
GSM_PE_LIBS Linker flags for the PE gsm, overriding the bundled version
......@@ -11827,6 +11838,116 @@ CPPFLAGS=$ac_save_CPPFLAGS
as_fn_append wine_notices "|FAudio ${notice_platform}MinGW development files not found (or too old); using bundled version."
fi
if ${FLUIDSYNTH_PE_CFLAGS:+false} :
then :
if test ${MINGW_PKG_CONFIG+y}
then :
FLUIDSYNTH_PE_CFLAGS=`$MINGW_PKG_CONFIG --cflags fluidsynth 2>/dev/null`
fi
fi
if ${FLUIDSYNTH_PE_LIBS:+false} :
then :
if test ${MINGW_PKG_CONFIG+y}
then :
FLUIDSYNTH_PE_LIBS=`$MINGW_PKG_CONFIG --libs fluidsynth 2>/dev/null`
fi
fi
FLUIDSYNTH_PE_LIBS=${FLUIDSYNTH_PE_LIBS:-"-lfluidsynth"}
ac_save_CPPFLAGS=$CPPFLAGS
CPPFLAGS="$CPPFLAGS $FLUIDSYNTH_PE_CFLAGS"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MinGW fluidsynth.h" >&5
printf %s "checking for MinGW fluidsynth.h... " >&6; }
if test ${ac_cv_mingw_header_fluidsynth_h+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_wine_check_headers_saved_cc=$CC
ac_wine_check_headers_saved_exeext=$ac_exeext
eval CC=\$${wine_arch}_CC
ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <fluidsynth.h>
int
main (void)
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ac_cv_mingw_header_fluidsynth_h=yes
else $as_nop
ac_cv_mingw_header_fluidsynth_h=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CC=$ac_wine_check_headers_saved_cc
ac_exeext=$ac_wine_check_headers_saved_exeext
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mingw_header_fluidsynth_h" >&5
printf "%s\n" "$ac_cv_mingw_header_fluidsynth_h" >&6; }
if test "x$ac_cv_mingw_header_fluidsynth_h" = xyes
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for new_fluid_synth in MinGW -lfluidsynth" >&5
printf %s "checking for new_fluid_synth in MinGW -lfluidsynth... " >&6; }
if test ${ac_cv_mingw_lib_fluidsynth+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_wine_check_headers_saved_cc=$CC
ac_wine_check_headers_saved_exeext=$ac_exeext
ac_wine_check_headers_saved_libs=$LIBS
eval CC=\$${wine_arch}_CC
ac_exeext=".exe"
LIBS="-lfluidsynth $FLUIDSYNTH_PE_LIBS $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
char new_fluid_synth ();
int
main (void)
{
return new_fluid_synth ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_mingw_lib_fluidsynth=yes
else $as_nop
ac_cv_mingw_lib_fluidsynth=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
CC=$ac_wine_check_headers_saved_cc
ac_exeext=$ac_wine_check_headers_saved_exeext
LIBS=$ac_wine_check_headers_saved_libs
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mingw_lib_fluidsynth" >&5
printf "%s\n" "$ac_cv_mingw_lib_fluidsynth" >&6; }
if test "x$ac_cv_mingw_lib_fluidsynth" = xyes
then :
:
else $as_nop
FLUIDSYNTH_PE_CFLAGS=""; FLUIDSYNTH_PE_LIBS=""
fi
else $as_nop
FLUIDSYNTH_PE_CFLAGS=""; FLUIDSYNTH_PE_LIBS=""
fi
CPPFLAGS=$ac_save_CPPFLAGS
if test "x$FLUIDSYNTH_PE_LIBS" = "x"
then
as_fn_append wine_notices "|Fluidsynth ${notice_platform}MinGW development files not found (or too old); using bundled version."
fi
if ${JPEG_PE_CFLAGS:+false} :
then :
if test ${MINGW_PKG_CONFIG+y}
......@@ -13053,6 +13174,21 @@ fi
printf "%s\n" "$as_me:${as_lineno-$LINENO}: faudio cflags: $FAUDIO_PE_CFLAGS" >&5
printf "%s\n" "$as_me:${as_lineno-$LINENO}: faudio libs: $FAUDIO_PE_LIBS" >&5
if ${FLUIDSYNTH_PE_LIBS:+false} :
then :
FLUIDSYNTH_PE_LIBS="fluidsynth"
if ${FLUIDSYNTH_PE_CFLAGS:+false} :
then :
FLUIDSYNTH_PE_CFLAGS="-I\$(top_srcdir)/libs/fluidsynth/include"
else $as_nop
enable_fluidsynth=no
fi
else $as_nop
enable_fluidsynth=no
fi
printf "%s\n" "$as_me:${as_lineno-$LINENO}: fluidsynth cflags: $FLUIDSYNTH_PE_CFLAGS" >&5
printf "%s\n" "$as_me:${as_lineno-$LINENO}: fluidsynth libs: $FLUIDSYNTH_PE_LIBS" >&5
if ${GSM_PE_LIBS:+false} :
then :
GSM_PE_LIBS=gsm
......@@ -21951,6 +22087,7 @@ wine_fn_config_makefile libs/dxerr8 enable_dxerr8
wine_fn_config_makefile libs/dxerr9 enable_dxerr9
wine_fn_config_makefile libs/dxguid enable_dxguid
wine_fn_config_makefile libs/faudio enable_faudio
wine_fn_config_makefile libs/fluidsynth enable_fluidsynth
wine_fn_config_makefile libs/gsm enable_gsm
wine_fn_config_makefile libs/jpeg enable_jpeg
wine_fn_config_makefile libs/jxr enable_jxr
......@@ -23104,6 +23241,8 @@ PE_ARCHS = $PE_ARCHS
MINGW_PKG_CONFIG = $MINGW_PKG_CONFIG
FAUDIO_PE_CFLAGS = $FAUDIO_PE_CFLAGS
FAUDIO_PE_LIBS = $FAUDIO_PE_LIBS
FLUIDSYNTH_PE_CFLAGS = $FLUIDSYNTH_PE_CFLAGS
FLUIDSYNTH_PE_LIBS = $FLUIDSYNTH_PE_LIBS
GSM_PE_CFLAGS = $GSM_PE_CFLAGS
GSM_PE_LIBS = $GSM_PE_LIBS
JPEG_PE_CFLAGS = $JPEG_PE_CFLAGS
......
......@@ -1036,6 +1036,15 @@ then
WINE_NOTICE([FAudio ${notice_platform}MinGW development files not found (or too old); using bundled version.])
fi
WINE_MINGW_PACKAGE_FLAGS(FLUIDSYNTH,[fluidsynth],[-lfluidsynth],
[WINE_CHECK_MINGW_HEADER(fluidsynth.h,
[WINE_CHECK_MINGW_LIB(fluidsynth,new_fluid_synth,[:],[FLUIDSYNTH_PE_CFLAGS=""; FLUIDSYNTH_PE_LIBS=""],[$FLUIDSYNTH_PE_LIBS])],
[FLUIDSYNTH_PE_CFLAGS=""; FLUIDSYNTH_PE_LIBS=""])])
if test "x$FLUIDSYNTH_PE_LIBS" = "x"
then
WINE_NOTICE([Fluidsynth ${notice_platform}MinGW development files not found (or too old); using bundled version.])
fi
WINE_MINGW_PACKAGE_FLAGS(JPEG,[libjpeg],,
[WINE_CHECK_MINGW_HEADER(jpeglib.h,
[WINE_CHECK_MINGW_LIB(jpeg,jpeg_start_decompress,[:],[JPEG_PE_CFLAGS=""; JPEG_PE_LIBS=""],[$JPEG_PE_LIBS])],
......@@ -1146,6 +1155,7 @@ then
fi
WINE_EXTLIB_FLAGS(FAUDIO, faudio, "faudio mfplat mfreadwrite mfuuid propsys", "-I\$(top_srcdir)/libs/faudio/include")
WINE_EXTLIB_FLAGS(FLUIDSYNTH, fluidsynth, "fluidsynth", "-I\$(top_srcdir)/libs/fluidsynth/include")
WINE_EXTLIB_FLAGS(GSM, gsm, gsm, "-I\$(top_srcdir)/libs/gsm/inc")
WINE_EXTLIB_FLAGS(JPEG, jpeg, jpeg, "-I\$(top_srcdir)/libs/jpeg")
WINE_EXTLIB_FLAGS(JXR, jxr, jxr, "-I\$(top_srcdir)/libs/jxr/jxrgluelib -I\$(top_srcdir)/libs/jxr/image/sys")
......@@ -3324,6 +3334,7 @@ WINE_CONFIG_MAKEFILE(libs/dxerr8)
WINE_CONFIG_MAKEFILE(libs/dxerr9)
WINE_CONFIG_MAKEFILE(libs/dxguid)
WINE_CONFIG_MAKEFILE(libs/faudio)
WINE_CONFIG_MAKEFILE(libs/fluidsynth)
WINE_CONFIG_MAKEFILE(libs/gsm)
WINE_CONFIG_MAKEFILE(libs/jpeg)
WINE_CONFIG_MAKEFILE(libs/jxr)
......
MODULE = dmsynth.dll
IMPORTS = dxguid uuid ole32 advapi32
IMPORTS = $(FLUIDSYNTH_PE_LIBS) dxguid uuid ole32 advapi32 user32
EXTRAINCL = $(FLUIDSYNTH_PE_CFLAGS)
C_SRCS = \
dmsynth_main.c \
......
......@@ -26,6 +26,8 @@
#include "dmsynth_private.h"
#include <fluidsynth.h>
WINE_DEFAULT_DEBUG_CHANNEL(dmsynth);
static void dump_dmus_instrument(DMUS_INSTRUMENT *instrument)
......@@ -228,6 +230,8 @@ struct synth
struct list instruments;
struct list waves;
fluid_settings_t *fluid_settings;
};
static inline struct synth *impl_from_IDirectMusicSynth8(IDirectMusicSynth8 *iface)
......@@ -299,6 +303,7 @@ static ULONG WINAPI synth_Release(IDirectMusicSynth8 *iface)
wave_release(wave);
}
delete_fluid_settings(This->fluid_settings);
free(This);
}
......@@ -1084,7 +1089,13 @@ HRESULT synth_create(IUnknown **ret_iface)
list_init(&obj->instruments);
list_init(&obj->waves);
if (!(obj->fluid_settings = new_fluid_settings())) goto failed;
TRACE("Created DirectMusicSynth %p\n", obj);
*ret_iface = (IUnknown *)&obj->IDirectMusicSynth8_iface;
return S_OK;
failed:
free(obj);
return E_OUTOFMEMORY;
}
[:Team:]
Current development team
Tom Moebert
Former development team
Josh Green
Pedro Lopez-Cabanillas
David Henningsson
[:Idea:]
* Samuel Bianchini, Peter Hanappe and Johnathan Lee
[:Development:]
Many people contributed to FluidSynth, sent suggestions or bug
fixes. The project was started by Peter Hanappe who is the main
author. Josh Green is the current maintainer. Below you'll find a
summary of contributions.
* Peter Hanappe. Initiated the project. files: stuck his nose in all
files.
* Josh Green is the former maintainer and contributed a lot of code
directly or indirectly through the Swami and Smurf code base.
The SoundFont loader is completely based on his code. He also wrote
the alsa sequencer driver. He made many changes and bug fixes,
but above all, he's one of the driving forces behind the synthesizer.
He also created the current FluidSynth graphic logo with Blender
(the blue waves with FluidSynth letters partially submerged).
* Markus Nentwig (re-)designed the resonant filter, the chorus, the
LADSPA subsystem, the MIDI router, optimized for SSE, made many
changes and bug fixes and got the synthesizer to actually work. Most
importantly, he used it on stage to make music.
* S. Christian Collins did much testing of FluidSynth in regards to
EMU10K1 compatibility and provided many synthesis fixes in that regard.
* Stephane Letz from Grame wrote most of the MidiShare driver, all of
the PortAudio driver, ported iiwusynth to MacOS X, and sent in many
fixes. files: iiwu_midishare.c, iiwu_portaudio.c
* Antoine Schmitt added the sequencer support, support for sample
loading (RAM Sfont), developed the
MacroMedia Director Xtra, and send in many many bug reports. Thanks
to Antoine, the synthesizer finds its way to multi-media
developers. files: in bindings/director/ and iiwu_seq.{c,h},
iiwu_event.{c,h}, iiwu_event_priv.h, iiwu_seqbind.{c,h},
iiwu_ramsfont.{c,h}
* Bob Ham added the code for "bank select" MIDI messages and send code
to define the synth's ALSA sequencer client name. files:
iiwu_midi.c, iiwu_alsa.c, iiwusynth.c, iiwusynth.h.
* Tim Goetze sent many patches and implemented the all_notes_off. He
also sent his code for the new ALSA driver. files: iiwu_synth.c,
iiwu_chan.c, iiwu_voice.c, iiwu_alsa.c
* Norbert Schnell from Ircam's jMax Team wrote most of the jMax/FTS
interface in a record time. He also pointed me to the technique of
using a lookup table for the interpolation coefficients. file:
iiwu_fts.c, iiwu_synth.c
* The initial alsa driver was based on the jMax alsa driver by
Francois Dechelle and his Real-time Team at Ircam
(https://www.ircam.fr/jmax). The jMax code was based upon Ardour's
alsa_device.cc by Paul Barton-Davis. file: iiwu_alsa.c
* Code was borrowed from the glib library to the smurf files. The goal was
to make iiwusynth independent from any library for maximum
portability.
* David Henningsson added code for fast rendering of MIDI files,
rewrote the thread safety for 1.1.2, and fixed many bugs.
* The midi device uses code from jMax's alsarawmidi.c file and from
Smurf's midi_alsaraw.c by Josh Green. file: iiwu_alsa.c
* The reverb algorithm was written by Jezar
(https://www.dreampoint.co.uk). His code is public domain. The code
was translated to C by Peter Hanappe. file: iiwu_synth.c
* The original code for the chorus effect was written by Juergen
Mueller and sundry contributors.
* Bob Ham added LADCCA support.
* Ebrahim Mayat made big efforts for compiling and running FluidSynth
on MacOS X. He also wrote the README-OSX file.
* Martin Uddén's midi package was used. His files are integrated into
the iiwu_midi file. Martin Uddén <nanook@lysator.liu.se> file:
iiwu_midi.c
* Ken Ellinwood send in a patch to add bank offsets to SoundFonts. An
adapted version was integrated in the source code. files:
fluid_cmd.c, fluidsynth/synth.h, fluid_synth.c.
* Some interpolation algorithms were used that were found in
the music-dsp archives (http://www.smartelectronix.com/musicdsp).
They were written by Joshua Scholar and others. file: iiwu_synth.c
* Macros to {increment,decrement} the 64-bit fixed point phase were
borrowed from Mozilla's macros to handle the Long-long type (64-bit
signed integer type). Mozilla NSPR library, www.mozilla.org. file:
iiwu_phase.h
* KO Myung-Hun for OS/2 support with Dart audio driver.
* Pedro Lopez-Cabanillas wrote the CoreMIDI driver for MacOSX, the CMake based
build system, revised the doxygen documentation, sequencer examples, fixes.
* Matt Giuca improved the midi player by letting it load midi files from RAM,
and by making it handle EOT events.
* Tom Moebert (fluidsynth's maintainer since Jun 2017) cleaned up and refactored
fluidsynth's API and revised its documentation, added support for 24 bit sample
soundfonts, added support for DLS soundfonts, fixed various bugs, implemented
unit tests and CI builds for Windows, Linux, MacOSX and BSD.
* Fabian Greffrath added initial support of vorbis-compressed sf3 sound fonts.
* Growing list of individuals who contributed bug fixes, corrections and minor features:
Nicolas Boulicault for ALSA sequencer midi.portname setting.
Werner Schweer
Dave Philips
Anthony Green
Jake Commander
Fernando Pablo Lopez-Lezcano
Raoul Bonisch
Sergey Pavlishin
Eric Van Buggenhaut
Ken Ellinwood
Takashi Iwai
Bob Ham
Gerald Pye
Rui Nuno Capela
Frieder Bürzele
Henri Manson
Mihail Zenkov
Paul Millar
Nick Daly
David Hilvert
Bernat Arlandis i Mañó
Sven Meier
Marcus Weseloh
Jean-jacques Ceresa
Vladimir Davidovich
Tamás Korodi
Evan Miller
The source code for FluidSynth is distributed under the terms of the
[GNU Lesser General Public License](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html),
see the [LICENSE](https://github.com/FluidSynth/fluidsynth/blob/master/LICENSE) file.
To better understand the conditions how FluidSynth can be used in
e.g. commercial or closed-source projects, please refer to the
[LicensingFAQ in our wiki](https://github.com/FluidSynth/fluidsynth/wiki/LicensingFAQ).
EXTLIB = libfluidsynth.a
EXTRADEFS = -DNDEBUG -DWITH_PROFILING
EXTRAINCL = -I$(srcdir)/src \
-I$(srcdir)/src/bindings \
-I$(srcdir)/src/drivers \
-I$(srcdir)/src/midi \
-I$(srcdir)/src/rvoice \
-I$(srcdir)/src/sfloader \
-I$(srcdir)/src/synth \
-I$(srcdir)/src/utils \
$(FLUIDSYNTH_PE_CFLAGS)
C_SRCS = \
glib.c \
src/midi/fluid_midi.c \
src/rvoice/fluid_adsr_env.c \
src/rvoice/fluid_chorus.c \
src/rvoice/fluid_iir_filter.c \
src/rvoice/fluid_lfo.c \
src/rvoice/fluid_rev.c \
src/rvoice/fluid_rvoice.c \
src/rvoice/fluid_rvoice_dsp.c \
src/rvoice/fluid_rvoice_event.c \
src/rvoice/fluid_rvoice_mixer.c \
src/sfloader/fluid_defsfont.c \
src/sfloader/fluid_samplecache.c \
src/sfloader/fluid_sffile.c \
src/sfloader/fluid_sfont.c \
src/synth/fluid_chan.c \
src/synth/fluid_event.c \
src/synth/fluid_gen.c \
src/synth/fluid_mod.c \
src/synth/fluid_synth.c \
src/synth/fluid_synth_monopoly.c \
src/synth/fluid_tuning.c \
src/synth/fluid_voice.c \
src/utils/fluid_conv.c \
src/utils/fluid_hash.c \
src/utils/fluid_list.c \
src/utils/fluid_ringbuffer.c \
src/utils/fluid_settings.c \
src/utils/fluid_sys.c
#ifndef CONFIG_H
#define CONFIG_H
/* Define to enable ALSA driver */
/* #undef ALSA_SUPPORT TRUE */
/* Define to activate sound output to files */
/* #undef AUFILE_SUPPORT 1 */
/* whether or not we are supporting CoreAudio */
/* #undef COREAUDIO_SUPPORT */
/* whether or not we are supporting CoreMIDI */
/* #undef COREMIDI_SUPPORT */
/* whether or not we are supporting DART */
/* #undef DART_SUPPORT */
/* Define if building for Mac OS X Darwin */
/* #undef DARWIN */
/* Define if D-Bus support is enabled */
/* #undef DBUS_SUPPORT 1 */
/* Soundfont to load automatically in some use cases */
/* #undef DEFAULT_SOUNDFONT "/usr/local/share/soundfonts/default.sf2" */
/* Define to enable FPE checks */
/* #undef FPE_CHECK */
/* Define to 1 if you have the <arpa/inet.h> header file. */
/* #undef HAVE_ARPA_INET_H */
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
/* #undef HAVE_FCNTL_H */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <io.h> header file. */
#define HAVE_IO_H 1
/* whether or not we are supporting lash */
/* #undef HAVE_LASH */
/* Define if systemd support is enabled */
/* #undef SYSTEMD_SUPPORT */
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <linux/soundcard.h> header file. */
/* #undef HAVE_LINUX_SOUNDCARD_H */
/* Define to 1 if you have the <machine/soundcard.h> header file. */
/* #undef HAVE_MACHINE_SOUNDCARD_H */
/* Define to 1 if you have the <math.h> header file. */
#define HAVE_MATH_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
/* #undef HAVE_NETINET_IN_H */
/* Define to 1 if you have the <netinet/tcp.h> header file. */
/* #undef HAVE_NETINET_TCP_H */
/* Define if compiling the mixer with multi-thread support */
#define ENABLE_MIXER_THREADS 1
/* Define if compiling with openMP to enable parallel audio rendering */
/* #undef HAVE_OPENMP */
/* Define to 1 if you have the <pthread.h> header file. */
/* #undef HAVE_PTHREAD_H */
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H */
/* Define to 1 if you have the <sys/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H */
/* Define to 1 if you have the <sys/soundcard.h> header file. */
/* #undef HAVE_SYS_SOUNDCARD_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
/* #undef HAVE_SYS_TIME_H */
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define to 1 if you have the <windows.h> header file. */
/* #undef HAVE_WINDOWS_H */
/* Define to 1 if you have the <getopt.h> header file. */
/* #undef HAVE_GETOPT_H */
/* Define to 1 if you have the inet_ntop() function. */
/* #undef HAVE_INETNTOP */
/* Define to enable JACK driver */
/* #undef JACK_SUPPORT */
/* Define to enable PipeWire driver */
/* #undef PIPEWIRE_SUPPORT */
/* Include the LADSPA Fx unit */
/* #undef LADSPA */
/* Define to enable IPV6 support */
/* #undef IPV6_SUPPORT */
/* Define to enable network support */
/* #undef NETWORK_SUPPORT */
/* Defined when fluidsynth is build in an automated environment, where no MSVC++ Runtime Debug Assertion dialogs should pop up */
#define NO_GUI 1
/* libinstpatch for DLS and GIG */
/* #undef LIBINSTPATCH_SUPPORT */
/* libsndfile has ogg vorbis support */
/* #undef LIBSNDFILE_HASVORBIS */
/* Define to enable libsndfile support */
/* #undef LIBSNDFILE_SUPPORT */
/* Define to enable MidiShare driver */
/* #undef MIDISHARE_SUPPORT */
/* Define if using the MinGW32 environment */
#define MINGW32 1
/* Define to enable OSS driver */
/* #undef OSS_SUPPORT */
/* Define to enable OPENSLES driver */
/* #undef OPENSLES_SUPPORT */
/* Define to enable Oboe driver */
/* #undef OBOE_SUPPORT */
/* Name of package */
#define PACKAGE "fluidsynth"
/* Define to the address where bug reports for this package should be sent. */
/* #undef PACKAGE_BUGREPORT */
/* Define to the full name of this package. */
/* #undef PACKAGE_NAME */
/* Define to the full name and version of this package. */
/* #undef PACKAGE_STRING */
/* Define to the one symbol short name of this package. */
/* #undef PACKAGE_TARNAME */
/* Define to the version of this package. */
/* #undef PACKAGE_VERSION */
/* Define to enable PortAudio driver */
/* #undef PORTAUDIO_SUPPORT */
/* Define to enable PulseAudio driver */
/* #undef PULSE_SUPPORT */
/* Define to enable DirectSound driver */
/* #undef DSOUND_SUPPORT 1 */
/* Define to enable Windows WASAPI driver */
/* #undef WASAPI_SUPPORT 1 */
/* Define to enable Windows WaveOut driver */
/* #undef WAVEOUT_SUPPORT 1 */
/* Define to enable Windows MIDI driver */
/* #undef WINMIDI_SUPPORT */
/* Define to enable SDL2 audio driver */
/* #undef SDL2_SUPPORT */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Soundfont to load for unit testing */
/* #undef TEST_SOUNDFONT */
/* Soundfont to load for UTF-8 unit testing */
/* #undef TEST_SOUNDFONT_UTF8_1 */
/* #undef TEST_SOUNDFONT_UTF8_2 */
/* #undef TEST_MIDI_UTF8 */
/* SF3 Soundfont to load for unit testing */
/* #undef TEST_SOUNDFONT_SF3 */
/* Define to enable SIGFPE assertions */
/* #undef TRAP_ON_FPE */
/* Define to do all DSP in single floating point precision */
/* #undef WITH_FLOAT */
/* Define to profile the DSP code */
/* #undef WITH_PROFILING */
/* Define to use the readline library for line editing */
/* #undef READLINE_SUPPORT */
/* Define if the compiler supports VLA */
#define SUPPORTS_VLA 1
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to 1 if you have the sinf() function. */
#define HAVE_SINF 1
/* Define to 1 if you have the cosf() function. */
#define HAVE_COSF 1
/* Define to 1 if you have the fabsf() function. */
#define HAVE_FABSF 1
/* Define to 1 if you have the powf() function. */
#define HAVE_POWF 1
/* Define to 1 if you have the sqrtf() function. */
#define HAVE_SQRTF 1
/* Define to 1 if you have the logf() function. */
#define HAVE_LOGF 1
/* Define to 1 if you have the socklen_t type. */
/* #undef HAVE_SOCKLEN_T */
#endif /* CONFIG_H */
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright 2023 Rémi Bernon for CodeWeavers
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <glib.h>
int g_vsnprintf( char *buffer, size_t size, const char *format, va_list args )
{
int ret = _vsnprintf( buffer, size - 1, format, args );
if (ret >= 0 && ret < size) buffer[ret] = 0;
else buffer[0] = 0;
return ret;
}
int g_snprintf( char *buffer, size_t size, const char *format, ... )
{
va_list args;
int ret;
va_start( args, format );
ret = g_vsnprintf( buffer, size, format, args );
va_end( args );
return ret;
}
double g_get_monotonic_time(void)
{
static LARGE_INTEGER frequency = {0};
LARGE_INTEGER counter;
if (!frequency.QuadPart) QueryPerformanceFrequency( &frequency );
QueryPerformanceCounter( &counter );
return counter.QuadPart * 1000000.0 / frequency.QuadPart; /* time in micros */
}
void g_usleep( unsigned int micros )
{
Sleep( micros / 1000 );
}
static DWORD CALLBACK g_thread_wrapper( void *args )
{
GThread *thread = args;
gpointer ret = thread->func( thread->data );
if (!InterlockedDecrement( &thread->ref )) free( thread );
return (UINT_PTR)ret;
}
GThread *g_thread_try_new( const char *name, GThreadFunc func, gpointer data, GError **err )
{
GThread *thread;
if (!(thread = calloc( 1, sizeof(*thread) ))) return NULL;
thread->ref = 2;
thread->func = func;
thread->data = data;
if (!(thread->handle = CreateThread( NULL, 0, g_thread_wrapper, thread, 0, NULL )))
{
free( thread );
return NULL;
}
return thread;
}
void g_thread_unref( GThread *thread )
{
CloseHandle( thread->handle );
if (!InterlockedDecrement( &thread->ref )) free( thread );
}
void g_thread_join( GThread *thread )
{
WaitForSingleObject( thread->handle, INFINITE );
g_thread_unref( thread );
}
void g_clear_error( GError **error )
{
*error = NULL;
}
int g_file_test( const char *path, int test )
{
DWORD attrs = GetFileAttributesA( path );
if (test == G_FILE_TEST_EXISTS) return attrs != INVALID_FILE_ATTRIBUTES;
if (test == G_FILE_TEST_IS_REGULAR) return attrs == FILE_ATTRIBUTE_NORMAL;
return 0;
}
/*
* Copyright 2023 Rémi Bernon for CodeWeavers
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <winsock.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#define GLIB_CHECK_VERSION(x, y, z) ((x) < GLIB_MAJOR_VERSION || ((x) == GLIB_MAJOR_VERSION && (y) <= GLIB_MINOR_VERSION))
#define GLIB_MAJOR_VERSION 2
#define GLIB_MINOR_VERSION 54
#define G_BYTE_ORDER 1234
#define G_BIG_ENDIAN 4321
#define GINT32_FROM_LE(val) ((INT32)(val))
#define GINT16_FROM_LE(val) ((INT16)(val))
#define G_UNLIKELY(expr) (expr)
#define G_LIKELY(expr) (expr)
#define g_return_val_if_fail( cond, val ) do { if (!(cond)) return (val); } while (0)
typedef void *gpointer;
typedef gpointer (*GThreadFunc)( gpointer data );
typedef struct _stat64 GStatBuf;
#define g_stat _stat64
typedef struct
{
const char *message;
} GError;
typedef struct
{
LONG ref;
HANDLE handle;
GThreadFunc func;
gpointer data;
} GThread;
extern int g_vsnprintf( char *buffer, size_t size, const char *format, va_list args ) __WINE_CRT_PRINTF_ATTR(3, 0);
extern int g_snprintf( char *buffer, size_t size, const char *format, ... ) __WINE_CRT_PRINTF_ATTR(3, 4);
extern double g_get_monotonic_time(void);
extern void g_usleep( unsigned int micros );
extern GThread *g_thread_try_new( const char *name, GThreadFunc func, gpointer data, GError **err );
extern void g_thread_unref( GThread *thread );
extern void g_thread_join( GThread *thread );
extern void g_clear_error( GError **error );
#define G_FILE_TEST_EXISTS 1
#define G_FILE_TEST_IS_REGULAR 2
extern int g_file_test( const char *path, int test );
#define g_new( type, count ) calloc( (count), sizeof(type) )
static void g_free( void *ptr ) { free( ptr ); }
typedef SRWLOCK GMutex;
static void g_mutex_init( GMutex *mutex ) {}
static void g_mutex_clear( GMutex *mutex ) {}
static void g_mutex_lock( GMutex *mutex ) { AcquireSRWLockExclusive( mutex ); }
static void g_mutex_unlock( GMutex *mutex ) { ReleaseSRWLockExclusive( mutex ); }
typedef CRITICAL_SECTION GRecMutex;
static void g_rec_mutex_init( GRecMutex *mutex ) { InitializeCriticalSection( mutex ); }
static void g_rec_mutex_clear( GRecMutex *mutex ) { DeleteCriticalSection( mutex ); }
static void g_rec_mutex_lock( GRecMutex *mutex ) { EnterCriticalSection( mutex ); }
static void g_rec_mutex_unlock( GRecMutex *mutex ) { LeaveCriticalSection( mutex ); }
typedef CONDITION_VARIABLE GCond;
static void g_cond_init( GCond *cond ) {}
static void g_cond_clear( GCond *cond ) {}
static void g_cond_signal( GCond *cond ) { WakeConditionVariable( cond ); }
static void g_cond_broadcast( GCond *cond ) { WakeAllConditionVariable( cond ); }
static void g_cond_wait( GCond *cond, GMutex *mutex ) { SleepConditionVariableSRW( cond, mutex, INFINITE, 0 ); }
static void g_atomic_int_inc( int *ptr ) { InterlockedIncrement( (LONG *)ptr ); }
static int g_atomic_int_add( int *ptr, int val ) { return InterlockedAdd( (LONG *)ptr, val ) - 1; }
static int g_atomic_int_get( int *ptr ) { return ReadAcquire( (LONG *)ptr ); }
static void g_atomic_int_set( int *ptr, int val ) { InterlockedExchange( (LONG *)ptr, val ); }
static int g_atomic_int_dec_and_test( int *ptr, int val ) { return !InterlockedAdd( (LONG *)ptr, -val ); }
static int g_atomic_int_compare_and_exchange( int *ptr, int cmp, int val ) { return InterlockedCompareExchange( (LONG *)ptr, val, cmp ) == cmp; }
/* 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_H
#define _FLUIDSYNTH_H
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define BUILD_SHARED_LIBS 0
#if (BUILD_SHARED_LIBS == 0)
#define FLUIDSYNTH_API // building static lib? no visibility control then
#elif defined(WIN32)
#if defined(FLUIDSYNTH_NOT_A_DLL)
#define FLUIDSYNTH_API
#elif defined(FLUIDSYNTH_DLL_EXPORTS)
#define FLUIDSYNTH_API __declspec(dllexport)
#else
#define FLUIDSYNTH_API __declspec(dllimport)
#endif
#elif defined(MACOS9)
#define FLUIDSYNTH_API __declspec(export)
#elif defined(__OS2__)
#define FLUIDSYNTH_API __declspec(dllexport)
#elif defined(__GNUC__)
#define FLUIDSYNTH_API __attribute__ ((visibility ("default")))
#else
#define FLUIDSYNTH_API
#endif
#if 1 /* Wine-specific code */
# define FLUID_DEPRECATED
#else /* Wine-specific code */
#if defined(__GNUC__) || defined(__clang__)
# define FLUID_DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER) && _MSC_VER > 1200
# define FLUID_DEPRECATED __declspec(deprecated)
#else
# define FLUID_DEPRECATED
#endif
#endif /* Wine-specific code */
/**
* @file fluidsynth.h
* @brief FluidSynth is a real-time synthesizer designed for SoundFont(R) files.
*
* This is the header of the fluidsynth library and contains the
* synthesizer's public API.
*
* Depending on how you want to use or extend the synthesizer you
* will need different API functions. You probably do not need all
* of them. Here is what you might want to do:
*
* - Embedded synthesizer: create a new synthesizer and send MIDI
* events to it. The sound goes directly to the audio output of
* your system.
*
* - Plugin synthesizer: create a synthesizer and send MIDI events
* but pull the audio back into your application.
*
* - SoundFont plugin: create a new type of "SoundFont" and allow
* the synthesizer to load your type of SoundFonts.
*
* - MIDI input: Create a MIDI handler to read the MIDI input on your
* machine and send the MIDI events directly to the synthesizer.
*
* - MIDI files: Open MIDI files and send the MIDI events to the
* synthesizer.
*
* - Command lines: You can send textual commands to the synthesizer.
*
* SoundFont(R) is a registered trademark of E-mu Systems, Inc.
*/
#include "fluidsynth/types.h"
#include "fluidsynth/settings.h"
#include "fluidsynth/synth.h"
#include "fluidsynth/shell.h"
#include "fluidsynth/sfont.h"
#include "fluidsynth/audio.h"
#include "fluidsynth/event.h"
#include "fluidsynth/midi.h"
#include "fluidsynth/seq.h"
#include "fluidsynth/seqbind.h"
#include "fluidsynth/log.h"
#include "fluidsynth/misc.h"
#include "fluidsynth/mod.h"
#include "fluidsynth/gen.h"
#include "fluidsynth/voice.h"
#include "fluidsynth/version.h"
#include "fluidsynth/ladspa.h"
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_H */
/* 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_AUDIO_H
#define _FLUIDSYNTH_AUDIO_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup audio_output Audio Output
*
* Functions for managing audio drivers and file renderers.
*
* The file renderer is used for fast rendering of MIDI files to
* audio files. The audio drivers are a high-level interface to
* connect the synthesizer with external audio sinks or to render
* real-time audio to files.
*/
/**
* @defgroup audio_driver Audio Driver
* @ingroup audio_output
*
* Functions for managing audio drivers.
*
* Defines functions for creating audio driver output. Use
* new_fluid_audio_driver() to create a new audio driver for a given synth
* and configuration settings.
*
* The function new_fluid_audio_driver2() can be
* used if custom audio processing is desired before the audio is sent to the
* audio driver (although it is not as efficient).
*
* @sa @ref CreatingAudioDriver
*
* @{
*/
/**
* Callback function type used with new_fluid_audio_driver2() to allow for
* custom user audio processing before the audio is sent to the driver.
*
* @param data The user data parameter as passed to new_fluid_audio_driver2().
* @param len Count of audio frames to synthesize.
* @param nfx Count of arrays in \c fx.
* @param fx Array of buffers to store effects audio to. Buffers may alias with buffers of \c out.
* @param nout Count of arrays in \c out.
* @param out Array of buffers to store (dry) audio to. Buffers may alias with buffers of \c fx.
* @return Should return #FLUID_OK on success, #FLUID_FAILED if an error occurred.
*
* This function is responsible for rendering audio to the buffers.
* The buffers passed to this function are allocated and owned by the respective
* audio driver and are only valid during that specific call (do not cache them).
* The buffers have already been zeroed-out.
* For further details please refer to fluid_synth_process().
*
* @parblock
* @note Whereas fluid_synth_process() allows aliasing buffers, there is the guarantee that @p out
* and @p fx buffers provided by fluidsynth's audio drivers never alias. This prevents downstream
* applications from e.g. applying a custom effect accidentally to the same buffer multiple times.
* @endparblock
*
* @parblock
* @note Also note that the Jack driver is currently the only driver that has dedicated @p fx buffers
* (but only if \setting{audio_jack_multi} is true). All other drivers do not provide @p fx buffers.
* In this case, users are encouraged to mix the effects into the provided dry buffers when calling
* fluid_synth_process().
* @code{.cpp}
int myCallback(void *, int len, int nfx, float *fx[], int nout, float *out[])
{
int ret;
if(nfx == 0)
{
float *fxb[4] = {out[0], out[1], out[0], out[1]};
ret = fluid_synth_process(synth, len, sizeof(fxb) / sizeof(fxb[0]), fxb, nout, out);
}
else
{
ret = fluid_synth_process(synth, len, nfx, fx, nout, out);
}
// ... client-code ...
return ret;
}
* @endcode
* For other possible use-cases refer to \ref fluidsynth_process.c .
* @endparblock
*/
typedef int (*fluid_audio_func_t)(void *data, int len,
int nfx, float *fx[],
int nout, float *out[]);
/** @startlifecycle{Audio Driver} */
FLUIDSYNTH_API fluid_audio_driver_t *new_fluid_audio_driver(fluid_settings_t *settings,
fluid_synth_t *synth);
FLUIDSYNTH_API fluid_audio_driver_t *new_fluid_audio_driver2(fluid_settings_t *settings,
fluid_audio_func_t func,
void *data);
FLUIDSYNTH_API void delete_fluid_audio_driver(fluid_audio_driver_t *driver);
/** @endlifecycle */
FLUIDSYNTH_API int fluid_audio_driver_register(const char **adrivers);
/** @} */
/**
* @defgroup file_renderer File Renderer
* @ingroup audio_output
*
* Functions for managing file renderers and triggering the rendering.
*
* The file renderer is only used to render a MIDI file to audio as fast
* as possible. Please see \ref FileRenderer for a full example.
*
* If you are looking for a way to write audio generated
* from real-time events (for example from an external sequencer or a MIDI controller) to a file,
* please have a look at the \c file \ref audio_driver instead.
*
*
* @{
*/
/** @startlifecycle{File Renderer} */
FLUIDSYNTH_API fluid_file_renderer_t *new_fluid_file_renderer(fluid_synth_t *synth);
FLUIDSYNTH_API void delete_fluid_file_renderer(fluid_file_renderer_t *dev);
/** @endlifecycle */
FLUIDSYNTH_API int fluid_file_renderer_process_block(fluid_file_renderer_t *dev);
FLUIDSYNTH_API int fluid_file_set_encoding_quality(fluid_file_renderer_t *dev, double q);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_AUDIO_H */
/* 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_EVENT_H
#define _FLUIDSYNTH_EVENT_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup sequencer_events Sequencer Events
* @ingroup sequencer
*
* Create, modify, query and destroy sequencer events.
*
* @{
*/
/**
* Sequencer event type enumeration.
*/
enum fluid_seq_event_type
{
FLUID_SEQ_NOTE = 0, /**< Note event with duration */
FLUID_SEQ_NOTEON, /**< Note on event */
FLUID_SEQ_NOTEOFF, /**< Note off event */
FLUID_SEQ_ALLSOUNDSOFF, /**< All sounds off event */
FLUID_SEQ_ALLNOTESOFF, /**< All notes off event */
FLUID_SEQ_BANKSELECT, /**< Bank select message */
FLUID_SEQ_PROGRAMCHANGE, /**< Program change message */
FLUID_SEQ_PROGRAMSELECT, /**< Program select message */
FLUID_SEQ_PITCHBEND, /**< Pitch bend message */
FLUID_SEQ_PITCHWHEELSENS, /**< Pitch wheel sensitivity set message @since 1.1.0 was misspelled previously */
FLUID_SEQ_MODULATION, /**< Modulation controller event */
FLUID_SEQ_SUSTAIN, /**< Sustain controller event */
FLUID_SEQ_CONTROLCHANGE, /**< MIDI control change event */
FLUID_SEQ_PAN, /**< Stereo pan set event */
FLUID_SEQ_VOLUME, /**< Volume set event */
FLUID_SEQ_REVERBSEND, /**< Reverb send set event */
FLUID_SEQ_CHORUSSEND, /**< Chorus send set event */
FLUID_SEQ_TIMER, /**< Timer event (useful for giving a callback at a certain time) */
FLUID_SEQ_CHANNELPRESSURE, /**< Channel aftertouch event @since 1.1.0 */
FLUID_SEQ_KEYPRESSURE, /**< Polyphonic aftertouch event @since 2.0.0 */
FLUID_SEQ_SYSTEMRESET, /**< System reset event @since 1.1.0 */
FLUID_SEQ_UNREGISTERING, /**< Called when a sequencer client is being unregistered. @since 1.1.0 */
FLUID_SEQ_SCALE, /**< Sets a new time scale for the sequencer @since 2.2.0 */
FLUID_SEQ_LASTEVENT /**< @internal Defines the count of events enums @warning This symbol
is not part of the public API and ABI stability guarantee and
may change at any time! */
};
/* Event alloc/free */
/** @startlifecycle{Sequencer Event} */
FLUIDSYNTH_API fluid_event_t *new_fluid_event(void);
FLUIDSYNTH_API void delete_fluid_event(fluid_event_t *evt);
/** @endlifecycle */
/* Initializing events */
FLUIDSYNTH_API void fluid_event_set_source(fluid_event_t *evt, fluid_seq_id_t src);
FLUIDSYNTH_API void fluid_event_set_dest(fluid_event_t *evt, fluid_seq_id_t dest);
/* Timer events */
FLUIDSYNTH_API void fluid_event_timer(fluid_event_t *evt, void *data);
/* Note events */
FLUIDSYNTH_API void fluid_event_note(fluid_event_t *evt, int channel,
short key, short vel,
unsigned int duration);
FLUIDSYNTH_API void fluid_event_noteon(fluid_event_t *evt, int channel, short key, short vel);
FLUIDSYNTH_API void fluid_event_noteoff(fluid_event_t *evt, int channel, short key);
FLUIDSYNTH_API void fluid_event_all_sounds_off(fluid_event_t *evt, int channel);
FLUIDSYNTH_API void fluid_event_all_notes_off(fluid_event_t *evt, int channel);
/* Instrument selection */
FLUIDSYNTH_API void fluid_event_bank_select(fluid_event_t *evt, int channel, short bank_num);
FLUIDSYNTH_API void fluid_event_program_change(fluid_event_t *evt, int channel, int preset_num);
FLUIDSYNTH_API void fluid_event_program_select(fluid_event_t *evt, int channel, unsigned int sfont_id, short bank_num, short preset_num);
/* Real-time generic instrument controllers */
FLUIDSYNTH_API
void fluid_event_control_change(fluid_event_t *evt, int channel, short control, int val);
/* Real-time instrument controllers shortcuts */
FLUIDSYNTH_API void fluid_event_pitch_bend(fluid_event_t *evt, int channel, int val);
FLUIDSYNTH_API void fluid_event_pitch_wheelsens(fluid_event_t *evt, int channel, int val);
FLUIDSYNTH_API void fluid_event_modulation(fluid_event_t *evt, int channel, int val);
FLUIDSYNTH_API void fluid_event_sustain(fluid_event_t *evt, int channel, int val);
FLUIDSYNTH_API void fluid_event_pan(fluid_event_t *evt, int channel, int val);
FLUIDSYNTH_API void fluid_event_volume(fluid_event_t *evt, int channel, int val);
FLUIDSYNTH_API void fluid_event_reverb_send(fluid_event_t *evt, int channel, int val);
FLUIDSYNTH_API void fluid_event_chorus_send(fluid_event_t *evt, int channel, int val);
FLUIDSYNTH_API void fluid_event_key_pressure(fluid_event_t *evt, int channel, short key, int val);
FLUIDSYNTH_API void fluid_event_channel_pressure(fluid_event_t *evt, int channel, int val);
FLUIDSYNTH_API void fluid_event_system_reset(fluid_event_t *evt);
/* Only when unregistering clients */
FLUIDSYNTH_API void fluid_event_unregistering(fluid_event_t *evt);
FLUIDSYNTH_API void fluid_event_scale(fluid_event_t *evt, double new_scale);
FLUIDSYNTH_API int fluid_event_from_midi_event(fluid_event_t *, const fluid_midi_event_t *);
/* Accessing event data */
FLUIDSYNTH_API int fluid_event_get_type(fluid_event_t *evt);
FLUIDSYNTH_API fluid_seq_id_t fluid_event_get_source(fluid_event_t *evt);
FLUIDSYNTH_API fluid_seq_id_t fluid_event_get_dest(fluid_event_t *evt);
FLUIDSYNTH_API int fluid_event_get_channel(fluid_event_t *evt);
FLUIDSYNTH_API short fluid_event_get_key(fluid_event_t *evt);
FLUIDSYNTH_API short fluid_event_get_velocity(fluid_event_t *evt);
FLUIDSYNTH_API short fluid_event_get_control(fluid_event_t *evt);
FLUIDSYNTH_API int fluid_event_get_value(fluid_event_t *evt);
FLUIDSYNTH_API int fluid_event_get_program(fluid_event_t *evt);
FLUIDSYNTH_API void *fluid_event_get_data(fluid_event_t *evt);
FLUIDSYNTH_API unsigned int fluid_event_get_duration(fluid_event_t *evt);
FLUIDSYNTH_API short fluid_event_get_bank(fluid_event_t *evt);
FLUIDSYNTH_API int fluid_event_get_pitch(fluid_event_t *evt);
FLUIDSYNTH_API double fluid_event_get_scale(fluid_event_t *evt);
FLUIDSYNTH_API unsigned int fluid_event_get_sfont_id(fluid_event_t *evt);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_EVENT_H */
/* 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_GEN_H
#define _FLUIDSYNTH_GEN_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup generators SoundFont Generators
* @ingroup soundfonts
*
* Functions and defines for SoundFont generator effects.
*
* @{
*/
/**
* Generator (effect) numbers (Soundfont 2.01 specifications section 8.1.3)
*/
enum fluid_gen_type
{
GEN_STARTADDROFS, /**< Sample start address offset (0-32767) */
GEN_ENDADDROFS, /**< Sample end address offset (-32767-0) */
GEN_STARTLOOPADDROFS, /**< Sample loop start address offset (-32767-32767) */
GEN_ENDLOOPADDROFS, /**< Sample loop end address offset (-32767-32767) */
GEN_STARTADDRCOARSEOFS, /**< Sample start address coarse offset (X 32768) */
GEN_MODLFOTOPITCH, /**< Modulation LFO to pitch */
GEN_VIBLFOTOPITCH, /**< Vibrato LFO to pitch */
GEN_MODENVTOPITCH, /**< Modulation envelope to pitch */
GEN_FILTERFC, /**< Filter cutoff */
GEN_FILTERQ, /**< Filter Q */
GEN_MODLFOTOFILTERFC, /**< Modulation LFO to filter cutoff */
GEN_MODENVTOFILTERFC, /**< Modulation envelope to filter cutoff */
GEN_ENDADDRCOARSEOFS, /**< Sample end address coarse offset (X 32768) */
GEN_MODLFOTOVOL, /**< Modulation LFO to volume */
GEN_UNUSED1, /**< Unused */
GEN_CHORUSSEND, /**< Chorus send amount */
GEN_REVERBSEND, /**< Reverb send amount */
GEN_PAN, /**< Stereo panning */
GEN_UNUSED2, /**< Unused */
GEN_UNUSED3, /**< Unused */
GEN_UNUSED4, /**< Unused */
GEN_MODLFODELAY, /**< Modulation LFO delay */
GEN_MODLFOFREQ, /**< Modulation LFO frequency */
GEN_VIBLFODELAY, /**< Vibrato LFO delay */
GEN_VIBLFOFREQ, /**< Vibrato LFO frequency */
GEN_MODENVDELAY, /**< Modulation envelope delay */
GEN_MODENVATTACK, /**< Modulation envelope attack */
GEN_MODENVHOLD, /**< Modulation envelope hold */
GEN_MODENVDECAY, /**< Modulation envelope decay */
GEN_MODENVSUSTAIN, /**< Modulation envelope sustain */
GEN_MODENVRELEASE, /**< Modulation envelope release */
GEN_KEYTOMODENVHOLD, /**< Key to modulation envelope hold */
GEN_KEYTOMODENVDECAY, /**< Key to modulation envelope decay */
GEN_VOLENVDELAY, /**< Volume envelope delay */
GEN_VOLENVATTACK, /**< Volume envelope attack */
GEN_VOLENVHOLD, /**< Volume envelope hold */
GEN_VOLENVDECAY, /**< Volume envelope decay */
GEN_VOLENVSUSTAIN, /**< Volume envelope sustain */
GEN_VOLENVRELEASE, /**< Volume envelope release */
GEN_KEYTOVOLENVHOLD, /**< Key to volume envelope hold */
GEN_KEYTOVOLENVDECAY, /**< Key to volume envelope decay */
GEN_INSTRUMENT, /**< Instrument ID (shouldn't be set by user) */
GEN_RESERVED1, /**< Reserved */
GEN_KEYRANGE, /**< MIDI note range */
GEN_VELRANGE, /**< MIDI velocity range */
GEN_STARTLOOPADDRCOARSEOFS, /**< Sample start loop address coarse offset (X 32768) */
GEN_KEYNUM, /**< Fixed MIDI note number */
GEN_VELOCITY, /**< Fixed MIDI velocity value */
GEN_ATTENUATION, /**< Initial volume attenuation */
GEN_RESERVED2, /**< Reserved */
GEN_ENDLOOPADDRCOARSEOFS, /**< Sample end loop address coarse offset (X 32768) */
GEN_COARSETUNE, /**< Coarse tuning */
GEN_FINETUNE, /**< Fine tuning */
GEN_SAMPLEID, /**< Sample ID (shouldn't be set by user) */
GEN_SAMPLEMODE, /**< Sample mode flags */
GEN_RESERVED3, /**< Reserved */
GEN_SCALETUNE, /**< Scale tuning */
GEN_EXCLUSIVECLASS, /**< Exclusive class number */
GEN_OVERRIDEROOTKEY, /**< Sample root note override */
/**
* Initial Pitch
*
* @note This is not "standard" SoundFont generator, because it is not
* mentioned in the list of generators in the SF2 specifications.
* It is used by FluidSynth internally to compute the nominal pitch of
* a note on note-on event. By nature it shouldn't be allowed to be modulated,
* however the specification defines a default modulator having "Initial Pitch"
* as destination (cf. SF2.01 page 57 section 8.4.10 MIDI Pitch Wheel to Initial Pitch).
* Thus it is impossible to cancel this default modulator, which would be required
* to let the MIDI Pitch Wheel controller modulate a different generator.
* In order to provide this flexibility, FluidSynth >= 2.1.0 uses a default modulator
* "Pitch Wheel to Fine Tune", rather than Initial Pitch. The same "compromise" can
* be found on the Audigy 2 ZS for instance.
*/
GEN_PITCH,
GEN_CUSTOM_BALANCE, /**< Balance @note Not a real SoundFont generator */
/* non-standard generator for an additional custom high- or low-pass filter */
GEN_CUSTOM_FILTERFC, /**< Custom filter cutoff frequency */
GEN_CUSTOM_FILTERQ, /**< Custom filter Q */
GEN_LAST /**< @internal Value defines the count of generators (#fluid_gen_type)
@warning This symbol is not part of the public API and ABI
stability guarantee and may change at any time! */
};
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_GEN_H */
/* 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
/**
* @defgroup ladspa Effect - LADSPA
* @ingroup synth
*
* Functions for configuring the LADSPA effects unit
*
* This header defines useful functions for programmatically manipulating the ladspa
* effects unit of the synth that can be retrieved via fluid_synth_get_ladspa_fx().
*
* Using any of those functions requires fluidsynth to be compiled with LADSPA support.
* Else all of those functions are useless dummies.
*
* @{
*/
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 */
/* 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_LOG_H
#define _FLUIDSYNTH_LOG_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup logging Logging
*
* Logging interface
*
* The default logging function of the fluidsynth prints its messages to the
* stderr. The synthesizer uses five level of messages: #FLUID_PANIC,
* #FLUID_ERR, #FLUID_WARN, #FLUID_INFO, and #FLUID_DBG.
*
* A client application can install a new log function to handle the messages
* differently. In the following example, the application sets a callback
* function to display #FLUID_PANIC messages in a dialog, and ignores all other
* messages by setting the log function to NULL:
*
* @code
* fluid_set_log_function(FLUID_PANIC, show_dialog, (void*) root_window);
* fluid_set_log_function(FLUID_ERR, NULL, NULL);
* fluid_set_log_function(FLUID_WARN, NULL, NULL);
* fluid_set_log_function(FLUID_DBG, NULL, NULL);
* @endcode
*
* @note The logging configuration is global and not tied to a specific
* synthesizer instance. That means that all synthesizer instances created in
* the same process share the same logging configuration.
*
* @{
*/
/**
* FluidSynth log levels.
*/
enum fluid_log_level
{
FLUID_PANIC, /**< The synth can't function correctly any more */
FLUID_ERR, /**< Serious error occurred */
FLUID_WARN, /**< Warning */
FLUID_INFO, /**< Verbose informational messages */
FLUID_DBG, /**< Debugging messages */
LAST_LOG_LEVEL /**< @internal This symbol is not part of the public API and ABI
stability guarantee and may change at any time! */
};
/**
* Log function handler callback type used by fluid_set_log_function().
*
* @param level Log level (#fluid_log_level)
* @param message Log message text
* @param data User data pointer supplied to fluid_set_log_function().
*/
typedef void (*fluid_log_function_t)(int level, const char *message, void *data);
FLUIDSYNTH_API
fluid_log_function_t fluid_set_log_function(int level, fluid_log_function_t fun, void *data);
FLUIDSYNTH_API void fluid_default_log_function(int level, const char *message, void *data);
FLUIDSYNTH_API int fluid_log(int level, const char *fmt, ...)
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
__attribute__ ((format (printf, 2, 3)))
#endif
;
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_LOG_H */
/* 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_MISC_H
#define _FLUIDSYNTH_MISC_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup misc Miscellaneous
*
* Miscellaneous utility functions and defines
*
* @{
*/
/**
* Value that indicates success, used by most libfluidsynth functions.
*
* @note This was not publicly defined prior to libfluidsynth 1.1.0. When
* writing code which should also be compatible with older versions, something
* like the following can be used:
*
* @code
* #include <fluidsynth.h>
*
* #ifndef FLUID_OK
* #define FLUID_OK (0)
* #define FLUID_FAILED (-1)
* #endif
* @endcode
*
* @since 1.1.0
*/
#define FLUID_OK (0)
/**
* Value that indicates failure, used by most libfluidsynth functions.
*
* @note See #FLUID_OK for more details.
*
* @since 1.1.0
*/
#define FLUID_FAILED (-1)
FLUIDSYNTH_API int fluid_is_soundfont(const char *filename);
FLUIDSYNTH_API int fluid_is_midifile(const char *filename);
FLUIDSYNTH_API void fluid_free(void* ptr);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_MISC_H */
/* 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_MOD_H
#define _FLUIDSYNTH_MOD_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup modulators SoundFont Modulators
* @ingroup soundfonts
*
* SoundFont modulator functions and constants.
*
* @{
*/
/**
* Flags defining the polarity, mapping function and type of a modulator source.
* Compare with SoundFont 2.04 PDF section 8.2.
*
* Note: Bit values do not correspond to the SoundFont spec! Also note that
* #FLUID_MOD_GC and #FLUID_MOD_CC are in the flags field instead of the source field.
*/
enum fluid_mod_flags
{
FLUID_MOD_POSITIVE = 0, /**< Mapping function is positive */
FLUID_MOD_NEGATIVE = 1, /**< Mapping function is negative */
FLUID_MOD_UNIPOLAR = 0, /**< Mapping function is unipolar */
FLUID_MOD_BIPOLAR = 2, /**< Mapping function is bipolar */
FLUID_MOD_LINEAR = 0, /**< Linear mapping function */
FLUID_MOD_CONCAVE = 4, /**< Concave mapping function */
FLUID_MOD_CONVEX = 8, /**< Convex mapping function */
FLUID_MOD_SWITCH = 12, /**< Switch (on/off) mapping function */
FLUID_MOD_GC = 0, /**< General controller source type (#fluid_mod_src) */
FLUID_MOD_CC = 16, /**< MIDI CC controller (source will be a MIDI CC number) */
FLUID_MOD_SIN = 0x80, /**< Custom non-standard sinus mapping function */
};
/**
* General controller (if #FLUID_MOD_GC in flags). This
* corresponds to SoundFont 2.04 PDF section 8.2.1
*/
enum fluid_mod_src
{
FLUID_MOD_NONE = 0, /**< No source controller */
FLUID_MOD_VELOCITY = 2, /**< MIDI note-on velocity */
FLUID_MOD_KEY = 3, /**< MIDI note-on note number */
FLUID_MOD_KEYPRESSURE = 10, /**< MIDI key pressure */
FLUID_MOD_CHANNELPRESSURE = 13, /**< MIDI channel pressure */
FLUID_MOD_PITCHWHEEL = 14, /**< Pitch wheel */
FLUID_MOD_PITCHWHEELSENS = 16 /**< Pitch wheel sensitivity */
};
/** @startlifecycle{Modulator} */
FLUIDSYNTH_API fluid_mod_t *new_fluid_mod(void);
FLUIDSYNTH_API void delete_fluid_mod(fluid_mod_t *mod);
/** @endlifecycle */
FLUIDSYNTH_API size_t fluid_mod_sizeof(void);
FLUIDSYNTH_API void fluid_mod_set_source1(fluid_mod_t *mod, int src, int flags);
FLUIDSYNTH_API void fluid_mod_set_source2(fluid_mod_t *mod, int src, int flags);
FLUIDSYNTH_API void fluid_mod_set_dest(fluid_mod_t *mod, int dst);
FLUIDSYNTH_API void fluid_mod_set_amount(fluid_mod_t *mod, double amount);
FLUIDSYNTH_API int fluid_mod_get_source1(const fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_get_flags1(const fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_get_source2(const fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_get_flags2(const fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_get_dest(const fluid_mod_t *mod);
FLUIDSYNTH_API double fluid_mod_get_amount(const fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_test_identity(const fluid_mod_t *mod1, const fluid_mod_t *mod2);
FLUIDSYNTH_API int fluid_mod_has_source(const fluid_mod_t *mod, int cc, int ctrl);
FLUIDSYNTH_API int fluid_mod_has_dest(const fluid_mod_t *mod, int gen);
FLUIDSYNTH_API void fluid_mod_clone(fluid_mod_t *mod, const fluid_mod_t *src);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_MOD_H */
/* 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_SEQ_H
#define _FLUIDSYNTH_SEQ_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup sequencer MIDI Sequencer
*
* MIDI event sequencer.
*
* The MIDI sequencer can be used to play MIDI events in a more flexible way than
* using the MIDI file player, which expects the events to be stored as
* Standard MIDI Files. Using the sequencer, you can provide the events one by
* one, with an optional timestamp for scheduling.
*
* @{
*/
/**
* Event callback prototype for destination clients.
*
* @param time Current sequencer tick value (see fluid_sequencer_get_tick()).
* @param event The event being received
* @param seq The sequencer instance
* @param data User defined data registered with the client
*
* @note @p time may not be of the same tick value as the scheduled event! In fact, depending on
* the sequencer's scale and the synth's sample-rate, @p time may be a few ticks too late. Although this
* itself is inaudible, it is important to consider,
* when you use this callback for enqueuing additional events over and over again with
* fluid_sequencer_send_at(): If you enqueue new events with a relative tick value you might introduce
* a timing error, which causes your sequence to sound e.g. slower than it's supposed to be. If this is
* your use-case, make sure to enqueue events with an absolute tick value.
*/
typedef void (*fluid_event_callback_t)(unsigned int time, fluid_event_t *event,
fluid_sequencer_t *seq, void *data);
/** @startlifecycle{MIDI Sequencer} */
FLUID_DEPRECATED FLUIDSYNTH_API fluid_sequencer_t *new_fluid_sequencer(void);
FLUIDSYNTH_API fluid_sequencer_t *new_fluid_sequencer2(int use_system_timer);
FLUIDSYNTH_API void delete_fluid_sequencer(fluid_sequencer_t *seq);
/** @endlifecycle */
FLUIDSYNTH_API int fluid_sequencer_get_use_system_timer(fluid_sequencer_t *seq);
FLUIDSYNTH_API
fluid_seq_id_t fluid_sequencer_register_client(fluid_sequencer_t *seq, const char *name,
fluid_event_callback_t callback, void *data);
FLUIDSYNTH_API void fluid_sequencer_unregister_client(fluid_sequencer_t *seq, fluid_seq_id_t id);
FLUIDSYNTH_API int fluid_sequencer_count_clients(fluid_sequencer_t *seq);
FLUIDSYNTH_API fluid_seq_id_t fluid_sequencer_get_client_id(fluid_sequencer_t *seq, int index);
FLUIDSYNTH_API char *fluid_sequencer_get_client_name(fluid_sequencer_t *seq, fluid_seq_id_t id);
FLUIDSYNTH_API int fluid_sequencer_client_is_dest(fluid_sequencer_t *seq, fluid_seq_id_t id);
FLUIDSYNTH_API void fluid_sequencer_process(fluid_sequencer_t *seq, unsigned int msec);
FLUIDSYNTH_API void fluid_sequencer_send_now(fluid_sequencer_t *seq, fluid_event_t *evt);
FLUIDSYNTH_API
int fluid_sequencer_send_at(fluid_sequencer_t *seq, fluid_event_t *evt,
unsigned int time, int absolute);
FLUIDSYNTH_API
void fluid_sequencer_remove_events(fluid_sequencer_t *seq, fluid_seq_id_t source, fluid_seq_id_t dest, int type);
FLUIDSYNTH_API unsigned int fluid_sequencer_get_tick(fluid_sequencer_t *seq);
FLUIDSYNTH_API void fluid_sequencer_set_time_scale(fluid_sequencer_t *seq, double scale);
FLUIDSYNTH_API double fluid_sequencer_get_time_scale(fluid_sequencer_t *seq);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_SEQ_H */
/* 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_SEQBIND_H
#define _FLUIDSYNTH_SEQBIND_H
#include "seq.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup sequencer
*
* @{
*/
FLUIDSYNTH_API
fluid_seq_id_t fluid_sequencer_register_fluidsynth(fluid_sequencer_t *seq, fluid_synth_t *synth);
FLUIDSYNTH_API
int fluid_sequencer_add_midi_event_to_buffer(void *data, fluid_midi_event_t *event);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_SEQBIND_H */
/* 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_SETTINGS_H
#define _FLUIDSYNTH_SETTINGS_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup settings Settings
*
* Functions for settings management
*
* To create a synthesizer object you will have to specify its
* settings. These settings are stored in a fluid_settings_t object.
* @code
* void
* my_synthesizer ()
* {
* fluid_settings_t *settings;
* fluid_synth_t *synth;
* fluid_audio_driver_t *adriver;
*
* settings = new_fluid_settings ();
* fluid_settings_setstr(settings, "audio.driver", "alsa");
* // ... change settings ...
* synth = new_fluid_synth (settings);
* adriver = new_fluid_audio_driver (settings, synth);
* // ...
* }
* @endcode
* @sa @ref CreatingSettings
*
* @{
*/
/**
* Hint FLUID_HINT_BOUNDED_BELOW indicates that the LowerBound field
* of the FLUID_PortRangeHint should be considered meaningful. The
* value in this field should be considered the (inclusive) lower
* bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also
* specified then the value of LowerBound should be multiplied by the
* sample rate.
*/
#define FLUID_HINT_BOUNDED_BELOW 0x1
/** Hint FLUID_HINT_BOUNDED_ABOVE indicates that the UpperBound field
of the FLUID_PortRangeHint should be considered meaningful. The
value in this field should be considered the (inclusive) upper
bound of the valid range. If FLUID_HINT_SAMPLE_RATE is also
specified then the value of UpperBound should be multiplied by the
sample rate. */
#define FLUID_HINT_BOUNDED_ABOVE 0x2
/**
* Hint FLUID_HINT_TOGGLED indicates that the data item should be
* considered a Boolean toggle. Data less than or equal to zero should
* be considered `off' or `false,' and data above zero should be
* considered `on' or `true.' FLUID_HINT_TOGGLED may not be used in
* conjunction with any other hint.
*/
#define FLUID_HINT_TOGGLED 0x4
#define FLUID_HINT_OPTIONLIST 0x02 /**< Setting is a list of string options */
/**
* Settings type
*
* Each setting has a defined type: numeric (double), integer, string or a
* set of values. The type of each setting can be retrieved using the
* function fluid_settings_get_type()
*/
enum fluid_types_enum
{
FLUID_NO_TYPE = -1, /**< Undefined type */
FLUID_NUM_TYPE, /**< Numeric (double) */
FLUID_INT_TYPE, /**< Integer */
FLUID_STR_TYPE, /**< String */
FLUID_SET_TYPE /**< Set of values */
};
/** @startlifecycle{Settings} */
FLUIDSYNTH_API fluid_settings_t *new_fluid_settings(void);
FLUIDSYNTH_API void delete_fluid_settings(fluid_settings_t *settings);
/** @endlifecycle */
FLUIDSYNTH_API
int fluid_settings_get_type(fluid_settings_t *settings, const char *name);
FLUIDSYNTH_API
int fluid_settings_get_hints(fluid_settings_t *settings, const char *name, int *val);
FLUIDSYNTH_API
int fluid_settings_is_realtime(fluid_settings_t *settings, const char *name);
FLUIDSYNTH_API
int fluid_settings_setstr(fluid_settings_t *settings, const char *name, const char *str);
FLUIDSYNTH_API
int fluid_settings_copystr(fluid_settings_t *settings, const char *name, char *str, int len);
FLUIDSYNTH_API
int fluid_settings_dupstr(fluid_settings_t *settings, const char *name, char **str);
FLUIDSYNTH_API
int fluid_settings_getstr_default(fluid_settings_t *settings, const char *name, char **def);
FLUIDSYNTH_API
int fluid_settings_str_equal(fluid_settings_t *settings, const char *name, const char *value);
FLUIDSYNTH_API
int fluid_settings_setnum(fluid_settings_t *settings, const char *name, double val);
FLUIDSYNTH_API
int fluid_settings_getnum(fluid_settings_t *settings, const char *name, double *val);
FLUIDSYNTH_API
int fluid_settings_getnum_default(fluid_settings_t *settings, const char *name, double *val);
FLUIDSYNTH_API
int fluid_settings_getnum_range(fluid_settings_t *settings, const char *name,
double *min, double *max);
FLUIDSYNTH_API
int fluid_settings_setint(fluid_settings_t *settings, const char *name, int val);
FLUIDSYNTH_API
int fluid_settings_getint(fluid_settings_t *settings, const char *name, int *val);
FLUIDSYNTH_API
int fluid_settings_getint_default(fluid_settings_t *settings, const char *name, int *val);
FLUIDSYNTH_API
int fluid_settings_getint_range(fluid_settings_t *settings, const char *name,
int *min, int *max);
/**
* Callback function type used with fluid_settings_foreach_option()
*
* @param data User defined data pointer
* @param name Setting name
* @param option A string option for this setting (iterates through the list)
*/
typedef void (*fluid_settings_foreach_option_t)(void *data, const char *name, const char *option);
FLUIDSYNTH_API
void fluid_settings_foreach_option(fluid_settings_t *settings,
const char *name, void *data,
fluid_settings_foreach_option_t func);
FLUIDSYNTH_API
int fluid_settings_option_count(fluid_settings_t *settings, const char *name);
FLUIDSYNTH_API char *fluid_settings_option_concat(fluid_settings_t *settings,
const char *name,
const char *separator);
/**
* Callback function type used with fluid_settings_foreach()
*
* @param data User defined data pointer
* @param name Setting name
* @param type Setting type (#fluid_types_enum)
*/
typedef void (*fluid_settings_foreach_t)(void *data, const char *name, int type);
FLUIDSYNTH_API
void fluid_settings_foreach(fluid_settings_t *settings, void *data,
fluid_settings_foreach_t func);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_SETTINGS_H */
/* 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_SHELL_H
#define _FLUIDSYNTH_SHELL_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup command_interface Command Interface
*
* Control and configuration interface
*
* The command interface allows you to send textual commands to
* the synthesizer, to parse a command file, or to read commands
* from the stdin or other input streams (like a TCP socket).
*
* For a full list of available commands, type \c help in the
* \ref command_shell or send the same command via a command handler.
* Further documentation can be found at
* https://github.com/FluidSynth/fluidsynth/wiki/UserManual#shell-commands
*
* @{
*/
FLUIDSYNTH_API fluid_istream_t fluid_get_stdin(void);
FLUIDSYNTH_API fluid_ostream_t fluid_get_stdout(void);
FLUIDSYNTH_API char *fluid_get_userconf(char *buf, int len);
FLUIDSYNTH_API char *fluid_get_sysconf(char *buf, int len);
/** @} */
/**
* @defgroup command_handler Command Handler
* @ingroup command_interface
* @brief Handles text commands and reading of configuration files
*
* @{
*/
/** @startlifecycle{Command Handler} */
FLUIDSYNTH_API
fluid_cmd_handler_t *new_fluid_cmd_handler(fluid_synth_t *synth, fluid_midi_router_t *router);
FLUIDSYNTH_API
fluid_cmd_handler_t *new_fluid_cmd_handler2(fluid_settings_t *settings, fluid_synth_t *synth,
fluid_midi_router_t *router, fluid_player_t *player);
FLUIDSYNTH_API
void delete_fluid_cmd_handler(fluid_cmd_handler_t *handler);
/** @endlifecycle */
FLUIDSYNTH_API
void fluid_cmd_handler_set_synth(fluid_cmd_handler_t *handler, fluid_synth_t *synth);
FLUIDSYNTH_API
int fluid_command(fluid_cmd_handler_t *handler, const char *cmd, fluid_ostream_t out);
FLUIDSYNTH_API
int fluid_source(fluid_cmd_handler_t *handler, const char *filename);
/** @} */
/**
* @defgroup command_shell Command Shell
* @ingroup command_interface
*
* Interactive shell to control and configure a synthesizer instance.
*
* If you need a platform independent way to get the standard input
* and output streams, use fluid_get_stdin() and fluid_get_stdout().
*
* For a full list of available commands, type \c help in the shell.
*
* @{
*/
/** @startlifecycle{Command Shell} */
FLUIDSYNTH_API
fluid_shell_t *new_fluid_shell(fluid_settings_t *settings, fluid_cmd_handler_t *handler,
fluid_istream_t in, fluid_ostream_t out, int thread);
FLUIDSYNTH_API
void fluid_usershell(fluid_settings_t *settings, fluid_cmd_handler_t *handler);
FLUIDSYNTH_API void delete_fluid_shell(fluid_shell_t *shell);
/** @endlifecycle */
/** @} */
/**
* @defgroup command_server Command Server
* @ingroup command_interface
*
* TCP socket server for a command handler.
*
* The socket server will open the TCP port set by \ref settings_shell_port
* (default 9800) and starts a new thread and \ref command_handler for each
* incoming connection.
*
* @note The server is only available if libfluidsynth has been compiled
* with network support (enable-network). Without network support, all related
* functions will return FLUID_FAILED or NULL.
*
* @{
*/
/** @startlifecycle{Command Server} */
FLUIDSYNTH_API
fluid_server_t *new_fluid_server(fluid_settings_t *settings,
fluid_synth_t *synth, fluid_midi_router_t *router);
FLUIDSYNTH_API
fluid_server_t *new_fluid_server2(fluid_settings_t *settings,
fluid_synth_t *synth, fluid_midi_router_t *router,
fluid_player_t *player);
FLUIDSYNTH_API void delete_fluid_server(fluid_server_t *server);
FLUIDSYNTH_API int fluid_server_join(fluid_server_t *server);
/** @endlifecycle */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_SHELL_H */
/* 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_TYPES_H
#define _FLUIDSYNTH_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup Types Types
* @brief Type declarations
*
* @{
*/
typedef struct _fluid_hashtable_t fluid_settings_t; /**< Configuration settings instance */
typedef struct _fluid_synth_t fluid_synth_t; /**< Synthesizer instance */
typedef struct _fluid_voice_t fluid_voice_t; /**< Synthesis voice instance */
typedef struct _fluid_sfloader_t fluid_sfloader_t; /**< SoundFont loader plugin */
typedef struct _fluid_sfont_t fluid_sfont_t; /**< SoundFont */
typedef struct _fluid_preset_t fluid_preset_t; /**< SoundFont preset */
typedef struct _fluid_sample_t fluid_sample_t; /**< SoundFont sample */
typedef struct _fluid_mod_t fluid_mod_t; /**< SoundFont modulator */
typedef struct _fluid_audio_driver_t fluid_audio_driver_t; /**< Audio driver instance */
typedef struct _fluid_file_renderer_t fluid_file_renderer_t; /**< Audio file renderer instance */
typedef struct _fluid_player_t fluid_player_t; /**< MIDI player instance */
typedef struct _fluid_midi_event_t fluid_midi_event_t; /**< MIDI event */
typedef struct _fluid_midi_driver_t fluid_midi_driver_t; /**< MIDI driver instance */
typedef struct _fluid_midi_router_t fluid_midi_router_t; /**< MIDI router instance */
typedef struct _fluid_midi_router_rule_t fluid_midi_router_rule_t; /**< MIDI router rule */
typedef struct _fluid_hashtable_t fluid_cmd_hash_t; /**< Command handler hash table */
typedef struct _fluid_shell_t fluid_shell_t; /**< Command shell */
typedef struct _fluid_server_t fluid_server_t; /**< TCP/IP shell server instance */
typedef struct _fluid_event_t fluid_event_t; /**< Sequencer event */
typedef struct _fluid_sequencer_t fluid_sequencer_t; /**< Sequencer instance */
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 struct _fluid_file_callbacks_t fluid_file_callbacks_t; /**< Callback struct to perform custom file loading of soundfonts */
typedef int fluid_istream_t; /**< Input stream descriptor */
typedef int fluid_ostream_t; /**< Output stream descriptor */
typedef short fluid_seq_id_t; /**< Unique client IDs used by the sequencer and #fluid_event_t, obtained by fluid_sequencer_register_client() and fluid_sequencer_register_fluidsynth() */
#if defined(_MSC_VER) && (_MSC_VER < 1800)
typedef __int64 fluid_long_long_t; // even on 32bit windows
#else
/**
* A typedef for C99's type long long, which is at least 64-bit wide, as guaranteed by the C99.
* @p __int64 will be used as replacement for VisualStudio 2010 and older.
*/
typedef long long fluid_long_long_t;
#endif
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_TYPES_H */
/* 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_VERSION_H
#define _FLUIDSYNTH_VERSION_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup misc
*
* @{
*/
#define FLUIDSYNTH_VERSION "2.3.3" /**< String constant of libfluidsynth version. */
#define FLUIDSYNTH_VERSION_MAJOR 2 /**< libfluidsynth major version integer constant. */
#define FLUIDSYNTH_VERSION_MINOR 3 /**< libfluidsynth minor version integer constant. */
#define FLUIDSYNTH_VERSION_MICRO 3 /**< libfluidsynth micro version integer constant. */
FLUIDSYNTH_API void fluid_version(int *major, int *minor, int *micro);
FLUIDSYNTH_API char* fluid_version_str(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_VERSION_H */
/* 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_VOICE_H
#define _FLUIDSYNTH_VOICE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup voices Voice Manipulation
* @ingroup soundfonts
*
* Synthesis voice manipulation functions.
*
* The interface to the synthesizer's voices.
* Examples on using them can be found in the source code of the default SoundFont
* loader (fluid_defsfont.c).
*
* Most of these functions should only be called from within synthesis context,
* such as the SoundFont loader's noteon method.
*
* @{
*/
/**
* Enum used with fluid_voice_add_mod() to specify how to handle duplicate modulators.
*/
enum fluid_voice_add_mod
{
FLUID_VOICE_OVERWRITE, /**< Overwrite any existing matching modulator */
FLUID_VOICE_ADD, /**< Add (sum) modulator amounts */
FLUID_VOICE_DEFAULT /**< For default modulators only, no need to check for duplicates */
};
FLUIDSYNTH_API void fluid_voice_add_mod(fluid_voice_t *voice, fluid_mod_t *mod, int mode);
FLUIDSYNTH_API float fluid_voice_gen_get(fluid_voice_t *voice, int gen);
FLUIDSYNTH_API void fluid_voice_gen_set(fluid_voice_t *voice, int gen, float val);
FLUIDSYNTH_API void fluid_voice_gen_incr(fluid_voice_t *voice, int gen, float val);
FLUIDSYNTH_API unsigned int fluid_voice_get_id(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_get_channel(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_get_key(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_get_actual_key(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_get_velocity(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_get_actual_velocity(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_is_playing(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_is_on(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_is_sustained(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_is_sostenuto(const fluid_voice_t *voice);
FLUIDSYNTH_API int fluid_voice_optimize_sample(fluid_sample_t *s);
FLUIDSYNTH_API void fluid_voice_update_param(fluid_voice_t *voice, int gen);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _FLUIDSYNTH_VOICE_H */
/* 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 _FLUID_LADSPA_H
#define _FLUID_LADSPA_H
#include "fluid_sys.h"
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);
void fluid_ladspa_run(fluid_ladspa_fx_t *fx, 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 buf_stride);
#endif /* _FLUID_LADSPA_H */
/* 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
*/
/* Author: Markus Nentwig, nentwig@users.sourceforge.net
*/
#ifndef _FLUID_MIDIROUTER_H
#define _FLUID_MIDIROUTER_H
#include "fluidsynth_priv.h"
#include "fluid_midi.h"
#include "fluid_sys.h"
#endif
/* 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
*/
#include "fluid_adsr_env.h"
DECLARE_FLUID_RVOICE_FUNCTION(fluid_adsr_env_set_data)
{
fluid_adsr_env_t *env = obj;
fluid_adsr_env_section_t section = param[0].i;
unsigned int count = param[1].i;
fluid_real_t coeff = param[2].real;
fluid_real_t increment = param[3].real;
fluid_real_t min = param[4].real;
fluid_real_t max = param[5].real;
env->data[section].count = count;
env->data[section].coeff = coeff;
env->data[section].increment = increment;
env->data[section].min = min;
env->data[section].max = max;
}
/* 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 _FLUID_ADSR_ENVELOPE_H
#define _FLUID_ADSR_ENVELOPE_H
#include "fluidsynth_priv.h"
#include "fluid_sys.h"
/*
* envelope data
*/
struct _fluid_env_data_t
{
unsigned int count;
fluid_real_t coeff;
fluid_real_t increment;
fluid_real_t min;
fluid_real_t max;
};
/* Indices for envelope tables */
enum fluid_voice_envelope_index
{
FLUID_VOICE_ENVDELAY,
FLUID_VOICE_ENVATTACK,
FLUID_VOICE_ENVHOLD,
FLUID_VOICE_ENVDECAY,
FLUID_VOICE_ENVSUSTAIN,
FLUID_VOICE_ENVRELEASE,
FLUID_VOICE_ENVFINISHED,
FLUID_VOICE_ENVLAST
};
typedef enum fluid_voice_envelope_index fluid_adsr_env_section_t;
typedef struct _fluid_adsr_env_t fluid_adsr_env_t;
struct _fluid_adsr_env_t
{
fluid_env_data_t data[FLUID_VOICE_ENVLAST];
unsigned int count;
fluid_real_t val; /* the current value of the envelope */
fluid_adsr_env_section_t section;
};
/* For performance, all functions are inlined */
static FLUID_INLINE void
fluid_adsr_env_calc(fluid_adsr_env_t *env)
{
fluid_env_data_t *env_data;
fluid_real_t x;
env_data = &env->data[env->section];
/* skip to the next section of the envelope if necessary */
while(env->count >= env_data->count)
{
// If we're switching envelope stages from decay to sustain, force the value to be the end value of the previous stage
// Hmm, should this only apply to volenv? It was so before refactoring, so keep it for now. [DH]
// No, must apply to both, otherwise some voices may sound detuned. [TM] (https://github.com/FluidSynth/fluidsynth/issues/1059)
if(env->section == FLUID_VOICE_ENVDECAY)
{
env->val = env_data->min * env_data->coeff;
}
env_data = &env->data[++env->section];
env->count = 0;
}
/* calculate the envelope value and check for valid range */
x = env_data->coeff * env->val + env_data->increment;
if(x < env_data->min)
{
x = env_data->min;
env->section++;
env->count = 0;
}
else if(x > env_data->max)
{
x = env_data->max;
env->section++;
env->count = 0;
}
else
{
env->count++;
}
env->val = x;
}
/* This one cannot be inlined since it is referenced in
the event queue */
DECLARE_FLUID_RVOICE_FUNCTION(fluid_adsr_env_set_data);
static FLUID_INLINE void
fluid_adsr_env_reset(fluid_adsr_env_t *env)
{
env->count = 0;
env->section = FLUID_VOICE_ENVDELAY;
env->val = 0.0f;
}
static FLUID_INLINE fluid_real_t
fluid_adsr_env_get_val(fluid_adsr_env_t *env)
{
return env->val;
}
static FLUID_INLINE void
fluid_adsr_env_set_val(fluid_adsr_env_t *env, fluid_real_t val)
{
env->val = val;
}
static FLUID_INLINE fluid_adsr_env_section_t
fluid_adsr_env_get_section(fluid_adsr_env_t *env)
{
return env->section;
}
static FLUID_INLINE void
fluid_adsr_env_set_section(fluid_adsr_env_t *env,
fluid_adsr_env_section_t section)
{
env->section = section;
env->count = 0;
}
/* Used for determining which voice to kill.
Returns max amplitude from now, and forward in time.
*/
static FLUID_INLINE fluid_real_t
fluid_adsr_env_get_max_val(fluid_adsr_env_t *env)
{
if(env->section > FLUID_VOICE_ENVATTACK)
{
return env->val * 1000;
}
else
{
return env->data[FLUID_VOICE_ENVATTACK].max;
}
}
#endif
/* 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 _FLUID_CHORUS_H
#define _FLUID_CHORUS_H
#include "fluidsynth_priv.h"
typedef struct _fluid_chorus_t fluid_chorus_t;
/* enum describing each chorus parameter */
enum fluid_chorus_param
{
FLUID_CHORUS_NR, /**< number of delay line */
FLUID_CHORUS_LEVEL, /**< output level */
FLUID_CHORUS_SPEED, /**< lfo frequency */
FLUID_CHORUS_DEPTH, /**< modulation depth */
FLUID_CHORUS_TYPE, /**< type of waveform */
FLUID_CHORUS_PARAM_LAST /* number of enum fluid_chorus_param */
};
/* return a bit flag from param: 2^param */
#define FLUID_CHORPARAM_TO_SETFLAG(param) (1 << param)
/** Flags for fluid_chorus_set() */
typedef enum
{
FLUID_CHORUS_SET_NR = FLUID_CHORPARAM_TO_SETFLAG(FLUID_CHORUS_NR),
FLUID_CHORUS_SET_LEVEL = FLUID_CHORPARAM_TO_SETFLAG(FLUID_CHORUS_LEVEL),
FLUID_CHORUS_SET_SPEED = FLUID_CHORPARAM_TO_SETFLAG(FLUID_CHORUS_SPEED),
FLUID_CHORUS_SET_DEPTH = FLUID_CHORPARAM_TO_SETFLAG(FLUID_CHORUS_DEPTH),
FLUID_CHORUS_SET_TYPE = FLUID_CHORPARAM_TO_SETFLAG(FLUID_CHORUS_TYPE),
/** Value for fluid_chorus_set() which sets all chorus parameters. */
FLUID_CHORUS_SET_ALL = FLUID_CHORUS_SET_NR
| FLUID_CHORUS_SET_LEVEL
| FLUID_CHORUS_SET_SPEED
| FLUID_CHORUS_SET_DEPTH
| FLUID_CHORUS_SET_TYPE,
} fluid_chorus_set_t;
/*
* chorus
*/
fluid_chorus_t *new_fluid_chorus(fluid_real_t sample_rate);
void delete_fluid_chorus(fluid_chorus_t *chorus);
void fluid_chorus_reset(fluid_chorus_t *chorus);
void fluid_chorus_set(fluid_chorus_t *chorus, int set, int nr, fluid_real_t level,
fluid_real_t speed, fluid_real_t depth_ms, int type);
void
fluid_chorus_samplerate_change(fluid_chorus_t *chorus, fluid_real_t sample_rate);
void fluid_chorus_processmix(fluid_chorus_t *chorus, const fluid_real_t *in,
fluid_real_t *left_out, fluid_real_t *right_out);
void fluid_chorus_processreplace(fluid_chorus_t *chorus, const fluid_real_t *in,
fluid_real_t *left_out, fluid_real_t *right_out);
#endif /* _FLUID_CHORUS_H */
/* 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 _FLUID_IIR_FILTER_H
#define _FLUID_IIR_FILTER_H
#include "fluidsynth_priv.h"
typedef struct _fluid_iir_filter_t fluid_iir_filter_t;
DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_init);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_fres);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_q);
void fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
fluid_real_t *dsp_buf, int dsp_buf_count);
void fluid_iir_filter_reset(fluid_iir_filter_t *iir_filter);
void fluid_iir_filter_calc(fluid_iir_filter_t *iir_filter,
fluid_real_t output_rate,
fluid_real_t fres_mod);
/* We can't do information hiding here, as fluid_voice_t includes the struct
without a pointer. */
struct _fluid_iir_filter_t
{
enum fluid_iir_filter_type type; /* specifies the type of this filter */
enum fluid_iir_filter_flags flags; /* additional flags to customize this filter */
/* filter coefficients */
/* The coefficients are normalized to a0. */
/* b0 and b2 are identical => b02 */
fluid_real_t b02; /* b0 / a0 */
fluid_real_t b1; /* b1 / a0 */
fluid_real_t a1; /* a0 / a0 */
fluid_real_t a2; /* a1 / a0 */
fluid_real_t b02_incr;
fluid_real_t b1_incr;
fluid_real_t a1_incr;
fluid_real_t a2_incr;
int filter_coeff_incr_count;
int compensate_incr; /* Flag: If set, must compensate history */
fluid_real_t hist1, hist2; /* Sample history for the IIR filter */
int filter_startup; /* Flag: If set, the filter will be set directly.
Else it changes smoothly. */
fluid_real_t fres; /* the resonance frequency, in cents (not absolute cents) */
fluid_real_t last_fres; /* Current resonance frequency of the IIR filter */
/* Serves as a flag: A deviation between fres and last_fres */
/* indicates, that the filter has to be recalculated. */
fluid_real_t q_lin; /* the q-factor on a linear scale */
fluid_real_t filter_gain; /* Gain correction factor, depends on q */
};
#endif
#include "fluid_lfo.h"
DECLARE_FLUID_RVOICE_FUNCTION(fluid_lfo_set_incr)
{
fluid_lfo_t *lfo = obj;
fluid_real_t increment = param[0].real;
lfo->increment = increment;
}
DECLARE_FLUID_RVOICE_FUNCTION(fluid_lfo_set_delay)
{
fluid_lfo_t *lfo = obj;
unsigned int delay = param[0].i;
lfo->delay = delay;
}
/* 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 _FLUID_LFO_H
#define _FLUID_LFO_H
#include "fluid_sys.h"
typedef struct _fluid_lfo_t fluid_lfo_t;
struct _fluid_lfo_t
{
fluid_real_t val; /* the current value of the LFO */
unsigned int delay; /* the delay of the lfo in samples */
fluid_real_t increment; /* the lfo frequency is converted to a per-buffer increment */
};
static FLUID_INLINE void
fluid_lfo_reset(fluid_lfo_t *lfo)
{
lfo->val = 0.0f;
}
// These two cannot be inlined since they're used by event_dispatch
DECLARE_FLUID_RVOICE_FUNCTION(fluid_lfo_set_incr);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_lfo_set_delay);
static FLUID_INLINE fluid_real_t
fluid_lfo_get_val(fluid_lfo_t *lfo)
{
return lfo->val;
}
static FLUID_INLINE void
fluid_lfo_calc(fluid_lfo_t *lfo, unsigned int cur_delay)
{
if(cur_delay < lfo->delay)
{
return;
}
lfo->val += lfo->increment;
if(lfo->val > (fluid_real_t) 1.0)
{
lfo->increment = -lfo->increment;
lfo->val = (fluid_real_t) 2.0 - lfo->val;
}
else if(lfo->val < (fluid_real_t) -1.0)
{
lfo->increment = -lfo->increment;
lfo->val = (fluid_real_t) -2.0 - lfo->val;
}
}
#endif
/* 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 _FLUID_PHASE_H
#define _FLUID_PHASE_H
/*
* phase
*/
#define FLUID_INTERP_BITS 8
#define FLUID_INTERP_BITS_MASK 0xff000000
#define FLUID_INTERP_BITS_SHIFT 24
#define FLUID_FRACT_MAX ((double)4294967296.0)
/* fluid_phase_t
* Purpose:
* Playing pointer for voice playback
*
* When a sample is played back at a different pitch, the playing pointer in the
* source sample will not advance exactly one sample per output sample.
* This playing pointer is implemented using fluid_phase_t.
* It is a 64 bit number. The higher 32 bits contain the 'index' (number of
* the current sample), the lower 32 bits the fractional part.
*/
typedef uint64_t fluid_phase_t;
/* Purpose:
* Set a to b.
* a: fluid_phase_t
* b: fluid_phase_t
*/
#define fluid_phase_set(a,b) a=b;
#define fluid_phase_set_int(a, b) ((a) = ((uint64_t)(b)) << 32)
/* Purpose:
* Sets the phase a to a phase increment given in b.
* For example, assume b is 0.9. After setting a to it, adding a to
* the playing pointer will advance it by 0.9 samples. */
#define fluid_phase_set_float(a, b) \
(a) = (((uint64_t)(b)) << 32) \
| (uint32_t) (((double)(b) - (int)(b)) * (double)FLUID_FRACT_MAX)
/* create a fluid_phase_t from an index and a fraction value */
#define fluid_phase_from_index_fract(index, fract) \
((((uint64_t)(index)) << 32) + (fract))
/* Purpose:
* Return the index and the fractional part, respectively. */
#define fluid_phase_index(_x) \
((unsigned int)((_x) >> 32))
#define fluid_phase_fract(_x) \
((uint32_t)((_x) & 0xFFFFFFFF))
/* Get the phase index with fractional rounding */
#define fluid_phase_index_round(_x) \
((unsigned int)(((_x) + 0x80000000) >> 32))
/* Purpose:
* Takes the fractional part of the argument phase and
* calculates the corresponding position in the interpolation table.
* The fractional position of the playing pointer is calculated with a quite high
* resolution (32 bits). It would be unpractical to keep a set of interpolation
* coefficients for each possible fractional part...
*/
#define fluid_phase_fract_to_tablerow(_x) \
((unsigned int)(fluid_phase_fract(_x) & FLUID_INTERP_BITS_MASK) >> FLUID_INTERP_BITS_SHIFT)
#define fluid_phase_double(_x) \
((double)(fluid_phase_index(_x)) + ((double)fluid_phase_fract(_x) / FLUID_FRACT_MAX))
/* Purpose:
* Advance a by a step of b (both are fluid_phase_t).
*/
#define fluid_phase_incr(a, b) a += b
/* Purpose:
* Subtract b from a (both are fluid_phase_t).
*/
#define fluid_phase_decr(a, b) a -= b
/* Purpose:
* Subtract b samples from a.
*/
#define fluid_phase_sub_int(a, b) ((a) -= (uint64_t)(b) << 32)
/* Purpose:
* Creates the expression a.index++. */
#define fluid_phase_index_plusplus(a) (((a) += 0x100000000LL)
#endif /* _FLUID_PHASE_H */
/* 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 _FLUID_REV_H
#define _FLUID_REV_H
#include "fluidsynth_priv.h"
typedef struct _fluid_revmodel_t fluid_revmodel_t;
/* enum describing each reverb parameter */
enum fluid_reverb_param
{
FLUID_REVERB_ROOMSIZE, /**< reverb time */
FLUID_REVERB_DAMP, /**< high frequency damping */
FLUID_REVERB_WIDTH, /**< stereo width */
FLUID_REVERB_LEVEL, /**< output level */
FLUID_REVERB_PARAM_LAST /* number of enum fluid_reverb_param */
};
/* return a bit flag from param: 2^param */
#define FLUID_REVPARAM_TO_SETFLAG(param) (1 << param)
/** Flags for fluid_revmodel_set() */
typedef enum
{
FLUID_REVMODEL_SET_ROOMSIZE = FLUID_REVPARAM_TO_SETFLAG(FLUID_REVERB_ROOMSIZE),
FLUID_REVMODEL_SET_DAMPING = FLUID_REVPARAM_TO_SETFLAG(FLUID_REVERB_DAMP),
FLUID_REVMODEL_SET_WIDTH = FLUID_REVPARAM_TO_SETFLAG(FLUID_REVERB_WIDTH),
FLUID_REVMODEL_SET_LEVEL = FLUID_REVPARAM_TO_SETFLAG(FLUID_REVERB_LEVEL),
/** Value for fluid_revmodel_set() which sets all reverb parameters. */
FLUID_REVMODEL_SET_ALL = FLUID_REVMODEL_SET_LEVEL
| FLUID_REVMODEL_SET_WIDTH
| FLUID_REVMODEL_SET_DAMPING
| FLUID_REVMODEL_SET_ROOMSIZE,
} fluid_revmodel_set_t;
/*
* reverb preset
*/
typedef struct _fluid_revmodel_presets_t
{
const char *name;
fluid_real_t roomsize;
fluid_real_t damp;
fluid_real_t width;
fluid_real_t level;
} fluid_revmodel_presets_t;
/*
* reverb
*/
fluid_revmodel_t *
new_fluid_revmodel(fluid_real_t sample_rate_max, fluid_real_t sample_rate);
void delete_fluid_revmodel(fluid_revmodel_t *rev);
void fluid_revmodel_processmix(fluid_revmodel_t *rev, const fluid_real_t *in,
fluid_real_t *left_out, fluid_real_t *right_out);
void fluid_revmodel_processreplace(fluid_revmodel_t *rev, const fluid_real_t *in,
fluid_real_t *left_out, fluid_real_t *right_out);
void fluid_revmodel_reset(fluid_revmodel_t *rev);
void fluid_revmodel_set(fluid_revmodel_t *rev, int set, fluid_real_t roomsize,
fluid_real_t damping, fluid_real_t width, fluid_real_t level);
int fluid_revmodel_samplerate_change(fluid_revmodel_t *rev, fluid_real_t sample_rate);
#endif /* _FLUID_REV_H */
/* 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 _FLUID_RVOICE_H
#define _FLUID_RVOICE_H
#include "fluidsynth_priv.h"
#include "fluid_iir_filter.h"
#include "fluid_adsr_env.h"
#include "fluid_lfo.h"
#include "fluid_phase.h"
#include "fluid_sfont.h"
typedef struct _fluid_rvoice_envlfo_t fluid_rvoice_envlfo_t;
typedef struct _fluid_rvoice_dsp_t fluid_rvoice_dsp_t;
typedef struct _fluid_rvoice_buffers_t fluid_rvoice_buffers_t;
typedef struct _fluid_rvoice_t fluid_rvoice_t;
/* Smallest amplitude that can be perceived (full scale is +/- 0.5)
* 16 bits => 96+4=100 dB dynamic range => 0.00001
* 24 bits => 144-4 = 140 dB dynamic range => 1.e-7
* 1.e-7 * 2 == 2.e-7 :)
*/
#define FLUID_NOISE_FLOOR ((fluid_real_t)2.e-7)
enum fluid_loop
{
FLUID_UNLOOPED = 0,
FLUID_LOOP_DURING_RELEASE = 1,
FLUID_NOTUSED = 2,
FLUID_LOOP_UNTIL_RELEASE = 3
};
/*
* rvoice ticks-based parameters
* These parameters must be updated even if the voice is currently quiet.
*/
struct _fluid_rvoice_envlfo_t
{
/* Note-off minimum length */
unsigned int ticks;
unsigned int noteoff_ticks;
/* vol env */
fluid_adsr_env_t volenv;
/* mod env */
fluid_adsr_env_t modenv;
fluid_real_t modenv_to_fc;
fluid_real_t modenv_to_pitch;
/* mod lfo */
fluid_lfo_t modlfo;
fluid_real_t modlfo_to_fc;
fluid_real_t modlfo_to_pitch;
fluid_real_t modlfo_to_vol;
/* vib lfo */
fluid_lfo_t viblfo;
fluid_real_t viblfo_to_pitch;
};
/*
* rvoice parameters needed for dsp interpolation
*/
struct _fluid_rvoice_dsp_t
{
/* interpolation method, as in fluid_interp in fluidsynth.h */
enum fluid_interp interp_method;
enum fluid_loop samplemode;
/* Flag that is set as soon as the first loop is completed. */
char has_looped;
/* Flag that initiates, that sample-related parameters have to be checked. */
char check_sample_sanity_flag;
fluid_sample_t *sample;
/* sample and loop start and end points (offset in sample memory). */
int start;
int end;
int loopstart;
int loopend; /* Note: first point following the loop (superimposed on loopstart) */
/* Stuff needed for portamento calculations */
fluid_real_t pitchoffset; /* the portamento range in midicents */
fluid_real_t pitchinc; /* the portamento increment in midicents */
/* Stuff needed for phase calculations */
fluid_real_t pitch; /* the pitch in midicents */
fluid_real_t root_pitch_hz;
fluid_real_t output_rate;
/* Stuff needed for amplitude calculations */
fluid_real_t attenuation; /* the attenuation in centibels */
fluid_real_t prev_attenuation; /* the previous attenuation in centibels
used by fluid_rvoice_multi_retrigger_attack() */
fluid_real_t min_attenuation_cB; /* Estimate on the smallest possible attenuation
* during the lifetime of the voice */
fluid_real_t amplitude_that_reaches_noise_floor_nonloop;
fluid_real_t amplitude_that_reaches_noise_floor_loop;
fluid_real_t synth_gain; /* master gain */
/* Dynamic input to the interpolator below */
fluid_real_t amp; /* current linear amplitude */
fluid_real_t amp_incr; /* amplitude increment value for the next FLUID_BUFSIZE samples */
fluid_phase_t phase; /* the phase (current sample offset) of the sample wave */
fluid_real_t phase_incr; /* the phase increment for the next FLUID_BUFSIZE samples */
};
/* Currently left, right, reverb, chorus. To be changed if we
ever add surround positioning, or stereo reverb/chorus */
#define FLUID_RVOICE_MAX_BUFS (4)
/*
* rvoice mixer-related parameters
*/
struct _fluid_rvoice_buffers_t
{
unsigned int count; /* Number of records in "bufs" */
struct
{
/* the actual, linearly interpolated amplitude with which the dsp sample should be mixed into the buf */
fluid_real_t current_amp;
/* the desired amplitude [...] mixed into the buf (directly set by e.g. rapidly changing PAN events) */
fluid_real_t target_amp;
/* Mapping to mixdown buffer index */
int mapping;
} bufs[FLUID_RVOICE_MAX_BUFS];
};
/*
* Hard real-time parameters needed to synthesize a voice
*/
struct _fluid_rvoice_t
{
fluid_rvoice_envlfo_t envlfo;
fluid_rvoice_dsp_t dsp;
fluid_iir_filter_t resonant_filter; /* IIR resonant dsp filter */
fluid_iir_filter_t resonant_custom_filter; /* optional custom/general-purpose IIR resonant filter */
fluid_rvoice_buffers_t buffers;
};
int fluid_rvoice_write(fluid_rvoice_t *voice, fluid_real_t *dsp_buf);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_amp);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_buffers_set_mapping);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_noteoff);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_voiceoff);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_reset);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_multi_retrigger_attack);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_portamento);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_output_rate);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_interp_method);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_root_pitch_hz);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_pitch);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_attenuation);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_min_attenuation_cB);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_viblfo_to_pitch);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_pitch);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_vol);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modlfo_to_fc);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_fc);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_modenv_to_pitch);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_synth_gain);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_start);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_end);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopstart);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_loopend);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_samplemode);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_set_sample);
/* defined in fluid_rvoice_dsp.c */
void fluid_rvoice_dsp_config(void);
int fluid_rvoice_dsp_interpolate_none(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
int fluid_rvoice_dsp_interpolate_linear(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
int fluid_rvoice_dsp_interpolate_4th_order(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
int fluid_rvoice_dsp_interpolate_7th_order(fluid_rvoice_dsp_t *voice, fluid_real_t *FLUID_RESTRICT dsp_buf, int is_looping);
/*
* Combines the most significant 16 bit part of a sample with a potentially present
* least sig. 8 bit part in order to create a 24 bit sample.
*/
static FLUID_INLINE int32_t
fluid_rvoice_get_sample(const short int *dsp_msb, const char *dsp_lsb, unsigned int idx)
{
/* cast sample to unsigned type, so we can safely shift and bitwise or
* without relying on undefined behaviour (should never happen anyway ofc...) */
uint32_t msb = (uint32_t)dsp_msb[idx];
uint8_t lsb = 0U;
/* most soundfonts have 16 bit samples, assume that it's unlikely we
* experience 24 bit samples here */
if(FLUID_UNLIKELY(dsp_lsb != NULL))
{
lsb = (uint8_t)dsp_lsb[idx];
}
return (int32_t)((msb << 8) | lsb);
}
#endif
/* 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
*/
#include "fluid_rvoice_event.h"
#include "fluid_rvoice.h"
#include "fluid_rvoice_mixer.h"
#include "fluid_iir_filter.h"
#include "fluid_lfo.h"
#include "fluid_adsr_env.h"
static int fluid_rvoice_eventhandler_push_LOCAL(fluid_rvoice_eventhandler_t *handler, const fluid_rvoice_event_t *src_event);
static FLUID_INLINE void
fluid_rvoice_event_dispatch(fluid_rvoice_event_t *event)
{
event->method(event->object, event->param);
}
/**
* In order to be able to push more than one event atomically,
* use push for all events, then use flush to commit them to the
* queue. If threadsafe is false, all events are processed immediately. */
int
fluid_rvoice_eventhandler_push_int_real(fluid_rvoice_eventhandler_t *handler,
fluid_rvoice_function_t method, void *object, int intparam,
fluid_real_t realparam)
{
fluid_rvoice_event_t local_event;
local_event.method = method;
local_event.object = object;
local_event.param[0].i = intparam;
local_event.param[1].real = realparam;
return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event);
}
int
fluid_rvoice_eventhandler_push(fluid_rvoice_eventhandler_t *handler, fluid_rvoice_function_t method, void *object, fluid_rvoice_param_t param[MAX_EVENT_PARAMS])
{
fluid_rvoice_event_t local_event;
local_event.method = method;
local_event.object = object;
FLUID_MEMCPY(&local_event.param, param, sizeof(*param) * MAX_EVENT_PARAMS);
return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event);
}
int
fluid_rvoice_eventhandler_push_ptr(fluid_rvoice_eventhandler_t *handler,
fluid_rvoice_function_t method, void *object, void *ptr)
{
fluid_rvoice_event_t local_event;
local_event.method = method;
local_event.object = object;
local_event.param[0].ptr = ptr;
return fluid_rvoice_eventhandler_push_LOCAL(handler, &local_event);
}
static int fluid_rvoice_eventhandler_push_LOCAL(fluid_rvoice_eventhandler_t *handler, const fluid_rvoice_event_t *src_event)
{
fluid_rvoice_event_t *event;
int old_queue_stored = fluid_atomic_int_add(&handler->queue_stored, 1);
event = fluid_ringbuffer_get_inptr(handler->queue, old_queue_stored);
if(event == NULL)
{
fluid_atomic_int_add(&handler->queue_stored, -1);
FLUID_LOG(FLUID_WARN, "Ringbuffer full, try increasing synth.polyphony!");
return FLUID_FAILED; // Buffer full...
}
FLUID_MEMCPY(event, src_event, sizeof(*event));
return FLUID_OK;
}
void
fluid_rvoice_eventhandler_finished_voice_callback(fluid_rvoice_eventhandler_t *eventhandler, fluid_rvoice_t *rvoice)
{
fluid_rvoice_t **vptr = fluid_ringbuffer_get_inptr(eventhandler->finished_voices, 0);
if(vptr == NULL)
{
return; // Buffer full
}
*vptr = rvoice;
fluid_ringbuffer_next_inptr(eventhandler->finished_voices, 1);
}
fluid_rvoice_eventhandler_t *
new_fluid_rvoice_eventhandler(int queuesize,
int finished_voices_size, int bufs, int fx_bufs, int fx_units,
fluid_real_t sample_rate_max, fluid_real_t sample_rate,
int extra_threads, int prio)
{
fluid_rvoice_eventhandler_t *eventhandler = FLUID_NEW(fluid_rvoice_eventhandler_t);
if(eventhandler == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
eventhandler->mixer = NULL;
eventhandler->queue = NULL;
eventhandler->finished_voices = NULL;
fluid_atomic_int_set(&eventhandler->queue_stored, 0);
eventhandler->finished_voices = new_fluid_ringbuffer(finished_voices_size,
sizeof(fluid_rvoice_t *));
if(eventhandler->finished_voices == NULL)
{
goto error_recovery;
}
eventhandler->queue = new_fluid_ringbuffer(queuesize, sizeof(fluid_rvoice_event_t));
if(eventhandler->queue == NULL)
{
goto error_recovery;
}
eventhandler->mixer = new_fluid_rvoice_mixer(bufs, fx_bufs, fx_units,
sample_rate_max, sample_rate, eventhandler, extra_threads, prio);
if(eventhandler->mixer == NULL)
{
goto error_recovery;
}
return eventhandler;
error_recovery:
delete_fluid_rvoice_eventhandler(eventhandler);
return NULL;
}
int
fluid_rvoice_eventhandler_dispatch_count(fluid_rvoice_eventhandler_t *handler)
{
return fluid_ringbuffer_get_count(handler->queue);
}
/**
* Call fluid_rvoice_event_dispatch for all events in queue
* @return number of events dispatched
*/
int
fluid_rvoice_eventhandler_dispatch_all(fluid_rvoice_eventhandler_t *handler)
{
fluid_rvoice_event_t *event;
int result = 0;
while(NULL != (event = fluid_ringbuffer_get_outptr(handler->queue)))
{
fluid_rvoice_event_dispatch(event);
result++;
fluid_ringbuffer_next_outptr(handler->queue);
}
return result;
}
void
delete_fluid_rvoice_eventhandler(fluid_rvoice_eventhandler_t *handler)
{
fluid_return_if_fail(handler != NULL);
delete_fluid_rvoice_mixer(handler->mixer);
delete_fluid_ringbuffer(handler->queue);
delete_fluid_ringbuffer(handler->finished_voices);
FLUID_FREE(handler);
}
/* 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 _FLUID_RVOICE_EVENT_H
#define _FLUID_RVOICE_EVENT_H
#include "fluidsynth_priv.h"
#include "fluid_rvoice_mixer.h"
#include "fluid_ringbuffer.h"
typedef struct _fluid_rvoice_event_t fluid_rvoice_event_t;
struct _fluid_rvoice_event_t
{
fluid_rvoice_function_t method;
void *object;
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
};
/*
* Bridge between the renderer thread and the midi state thread.
* fluid_rvoice_eventhandler_fetch_all() can be called in parallel
* with fluid_rvoice_eventhandler_push/flush()
*/
struct _fluid_rvoice_eventhandler_t
{
fluid_ringbuffer_t *queue; /**< List of fluid_rvoice_event_t */
fluid_atomic_int_t queue_stored; /**< Extras pushed but not flushed */
fluid_ringbuffer_t *finished_voices; /**< return queue from handler, list of fluid_rvoice_t* */
fluid_rvoice_mixer_t *mixer;
};
fluid_rvoice_eventhandler_t *new_fluid_rvoice_eventhandler(
int queuesize, int finished_voices_size, int bufs,
int fx_bufs, int fx_units, fluid_real_t sample_rate_max, fluid_real_t sample_rate, int, int);
void delete_fluid_rvoice_eventhandler(fluid_rvoice_eventhandler_t *);
int fluid_rvoice_eventhandler_dispatch_all(fluid_rvoice_eventhandler_t *);
int fluid_rvoice_eventhandler_dispatch_count(fluid_rvoice_eventhandler_t *);
void fluid_rvoice_eventhandler_finished_voice_callback(fluid_rvoice_eventhandler_t *eventhandler,
fluid_rvoice_t *rvoice);
static FLUID_INLINE void
fluid_rvoice_eventhandler_flush(fluid_rvoice_eventhandler_t *handler)
{
int queue_stored = fluid_atomic_int_get(&handler->queue_stored);
if(queue_stored > 0)
{
fluid_atomic_int_set(&handler->queue_stored, 0);
fluid_ringbuffer_next_inptr(handler->queue, queue_stored);
}
}
/**
* @return next finished voice, or NULL if nothing in queue
*/
static FLUID_INLINE fluid_rvoice_t *
fluid_rvoice_eventhandler_get_finished_voice(fluid_rvoice_eventhandler_t *handler)
{
void *result = fluid_ringbuffer_get_outptr(handler->finished_voices);
if(result == NULL)
{
return NULL;
}
result = * (fluid_rvoice_t **) result;
fluid_ringbuffer_next_outptr(handler->finished_voices);
return result;
}
int fluid_rvoice_eventhandler_push_int_real(fluid_rvoice_eventhandler_t *handler,
fluid_rvoice_function_t method, void *object, int intparam,
fluid_real_t realparam);
int fluid_rvoice_eventhandler_push_ptr(fluid_rvoice_eventhandler_t *handler,
fluid_rvoice_function_t method, void *object, void *ptr);
int fluid_rvoice_eventhandler_push(fluid_rvoice_eventhandler_t *handler,
fluid_rvoice_function_t method, void *object,
fluid_rvoice_param_t param[MAX_EVENT_PARAMS]);
static FLUID_INLINE void
fluid_rvoice_eventhandler_add_rvoice(fluid_rvoice_eventhandler_t *handler,
fluid_rvoice_t *rvoice)
{
fluid_rvoice_eventhandler_push_ptr(handler, fluid_rvoice_mixer_add_voice,
handler->mixer, rvoice);
}
#endif
/* 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 _FLUID_RVOICE_MIXER_H
#define _FLUID_RVOICE_MIXER_H
#include "fluidsynth_priv.h"
#include "fluid_rvoice.h"
#include "fluid_ladspa.h"
typedef struct _fluid_rvoice_mixer_t fluid_rvoice_mixer_t;
int fluid_rvoice_mixer_render(fluid_rvoice_mixer_t *mixer, int blockcount);
int fluid_rvoice_mixer_get_bufs(fluid_rvoice_mixer_t *mixer,
fluid_real_t **left, fluid_real_t **right);
int fluid_rvoice_mixer_get_fx_bufs(fluid_rvoice_mixer_t *mixer,
fluid_real_t **fx_left, fluid_real_t **fx_right);
int fluid_rvoice_mixer_get_bufcount(fluid_rvoice_mixer_t *mixer);
#if WITH_PROFILING
int fluid_rvoice_mixer_get_active_voices(fluid_rvoice_mixer_t *mixer);
#endif
fluid_rvoice_mixer_t *new_fluid_rvoice_mixer(int buf_count, int fx_buf_count, int fx_units,
fluid_real_t sample_rate_max, fluid_real_t sample_rate,
fluid_rvoice_eventhandler_t *, int, int);
void delete_fluid_rvoice_mixer(fluid_rvoice_mixer_t *);
void
fluid_rvoice_mixer_set_reverb_full(const fluid_rvoice_mixer_t *mixer,
int fx_group, int set, const double values[]);
double
fluid_rvoice_mixer_reverb_get_param(const fluid_rvoice_mixer_t *mixer,
int fx_group, int param);
void
fluid_rvoice_mixer_set_chorus_full(const fluid_rvoice_mixer_t *mixer,
int fx_group, int set, const double values[]);
double
fluid_rvoice_mixer_chorus_get_param(const fluid_rvoice_mixer_t *mixer,
int fx_group, int param);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_add_voice);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_samplerate);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_polyphony);
/* @deprecated */
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_chorus_enabled);
/* @deprecated */
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_reverb_enabled);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_reverb_enable);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_chorus_enable);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_chorus_params);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_reverb_params);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_reset_reverb);
DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_reset_chorus);
void fluid_rvoice_mixer_set_mix_fx(fluid_rvoice_mixer_t *mixer, int on);
#ifdef LADSPA
void fluid_rvoice_mixer_set_ladspa(fluid_rvoice_mixer_t *mixer,
fluid_ladspa_fx_t *ladspa_fx, int audio_groups);
#endif
#endif
/* FluidSynth - A Software Synthesizer
*
* Copyright (C) 2003 Peter Hanappe and others.
*
* SoundFont loading code borrowed from Smurf SoundFont Editor by Josh Green
*
* 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 _FLUID_DEFSFONT_H
#define _FLUID_DEFSFONT_H
#include "fluidsynth.h"
#include "fluidsynth_priv.h"
#include "fluid_sffile.h"
#include "fluid_list.h"
#include "fluid_mod.h"
#include "fluid_gen.h"
/*-----------------------------------sfont.h----------------------------*/
#define SF_SAMPMODES_LOOP 1
#define SF_SAMPMODES_UNROLL 2
#define SF_MIN_SAMPLERATE 400
#define SF_MAX_SAMPLERATE 50000
#define SF_MIN_SAMPLE_LENGTH 32
/***************************************************************
*
* FORWARD DECLARATIONS
*/
typedef struct _fluid_defsfont_t fluid_defsfont_t;
typedef struct _fluid_defpreset_t fluid_defpreset_t;
typedef struct _fluid_preset_zone_t fluid_preset_zone_t;
typedef struct _fluid_inst_t fluid_inst_t;
typedef struct _fluid_inst_zone_t fluid_inst_zone_t; /**< Soundfont Instrument Zone */
typedef struct _fluid_voice_zone_t fluid_voice_zone_t;
/* defines the velocity and key range for a zone */
struct _fluid_zone_range_t
{
int keylo;
int keyhi;
int vello;
int velhi;
unsigned char ignore; /* set to TRUE for legato playing to ignore this range zone */
};
/* Stored on a preset zone to keep track of the inst zones that could start a voice
* and their combined preset zone/instument zone ranges */
struct _fluid_voice_zone_t
{
fluid_inst_zone_t *inst_zone;
fluid_zone_range_t range;
};
/*
Public interface
*/
fluid_sfont_t *fluid_defsfloader_load(fluid_sfloader_t *loader, const char *filename);
int fluid_defsfont_sfont_delete(fluid_sfont_t *sfont);
const char *fluid_defsfont_sfont_get_name(fluid_sfont_t *sfont);
fluid_preset_t *fluid_defsfont_sfont_get_preset(fluid_sfont_t *sfont, int bank, int prenum);
void fluid_defsfont_sfont_iteration_start(fluid_sfont_t *sfont);
fluid_preset_t *fluid_defsfont_sfont_iteration_next(fluid_sfont_t *sfont);
void fluid_defpreset_preset_delete(fluid_preset_t *preset);
const char *fluid_defpreset_preset_get_name(fluid_preset_t *preset);
int fluid_defpreset_preset_get_banknum(fluid_preset_t *preset);
int fluid_defpreset_preset_get_num(fluid_preset_t *preset);
int fluid_defpreset_preset_noteon(fluid_preset_t *preset, fluid_synth_t *synth, int chan, int key, int vel);
int fluid_zone_inside_range(fluid_zone_range_t *zone_range, int key, int vel);
/*
* fluid_defsfont_t
*/
struct _fluid_defsfont_t
{
const fluid_file_callbacks_t *fcbs; /* the file callbacks used to load this Soundfont */
char *filename; /* the filename of this soundfont */
unsigned int samplepos; /* the position in the file at which the sample data starts */
unsigned int samplesize; /* the size of the sample data in bytes */
short *sampledata; /* the sample data, loaded in ram */
unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit sample support */
unsigned int sample24size; /* length within sffd of the sm24 chunk */
char *sample24data; /* if not NULL, the least significant byte of the 24bit sample data, loaded in ram */
fluid_sfont_t *sfont; /* pointer to parent sfont */
fluid_list_t *sample; /* the samples in this soundfont */
fluid_list_t *preset; /* the presets of this soundfont */
fluid_list_t *inst; /* the instruments of this soundfont */
int mlock; /* Should we try memlock (avoid swapping)? */
int dynamic_samples; /* Enables dynamic sample loading if set */
fluid_list_t *preset_iter_cur; /* the current preset in the iteration */
};
fluid_defsfont_t *new_fluid_defsfont(fluid_settings_t *settings);
int delete_fluid_defsfont(fluid_defsfont_t *defsfont);
int fluid_defsfont_load(fluid_defsfont_t *defsfont, const fluid_file_callbacks_t *file_callbacks, const char *file);
const char *fluid_defsfont_get_name(fluid_defsfont_t *defsfont);
fluid_preset_t *fluid_defsfont_get_preset(fluid_defsfont_t *defsfont, int bank, int prenum);
void fluid_defsfont_iteration_start(fluid_defsfont_t *defsfont);
fluid_preset_t *fluid_defsfont_iteration_next(fluid_defsfont_t *defsfont);
int fluid_defsfont_load_sampledata(fluid_defsfont_t *defsfont, SFData *sfdata, fluid_sample_t *sample);
int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdata);
int fluid_defsfont_add_sample(fluid_defsfont_t *defsfont, fluid_sample_t *sample);
int fluid_defsfont_add_preset(fluid_defsfont_t *defsfont, fluid_defpreset_t *defpreset);
/*
* fluid_preset_t
*/
struct _fluid_defpreset_t
{
fluid_defpreset_t *next;
char name[21]; /* the name of the preset */
unsigned int bank; /* the bank number */
unsigned int num; /* the preset number */
fluid_preset_zone_t *global_zone; /* the global zone of the preset */
fluid_preset_zone_t *zone; /* the chained list of preset zones */
int pinned; /* preset samples pinned to sample cache? */
};
fluid_defpreset_t *new_fluid_defpreset(void);
void delete_fluid_defpreset(fluid_defpreset_t *defpreset);
fluid_defpreset_t *fluid_defpreset_next(fluid_defpreset_t *defpreset);
int fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset, SFPreset *sfpreset, fluid_defsfont_t *defsfont, SFData *sfdata);
int fluid_defpreset_set_global_zone(fluid_defpreset_t *defpreset, fluid_preset_zone_t *zone);
int fluid_defpreset_add_zone(fluid_defpreset_t *defpreset, fluid_preset_zone_t *zone);
fluid_preset_zone_t *fluid_defpreset_get_zone(fluid_defpreset_t *defpreset);
fluid_preset_zone_t *fluid_defpreset_get_global_zone(fluid_defpreset_t *defpreset);
int fluid_defpreset_get_banknum(fluid_defpreset_t *defpreset);
int fluid_defpreset_get_num(fluid_defpreset_t *defpreset);
const char *fluid_defpreset_get_name(fluid_defpreset_t *defpreset);
int fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int chan, int key, int vel);
/*
* fluid_preset_zone
*/
struct _fluid_preset_zone_t
{
fluid_preset_zone_t *next;
char *name;
fluid_inst_t *inst;
fluid_list_t *voice_zone;
fluid_zone_range_t range;
fluid_gen_t gen[GEN_LAST];
fluid_mod_t *mod; /* List of modulators */
};
fluid_preset_zone_t *new_fluid_preset_zone(char *name);
void delete_fluid_list_mod(fluid_mod_t *mod);
void delete_fluid_preset_zone(fluid_preset_zone_t *zone);
fluid_preset_zone_t *fluid_preset_zone_next(fluid_preset_zone_t *zone);
int fluid_preset_zone_import_sfont(fluid_preset_zone_t *zone, fluid_preset_zone_t *global_zone, SFZone *sfzone, fluid_defsfont_t *defssfont, SFData *sfdata);
fluid_inst_t *fluid_preset_zone_get_inst(fluid_preset_zone_t *zone);
/*
* fluid_inst_t
*/
struct _fluid_inst_t
{
char name[21];
int source_idx; /* Index of instrument in source Soundfont */
fluid_inst_zone_t *global_zone;
fluid_inst_zone_t *zone;
};
fluid_inst_t *new_fluid_inst(void);
fluid_inst_t *fluid_inst_import_sfont(int inst_idx, fluid_defsfont_t *defsfont, SFData *sfdata);
void delete_fluid_inst(fluid_inst_t *inst);
int fluid_inst_set_global_zone(fluid_inst_t *inst, fluid_inst_zone_t *zone);
int fluid_inst_add_zone(fluid_inst_t *inst, fluid_inst_zone_t *zone);
fluid_inst_zone_t *fluid_inst_get_zone(fluid_inst_t *inst);
fluid_inst_zone_t *fluid_inst_get_global_zone(fluid_inst_t *inst);
/*
* fluid_inst_zone_t
*/
struct _fluid_inst_zone_t
{
fluid_inst_zone_t *next;
char *name;
fluid_sample_t *sample;
fluid_zone_range_t range;
fluid_gen_t gen[GEN_LAST];
fluid_mod_t *mod; /* List of modulators */
};
fluid_inst_zone_t *new_fluid_inst_zone(char *name);
void delete_fluid_inst_zone(fluid_inst_zone_t *zone);
fluid_inst_zone_t *fluid_inst_zone_next(fluid_inst_zone_t *zone);
int fluid_inst_zone_import_sfont(fluid_inst_zone_t *inst_zone, fluid_inst_zone_t *global_inst_zone, SFZone *sfzone, fluid_defsfont_t *defsfont, SFData *sfdata);
fluid_sample_t *fluid_inst_zone_get_sample(fluid_inst_zone_t *zone);
int fluid_sample_import_sfont(fluid_sample_t *sample, SFSample *sfsample, fluid_defsfont_t *defsfont);
int fluid_sample_in_rom(fluid_sample_t *sample);
#endif /* _FLUID_SFONT_H */
#ifndef _FLUID_INSTPATCH_H
#define _FLUID_INSTPATCH_H
#include "fluid_sfont.h"
#include "fluid_settings.h"
void fluid_instpatch_init(void);
void fluid_instpatch_deinit(void);
fluid_sfloader_t *new_fluid_instpatch_loader(fluid_settings_t *settings);
int fluid_instpatch_supports_multi_init(void);
#endif // _FLUID_INSTPATCH_H
/* FluidSynth - A Software Synthesizer
*
* Copyright (C) 2003 Peter Hanappe and others.
*
* SoundFont file loading code borrowed from Smurf SoundFont Editor
* Copyright (C) 1999-2001 Josh Green
*
* 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
*/
/* CACHED SAMPLE DATA LOADER
*
* This is a wrapper around fluid_sffile_read_sample_data that attempts to cache the read
* data across all FluidSynth instances in a global (process-wide) list.
*/
#include "fluid_samplecache.h"
#include "fluid_sys.h"
#include "fluid_list.h"
typedef struct _fluid_samplecache_entry_t fluid_samplecache_entry_t;
struct _fluid_samplecache_entry_t
{
/* The following members all form the cache key */
char *filename;
time_t modification_time;
unsigned int sf_samplepos;
unsigned int sf_samplesize;
unsigned int sf_sample24pos;
unsigned int sf_sample24size;
unsigned int sample_start;
unsigned int sample_end;
int sample_type;
/* End of cache key members */
short *sample_data;
char *sample_data24;
int sample_count;
int num_references;
int mlocked;
};
static fluid_list_t *samplecache_list = NULL;
static fluid_mutex_t samplecache_mutex = FLUID_MUTEX_INIT;
static fluid_samplecache_entry_t *new_samplecache_entry(SFData *sf, unsigned int sample_start,
unsigned int sample_end, int sample_type, time_t mtime);
static fluid_samplecache_entry_t *get_samplecache_entry(SFData *sf, unsigned int sample_start,
unsigned int sample_end, int sample_type, time_t mtime);
static void delete_samplecache_entry(fluid_samplecache_entry_t *entry);
static int fluid_get_file_modification_time(char *filename, time_t *modification_time);
/* PUBLIC INTERFACE */
int fluid_samplecache_load(SFData *sf,
unsigned int sample_start, unsigned int sample_end, int sample_type,
int try_mlock, short **sample_data, char **sample_data24)
{
fluid_samplecache_entry_t *entry;
int ret;
time_t mtime;
fluid_mutex_lock(samplecache_mutex);
if(fluid_get_file_modification_time(sf->fname, &mtime) == FLUID_FAILED)
{
mtime = 0;
}
entry = get_samplecache_entry(sf, sample_start, sample_end, sample_type, mtime);
if(entry == NULL)
{
fluid_mutex_unlock(samplecache_mutex);
entry = new_samplecache_entry(sf, sample_start, sample_end, sample_type, mtime);
if(entry == NULL)
{
ret = -1;
goto unlock_exit;
}
fluid_mutex_lock(samplecache_mutex);
samplecache_list = fluid_list_prepend(samplecache_list, entry);
}
fluid_mutex_unlock(samplecache_mutex);
if(try_mlock && !entry->mlocked)
{
/* Lock the memory to disable paging. It's okay if this fails. It
* probably means that the user doesn't have the required permission. */
if(fluid_mlock(entry->sample_data, entry->sample_count * sizeof(short)) == 0)
{
if(entry->sample_data24 != NULL)
{
entry->mlocked = (fluid_mlock(entry->sample_data24, entry->sample_count) == 0);
}
else
{
entry->mlocked = TRUE;
}
if(!entry->mlocked)
{
fluid_munlock(entry->sample_data, entry->sample_count * sizeof(short));
FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible.");
}
}
}
entry->num_references++;
*sample_data = entry->sample_data;
*sample_data24 = entry->sample_data24;
ret = entry->sample_count;
unlock_exit:
return ret;
}
int fluid_samplecache_unload(const short *sample_data)
{
fluid_list_t *entry_list;
fluid_samplecache_entry_t *entry;
int ret;
fluid_mutex_lock(samplecache_mutex);
entry_list = samplecache_list;
while(entry_list)
{
entry = (fluid_samplecache_entry_t *)fluid_list_get(entry_list);
if(sample_data == entry->sample_data)
{
entry->num_references--;
if(entry->num_references == 0)
{
if(entry->mlocked)
{
fluid_munlock(entry->sample_data, entry->sample_count * sizeof(short));
if(entry->sample_data24 != NULL)
{
fluid_munlock(entry->sample_data24, entry->sample_count);
}
}
samplecache_list = fluid_list_remove(samplecache_list, entry);
delete_samplecache_entry(entry);
}
ret = FLUID_OK;
goto unlock_exit;
}
entry_list = fluid_list_next(entry_list);
}
FLUID_LOG(FLUID_ERR, "Trying to free sample data not found in cache.");
ret = FLUID_FAILED;
unlock_exit:
fluid_mutex_unlock(samplecache_mutex);
return ret;
}
/* Private functions */
static fluid_samplecache_entry_t *new_samplecache_entry(SFData *sf,
unsigned int sample_start,
unsigned int sample_end,
int sample_type,
time_t mtime)
{
fluid_samplecache_entry_t *entry;
entry = FLUID_NEW(fluid_samplecache_entry_t);
if(entry == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
return NULL;
}
FLUID_MEMSET(entry, 0, sizeof(*entry));
entry->filename = FLUID_STRDUP(sf->fname);
if(entry->filename == NULL)
{
FLUID_LOG(FLUID_ERR, "Out of memory");
goto error_exit;
}
entry->sf_samplepos = sf->samplepos;
entry->sf_samplesize = sf->samplesize;
entry->sf_sample24pos = sf->sample24pos;
entry->sf_sample24size = sf->sample24size;
entry->sample_start = sample_start;
entry->sample_end = sample_end;
entry->sample_type = sample_type;
entry->modification_time = mtime;
entry->sample_count = fluid_sffile_read_sample_data(sf, sample_start, sample_end, sample_type,
&entry->sample_data, &entry->sample_data24);
if(entry->sample_count < 0)
{
goto error_exit;
}
return entry;
error_exit:
delete_samplecache_entry(entry);
return NULL;
}
static void delete_samplecache_entry(fluid_samplecache_entry_t *entry)
{
fluid_return_if_fail(entry != NULL);
FLUID_FREE(entry->filename);
FLUID_FREE(entry->sample_data);
FLUID_FREE(entry->sample_data24);
FLUID_FREE(entry);
}
static fluid_samplecache_entry_t *get_samplecache_entry(SFData *sf,
unsigned int sample_start,
unsigned int sample_end,
int sample_type,
time_t mtime)
{
fluid_list_t *entry_list;
fluid_samplecache_entry_t *entry;
entry_list = samplecache_list;
while(entry_list)
{
entry = (fluid_samplecache_entry_t *)fluid_list_get(entry_list);
if((FLUID_STRCMP(sf->fname, entry->filename) == 0) &&
(mtime == entry->modification_time) &&
(sf->samplepos == entry->sf_samplepos) &&
(sf->samplesize == entry->sf_samplesize) &&
(sf->sample24pos == entry->sf_sample24pos) &&
(sf->sample24size == entry->sf_sample24size) &&
(sample_start == entry->sample_start) &&
(sample_end == entry->sample_end) &&
(sample_type == entry->sample_type))
{
return entry;
}
entry_list = fluid_list_next(entry_list);
}
return NULL;
}
static int fluid_get_file_modification_time(char *filename, time_t *modification_time)
{
fluid_stat_buf_t buf;
if(fluid_stat(filename, &buf))
{
return FLUID_FAILED;
}
*modification_time = buf.st_mtime;
return FLUID_OK;
}
/* Only used for tests */
int fluid_samplecache_count_entries(void)
{
fluid_list_t *entry;
int count = 0;
fluid_mutex_lock(samplecache_mutex);
for(entry = samplecache_list; entry != NULL; entry = fluid_list_next(entry))
{
count++;
}
fluid_mutex_unlock(samplecache_mutex);
return count;
}
/* 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 _FLUID_SAMPLECACHE_H
#define _FLUID_SAMPLECACHE_H
#include "fluid_sfont.h"
#include "fluid_sffile.h"
int fluid_samplecache_load(SFData *sf,
unsigned int sample_start, unsigned int sample_end, int sample_type,
int try_mlock, short **data, char **data24);
int fluid_samplecache_unload(const short *sample_data);
/* Only used for tests */
int fluid_samplecache_count_entries(void);
#endif /* _FLUID_SAMPLECACHE_H */
/* FluidSynth - A Software Synthesizer
*
* Copyright (C) 2003 Peter Hanappe and others.
*
* SoundFont loading code borrowed from Smurf SoundFont Editor by Josh Green
*
* 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 _FLUID_SFFILE_H
#define _FLUID_SFFILE_H
#include "fluid_gen.h"
#include "fluid_list.h"
#include "fluid_mod.h"
#include "fluidsynth.h"
#include "fluid_sys.h"
/* Sound Font structure defines */
/* Forward declarations */
typedef union _SFGenAmount SFGenAmount;
typedef struct _SFVersion SFVersion;
typedef struct _SFMod SFMod;
typedef struct _SFGen SFGen;
typedef struct _SFZone SFZone;
typedef struct _SFSample SFSample;
typedef struct _SFInst SFInst;
typedef struct _SFPreset SFPreset;
typedef struct _SFData SFData;
typedef struct _SFChunk SFChunk;
struct _SFVersion
{
/* version structure */
unsigned short major;
unsigned short minor;
};
struct _SFMod
{
/* Modulator structure */
unsigned short src; /* source modulator */
unsigned short dest; /* destination generator */
signed short amount; /* signed, degree of modulation */
unsigned short amtsrc; /* second source controls amnt of first */
unsigned short trans; /* transform applied to source */
};
union _SFGenAmount /* Generator amount structure */
{
signed short sword; /* signed 16 bit value */
unsigned short uword; /* unsigned 16 bit value */
struct
{
unsigned char lo; /* low value for ranges */
unsigned char hi; /* high value for ranges */
} range;
};
struct _SFGen
{
/* Generator structure */
unsigned short id; /* generator ID */
SFGenAmount amount; /* generator value */
};
struct _SFZone
{
/* Sample/instrument zone structure */
fluid_list_t *gen; /* list of generators */
fluid_list_t *mod; /* list of modulators */
};
struct _SFSample
{
/* Sample structure */
char name[21]; /* Name of sample */
int idx; /* Index of this instrument in the Soundfont */
unsigned int start; /* Offset in sample area to start of sample */
unsigned int end; /* Offset from start to end of sample,
this is the last point of the
sample, the SF spec has this as the
1st point after, corrected on
load/save */
unsigned int loopstart; /* Offset from start to start of loop */
unsigned int loopend; /* Offset from start to end of loop,
marks the first point after loop,
whose sample value is ideally
equivalent to loopstart */
unsigned int samplerate; /* Sample rate recorded at */
unsigned char origpitch; /* root midi key number */
signed char pitchadj; /* pitch correction in cents */
unsigned short sampletype; /* 1 mono,2 right,4 left,linked 8,0x8000=ROM */
fluid_sample_t *fluid_sample; /* Imported sample (fixed up in fluid_defsfont_load) */
};
struct _SFInst
{
/* Instrument structure */
char name[21]; /* Name of instrument */
int idx; /* Index of this instrument in the Soundfont */
fluid_list_t *zone; /* list of instrument zones */
};
struct _SFPreset
{
/* Preset structure */
char name[21]; /* preset name */
unsigned short prenum; /* preset number */
unsigned short bank; /* bank number */
fluid_list_t *zone; /* list of preset zones */
};
/* NOTE: sffd is also used to determine if sound font is new (NULL) */
struct _SFData
{
/* Sound font data structure */
SFVersion version; /* sound font version */
SFVersion romver; /* ROM version */
unsigned int filesize;
unsigned int samplepos; /* position within sffd of the sample chunk */
unsigned int samplesize; /* length within sffd of the sample chunk */
unsigned int sample24pos; /* position within sffd of the sm24 chunk, set to zero if no 24 bit
sample support */
unsigned int sample24size; /* length within sffd of the sm24 chunk */
unsigned int hydrapos;
unsigned int hydrasize;
char *fname; /* file name */
FILE *sffd; /* loaded sfont file descriptor */
const fluid_file_callbacks_t *fcbs; /* file callbacks used to read this file */
fluid_rec_mutex_t mtx; /* this mutex can be used to synchronize calls to fcbs when using multiple threads (e.g. SF3 loading) */
fluid_list_t *info; /* linked list of info strings (1st byte is ID) */
fluid_list_t *preset; /* linked list of preset info */
fluid_list_t *inst; /* linked list of instrument info */
fluid_list_t *sample; /* linked list of sample info */
};
/* functions */
/*-----------------------------------sffile.h----------------------------*/
/*
File structures and routines (used to be in sffile.h)
*/
/* sfont file data structures */
struct _SFChunk
{
/* RIFF file chunk structure */
unsigned int id; /* chunk id */
unsigned int size; /* size of the following chunk */
};
/* Public functions */
SFData *fluid_sffile_open(const char *fname, const fluid_file_callbacks_t *fcbs);
void fluid_sffile_close(SFData *sf);
int fluid_sffile_parse_presets(SFData *sf);
int fluid_sffile_read_sample_data(SFData *sf, unsigned int sample_start, unsigned int sample_end,
int sample_type, short **data, char **data24);
/* extern only for unit test purposes */
int load_igen(SFData *sf, int size);
int load_pgen(SFData *sf, int size);
void delete_preset(SFPreset *preset);
void delete_inst(SFInst *inst);
void delete_zone(SFZone *zone);
#endif /* _FLUID_SFFILE_H */
/* 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 _PRIV_FLUID_SFONT_H
#define _PRIV_FLUID_SFONT_H
#include "fluidsynth.h"
int fluid_sample_validate(fluid_sample_t *sample, unsigned int max_end);
int fluid_sample_sanitize_loop(fluid_sample_t *sample, unsigned int max_end);
/*
* Utility macros to access soundfonts, presets, and samples
*/
#define fluid_sfloader_delete(_loader) { if ((_loader) && (_loader)->free) (*(_loader)->free)(_loader); }
#define fluid_sfloader_load(_loader, _filename) (*(_loader)->load)(_loader, _filename)
#define fluid_sfont_delete_internal(_sf) ( ((_sf) && (_sf)->free)? (*(_sf)->free)(_sf) : 0)
#define fluid_preset_delete_internal(_preset) \
{ if ((_preset) && (_preset)->free) { (*(_preset)->free)(_preset); }}
#define fluid_preset_noteon(_preset,_synth,_ch,_key,_vel) \
(*(_preset)->noteon)(_preset,_synth,_ch,_key,_vel)
#define fluid_preset_notify(_preset,_reason,_chan) \
( ((_preset) && (_preset)->notify) ? (*(_preset)->notify)(_preset,_reason,_chan) : FLUID_OK )
#define fluid_sample_incr_ref(_sample) { (_sample)->refcount++; }
#define fluid_sample_decr_ref(_sample) \
(_sample)->refcount--; \
if (((_sample)->refcount == 0) && ((_sample)->notify)) \
(*(_sample)->notify)(_sample, FLUID_SAMPLE_DONE);
/**
* File callback structure to enable custom soundfont loading (e.g. from memory).
*/
struct _fluid_file_callbacks_t
{
fluid_sfloader_callback_open_t fopen;
fluid_sfloader_callback_read_t fread;
fluid_sfloader_callback_seek_t fseek;
fluid_sfloader_callback_close_t fclose;
fluid_sfloader_callback_tell_t ftell;
};
/**
* SoundFont loader structure.
*/
struct _fluid_sfloader_t
{
void *data; /**< User defined data pointer used by _fluid_sfloader_t::load() */
/** Callback structure specifying file operations used during soundfont loading to allow custom loading, such as from memory */
fluid_file_callbacks_t file_callbacks;
fluid_sfloader_free_t free;
fluid_sfloader_load_t load;
};
/**
* Virtual SoundFont instance structure.
*/
struct _fluid_sfont_t
{
void *data; /**< User defined data */
int id; /**< SoundFont ID */
int refcount; /**< SoundFont reference count (1 if no presets referencing it) */
int bankofs; /**< Bank offset */
fluid_sfont_free_t free;
fluid_sfont_get_name_t get_name;
fluid_sfont_get_preset_t get_preset;
fluid_sfont_iteration_start_t iteration_start;
fluid_sfont_iteration_next_t iteration_next;
};
/**
* Virtual SoundFont preset.
*/
struct _fluid_preset_t
{
void *data; /**< User supplied data */
fluid_sfont_t *sfont; /**< Parent virtual SoundFont */
fluid_preset_free_t free;
fluid_preset_get_name_t get_name;
fluid_preset_get_banknum_t get_banknum;
fluid_preset_get_num_t get_num;
fluid_preset_noteon_t noteon;
/**
* Virtual SoundFont preset notify method.
* @param preset Virtual SoundFont preset
* @param reason #FLUID_PRESET_SELECTED or #FLUID_PRESET_UNSELECTED
* @param chan MIDI channel number
* @return Should return #FLUID_OK
*
* Implement this optional method if the preset needs to be notified about
* preset select and unselect events.
*
* This method may be called from within synthesis context and therefore
* should be as efficient as possible and not perform any operations considered
* bad for realtime audio output (memory allocations and other OS calls).
*/
int (*notify)(fluid_preset_t *preset, int reason, int chan);
};
/**
* Virtual SoundFont sample.
*/
struct _fluid_sample_t
{
char name[21]; /**< Sample name */
/* The following four sample pointers store the original pointers from the Soundfont
* file. They are never changed after loading and are used to re-create the
* actual sample pointers after a sample has been unloaded and loaded again. The
* actual sample pointers get modified during loading for SF3 (compressed) samples
* and individually loaded SF2 samples. */
unsigned int source_start;
unsigned int source_end;
unsigned int source_loopstart;
unsigned int source_loopend;
unsigned int start; /**< Start index */
unsigned int end; /**< End index, index of last valid sample point (contrary to SF spec) */
unsigned int loopstart; /**< Loop start index */
unsigned int loopend; /**< Loop end index, first point following the loop (superimposed on loopstart) */
unsigned int samplerate; /**< Sample rate */
int origpitch; /**< Original pitch (MIDI note number, 0-127) */
int pitchadj; /**< Fine pitch adjustment (+/- 99 cents) */
int sampletype; /**< Specifies the type of this sample as indicated by the #fluid_sample_type enum */
int auto_free; /**< TRUE if _fluid_sample_t::data and _fluid_sample_t::data24 should be freed upon sample destruction */
short *data; /**< Pointer to the sample's 16 bit PCM data */
char *data24; /**< If not NULL, pointer to the least significant byte counterparts of each sample data point in order to create 24 bit audio samples */
int amplitude_that_reaches_noise_floor_is_valid; /**< Indicates if \a amplitude_that_reaches_noise_floor is valid (TRUE), set to FALSE initially to calculate. */
double amplitude_that_reaches_noise_floor; /**< The amplitude at which the sample's loop will be below the noise floor. For voice off optimization, calculated automatically. */
unsigned int refcount; /**< Count of voices using this sample */
int preset_count; /**< Count of selected presets using this sample (used for dynamic sample loading) */
/**
* Implement this function to receive notification when sample is no longer used.
* @param sample Virtual SoundFont sample
* @param reason #FLUID_SAMPLE_DONE only currently
* @return Should return #FLUID_OK
*/
int (*notify)(fluid_sample_t *sample, int reason);
};
#endif /* _PRIV_FLUID_SFONT_H */
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment