Merge branch 'master' into rvoice-align

This commit is contained in:
Tom M 2018-05-11 16:53:42 +02:00 committed by GitHub
commit f1384f03d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 338 additions and 182 deletions

View file

@ -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

View file

@ -333,9 +333,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" )

View file

@ -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: <deprecated>SOME TEXT</deprecated>
-->
<?xml-stylesheet type="text/xsl" href="fluidsettings.xsl"?>
<fluidsettings>
@ -228,17 +230,6 @@ https://stackoverflow.com/a/6251757
score.
</desc>
</setting>
<setting>
<name>parallel-render</name>
<type>bool</type>
<def>1 (TRUE)</def>
<desc>
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.
</desc>
<deprecated>
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.
</deprecated>
</setting>
<setting>
<name>polyphony</name>
<type>int</type>

View file

@ -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
@ -101,6 +102,7 @@ Changes in FluidSynth 2.0.0 concerning developers:
<br /><br />
- 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
@ -109,6 +111,7 @@ Changes in FluidSynth 2.0.0 concerning developers:
<br /><br />
- add <a href="fluidsettings.xml#midi.autoconnect">"midi.autoconnect"</a> a setting for automatically connecting fluidsynth to available MIDI input ports
- add <a href="fluidsettings.xml#synth.overflow.important">"synth.overflow.important"</a> and <a href="fluidsettings.xml#synth.overflow.important-channels">"synth.overflow.important-channels"</a> settings to take midi channels during overflow calculation into account that are considered to be "important"
- add <a href="fluidsettings.xml#synth.dynamic-sample-loading">"synth.dynamic-sample-loading"</a> 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()

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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
@ -100,7 +100,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 */
@ -115,6 +115,10 @@ 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)
{
@ -271,7 +275,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]);
@ -428,7 +432,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++)
@ -585,7 +589,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();
@ -617,7 +621,9 @@ void delete_fluid_rvoice_mixer(fluid_rvoice_mixer_t* mixer)
{
fluid_return_if_fail(mixer != NULL);
#ifdef ENABLE_MIXER_THREADS
#if ENABLE_MIXER_THREADS
delete_rvoice_mixer_threads(mixer);
if (mixer->thread_ready)
delete_fluid_cond(mixer->thread_ready);
if (mixer->wakeup_threads)
@ -765,7 +771,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)
@ -981,24 +987,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);
@ -1017,6 +1008,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)
{
#if 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)
@ -1062,7 +1074,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

View file

@ -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);
/***************************************************************
@ -127,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);
}
@ -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;
}
@ -266,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
@ -513,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;
@ -636,7 +643,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 +664,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 +846,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);
@ -966,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");
@ -994,6 +998,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 +1010,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;
voice_zone->range.ignore = FALSE;
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
*/
@ -1018,6 +1075,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);
@ -1045,14 +1103,22 @@ 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");
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 (zone->inst == NULL)
{
return FLUID_FAILED;
}
if (fluid_inst_import_sfont(zone, zone->inst,
(SFInst *) sfzone->instsamp->data, defsfont) != FLUID_OK) {
return FLUID_FAILED;
if (fluid_preset_zone_create_voice_zones(zone) == FLUID_FAILED)
{
return FLUID_FAILED;
}
}
@ -1256,16 +1322,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);
@ -1281,25 +1355,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(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;
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;
}
/*
@ -1408,8 +1484,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 +1516,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) { */
@ -1829,3 +1897,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;
}

View file

@ -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;
};
/*
@ -76,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);
@ -107,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 */
@ -118,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);
@ -163,6 +172,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 */
@ -180,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);
@ -210,8 +220,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);

View file

@ -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;

View file

@ -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);
@ -2000,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;
}

View file

@ -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 */
};

View file

@ -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 */

View file

@ -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
@ -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) \
@ -231,7 +227,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. */

View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -14,6 +14,7 @@ ADD_FLUID_TEST(test_sfont_loading)
ADD_FLUID_TEST(test_sample_rate_change)
ADD_FLUID_TEST(test_preset_sample_loading)
ADD_FLUID_TEST(test_pointer_alignment)
ADD_FLUID_TEST(test_seqbind_unregister)
if ( LIBSNDFILE_HASVORBIS )
ADD_FLUID_TEST(test_sf3_sfont_loading)

View file

@ -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;
}