From ac5aa418aeacdafd71cf0416c7b3959ce5485f4e Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Sat, 2 Dec 2017 12:19:13 +0100 Subject: [PATCH 01/13] Use float instead of fluid_real_t for overflow parameters and calculations --- src/synth/fluid_synth.c | 4 ++-- src/synth/fluid_voice.c | 4 ++-- src/synth/fluid_voice.h | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index e0c16e29..55b23e45 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -3168,8 +3168,8 @@ static fluid_voice_t* fluid_synth_free_voice_by_kill_LOCAL(fluid_synth_t* synth) { int i; - fluid_real_t best_prio = OVERFLOW_PRIO_CANNOT_KILL-1; - fluid_real_t this_voice_prio; + float best_prio = OVERFLOW_PRIO_CANNOT_KILL-1; + float this_voice_prio; fluid_voice_t* voice; int best_voice_index=-1; unsigned int ticks = fluid_synth_get_ticks(synth); diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index 214d006c..ce966434 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -1681,12 +1681,12 @@ fluid_voice_optimize_sample(fluid_sample_t* s) return FLUID_OK; } -fluid_real_t +float fluid_voice_get_overflow_prio(fluid_voice_t* voice, fluid_overflow_prio_t* score, unsigned int cur_time) { - fluid_real_t this_voice_prio = 0; + float this_voice_prio = 0; /* Are we already overflowing? */ if (!voice->can_access_overflow_rvoice) { diff --git a/src/synth/fluid_voice.h b/src/synth/fluid_voice.h index 4103f08d..0bfea234 100644 --- a/src/synth/fluid_voice.h +++ b/src/synth/fluid_voice.h @@ -37,11 +37,11 @@ typedef struct _fluid_overflow_prio_t fluid_overflow_prio_t; struct _fluid_overflow_prio_t { - fluid_real_t percussion; /**< Is this voice on the drum channel? Then add this score */ - fluid_real_t released; /**< Is this voice in release stage? Then add this score (usually negative) */ - fluid_real_t sustained; /**< Is this voice sustained? Then add this score (usually negative) */ - fluid_real_t volume; /**< Multiply current (or future) volume (a value between 0 and 1) */ - fluid_real_t age; /**< This score will be divided by the number of seconds the voice has lasted */ + float percussion; /**< Is this voice on the drum channel? Then add this score */ + float released; /**< Is this voice in release stage? Then add this score (usually negative) */ + float sustained; /**< Is this voice sustained? Then add this score (usually negative) */ + float volume; /**< Multiply current (or future) volume (a value between 0 and 1) */ + float age; /**< This score will be divided by the number of seconds the voice has lasted */ }; enum fluid_voice_status @@ -148,7 +148,7 @@ void fluid_voice_stop(fluid_voice_t* voice); void fluid_voice_overflow_rvoice_finished(fluid_voice_t* voice); int fluid_voice_kill_excl(fluid_voice_t* voice); -fluid_real_t fluid_voice_get_overflow_prio(fluid_voice_t* voice, +float fluid_voice_get_overflow_prio(fluid_voice_t* voice, fluid_overflow_prio_t* score, unsigned int cur_time); From 3973b9566d223716c19f239f44d5d5193c6a05f1 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Sat, 2 Dec 2017 12:07:59 +0100 Subject: [PATCH 02/13] Add float-typed wrapper for fluid_settings_getnum Avoids the need to store the value in a local double before assigning it to the target variable. --- src/synth/fluid_synth.c | 20 ++++++-------------- src/utils/fluid_settings.c | 21 +++++++++++++++++++++ src/utils/fluid_settings.h | 3 +++ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 55b23e45..f108c869 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -515,8 +515,6 @@ new_fluid_synth(fluid_settings_t *settings) { fluid_synth_t* synth; fluid_sfloader_t* loader; - double gain; - double num_val; int i, nbuf; int with_ladspa = 0; @@ -569,21 +567,15 @@ new_fluid_synth(fluid_settings_t *settings) fluid_settings_getint(settings, "synth.audio-channels", &synth->audio_channels); fluid_settings_getint(settings, "synth.audio-groups", &synth->audio_groups); fluid_settings_getint(settings, "synth.effects-channels", &synth->effects_channels); - fluid_settings_getnum(settings, "synth.gain", &gain); - synth->gain = gain; + fluid_settings_getnum_float(settings, "synth.gain", &synth->gain); fluid_settings_getint(settings, "synth.device-id", &synth->device_id); fluid_settings_getint(settings, "synth.cpu-cores", &synth->cores); - fluid_settings_getnum(settings, "synth.overflow.percussion", &num_val); - synth->overflow.percussion = num_val; - fluid_settings_getnum(settings, "synth.overflow.released", &num_val); - synth->overflow.released = num_val; - fluid_settings_getnum(settings, "synth.overflow.sustained", &num_val); - synth->overflow.sustained = num_val; - fluid_settings_getnum(settings, "synth.overflow.volume", &num_val); - synth->overflow.volume = num_val; - fluid_settings_getnum(settings, "synth.overflow.age", &num_val); - synth->overflow.age = num_val; + fluid_settings_getnum_float(settings, "synth.overflow.percussion", &synth->overflow.percussion); + fluid_settings_getnum_float(settings, "synth.overflow.released", &synth->overflow.released); + fluid_settings_getnum_float(settings, "synth.overflow.sustained", &synth->overflow.sustained); + fluid_settings_getnum_float(settings, "synth.overflow.volume", &synth->overflow.volume); + fluid_settings_getnum_float(settings, "synth.overflow.age", &synth->overflow.age); /* register the callbacks */ fluid_settings_callback_num(settings, "synth.sample-rate", diff --git a/src/utils/fluid_settings.c b/src/utils/fluid_settings.c index 72a096c1..63d34a13 100644 --- a/src/utils/fluid_settings.c +++ b/src/utils/fluid_settings.c @@ -1249,6 +1249,27 @@ fluid_settings_getnum(fluid_settings_t* settings, const char *name, double* val) return retval; } +/** + * float-typed wrapper for fluid_settings_getnum + * + * @param settings a settings object + * @param name a setting's name + * @param val variable pointer to receive the setting's float value + * @return #FLUID_OK if the value exists, #FLUID_FAILED otherwise + */ +int fluid_settings_getnum_float(fluid_settings_t *settings, const char *name, float *val) +{ + double tmp; + + if (fluid_settings_getnum(settings, name, &tmp) == FLUID_OK) + { + *val = tmp; + return FLUID_OK; + } + + return FLUID_FAILED; +} + /** * Get the range of values of a numeric setting * diff --git a/src/utils/fluid_settings.h b/src/utils/fluid_settings.h index 65f23280..6eef5896 100644 --- a/src/utils/fluid_settings.h +++ b/src/utils/fluid_settings.h @@ -40,6 +40,9 @@ int fluid_settings_register_num(fluid_settings_t* settings, const char* name, do int fluid_settings_callback_num(fluid_settings_t* settings, const char* name, fluid_num_update_t fun, void* data); +/* Type specific wrapper for fluid_settings_getnum */ +int fluid_settings_getnum_float(fluid_settings_t *settings, const char *name, float *val); + typedef void (*fluid_int_update_t)(void* data, const char* name, int value); int fluid_settings_register_int(fluid_settings_t* settings, const char* name, int def, From 0a57c4cf0a9951ee770de9e01e191717bbfd2f36 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Sat, 2 Dec 2017 15:54:45 +0100 Subject: [PATCH 03/13] Document synth.overflow.* settings --- doc/fluidsettings.xml | 65 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/doc/fluidsettings.xml b/doc/fluidsettings.xml index 8fe243af..d486c91f 100644 --- a/doc/fluidsettings.xml +++ b/doc/fluidsettings.xml @@ -114,6 +114,71 @@ https://stackoverflow.com/a/6251757 Sets the minimum note duration in milliseconds. This ensures that really short duration note events, such as percussion notes, have a better chance of sounding as intended. Set to 0 to disable this feature. + + overflow.age + num + 1000 + -10000 + 10000 + + This score is divided by the number of seconds this voice has been + active and is added to the overflow priority. It is usually a positive + value and gives voices which have just been started a higher priority, + making them less likely to be killed in an overflow situation. + + + + overflow.percussion + num + 4000 + -10000 + 10000 + + Sets the overflow priority score added to voices on a percussion + channel. This is usually a positive score, to give percussion voices + a higher priority and less chance of being killed in an overflow + situation. + + + + overflow.released + num + -2000 + -10000 + 10000 + + Sets the overflow priority score added to voices that have already + received a note-off event. This is usually a negative score, to give released + voices a lower priority so that they are killed first in an overflow + situation. + + + + overflow.sustained + num + -1000 + -10000 + 10000 + + Sets the overflow priority score added to voices that are currently + sustained. With the default value, sustained voices are considered less + important and are more likely to be killed in an overflow situation. + + + + overflow.volume + num + 500 + -10000 + 10000 + + Sets the overflow priority score added to voices based on their current + volume. The voice volume is normalized to a value between 0 and 1 and + multiplied with this setting. So voices with maximum volume get added + the full score, voices with only half that volume get added half of this + score. + + parallel-render bool From a3aef4b2eef0f1f10793d0365c467b213e69d921 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Sat, 2 Dec 2017 15:57:21 +0100 Subject: [PATCH 04/13] Add ability to mark channels as important in overflow priority calculation FluidSynths overflow priority calculation, that determines which voice to kill if the current polyphony limit has been reached, treats all channels as equal. Only percussion channels can get a user defined score added to their priority. In certain use-cases there can be a number of MIDI channels that are much more important than other ones, and not just percussion channels. For example, a channel playing a constant pad sound which would be very noticeable if killed. This change adds two new synth.overflow settings: - synth.overflow.important - synth.overflow.important-channels They add the ability to mark MIDI channels as "important" and have the overflow calculation add a user defined score to voices on those channels. --- doc/fluidsettings.xml | 24 +++++++++ src/synth/fluid_synth.c | 107 ++++++++++++++++++++++++++++++++++++- src/synth/fluid_voice.c | 8 +++ src/synth/fluid_voice.h | 3 ++ src/utils/fluid_settings.c | 33 ++++++++++++ src/utils/fluid_settings.h | 2 + 6 files changed, 175 insertions(+), 2 deletions(-) diff --git a/doc/fluidsettings.xml b/doc/fluidsettings.xml index d486c91f..c19687b0 100644 --- a/doc/fluidsettings.xml +++ b/doc/fluidsettings.xml @@ -127,6 +127,30 @@ https://stackoverflow.com/a/6251757 making them less likely to be killed in an overflow situation. + + overflow.important + num + 5000 + -50000 + 50000 + + This score is added to voices on channels marked with the + synth.overflow.important-channels setting. + + + + overflow.important-channels + str + "" + + This setting is a comma-separated list of MIDI channel numbers that should + be treated as "important" by the overflow calculation, adding the score + set by synth.overflow.important to each voice on those channels. It can + be used to make voices on particular MIDI channels + less likely (synth.overflow.important > 0) or more likely + (synth.overflow.important < 0) to be killed in an overflow situation. + + overflow.percussion num diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index f108c869..536e89aa 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -98,12 +98,18 @@ static void fluid_synth_set_gen_LOCAL (fluid_synth_t* synth, int chan, int param, float value, int absolute); static void fluid_synth_stop_LOCAL (fluid_synth_t *synth, unsigned int id); + +static int fluid_synth_set_important_channels(fluid_synth_t *synth, const char *channels); + + /* Callback handlers for real-time settings */ static void fluid_synth_handle_sample_rate(void *data, const char *name, double value); static void fluid_synth_handle_gain(void *data, const char *name, double value); static void fluid_synth_handle_polyphony(void *data, const char *name, int value); static void fluid_synth_handle_device_id(void *data, const char *name, int value); static void fluid_synth_handle_overflow(void *data, const char *name, double value); +static void fluid_synth_handle_important_channels(void *data, const char *name, + const char *value); /*************************************************************** @@ -184,6 +190,8 @@ void fluid_synth_settings(fluid_settings_t* settings) fluid_settings_register_num(settings, "synth.overflow.released", -2000, -10000, 10000, 0); fluid_settings_register_num(settings, "synth.overflow.age", 1000, -10000, 10000, 0); fluid_settings_register_num(settings, "synth.overflow.volume", 500, -10000, 10000, 0); + fluid_settings_register_num(settings, "synth.overflow.important", 5000, -50000, 50000, 0); + fluid_settings_register_str(settings, "synth.overflow.important-channels", "", 0); fluid_settings_register_str(settings, "synth.midi-bank-select", "gs", 0); fluid_settings_add_option(settings, "synth.midi-bank-select", "gm"); @@ -515,6 +523,7 @@ new_fluid_synth(fluid_settings_t *settings) { fluid_synth_t* synth; fluid_sfloader_t* loader; + char *important_channels; int i, nbuf; int with_ladspa = 0; @@ -576,6 +585,7 @@ new_fluid_synth(fluid_settings_t *settings) fluid_settings_getnum_float(settings, "synth.overflow.sustained", &synth->overflow.sustained); fluid_settings_getnum_float(settings, "synth.overflow.volume", &synth->overflow.volume); fluid_settings_getnum_float(settings, "synth.overflow.age", &synth->overflow.age); + fluid_settings_getnum_float(settings, "synth.overflow.important", &synth->overflow.important); /* register the callbacks */ fluid_settings_callback_num(settings, "synth.sample-rate", @@ -596,6 +606,10 @@ new_fluid_synth(fluid_settings_t *settings) fluid_synth_handle_overflow, synth); fluid_settings_callback_num(settings, "synth.overflow.volume", fluid_synth_handle_overflow, synth); + fluid_settings_callback_num(settings, "synth.overflow.important", + fluid_synth_handle_overflow, synth); + fluid_settings_callback_str(settings, "synth.overflow.important-channels", + fluid_synth_handle_important_channels, synth); /* do some basic sanity checking on the settings */ @@ -633,7 +647,6 @@ new_fluid_synth(fluid_settings_t *settings) synth->effects_channels = 2; } - /* The number of buffers is determined by the higher number of nr * groups / nr audio channels. If LADSPA is unused, they should be * the same. */ @@ -642,6 +655,16 @@ new_fluid_synth(fluid_settings_t *settings) nbuf = synth->audio_groups; } + if (fluid_settings_dupstr(settings, "synth.overflow.important-channels", + &important_channels) == FLUID_OK) + { + if (fluid_synth_set_important_channels(synth, important_channels) != FLUID_OK) + { + FLUID_LOG(FLUID_WARN, "Failed to set overflow important channels"); + } + FLUID_FREE(important_channels); + } + /* as soon as the synth is created it starts playing. */ synth->state = FLUID_SYNTH_PLAYING; synth->sfont_info = NULL; @@ -900,6 +923,8 @@ delete_fluid_synth(fluid_synth_t* synth) fluid_mod_delete(mod); } + FLUID_FREE(synth->overflow.important_channels); + fluid_rec_mutex_destroy(synth->mutex); FLUID_FREE(synth); @@ -3150,11 +3175,13 @@ static void fluid_synth_handle_overflow (void *data, const char *name, double va else if (FLUID_STRCMP(name, "synth.overflow.age") == 0) { synth->overflow.age = value; } + else if (FLUID_STRCMP(name, "synth.overflow.important") == 0) { + synth->overflow.important = value; + } fluid_synth_api_exit(synth); } - /* Selects a voice for killing. */ static fluid_voice_t* fluid_synth_free_voice_by_kill_LOCAL(fluid_synth_t* synth) @@ -5281,3 +5308,79 @@ fluid_ladspa_fx_t *fluid_synth_get_ladspa_fx(fluid_synth_t *synth) return synth->ladspa_fx; } + +/** + * Set the important channels for voice overflow priority calculation. + * + * @param synth FluidSynth instance + * @param channels comma-separated list of channel numbers + * @return FLUID_OK on success, otherwise FLUID_FAILED + */ +static int fluid_synth_set_important_channels(fluid_synth_t *synth, const char *channels) +{ + int i; + int retval = FLUID_FAILED; + int *values = NULL; + int num_values; + fluid_overflow_prio_t *scores; + + fluid_return_val_if_fail(synth != NULL, FLUID_FAILED); + + scores = &synth->overflow; + if (scores->num_important_channels < synth->midi_channels) + { + scores->important_channels = FLUID_REALLOC(scores->important_channels, + sizeof(*scores->important_channels) * synth->midi_channels); + if (scores->important_channels == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + goto exit; + } + scores->num_important_channels = synth->midi_channels; + } + + for (i = 0; i < scores->num_important_channels; i++) + { + scores->important_channels[i] = FALSE; + } + + if (channels != NULL) + { + values = FLUID_ARRAY(int, synth->midi_channels); + if (values == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + goto exit; + } + /* Every channel given in the comma-separated list of channel numbers + * is set to TRUE, i.e. flagging it as "important". Channel numbers are + * 1-based. */ + num_values = fluid_settings_split_csv(channels, values, synth->midi_channels); + for (i = 0; i < num_values; i++) + { + if (values[i] > 0 && values[i] <= synth->midi_channels) + { + scores->important_channels[values[i] - 1] = TRUE; + } + } + } + + retval = FLUID_OK; + +exit: + FLUID_FREE(values); + return retval; +} + +/* + * Handler for synth.overflow.important-channels setting. + */ +static void fluid_synth_handle_important_channels(void *data, const char *name, + const char *value) +{ + fluid_synth_t *synth = (fluid_synth_t *)data; + + fluid_synth_api_enter(synth); + fluid_synth_set_important_channels(synth, value); + fluid_synth_api_exit(synth); +} diff --git a/src/synth/fluid_voice.c b/src/synth/fluid_voice.c index ce966434..7c3a64b5 100644 --- a/src/synth/fluid_voice.c +++ b/src/synth/fluid_voice.c @@ -1687,6 +1687,7 @@ fluid_voice_get_overflow_prio(fluid_voice_t* voice, unsigned int cur_time) { float this_voice_prio = 0; + int channel; /* Are we already overflowing? */ if (!voice->can_access_overflow_rvoice) { @@ -1734,6 +1735,13 @@ fluid_voice_get_overflow_prio(fluid_voice_t* voice, } this_voice_prio += score->volume / a; } + + /* Check if this voice is on an important channel. If so, then add the + * score for important channels */ + channel = fluid_voice_get_channel(voice); + if (channel < score->num_important_channels && score->important_channels[channel]) { + this_voice_prio += score->important; + } return this_voice_prio; } diff --git a/src/synth/fluid_voice.h b/src/synth/fluid_voice.h index 0bfea234..ef904138 100644 --- a/src/synth/fluid_voice.h +++ b/src/synth/fluid_voice.h @@ -42,6 +42,9 @@ struct _fluid_overflow_prio_t float sustained; /**< Is this voice sustained? Then add this score (usually negative) */ float volume; /**< Multiply current (or future) volume (a value between 0 and 1) */ float age; /**< This score will be divided by the number of seconds the voice has lasted */ + float important; /**< This score will be added to all important channels */ + char *important_channels; /**< "important" flags indexed by MIDI channel number */ + int num_important_channels; /**< Number of elements in the important_channels array */ }; enum fluid_voice_status diff --git a/src/utils/fluid_settings.c b/src/utils/fluid_settings.c index 63d34a13..b0565290 100644 --- a/src/utils/fluid_settings.c +++ b/src/utils/fluid_settings.c @@ -1738,3 +1738,36 @@ fluid_settings_foreach (fluid_settings_t* settings, void* data, delete_fluid_list (bag.names); /* -- Free names list */ } + +/** + * Split a comma-separated list of integers and fill the passed + * in buffer with the parsed values. + * + * @param str the comma-separated string to split + * @param buf user-supplied buffer to hold the parsed numbers + * @param buf_len length of user-supplied buffer + * @return number of parsed values or -1 on failure + */ +int fluid_settings_split_csv(const char *str, int *buf, int buf_len) +{ + char *s; + char *tok; + char *tokstr; + int n = 0; + + s = tokstr = FLUID_STRDUP(str); + if (s == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return -1; + } + + while ((tok = fluid_strtok(&tokstr, ",")) && n < buf_len) + { + buf[n++] = atoi(tok); + } + + FLUID_FREE(s); + + return n; +} diff --git a/src/utils/fluid_settings.h b/src/utils/fluid_settings.h index 6eef5896..45582ec8 100644 --- a/src/utils/fluid_settings.h +++ b/src/utils/fluid_settings.h @@ -50,4 +50,6 @@ int fluid_settings_register_int(fluid_settings_t* settings, const char* name, in int fluid_settings_callback_int(fluid_settings_t* settings, const char* name, fluid_int_update_t fun, void* data); +int fluid_settings_split_csv(const char *str, int *buf, int buf_len); + #endif /* _FLUID_SETTINGS_H */ From 8525e420b070c0f8c0ed52958a1921be379def8d Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Sat, 2 Dec 2017 17:03:03 +0100 Subject: [PATCH 05/13] Allow overwriting the compile-time flags for gcc/clang. --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68a27f5b..8e6cbb61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,9 +158,9 @@ if ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" ) endif ( OS2 ) set ( GNUCC_WARNING_FLAGS "-Wall -W -Wpointer-arith -Wbad-function-cast -Wno-cast-qual -Wcast-align -Wstrict-prototypes -Wno-unused-parameter -Wdeclaration-after-statement" ) - set ( CMAKE_C_FLAGS_DEBUG "-std=gnu89 -g ${GNUCC_VISIBILITY_FLAG} -DDEBUG ${GNUCC_WARNING_FLAGS} -fsanitize=undefined" ) - set ( CMAKE_C_FLAGS_RELEASE "-std=gnu89 -O2 -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS}" ) - set ( CMAKE_C_FLAGS_RELWITHDEBINFO "-std=gnu89 -O2 -g -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS}" ) + set ( CMAKE_C_FLAGS_DEBUG "-std=gnu89 -g ${GNUCC_VISIBILITY_FLAG} -DDEBUG ${GNUCC_WARNING_FLAGS} -fsanitize=undefined ${CMAKE_C_FLAGS_DEBUG}" ) + set ( CMAKE_C_FLAGS_RELEASE "-std=gnu89 -O2 -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS} ${CMAKE_C_FLAGS_RELEASE}" ) + set ( CMAKE_C_FLAGS_RELWITHDEBINFO "-std=gnu89 -O2 -g -fomit-frame-pointer -finline-functions ${GNUCC_VISIBILITY_FLAG} -DNDEBUG ${GNUCC_WARNING_FLAGS} ${CMAKE_C_FLAGS_RELWITHDEBINFO}" ) endif ( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" ) # Windows From cdfe8d3d7db04fc02167bae0b935ff4d18bab317 Mon Sep 17 00:00:00 2001 From: carlo-bramini <30959007+carlo-bramini@users.noreply.github.com> Date: Sun, 3 Dec 2017 13:12:27 +0100 Subject: [PATCH 06/13] Include fixes 2 (#296) Remove redundant includes --- src/bindings/fluid_filerenderer.c | 4 +--- src/drivers/fluid_alsa.c | 6 ------ src/drivers/fluid_aufile.c | 4 +--- src/drivers/fluid_coreaudio.c | 2 -- src/drivers/fluid_jack.c | 2 -- src/drivers/fluid_pulse.c | 2 -- src/midi/fluid_seq.c | 1 - src/synth/fluid_synth.c | 2 -- src/synth/fluid_synth.h | 6 +----- src/utils/fluid_settings.c | 1 - src/utils/fluidsynth_priv.h | 1 - 11 files changed, 3 insertions(+), 28 deletions(-) diff --git a/src/bindings/fluid_filerenderer.c b/src/bindings/fluid_filerenderer.c index 8ef4a051..b132bfa9 100644 --- a/src/bindings/fluid_filerenderer.c +++ b/src/bindings/fluid_filerenderer.c @@ -22,10 +22,8 @@ * Low-level routines for file output. */ -#include -#include "fluidsynth_priv.h" -#include "fluid_synth.h" #include "fluid_sys.h" +#include "fluid_synth.h" #include "fluid_settings.h" #if LIBSNDFILE_SUPPORT diff --git a/src/drivers/fluid_alsa.c b/src/drivers/fluid_alsa.c index afb593fb..4d4d3004 100644 --- a/src/drivers/fluid_alsa.c +++ b/src/drivers/fluid_alsa.c @@ -34,13 +34,7 @@ #define ALSA_PCM_NEW_HW_PARAMS_API #include -#include -#include -#include #include -#include - -#include "config.h" #include "fluid_lash.h" diff --git a/src/drivers/fluid_aufile.c b/src/drivers/fluid_aufile.c index 7d5865dd..84cd03ed 100644 --- a/src/drivers/fluid_aufile.c +++ b/src/drivers/fluid_aufile.c @@ -24,11 +24,9 @@ * */ +#include "fluid_sys.h" #include "fluid_adriver.h" #include "fluid_settings.h" -#include "fluid_sys.h" -#include "config.h" -#include /** fluid_file_audio_driver_t diff --git a/src/drivers/fluid_coreaudio.c b/src/drivers/fluid_coreaudio.c index a3a146c3..18257b91 100644 --- a/src/drivers/fluid_coreaudio.c +++ b/src/drivers/fluid_coreaudio.c @@ -30,8 +30,6 @@ #include "fluid_mdriver.h" #include "fluid_settings.h" -#include "config.h" - #if COREAUDIO_SUPPORT #include #include diff --git a/src/drivers/fluid_jack.c b/src/drivers/fluid_jack.c index 75fd1d37..296306e7 100644 --- a/src/drivers/fluid_jack.c +++ b/src/drivers/fluid_jack.c @@ -28,7 +28,6 @@ * */ -#include "fluidsynth_priv.h" #include "fluid_sys.h" #include "fluid_synth.h" #include "fluid_adriver.h" @@ -38,7 +37,6 @@ #include #include -#include "config.h" #include "fluid_lash.h" diff --git a/src/drivers/fluid_pulse.c b/src/drivers/fluid_pulse.c index 2cdd0219..b86b15f4 100644 --- a/src/drivers/fluid_pulse.c +++ b/src/drivers/fluid_pulse.c @@ -28,8 +28,6 @@ #include "fluid_adriver.h" #include "fluid_settings.h" -#include "config.h" - #if PULSE_SUPPORT #include diff --git a/src/midi/fluid_seq.c b/src/midi/fluid_seq.c index e2c6d99c..b4ba1b75 100644 --- a/src/midi/fluid_seq.c +++ b/src/midi/fluid_seq.c @@ -28,7 +28,6 @@ */ #include "fluid_event_priv.h" -#include "fluidsynth_priv.h" // FLUID_NEW, etc #include "fluid_sys.h" // timer, threads, etc... #include "fluid_list.h" diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index e0c16e29..8660fdac 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -18,8 +18,6 @@ * 02110-1301, USA */ -#include - #include "fluid_synth.h" #include "fluid_sys.h" #include "fluid_chan.h" diff --git a/src/synth/fluid_synth.h b/src/synth/fluid_synth.h index a21902b0..3400fe8a 100644 --- a/src/synth/fluid_synth.h +++ b/src/synth/fluid_synth.h @@ -28,17 +28,13 @@ * INCLUDES */ -#if HAVE_CONFIG_H -#include "config.h" -#endif -#include "fluidsynth_priv.h" +#include "fluid_sys.h" #include "fluid_list.h" #include "fluid_rev.h" #include "fluid_voice.h" #include "fluid_chorus.h" #include "fluid_ladspa.h" #include "fluid_midi_router.h" -#include "fluid_sys.h" #include "fluid_rvoice_event.h" /*************************************************************** diff --git a/src/utils/fluid_settings.c b/src/utils/fluid_settings.c index 72a096c1..c91bfe8a 100644 --- a/src/utils/fluid_settings.c +++ b/src/utils/fluid_settings.c @@ -18,7 +18,6 @@ * 02110-1301, USA */ -#include "fluidsynth_priv.h" #include "fluid_sys.h" #include "fluid_hash.h" #include "fluid_synth.h" diff --git a/src/utils/fluidsynth_priv.h b/src/utils/fluidsynth_priv.h index 130f1dd7..e79e0efa 100644 --- a/src/utils/fluidsynth_priv.h +++ b/src/utils/fluidsynth_priv.h @@ -129,7 +129,6 @@ typedef guint64 uint64_t; #if defined(WIN32) && HAVE_WINDOWS_H #include #include /* Provides also socklen_t */ -#include /* WIN32 special defines */ #define DSOUND_SUPPORT 1 From c30d519572b3f32a6192cbdb2af6f93d2719d111 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Dec 2017 15:13:26 +0100 Subject: [PATCH 07/13] return -1 in fluid_midi_file_getc() closes #93 --- src/midi/fluid_midi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index eb84ded8..5d5e517d 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -126,7 +126,7 @@ delete_fluid_midi_file (fluid_midi_file *mf) /* * Gets the next byte in a MIDI file, taking into account previous running status. * - * returns FLUID_FAILED if EOF or read error + * returns -1 if EOF or read error */ int fluid_midi_file_getc (fluid_midi_file *mf) @@ -138,7 +138,7 @@ fluid_midi_file_getc (fluid_midi_file *mf) } else { if (mf->buf_pos >= mf->buf_len) { mf->eof = TRUE; - return FLUID_FAILED; + return -1; } c = mf->buffer[mf->buf_pos++]; mf->trackpos++; From 7be328a357ece7a1bc7c8873c9fa76058493190d Mon Sep 17 00:00:00 2001 From: carlo-bramini Date: Sun, 3 Dec 2017 19:37:20 +0100 Subject: [PATCH 08/13] Simpler implementation of WINMIDI driver. --- src/drivers/fluid_winmidi.c | 137 ++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 78 deletions(-) diff --git a/src/drivers/fluid_winmidi.c b/src/drivers/fluid_winmidi.c index fc2021a1..7b588eb6 100644 --- a/src/drivers/fluid_winmidi.c +++ b/src/drivers/fluid_winmidi.c @@ -44,22 +44,17 @@ typedef struct { fluid_midi_driver_t driver; HMIDIIN hmidiin; - fluid_atomic_int_t closing; /* Set to TRUE when closing driver, to prevent endless SYSEX lockup loop */ - - fluid_thread_t *sysExAddThread; /* Thread for SYSEX re-add thread */ - fluid_cond_mutex_t *mutex; /* Lock for condition */ - fluid_cond_t *cond; /* Condition to signal MIDI event thread of available events */ /* MIDI HDR for SYSEX buffer */ MIDIHDR sysExHdrs[MIDI_SYSEX_BUF_COUNT]; - /* TRUE for each MIDIHDR buffer which should be re-added to MIDI device */ - fluid_atomic_int_t sysExHdrAdd[MIDI_SYSEX_BUF_COUNT]; + /* Thread for SYSEX re-add thread */ + HANDLE hThread; + DWORD dwThread; /* Sysex data buffer */ unsigned char sysExBuf[MIDI_SYSEX_BUF_COUNT * MIDI_SYSEX_MAX_SIZE]; - int sysExOffset; /* Current offset in sysex buffer (for message continuation) */ } fluid_winmidi_driver_t; static char fluid_winmidi_error_buffer[256]; @@ -76,7 +71,6 @@ void delete_fluid_winmidi_driver(fluid_midi_driver_t* p); void CALLBACK fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR msg, DWORD_PTR extra); -static fluid_thread_return_t fluid_winmidi_add_sysex_thread (void *data); static char* fluid_winmidi_input_error(int no); int fluid_winmidi_driver_status(fluid_midi_driver_t* p); @@ -99,6 +93,34 @@ void fluid_winmidi_midi_driver_settings(fluid_settings_t* settings) } } +/* Thread for re-adding SYSEX buffers */ +static DWORD WINAPI fluid_winmidi_add_sysex_thread(void *data) +{ + fluid_winmidi_driver_t *dev = (fluid_winmidi_driver_t *)data; + MSG msg; + int code; + + for (;;) { + code = GetMessage(&msg, NULL, 0, 0); + + if (code < 0) { + FLUID_LOG(FLUID_ERR, "fluid_winmidi_add_sysex_thread: GetMessage() failed."); + break; + } + + if (msg.message == WM_CLOSE) + break; + + switch (msg.message) { + case MM_MIM_LONGDATA: + midiInAddBuffer(dev->hmidiin, (LPMIDIHDR)msg.lParam, sizeof(MIDIHDR)); + break; + } + } + + return 0; +} + /* * new_fluid_winmidi_driver */ @@ -129,7 +151,6 @@ new_fluid_winmidi_driver(fluid_settings_t* settings, dev->hmidiin = NULL; dev->driver.handler = handler; dev->driver.data = data; - fluid_atomic_int_set (&dev->closing, FALSE); /* get the device name. if none is specified, use the default device. */ if(fluid_settings_dupstr(settings, "midi.winmidi.device", &devname) != FLUID_OK || !devname) { @@ -181,10 +202,9 @@ new_fluid_winmidi_driver(fluid_settings_t* settings, /* Prepare and add SYSEX buffers */ for (i = 0; i < MIDI_SYSEX_BUF_COUNT; i++) { - fluid_atomic_int_set (&dev->sysExHdrAdd[i], FALSE); hdr = &dev->sysExHdrs[i]; - hdr->lpData = &dev->sysExBuf[i * MIDI_SYSEX_MAX_SIZE]; + hdr->lpData = (LPSTR)&dev->sysExBuf[i * MIDI_SYSEX_MAX_SIZE]; hdr->dwBufferLength = MIDI_SYSEX_MAX_SIZE; /* Prepare a buffer for SYSEX data and add it */ @@ -205,31 +225,28 @@ new_fluid_winmidi_driver(fluid_settings_t* settings, fluid_winmidi_input_error (err), err); } + /* Create thread which processes re-adding SYSEX buffers */ + dev->hThread = CreateThread( + NULL, + 0, + (LPTHREAD_START_ROUTINE) + fluid_winmidi_add_sysex_thread, + dev, + 0, + &dev->dwThread); + + if (dev->hThread == NULL) + { + FLUID_LOG(FLUID_ERR, "Failed to create SYSEX buffer processing thread"); + goto error_recovery; + } + /* Start the MIDI input interface */ if (midiInStart(dev->hmidiin) != MMSYSERR_NOERROR) { FLUID_LOG(FLUID_ERR, "Failed to start the MIDI input. MIDI input not available."); goto error_recovery; } - /* Create mutex and condition */ - dev->mutex = new_fluid_cond_mutex (); - dev->cond = new_fluid_cond (); - - if (!dev->mutex || !dev->cond) - { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - - /* Create thread which processes re-adding SYSEX buffers */ - dev->sysExAddThread = new_fluid_thread ("winmidi-sysex", fluid_winmidi_add_sysex_thread, - dev, 0, FALSE); - if (!dev->sysExAddThread) - { - FLUID_LOG(FLUID_ERR, "Failed to create SYSEX buffer processing thread"); - goto error_recovery; - } - if (devname) FLUID_FREE (devname); /* -- free device name */ return (fluid_midi_driver_t*) dev; @@ -248,27 +265,22 @@ delete_fluid_winmidi_driver(fluid_midi_driver_t* p) { fluid_winmidi_driver_t* dev = (fluid_winmidi_driver_t*) p; fluid_return_if_fail (dev != NULL); - - if (dev->hmidiin != NULL) { - fluid_atomic_int_set (&dev->closing, TRUE); - if (dev->sysExAddThread) - { - fluid_cond_mutex_lock (dev->mutex); /* ++ lock */ - fluid_cond_signal (dev->cond); - fluid_cond_mutex_unlock (dev->mutex); /* -- unlock */ + if (dev->hThread != NULL) + { + PostThreadMessage(dev->dwThread, WM_CLOSE, 0, 0); + WaitForSingleObject(dev->hThread, INFINITE); - fluid_thread_join (dev->sysExAddThread); - } + dev->hThread = NULL; + } + if (dev->hmidiin != NULL) + { midiInStop(dev->hmidiin); midiInReset(dev->hmidiin); midiInClose(dev->hmidiin); } - if (dev->mutex) delete_fluid_cond_mutex (dev->mutex); - if (dev->cond) delete_fluid_cond (dev->cond); - FLUID_FREE(dev); } @@ -280,7 +292,6 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance, fluid_midi_event_t event; LPMIDIHDR pMidiHdr; unsigned char *data; - int index; unsigned int msg_param = (unsigned int) dwParam1; switch (wMsg) { @@ -306,7 +317,8 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance, break; case MIM_LONGDATA: /* SYSEX data */ - if (fluid_atomic_int_get (&dev->closing)) break; /* Prevent MIM_LONGDATA endless loop, don't re-add buffer if closing */ + if (dev->hThread == NULL) + break; pMidiHdr = (LPMIDIHDR)dwParam1; data = (unsigned char *)(pMidiHdr->lpData); @@ -320,12 +332,7 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance, (*dev->driver.handler)(dev->driver.data, &event); } - index = (pMidiHdr - dev->sysExHdrs) / sizeof (MIDIHDR); - fluid_atomic_int_set (&dev->sysExHdrAdd[index], TRUE); - - fluid_cond_mutex_lock (dev->mutex); /* ++ lock */ - fluid_cond_signal (dev->cond); - fluid_cond_mutex_unlock (dev->mutex); /* -- unlock */ + PostThreadMessage(dev->dwThread, MM_MIM_LONGDATA, 0, dwParam1); break; case MIM_ERROR: @@ -339,32 +346,6 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance, } } -/* Thread for re-adding SYSEX buffers */ -static fluid_thread_return_t -fluid_winmidi_add_sysex_thread (void *data) -{ - fluid_winmidi_driver_t *dev = data; - int i; - - while (!fluid_atomic_int_get (&dev->closing)) - { - fluid_cond_mutex_lock (dev->mutex); /* ++ lock */ - fluid_cond_wait (dev->cond, dev->mutex); - fluid_cond_mutex_unlock (dev->mutex); /* -- unlock */ - - for (i = 0; i < MIDI_SYSEX_BUF_COUNT; i++) - { - if (fluid_atomic_int_get (&dev->sysExHdrAdd[i])) - { - fluid_atomic_int_set (&dev->sysExHdrAdd[i], FALSE); - midiInAddBuffer (dev->hmidiin, &dev->sysExHdrs[i], sizeof (MIDIHDR)); - } - } - } - - return FLUID_THREAD_RETURN_VALUE; -} - int fluid_winmidi_driver_status(fluid_midi_driver_t* p) { From 6eb450b40c6ec2ee63b525036419f2a6b9669714 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Dec 2017 20:31:00 +0100 Subject: [PATCH 09/13] silence -Wdocumentation warnings --- src/bindings/fluid_filerenderer.c | 5 ++--- src/midi/fluid_midi.c | 2 -- src/sfloader/fluid_ramsfont.c | 1 - src/synth/fluid_synth.c | 1 - src/utils/fluid_ringbuffer.h | 2 +- 5 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/bindings/fluid_filerenderer.c b/src/bindings/fluid_filerenderer.c index b132bfa9..477dd8d8 100644 --- a/src/bindings/fluid_filerenderer.c +++ b/src/bindings/fluid_filerenderer.c @@ -288,10 +288,10 @@ new_fluid_file_renderer(fluid_synth_t* synth) * @since 1.1.7 */ int -fluid_file_set_encoding_quality(fluid_file_renderer_t* r, double q) +fluid_file_set_encoding_quality(fluid_file_renderer_t* dev, double q) { #if LIBSNDFILE_SUPPORT - if (sf_command (r->sndfile, SFC_SET_VBR_ENCODING_QUALITY, &q, sizeof (double)) == SF_TRUE) + if (sf_command (dev->sndfile, SFC_SET_VBR_ENCODING_QUALITY, &q, sizeof (double)) == SF_TRUE) return FLUID_OK; else #endif @@ -453,7 +453,6 @@ fluid_file_renderer_parse_options (char *filetype, char *format, char *endian, /** * Searches for a supported libsndfile file type by extension. * @param extension The extension string - * @param ext_len Length of the extension string * @param type Location to store the type (unmodified if not found) * @return TRUE if found, FALSE otherwise */ diff --git a/src/midi/fluid_midi.c b/src/midi/fluid_midi.c index 5d5e517d..c3cbd9d9 100644 --- a/src/midi/fluid_midi.c +++ b/src/midi/fluid_midi.c @@ -797,7 +797,6 @@ new_fluid_midi_event () /** * Delete MIDI event structure. * @param evt MIDI event structure - * @return Always returns #FLUID_OK */ void delete_fluid_midi_event(fluid_midi_event_t *evt) @@ -1259,7 +1258,6 @@ new_fluid_player(fluid_synth_t *synth) /** * Delete a MIDI player instance. * @param player MIDI player instance - * @return Always returns #FLUID_OK */ void delete_fluid_player(fluid_player_t *player) diff --git a/src/sfloader/fluid_ramsfont.c b/src/sfloader/fluid_ramsfont.c index d75eb545..b2385632 100644 --- a/src/sfloader/fluid_ramsfont.c +++ b/src/sfloader/fluid_ramsfont.c @@ -1211,7 +1211,6 @@ new_fluid_ramsample (void) /** * Delete a RAM SoundFont sample. * @param sample Sample to delete - * @return #FLUID_OK */ void delete_fluid_ramsample (fluid_sample_t* sample) diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 8660fdac..95eb2ae0 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -790,7 +790,6 @@ new_fluid_synth(fluid_settings_t *settings) /** * Delete a FluidSynth instance. * @param synth FluidSynth instance to delete - * @return FLUID_OK * * @note Other users of a synthesizer instance, such as audio and MIDI drivers, * should be deleted prior to freeing the FluidSynth instance. diff --git a/src/utils/fluid_ringbuffer.h b/src/utils/fluid_ringbuffer.h index eff598e4..a1d2c221 100644 --- a/src/utils/fluid_ringbuffer.h +++ b/src/utils/fluid_ringbuffer.h @@ -46,7 +46,7 @@ void delete_fluid_ringbuffer (fluid_ringbuffer_t *queue); /** * Get pointer to next input array element in queue. * @param queue Lockless queue instance - * @param count Normally zero, or more if you need to push several items at once + * @param offset Normally zero, or more if you need to push several items at once * @return Pointer to array element in queue to store data to or NULL if queue is full * * This function along with fluid_ringbuffer_next_inptr() form a queue "push" From 8a4033e2e19cf80f84444ccc8cca3998e8f2b0f0 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 3 Dec 2017 21:37:25 +0100 Subject: [PATCH 10/13] mention fluid_player_seek() in API docs --- doc/fluidsynth-v11-devdoc.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/fluidsynth-v11-devdoc.txt b/doc/fluidsynth-v11-devdoc.txt index 663b1303..f9628ea0 100644 --- a/doc/fluidsynth-v11-devdoc.txt +++ b/doc/fluidsynth-v11-devdoc.txt @@ -94,13 +94,13 @@ Changes in FluidSynth 2.0.0 concerning developers:

- add "synth.volenv" a setting for volume envelope processing - add "midi.autoconnect" a setting for automatically connecting fluidsynth to available MIDI input ports -- add support for polyonic key pressure events, see fluid_event_key_pressure() +- add support for polyonic key pressure events, see fluid_event_key_pressure() and fluid_synth_key_pressure() - add fluid_synth_add_default_mod() and fluid_synth_remove_default_mod() for manipulating default modulators - add individual reverb setters: fluid_synth_set_reverb_roomsize(), fluid_synth_set_reverb_damp(), fluid_synth_set_reverb_width(), fluid_synth_set_reverb_level() - add individual chorus setters: fluid_synth_set_chorus_nr(), fluid_synth_set_chorus_level(), fluid_synth_set_chorus_speed(), fluid_synth_set_chorus_depth(), fluid_synth_set_chorus_type() - introduce a separate data type for sequencer client IDs: #fluid_seq_id_t - add file callback struct to _fluid_sfloader_t and expose new_fluid_defsfloader() to enable soundfont loading from memory ( see fluid_sfload_mem.c ) - +- add seek support to midi-player, see fluid_player_seek() \section NewIn1_1_9 Whats new in 1.1.9? From d77974c1352b6da14e00a278392e196bc64fe130 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Mon, 4 Dec 2017 18:50:43 +0100 Subject: [PATCH 11/13] Add note about channel numbers being 1-based. --- doc/fluidsettings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fluidsettings.xml b/doc/fluidsettings.xml index c19687b0..4054a425 100644 --- a/doc/fluidsettings.xml +++ b/doc/fluidsettings.xml @@ -148,7 +148,8 @@ https://stackoverflow.com/a/6251757 set by synth.overflow.important to each voice on those channels. It can be used to make voices on particular MIDI channels less likely (synth.overflow.important > 0) or more likely - (synth.overflow.important < 0) to be killed in an overflow situation. + (synth.overflow.important < 0) to be killed in an overflow situation. Channel + numbers are 1-based, so the first MIDI channel is number 1.
From ae48793c2803e688dc589089af4b180f65fcd8b6 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Mon, 4 Dec 2017 18:53:47 +0100 Subject: [PATCH 12/13] Replace loop with memset --- src/synth/fluid_synth.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 536e89aa..5da471ba 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -5339,10 +5339,8 @@ static int fluid_synth_set_important_channels(fluid_synth_t *synth, const char * scores->num_important_channels = synth->midi_channels; } - for (i = 0; i < scores->num_important_channels; i++) - { - scores->important_channels[i] = FALSE; - } + FLUID_MEMSET(scores->important_channels, FALSE, + sizeof(*scores->important_channels) * scores->num_important_channels); if (channels != NULL) { From a808e28f8b5236547f6430aafff8ad202668c8e5 Mon Sep 17 00:00:00 2001 From: derselbst Date: Tue, 5 Dec 2017 22:57:28 +0100 Subject: [PATCH 13/13] cleanup winmidi driver --- src/drivers/fluid_winmidi.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/drivers/fluid_winmidi.c b/src/drivers/fluid_winmidi.c index 7b588eb6..b63985ff 100644 --- a/src/drivers/fluid_winmidi.c +++ b/src/drivers/fluid_winmidi.c @@ -26,8 +26,7 @@ * NOTE: Unfortunately midiInAddBuffer(), for SYSEX data, should not be called * from within the MIDI input callback, despite many examples contrary to that * on the Internet. Some MIDI devices will deadlock. Therefore we add MIDIHDR - * pointers to a queue and re-add them in a separate thread, using a mutex and - * conditional to wake up the thread. Lame-o API! :( + * pointers to a queue and re-add them in a separate thread. Lame-o API! :( */ #include "fluidsynth_priv.h" @@ -71,8 +70,7 @@ void delete_fluid_winmidi_driver(fluid_midi_driver_t* p); void CALLBACK fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR msg, DWORD_PTR extra); -static char* fluid_winmidi_input_error(int no); -int fluid_winmidi_driver_status(fluid_midi_driver_t* p); +static char* fluid_winmidi_input_error(MMRESULT no); void fluid_winmidi_midi_driver_settings(fluid_settings_t* settings) @@ -131,7 +129,7 @@ new_fluid_winmidi_driver(fluid_settings_t* settings, fluid_winmidi_driver_t* dev; MIDIHDR *hdr; MMRESULT res; - UINT i, err, num, midi_num = 0; + UINT i, num, midi_num = 0; MIDIINCAPS in_caps; char* devname = NULL; @@ -146,7 +144,7 @@ new_fluid_winmidi_driver(fluid_settings_t* settings, return NULL; } - memset (dev, 0, sizeof (fluid_winmidi_driver_t)); + FLUID_MEMSET (dev, 0, sizeof (fluid_winmidi_driver_t)); dev->hmidiin = NULL; dev->driver.handler = handler; @@ -190,12 +188,12 @@ new_fluid_winmidi_driver(fluid_settings_t* settings, } /* try opening the device */ - err = midiInOpen(&dev->hmidiin, midi_num, + res = midiInOpen(&dev->hmidiin, midi_num, (DWORD_PTR) fluid_winmidi_callback, (DWORD_PTR) dev, CALLBACK_FUNCTION); - if (err != MMSYSERR_NOERROR) { + if (res != MMSYSERR_NOERROR) { FLUID_LOG(FLUID_ERR, "Couldn't open MIDI input: %s (error %d)", - fluid_winmidi_input_error(err), err); + fluid_winmidi_input_error(res), res); goto error_recovery; } @@ -208,21 +206,21 @@ new_fluid_winmidi_driver(fluid_settings_t* settings, hdr->dwBufferLength = MIDI_SYSEX_MAX_SIZE; /* Prepare a buffer for SYSEX data and add it */ - err = midiInPrepareHeader (dev->hmidiin, hdr, sizeof (MIDIHDR)); + res = midiInPrepareHeader (dev->hmidiin, hdr, sizeof (MIDIHDR)); - if (err == MMSYSERR_NOERROR) + if (res == MMSYSERR_NOERROR) { - err = midiInAddBuffer (dev->hmidiin, hdr, sizeof (MIDIHDR)); + res = midiInAddBuffer (dev->hmidiin, hdr, sizeof (MIDIHDR)); - if (err != MMSYSERR_NOERROR) + if (res != MMSYSERR_NOERROR) { FLUID_LOG (FLUID_WARN, "Failed to prepare MIDI SYSEX buffer: %s (error %d)", - fluid_winmidi_input_error (err), err); + fluid_winmidi_input_error (res), res); midiInUnprepareHeader (dev->hmidiin, hdr, sizeof (MIDIHDR)); } } else FLUID_LOG (FLUID_WARN, "Failed to prepare MIDI SYSEX buffer: %s (error %d)", - fluid_winmidi_input_error (err), err); + fluid_winmidi_input_error (res), res); } /* Create thread which processes re-adding SYSEX buffers */ @@ -346,14 +344,8 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance, } } -int -fluid_winmidi_driver_status(fluid_midi_driver_t* p) -{ - return 0; -} - static char* -fluid_winmidi_input_error(int no) +fluid_winmidi_input_error(MMRESULT no) { midiInGetErrorText(no, fluid_winmidi_error_buffer, 256); return fluid_winmidi_error_buffer;