Merge branch 'linked-modulators' of https://github.com/FluidSynth/fluidsynth into linked-modulators

Merge updated upstream branch.
This commit is contained in:
jjceresa 2019-10-06 00:58:24 +02:00
commit 6264bb2922
15 changed files with 97 additions and 83 deletions

View file

@ -29,7 +29,7 @@ set ( PACKAGE "fluidsynth" )
# FluidSynth package version
set ( FLUIDSYNTH_VERSION_MAJOR 2 )
set ( FLUIDSYNTH_VERSION_MINOR 0 )
set ( FLUIDSYNTH_VERSION_MICRO 6 )
set ( FLUIDSYNTH_VERSION_MICRO 7 )
set ( VERSION "${FLUIDSYNTH_VERSION_MAJOR}.${FLUIDSYNTH_VERSION_MINOR}.${FLUIDSYNTH_VERSION_MICRO}" )
set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
@ -43,8 +43,8 @@ set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
# if any interfaces have been removed/changed (compatibility broken): AGE=0
# This is not exactly the same algorithm as the libtool one, but the results are the same.
set ( LIB_VERSION_CURRENT 2 )
set ( LIB_VERSION_AGE 1 )
set ( LIB_VERSION_REVISION 3 )
set ( LIB_VERSION_AGE 2 )
set ( LIB_VERSION_REVISION 0 )
set ( LIB_VERSION_INFO
"${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" )
@ -196,7 +196,7 @@ if ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_
else () # not intel
# gcc and clang support bad function cast and alignment warnings; add them as well.
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wbad-function-cast -Wcast-align" )
if ( enable-ubsan )
set ( CMAKE_C_FLAGS "-fsanitize=address,undefined ${CMAKE_C_FLAGS}" )
set ( CMAKE_EXE_LINKER_FLAGS "-fsanitize=address,undefined ${CMAKE_EXE_LINKER_FLAGS}" )

View file

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = libfluidsynth
PROJECT_NUMBER = 2.0.6
PROJECT_NUMBER = 2.0.7
OUTPUT_DIRECTORY = api
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English

View file

@ -8,8 +8,8 @@
\author David Henningsson
\author Tom Moebert
\author Copyright © 2003-2019 Peter Hanappe, Conrad Berhörster, Antoine Schmitt, Pedro López-Cabanillas, Josh Green, David Henningsson, Tom Moebert
\version Revision 2.0.6
\date 2019-08-17
\version Revision 2.0.7
\date 2019-09-25
All the source code examples in this document are in the public domain; you can use them as you please. This document is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ . The FluidSynth library is distributed under the GNU Lesser General Public License. A copy of the GNU Lesser General Public License is contained in the FluidSynth package; if not, visit http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt or write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -21,6 +21,7 @@ All the source code examples in this document are in the public domain; you can
- \ref Disclaimer
- \ref Introduction
- \ref NewIn2_0_7
- \ref NewIn2_0_6
- \ref NewIn2_0_5
- \ref NewIn2_0_3
@ -64,6 +65,11 @@ What is FluidSynth?
- FluidSynth is open source, in active development. For more details, take a look at http://www.fluidsynth.org
\section NewIn2_0_7 Whats new in 2.0.7?
- fluid_free() has been added to allow proper deallocation by programming languages other than C/C++
\section NewIn2_0_6 Whats new in 2.0.6?
- the MIDI player did not emit any audio when calling fluid_player_play() after fluid_player_stop()

View file

