Update Fluidsynth to v2.0.6-git

This commit is contained in:
Robin Gareus 2019-09-04 04:22:24 +02:00
parent 69a3b0b46e
commit fdcddc736b
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
19 changed files with 329 additions and 239 deletions

View file

@ -1,7 +1,7 @@
This is a stripped down version of fluidsynth (library only) This is a stripped down version of fluidsynth (library only)
from git://github.com/FluidSynth/fluidsynth.git from git://github.com/FluidSynth/fluidsynth.git
rev. v2.0.5-46-gc9a670d5 rev. v2.0.6-92-gc6030874
fluidsynth is licensed in terms of the LGPL-2+, see individual source fluidsynth is licensed in terms of the LGPL-2+, see individual source
files for (C) holders. files for (C) holders.

View file

@ -3,8 +3,8 @@
#define FLUIDSYNTH_VERSION_MAJOR 2 #define FLUIDSYNTH_VERSION_MAJOR 2
#define FLUIDSYNTH_VERSION_MINOR 0 #define FLUIDSYNTH_VERSION_MINOR 0
#define FLUIDSYNTH_VERSION_MICRO 4 #define FLUIDSYNTH_VERSION_MICRO 6
#define FLUIDSYNTH_VERSION "2.0.4" #define FLUIDSYNTH_VERSION "2.0.6"
/* Define to enable ALSA driver */ /* Define to enable ALSA driver */
/* #undef ALSA_SUPPORT */ /* #undef ALSA_SUPPORT */
@ -198,7 +198,7 @@
/* #undef TRAP_ON_FPE */ /* #undef TRAP_ON_FPE */
/* Version number of package */ /* Version number of package */
#define VERSION "2.0.4" #define VERSION "2.0.6"
/* Define to do all DSP in single floating point precision */ /* Define to do all DSP in single floating point precision */
/* #undef WITH_FLOAT */ /* #undef WITH_FLOAT */

View file

