From c4003bef396c60c4ddfaf2f4c033460524cb884f Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Sun, 22 Apr 2018 18:30:44 +0200 Subject: [PATCH 01/16] Store mutable information about inst zones in new fluid_voice_zone_t struct This change separates the static instrument zone information read from the Soundfont from the information that gets modified on import and later via the legato handling. It opens opens up the possibility of having unique instruments that only get imported once and then linked into the individual preset zones. --- src/sfloader/fluid_defsfont.c | 92 ++++++++++++++++++++++++++--------- src/sfloader/fluid_defsfont.h | 12 ++++- 2 files changed, 79 insertions(+), 25 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 3d5d786d..6d06c3ae 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -636,7 +636,8 @@ fluid_defpreset_noteon(fluid_defpreset_t* defpreset, fluid_synth_t* synth, int c fluid_preset_zone_t *preset_zone, *global_preset_zone; fluid_inst_t* inst; fluid_inst_zone_t *inst_zone, *global_inst_zone; - fluid_sample_t* sample; + fluid_voice_zone_t *voice_zone; + fluid_list_t *list; fluid_voice_t* voice; fluid_mod_t * mod; fluid_mod_t * mod_list[FLUID_NUM_MOD]; /* list for 'sorting' preset modulators */ @@ -656,24 +657,20 @@ fluid_defpreset_noteon(fluid_defpreset_t* defpreset, fluid_synth_t* synth, int c inst = fluid_preset_zone_get_inst(preset_zone); global_inst_zone = fluid_inst_get_global_zone(inst); - /* run thru all the zones of this instrument */ - inst_zone = fluid_inst_get_zone(inst); - while (inst_zone != NULL) { - /* make sure this instrument zone has a valid sample */ - sample = fluid_inst_zone_get_sample(inst_zone); - if ((sample == NULL) || fluid_sample_in_rom(sample)) { - inst_zone = fluid_inst_zone_next(inst_zone); - continue; - } + /* run thru all the zones of this instrument that could start a voice */ + for (list = preset_zone->voice_zone; list != NULL; list = fluid_list_next(list)) { + voice_zone = fluid_list_get(list); /* check if the instrument zone is ignored and the note falls into the key and velocity range of this instrument zone. An instrument zone must be ignored when its voice is already running played by a legato passage (see fluid_synth_noteon_monopoly_legato()) */ - if (fluid_zone_inside_range(&inst_zone->range, key, vel)) { + if (fluid_zone_inside_range(&voice_zone->range, key, vel)) { + + inst_zone = voice_zone->inst_zone; /* this is a good zone. allocate a new synthesis process and initialize it */ - voice = fluid_synth_alloc_voice_LOCAL(synth, sample, chan, key, vel, &inst_zone->range); + voice = fluid_synth_alloc_voice_LOCAL(synth, inst_zone->sample, chan, key, vel, &voice_zone->range); if (voice == NULL) { return FLUID_FAILED; } @@ -842,7 +839,6 @@ fluid_defpreset_noteon(fluid_defpreset_t* defpreset, fluid_synth_t* synth, int c */ } - inst_zone = fluid_inst_zone_next(inst_zone); } } preset_zone = fluid_preset_zone_next(preset_zone); @@ -994,6 +990,7 @@ void delete_fluid_preset_zone(fluid_preset_zone_t* zone) { fluid_mod_t *mod, *tmp; + fluid_list_t *list; fluid_return_if_fail(zone != NULL); @@ -1005,11 +1002,63 @@ delete_fluid_preset_zone(fluid_preset_zone_t* zone) delete_fluid_mod (tmp); } + for (list = zone->voice_zone; list != NULL; list = fluid_list_next(list)) + { + FLUID_FREE(fluid_list_get(list)); + } + delete_fluid_list(zone->voice_zone); + FLUID_FREE (zone->name); delete_fluid_inst (zone->inst); FLUID_FREE(zone); } +static int fluid_preset_zone_create_voice_zones(fluid_preset_zone_t* preset_zone) +{ + fluid_inst_zone_t *inst_zone; + fluid_sample_t *sample; + fluid_voice_zone_t *voice_zone; + fluid_zone_range_t *irange; + fluid_zone_range_t *prange = &preset_zone->range; + + fluid_return_val_if_fail(preset_zone->inst != NULL, FLUID_FAILED); + + inst_zone = fluid_inst_get_zone(preset_zone->inst); + while (inst_zone != NULL) { + + /* We only create voice ranges for zones that could actually start a voice, + * i.e. that have a sample and don't point to ROM */ + sample = fluid_inst_zone_get_sample(inst_zone); + if ((sample == NULL) || fluid_sample_in_rom(sample)) + { + inst_zone = fluid_inst_zone_next(inst_zone); + continue; + } + + voice_zone = FLUID_NEW(fluid_voice_zone_t); + if (voice_zone == NULL) + { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return FLUID_FAILED; + } + + voice_zone->inst_zone = inst_zone; + + irange = &inst_zone->range; + + voice_zone->range.keylo = (prange->keylo > irange->keylo) ? prange->keylo : irange->keylo; + voice_zone->range.keyhi = (prange->keyhi < irange->keyhi) ? prange->keyhi : irange->keyhi; + voice_zone->range.vello = (prange->vello > irange->vello) ? prange->vello : irange->vello; + voice_zone->range.velhi = (prange->velhi < irange->velhi) ? prange->velhi : irange->velhi; + + preset_zone->voice_zone = fluid_list_append(preset_zone->voice_zone, voice_zone); + + inst_zone = fluid_inst_zone_next(inst_zone); + } + + return FLUID_OK; +} + /* * fluid_preset_zone_import_sfont */ @@ -1054,6 +1103,11 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_ (SFInst *) sfzone->instsamp->data, defsfont) != FLUID_OK) { return FLUID_FAILED; } + + if (fluid_preset_zone_create_voice_zones(zone) == FLUID_FAILED) + { + return FLUID_FAILED; + } } /* Import the modulators (only SF2.1 and higher) */ @@ -1284,7 +1338,7 @@ fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst, return FLUID_FAILED; } - if (fluid_inst_zone_import_sfont(preset_zone, inst_zone, sfzone, defsfont) != FLUID_OK) { + if (fluid_inst_zone_import_sfont(inst_zone, sfzone, defsfont) != FLUID_OK) { delete_fluid_inst_zone(inst_zone); return FLUID_FAILED; } @@ -1408,8 +1462,7 @@ fluid_inst_zone_next(fluid_inst_zone_t* zone) * fluid_inst_zone_import_sfont */ int -fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t* inst_zone, - SFZone *sfzone, fluid_defsfont_t* defsfont) +fluid_inst_zone_import_sfont(fluid_inst_zone_t* inst_zone, SFZone *sfzone, fluid_defsfont_t* defsfont) { fluid_list_t *r; SFGen* sfgen; @@ -1441,13 +1494,6 @@ fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_zone_t } r = fluid_list_next(r); } - - /* adjust instrument zone keyrange to integrate preset zone keyrange */ - if (preset_zone->range.keylo > inst_zone->range.keylo) inst_zone->range.keylo = preset_zone->range.keylo; - if (preset_zone->range.keyhi < inst_zone->range.keyhi) inst_zone->range.keyhi = preset_zone->range.keyhi; - /* adjust instrument zone to integrate preset zone velrange */ - if (preset_zone->range.vello > inst_zone->range.vello) inst_zone->range.vello = preset_zone->range.vello; - if (preset_zone->range.velhi < inst_zone->range.velhi) inst_zone->range.velhi = preset_zone->range.velhi; /* FIXME */ /* if (zone->gen[GEN_EXCLUSIVECLASS].flags == GEN_SET) { */ diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index 11755953..67fd2cf8 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -53,6 +53,7 @@ typedef struct _fluid_defpreset_t fluid_defpreset_t; typedef struct _fluid_preset_zone_t fluid_preset_zone_t; typedef struct _fluid_inst_t fluid_inst_t; typedef struct _fluid_inst_zone_t fluid_inst_zone_t; /**< Soundfont Instrument Zone */ +typedef struct _fluid_voice_zone_t fluid_voice_zone_t; /* defines the velocity and key range for a zone */ struct _fluid_zone_range_t @@ -64,6 +65,13 @@ struct _fluid_zone_range_t unsigned char ignore; /* set to TRUE for legato playing to ignore this range zone */ }; +/* Stored on a preset zone to keep track of the inst zones that could start a voice + * and their combined preset zone/instument zone ranges */ +struct _fluid_voice_zone_t +{ + fluid_inst_zone_t *inst_zone; + fluid_zone_range_t range; +}; /* @@ -163,6 +171,7 @@ struct _fluid_preset_zone_t fluid_preset_zone_t* next; char* name; fluid_inst_t* inst; + fluid_list_t* voice_zone; fluid_zone_range_t range; fluid_gen_t gen[GEN_LAST]; fluid_mod_t * mod; /* List of modulators */ @@ -210,8 +219,7 @@ struct _fluid_inst_zone_t fluid_inst_zone_t* new_fluid_inst_zone(char* name); void delete_fluid_inst_zone(fluid_inst_zone_t* zone); fluid_inst_zone_t* fluid_inst_zone_next(fluid_inst_zone_t* zone); -int fluid_inst_zone_import_sfont(fluid_preset_zone_t* preset_zone, - fluid_inst_zone_t* inst_zone, SFZone *sfzone, fluid_defsfont_t* defsfont); +int fluid_inst_zone_import_sfont(fluid_inst_zone_t* inst_zone, SFZone *sfzone, fluid_defsfont_t* defsfont); fluid_sample_t* fluid_inst_zone_get_sample(fluid_inst_zone_t* zone); From df3bab0b40840d9ead7ea6dd2f113fb0398c1dc0 Mon Sep 17 00:00:00 2001 From: Marcus Weseloh Date: Sun, 22 Apr 2018 19:01:15 +0200 Subject: [PATCH 02/16] Only import instruments once from Soundfont This changes the way instruments and their related information is imported from a Soundfont. Previously, each preset zone got a complete copy of the instrument and related information, wasting a lot of precious memory. After this change, an instrument and related information is only imported once and then linked into all preset zones that use this instrument. --- src/sfloader/fluid_defsfont.c | 67 +++++++++++++++++++++++++++-------- src/sfloader/fluid_defsfont.h | 5 +-- src/sfloader/fluid_sffile.c | 1 + src/sfloader/fluid_sffile.h | 1 + 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 6d06c3ae..2ab1731a 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -39,6 +39,8 @@ static int unload_preset_samples(fluid_defsfont_t *defsfont, fluid_preset_t *pre static void unload_sample(fluid_sample_t *sample); static int dynamic_samples_preset_notify(fluid_preset_t *preset, int reason, int chan); static int dynamic_samples_sample_notify(fluid_sample_t *sample, int reason); +static int fluid_preset_zone_create_voice_zones(fluid_preset_zone_t* preset_zone); +static fluid_inst_t *find_inst_by_idx(fluid_defsfont_t *defsfont, int idx); /*************************************************************** @@ -248,6 +250,11 @@ int delete_fluid_defsfont(fluid_defsfont_t* defsfont) } delete_fluid_list(defsfont->preset); + for (list = defsfont->inst; list; list = fluid_list_next(list)) { + delete_fluid_inst(fluid_list_get(list)); + } + delete_fluid_list(defsfont->inst); + FLUID_FREE(defsfont); return FLUID_OK; } @@ -962,6 +969,7 @@ new_fluid_preset_zone(char *name) return NULL; } zone->next = NULL; + zone->voice_zone = NULL; zone->name = FLUID_STRDUP(name); if (zone->name == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); @@ -1009,7 +1017,6 @@ delete_fluid_preset_zone(fluid_preset_zone_t* zone) delete_fluid_list(zone->voice_zone); FLUID_FREE (zone->name); - delete_fluid_inst (zone->inst); FLUID_FREE(zone); } @@ -1067,6 +1074,7 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_ { fluid_list_t *r; SFGen* sfgen; + SFInst* sfinst; int count; for (count = 0, r = sfzone->gen; r != NULL; count++) { sfgen = (SFGen *)fluid_list_get(r); @@ -1094,13 +1102,16 @@ fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_ r = fluid_list_next(r); } if ((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL)) { - zone->inst = (fluid_inst_t*) new_fluid_inst(); - if (zone->inst == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - return FLUID_FAILED; + sfinst = sfzone->instsamp->data; + + zone->inst = find_inst_by_idx(defsfont, sfinst->idx); + if (zone->inst == NULL) + { + zone->inst = fluid_inst_import_sfont(zone, sfinst, defsfont); } - if (fluid_inst_import_sfont(zone, zone->inst, - (SFInst *) sfzone->instsamp->data, defsfont) != FLUID_OK) { + + if (zone->inst == NULL) + { return FLUID_FAILED; } @@ -1310,16 +1321,24 @@ fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone) /* * fluid_inst_import_sfont */ -int -fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst, - SFInst *sfinst, fluid_defsfont_t* defsfont) +fluid_inst_t * +fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, SFInst *sfinst, fluid_defsfont_t* defsfont) { fluid_list_t *p; + fluid_inst_t *inst; SFZone* sfzone; fluid_inst_zone_t* inst_zone; char zone_name[256]; int count; + inst = (fluid_inst_t*) new_fluid_inst(); + if (inst == NULL) { + FLUID_LOG(FLUID_ERR, "Out of memory"); + return NULL; + } + + inst->source_idx = sfinst->idx; + p = sfinst->zone; if (FLUID_STRLEN(sfinst->name) > 0) { FLUID_STRCPY(inst->name, sfinst->name); @@ -1335,25 +1354,27 @@ fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst, inst_zone = new_fluid_inst_zone(zone_name); if (inst_zone == NULL) { - return FLUID_FAILED; + return NULL; } if (fluid_inst_zone_import_sfont(inst_zone, sfzone, defsfont) != FLUID_OK) { delete_fluid_inst_zone(inst_zone); - return FLUID_FAILED; + return NULL; } if ((count == 0) && (fluid_inst_zone_get_sample(inst_zone) == NULL)) { fluid_inst_set_global_zone(inst, inst_zone); } else if (fluid_inst_add_zone(inst, inst_zone) != FLUID_OK) { - return FLUID_FAILED; + return NULL; } p = fluid_list_next(p); count++; } - return FLUID_OK; + + defsfont->inst = fluid_list_append(defsfont->inst, inst); + return inst; } /* @@ -1875,3 +1896,21 @@ static void unload_sample(fluid_sample_t *sample) sample->data24 = NULL; } } + +static fluid_inst_t *find_inst_by_idx(fluid_defsfont_t *defsfont, int idx) +{ + fluid_list_t *list; + fluid_inst_t *inst; + + for (list = defsfont->inst; list != NULL; list = fluid_list_next(list)) + { + inst = fluid_list_get(list); + + if (inst->source_idx == idx) + { + return inst; + } + } + + return NULL; +} diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index 67fd2cf8..2807720c 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -115,6 +115,7 @@ struct _fluid_defsfont_t fluid_sfont_t *sfont; /* pointer to parent sfont */ fluid_list_t* sample; /* the samples in this soundfont */ fluid_list_t* preset; /* the presets of this soundfont */ + fluid_list_t* inst; /* the instruments of this soundfont */ int mlock; /* Should we try memlock (avoid swapping)? */ int dynamic_samples; /* Enables dynamic sample loading if set */ @@ -189,13 +190,13 @@ fluid_inst_t* fluid_preset_zone_get_inst(fluid_preset_zone_t* zone); struct _fluid_inst_t { char name[21]; + int source_idx; /* Index of instrument in source Soundfont */ fluid_inst_zone_t* global_zone; fluid_inst_zone_t* zone; }; fluid_inst_t* new_fluid_inst(void); -int fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, fluid_inst_t* inst, - SFInst *sfinst, fluid_defsfont_t* defsfont); +fluid_inst_t* fluid_inst_import_sfont(fluid_preset_zone_t* preset_zone, SFInst *sfinst, fluid_defsfont_t* defsfont); void delete_fluid_inst(fluid_inst_t* inst); int fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone); int fluid_inst_add_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone); diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 095629a5..3540dce6 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -1281,6 +1281,7 @@ static int load_ihdr(SFData *sf, int size) p = FLUID_NEW(SFInst); sf->inst = fluid_list_append(sf->inst, p); p->zone = NULL; /* For proper cleanup if fail (fluid_sffile_close) */ + p->idx = i; READSTR(sf, &p->name); /* Possible read failure ^ */ READW(sf, zndx); diff --git a/src/sfloader/fluid_sffile.h b/src/sfloader/fluid_sffile.h index a1f0d850..9a0e2126 100644 --- a/src/sfloader/fluid_sffile.h +++ b/src/sfloader/fluid_sffile.h @@ -114,6 +114,7 @@ struct _SFSample struct _SFInst { /* Instrument structure */ char name[21]; /* Name of instrument */ + int idx; /* Index of this instrument in the Soundfont */ fluid_list_t *zone; /* list of instrument zones */ }; From 2ad96d020e4bb2653a6650bd7302facee16d9f11 Mon Sep 17 00:00:00 2001 From: derselbst Date: Wed, 25 Apr 2018 21:05:02 +0200 Subject: [PATCH 03/16] avoid leaking rvoice_mixer threads introduced in 7ae909929318cb48aebb0d551903269e0c5a6735 --- src/rvoice/fluid_rvoice_mixer.c | 43 ++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/rvoice/fluid_rvoice_mixer.c b/src/rvoice/fluid_rvoice_mixer.c index 2ac07f90..ea9d513c 100644 --- a/src/rvoice/fluid_rvoice_mixer.c +++ b/src/rvoice/fluid_rvoice_mixer.c @@ -99,6 +99,8 @@ struct _fluid_rvoice_mixer_t { #endif }; +static void delete_rvoice_mixer_threads(fluid_rvoice_mixer_t* mixer); + static FLUID_INLINE void fluid_rvoice_mixer_process_fx(fluid_rvoice_mixer_t* mixer) { @@ -616,6 +618,7 @@ void delete_fluid_rvoice_mixer(fluid_rvoice_mixer_t* mixer) { fluid_return_if_fail(mixer != NULL); + delete_rvoice_mixer_threads(mixer); #ifdef ENABLE_MIXER_THREADS if (mixer->thread_ready) delete_fluid_cond(mixer->thread_ready); @@ -922,24 +925,9 @@ fluid_render_loop_multithread(fluid_rvoice_mixer_t* mixer) // mixer->current_blockcount, test, mixer->active_voices, waits); } -#endif - -/** - * Update amount of extra mixer threads. - * @param thread_count Number of extra mixer threads for multi-core rendering - * @param prio_level real-time prio level for the extra mixer threads - */ -DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_threads) +static void delete_rvoice_mixer_threads(fluid_rvoice_mixer_t* mixer) { -#ifdef ENABLE_MIXER_THREADS - char name[16]; - int i; - fluid_rvoice_mixer_t* mixer = obj; - int thread_count = param[0].i; - int prio_level = param[1].real; - - // Kill all existing threads first - if (mixer->thread_count) { + int i; fluid_atomic_int_set(&mixer->threads_should_terminate, 1); // Signal threads to wake up fluid_cond_mutex_lock(mixer->wakeup_threads_m); @@ -958,6 +946,27 @@ DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_threads) FLUID_FREE(mixer->threads); mixer->thread_count = 0; mixer->threads = NULL; +} +#endif + +/** + * Update amount of extra mixer threads. + * @param thread_count Number of extra mixer threads for multi-core rendering + * @param prio_level real-time prio level for the extra mixer threads + */ +DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_threads) +{ +#ifdef ENABLE_MIXER_THREADS + char name[16]; + int i; + fluid_rvoice_mixer_t* mixer = obj; + int thread_count = param[0].i; + int prio_level = param[1].real; + + // Kill all existing threads first + if (mixer->thread_count) + { + delete_rvoice_mixer_threads(mixer); } if (thread_count == 0) From 354bea9cfc34af38c728c40fe15832d6e7d9ed93 Mon Sep 17 00:00:00 2001 From: derselbst Date: Wed, 25 Apr 2018 21:08:48 +0200 Subject: [PATCH 04/16] fix build if ENABLE_MIXER_THREADS == 0 --- src/rvoice/fluid_rvoice_mixer.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/rvoice/fluid_rvoice_mixer.c b/src/rvoice/fluid_rvoice_mixer.c index ea9d513c..5e1c46fa 100644 --- a/src/rvoice/fluid_rvoice_mixer.c +++ b/src/rvoice/fluid_rvoice_mixer.c @@ -38,7 +38,7 @@ typedef struct _fluid_mixer_buffers_t fluid_mixer_buffers_t; struct _fluid_mixer_buffers_t { fluid_rvoice_mixer_t* mixer; /**< Owner of object */ -#ifdef ENABLE_MIXER_THREADS +#if ENABLE_MIXER_THREADS fluid_thread_t* thread; /**< Thread object */ #endif @@ -84,7 +84,7 @@ struct _fluid_rvoice_mixer_t { fluid_ladspa_fx_t* ladspa_fx; /**< Used by mixer only: Effects unit for LADSPA support. Never created or freed */ #endif -#ifdef ENABLE_MIXER_THREADS +#if ENABLE_MIXER_THREADS // int sleeping_threads; /**< Atomic: number of threads currently asleep */ // int active_threads; /**< Atomic: number of threads in the thread loop */ fluid_atomic_int_t threads_should_terminate; /**< Atomic: Set to TRUE when threads should terminate */ @@ -99,7 +99,9 @@ struct _fluid_rvoice_mixer_t { #endif }; +#if ENABLE_MIXER_THREADS static void delete_rvoice_mixer_threads(fluid_rvoice_mixer_t* mixer); +#endif static FLUID_INLINE void fluid_rvoice_mixer_process_fx(fluid_rvoice_mixer_t* mixer) @@ -277,7 +279,7 @@ fluid_mixer_buffer_process_finished_voices(fluid_mixer_buffers_t* buffers) static FLUID_INLINE void fluid_rvoice_mixer_process_finished_voices(fluid_rvoice_mixer_t* mixer) { -#ifdef ENABLE_MIXER_THREADS +#if ENABLE_MIXER_THREADS int i; for (i=0; i < mixer->thread_count; i++) fluid_mixer_buffer_process_finished_voices(&mixer->threads[i]); @@ -380,7 +382,7 @@ DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_polyphony) == FLUID_FAILED) return /*FLUID_FAILED*/; -#ifdef ENABLE_MIXER_THREADS +#if ENABLE_MIXER_THREADS { int i; for (i=0; i < handler->thread_count; i++) @@ -554,7 +556,7 @@ new_fluid_rvoice_mixer(int buf_count, int fx_buf_count, fluid_real_t sample_rate return NULL; } -#ifdef ENABLE_MIXER_THREADS +#if ENABLE_MIXER_THREADS mixer->thread_ready = new_fluid_cond(); mixer->wakeup_threads = new_fluid_cond(); mixer->thread_ready_m = new_fluid_cond_mutex(); @@ -618,8 +620,9 @@ void delete_fluid_rvoice_mixer(fluid_rvoice_mixer_t* mixer) { fluid_return_if_fail(mixer != NULL); +#if ENABLE_MIXER_THREADS delete_rvoice_mixer_threads(mixer); -#ifdef ENABLE_MIXER_THREADS + if (mixer->thread_ready) delete_fluid_cond(mixer->thread_ready); if (mixer->wakeup_threads) @@ -751,7 +754,7 @@ int fluid_rvoice_mixer_get_active_voices(fluid_rvoice_mixer_t* mixer) } #endif -#ifdef ENABLE_MIXER_THREADS +#if ENABLE_MIXER_THREADS static FLUID_INLINE fluid_rvoice_t* fluid_mixer_get_mt_rvoice(fluid_rvoice_mixer_t* mixer) @@ -956,7 +959,7 @@ static void delete_rvoice_mixer_threads(fluid_rvoice_mixer_t* mixer) */ DECLARE_FLUID_RVOICE_FUNCTION(fluid_rvoice_mixer_set_threads) { -#ifdef ENABLE_MIXER_THREADS +#if ENABLE_MIXER_THREADS char name[16]; int i; fluid_rvoice_mixer_t* mixer = obj; @@ -1013,7 +1016,7 @@ fluid_rvoice_mixer_render(fluid_rvoice_mixer_t* mixer, int blockcount) fluid_profile(FLUID_PROF_ONE_BLOCK_CLEAR, prof_ref, mixer->active_voices, mixer->current_blockcount * FLUID_BUFSIZE); -#ifdef ENABLE_MIXER_THREADS +#if ENABLE_MIXER_THREADS if (mixer->thread_count > 0) fluid_render_loop_multithread(mixer); else From 1a5ea8d8e5942270dfd45312d3b99bc1a8998f4d Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 27 Apr 2018 21:32:00 +0200 Subject: [PATCH 05/16] fix signedness warning --- src/sfloader/fluid_defsfont.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 2ab1731a..3664d48b 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -273,7 +273,7 @@ const char* fluid_defsfont_get_name(fluid_defsfont_t* defsfont) int fluid_defsfont_load_sampledata(fluid_defsfont_t *defsfont, SFData *sfdata, fluid_sample_t *sample) { int num_samples; - int source_end = sample->source_end; + unsigned int source_end = sample->source_end; /* For uncompressed samples we want to include the 46 zero sample word area following each sample * in the Soundfont. Otherwise samples with loopend > end, which we have decided not to correct, would From 4add88db7ce54e906af56ed6f777ca22ed50c442 Mon Sep 17 00:00:00 2001 From: derselbst Date: Fri, 27 Apr 2018 21:39:28 +0200 Subject: [PATCH 06/16] document dynamic sample loading in API docs --- doc/fluidsynth-v11-devdoc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fluidsynth-v11-devdoc.txt b/doc/fluidsynth-v11-devdoc.txt index ccea75d6..57e45209 100644 --- a/doc/fluidsynth-v11-devdoc.txt +++ b/doc/fluidsynth-v11-devdoc.txt @@ -109,6 +109,7 @@ Changes in FluidSynth 2.0.0 concerning developers:

- add "midi.autoconnect" a setting for automatically connecting fluidsynth to available MIDI input ports - add "synth.overflow.important" and "synth.overflow.important-channels" settings to take midi channels during overflow calculation into account that are considered to be "important" +- add "synth.dynamic-sample-loading" a setting for enabling on demand sample loading - add support for polyphonic 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() From 3e3bef87ec70108094f980f6bf808c0eb873c4fa Mon Sep 17 00:00:00 2001 From: derselbst Date: Sun, 29 Apr 2018 16:11:30 +0200 Subject: [PATCH 07/16] report errors in fluid_handle_set() --- src/bindings/fluid_cmd.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/bindings/fluid_cmd.c b/src/bindings/fluid_cmd.c index 01396b55..12dfa49c 100644 --- a/src/bindings/fluid_cmd.c +++ b/src/bindings/fluid_cmd.c @@ -1402,10 +1402,11 @@ fluid_handle_set(void* data, int ac, char** av, fluid_ostream_t out) FLUID_ENTRY_COMMAND(data); int hints; int ival; + int ret = FLUID_FAILED; if (ac < 2) { fluid_ostream_printf(out, "set: Too few arguments.\n"); - return FLUID_FAILED; + return ret; } switch (fluid_settings_get_type (handler->synth->settings, av[0])) @@ -1425,20 +1426,23 @@ fluid_handle_set(void* data, int ac, char** av, fluid_ostream_t out) } else ival = atoi (av[1]); - fluid_settings_setint (handler->synth->settings, av[0], ival); + ret = fluid_settings_setint (handler->synth->settings, av[0], ival); break; case FLUID_NUM_TYPE: - fluid_settings_setnum (handler->synth->settings, av[0], atof (av[1])); + ret = fluid_settings_setnum (handler->synth->settings, av[0], atof (av[1])); break; case FLUID_STR_TYPE: - fluid_settings_setstr(handler->synth->settings, av[0], av[1]); + ret = fluid_settings_setstr(handler->synth->settings, av[0], av[1]); break; case FLUID_SET_TYPE: fluid_ostream_printf (out, "set: Parameter '%s' is a node.\n", av[0]); - break; + return FLUID_FAILED; } - return FLUID_OK; + if(ret == FLUID_FAILED) + fluid_ostream_printf(out, "set: Value out of range.\n"); + + return ret; } int @@ -1458,27 +1462,27 @@ fluid_handle_get(void* data, int ac, char** av, fluid_ostream_t out) case FLUID_NUM_TYPE: { double value; fluid_settings_getnum(handler->synth->settings, av[0], &value); - fluid_ostream_printf(out, "%.3f", value); + fluid_ostream_printf(out, "%.3f\n", value); break; } case FLUID_INT_TYPE: { int value; fluid_settings_getint(handler->synth->settings, av[0], &value); - fluid_ostream_printf(out, "%d", value); + fluid_ostream_printf(out, "%d\n", value); break; } case FLUID_STR_TYPE: { char* s; fluid_settings_dupstr(handler->synth->settings, av[0], &s); /* ++ alloc string */ - fluid_ostream_printf(out, "%s", s ? s : "NULL"); + fluid_ostream_printf(out, "%s\n", s ? s : "NULL"); if (s) FLUID_FREE (s); /* -- free string */ break; } case FLUID_SET_TYPE: - fluid_ostream_printf(out, "%s is a node", av[0]); + fluid_ostream_printf(out, "%s is a node\n", av[0]); break; } From edd52edac2f9f9208af783b9f3a1c80091b30dea Mon Sep 17 00:00:00 2001 From: derselbst Date: Mon, 30 Apr 2018 10:09:48 +0200 Subject: [PATCH 08/16] consistently use signed int for sfont_id, bank_num and preset_num --- CMakeLists.txt | 4 +- doc/fluidsynth-v11-devdoc.txt | 1 + include/fluidsynth/ramsfont.h | 8 ++-- include/fluidsynth/sfont.h | 2 +- include/fluidsynth/synth.h | 22 +++++------ src/sfloader/fluid_defsfont.c | 4 +- src/sfloader/fluid_defsfont.h | 4 +- src/sfloader/fluid_ramsfont.c | 26 ++++++------- src/sfloader/fluid_sfont.h | 2 +- src/synth/fluid_synth.c | 69 ++++++++++++++++++++--------------- src/synth/fluid_synth.h | 6 +-- 11 files changed, 79 insertions(+), 69 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cd4ac49..619a62ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -323,9 +323,9 @@ find_program( CLANG_TIDY message ( STATUS "Found clang-tidy" ) # whenever clang-tidy is available, use it to automatically add braces after ever "make" if ( WITH_PROFILING ) - set ( CMAKE_C_CLANG_TIDY "clang-tidy" ) +# set ( CMAKE_C_CLANG_TIDY "clang-tidy" ) else ( WITH_PROFILING ) - set ( CMAKE_C_CLANG_TIDY "clang-tidy;-checks=-*,readability-braces-around-statements;-format-style=file" ) +# set ( CMAKE_C_CLANG_TIDY "clang-tidy;-checks=-*,readability-braces-around-statements;-format-style=file" ) endif ( WITH_PROFILING ) endif ( CLANG_TIDY ) endif ( CMAKE_VERSION VERSION_GREATER "3.6.0" ) diff --git a/doc/fluidsynth-v11-devdoc.txt b/doc/fluidsynth-v11-devdoc.txt index 57e45209..0a6f577f 100644 --- a/doc/fluidsynth-v11-devdoc.txt +++ b/doc/fluidsynth-v11-devdoc.txt @@ -101,6 +101,7 @@ Changes in FluidSynth 2.0.0 concerning developers:

- all public \c fluid_settings_* functions that return an integer which is not meant to be interpreted as bool consistently return either FLUID_OK or FLUID_FAILED - all public delete_* functions return void and are safe when called with NULL +- all public functions consistently receive signed integers for soundfont ids, bank and program numbers - the shell command handler was decoupled internally, as a consequence the param list of new_fluid_server() and new_fluid_cmd_handler() was adapted - reverb: roomsize is now limited to an upper threshold of 1.0 to avoid exponential volume increase - use unique device names for the "audio.portaudio.device" setting diff --git a/include/fluidsynth/ramsfont.h b/include/fluidsynth/ramsfont.h index 2035ed1d..7d3d1eb9 100644 --- a/include/fluidsynth/ramsfont.h +++ b/include/fluidsynth/ramsfont.h @@ -43,18 +43,18 @@ FLUIDSYNTH_API fluid_sfont_t* fluid_ramsfont_create_sfont(void); FLUIDSYNTH_API int fluid_ramsfont_set_name(fluid_ramsfont_t* sfont, const char *name); FLUIDSYNTH_API int fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample, + int bank, int num, fluid_sample_t* sample, int lokey, int hikey); FLUIDSYNTH_API int fluid_ramsfont_remove_izone(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample); + int bank, int num, fluid_sample_t* sample); FLUIDSYNTH_API int fluid_ramsfont_izone_set_gen(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample, + int bank, int num, fluid_sample_t* sample, int gen_type, float value); FLUIDSYNTH_API int fluid_ramsfont_izone_set_loop(fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num, fluid_sample_t* sample, + int bank, int num, fluid_sample_t* sample, int on, float loopstart, float loopend); diff --git a/include/fluidsynth/sfont.h b/include/fluidsynth/sfont.h index 0f12b538..d84c33d2 100644 --- a/include/fluidsynth/sfont.h +++ b/include/fluidsynth/sfont.h @@ -170,7 +170,7 @@ typedef const char* (*fluid_sfont_get_name_t)(fluid_sfont_t* sfont); * @return Should return an allocated virtual preset or NULL if it could not * be found. */ -typedef fluid_preset_t* (*fluid_sfont_get_preset_t)(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum); +typedef fluid_preset_t* (*fluid_sfont_get_preset_t)(fluid_sfont_t* sfont, int bank, int prenum); /** * Method to free a virtual SoundFont bank. Any custom user provided cleanup function must ultimately call diff --git a/include/fluidsynth/synth.h b/include/fluidsynth/synth.h index f3e70d84..b8ea684f 100644 --- a/include/fluidsynth/synth.h +++ b/include/fluidsynth/synth.h @@ -65,18 +65,18 @@ FLUIDSYNTH_API int fluid_synth_get_pitch_wheel_sens(fluid_synth_t* synth, int ch FLUIDSYNTH_API int fluid_synth_program_change(fluid_synth_t* synth, int chan, int program); FLUIDSYNTH_API int fluid_synth_channel_pressure(fluid_synth_t* synth, int chan, int val); FLUIDSYNTH_API int fluid_synth_key_pressure(fluid_synth_t* synth, int chan, int key, int val); -FLUIDSYNTH_API int fluid_synth_bank_select(fluid_synth_t* synth, int chan, unsigned int bank); -FLUIDSYNTH_API int fluid_synth_sfont_select(fluid_synth_t* synth, int chan, unsigned int sfont_id); +FLUIDSYNTH_API int fluid_synth_bank_select(fluid_synth_t* synth, int chan, int bank); +FLUIDSYNTH_API int fluid_synth_sfont_select(fluid_synth_t* synth, int chan, int sfont_id); FLUIDSYNTH_API -int fluid_synth_program_select(fluid_synth_t* synth, int chan, unsigned int sfont_id, - unsigned int bank_num, unsigned int preset_num); +int fluid_synth_program_select(fluid_synth_t* synth, int chan, int sfont_id, + int bank_num, int preset_num); FLUIDSYNTH_API int fluid_synth_program_select_by_sfont_name (fluid_synth_t* synth, int chan, - const char *sfont_name, unsigned int bank_num, - unsigned int preset_num); + const char *sfont_name, int bank_num, + int preset_num); FLUIDSYNTH_API -int fluid_synth_get_program(fluid_synth_t* synth, int chan, unsigned int* sfont_id, - unsigned int* bank_num, unsigned int* preset_num); +int fluid_synth_get_program(fluid_synth_t* synth, int chan, int* sfont_id, + int* bank_num, int* preset_num); FLUIDSYNTH_API int fluid_synth_unset_program (fluid_synth_t *synth, int chan); FLUIDSYNTH_API int fluid_synth_program_reset(fluid_synth_t* synth); FLUIDSYNTH_API int fluid_synth_system_reset(fluid_synth_t* synth); @@ -108,13 +108,13 @@ FLUIDSYNTH_API int fluid_synth_stop(fluid_synth_t* synth, unsigned int id); FLUIDSYNTH_API int fluid_synth_sfload(fluid_synth_t* synth, const char* filename, int reset_presets); -FLUIDSYNTH_API int fluid_synth_sfreload(fluid_synth_t* synth, unsigned int id); -FLUIDSYNTH_API int fluid_synth_sfunload(fluid_synth_t* synth, unsigned int id, int reset_presets); +FLUIDSYNTH_API int fluid_synth_sfreload(fluid_synth_t* synth, int id); +FLUIDSYNTH_API int fluid_synth_sfunload(fluid_synth_t* synth, int id, int reset_presets); FLUIDSYNTH_API int fluid_synth_add_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont); FLUIDSYNTH_API int fluid_synth_remove_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont); FLUIDSYNTH_API int fluid_synth_sfcount(fluid_synth_t* synth); FLUIDSYNTH_API fluid_sfont_t* fluid_synth_get_sfont(fluid_synth_t* synth, unsigned int num); -FLUIDSYNTH_API fluid_sfont_t* fluid_synth_get_sfont_by_id(fluid_synth_t* synth, unsigned int id); +FLUIDSYNTH_API fluid_sfont_t* fluid_synth_get_sfont_by_id(fluid_synth_t* synth, int id); FLUIDSYNTH_API fluid_sfont_t *fluid_synth_get_sfont_by_name (fluid_synth_t* synth, const char *name); FLUIDSYNTH_API int fluid_synth_set_bank_offset(fluid_synth_t* synth, int sfont_id, int offset); diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 3664d48b..33968984 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -129,7 +129,7 @@ const char* fluid_defsfont_sfont_get_name(fluid_sfont_t* sfont) } fluid_preset_t* -fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum) +fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, int bank, int prenum) { return fluid_defsfont_get_preset(fluid_sfont_get_data(sfont), bank, prenum); } @@ -520,7 +520,7 @@ int fluid_defsfont_add_preset(fluid_defsfont_t* defsfont, fluid_defpreset_t* def /* * fluid_defsfont_get_preset */ -fluid_preset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigned int bank, unsigned int num) +fluid_preset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, int bank, int num) { fluid_preset_t *preset; fluid_list_t *list; diff --git a/src/sfloader/fluid_defsfont.h b/src/sfloader/fluid_defsfont.h index 2807720c..3470aa0e 100644 --- a/src/sfloader/fluid_defsfont.h +++ b/src/sfloader/fluid_defsfont.h @@ -84,7 +84,7 @@ fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* file int fluid_defsfont_sfont_delete(fluid_sfont_t* sfont); const char* fluid_defsfont_sfont_get_name(fluid_sfont_t* sfont); -fluid_preset_t* fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum); +fluid_preset_t* fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, int bank, int prenum); void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont); fluid_preset_t *fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont); @@ -127,7 +127,7 @@ fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings); int delete_fluid_defsfont(fluid_defsfont_t* defsfont); int fluid_defsfont_load(fluid_defsfont_t* defsfont, const fluid_file_callbacks_t* file_callbacks, const char* file); const char* fluid_defsfont_get_name(fluid_defsfont_t* defsfont); -fluid_preset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, unsigned int bank, unsigned int prenum); +fluid_preset_t* fluid_defsfont_get_preset(fluid_defsfont_t* defsfont, int bank, int prenum); void fluid_defsfont_iteration_start(fluid_defsfont_t* defsfont); fluid_preset_t *fluid_defsfont_iteration_next(fluid_defsfont_t* defsfont); int fluid_defsfont_load_sampledata(fluid_defsfont_t *defsfont, SFData *sfdata, fluid_sample_t *sample); diff --git a/src/sfloader/fluid_ramsfont.c b/src/sfloader/fluid_ramsfont.c index 41148121..1d41842b 100644 --- a/src/sfloader/fluid_ramsfont.c +++ b/src/sfloader/fluid_ramsfont.c @@ -27,8 +27,8 @@ static int fluid_ramsfont_sfont_delete(fluid_sfont_t* sfont); static const char *fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont); static fluid_preset_t *fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, - unsigned int bank, - unsigned int prenum); + int bank, + int prenum); static void fluid_ramsfont_sfont_iteration_start(fluid_sfont_t* sfont); static fluid_preset_t *fluid_ramsfont_sfont_iteration_next(fluid_sfont_t* sfont); static void fluid_rampreset_preset_delete(fluid_preset_t* preset); @@ -44,7 +44,7 @@ static const char *fluid_ramsfont_get_name(fluid_ramsfont_t* sfont); static int fluid_ramsfont_add_preset (fluid_ramsfont_t* sfont, fluid_rampreset_t* rampreset); static fluid_preset_t *fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont, - unsigned int bank, unsigned int num); + int bank, int num); static void fluid_ramsfont_iteration_start (fluid_ramsfont_t* sfont); static fluid_preset_t *fluid_ramsfont_iteration_next (fluid_ramsfont_t* sfont); static fluid_rampreset_t* new_fluid_rampreset(fluid_ramsfont_t* sfont); @@ -127,7 +127,7 @@ fluid_ramsfont_sfont_get_name(fluid_sfont_t* sfont) /* RAM SoundFont loader method to get a preset */ static fluid_preset_t * -fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum) +fluid_ramsfont_sfont_get_preset(fluid_sfont_t* sfont, int bank, int prenum) { return fluid_ramsfont_get_preset((fluid_ramsfont_t*) sfont->data, bank, prenum); } @@ -307,8 +307,8 @@ fluid_ramsfont_add_preset (fluid_ramsfont_t* sfont, fluid_rampreset_t* rampreset * @return #FLUID_OK on success, #FLUID_FAILED otherwise */ int -fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont, unsigned int bank, - unsigned int num, fluid_sample_t* sample, +fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont, int bank, + int num, fluid_sample_t* sample, int lokey, int hikey) { /*- find or create a preset @@ -363,8 +363,8 @@ fluid_ramsfont_add_izone(fluid_ramsfont_t* sfont, unsigned int bank, * @return #FLUID_OK on success, #FLUID_FAILED otherwise */ int -fluid_ramsfont_remove_izone (fluid_ramsfont_t* sfont, unsigned int bank, - unsigned int num, fluid_sample_t* sample) +fluid_ramsfont_remove_izone (fluid_ramsfont_t* sfont, int bank, + int num, fluid_sample_t* sample) { int err; fluid_rampreset_t *rampreset; @@ -398,8 +398,8 @@ fluid_ramsfont_remove_izone (fluid_ramsfont_t* sfont, unsigned int bank, * @return #FLUID_OK on success, #FLUID_FAILED otherwise */ int -fluid_ramsfont_izone_set_gen (fluid_ramsfont_t* sfont, unsigned int bank, - unsigned int num, fluid_sample_t* sample, +fluid_ramsfont_izone_set_gen (fluid_ramsfont_t* sfont, int bank, + int num, fluid_sample_t* sample, int gen_type, float value) { fluid_rampreset_t* rampreset; @@ -427,8 +427,8 @@ fluid_ramsfont_izone_set_gen (fluid_ramsfont_t* sfont, unsigned int bank, * @return #FLUID_OK on success, #FLUID_FAILED otherwise */ int -fluid_ramsfont_izone_set_loop (fluid_ramsfont_t *sfont, unsigned int bank, - unsigned int num, fluid_sample_t* sample, +fluid_ramsfont_izone_set_loop (fluid_ramsfont_t *sfont, int bank, + int num, fluid_sample_t* sample, int on, float loopstart, float loopend) { fluid_rampreset_t* rampreset; @@ -444,7 +444,7 @@ fluid_ramsfont_izone_set_loop (fluid_ramsfont_t *sfont, unsigned int bank, /* Get a preset from a RAM SoundFont */ static fluid_preset_t * -fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont, unsigned int bank, unsigned int num) +fluid_ramsfont_get_preset (fluid_ramsfont_t* sfont, int bank, int num) { fluid_preset_t *preset; fluid_list_t *list; diff --git a/src/sfloader/fluid_sfont.h b/src/sfloader/fluid_sfont.h index 9d3ee6e6..e0a5b1a4 100644 --- a/src/sfloader/fluid_sfont.h +++ b/src/sfloader/fluid_sfont.h @@ -121,7 +121,7 @@ void fluid_sfont_set_iteration_next(fluid_sfont_t* sfont, fluid_sfont_iteration_ */ struct _fluid_sfont_t { void* data; /**< User defined data */ - unsigned int id; /**< SoundFont ID */ + int id; /**< SoundFont ID */ int refcount; /**< SoundFont reference count (1 if no presets referencing it) */ int bankofs; /**< Bank offset */ diff --git a/src/synth/fluid_synth.c b/src/synth/fluid_synth.c index 3c10a760..b2e66d1f 100644 --- a/src/synth/fluid_synth.c +++ b/src/synth/fluid_synth.c @@ -78,11 +78,11 @@ static int fluid_synth_update_pitch_wheel_sens_LOCAL(fluid_synth_t* synth, int c static int fluid_synth_set_preset (fluid_synth_t *synth, int chan, fluid_preset_t *preset); static fluid_preset_t* -fluid_synth_get_preset(fluid_synth_t* synth, unsigned int sfontnum, - unsigned int banknum, unsigned int prognum); +fluid_synth_get_preset(fluid_synth_t* synth, int sfontnum, + int banknum, int prognum); static fluid_preset_t* fluid_synth_get_preset_by_sfont_name(fluid_synth_t* synth, const char *sfontname, - unsigned int banknum, unsigned int prognum); + int banknum, int prognum); static void fluid_synth_update_presets(fluid_synth_t* synth); static void fluid_synth_update_gain_LOCAL(fluid_synth_t* synth); @@ -2221,8 +2221,8 @@ fluid_synth_set_preset (fluid_synth_t *synth, int chan, fluid_preset_t *preset) * Returns preset pointer or NULL. */ static fluid_preset_t* -fluid_synth_get_preset(fluid_synth_t* synth, unsigned int sfontnum, - unsigned int banknum, unsigned int prognum) +fluid_synth_get_preset(fluid_synth_t* synth, int sfontnum, + int banknum, int prognum) { fluid_sfont_t *sfont; fluid_list_t *list; @@ -2247,7 +2247,7 @@ fluid_synth_get_preset(fluid_synth_t* synth, unsigned int sfontnum, */ static fluid_preset_t* fluid_synth_get_preset_by_sfont_name(fluid_synth_t* synth, const char *sfontname, - unsigned int banknum, unsigned int prognum) + int banknum, int prognum) { fluid_sfont_t *sfont; fluid_list_t *list; @@ -2268,8 +2268,8 @@ fluid_synth_get_preset_by_sfont_name(fluid_synth_t* synth, const char *sfontname * Returns preset pointer or NULL. */ fluid_preset_t* -fluid_synth_find_preset(fluid_synth_t* synth, unsigned int banknum, - unsigned int prognum) +fluid_synth_find_preset(fluid_synth_t* synth, int banknum, + int prognum) { fluid_preset_t *preset; fluid_sfont_t *sfont; @@ -2388,10 +2388,11 @@ fluid_synth_program_change(fluid_synth_t* synth, int chan, int prognum) * */ int -fluid_synth_bank_select(fluid_synth_t* synth, int chan, unsigned int bank) +fluid_synth_bank_select(fluid_synth_t* synth, int chan, int bank) { int result; fluid_return_val_if_fail (bank <= 16383, FLUID_FAILED); + fluid_return_val_if_fail (bank >= 0, FLUID_FAILED); FLUID_API_ENTRY_CHAN(FLUID_FAILED); /* Allowed only on MIDI channel enabled */ @@ -2415,7 +2416,7 @@ fluid_synth_bank_select(fluid_synth_t* synth, int chan, unsigned int bank) * after having selected the soundfont. */ int -fluid_synth_sfont_select(fluid_synth_t* synth, int chan, unsigned int sfont_id) +fluid_synth_sfont_select(fluid_synth_t* synth, int chan, int sfont_id) { int result; FLUID_API_ENTRY_CHAN(FLUID_FAILED); @@ -2457,8 +2458,8 @@ fluid_synth_unset_program (fluid_synth_t *synth, int chan) * @return #FLUID_OK on success, #FLUID_FAILED otherwise */ int -fluid_synth_get_program(fluid_synth_t* synth, int chan, unsigned int* sfont_id, - unsigned int* bank_num, unsigned int* preset_num) +fluid_synth_get_program(fluid_synth_t* synth, int chan, int* sfont_id, + int* bank_num, int* preset_num) { int result; fluid_channel_t* channel; @@ -2472,8 +2473,7 @@ fluid_synth_get_program(fluid_synth_t* synth, int chan, unsigned int* sfont_id, FLUID_API_RETURN_IF_CHAN_DISABLED(FLUID_FAILED); channel = synth->channel[chan]; - fluid_channel_get_sfont_bank_prog(channel, (int *)sfont_id, (int *)bank_num, - (int *)preset_num); + fluid_channel_get_sfont_bank_prog(channel, sfont_id, bank_num, preset_num); /* 128 indicates that the preset is unset. Set to 0 to be backwards compatible. */ if (*preset_num == FLUID_UNSET_PROGRAM) *preset_num = 0; @@ -2492,12 +2492,15 @@ fluid_synth_get_program(fluid_synth_t* synth, int chan, unsigned int* sfont_id, * @return #FLUID_OK on success, #FLUID_FAILED otherwise */ int -fluid_synth_program_select(fluid_synth_t* synth, int chan, unsigned int sfont_id, - unsigned int bank_num, unsigned int preset_num) +fluid_synth_program_select(fluid_synth_t* synth, int chan, int sfont_id, + int bank_num, int preset_num) { fluid_preset_t* preset = NULL; fluid_channel_t* channel; int result; + fluid_return_val_if_fail(bank_num >= 0, FLUID_FAILED); + fluid_return_val_if_fail(preset_num >= 0, FLUID_FAILED); + FLUID_API_ENTRY_CHAN(FLUID_FAILED); /* Allowed only on MIDI channel enabled */ @@ -2533,8 +2536,8 @@ fluid_synth_program_select(fluid_synth_t* synth, int chan, unsigned int sfont_id */ int fluid_synth_program_select_by_sfont_name (fluid_synth_t* synth, int chan, - const char *sfont_name, unsigned int bank_num, - unsigned int preset_num) + const char *sfont_name, int bank_num, + int preset_num) { fluid_preset_t* preset = NULL; fluid_channel_t* channel; @@ -3655,12 +3658,15 @@ fluid_synth_sfload(fluid_synth_t* synth, const char* filename, int reset_presets fluid_sfont_t *sfont; fluid_list_t *list; fluid_sfloader_t *loader; - unsigned int sfont_id; + int sfont_id; fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); fluid_return_val_if_fail (filename != NULL, FLUID_FAILED); fluid_synth_api_enter(synth); + sfont_id = synth->sfont_id; + if(++sfont_id != FLUID_FAILED) + { /* MT NOTE: Loaders list should not change. */ for (list = synth->loaders; list; list = fluid_list_next(list)) { @@ -3670,17 +3676,17 @@ fluid_synth_sfload(fluid_synth_t* synth, const char* filename, int reset_presets if (sfont != NULL) { sfont->refcount++; - sfont->id = sfont_id = ++synth->sfont_id; + synth->sfont_id = sfont->id = sfont_id; synth->sfont = fluid_list_prepend(synth->sfont, sfont); /* prepend to list */ /* reset the presets for all channels if requested */ if (reset_presets) fluid_synth_program_reset(synth); - FLUID_API_RETURN((int)sfont_id); + FLUID_API_RETURN(sfont_id); } } - + } FLUID_LOG(FLUID_ERR, "Failed to load SoundFont \"%s\"", filename); FLUID_API_RETURN(FLUID_FAILED); } @@ -3693,7 +3699,7 @@ fluid_synth_sfload(fluid_synth_t* synth, const char* filename, int reset_presets * @return #FLUID_OK on success, #FLUID_FAILED on error */ int -fluid_synth_sfunload(fluid_synth_t* synth, unsigned int id, int reset_presets) +fluid_synth_sfunload(fluid_synth_t* synth, int id, int reset_presets) { fluid_sfont_t *sfont = NULL; fluid_list_t *list; @@ -3767,7 +3773,7 @@ fluid_synth_sfunload_callback(void* data, unsigned int msec) * @return SoundFont ID on success, #FLUID_FAILED on error */ int -fluid_synth_sfreload(fluid_synth_t* synth, unsigned int id) +fluid_synth_sfreload(fluid_synth_t* synth, int id) { char *filename = NULL; fluid_sfont_t *sfont; @@ -3831,18 +3837,21 @@ exit: int fluid_synth_add_sfont(fluid_synth_t* synth, fluid_sfont_t* sfont) { - unsigned int sfont_id; + int sfont_id; fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); fluid_return_val_if_fail (sfont != NULL, FLUID_FAILED); fluid_synth_api_enter(synth); - - sfont->id = sfont_id = ++synth->sfont_id; + sfont_id = synth->sfont_id; + if(++sfont_id != FLUID_FAILED) + { + synth->sfont_id = sfont->id = sfont_id; synth->sfont = fluid_list_prepend (synth->sfont, sfont); /* prepend to list */ /* reset the presets for all channels */ fluid_synth_program_reset (synth); + } FLUID_API_RETURN(sfont_id); } @@ -3936,7 +3945,7 @@ fluid_synth_get_sfont(fluid_synth_t* synth, unsigned int num) * the duration of use of the returned pointer. */ fluid_sfont_t * -fluid_synth_get_sfont_by_id(fluid_synth_t* synth, unsigned int id) +fluid_synth_get_sfont_by_id(fluid_synth_t* synth, int id) { fluid_sfont_t* sfont = NULL; fluid_list_t* list; @@ -5295,7 +5304,7 @@ fluid_synth_set_bank_offset(fluid_synth_t* synth, int sfont_id, int offset) for (list = synth->sfont; list; list = fluid_list_next(list)) { sfont = fluid_list_get (list); - if (fluid_sfont_get_id (sfont) == (unsigned int)sfont_id) + if (fluid_sfont_get_id (sfont) == sfont_id) { sfont->bankofs = offset; break; @@ -5330,7 +5339,7 @@ fluid_synth_get_bank_offset(fluid_synth_t* synth, int sfont_id) for (list = synth->sfont; list; list = fluid_list_next(list)) { sfont = fluid_list_get (list); - if (fluid_sfont_get_id (sfont) == (unsigned int)sfont_id) + if (fluid_sfont_get_id (sfont) == sfont_id) { offset = sfont->bankofs; break; diff --git a/src/synth/fluid_synth.h b/src/synth/fluid_synth.h index d348d014..2b2d9b31 100644 --- a/src/synth/fluid_synth.h +++ b/src/synth/fluid_synth.h @@ -114,7 +114,7 @@ struct _fluid_synth_t fluid_list_t *loaders; /**< the SoundFont loaders */ fluid_list_t *sfont; /**< List of fluid_sfont_info_t for each loaded SoundFont (remains until SoundFont is unloaded) */ - unsigned int sfont_id; /**< Incrementing ID assigned to each loaded SoundFont */ + int sfont_id; /**< Incrementing ID assigned to each loaded SoundFont */ float gain; /**< master gain */ fluid_channel_t** channel; /**< the channels */ @@ -174,8 +174,8 @@ typedef int (*fluid_audio_callback_t)(fluid_synth_t* synth, int len, void* out2, int roff, int rincr); fluid_preset_t* fluid_synth_find_preset(fluid_synth_t* synth, - unsigned int banknum, - unsigned int prognum); + int banknum, + int prognum); void fluid_synth_sfont_unref (fluid_synth_t *synth, fluid_sfont_t *sfont); void fluid_synth_dither_s16(int *dither_index, int len, float* lin, float* rin, From c64d2b44bebaa68d0ea14e5a8ebbe15fb32adfe2 Mon Sep 17 00:00:00 2001 From: derselbst Date: Mon, 30 Apr 2018 10:16:01 +0200 Subject: [PATCH 09/16] silence uninitialized warning --- src/sfloader/fluid_sffile.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sfloader/fluid_sffile.c b/src/sfloader/fluid_sffile.c index 3540dce6..230ffeaa 100644 --- a/src/sfloader/fluid_sffile.c +++ b/src/sfloader/fluid_sffile.c @@ -2001,12 +2001,15 @@ static sf_count_t sfvio_seek(sf_count_t offset, int whence, void *user_data) case SEEK_END: new_offset = sfvio_get_filelen(user_data) + offset; break; + default: + goto fail; /* proper error handling not possible?? */ } if (sf->fcbs->fseek(sf->sffd, sf->samplepos + data->start + new_offset, SEEK_SET) != FLUID_FAILED) { data->offset = new_offset; } +fail: return data->offset; } From 2bff09b4205f629021df31578fffc77f8adfbcba Mon Sep 17 00:00:00 2001 From: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sat, 5 May 2018 16:40:55 +0200 Subject: [PATCH 10/16] fluid_rvoice_check_sample_sanity cleanup (#375) Check already done by the caller. --- src/rvoice/fluid_rvoice.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/rvoice/fluid_rvoice.c b/src/rvoice/fluid_rvoice.c index 226b3c80..436dda7e 100644 --- a/src/rvoice/fluid_rvoice.c +++ b/src/rvoice/fluid_rvoice.c @@ -126,10 +126,6 @@ fluid_rvoice_check_sample_sanity(fluid_rvoice_t* voice) int max_index_loop=(int) voice->dsp.sample->end - FLUID_MIN_LOOP_PAD + 1; /* 'end' is last valid sample, loopend can be + 1 */ fluid_check_fpe("voice_check_sample_sanity start"); - if (!voice->dsp.check_sample_sanity_flag){ - return; - } - #if 0 printf("Sample from %i to %i\n",voice->dsp.sample->start, voice->dsp.sample->end); printf("Sample loop from %i %i\n",voice->dsp.sample->loopstart, voice->dsp.sample->loopend); From bad31022513e45e72734779ab5c320c091cbc59c Mon Sep 17 00:00:00 2001 From: Tom M Date: Sat, 5 May 2018 17:48:27 +0200 Subject: [PATCH 11/16] Fix Travis CI (#376) * fix build on macOSx with gcc7 * use gold linker for debug build * add gcc8 build --- .travis.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a9bd2061..92c62ec9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,7 +82,7 @@ matrix: - ladspa-sdk env: - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5" - - CMAKE_FLAGS="-Denable-debug=1" + - CMAKE_FLAGS="-Denable-debug=1 -DCMAKE_C_FLAGS_DEBUG=-fuse-ld=gold" # works on Precise and Trusty - os: linux @@ -114,6 +114,21 @@ matrix: env: - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" + # works on Precise and Trusty + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-8 + - cmake-data + - cmake + - libglib2.0-0 + - ladspa-sdk + env: + - MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" + # works on Precise and Trusty - os: linux addons: @@ -188,7 +203,7 @@ matrix: - os: osx osx_image: xcode8 env: - - MATRIX_EVAL="brew install gcc glib gettext libsndfile jack dbus-glib pulseaudio portaudio && brew link gettext && CC=gcc-7 && CXX=g++-7" + - MATRIX_EVAL="brew install gcc glib gettext libsndfile jack dbus-glib pulseaudio portaudio && brew link gettext && CC=gcc-8 && CXX=g++-8" before_install: - if [ $TRAVIS_OS_NAME = linux ]; then sudo apt-get update; else brew update; fi From d47de30f160c222039f7b552ff13edb6c955f484 Mon Sep 17 00:00:00 2001 From: derselbst Date: Sat, 5 May 2018 20:55:26 +0200 Subject: [PATCH 12/16] fix tautological comparision on platforms where `char` is implemented as `unsigned char`, addresses #378 --- src/synth/fluid_chan.h | 20 ++++++++++---------- src/synth/fluid_synth_monopoly.c | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/synth/fluid_chan.h b/src/synth/fluid_chan.h index cc78ce65..cad670a3 100644 --- a/src/synth/fluid_chan.h +++ b/src/synth/fluid_chan.h @@ -65,8 +65,8 @@ struct mononote { unsigned char next; /* next note */ - char note; /* note */ - char vel; /* velocity */ + unsigned char note; /* note */ + unsigned char vel; /* velocity */ }; /* @@ -87,25 +87,25 @@ struct _fluid_channel_t /* monophonic list - legato detector */ unsigned char i_first; /**< First note index */ unsigned char i_last; /**< most recent note index since the most recent add */ - char prev_note; /**< previous note of the most recent add/remove */ + unsigned char prev_note; /**< previous note of the most recent add/remove */ unsigned char n_notes; /**< actual number of notes in the list */ struct mononote monolist[FLUID_CHANNEL_SIZE_MONOLIST]; /**< monophonic list */ - char key_mono_sustained; /**< previous sustained monophonic note */ - char previous_cc_breath; /**< Previous Breath */ + unsigned char key_mono_sustained; /**< previous sustained monophonic note */ + unsigned char previous_cc_breath; /**< Previous Breath */ enum fluid_channel_legato_mode legatomode; /**< legato mode */ enum fluid_channel_portamento_mode portamentomode; /**< portamento mode */ /*- End of Poly/mono variables description */ - char cc[128]; /**< MIDI controller values */ - char key_pressure[128]; /**< MIDI polyphonic key pressure */ + unsigned char cc[128]; /**< MIDI controller values from [0;127] */ + unsigned char key_pressure[128]; /**< MIDI polyphonic key pressure from [0;127] */ /* Drum channel flag, CHANNEL_TYPE_MELODIC, or CHANNEL_TYPE_DRUM. */ enum fluid_midi_channel_type channel_type; enum fluid_interp interp_method; /**< Interpolation method (enum fluid_interp) */ - char channel_pressure; /**< MIDI channel pressure */ - char pitch_wheel_sensitivity; /**< Current pitch wheel sensitivity */ + unsigned char channel_pressure; /**< MIDI channel pressure from [0;127] */ + unsigned char pitch_wheel_sensitivity; /**< Current pitch wheel sensitivity */ short pitch_bend; /**< Current pitch bend value */ /* Sostenuto order id gives the order of SostenutoOn event. * This value is useful to known when the sostenuto pedal is depressed @@ -231,7 +231,7 @@ int fluid_channel_get_interp_method(fluid_channel_t* chan); fluid_channel_legato(chan)) /* Macros interface to monophonic list variables */ -#define INVALID_NOTE (-1) +#define INVALID_NOTE (255) /* Returns true when a note is a valid note */ #define fluid_channel_is_valid_note(n) (n != INVALID_NOTE) /* Marks prev_note as invalid. */ diff --git a/src/synth/fluid_synth_monopoly.c b/src/synth/fluid_synth_monopoly.c index 9aac56ec..400187b6 100644 --- a/src/synth/fluid_synth_monopoly.c +++ b/src/synth/fluid_synth_monopoly.c @@ -163,9 +163,9 @@ * - In mono legato playing,default_fromkey must be valid. */ static char fluid_synth_get_fromkey_portamento_legato(fluid_channel_t* chan, - char default_fromkey) + int default_fromkey) { - char ptc = fluid_channel_get_cc(chan, PORTAMENTO_CTRL); + unsigned char ptc = fluid_channel_get_cc(chan, PORTAMENTO_CTRL); if(fluid_channel_is_valid_note(ptc)) { /* CC PTC has been received */ fluid_channel_clear_portamento(chan); /* clears the CC PTC receive */ @@ -178,7 +178,7 @@ static char fluid_synth_get_fromkey_portamento_legato(fluid_channel_t* chan, } else { /* determines and returns fromkey portamento */ - char fromkey_portamento = INVALID_NOTE; + unsigned char fromkey_portamento = INVALID_NOTE; if(fluid_channel_portamento(chan)) { /* Portamento when Portamento pedal is On */ /* 'fromkey portamento'is determined from the portamento mode From 3dcb7d3b926c5c9a4132726d34669af26577d06f Mon Sep 17 00:00:00 2001 From: jjceresa <32781294+jjceresa@users.noreply.github.com> Date: Sat, 5 May 2018 21:08:59 +0200 Subject: [PATCH 13/16] remove redundant function declarations (#379) Remove fluid_channel_get_interp_method(), fluid_channel_set_interp_method(), fluid_channel_get_preset() and fluid_channel_get_num() as they are already defined as macros. --- src/synth/fluid_chan.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/synth/fluid_chan.h b/src/synth/fluid_chan.h index cad670a3..6fac7d68 100644 --- a/src/synth/fluid_chan.h +++ b/src/synth/fluid_chan.h @@ -148,16 +148,12 @@ void fluid_channel_init_ctrl(fluid_channel_t* chan, int is_all_ctrl_off); void delete_fluid_channel(fluid_channel_t* chan); void fluid_channel_reset(fluid_channel_t* chan); int fluid_channel_set_preset(fluid_channel_t* chan, fluid_preset_t* preset); -fluid_preset_t* fluid_channel_get_preset(fluid_channel_t* chan); void fluid_channel_set_sfont_bank_prog(fluid_channel_t* chan, int sfont, int bank, int prog); void fluid_channel_set_bank_lsb(fluid_channel_t* chan, int banklsb); void fluid_channel_set_bank_msb(fluid_channel_t* chan, int bankmsb); void fluid_channel_get_sfont_bank_prog(fluid_channel_t* chan, int *sfont, int *bank, int *prog); -int fluid_channel_get_num(fluid_channel_t* chan); -void fluid_channel_set_interp_method(fluid_channel_t* chan, int new_method); -int fluid_channel_get_interp_method(fluid_channel_t* chan); #define fluid_channel_get_preset(chan) ((chan)->preset) #define fluid_channel_set_cc(chan, num, val) \ From 34912586f09ce88605f5cbbcaeef06eafdf82d11 Mon Sep 17 00:00:00 2001 From: derselbst Date: Tue, 8 May 2018 22:19:28 +0200 Subject: [PATCH 14/16] add a unit test for manually unregistering via fluid_event_unregistering() currently results in a double free --- test/CMakeLists.txt | 1 + test/test_seqbind_unregister.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 test/test_seqbind_unregister.c diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fa8e9c00..3952b27c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,6 +13,7 @@ ADD_FLUID_TEST(test_sample_cache) ADD_FLUID_TEST(test_sfont_loading) ADD_FLUID_TEST(test_sample_rate_change) ADD_FLUID_TEST(test_preset_sample_loading) +ADD_FLUID_TEST(test_seqbind_unregister) if ( LIBSNDFILE_HASVORBIS ) ADD_FLUID_TEST(test_sf3_sfont_loading) diff --git a/test/test_seqbind_unregister.c b/test/test_seqbind_unregister.c new file mode 100644 index 00000000..c328e73e --- /dev/null +++ b/test/test_seqbind_unregister.c @@ -0,0 +1,29 @@ + +#include "test.h" +#include "fluidsynth.h" // use local fluidsynth header + +// simple test to ensure that manually unregistering and deleting the internal fluid_seqbind_t works without crashing +int main() +{ + fluid_settings_t* settings = new_fluid_settings(); + fluid_synth_t* synth = new_fluid_synth(settings); + fluid_sequencer_t* seq = new_fluid_sequencer2(0 /*i.e. use sample timer*/); + + // silently creates a fluid_seqbind_t + int seqid = fluid_sequencer_register_fluidsynth(seq, synth); + + fluid_event_t* evt = new_fluid_event(); + fluid_event_set_source(evt, -1); + fluid_event_set_dest(evt, seqid); + + // manually free the fluid_seqbind_t + fluid_event_unregistering(evt); + fluid_sequencer_send_now(seq, evt); + + // client should be removed, deleting the seq should not free the struct again + delete_fluid_sequencer(seq); + delete_fluid_synth(synth); + delete_fluid_settings(settings); + + return EXIT_SUCCESS; +} From 8c2ef3003824493772f830b5bfe4cc3df47f0821 Mon Sep 17 00:00:00 2001 From: derselbst Date: Wed, 9 May 2018 11:36:08 +0200 Subject: [PATCH 15/16] fix uninitialized member access of voice_zone->range.ignore; introduced in #370 --- src/sfloader/fluid_defsfont.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sfloader/fluid_defsfont.c b/src/sfloader/fluid_defsfont.c index 33968984..f6ef1794 100644 --- a/src/sfloader/fluid_defsfont.c +++ b/src/sfloader/fluid_defsfont.c @@ -1057,6 +1057,7 @@ static int fluid_preset_zone_create_voice_zones(fluid_preset_zone_t* preset_zone voice_zone->range.keyhi = (prange->keyhi < irange->keyhi) ? prange->keyhi : irange->keyhi; voice_zone->range.vello = (prange->vello > irange->vello) ? prange->vello : irange->vello; voice_zone->range.velhi = (prange->velhi < irange->velhi) ? prange->velhi : irange->velhi; + voice_zone->range.ignore = FALSE; preset_zone->voice_zone = fluid_list_append(preset_zone->voice_zone, voice_zone); From 36546a9efb4464cbbb45c62aadb9e1cd95212d70 Mon Sep 17 00:00:00 2001 From: derselbst Date: Wed, 9 May 2018 20:54:51 +0200 Subject: [PATCH 16/16] remove synth.parallel-render setting --- doc/fluidsettings.xml | 13 ++----------- doc/fluidsynth-v11-devdoc.txt | 5 +++-- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/doc/fluidsettings.xml b/doc/fluidsettings.xml index a4a1a84c..6144fa68 100644 --- a/doc/fluidsettings.xml +++ b/doc/fluidsettings.xml @@ -10,6 +10,8 @@ NOTE: You're not expected to look at this raw XML file. Please open it in a webb https://stackoverflow.com/a/3839054 https://stackoverflow.com/a/6251757 + +Developers: Settings can be deprecated by adding: SOME TEXT --> @@ -228,17 +230,6 @@ https://stackoverflow.com/a/6251757 score. - - parallel-render - bool - 1 (TRUE) - - This is the low-latency setting. If on, you're allowed to call fluid_synth_write_s16, fluid_synth_write_float, fluid_synth_nwrite_float or fluid_synth_process in parallel with the rest of the calls, and it won't be blocked by time intensive calls to the synth. Turn it off if throughput is more important than latency, e g in rendering-to-file scenarios where underruns is not an issue. - - - As of 1.1.7 this option is deprecated and has been removed in 2.0. This option enforces thread safety for rvoice_mixer, which causes rvoice_events to be queued internally. The current implementation relies on the fact that this option is set to TRUE to correctly render any amount of requested audio. Also calling fluid_synth_write_* in parallel is not considered to be a use-case. It would cause undefined audio output, as it would be unpredictable for the user which rvoice_events specifically would be dispatched to which fluid_synth_write_* call. - - polyphony int diff --git a/doc/fluidsynth-v11-devdoc.txt b/doc/fluidsynth-v11-devdoc.txt index 0a6f577f..45b352bd 100644 --- a/doc/fluidsynth-v11-devdoc.txt +++ b/doc/fluidsynth-v11-devdoc.txt @@ -85,10 +85,11 @@ Changes in FluidSynth 2.0.0 concerning developers: - remove deprecated fluid_synth_reset_tuning(), use fluid_synth_deactivate_tuning(synth, chan, FALSE) instead - remove deprecated FLUID_HINT_INTEGER - remove deprecated fluid_synth_set_gen2() as there doesnt seem to be a use case for absolute generator values -- remove fluid_cmd_handler_register() and fluid_cmd_handler_unregister() from public API, as they seem to be unused downstream -- remove misspelled FLUID_SEQ_PITCHWHHELSENS macro +- remove deprecated "synth.parallel-render" setting - remove obsolete "audio.[out|in]put-channels" settings - remove unimplemented "synth.dump" setting +- remove fluid_cmd_handler_register() and fluid_cmd_handler_unregister() from public API, as they seem to be unused downstream +- remove misspelled FLUID_SEQ_PITCHWHHELSENS macro - remove struct _fluid_mod_t from public API, use the getters and setters of mod.h instead - remove struct _fluid_gen_t, fluid_gen_set_default_values() and enum fluid_gen_flags from public API - remove macros fluid_sfont_get_id() and fluid_sample_refcount() from public API