@ -62,6 +62,7 @@ extern "C" {
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

View file

@ -32,13 +32,13 @@ extern "C" {
* @brief Embeddable SoundFont synthesizer
*
* You create a new synthesizer with new_fluid_synth() and you destroy
* if with delete_fluid_synth(). Use the settings structure to specify
* it with delete_fluid_synth(). Use the fluid_settings_t structure to specify
* the synthesizer characteristics.
*
* You have to load a SoundFont in order to hear any sound. For that
* you use the fluid_synth_sfload() function.
*
* You can use the audio driver functions described below to open
* You can use the audio driver functions to open
* the audio device and create a background audio thread.
*
* The API for sending MIDI events is probably what you expect:
@ -244,7 +244,7 @@ FLUID_DEPRECATED FLUIDSYNTH_API const char *fluid_synth_error(fluid_synth_t *syn
enum fluid_synth_add_mod
{
FLUID_SYNTH_OVERWRITE, /**< Overwrite any existing matching modulator */
FLUID_SYNTH_ADD, /**< Add (sum) modulator amounts */
FLUID_SYNTH_ADD, /**< Sum up modulator amounts */
};
FLUIDSYNTH_API int fluid_synth_add_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod, int mode);
@ -296,7 +296,7 @@ enum fluid_iir_filter_type
};
/**
* Specifies optional settings to use for the custom IIR filter
* Specifies optional settings to use for the custom IIR filter. Can be bitwise ORed.
*/
enum fluid_iir_filter_flags
{

View file

@ -693,7 +693,6 @@ fluid_defpreset_next(fluid_defpreset_t *defpreset)
}
#ifdef DEBUG
void fluid_print_voice_mod(fluid_voice_t *voice);
/*
Prints all the voice modulators of an instrument zone.
@ -726,14 +725,14 @@ void fluid_print_voice_mod(fluid_voice_t *voice);
- instrument zone 3 of instrument named "Synth Brass 2", filter name must be
"iz:Synth Brass 2/3".
fluid_print_voice_mod(voice, preset_zone->name, "pz:Synth Brass 2/1",
fluid_voice_print_mod(voice, preset_zone->name, "pz:Synth Brass 2/1",
inst_zone->name, "iz:Synth Brass 2/3");
2)printing voices modulators for any instrument zones:
fluid_print_voice_mod(voice, preset_zone->name, NULL, NULL);
fluid_voice_print_mod(voice, preset_zone->name, NULL, NULL);
*/
static void fluid_print_zone_voice_mod(fluid_voice_t *voice,
static void fluid_zone_print_voice_mod(fluid_voice_t *voice,
char *preset_zone_name,
char *filter_preset_zone_name,
char *inst_zone_name,
@ -749,8 +748,8 @@ static void fluid_print_zone_voice_mod(fluid_voice_t *voice,
{
return;
}
FLUID_LOG(FLUID_INFO, "\"%s\" \"%s\" voice modulators ---------------------------------", preset_zone_name,inst_zone_name);
fluid_print_voice_mod(voice);
FLUID_LOG(FLUID_DBG, "\"%s\" \"%s\" voice modulators ---------------------------------", preset_zone_name,inst_zone_name);
fluid_voice_print_mod(voice);
}
#endif
@ -1167,10 +1166,10 @@ fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int c
- instrument zone 3 of instrument named "Synth Brass 2", filter name must be
"iz:Synth Brass 2/3".
fluid_print_zone_voice_mod(voice, preset_zone->name, "pz:Synth Brass 2/1",
fluid_zone_print_voice_mod(voice, preset_zone->name, "pz:Synth Brass 2/1",
inst_zone->name, "iz:Synth Brass 2/3");
*/
fluid_print_zone_voice_mod(voice, preset_zone->name, NULL,
fluid_zone_print_voice_mod(voice, preset_zone->name, NULL,
inst_zone->name, NULL);
#endif
/* add the synthesis process to the synthesis loop. */

View file

@ -2,6 +2,7 @@
#include "fluid_instpatch.h"
#include "fluid_list.h"
#include "fluid_sfont.h"
#include "fluid_sys.h"
#include <libinstpatch/libinstpatch.h>

View file

@ -132,11 +132,6 @@ static void fluid_synth_handle_reverb_chorus_int(void *data, const char *name, i
static void fluid_synth_reset_basic_channel_LOCAL(fluid_synth_t *synth, int chan, int nbr_chan);
static int fluid_synth_check_next_basic_channel(fluid_synth_t *synth, int basicchan, int mode, int val);
static void fluid_synth_set_basic_channel_LOCAL(fluid_synth_t *synth, int basicchan, int mode, int val);
static int fluid_synth_set_reverb_full_LOCAL(fluid_synth_t *synth, int set, double roomsize,
double damping, double width, double level);
static int fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double level,
double speed, double depth_ms, int type);
/***************************************************************
*
@ -595,8 +590,10 @@ static FLUID_INLINE unsigned int fluid_synth_get_min_note_length_LOCAL(fluid_syn
* @param settings Configuration parameters to use (used directly).
* @return New FluidSynth instance or NULL on error
*
* @note The settings parameter is used directly and should not be modified
* or freed independently.
* @note The @p settings parameter is used directly and should freed after
* the synth has been deleted. Further note that you may modify FluidSettings of the
* @p settings instance. However, only those FluidSettings marked as 'realtime' will
* affect the synth immediately.
*/
fluid_synth_t *
new_fluid_synth(fluid_settings_t *settings)
@ -916,7 +913,7 @@ new_fluid_synth(fluid_settings_t *settings)
fluid_settings_getnum(settings, "synth.reverb.width", &width);
fluid_settings_getnum(settings, "synth.reverb.level", &level);
fluid_synth_set_reverb_full_LOCAL(synth,
fluid_synth_set_reverb_full(synth,
FLUID_REVMODEL_SET_ALL,
room,
damp,
@ -932,7 +929,7 @@ new_fluid_synth(fluid_settings_t *settings)
fluid_settings_getnum(settings, "synth.chorus.speed", &speed);
fluid_settings_getnum(settings, "synth.chorus.depth", &depth);
fluid_synth_set_chorus_full_LOCAL(synth,
fluid_synth_set_chorus_full(synth,
FLUID_CHORUS_SET_ALL,
i,
level,
@ -5060,6 +5057,7 @@ fluid_synth_set_reverb_full(fluid_synth_t *synth, int set, double roomsize,
double damping, double width, double level)
{
int ret;
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
/* if non of the flags is set, fail */
@ -5068,16 +5066,6 @@ fluid_synth_set_reverb_full(fluid_synth_t *synth, int set, double roomsize,
/* Synth shadow values are set here so that they will be returned if querried */
fluid_synth_api_enter(synth);
ret = fluid_synth_set_reverb_full_LOCAL(synth, set, roomsize, damping, width, level);
FLUID_API_RETURN(ret);
}
static int
fluid_synth_set_reverb_full_LOCAL(fluid_synth_t *synth, int set, double roomsize,
double damping, double width, double level)
{
int ret;
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
if(set & FLUID_REVMODEL_SET_ROOMSIZE)
{
@ -5109,7 +5097,7 @@ fluid_synth_set_reverb_full_LOCAL(fluid_synth_t *synth, int set, double roomsize
fluid_rvoice_mixer_set_reverb_params,
synth->eventhandler->mixer,
param);
return ret;
FLUID_API_RETURN(ret);
}
/**
@ -5275,6 +5263,7 @@ fluid_synth_set_chorus_full(fluid_synth_t *synth, int set, int nr, double level,
double speed, double depth_ms, int type)
{
int ret;
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
fluid_return_val_if_fail(synth != NULL, FLUID_FAILED);
/* if non of the flags is set, fail */
@ -5283,18 +5272,6 @@ fluid_synth_set_chorus_full(fluid_synth_t *synth, int set, int nr, double level,
/* Synth shadow values are set here so that they will be returned if queried */
fluid_synth_api_enter(synth);
ret = fluid_synth_set_chorus_full_LOCAL(synth, set, nr, level, speed, depth_ms, type);
FLUID_API_RETURN(ret);
}
static int
fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double level,
double speed, double depth_ms, int type)
{
int ret;
fluid_rvoice_param_t param[MAX_EVENT_PARAMS];
if(set & FLUID_CHORUS_SET_NR)
{
synth->chorus_nr = nr;
@ -5331,7 +5308,7 @@ fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double
synth->eventhandler->mixer,
param);
return (ret);
FLUID_API_RETURN(ret);
}
/**

View file

@ -2217,13 +2217,8 @@ void fluid_voice_set_custom_filter(fluid_voice_t *voice, enum fluid_iir_filter_t
UPDATE_RVOICE_GENERIC_I2(fluid_iir_filter_init, &voice->rvoice->resonant_custom_filter, type, flags);
}
#ifdef DEBUG
/*
Prints all the voice modulators.
@param voice voice
*/
void fluid_print_voice_mod(fluid_voice_t *voice)
/* Prints all the voice modulators. */
void fluid_voice_print_mod(fluid_voice_t *voice)
{
int i, mod_idx;
fluid_mod_t *mod;
@ -2233,7 +2228,7 @@ void fluid_print_voice_mod(fluid_voice_t *voice)
mod = &voice->mod[i];
fluid_dump_linked_mod (mod, mod_idx, i);
}
printf("modulateur num:%d, total members:%d\n", mod_idx, i);
FLUID_LOG(FLUID_DBG, "Number of voice modulators: %d, Total members:%d\n", mod_idx, i);
}
/*
@ -2295,5 +2290,3 @@ fluid_mod_t *fluid_voice_get_modulator(fluid_voice_t *voice, int mod_idx)
}
return NULL;
}
#endif

View file

@ -194,4 +194,8 @@ fluid_real_t fluid_voice_gen_value(const fluid_voice_t *voice, int num);
void fluid_voice_set_custom_filter(fluid_voice_t *voice, enum fluid_iir_filter_type type, enum fluid_iir_filter_flags flags);
void fluid_voice_print_mod(fluid_voice_t *voice);
int fluid_voice_get_count_modulators(fluid_voice_t *voice);
fluid_mod_t *fluid_voice_get_modulator(fluid_voice_t *voice, int mod_idx);
#endif /* _FLUID_VOICE_H */

View file

@ -1048,7 +1048,7 @@ fluid_settings_copystr(fluid_settings_t *settings, const char *name,
* @since 1.1.0
*
* Like fluid_settings_copystr() but allocates a new copy of the string. Caller
* owns the string and should free it with free() when done using it.
* owns the string and should free it with fluid_free() when done using it.
*/
int
fluid_settings_dupstr(fluid_settings_t *settings, const char *name, char **str)
@ -1117,7 +1117,7 @@ fluid_settings_dupstr(fluid_settings_t *settings, const char *name, char **str)
* @param settings a settings object
* @param name a setting's name
* @param s a string to be tested
* @return TRUE if the value exists and is equal to 's', FALSE otherwise
* @return TRUE if the value exists and is equal to \c s, FALSE otherwise
*/
int
fluid_settings_str_equal(fluid_settings_t *settings, const char *name, const char *s)
@ -1645,7 +1645,7 @@ int fluid_settings_getint_default(fluid_settings_t *settings, const char *name,
* @param data any user provided pointer
* @param func callback function to be called on each iteration
*
* @note Starting with FluidSynth 1.1.0 the \a func callback is called for each
* @note Starting with FluidSynth 1.1.0 the \p func callback is called for each
* option in alphabetical order. Sort order was undefined in previous versions.
*/
void
@ -1728,7 +1728,7 @@ fluid_settings_option_count(fluid_settings_t *settings, const char *name)
* @param name Settings name
* @param separator String to use between options (NULL to use ", ")
* @return Newly allocated string or NULL on error (out of memory, not a valid
* setting \a name or not a string setting). Free the string when finished with it.
* setting \p name or not a string setting). Free the string when finished with it by using fluid_free().
* @since 1.1.0
*/
char *
@ -1870,7 +1870,7 @@ fluid_settings_foreach_iter(void *key, void *value, void *data)
* @param data any user provided pointer
* @param func callback function to be called on each iteration
*
* @note Starting with FluidSynth 1.1.0 the \a func callback is called for each
* @note Starting with FluidSynth 1.1.0 the \p func callback is called for each
* setting in alphabetical order. Sort order was undefined in previous versions.
*/
void

View file

@ -192,6 +192,40 @@ fluid_log(int level, const char *fmt, ...)
return FLUID_FAILED;
}
void* fluid_alloc(size_t len)
{
void* ptr = malloc(len);
#if defined(DEBUG) && !defined(_MSC_VER)
// garbage initialize allocated memory for debug builds to ease reproducing
// bugs like 44453ff23281b3318abbe432fda90888c373022b .
//
// MSVC++ already garbage initializes allocated memory by itself (debug-heap).
//
// 0xCC because
// * it makes pointers reliably crash when dereferencing them,
// * floating points are still some valid but insanely huge negative number, and
// * if for whatever reason this allocated memory is executed, it'll trigger
// INT3 (...at least on x86)
if(ptr != NULL)
{
memset(ptr, 0xCC, len);
}
#endif
return ptr;
}
/**
* Convenience wrapper for free() that satisfies at least C90 requirements.
* Especially useful when using fluidsynth with programming languages that do not provide malloc() and free().
* @note Only use this function when the API documentation explicitly says so. Otherwise use adequate \c delete_fluid_* functions.
* @since 2.0.7
*/
void fluid_free(void* ptr)
{
free(ptr);
}
/**
* An improved strtok, still trashes the input string, but is portable and
* thread safe. Also skips token chars at beginning of token string and never

View file

@ -739,4 +739,6 @@ static FLUID_INLINE void *fluid_align_ptr(const void *ptr, unsigned int alignmen
#define FLUID_DEFAULT_ALIGNMENT (64U)
void* fluid_alloc(size_t len);
#endif /* _FLUID_SYS_H */

View file

@ -181,12 +181,12 @@ typedef void (*fluid_rvoice_function_t)(void *obj, const fluid_rvoice_param_t pa
#endif
/* Memory allocation */
#define FLUID_MALLOC(_n) malloc(_n)
#define FLUID_MALLOC(_n) fluid_alloc(_n)
#define FLUID_REALLOC(_p,_n) realloc(_p,_n)
#define FLUID_NEW(_t) (_t*)malloc(sizeof(_t))
#define FLUID_ARRAY_ALIGNED(_t,_n,_a) (_t*)malloc((_n)*sizeof(_t) + ((unsigned int)_a - 1u))
#define FLUID_FREE(_p) fluid_free(_p)
#define FLUID_NEW(_t) (_t*)FLUID_MALLOC(sizeof(_t))
#define FLUID_ARRAY_ALIGNED(_t,_n,_a) (_t*)FLUID_MALLOC((_n)*sizeof(_t) + ((unsigned int)_a - 1u))
#define FLUID_ARRAY(_t,_n) FLUID_ARRAY_ALIGNED(_t,_n,1u)
#define FLUID_FREE(_p) free(_p)
/* File access */
#define FLUID_FOPEN(_f,_m) fopen(_f,_m)

View file

@ -10,12 +10,6 @@ FLUID_VOICE_DEFAULT, FLUID_VOICE_ADD, FLUID_VOICE_OVERWRITE.
#include "synth/fluid_voice.h"
#include "synth/fluid_chan.h"
//----------------------------------------------------------------------------
/* external functions */
void fluid_print_voice_mod(fluid_voice_t *voice);
int fluid_voice_get_count_modulators(fluid_voice_t *voice);
fluid_mod_t *fluid_voice_get_modulator(fluid_voice_t *voice, int mod_idx);
//----------------------------------------------------------------------------
static int fluid_compare_mod_structure(fluid_mod_t *mod1, fluid_mod_t *mod2);
@ -67,7 +61,10 @@ int main(void)
voice = new_fluid_voice(NULL, 22050);
TEST_ASSERT(voice != NULL);
fluid_print_voice_mod(voice);
voice->channel = NULL;
voice->mod_count = 0;
fluid_voice_print_mod(voice);
voice_mod_count = fluid_voice_get_count_modulators(voice);
TEST_ASSERT(voice_mod_count == 0);
@ -78,7 +75,7 @@ int main(void)
// add a valid new simple modulator in mode FLUID_VOICE_DEFAULT
fluid_voice_add_mod(voice, mod1_simple_in, FLUID_VOICE_DEFAULT);
fluid_print_voice_mod(voice);
fluid_voice_print_mod(voice);
// Check if the new modulator has been correctly added in mode
// FLUID_VOICE_DEFAULT. Voice count of modulators must be voice_mod_count
@ -102,7 +99,7 @@ int main(void)
// add a valid identical simple modulator in mode FLUID_VOICE_ADD
fluid_voice_add_mod(voice, mod1_simple_in, FLUID_VOICE_ADD);
fluid_print_voice_mod(voice);
fluid_voice_print_mod(voice);
// Check if the identical modulator has been correctly added in mode
// FLUID_VOICE_ADD. Voice count of modulators must be the same as for
@ -128,7 +125,7 @@ int main(void)
// add a valid identical simple modulator in mode FLUID_VOICE_OVERWRITE
fluid_voice_add_mod(voice, mod1_simple_in, FLUID_VOICE_OVERWRITE);
fluid_print_voice_mod(voice);
fluid_voice_print_mod(voice);
// Check if the identical modulator has been correctly added in mode
// FLUID_VOICE_OVERWRITE. Voice count of modulators must be the same as for
@ -152,7 +149,7 @@ int main(void)
// add a valid identical simple modulator in mode FLUID_VOICE_ADD
fluid_voice_add_mod(voice, mod2_simple_in, FLUID_VOICE_ADD);
fluid_print_voice_mod(voice);
fluid_voice_print_mod(voice);
// Check if the identical modulator has been correctly added in mode
// FLUID_VOICE_ADD. Voice count of modulators must be the same as for
@ -175,7 +172,7 @@ int main(void)
{
// add a valid new simple modulator in mode FLUID_VOICE_DEFAULT
fluid_voice_add_mod(voice, mod3_simple_in, FLUID_VOICE_DEFAULT);
fluid_print_voice_mod(voice);
fluid_voice_print_mod(voice);
// Check that the new modulator hasn't been added in mode FLUID_VOICE_DEFAULT.
// Voice count of modulators must be the same as for test 1_4.