@ -150,7 +150,7 @@ fluid_tc2sec_delay(fluid_real_t tc)
return (fluid_real_t) 0.0f; return (fluid_real_t) 0.0f;
}; };
if(tc < -12000.) if(tc < -12000.f)
{ {
tc = (fluid_real_t) -12000.0f; tc = (fluid_real_t) -12000.0f;
} }
@ -160,7 +160,7 @@ fluid_tc2sec_delay(fluid_real_t tc)
tc = (fluid_real_t) 5000.0f; tc = (fluid_real_t) 5000.0f;
} }
return (fluid_real_t) pow(2.0, (double) tc / 1200.0); return FLUID_POW(2.f, tc / 1200.f);
} }
/* /*
@ -173,22 +173,22 @@ fluid_tc2sec_attack(fluid_real_t tc)
* SF2.01 section 8.1.3 items 26, 34 * SF2.01 section 8.1.3 items 26, 34
* The most negative number indicates a delay of 0 * The most negative number indicates a delay of 0
* Range is limited from -12000 to 8000 */ * Range is limited from -12000 to 8000 */
if(tc <= -32768.) if(tc <= -32768.f)
{ {
return (fluid_real_t) 0.0; return (fluid_real_t) 0.f;
}; };
if(tc < -12000.) if(tc < -12000.f)
{ {
tc = (fluid_real_t) -12000.0; tc = (fluid_real_t) -12000.f;
}; };
if(tc > 8000.) if(tc > 8000.f)
{ {
tc = (fluid_real_t) 8000.0; tc = (fluid_real_t) 8000.f;
}; };
return (fluid_real_t) pow(2.0, (double) tc / 1200.0); return FLUID_POW(2.f, tc / 1200.f);
} }
/* /*
@ -198,7 +198,7 @@ fluid_real_t
fluid_tc2sec(fluid_real_t tc) fluid_tc2sec(fluid_real_t tc)
{ {
/* No range checking here! */ /* No range checking here! */
return (fluid_real_t) pow(2.0, (double) tc / 1200.0); return FLUID_POW(2.f, tc / 1200.f);
} }
/* /*
@ -211,22 +211,22 @@ fluid_tc2sec_release(fluid_real_t tc)
* SF2.01 section 8.1.3 items 30, 38 * SF2.01 section 8.1.3 items 30, 38
* No 'most negative number' rule here! * No 'most negative number' rule here!
* Range is limited from -12000 to 8000 */ * Range is limited from -12000 to 8000 */
if(tc <= -32768.) if(tc <= -32768.f)
{ {
return (fluid_real_t) 0.0; return (fluid_real_t) 0.f;
}; };
if(tc < -12000.) if(tc < -12000.f)
{ {
tc = (fluid_real_t) -12000.0; tc = (fluid_real_t) -12000.f;
}; };
if(tc > 8000.) if(tc > 8000.f)
{ {
tc = (fluid_real_t) 8000.0; tc = (fluid_real_t) 8000.f;
}; };
return (fluid_real_t) pow(2.0, (double) tc / 1200.0); return FLUID_POW(2.f, tc / 1200.f);
} }
/* /*
@ -238,13 +238,13 @@ fluid_tc2sec_release(fluid_real_t tc)
* *
fluid_hz2ct(fluid_real_t f) fluid_hz2ct(fluid_real_t f)
{ {
return (fluid_real_t)(6900 + (1200 / M_LN2) * log(f / 440.0)); return 6900.f + (1200.f / FLUID_M_LN2) * FLUID_LOGF(f / 440.0f));
} }
*/ */
fluid_real_t fluid_real_t
fluid_act2hz(fluid_real_t c) fluid_act2hz(fluid_real_t c)
{ {
return (fluid_real_t)(8.176 * pow(2.0, (double) c / 1200.0)); return 8.176f * FLUID_POW(2.f, c / 1200.f);
} }
/* /*
@ -258,17 +258,17 @@ fluid_pan(fluid_real_t c, int left)
c = -c; c = -c;
} }
if(c <= -500) if(c <= -500.f)
{ {
return (fluid_real_t) 0.0; return (fluid_real_t) 0.f;
} }
else if(c >= 500) else if(c >= 500.f)
{ {
return (fluid_real_t) 1.0; return (fluid_real_t) 1.f;
} }
else else
{ {
return fluid_pan_tab[(int)(c + 500)]; return fluid_pan_tab[(int)(c) + 500];
} }
} }
@ -284,17 +284,17 @@ fluid_pan(fluid_real_t c, int left)
fluid_real_t fluid_balance(fluid_real_t balance, int left) fluid_real_t fluid_balance(fluid_real_t balance, int left)
{ {
/* This is the most common case */ /* This is the most common case */
if(balance == 0) if(balance == 0.f)
{ {
return 1.0f; return 1.0f;
} }
if((left && balance < 0) || (!left && balance > 0)) if((left && balance < 0.f) || (!left && balance > 0.f))
{ {
return 1.0f; return 1.0f;
} }
if(balance < 0) if(balance < 0.f)
{ {
balance = -balance; balance = -balance;
} }
@ -308,13 +308,13 @@ fluid_real_t fluid_balance(fluid_real_t balance, int left)
fluid_real_t fluid_real_t
fluid_concave(fluid_real_t val) fluid_concave(fluid_real_t val)
{ {
if(val < 0) if(val < 0.f)
{ {
return 0; return 0.f;
} }
else if(val >= FLUID_VEL_CB_SIZE) else if(val >= (fluid_real_t)FLUID_VEL_CB_SIZE)
{ {
return 1; return 1.f;
} }
return fluid_concave_tab[(int) val]; return fluid_concave_tab[(int) val];
@ -326,13 +326,13 @@ fluid_concave(fluid_real_t val)
fluid_real_t fluid_real_t
fluid_convex(fluid_real_t val) fluid_convex(fluid_real_t val)
{ {
if(val < 0) if(val < 0.f)
{ {
return 0; return 0.f;
} }
else if(val >= FLUID_VEL_CB_SIZE) else if(val >= (fluid_real_t)FLUID_VEL_CB_SIZE)
{ {
return 1; return 1.f;
} }
return fluid_convex_tab[(int) val]; return fluid_convex_tab[(int) val];

View file

@ -1712,7 +1712,7 @@ static const fluid_real_t fluid_cb2amp_tab[1441] = {
2.985382618917960e-03, /* 505 */ 2.985382618917960e-03, /* 505 */
2.951209226666387e-03, /* 506 */ 2.951209226666387e-03, /* 506 */
2.917427014001166e-03, /* 507 */ 2.917427014001166e-03, /* 507 */
2.884031503126605e-03, /* 508 */ 2.884031503126606e-03, /* 508 */
2.851018267503910e-03, /* 509 */ 2.851018267503910e-03, /* 509 */
2.818382931264455e-03, /* 510 */ 2.818382931264455e-03, /* 510 */
2.786121168629769e-03, /* 511 */ 2.786121168629769e-03, /* 511 */

View file

@ -104,7 +104,7 @@ fluid_sfont_t *fluid_defsfloader_load(fluid_sfloader_t *loader, const char *file
if(fluid_defsfont_load(defsfont, &loader->file_callbacks, filename) == FLUID_FAILED) if(fluid_defsfont_load(defsfont, &loader->file_callbacks, filename) == FLUID_FAILED)
{ {
fluid_sfont_delete_internal(sfont); fluid_defsfont_sfont_delete(sfont);
return NULL; return NULL;
} }
@ -499,7 +499,7 @@ int fluid_defsfont_load(fluid_defsfont_t *defsfont, const fluid_file_callbacks_t
while(p != NULL) while(p != NULL)
{ {
sfpreset = (SFPreset *)fluid_list_get(p); sfpreset = (SFPreset *)fluid_list_get(p);
defpreset = new_fluid_defpreset(defsfont); defpreset = new_fluid_defpreset();
if(defpreset == NULL) if(defpreset == NULL)
{ {
@ -621,7 +621,7 @@ fluid_preset_t *fluid_defsfont_iteration_next(fluid_defsfont_t *defsfont)
* new_fluid_defpreset * new_fluid_defpreset
*/ */
fluid_defpreset_t * fluid_defpreset_t *
new_fluid_defpreset(fluid_defsfont_t *defsfont) new_fluid_defpreset(void)
{ {
fluid_defpreset_t *defpreset = FLUID_NEW(fluid_defpreset_t); fluid_defpreset_t *defpreset = FLUID_NEW(fluid_defpreset_t);
@ -632,7 +632,6 @@ new_fluid_defpreset(fluid_defsfont_t *defsfont)
} }
defpreset->next = NULL; defpreset->next = NULL;
defpreset->defsfont = defsfont;
defpreset->name[0] = 0; defpreset->name[0] = 0;
defpreset->bank = 0; defpreset->bank = 0;
defpreset->num = 0; defpreset->num = 0;

View file

@ -143,7 +143,6 @@ int fluid_defsfont_add_preset(fluid_defsfont_t *defsfont, fluid_defpreset_t *def
struct _fluid_defpreset_t struct _fluid_defpreset_t
{ {
fluid_defpreset_t *next; fluid_defpreset_t *next;
fluid_defsfont_t *defsfont; /* the soundfont this preset belongs to */
char name[21]; /* the name of the preset */ char name[21]; /* the name of the preset */
unsigned int bank; /* the bank number */ unsigned int bank; /* the bank number */
unsigned int num; /* the preset number */ unsigned int num; /* the preset number */
@ -151,7 +150,7 @@ struct _fluid_defpreset_t
fluid_preset_zone_t *zone; /* the chained list of preset zones */ fluid_preset_zone_t *zone; /* the chained list of preset zones */
}; };
fluid_defpreset_t *new_fluid_defpreset(fluid_defsfont_t *defsfont); fluid_defpreset_t *new_fluid_defpreset(void);
void delete_fluid_defpreset(fluid_defpreset_t *defpreset); void delete_fluid_defpreset(fluid_defpreset_t *defpreset);
fluid_defpreset_t *fluid_defpreset_next(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); int fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset, SFPreset *sfpreset, fluid_defsfont_t *defsfont);

View file

@ -73,7 +73,7 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
/* filter (implement the voice filter according to SoundFont standard) */ /* filter (implement the voice filter according to SoundFont standard) */
/* Check for denormal number (too close to zero). */ /* Check for denormal number (too close to zero). */
if(fabs(dsp_hist1) < 1e-20) if(FLUID_FABS(dsp_hist1) < 1e-20f)
{ {
dsp_hist1 = 0.0f; /* FIXME JMG - Is this even needed? */ dsp_hist1 = 0.0f; /* FIXME JMG - Is this even needed? */
} }
@ -109,7 +109,7 @@ fluid_iir_filter_apply(fluid_iir_filter_t *iir_filter,
dsp_b1 += dsp_b1_incr; dsp_b1 += dsp_b1_incr;
/* Compensate history to avoid the filter going havoc with large frequency changes */ /* Compensate history to avoid the filter going havoc with large frequency changes */
if(iir_filter->compensate_incr && fabs(dsp_b02) > 0.001) if(iir_filter->compensate_incr && FLUID_FABS(dsp_b02) > 0.001f)
{ {
fluid_real_t compensate = old_b02 / dsp_b02; fluid_real_t compensate = old_b02 / dsp_b02;
dsp_hist1 *= compensate; dsp_hist1 *= compensate;
@ -205,7 +205,7 @@ static fluid_real_t fluid_iir_filter_q_from_dB(fluid_real_t q_dB)
/* The 'sound font' Q is defined in dB. The filter needs a linear /* The 'sound font' Q is defined in dB. The filter needs a linear
q. Convert. */ q. Convert. */
return pow(10.0f, q_dB / 20.0f); return FLUID_POW(10.0f, q_dB / 20.0f);
} }
DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_q) DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_q)
@ -247,7 +247,7 @@ DECLARE_FLUID_RVOICE_FUNCTION(fluid_iir_filter_set_q)
* (numerator of the filter equation). This gain factor depends * (numerator of the filter equation). This gain factor depends
* only on Q, so this is the right place to calculate it. * only on Q, so this is the right place to calculate it.
*/ */
iir_filter->filter_gain /= sqrt(q); iir_filter->filter_gain /= FLUID_SQRT(q);
} }
/* The synthesis loop will have to recalculate the filter coefficients. */ /* The synthesis loop will have to recalculate the filter coefficients. */
@ -277,8 +277,8 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t *iir_filter,
fluid_real_t omega = (fluid_real_t)(2.0 * M_PI) * fluid_real_t omega = (fluid_real_t)(2.0 * M_PI) *
(iir_filter->last_fres / output_rate); (iir_filter->last_fres / output_rate);
fluid_real_t sin_coeff = (fluid_real_t) sin(omega); fluid_real_t sin_coeff = FLUID_SIN(omega);
fluid_real_t cos_coeff = (fluid_real_t) cos(omega); fluid_real_t cos_coeff = FLUID_COS(omega);
fluid_real_t alpha_coeff = sin_coeff / (2.0f * iir_filter->q_lin); fluid_real_t alpha_coeff = sin_coeff / (2.0f * iir_filter->q_lin);
fluid_real_t a0_inv = 1.0f / (1.0f + alpha_coeff); fluid_real_t a0_inv = 1.0f / (1.0f + alpha_coeff);
@ -352,10 +352,10 @@ fluid_iir_filter_calculate_coefficients(fluid_iir_filter_t *iir_filter,
iir_filter->b02_incr = (b02_temp - iir_filter->b02) / transition_samples; iir_filter->b02_incr = (b02_temp - iir_filter->b02) / transition_samples;
iir_filter->b1_incr = (b1_temp - iir_filter->b1) / transition_samples; iir_filter->b1_incr = (b1_temp - iir_filter->b1) / transition_samples;
if(fabs(iir_filter->b02) > 0.0001) if(FLUID_FABS(iir_filter->b02) > 0.0001f)
{ {
fluid_real_t quota = b02_temp / iir_filter->b02; fluid_real_t quota = b02_temp / iir_filter->b02;
iir_filter->compensate_incr = quota < 0.5 || quota > 2; iir_filter->compensate_incr = quota < 0.5f || quota > 2.f;
} }
/* Have to add the increments filter_coeff_incr_count times. */ /* Have to add the increments filter_coeff_incr_count times. */
@ -393,13 +393,13 @@ void fluid_iir_filter_calc(fluid_iir_filter_t *iir_filter,
{ {
fres = 0.45f * output_rate; fres = 0.45f * output_rate;
} }
else if(fres < 5) else if(fres < 5.f)
{ {
fres = 5; fres = 5.f;
} }
/* if filter enabled and there is a significant frequency change.. */ /* if filter enabled and there is a significant frequency change.. */
if(iir_filter->type != FLUID_IIR_DISABLED && fabs(fres - iir_filter->last_fres) > 0.01) if(iir_filter->type != FLUID_IIR_DISABLED && FLUID_FABS(fres - iir_filter->last_fres) > 0.01f)
{ {
/* The filter coefficients have to be recalculated (filter /* The filter coefficients have to be recalculated (filter
* parameters have changed). Recalculation for various reasons is * parameters have changed). Recalculation for various reasons is

View file

@ -48,7 +48,7 @@ static fluid_midi_event_t *fluid_track_next_event(fluid_track_t *track);
static int fluid_track_get_duration(fluid_track_t *track); static int fluid_track_get_duration(fluid_track_t *track);
static int fluid_track_reset(fluid_track_t *track); static int fluid_track_reset(fluid_track_t *track);
static int fluid_track_send_events(fluid_track_t *track, static void fluid_track_send_events(fluid_track_t *track,
fluid_synth_t *synth, fluid_synth_t *synth,
fluid_player_t *player, fluid_player_t *player,
unsigned int ticks); unsigned int ticks);
@ -1553,13 +1553,12 @@ fluid_track_reset(fluid_track_t *track)
/* /*
* fluid_track_send_events * fluid_track_send_events
*/ */
int void
fluid_track_send_events(fluid_track_t *track, fluid_track_send_events(fluid_track_t *track,
fluid_synth_t *synth, fluid_synth_t *synth,
fluid_player_t *player, fluid_player_t *player,
unsigned int ticks) unsigned int ticks)
{ {
int status = FLUID_OK;
fluid_midi_event_t *event; fluid_midi_event_t *event;
int seeking = player->seek_ticks >= 0; int seeking = player->seek_ticks >= 0;
@ -1580,7 +1579,7 @@ fluid_track_send_events(fluid_track_t *track,
if(event == NULL) if(event == NULL)
{ {
return status; return;
} }
/* printf("track=%02d\tticks=%05u\ttrack=%05u\tdtime=%05u\tnext=%05u\n", */ /* printf("track=%02d\tticks=%05u\ttrack=%05u\tdtime=%05u\tnext=%05u\n", */
@ -1592,7 +1591,7 @@ fluid_track_send_events(fluid_track_t *track,
if(track->ticks + event->dtime > ticks) if(track->ticks + event->dtime > ticks)
{ {
return status; return;
} }
track->ticks += event->dtime; track->ticks += event->dtime;
@ -1620,8 +1619,6 @@ fluid_track_send_events(fluid_track_t *track,
fluid_track_next_event(track); fluid_track_next_event(track);
} }
return status;
} }
/****************************************************** /******************************************************
@ -1679,6 +1676,26 @@ new_fluid_player(fluid_synth_t *synth)
fluid_player_set_playback_callback(player, fluid_synth_handle_midi_event, synth); fluid_player_set_playback_callback(player, fluid_synth_handle_midi_event, synth);
player->use_system_timer = fluid_settings_str_equal(synth->settings, player->use_system_timer = fluid_settings_str_equal(synth->settings,
"player.timing-source", "system"); "player.timing-source", "system");
if(player->use_system_timer)
{
player->system_timer = new_fluid_timer((int) player->deltatime,
fluid_player_callback, player, TRUE, FALSE, TRUE);
if(player->system_timer == NULL)
{
goto err;
}
}
else
{
player->sample_timer = new_fluid_sample_timer(player->synth,
fluid_player_callback, player);
if(player->sample_timer == NULL)
{
goto err;
}
}
fluid_settings_getint(synth->settings, "player.reset-synth", &i); fluid_settings_getint(synth->settings, "player.reset-synth", &i);
fluid_player_handle_reset_synth(player, NULL, i); fluid_player_handle_reset_synth(player, NULL, i);
@ -1687,11 +1704,16 @@ new_fluid_player(fluid_synth_t *synth)
fluid_player_handle_reset_synth, player); fluid_player_handle_reset_synth, player);
return player; return player;
err:
delete_fluid_player(player);
return NULL;
} }
/** /**
* Delete a MIDI player instance. * Delete a MIDI player instance.
* @param player MIDI player instance * @param player MIDI player instance
* @warning Do not call while the \p synth renders audio, i.e. an audio driver is running or any other synthesizer thread calls fluid_synth_process() or fluid_synth_nwrite_float() or fluid_synth_write_*() !
*/ */
void void
delete_fluid_player(fluid_player_t *player) delete_fluid_player(fluid_player_t *player)
@ -1704,6 +1726,9 @@ delete_fluid_player(fluid_player_t *player)
fluid_player_stop(player); fluid_player_stop(player);
fluid_player_reset(player); fluid_player_reset(player);
delete_fluid_timer(player->system_timer);
delete_fluid_sample_timer(player->synth, player->sample_timer);
while(player->playlist != NULL) while(player->playlist != NULL)
{ {
q = player->playlist->next; q = player->playlist->next;
@ -2031,6 +2056,11 @@ fluid_player_callback(void *data, unsigned int msec)
loadnextfile = player->currentfile == NULL ? 1 : 0; loadnextfile = player->currentfile == NULL ? 1 : 0;
if(player->status == FLUID_PLAYER_DONE)
{
fluid_synth_all_notes_off(synth, -1);
return 1;
}
do do
{ {
if(loadnextfile) if(loadnextfile)
@ -2059,12 +2089,7 @@ fluid_player_callback(void *data, unsigned int msec)
if(!fluid_track_eot(player->track[i])) if(!fluid_track_eot(player->track[i]))
{ {
status = FLUID_PLAYER_PLAYING; status = FLUID_PLAYER_PLAYING;
fluid_track_send_events(player->track[i], synth, player, player->cur_ticks);
if(fluid_track_send_events(player->track[i], synth, player,
player->cur_ticks) != FLUID_OK)
{
/* */
}
} }
} }
@ -2099,63 +2124,33 @@ fluid_player_callback(void *data, unsigned int msec)
int int
fluid_player_play(fluid_player_t *player) fluid_player_play(fluid_player_t *player)
{ {
if(player->status == FLUID_PLAYER_PLAYING) if(player->status == FLUID_PLAYER_PLAYING ||
player->playlist == NULL)
{ {
return FLUID_OK; return FLUID_OK;
} }
if(player->playlist == NULL) if(!player->use_system_timer)
{ {
return FLUID_OK; fluid_sample_timer_reset(player->synth, player->sample_timer);
} }
player->status = FLUID_PLAYER_PLAYING; player->status = FLUID_PLAYER_PLAYING;
if(player->use_system_timer)
{
player->system_timer = new_fluid_timer((int) player->deltatime,
fluid_player_callback, (void *) player, TRUE, FALSE, TRUE);
if(player->system_timer == NULL)
{
return FLUID_FAILED;
}
}
else
{
player->sample_timer = new_fluid_sample_timer(player->synth,
fluid_player_callback, (void *) player);
if(player->sample_timer == NULL)
{
return FLUID_FAILED;
}
}
return FLUID_OK; return FLUID_OK;
} }
/** /**
* Stops a MIDI player. * Pauses the MIDI playback.
*
* It will not rewind to the beginning of the file, use fluid_player_seek() for this purpose.
* @param player MIDI player instance * @param player MIDI player instance
* @return Always returns #FLUID_OK * @return Always returns #FLUID_OK
*/ */
int int
fluid_player_stop(fluid_player_t *player) fluid_player_stop(fluid_player_t *player)
{ {
if(player->system_timer != NULL)
{
delete_fluid_timer(player->system_timer);
}
if(player->sample_timer != NULL)
{
delete_fluid_sample_timer(player->synth, player->sample_timer);
}
player->status = FLUID_PLAYER_DONE; player->status = FLUID_PLAYER_DONE;
player->sample_timer = NULL; fluid_player_seek(player, fluid_player_get_current_tick(player));
player->system_timer = NULL;
return FLUID_OK; return FLUID_OK;
} }
@ -2241,26 +2236,17 @@ int fluid_player_set_bpm(fluid_player_t *player, int bpm)
} }
/** /**
* Wait for a MIDI player to terminate (when done playing). * Wait for a MIDI player until the playback has been stopped.
* @param player MIDI player instance * @param player MIDI player instance
* @return #FLUID_OK on success, #FLUID_FAILED otherwise * @return Always #FLUID_OK
*/ */
int int
fluid_player_join(fluid_player_t *player) fluid_player_join(fluid_player_t *player)
{ {
if(player->system_timer)
{
return fluid_timer_join(player->system_timer);
}
else if(player->sample_timer)
{
/* Busy-wait loop, since there's no thread to wait for... */
while(player->status != FLUID_PLAYER_DONE) while(player->status != FLUID_PLAYER_DONE)
{ {
fluid_msleep(10); fluid_msleep(10);
} }
}
return FLUID_OK; return FLUID_OK;
} }

View file

@ -334,21 +334,21 @@ fluid_mod_transform_source_value(fluid_real_t val, unsigned char mod_flags, cons
* is close enough. * is close enough.
*/ */
case FLUID_MOD_SIN | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* custom sin(x) */ case FLUID_MOD_SIN | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* custom sin(x) */
val = sin(M_PI / 2 * val_norm * 0.87); val = FLUID_SIN((FLUID_M_PI / 2.0f * 0.87f) * val_norm);
break; break;
case FLUID_MOD_SIN | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* custom */ case FLUID_MOD_SIN | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* custom */
val = sin(M_PI / 2 * (1.0f - val_norm) * 0.87); val = FLUID_SIN((FLUID_M_PI / 2.0f * 0.87f) * (1.0f - val_norm));
break; break;
case FLUID_MOD_SIN | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* custom */ case FLUID_MOD_SIN | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* custom */
val = (val_norm > 0.5f) ? sin(M_PI / 2 * 2 * (val_norm - 0.5f)) val = (val_norm > 0.5f) ? FLUID_SIN(FLUID_M_PI * (val_norm - 0.5f))
: -sin(M_PI / 2 * 2 * (0.5f - val_norm)); : -FLUID_SIN(FLUID_M_PI * (0.5f - val_norm));
break; break;
case FLUID_MOD_SIN | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* custom */ case FLUID_MOD_SIN | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* custom */
val = (val_norm > 0.5f) ? -sin(M_PI / 2 * 2 * (val_norm - 0.5f)) val = (val_norm > 0.5f) ? -FLUID_SIN(FLUID_M_PI * (val_norm - 0.5f))
: sin(M_PI / 2 * 2 * (0.5f - val_norm)); : FLUID_SIN(FLUID_M_PI * (0.5f - val_norm));
break; break;
default: default:
@ -605,11 +605,11 @@ fluid_mod_check_cc_source(const fluid_mod_t *mod, unsigned char src1_select)
*/ */
int fluid_mod_check_sources(const fluid_mod_t *mod, const char *name) int fluid_mod_check_sources(const fluid_mod_t *mod, const char *name)
{ {
static const char *invalid_non_cc_src = static const char invalid_non_cc_src[] =
"Invalid modulator, using non-CC source %s.src%d=%d"; "Invalid modulator, using non-CC source %s.src%d=%d";
static const char *invalid_cc_src = static const char invalid_cc_src[] =
"Invalid modulator, using CC source %s.src%d=%d"; "Invalid modulator, using CC source %s.src%d=%d";
static const char *src1_is_none = static const char src1_is_none[] =
"Modulator with source 1 none %s.src1=%d"; "Modulator with source 1 none %s.src1=%d";
/* checks valid non cc sources */ /* checks valid non cc sources */

View file

@ -193,9 +193,9 @@
#define DENORMALISING #define DENORMALISING
#ifdef DENORMALISING #ifdef DENORMALISING
#define DC_OFFSET 1e-8 #define DC_OFFSET 1e-8f
#else #else
#define DC_OFFSET 0.0 #define DC_OFFSET 0.0f
#endif #endif
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
@ -272,7 +272,7 @@ a flatter response on comb filter. So the input gain is set to 0.1 rather 1.0. *
#define INTERP_SAMPLES_NBR 1 #define INTERP_SAMPLES_NBR 1
/* phase offset between modulators waveform */ /* phase offset between modulators waveform */
#define MOD_PHASE (360.0/(float) NBR_DELAYS) #define MOD_PHASE (360.0f/(float) NBR_DELAYS)
#if (NBR_DELAYS == 8) #if (NBR_DELAYS == 8)
#define DELAY_L0 601 #define DELAY_L0 601
@ -431,12 +431,16 @@ typedef struct
static void set_mod_frequency(sinus_modulator *mod, static void set_mod_frequency(sinus_modulator *mod,
float freq, float sample_rate, float phase) float freq, float sample_rate, float phase)
{ {
fluid_real_t w = 2 * M_PI * freq / sample_rate; /* intial angle */ fluid_real_t w = 2 * FLUID_M_PI * freq / sample_rate; /* intial angle */
fluid_real_t a;
mod->a1 = 2 * cos(w); mod->a1 = 2 * FLUID_COS(w);
mod->buffer2 = sin(2 * M_PI * phase / 360 - w); /* y(n-1) = sin(-intial angle) */
mod->buffer1 = sin(2 * M_PI * phase / 360); /* y(n) = sin(initial phase) */ a = (2 * FLUID_M_PI / 360) * phase;
mod->reset_buffer2 = sin(M_PI / 2.0 - w); /* reset value for PI/2 */
mod->buffer2 = FLUID_SIN(a - w); /* y(n-1) = sin(-intial angle) */
mod->buffer1 = FLUID_SIN(a); /* y(n) = sin(initial phase) */
mod->reset_buffer2 = FLUID_SIN(FLUID_M_PI / 2 - w); /* reset value for PI/2 */
} }
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
@ -453,15 +457,15 @@ static FLUID_INLINE fluid_real_t get_mod_sinus(sinus_modulator *mod)
out = mod->a1 * mod->buffer1 - mod->buffer2; out = mod->a1 * mod->buffer1 - mod->buffer2;
mod->buffer2 = mod->buffer1; mod->buffer2 = mod->buffer1;
if(out >= 1.0) /* reset in case of instability near PI/2 */ if(out >= 1.0f) /* reset in case of instability near PI/2 */
{ {
out = 1.0; /* forces output to the right value */ out = 1.0f; /* forces output to the right value */
mod->buffer2 = mod->reset_buffer2; mod->buffer2 = mod->reset_buffer2;
} }
if(out <= -1.0) /* reset in case of instability near -PI/2 */ if(out <= -1.0f) /* reset in case of instability near -PI/2 */
{ {
out = -1.0; /* forces output to the right value */ out = -1.0f; /* forces output to the right value */
mod->buffer2 = - mod->reset_buffer2; mod->buffer2 = - mod->reset_buffer2;
} }
@ -736,7 +740,7 @@ static void update_rev_time_damping(fluid_late *late,
fluid_real_t sample_period = 1 / late->samplerate; /* Sampling period */ fluid_real_t sample_period = 1 / late->samplerate; /* Sampling period */
fluid_real_t dc_rev_time; /* Reverb time at 0 Hz (in seconds) */ fluid_real_t dc_rev_time; /* Reverb time at 0 Hz (in seconds) */
fluid_real_t alpha; fluid_real_t alpha, alpha2;
/*-------------------------------------------- /*--------------------------------------------
Computes dc_rev_time and alpha Computes dc_rev_time and alpha
@ -753,7 +757,7 @@ static void update_rev_time_damping(fluid_late *late,
------------------------------------------*/ ------------------------------------------*/
dc_rev_time = GET_DC_REV_TIME(roomsize); dc_rev_time = GET_DC_REV_TIME(roomsize);
/* computes gi_tmp from dc_rev_time using relation E2 */ /* computes gi_tmp from dc_rev_time using relation E2 */
gi_tmp = (fluid_real_t) pow(10, -3 * delay_length[NBR_DELAYS - 1] * gi_tmp = FLUID_POW(10, -3 * delay_length[NBR_DELAYS - 1] *
sample_period / dc_rev_time); /* E2 */ sample_period / dc_rev_time); /* E2 */
#else #else
/* roomsize parameters have the same response that Freeverb, that is: /* roomsize parameters have the same response that Freeverb, that is:
@ -766,14 +770,14 @@ static void update_rev_time_damping(fluid_late *late,
fluid_real_t gi_min, gi_max; fluid_real_t gi_min, gi_max;
/* values gi_min et gi_max are computed using E2 for the line with /* values gi_min et gi_max are computed using E2 for the line with
maximum delay */ maximum delay */
gi_max = (fluid_real_t)pow(10, -3 * delay_length[NBR_DELAYS - 1] * gi_max = FLUID_POW(10, (-3 * delay_length[NBR_DELAYS - 1] / MAX_DC_REV_TIME) *
sample_period / MAX_DC_REV_TIME); /* E2 */ sample_period); /* E2 */
gi_min = (fluid_real_t)pow(10, -3 * delay_length[NBR_DELAYS - 1] * gi_min = FLUID_POW(10, (-3 * delay_length[NBR_DELAYS - 1] / MIN_DC_REV_TIME) *
sample_period / MIN_DC_REV_TIME); /* E2 */ sample_period); /* E2 */
/* gi = f(roomsize, gi_max, gi_min) */ /* gi = f(roomsize, gi_max, gi_min) */
gi_tmp = gi_min + roomsize * (gi_max - gi_min); gi_tmp = gi_min + roomsize * (gi_max - gi_min);
/* Computes T60DC from gi using inverse of relation E2.*/ /* Computes T60DC from gi using inverse of relation E2.*/
dc_rev_time = -3 * delay_length[NBR_DELAYS - 1] * sample_period / log10(gi_tmp); dc_rev_time = -3 * FLUID_M_LN10 * delay_length[NBR_DELAYS - 1] * sample_period / FLUID_LOGF(gi_tmp);
} }
#endif /* ROOMSIZE_RESPONSE_LINEAR */ #endif /* ROOMSIZE_RESPONSE_LINEAR */
/*-------------------------------------------- /*--------------------------------------------
@ -781,8 +785,12 @@ static void update_rev_time_damping(fluid_late *late,
----------------------------------------------*/ ----------------------------------------------*/
/* Computes alpha from damp,ai_tmp,gi_tmp using relation R */ /* Computes alpha from damp,ai_tmp,gi_tmp using relation R */
/* - damp (0 to 1) controls concave reverb time for fs/2 frequency (T60DC to 0) */ /* - damp (0 to 1) controls concave reverb time for fs/2 frequency (T60DC to 0) */
ai_tmp = 1.0 * damp; ai_tmp = 1.0f * damp;
alpha = sqrt(1 / (1 - ai_tmp / (20 * log10(gi_tmp) * log(10) / 80))); /* R */
/* Preserve the square of R */
alpha2 = 1.f / (1.f - ai_tmp / ((20.f / 80.f) * FLUID_LOGF(gi_tmp)));
alpha = FLUID_SQRT(alpha2); /* R */
} }
/* updates tone corrector coefficients b1,b2 from alpha */ /* updates tone corrector coefficients b1,b2 from alpha */
@ -802,15 +810,15 @@ static void update_rev_time_damping(fluid_late *late,
for(i = 0; i < NBR_DELAYS; i++) for(i = 0; i < NBR_DELAYS; i++)
{ {
/* iir low pass filter gain */ /* iir low pass filter gain */
fluid_real_t gi = (fluid_real_t)pow(10, -3 * delay_length[i] * fluid_real_t gi = FLUID_POW(10, -3 * delay_length[i] *
sample_period / dc_rev_time); sample_period / dc_rev_time);
/* iir low pass filter feedback gain */ /* iir low pass filter feedback gain */
fluid_real_t ai = (fluid_real_t)(20 * log10(gi) * log(10) / 80 * fluid_real_t ai = (20.f / 80.f) * FLUID_LOGF(gi) * (1.f - 1.f / alpha2);
(1 - 1 / pow(alpha, 2)));
/* b0 = gi * (1 - ai), a1 = - ai */ /* b0 = gi * (1 - ai), a1 = - ai */
set_fdn_delay_lpf(&late->mod_delay_lines[i].dl.damping, set_fdn_delay_lpf(&late->mod_delay_lines[i].dl.damping,
gi * (1 - ai), -ai); gi * (1.f - ai), -ai);
} }
} }

View file

@ -599,8 +599,8 @@ fluid_rvoice_noteoff_LOCAL(fluid_rvoice_t *voice, unsigned int min_ticks)
{ {
fluid_real_t lfo = fluid_lfo_get_val(&voice->envlfo.modlfo) * -voice->envlfo.modlfo_to_vol; fluid_real_t lfo = fluid_lfo_get_val(&voice->envlfo.modlfo) * -voice->envlfo.modlfo_to_vol;
fluid_real_t amp = fluid_adsr_env_get_val(&voice->envlfo.volenv) * fluid_cb2amp(lfo); fluid_real_t amp = fluid_adsr_env_get_val(&voice->envlfo.volenv) * fluid_cb2amp(lfo);
fluid_real_t env_value = - (((-200 / M_LN10) * log(amp) - lfo) / FLUID_PEAK_ATTENUATION - 1); fluid_real_t env_value = - (((-200.f / FLUID_M_LN10) * FLUID_LOGF(amp) - lfo) / FLUID_PEAK_ATTENUATION - 1);
fluid_clip(env_value, 0.0, 1.0); fluid_clip(env_value, 0.0f, 1.0f);
fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value); fluid_adsr_env_set_val(&voice->envlfo.volenv, env_value);
} }
} }
@ -712,7 +712,7 @@ DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_multi_retrigger_attack)
Here we need the inverse of fluid_convex() function defined as: Here we need the inverse of fluid_convex() function defined as:
new_value = pow(10, (1 - current_val) . FLUID_PEAK_ATTENUATION / -200 . 2.0) new_value = pow(10, (1 - current_val) . FLUID_PEAK_ATTENUATION / -200 . 2.0)
For performance reason we use fluid_cb2amp(Val) = pow(10, val/-200) with For performance reason we use fluid_cb2amp(Val) = pow(10, val/-200) with
val = (1 current_val) . FLUID_PEAK_ATTENUATION / 2.0 val = (1 - current_val) . FLUID_PEAK_ATTENUATION / 2.0
*/ */
fluid_real_t new_value; /* new modenv value */ fluid_real_t new_value; /* new modenv value */
new_value = fluid_cb2amp((1.0f - fluid_adsr_env_get_val(&voice->envlfo.modenv)) new_value = fluid_cb2amp((1.0f - fluid_adsr_env_get_val(&voice->envlfo.modenv))

View file

@ -190,6 +190,7 @@ int fluid_sfloader_set_callbacks(fluid_sfloader_t *loader,
cb->ftell = tell; cb->ftell = tell;
cb->fclose = close; cb->fclose = close;
// NOTE: if we ever make the instpatch loader public, this may return FLUID_FAILED
return FLUID_OK; return FLUID_OK;
} }

View file

@ -463,6 +463,11 @@ fluid_synth_init(void)
fluid_mod_set_dest(&custom_balance_mod, GEN_CUSTOM_BALANCE); /* Destination: stereo balance */ fluid_mod_set_dest(&custom_balance_mod, GEN_CUSTOM_BALANCE); /* Destination: stereo balance */
/* Amount: 96 dB of attenuation (on the opposite channel) */ /* Amount: 96 dB of attenuation (on the opposite channel) */
fluid_mod_set_amount(&custom_balance_mod, FLUID_PEAK_ATTENUATION); /* Amount: 960 */ fluid_mod_set_amount(&custom_balance_mod, FLUID_PEAK_ATTENUATION); /* Amount: 960 */
#ifdef LIBINSTPATCH_SUPPORT
/* defer libinstpatch init to fluid_instpatch.c to avoid #include "libinstpatch.h" */
fluid_instpatch_init();
#endif
} }
static FLUID_INLINE unsigned int fluid_synth_get_ticks(fluid_synth_t *synth) static FLUID_INLINE unsigned int fluid_synth_get_ticks(fluid_synth_t *synth)
@ -494,16 +499,13 @@ struct _fluid_sample_timer_t
*/ */
static void fluid_sample_timer_process(fluid_synth_t *synth) static void fluid_sample_timer_process(fluid_synth_t *synth)
{ {
fluid_sample_timer_t *st, *stnext; fluid_sample_timer_t *st;
long msec; long msec;
int cont; int cont;
unsigned int ticks = fluid_synth_get_ticks(synth); unsigned int ticks = fluid_synth_get_ticks(synth);
for(st = synth->sample_timers; st; st = stnext) for(st = synth->sample_timers; st; st = st->next)
{ {
/* st may be freed in the callback below. cache it's successor now to avoid use after free */
stnext = st->next;
if(st->isfinished) if(st->isfinished)
{ {
continue; continue;
@ -529,7 +531,7 @@ fluid_sample_timer_t *new_fluid_sample_timer(fluid_synth_t *synth, fluid_timer_c
return NULL; return NULL;
} }
result->starttick = fluid_synth_get_ticks(synth); fluid_sample_timer_reset(synth, result);
result->isfinished = 0; result->isfinished = 0;
result->data = data; result->data = data;
result->callback = callback; result->callback = callback;
@ -559,6 +561,10 @@ void delete_fluid_sample_timer(fluid_synth_t *synth, fluid_sample_timer_t *timer
} }
} }
void fluid_sample_timer_reset(fluid_synth_t *synth, fluid_sample_timer_t *timer)
{
timer->starttick = fluid_synth_get_ticks(synth);
}
/*************************************************************** /***************************************************************
* *
@ -816,6 +822,20 @@ new_fluid_synth(fluid_settings_t *settings)
#endif /* LADSPA */ #endif /* LADSPA */
} }
/* allocate and add the dls sfont loader */
#ifdef LIBINSTPATCH_SUPPORT
loader = new_fluid_instpatch_loader(settings);
if(loader == NULL)
{
FLUID_LOG(FLUID_WARN, "Failed to create the instpatch SoundFont loader");
}
else
{
fluid_synth_add_sfloader(synth, loader);
}
#endif
/* allocate and add the default sfont loader */ /* allocate and add the default sfont loader */
loader = new_fluid_defsfloader(settings); loader = new_fluid_defsfloader(settings);
@ -837,6 +857,7 @@ new_fluid_synth(fluid_settings_t *settings)
goto error_recovery; goto error_recovery;
} }
FLUID_MEMSET(synth->channel, 0, synth->midi_channels * sizeof(*synth->channel));
for(i = 0; i < synth->midi_channels; i++) for(i = 0; i < synth->midi_channels; i++)
{ {
synth->channel[i] = new_fluid_channel(synth, i); synth->channel[i] = new_fluid_channel(synth, i);
@ -856,6 +877,7 @@ new_fluid_synth(fluid_settings_t *settings)
goto error_recovery; goto error_recovery;
} }
FLUID_MEMSET(synth->voice, 0, synth->nvoice * sizeof(*synth->voice));
for(i = 0; i < synth->nvoice; i++) for(i = 0; i < synth->nvoice; i++)
{ {
synth->voice[i] = new_fluid_voice(synth->eventhandler, synth->sample_rate); synth->voice[i] = new_fluid_voice(synth->eventhandler, synth->sample_rate);
@ -1007,10 +1029,13 @@ delete_fluid_synth(fluid_synth_t *synth)
if(synth->channel != NULL) if(synth->channel != NULL)
{ {
for(i = 0; i < synth->midi_channels; i++) for(i = 0; i < synth->midi_channels; i++)
{
if(synth->channel[i] != NULL)
{ {
fluid_channel_set_preset(synth->channel[i], NULL); fluid_channel_set_preset(synth->channel[i], NULL);
} }
} }
}
delete_fluid_rvoice_eventhandler(synth->eventhandler); delete_fluid_rvoice_eventhandler(synth->eventhandler);
@ -1712,7 +1737,7 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
case RPN_CHANNEL_FINE_TUNE: /* Fine tune is 14 bit over +/-1 semitone (+/- 100 cents, 8192 = center) */ case RPN_CHANNEL_FINE_TUNE: /* Fine tune is 14 bit over +/-1 semitone (+/- 100 cents, 8192 = center) */
fluid_synth_set_gen_LOCAL(synth, channum, GEN_FINETUNE, fluid_synth_set_gen_LOCAL(synth, channum, GEN_FINETUNE,
(data - 8192) / 8192.0 * 100.0); (float)(data - 8192) * (100.0f / 8192.0f));
break; break;
case RPN_CHANNEL_COARSE_TUNE: /* Coarse tune is 7 bit and in semitones (64 is center) */ case RPN_CHANNEL_COARSE_TUNE: /* Coarse tune is 7 bit and in semitones (64 is center) */
@ -5329,8 +5354,8 @@ fluid_synth_set_chorus_full_LOCAL(fluid_synth_t *synth, int set, int nr, double
int int
fluid_synth_get_chorus_nr(fluid_synth_t *synth) fluid_synth_get_chorus_nr(fluid_synth_t *synth)
{ {
double result; int result;
fluid_return_val_if_fail(synth != NULL, 0.0); fluid_return_val_if_fail(synth != NULL, 0);
fluid_synth_api_enter(synth); fluid_synth_api_enter(synth);
result = synth->chorus_nr; result = synth->chorus_nr;
@ -5393,8 +5418,8 @@ fluid_synth_get_chorus_depth(fluid_synth_t *synth)
int int
fluid_synth_get_chorus_type(fluid_synth_t *synth) fluid_synth_get_chorus_type(fluid_synth_t *synth)
{ {
double result; int result;
fluid_return_val_if_fail(synth != NULL, 0.0); fluid_return_val_if_fail(synth != NULL, 0);
fluid_synth_api_enter(synth); fluid_synth_api_enter(synth);
result = synth->chorus_type; result = synth->chorus_type;
@ -5483,7 +5508,7 @@ fluid_synth_set_interp_method(fluid_synth_t *synth, int chan, int interp_method)
} }
FLUID_API_RETURN(FLUID_OK); FLUID_API_RETURN(FLUID_OK);
}; }
/** /**
* Get the total count of MIDI channels. * Get the total count of MIDI channels.
@ -6110,18 +6135,18 @@ fluid_synth_get_settings(fluid_synth_t *synth)
} }
/** /**
* Set a SoundFont generator (effect) value on a MIDI channel in real-time. * Apply an offset to a SoundFont generator on a MIDI channel.
*
* This function allows to set an offset for the specified destination generator in real-time.
* The offset will be applied immediately to all voices that are currently and subsequently playing
* on the given MIDI channel. This functionality works equivalent to using NRPN MIDI messages to
* manipulate synthesis parameters. See SoundFont spec, paragraph 8.1.3, for details on SoundFont
* generator parameters and valid ranges, as well as paragraph 9.6 for details on NRPN messages.
* @param synth FluidSynth instance * @param synth FluidSynth instance
* @param chan MIDI channel number (0 to MIDI channel count - 1) * @param chan MIDI channel number (0 to MIDI channel count - 1)
* @param param SoundFont generator ID (#fluid_gen_type) * @param param SoundFont generator ID (#fluid_gen_type)
* @param value Offset or absolute generator value to assign to the MIDI channel * @param value Offset value (in native units of the generator) to assign to the MIDI channel
* @return #FLUID_OK on success, #FLUID_FAILED otherwise * @return #FLUID_OK on success, #FLUID_FAILED otherwise
*
* This function allows for setting all effect parameters in real time on a
* MIDI channel. Setting absolute to non-zero will cause the value to override
* any generator values set in the instruments played on the MIDI channel.
* See SoundFont 2.01 spec, paragraph 8.1.3, page 48 for details on SoundFont
* generator parameters and valid ranges.
*/ */
int fluid_synth_set_gen(fluid_synth_t *synth, int chan, int param, float value) int fluid_synth_set_gen(fluid_synth_t *synth, int chan, int param, float value)
{ {
@ -6154,11 +6179,13 @@ fluid_synth_set_gen_LOCAL(fluid_synth_t *synth, int chan, int param, float value
} }
/** /**
* Get generator value assigned to a MIDI channel. * Retrive the generator NRPN offset assigned to a MIDI channel.
*
* The value returned is in native units of the generator. By default, the offset is zero.
* @param synth FluidSynth instance * @param synth FluidSynth instance
* @param chan MIDI channel number (0 to MIDI channel count - 1) * @param chan MIDI channel number (0 to MIDI channel count - 1)
* @param param SoundFont generator ID (#fluid_gen_type) * @param param SoundFont generator ID (#fluid_gen_type)
* @return Current generator value assigned to MIDI channel * @return Current NRPN generator offset value assigned to the MIDI channel
*/ */
float float
fluid_synth_get_gen(fluid_synth_t *synth, int chan, int param) fluid_synth_get_gen(fluid_synth_t *synth, int chan, int param)

View file

@ -205,7 +205,7 @@ int fluid_synth_set_chorus_full(fluid_synth_t *synth, int set, int nr, double le
fluid_sample_timer_t *new_fluid_sample_timer(fluid_synth_t *synth, fluid_timer_callback_t callback, void *data); fluid_sample_timer_t *new_fluid_sample_timer(fluid_synth_t *synth, fluid_timer_callback_t callback, void *data);
void delete_fluid_sample_timer(fluid_synth_t *synth, fluid_sample_timer_t *timer); void delete_fluid_sample_timer(fluid_synth_t *synth, fluid_sample_timer_t *timer);
void fluid_sample_timer_reset(fluid_synth_t *synth, fluid_sample_timer_t *timer);
void fluid_synth_process_event_queue(fluid_synth_t *synth); void fluid_synth_process_event_queue(fluid_synth_t *synth);

View file

@ -1252,6 +1252,9 @@ fluid_istream_gets(fluid_istream_t in, char *buf, int len)
/* Handle read differently depending on if its a socket or file descriptor */ /* Handle read differently depending on if its a socket or file descriptor */
if(!(in & FLUID_SOCKET_FLAG)) if(!(in & FLUID_SOCKET_FLAG))
{ {
// usually read() is supposed to return '\n' as last valid character of the user input
// when compiled with compatibility for WinXP however, read() may return 0 (EOF) rather than '\n'
// this would cause the shell to exit early
n = read(in, &c, 1); n = read(in, &c, 1);
if(n == -1) if(n == -1)
@ -1275,7 +1278,8 @@ fluid_istream_gets(fluid_istream_t in, char *buf, int len)
if(n == 0) if(n == 0)
{ {
*buf = 0; *buf = 0;
return 0; // return 1 if read from stdin, else 0, to fix early exit of shell
return (in == STDIN_FILENO);
} }
if(c == '\n') if(c == '\n')

View file

@ -707,13 +707,13 @@ enum
#ifdef FPE_CHECK #ifdef FPE_CHECK
#define fluid_check_fpe(expl) fluid_check_fpe_i386(expl) #define fluid_check_fpe(expl) fluid_check_fpe_i386(expl)
#define fluid_clear_fpe() fluid_clear_fpe_i386() #define fluid_clear_fpe() fluid_clear_fpe_i386()
unsigned int fluid_check_fpe_i386(char *explanation_in_case_of_fpe);
void fluid_clear_fpe_i386(void);
#else #else
#define fluid_check_fpe(expl) #define fluid_check_fpe(expl)
#define fluid_clear_fpe() #define fluid_clear_fpe()
#endif #endif
unsigned int fluid_check_fpe_i386(char *explanation_in_case_of_fpe);
void fluid_clear_fpe_i386(void);
/* System control */ /* System control */
void fluid_msleep(unsigned int msecs); void fluid_msleep(unsigned int msecs);

View file

@ -344,9 +344,9 @@ fluid_voice_init(fluid_voice_t *voice, fluid_sample_t *sample,
voice->synth_gain = gain; voice->synth_gain = gain;
/* avoid division by zero later*/ /* avoid division by zero later*/
if(voice->synth_gain < 0.0000001) if(voice->synth_gain < 0.0000001f)
{ {
voice->synth_gain = 0.0000001; voice->synth_gain = 0.0000001f;
} }
UPDATE_RVOICE_R1(fluid_rvoice_set_synth_gain, voice->synth_gain); UPDATE_RVOICE_R1(fluid_rvoice_set_synth_gain, voice->synth_gain);
@ -680,32 +680,32 @@ calculate_hold_decay_buffers(fluid_voice_t *voice, int gen_base,
if(is_decay) if(is_decay)
{ {
/* SF 2.01 section 8.1.3 # 28, 36 */ /* SF 2.01 section 8.1.3 # 28, 36 */
if(timecents > 8000.0) if(timecents > 8000.f)
{ {
timecents = 8000.0; timecents = 8000.f;
} }
} }
else else
{ {
/* SF 2.01 section 8.1.3 # 27, 35 */ /* SF 2.01 section 8.1.3 # 27, 35 */
if(timecents > 5000) if(timecents > 5000.f)
{ {
timecents = 5000.0; timecents = 5000.f;
} }
/* SF 2.01 section 8.1.2 # 27, 35: /* SF 2.01 section 8.1.2 # 27, 35:
* The most negative number indicates no hold time * The most negative number indicates no hold time
*/ */
if(timecents <= -32768.) if(timecents <= -32768.f)
{ {
return 0; return 0;
} }
} }
/* SF 2.01 section 8.1.3 # 27, 28, 35, 36 */ /* SF 2.01 section 8.1.3 # 27, 28, 35, 36 */
if(timecents < -12000.0) if(timecents < -12000.f)
{ {
timecents = -12000.0; timecents = -12000.f;
} }
seconds = fluid_tc2sec(timecents); seconds = fluid_tc2sec(timecents);
@ -714,7 +714,7 @@ calculate_hold_decay_buffers(fluid_voice_t *voice, int gen_base,
/* round to next full number of buffers */ /* round to next full number of buffers */
buffers = (int)(((fluid_real_t)voice->output_rate * seconds) buffers = (int)(((fluid_real_t)voice->output_rate * seconds)
/ (fluid_real_t)FLUID_BUFSIZE / (fluid_real_t)FLUID_BUFSIZE
+ 0.5); + 0.5f);
return buffers; return buffers;
} }
@ -774,7 +774,7 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
/* Range: SF2.01 section 8.1.3 # 48 /* Range: SF2.01 section 8.1.3 # 48
* Motivation for range checking: * Motivation for range checking:
* OHPiano.SF2 sets initial attenuation to a whooping -96 dB */ * OHPiano.SF2 sets initial attenuation to a whooping -96 dB */
fluid_clip(voice->attenuation, 0.0, 1440.0); fluid_clip(voice->attenuation, 0.f, 1440.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_attenuation, voice->attenuation); UPDATE_RVOICE_R1(fluid_rvoice_set_attenuation, voice->attenuation);
break; break;
@ -794,14 +794,14 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
case GEN_REVERBSEND: case GEN_REVERBSEND:
/* The generator unit is 'tenths of a percent'. */ /* The generator unit is 'tenths of a percent'. */
voice->reverb_send = x / 1000.0f; voice->reverb_send = x / 1000.0f;
fluid_clip(voice->reverb_send, 0.0, 1.0); fluid_clip(voice->reverb_send, 0.f, 1.f);
UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 2, fluid_voice_calculate_gain_amplitude(voice, voice->reverb_send)); UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 2, fluid_voice_calculate_gain_amplitude(voice, voice->reverb_send));
break; break;
case GEN_CHORUSSEND: case GEN_CHORUSSEND:
/* The generator unit is 'tenths of a percent'. */ /* The generator unit is 'tenths of a percent'. */
voice->chorus_send = x / 1000.0f; voice->chorus_send = x / 1000.0f;
fluid_clip(voice->chorus_send, 0.0, 1.0); fluid_clip(voice->chorus_send, 0.f, 1.f);
UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 3, fluid_voice_calculate_gain_amplitude(voice, voice->chorus_send)); UPDATE_RVOICE_BUFFERS_AMP(fluid_rvoice_buffers_set_amp, 3, fluid_voice_calculate_gain_amplitude(voice, voice->chorus_send));
break; break;
@ -870,17 +870,17 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
break; break;
case GEN_MODLFOTOPITCH: case GEN_MODLFOTOPITCH:
fluid_clip(x, -12000.0, 12000.0); fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_pitch, x); UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_pitch, x);
break; break;
case GEN_MODLFOTOVOL: case GEN_MODLFOTOVOL:
fluid_clip(x, -960.0, 960.0); fluid_clip(x, -960.f, 960.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_vol, x); UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_vol, x);
break; break;
case GEN_MODLFOTOFILTERFC: case GEN_MODLFOTOFILTERFC:
fluid_clip(x, -12000, 12000); fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_fc, x); UPDATE_RVOICE_R1(fluid_rvoice_set_modlfo_to_fc, x);
break; break;
@ -917,7 +917,7 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
break; break;
case GEN_VIBLFOTOPITCH: case GEN_VIBLFOTOPITCH:
fluid_clip(x, -12000.0, 12000.0); fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_viblfo_to_pitch, x); UPDATE_RVOICE_R1(fluid_rvoice_set_viblfo_to_pitch, x);
break; break;
@ -970,7 +970,7 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
break; break;
case GEN_MODENVTOPITCH: case GEN_MODENVTOPITCH:
fluid_clip(x, -12000.0, 12000.0); fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modenv_to_pitch, x); UPDATE_RVOICE_R1(fluid_rvoice_set_modenv_to_pitch, x);
break; break;
@ -979,7 +979,7 @@ fluid_voice_update_param(fluid_voice_t *voice, int gen)
* Motivation for range checking: * Motivation for range checking:
* Filter is reported to make funny noises now and then * Filter is reported to make funny noises now and then
*/ */
fluid_clip(x, -12000.0, 12000.0); fluid_clip(x, -12000.f, 12000.f);
UPDATE_RVOICE_R1(fluid_rvoice_set_modenv_to_fc, x); UPDATE_RVOICE_R1(fluid_rvoice_set_modenv_to_fc, x);
break; break;
@ -1271,7 +1271,7 @@ void fluid_voice_update_portamento(fluid_voice_t *voice, int fromkey, int tokey)
unsigned int countinc = (unsigned int)(((fluid_real_t)voice->output_rate * unsigned int countinc = (unsigned int)(((fluid_real_t)voice->output_rate *
0.001f * 0.001f *
(fluid_real_t)fluid_channel_portamentotime(channel)) / (fluid_real_t)fluid_channel_portamentotime(channel)) /
(fluid_real_t)FLUID_BUFSIZE + 0.5); (fluid_real_t)FLUID_BUFSIZE + 0.5f);
/* Send portamento parameters to the voice dsp */ /* Send portamento parameters to the voice dsp */
UPDATE_RVOICE_GENERIC_IR(fluid_rvoice_set_portamento, voice->rvoice, countinc, pitchoffset); UPDATE_RVOICE_GENERIC_IR(fluid_rvoice_set_portamento, voice->rvoice, countinc, pitchoffset);
@ -1745,7 +1745,7 @@ fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t *voice)
|| (mod->flags2 & FLUID_MOD_BIPOLAR) || (mod->flags2 & FLUID_MOD_BIPOLAR)
|| (mod->amount < 0)) || (mod->amount < 0))
{ {
min_val *= -1.0; /* min_val = - |amount|*/ min_val = -min_val; /* min_val = - |amount|*/
} }
else else
{ {
@ -1792,9 +1792,9 @@ int fluid_voice_set_gain(fluid_voice_t *voice, fluid_real_t gain)
fluid_real_t left, right, reverb, chorus; fluid_real_t left, right, reverb, chorus;
/* avoid division by zero*/ /* avoid division by zero*/
if(gain < 0.0000001) if(gain < 0.0000001f)
{ {
gain = 0.0000001; gain = 0.0000001f;
} }
voice->synth_gain = gain; voice->synth_gain = gain;
@ -1964,9 +1964,9 @@ fluid_voice_get_overflow_prio(fluid_voice_t *voice,
// FIXME: Should take into account where on the envelope we are...? // FIXME: Should take into account where on the envelope we are...?
} }
if(a < 0.1) if(a < 0.1f)
{ {
a = 0.1; // Avoid div by zero a = 0.1f; // Avoid div by zero
} }
this_voice_prio += score->volume / a; this_voice_prio += score->volume / a;

View file

@ -126,19 +126,80 @@ typedef void (*fluid_rvoice_function_t)(void *obj, const fluid_rvoice_param_t pa
* SYSTEM INTERFACE * SYSTEM INTERFACE
*/ */
/* Math constants */
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
#ifndef M_LN2
#define M_LN2 0.69314718055994530941723212145818
#endif
#ifndef M_LN10
#define M_LN10 2.3025850929940456840179914546844
#endif
#define FLUID_M_PI ((fluid_real_t)M_PI)
#define FLUID_M_LN2 ((fluid_real_t)M_LN2)
#define FLUID_M_LN10 ((fluid_real_t)M_LN10)
/* Math functions */
#if defined WITH_FLOAT && defined HAVE_SINF
#define FLUID_SIN sinf
#else
#define FLUID_SIN (fluid_real_t)sin
#endif
#if defined WITH_FLOAT && defined HAVE_COSF
#define FLUID_COS cosf
#else
#define FLUID_COS (fluid_real_t)cos
#endif
#if defined WITH_FLOAT && defined HAVE_FABSF
#define FLUID_FABS fabsf
#else
#define FLUID_FABS (fluid_real_t)fabs
#endif
#if defined WITH_FLOAT && defined HAVE_POWF
#define FLUID_POW powf
#else
#define FLUID_POW (fluid_real_t)pow
#endif
#if defined WITH_FLOAT && defined HAVE_SQRTF
#define FLUID_SQRT sqrtf
#else
#define FLUID_SQRT (fluid_real_t)sqrt
#endif
#if defined WITH_FLOAT && defined HAVE_LOGF
#define FLUID_LOGF logf
#else
#define FLUID_LOGF (fluid_real_t)log
#endif
/* Memory allocation */
#define FLUID_MALLOC(_n) malloc(_n) #define FLUID_MALLOC(_n) malloc(_n)
#define FLUID_REALLOC(_p,_n) realloc(_p,_n) #define FLUID_REALLOC(_p,_n) realloc(_p,_n)
#define FLUID_NEW(_t) (_t*)malloc(sizeof(_t)) #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_ARRAY_ALIGNED(_t,_n,_a) (_t*)malloc((_n)*sizeof(_t) + ((unsigned int)_a - 1u))
#define FLUID_ARRAY(_t,_n) FLUID_ARRAY_ALIGNED(_t,_n,1u) #define FLUID_ARRAY(_t,_n) FLUID_ARRAY_ALIGNED(_t,_n,1u)
#define FLUID_FREE(_p) free(_p) #define FLUID_FREE(_p) free(_p)
/* File access */
#define FLUID_FOPEN(_f,_m) fopen(_f,_m) #define FLUID_FOPEN(_f,_m) fopen(_f,_m)
#define FLUID_FCLOSE(_f) fclose(_f) #define FLUID_FCLOSE(_f) fclose(_f)
#define FLUID_FREAD(_p,_s,_n,_f) fread(_p,_s,_n,_f) #define FLUID_FREAD(_p,_s,_n,_f) fread(_p,_s,_n,_f)
#define FLUID_FSEEK(_f,_n,_set) fseek(_f,_n,_set) #define FLUID_FSEEK(_f,_n,_set) fseek(_f,_n,_set)
#define FLUID_FTELL(_f) ftell(_f) #define FLUID_FTELL(_f) ftell(_f)
/* Memory functions */
#define FLUID_MEMCPY(_dst,_src,_n) memcpy(_dst,_src,_n) #define FLUID_MEMCPY(_dst,_src,_n) memcpy(_dst,_src,_n)
#define FLUID_MEMSET(_s,_c,_n) memset(_s,_c,_n) #define FLUID_MEMSET(_s,_c,_n) memset(_s,_c,_n)
/* String functions */
#define FLUID_STRLEN(_s) strlen(_s) #define FLUID_STRLEN(_s) strlen(_s)
#define FLUID_STRCMP(_s,_t) strcmp(_s,_t) #define FLUID_STRCMP(_s,_t) strcmp(_s,_t)
#define FLUID_STRNCMP(_s,_t,_n) strncmp(_s,_t,_n) #define FLUID_STRNCMP(_s,_t,_n) strncmp(_s,_t,_n)
@ -212,18 +273,6 @@ do { strncpy(_dst,_src,_n); \
#define FLUID_LOG fluid_log #define FLUID_LOG fluid_log
#endif #endif
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
#ifndef M_LN2
#define M_LN2 0.69314718055994530941723212145818
#endif
#ifndef M_LN10
#define M_LN10 2.3025850929940456840179914546844
#endif
#ifdef DEBUG #ifdef DEBUG
#define FLUID_ASSERT(a) g_assert(a) #define FLUID_ASSERT(a) g_assert(a)
#else #else

View file

@ -78,7 +78,7 @@ index 946a873bbf..79f83a4583 100644
/* /*
* fluid_hashtable_foreach_remove_or_steal: * fluid_hashtable_foreach_remove_or_steal:
diff --git b/libs/fluidsynth/src/fluid_midi.c a/libs/fluidsynth/src/fluid_midi.c diff --git b/libs/fluidsynth/src/fluid_midi.c a/libs/fluidsynth/src/fluid_midi.c
index 6e527b1822..5b2efe0b9b 100644 index cd0d23ced3..c92fb2fefa 100644
--- b/libs/fluidsynth/src/fluid_midi.c --- b/libs/fluidsynth/src/fluid_midi.c
+++ a/libs/fluidsynth/src/fluid_midi.c +++ a/libs/fluidsynth/src/fluid_midi.c
@@ -77,7 +77,7 @@ static int fluid_midi_file_read_tracklen(fluid_midi_file *mf); @@ -77,7 +77,7 @@ static int fluid_midi_file_read_tracklen(fluid_midi_file *mf);
@ -107,13 +107,13 @@ index 6e527b1822..5b2efe0b9b 100644
/* /*
* new_fluid_track * new_fluid_track
*/ */
@@ -2518,3 +2519,4 @@ fluid_midi_event_length(unsigned char event) @@ -2504,3 +2505,4 @@ fluid_midi_event_length(unsigned char event)
return 1; return 1;
} }
+#endif +#endif
diff --git b/libs/fluidsynth/src/fluid_mod.c a/libs/fluidsynth/src/fluid_mod.c diff --git b/libs/fluidsynth/src/fluid_mod.c a/libs/fluidsynth/src/fluid_mod.c
index 84e97731e5..5e57455d4d 100644 index 47547b5b5e..57313caf42 100644
--- b/libs/fluidsynth/src/fluid_mod.c --- b/libs/fluidsynth/src/fluid_mod.c
+++ a/libs/fluidsynth/src/fluid_mod.c +++ a/libs/fluidsynth/src/fluid_mod.c
@@ -603,7 +603,7 @@ fluid_mod_check_cc_source(const fluid_mod_t *mod, unsigned char src1_select) @@ -603,7 +603,7 @@ fluid_mod_check_cc_source(const fluid_mod_t *mod, unsigned char src1_select)
@ -123,7 +123,7 @@ index 84e97731e5..5e57455d4d 100644
-int fluid_mod_check_sources(const fluid_mod_t *mod, char *name) -int fluid_mod_check_sources(const fluid_mod_t *mod, char *name)
+int fluid_mod_check_sources(const fluid_mod_t *mod, const char *name) +int fluid_mod_check_sources(const fluid_mod_t *mod, const char *name)
{ {
static const char *invalid_non_cc_src = static const char invalid_non_cc_src[] =
"Invalid modulator, using non-CC source %s.src%d=%d"; "Invalid modulator, using non-CC source %s.src%d=%d";
diff --git b/libs/fluidsynth/src/fluid_mod.h a/libs/fluidsynth/src/fluid_mod.h diff --git b/libs/fluidsynth/src/fluid_mod.h a/libs/fluidsynth/src/fluid_mod.h
index 3e7661741f..ec8e967a35 100644 index 3e7661741f..ec8e967a35 100644
@ -191,10 +191,18 @@ index 5b2b08748f..1811169846 100644
static int static int
diff --git b/libs/fluidsynth/src/fluid_synth.c a/libs/fluidsynth/src/fluid_synth.c diff --git b/libs/fluidsynth/src/fluid_synth.c a/libs/fluidsynth/src/fluid_synth.c
index b72d5139ef..83d427fcac 100644 index 426d3c4fc0..42064f93d6 100644
--- b/libs/fluidsynth/src/fluid_synth.c --- b/libs/fluidsynth/src/fluid_synth.c
+++ a/libs/fluidsynth/src/fluid_synth.c +++ a/libs/fluidsynth/src/fluid_synth.c
@@ -267,7 +267,7 @@ void fluid_version(int *major, int *minor, int *micro) @@ -25,7 +25,6 @@
#include "fluid_settings.h"
#include "fluid_sfont.h"
#include "fluid_defsfont.h"
-#include "fluid_instpatch.h"
#ifdef TRAP_ON_FPE
#define _GNU_SOURCE
@@ -268,7 +267,7 @@ void fluid_version(int *major, int *minor, int *micro)
* @return FluidSynth version string, which is internal and should not be * @return FluidSynth version string, which is internal and should not be
* modified or freed. * modified or freed.
*/ */
@ -203,7 +211,16 @@ index b72d5139ef..83d427fcac 100644
fluid_version_str(void) fluid_version_str(void)
{ {
return FLUIDSYNTH_VERSION; return FLUIDSYNTH_VERSION;
@@ -6419,6 +6419,7 @@ int fluid_synth_set_channel_type(fluid_synth_t *synth, int chan, int type) @@ -5509,7 +5508,7 @@ fluid_synth_set_interp_method(fluid_synth_t *synth, int chan, int interp_method)
}
FLUID_API_RETURN(FLUID_OK);
-};
+}
/**
* Get the total count of MIDI channels.
@@ -6447,6 +6446,7 @@ int fluid_synth_set_channel_type(fluid_synth_t *synth, int chan, int type)
FLUID_API_RETURN(FLUID_OK); FLUID_API_RETURN(FLUID_OK);
} }
@ -211,7 +228,7 @@ index b72d5139ef..83d427fcac 100644
/** /**
* Return the LADSPA effects instance used by FluidSynth * Return the LADSPA effects instance used by FluidSynth
* *
@@ -6431,6 +6432,7 @@ fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth) @@ -6459,6 +6459,7 @@ fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth)
return synth->ladspa_fx; return synth->ladspa_fx;
} }
@ -220,7 +237,7 @@ index b72d5139ef..83d427fcac 100644
/** /**
* Configure a general-purpose IIR biquad filter. * Configure a general-purpose IIR biquad filter.
diff --git b/libs/fluidsynth/src/fluid_synth.h a/libs/fluidsynth/src/fluid_synth.h diff --git b/libs/fluidsynth/src/fluid_synth.h a/libs/fluidsynth/src/fluid_synth.h
index f061aeaf38..2b35f1fcb0 100644 index 0b9758bad5..fe222f7b6f 100644
--- b/libs/fluidsynth/src/fluid_synth.h --- b/libs/fluidsynth/src/fluid_synth.h
+++ a/libs/fluidsynth/src/fluid_synth.h +++ a/libs/fluidsynth/src/fluid_synth.h
@@ -33,8 +33,6 @@ @@ -33,8 +33,6 @@
@ -243,7 +260,7 @@ index f061aeaf38..2b35f1fcb0 100644
enum fluid_iir_filter_flags custom_filter_flags; /**< filter type of the user-defined filter currently used for all voices */ enum fluid_iir_filter_flags custom_filter_flags; /**< filter type of the user-defined filter currently used for all voices */
}; };
diff --git b/libs/fluidsynth/src/fluid_sys.c a/libs/fluidsynth/src/fluid_sys.c diff --git b/libs/fluidsynth/src/fluid_sys.c a/libs/fluidsynth/src/fluid_sys.c
index 4225583481..22694f21c5 100644 index 5d123883b3..938c05cf22 100644
--- b/libs/fluidsynth/src/fluid_sys.c --- b/libs/fluidsynth/src/fluid_sys.c
+++ a/libs/fluidsynth/src/fluid_sys.c +++ a/libs/fluidsynth/src/fluid_sys.c
@@ -205,9 +205,10 @@ fluid_log(int level, const char *fmt, ...) @@ -205,9 +205,10 @@ fluid_log(int level, const char *fmt, ...)
@ -260,7 +277,7 @@ index 4225583481..22694f21c5 100644
if(str == NULL || delim == NULL || !*delim) if(str == NULL || delim == NULL || !*delim)
diff --git b/libs/fluidsynth/src/fluid_sys.h a/libs/fluidsynth/src/fluid_sys.h diff --git b/libs/fluidsynth/src/fluid_sys.h a/libs/fluidsynth/src/fluid_sys.h
index 65c088ca3c..5d82b686dd 100644 index 6490359027..3bc0c5a40f 100644
--- b/libs/fluidsynth/src/fluid_sys.h --- b/libs/fluidsynth/src/fluid_sys.h
+++ a/libs/fluidsynth/src/fluid_sys.h +++ a/libs/fluidsynth/src/fluid_sys.h
@@ -128,8 +128,9 @@ typedef guint64 uint64_t; @@ -128,8 +128,9 @@ typedef guint64 uint64_t;