From 2479c03b78873ee19f629a51bd7193255c688f94 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Sun, 17 Oct 2010 10:20:57 +0000 Subject: [PATCH] Code cleanup, and remove unnecessary atomicy and shadow variables, now that the new architecture is in place. --- fluidsynth/src/synth/fluid_chan.c | 94 +-- fluidsynth/src/synth/fluid_chan.h | 59 +- fluidsynth/src/synth/fluid_synth.c | 957 ++--------------------------- fluidsynth/src/synth/fluid_synth.h | 114 +--- fluidsynth/src/synth/fluid_voice.c | 11 +- 5 files changed, 108 insertions(+), 1127 deletions(-) diff --git a/fluidsynth/src/synth/fluid_chan.c b/fluidsynth/src/synth/fluid_chan.c index e6b07006..50850e70 100644 --- a/fluidsynth/src/synth/fluid_chan.c +++ b/fluidsynth/src/synth/fluid_chan.c @@ -53,7 +53,6 @@ new_fluid_channel(fluid_synth_t* synth, int num) chan->synth = synth; chan->channum = num; chan->preset = NULL; - chan->shadow_preset = NULL; chan->tuning = NULL; fluid_channel_init(chan); @@ -65,7 +64,6 @@ new_fluid_channel(fluid_synth_t* synth, int num) static void fluid_channel_init(fluid_channel_t* chan) { -// fluid_event_queue_elem_t *event; fluid_preset_t *newpreset; int prognum, banknum; @@ -75,7 +73,6 @@ fluid_channel_init(fluid_channel_t* chan) chan->sfont_bank_prog = 0 << SFONT_SHIFTVAL | banknum << BANK_SHIFTVAL | prognum << PROG_SHIFTVAL; - /* FIXME - fluid_synth_find_preset not real-time safe */ newpreset = fluid_synth_find_preset(chan->synth, banknum, prognum); fluid_channel_set_preset(chan, newpreset); @@ -87,25 +84,7 @@ fluid_channel_init(fluid_channel_t* chan) if (chan->tuning) { -#if 0 - event = fluid_event_queue_get_inptr (chan->synth->return_queue); - - if (event) - { - event->type = FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING; - event->unref_tuning.tuning = chan->tuning; - event->unref_tuning.count = 1; - fluid_event_queue_next_inptr (chan->synth->return_queue); - } - else - { /* Just unref it in synthesis thread if queue is full */ - - fluid_tuning_unref (chan->tuning, 1); - FLUID_LOG (FLUID_ERR, "Synth return event queue full"); - } -#else fluid_tuning_unref (chan->tuning, 1); -#endif chan->tuning = NULL; } } @@ -208,28 +187,9 @@ fluid_channel_reset(fluid_channel_t* chan) int fluid_channel_set_preset(fluid_channel_t* chan, fluid_preset_t* preset) { -// fluid_event_queue_elem_t *event; fluid_preset_notify (chan->preset, FLUID_PRESET_UNSELECTED, chan->channum); - /* Set shadow preset again, so it contains the actual latest assigned value */ - fluid_atomic_pointer_set (&chan->shadow_preset, preset); - -#if 0 - if (chan->preset) /* Queue preset free (shouldn't free() in synth context) */ - { - event = fluid_event_queue_get_inptr (chan->synth->return_queue); - if (!event) - { - FLUID_LOG (FLUID_ERR, "Synth return event queue full"); - return FLUID_FAILED; - } - - event->type = FLUID_EVENT_QUEUE_ELEM_FREE_PRESET; - event->pval = chan->preset; - fluid_event_queue_next_inptr (chan->synth->return_queue); - } -#endif if (chan->preset) { fluid_sfont_t *sfont; sfont = chan->preset->sfont; @@ -259,15 +219,9 @@ fluid_channel_set_sfont_bank_prog(fluid_channel_t* chan, int sfontnum, | ((banknum != -1) ? 0 : BANK_MASKVAL) | ((prognum != -1) ? 0 : PROG_MASKVAL); - /* Loop until SoundFont, bank and program integer is atomically assigned */ - do - { - oldval = fluid_atomic_int_get (&chan->sfont_bank_prog); - newval = (newval & ~oldmask) | (oldval & oldmask); - } - while (newval != oldval - && !fluid_atomic_int_compare_and_exchange (&chan->sfont_bank_prog, - oldval, newval)); + oldval = chan->sfont_bank_prog; + newval = (newval & ~oldmask) | (oldval & oldmask); + chan->sfont_bank_prog = newval; } /* Set bank LSB 7 bits */ @@ -276,24 +230,18 @@ fluid_channel_set_bank_lsb(fluid_channel_t* chan, int banklsb) { int oldval, newval, style; - style = fluid_atomic_int_get (&chan->synth->bank_select); + style = chan->synth->bank_select; if (style == FLUID_BANK_STYLE_GM || style == FLUID_BANK_STYLE_GS || chan->channum == 9) //TODO: ask for channel drum mode, instead of number return; /* ignored */ - /* Loop until bank LSB is atomically assigned */ - do - { - oldval = fluid_atomic_int_get (&chan->sfont_bank_prog); - if (style == FLUID_BANK_STYLE_XG) - newval = (oldval & ~BANK_MASKVAL) | (banklsb << BANK_SHIFTVAL); - else /* style == FLUID_BANK_STYLE_MMA */ - newval = (oldval & ~BANKLSB_MASKVAL) | (banklsb << BANK_SHIFTVAL); - } - while (newval != oldval - && !fluid_atomic_int_compare_and_exchange (&chan->sfont_bank_prog, - oldval, newval)); + oldval = chan->sfont_bank_prog; + if (style == FLUID_BANK_STYLE_XG) + newval = (oldval & ~BANK_MASKVAL) | (banklsb << BANK_SHIFTVAL); + else /* style == FLUID_BANK_STYLE_MMA */ + newval = (oldval & ~BANKLSB_MASKVAL) | (banklsb << BANK_SHIFTVAL); + chan->sfont_bank_prog = newval; } /* Set bank MSB 7 bits */ @@ -302,25 +250,19 @@ fluid_channel_set_bank_msb(fluid_channel_t* chan, int bankmsb) { int oldval, newval, style; - style = fluid_atomic_int_get (&chan->synth->bank_select); + style = chan->synth->bank_select; if (style == FLUID_BANK_STYLE_GM || style == FLUID_BANK_STYLE_XG || chan->channum == 9) //TODO: ask for channel drum mode, instead of number return; /* ignored */ //TODO: if style == XG and bankmsb == 127, convert the channel to drum mode - /* Loop until bank MSB is atomically assigned */ - do - { - oldval = fluid_atomic_int_get (&chan->sfont_bank_prog); - if (style == FLUID_BANK_STYLE_GS) - newval = (oldval & ~BANK_MASKVAL) | (bankmsb << BANK_SHIFTVAL); - else /* style == FLUID_BANK_STYLE_MMA */ - newval = (oldval & ~BANKMSB_MASKVAL) | (bankmsb << (BANK_SHIFTVAL + 7)); - } - while (newval != oldval - && !fluid_atomic_int_compare_and_exchange (&chan->sfont_bank_prog, - oldval, newval)); + oldval = chan->sfont_bank_prog; + if (style == FLUID_BANK_STYLE_GS) + newval = (oldval & ~BANK_MASKVAL) | (bankmsb << BANK_SHIFTVAL); + else /* style == FLUID_BANK_STYLE_MMA */ + newval = (oldval & ~BANKMSB_MASKVAL) | (bankmsb << (BANK_SHIFTVAL + 7)); + chan->sfont_bank_prog = newval; } /* Get SoundFont ID, MIDI bank and/or program. Use NULL to ignore a value. */ @@ -330,7 +272,7 @@ fluid_channel_get_sfont_bank_prog(fluid_channel_t* chan, int *sfont, { int sfont_bank_prog; - sfont_bank_prog = fluid_atomic_int_get (&chan->sfont_bank_prog); + sfont_bank_prog = chan->sfont_bank_prog; if (sfont) *sfont = (sfont_bank_prog & SFONT_MASKVAL) >> SFONT_SHIFTVAL; if (bank) *bank = (sfont_bank_prog & BANK_MASKVAL) >> BANK_SHIFTVAL; diff --git a/fluidsynth/src/synth/fluid_chan.h b/fluidsynth/src/synth/fluid_chan.h index 7e21a99d..879dc6fc 100644 --- a/fluidsynth/src/synth/fluid_chan.h +++ b/fluidsynth/src/synth/fluid_chan.h @@ -28,29 +28,8 @@ /* * fluid_channel_t * - * Mutual exclusion notes: - * - * Set once on init: - * channum - * synth - * - * Synthesis thread context only: - * preset - * tuning - * nrpn_select - * nrpn_active - * gen[] - * gen_abs[] - * - * Uses atomic operations: - * sfont_bank_prog - * shadow_preset - * key_pressure - * channel_pressure - * pitch_bend - * pitch_wheel_sensitivity - * cc[] - * interp_method + * Mutual exclusion notes (as of 1.1.2): + * None - everything should have been synchronized by the synth. */ struct _fluid_channel_t { @@ -61,7 +40,6 @@ struct _fluid_channel_t int sfont_bank_prog; /**< SoundFont ID (bit 21-31), bank (bit 7-20), program (bit 0-6) */ fluid_preset_t* preset; /**< Selected preset */ - fluid_preset_t* shadow_preset; /**< Most recently assigned preset */ int key_pressure; /**< MIDI key pressure */ int channel_pressure; /**< MIDI channel pressure */ @@ -116,40 +94,41 @@ 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) \ - fluid_atomic_int_set (&(chan)->cc[num], val) -#define fluid_channel_get_cc(chan, num) fluid_atomic_int_get (&(chan)->cc[num]) + ((chan)->cc[num] = (val)) +#define fluid_channel_get_cc(chan, num) \ + ((chan)->cc[num]) #define fluid_channel_get_key_pressure(chan) \ - fluid_atomic_int_get (&(chan)->key_pressure) + ((chan)->key_pressure) #define fluid_channel_set_key_pressure(chan, val) \ - fluid_atomic_int_set (&(chan)->key_pressure, val) + ((chan)->key_pressure = (val)) #define fluid_channel_get_channel_pressure(chan) \ - fluid_atomic_int_get (&(chan)->channel_pressure) + ((chan)->channel_pressure) #define fluid_channel_set_channel_pressure(chan, val) \ - fluid_atomic_int_set (&(chan)->channel_pressure, val) + ((chan)->channel_pressure = (val)) #define fluid_channel_get_pitch_bend(chan) \ - fluid_atomic_int_get (&(chan)->pitch_bend) + ((chan)->pitch_bend) #define fluid_channel_set_pitch_bend(chan, val) \ - fluid_atomic_int_set (&(chan)->pitch_bend, val) + ((chan)->pitch_bend = (val)) #define fluid_channel_get_pitch_wheel_sensitivity(chan) \ - fluid_atomic_int_get (&(chan)->pitch_wheel_sensitivity) + ((chan)->pitch_wheel_sensitivity) #define fluid_channel_set_pitch_wheel_sensitivity(chan, val) \ - fluid_atomic_int_set (&(chan)->pitch_wheel_sensitivity, val) + ((chan)->pitch_wheel_sensitivity = (val)) #define fluid_channel_get_num(chan) ((chan)->channum) #define fluid_channel_set_interp_method(chan, new_method) \ - fluid_atomic_int_set (&(chan)->interp_method, new_method) + ((chan)->interp_method = (new_method)) #define fluid_channel_get_interp_method(chan) \ - fluid_atomic_int_get (&(chan)->interp_method); + ((chan)->interp_method); #define fluid_channel_set_tuning(_c, _t) { (_c)->tuning = _t; } #define fluid_channel_has_tuning(_c) ((_c)->tuning != NULL) #define fluid_channel_get_tuning(_c) ((_c)->tuning) #define fluid_channel_get_tuning_bank(chan) \ - fluid_atomic_int_get (&(chan)->tuning_bank) + ((chan)->tuning_bank) #define fluid_channel_set_tuning_bank(chan, bank) \ - fluid_atomic_int_set (&(chan)->tuning_bank, bank) + ((chan)->tuning_bank = (bank)) #define fluid_channel_get_tuning_prog(chan) \ - fluid_atomic_int_get (&(chan)->tuning_prog) + ((chan)->tuning_prog) #define fluid_channel_set_tuning_prog(chan, prog) \ - fluid_atomic_int_set (&(chan)->tuning_prog, prog) + ((chan)->tuning_prog = (prog)) #define fluid_channel_sustained(_c) ((_c)->cc[SUSTAIN_SWITCH] >= 64) #define fluid_channel_set_gen(_c, _n, _v, _a) { (_c)->gen[_n] = _v; (_c)->gen_abs[_n] = _a; } #define fluid_channel_get_gen(_c, _n) ((_c)->gen[_n]) diff --git a/fluidsynth/src/synth/fluid_synth.c b/fluidsynth/src/synth/fluid_synth.c index 059f7d8b..163eebf9 100644 --- a/fluidsynth/src/synth/fluid_synth.c +++ b/fluidsynth/src/synth/fluid_synth.c @@ -36,28 +36,8 @@ extern int feenableexcept (int excepts); #endif -/* A descriptive alias for fluid_return_if_fail/fluid_return_val_if_fail */ -//#define fluid_synth_is_synth_thread(_s) (fluid_thread_get_id() == (_s)->synth_thread_id) - -/* Macro used to check if an event should be queued or not (not in synthesis thread context?) */ -//#define fluid_synth_should_queue(_s) (!fluid_synth_is_synth_thread(_s)) -#define fluid_synth_should_queue(_s) (0) - - static void fluid_synth_init(void); -#if 0 -static void fluid_synth_return_event_process_thread (void* data); -static fluid_event_queue_t *fluid_synth_get_event_queue (fluid_synth_t* synth); -static void fluid_synth_thread_queue_destroy_notify (void *data); -#endif - -static int fluid_synth_queue_midi_event (fluid_synth_t* synth, int type, int chan, - int param1, int param2); -static int fluid_synth_queue_gen_event (fluid_synth_t* synth, int chan, - int param, float value, int absolute); -static int fluid_synth_queue_int_event (fluid_synth_t* synth, int type, int val); - static int fluid_synth_noteon_LOCAL(fluid_synth_t* synth, int chan, int key, int vel); static int fluid_synth_noteoff_LOCAL(fluid_synth_t* synth, int chan, int key); @@ -97,13 +77,13 @@ static int fluid_synth_update_gain(fluid_synth_t* synth, static void fluid_synth_update_gain_LOCAL(fluid_synth_t* synth); static int fluid_synth_update_polyphony(fluid_synth_t* synth, char* name, int value); -static int fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth); +static int fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth, int new_polyphony); static void init_dither(void); static inline int roundi (float x); static int fluid_synth_render_blocks(fluid_synth_t* synth, int blockcount); //static void fluid_synth_core_thread_func (void* data); -static FLUID_INLINE void fluid_synth_process_event_queue_LOCAL - (fluid_synth_t *synth, fluid_event_queue_t *queue); +//static FLUID_INLINE void fluid_synth_process_event_queue_LOCAL +// (fluid_synth_t *synth, fluid_event_queue_t *queue); static fluid_voice_t* fluid_synth_free_voice_by_kill_LOCAL(fluid_synth_t* synth); static void fluid_synth_kill_by_exclusive_class_LOCAL(fluid_synth_t* synth, fluid_voice_t* new_voice); @@ -590,18 +570,6 @@ new_fluid_synth(fluid_settings_t *settings) fluid_settings_getint(settings, "synth.threadsafe-api", &synth->use_mutex); synth->public_api_count = 0; -#if 0 - fluid_private_init(synth->thread_queues); - synth->return_queue = fluid_event_queue_new (FLUID_MAX_RETURN_EVENTS); - synth->return_queue_mutex = new_fluid_cond_mutex (); - synth->return_queue_cond = new_fluid_cond (); - - if (synth->return_queue == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } -#endif - synth->settings = settings; fluid_settings_getint(settings, "synth.reverb.active", &synth->with_reverb); @@ -610,7 +578,6 @@ new_fluid_synth(fluid_settings_t *settings) fluid_settings_getint(settings, "synth.dump", &synth->dump); fluid_settings_getint(settings, "synth.polyphony", &synth->polyphony); - synth->shadow_polyphony = synth->polyphony; fluid_settings_getnum(settings, "synth.sample-rate", &synth->sample_rate); fluid_settings_getint(settings, "synth.midi-channels", &synth->midi_channels); fluid_settings_getint(settings, "synth.audio-channels", &synth->audio_channels); @@ -751,73 +718,10 @@ new_fluid_synth(fluid_settings_t *settings) fluid_synth_set_reverb_on(synth, synth->with_reverb); fluid_synth_set_chorus_on(synth, synth->with_chorus); -#if 0 - /* Allocate the sample buffers */ - synth->left_buf = NULL; - synth->right_buf = NULL; - synth->fx_left_buf = NULL; - synth->fx_right_buf = NULL; - - /* Left and right audio buffers */ - - synth->left_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf); - synth->right_buf = FLUID_ARRAY(fluid_real_t*, synth->nbuf); - - if ((synth->left_buf == NULL) || (synth->right_buf == NULL)) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - - FLUID_MEMSET(synth->left_buf, 0, synth->nbuf * sizeof(fluid_real_t*)); - FLUID_MEMSET(synth->right_buf, 0, synth->nbuf * sizeof(fluid_real_t*)); - - for (i = 0; i < synth->nbuf; i++) { - - synth->left_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE); - synth->right_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE); - - if ((synth->left_buf[i] == NULL) || (synth->right_buf[i] == NULL)) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - } - - /* Effects audio buffers */ - - synth->fx_left_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels); - synth->fx_right_buf = FLUID_ARRAY(fluid_real_t*, synth->effects_channels); - - if ((synth->fx_left_buf == NULL) || (synth->fx_right_buf == NULL)) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - - FLUID_MEMSET(synth->fx_left_buf, 0, synth->effects_channels * sizeof(fluid_real_t*)); - FLUID_MEMSET(synth->fx_right_buf, 0, synth->effects_channels * sizeof(fluid_real_t*)); - - for (i = 0; i < synth->effects_channels; i++) { - synth->fx_left_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE); - synth->fx_right_buf[i] = FLUID_ARRAY(fluid_real_t, FLUID_BUFSIZE); - - if ((synth->fx_left_buf[i] == NULL) || (synth->fx_right_buf[i] == NULL)) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - } -#endif - synth->cur = FLUID_BUFSIZE; synth->curmax = 0; synth->dither_index = 0; -#if 0 - /* allocate the reverb module */ - synth->reverb = new_fluid_revmodel(); - if (synth->reverb == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } -#endif synth->reverb_roomsize = FLUID_REVERB_DEFAULT_ROOMSIZE; synth->reverb_damping = FLUID_REVERB_DEFAULT_DAMP; synth->reverb_width = FLUID_REVERB_DEFAULT_WIDTH; @@ -830,14 +734,6 @@ new_fluid_synth(fluid_settings_t *settings) synth->reverb_damping, synth->reverb_width, synth->reverb_level, 0.0f); -#if 0 - /* allocate the chorus module */ - synth->chorus = new_fluid_chorus(synth->sample_rate); - if (synth->chorus == NULL) { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } -#endif /* Initialize multi-core variables if multiple cores enabled */ if (synth->cores > 1) { @@ -845,40 +741,6 @@ new_fluid_synth(fluid_settings_t *settings) fluid_settings_getint (synth->settings, "audio.realtime-prio", &prio_level); fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_threads, synth->cores-1, prio_level); - -#if 0 - synth->core_mutex = new_fluid_cond_mutex (); - synth->core_cond = new_fluid_cond (); - synth->core_wait_last_cond = new_fluid_cond (); - - synth->core_threads = FLUID_ARRAY (fluid_thread_t *, synth->cores - 1); - synth->core_voice_processed = FLUID_ARRAY (fluid_voice_t *, synth->polyphony); - synth->core_bufs = FLUID_MALLOC (synth->polyphony * FLUID_BUFSIZE * sizeof (fluid_real_t)); - - if (!synth->core_mutex || !synth->core_cond || !synth->core_wait_last_cond - || !synth->core_threads || !synth->core_voice_processed - || !synth->core_bufs) - { - FLUID_LOG(FLUID_ERR, "Out of memory"); - goto error_recovery; - } - - synth->cores_active = TRUE; - synth->core_work = FALSE; - synth->core_inprogress = 0; - synth->core_waiting_for_last = FALSE; - - for (i = 0; i < synth->polyphony; i++) - synth->core_voice_processed[i] = NULL; - - for (i = 0; i < synth->cores - 1; i++) - { - synth->core_threads[i] = new_fluid_thread (fluid_synth_core_thread_func, - synth, prio_level, FALSE); - if (!synth->core_threads[i]) - FLUID_LOG(FLUID_ERR, "Failed to create a synthesis core thread"); - } -#endif } synth->bank_select = FLUID_BANK_STYLE_GS; @@ -894,11 +756,6 @@ new_fluid_synth(fluid_settings_t *settings) /* FIXME */ synth->start = fluid_curtime(); -#if 0 - /* Spawn a thread to process synth thread return events */ - synth->return_queue_thread = new_fluid_thread (fluid_synth_return_event_process_thread, - synth, 0, FALSE); -#endif return synth; error_recovery: @@ -906,54 +763,6 @@ new_fluid_synth(fluid_settings_t *settings) return NULL; } -#if 0 -/* Callback to process synthesis thread return events */ -static void -fluid_synth_return_event_process_thread (void* data) -{ - fluid_synth_t *synth = data; - fluid_event_queue_elem_t *event; - fluid_preset_t *preset; - fluid_sfont_t *sfont; - - /* Loop while synth is PLAYING */ - do - { /* Block until we have some work to do or synth stops playing */ - fluid_cond_mutex_lock (synth->return_queue_mutex); - - while (!(event = fluid_event_queue_get_outptr (synth->return_queue)) - && fluid_atomic_int_get (&synth->state) == FLUID_SYNTH_PLAYING) - fluid_cond_wait (synth->return_queue_cond, synth->return_queue_mutex); - - fluid_cond_mutex_unlock (synth->return_queue_mutex); - - if (!event) break; /* No event means synth stopped playing */ - - /* Loop while there are return events */ - do - { - switch (event->type) - { - case FLUID_EVENT_QUEUE_ELEM_FREE_PRESET: /* Preset free event */ - preset = (fluid_preset_t *)(event->pval); - sfont = preset->sfont; - - /* Delete presets under mutex lock, to protect chan->shadow_preset */ - fluid_rec_mutex_lock (synth->mutex); - delete_fluid_preset (preset); - fluid_rec_mutex_unlock (synth->mutex); - - fluid_synth_sfont_unref (synth, sfont); /* -- unref preset's SoundFont */ - break; - } - - fluid_event_queue_next_outptr (synth->return_queue); - } - while ((event = fluid_event_queue_get_outptr (synth->return_queue))); - } - while (fluid_atomic_int_get (&synth->state) == FLUID_SYNTH_PLAYING); -} -#endif /** * Delete a FluidSynth instance. @@ -978,50 +787,6 @@ delete_fluid_synth(fluid_synth_t* synth) fluid_profiling_print(); -#if 0 - /* Stop return event queue thread, and process remaining events */ - if (synth->return_queue_thread) - { /* Signal the return queue thread to cause it to exit */ - fluid_cond_mutex_lock (synth->return_queue_mutex); - fluid_atomic_int_set (&synth->state, FLUID_SYNTH_STOPPED); - fluid_cond_signal (synth->return_queue_cond); - fluid_cond_mutex_unlock (synth->return_queue_mutex); - - fluid_thread_join (synth->return_queue_thread); - delete_fluid_thread (synth->return_queue_thread); - } - else fluid_atomic_int_set (&synth->state, FLUID_SYNTH_STOPPED); - - if (synth->return_queue) - fluid_event_queue_free(synth->return_queue); - - if (synth->return_queue_mutex) - delete_fluid_cond_mutex (synth->return_queue_mutex); - - if (synth->return_queue_cond) - delete_fluid_cond (synth->return_queue_cond); - - /* Free multi-core resources (if multi-core enabled) */ - if (synth->cores > 1) - { - /* Signal slave core threads to exit and wait for them to finish */ - fluid_cond_mutex_lock (synth->core_mutex); /* ++ Lock */ - synth->cores_active = FALSE; - fluid_cond_broadcast (synth->core_cond); - fluid_cond_mutex_unlock (synth->core_mutex); /* -- Unlock */ - - for (i = 0; i < synth->cores - 1; i++) - if (synth->core_threads[i]) - fluid_thread_join (synth->core_threads[i]); - - delete_fluid_cond_mutex (synth->core_mutex); - delete_fluid_cond (synth->core_cond); - delete_fluid_cond (synth->core_wait_last_cond); - FLUID_FREE (synth->core_voice_processed); - FLUID_FREE (synth->core_bufs); - } -#endif - /* turn off all voices, needed to unload SoundFont data */ if (synth->voice != NULL) { for (i = 0; i < synth->nvoice; i++) { @@ -1075,54 +840,6 @@ delete_fluid_synth(fluid_synth_t* synth) FLUID_FREE(synth->voice); } -#if 0 - /* free all the sample buffers */ - if (synth->left_buf != NULL) { - for (i = 0; i < synth->nbuf; i++) { - if (synth->left_buf[i] != NULL) { - FLUID_FREE(synth->left_buf[i]); - } - } - FLUID_FREE(synth->left_buf); - } - - if (synth->right_buf != NULL) { - for (i = 0; i < synth->nbuf; i++) { - if (synth->right_buf[i] != NULL) { - FLUID_FREE(synth->right_buf[i]); - } - } - FLUID_FREE(synth->right_buf); - } - - if (synth->fx_left_buf != NULL) { - for (i = 0; i < synth->effects_channels; i++) { - if (synth->fx_left_buf[i] != NULL) { - FLUID_FREE(synth->fx_left_buf[i]); - } - } - FLUID_FREE(synth->fx_left_buf); - } - - if (synth->fx_right_buf != NULL) { - for (i = 0; i < synth->effects_channels; i++) { - if (synth->fx_right_buf[i] != NULL) { - FLUID_FREE(synth->fx_right_buf[i]); - } - } - FLUID_FREE(synth->fx_right_buf); - } - - /* release the reverb module */ - if (synth->reverb != NULL) { - delete_fluid_revmodel(synth->reverb); - } - - /* release the chorus module */ - if (synth->chorus != NULL) { - delete_fluid_chorus(synth->chorus); - } -#endif /* free the tunings, if any */ if (synth->tuning != NULL) { @@ -1147,25 +864,6 @@ delete_fluid_synth(fluid_synth_t* synth) FLUID_FREE(synth->LADSPA_FxUnit); #endif -#if 0 - fluid_private_free (synth->thread_queues); - - /* free any queues in pool */ - for (list = synth->queue_pool; list; list = list->next) { - queue = (fluid_event_queue_t *)(list->data); - /* Prevent double-free later */ - for (i = 0; i < FLUID_MAX_EVENT_QUEUES; i++) - if (synth->queues[i] == queue) synth->queues[i] = NULL; - fluid_event_queue_free (queue); - } - - /* free remaining event queues, if any */ - for (i = 0; i < FLUID_MAX_EVENT_QUEUES; i++) - if (synth->queues[i]) fluid_event_queue_free (synth->queues[i]); - - delete_fluid_list (synth->queue_pool); -#endif - fluid_rec_mutex_destroy(synth->mutex); FLUID_FREE(synth); @@ -1188,192 +886,6 @@ fluid_synth_error(fluid_synth_t* synth) return fluid_error(); } -#if 0 -/* Get event queue for the current thread (create if necessary) */ -static fluid_event_queue_t * -fluid_synth_get_event_queue (fluid_synth_t* synth) -{ - fluid_event_queue_t *queue; - int i; - - queue = fluid_private_get (synth->thread_queues); /* Get event queue for this thread */ - - if (!queue) /* This thread has no queue yet? */ - { - fluid_rec_mutex_lock (synth->mutex); /* ++ lock queue_pool */ - - /* Use an unclaimed queue, if any (it will already be in synth->queues[] in that case) */ - if (synth->queue_pool) - { - fluid_list_t *p; - - queue = synth->queue_pool->data; - - /* Remove from queue_pool list */ - p = synth->queue_pool; - synth->queue_pool = fluid_list_remove_link (p, p); - delete1_fluid_list (p); - } - - fluid_rec_mutex_unlock (synth->mutex); /* -- unlock queue_pool */ - - if (!queue) /* Create event queue, if one wasn't re-claimed */ - { - queue = fluid_event_queue_new (FLUID_MAX_EVENTS_PER_BUFSIZE); - if (!queue) return NULL; /* Error has already been logged */ - - queue->userdata = synth; - - /* Atomicly and in a lock free fashion, put queue pointer in queues[] array */ - for (i = 0; i < FLUID_MAX_EVENT_QUEUES; i++) - { - if (!fluid_atomic_pointer_get (&synth->queues[i])) - { - if (fluid_atomic_pointer_compare_and_exchange ((void **)&synth->queues[i], - NULL, (void *)queue)) - break; - } - } - - if (i == FLUID_MAX_EVENT_QUEUES) - { - FLUID_LOG (FLUID_ERR, "Maximum thread event queues exceeded"); - return NULL; - } - } - - fluid_private_set (synth->thread_queues, queue, fluid_synth_thread_queue_destroy_notify); - } - - return queue; -} - -/* Get available event for sending to synthesis thread. Returns NULL on error. - * queue is an output parameter. */ -static fluid_event_queue_elem_t * -fluid_synth_get_event_elem (fluid_synth_t* synth, fluid_event_queue_t **queue) -{ - fluid_event_queue_t *q; - fluid_event_queue_elem_t *event; - - q = fluid_synth_get_event_queue (synth); - if (!q) return NULL; - - event = fluid_event_queue_get_inptr (q); - if (!event) - { - FLUID_LOG (FLUID_ERR, "Synthesis event queue full"); - return NULL; - } - - *queue = q; - - return event; -} -#endif -/** - * Queues a MIDI event to the FluidSynth synthesis thread. - * @param synth FluidSynth instance - * @param type MIDI event type (#fluid_midi_event_type) - * @param chan MIDI channel number (0 to MIDI channel count - 1) - * @param param1 MIDI event first parameter (depends on type) - * @param param2 MIDI event second parameter (depends on type) - * @return FLUID_OK on success, FLUID_FAILED otherwise - */ -static int -fluid_synth_queue_midi_event (fluid_synth_t* synth, int type, int chan, - int param1, int param2) -{ -#if 0 - fluid_event_queue_t *queue; - fluid_event_queue_elem_t *event; - - event = fluid_synth_get_event_elem (synth, &queue); - if (!event) return FLUID_FAILED; - - event->type = FLUID_EVENT_QUEUE_ELEM_MIDI; - event->midi.type = type; - event->midi.channel = chan; - event->midi.param1 = param1; - event->midi.param2 = param2; - - fluid_event_queue_next_inptr (queue); -#endif - return FLUID_OK; -} - -/** - * Queues a generator assignment event to the FluidSynth synthesis thread. - * @param synth FluidSynth instance - * @param chan MIDI channel number (0 to MIDI channel count - 1) - * @param param Generator ID (#fluid_gen_type) - * @param value Value to assign to generator - * @param absolute TRUE if value is an absolute assignment, FALSE for relative - * @return FLUID_OK on success, FLUID_FAILED otherwise - */ -static int -fluid_synth_queue_gen_event (fluid_synth_t* synth, int chan, - int param, float value, int absolute) -{ -#if 0 - fluid_event_queue_t *queue; - fluid_event_queue_elem_t *event; - - event = fluid_synth_get_event_elem (synth, &queue); - if (!event) return FLUID_FAILED; - - event->type = FLUID_EVENT_QUEUE_ELEM_GEN; - event->gen.channel = chan; - event->gen.param = param; - event->gen.value = value; - event->gen.absolute = absolute; - - fluid_event_queue_next_inptr (queue); -#endif - return FLUID_OK; -} - -/** - * Queues an event with an integer value payload. - * @param synth FluidSynth instance - * @param type Event type (#fluid_event_queue_elem) - * @param val Event value - * @return FLUID_OK on success, FLUID_FAILED otherwise - */ -static int -fluid_synth_queue_int_event (fluid_synth_t* synth, int type, int val) -{ -#if 0 - fluid_event_queue_t *queue; - fluid_event_queue_elem_t *event; - - event = fluid_synth_get_event_elem (synth, &queue); - if (!event) return FLUID_FAILED; - - event->type = type; - event->ival = val; - - fluid_event_queue_next_inptr (queue); -#endif - return FLUID_OK; -} - -#if 0 -/* Gets called when a thread ends, which has been assigned a queue */ -static void -fluid_synth_thread_queue_destroy_notify (void *data) -{ - fluid_event_queue_t *queue = data; - fluid_synth_t *synth = queue->userdata; - - /* Queues are not freed (can't be thread safe without locking in synth thread), - * added to pool for potential future use */ - fluid_rec_mutex_lock (synth->mutex); /* ++ lock queue_pool */ - synth->queue_pool = fluid_list_prepend (synth->queue_pool, queue); - fluid_rec_mutex_unlock (synth->mutex); /* -- unlock queue_pool */ -} -#endif - /** * Send a note-on event to a FluidSynth object. * @param synth FluidSynth instance @@ -1390,12 +902,7 @@ fluid_synth_noteon(fluid_synth_t* synth, int chan, int key, int vel) fluid_return_val_if_fail (vel >= 0 && vel <= 127, FLUID_FAILED); FLUID_API_ENTRY_CHAN(FLUID_FAILED); -#if 0 - if (fluid_synth_should_queue (synth)) - result = fluid_synth_queue_midi_event (synth, NOTE_ON, chan, key, vel); - else -#endif - result = fluid_synth_noteon_LOCAL (synth, chan, key, vel); + result = fluid_synth_noteon_LOCAL (synth, chan, key, vel); FLUID_API_RETURN(result); } @@ -1446,12 +953,7 @@ fluid_synth_noteoff(fluid_synth_t* synth, int chan, int key) fluid_return_val_if_fail (key >= 0 && key <= 127, FLUID_FAILED); FLUID_API_ENTRY_CHAN(FLUID_FAILED); -#if 0 - if (fluid_synth_should_queue (synth)) - result = fluid_synth_queue_midi_event (synth, NOTE_OFF, chan, key, 0); - else -#endif - result = fluid_synth_noteoff_LOCAL (synth, chan, key); + result = fluid_synth_noteoff_LOCAL (synth, chan, key); FLUID_API_RETURN(result); } @@ -1525,10 +1027,7 @@ fluid_synth_cc(fluid_synth_t* synth, int chan, int num, int val) FLUID_LOG(FLUID_INFO, "cc\t%d\t%d\t%d", chan, num, val); fluid_channel_set_cc (synth->channel[chan], num, val); - - if (fluid_synth_should_queue (synth)) - result = fluid_synth_queue_midi_event (synth, CONTROL_CHANGE, chan, num, 0); - else result = fluid_synth_cc_LOCAL (synth, chan, num); + result = fluid_synth_cc_LOCAL (synth, chan, num); FLUID_API_RETURN(result); } @@ -1566,12 +1065,12 @@ fluid_synth_cc_LOCAL (fluid_synth_t* synth, int channum, int num) { int data = (value << 7) + fluid_channel_get_cc (chan, DATA_ENTRY_LSB); - if (fluid_atomic_int_get (&chan->nrpn_active)) /* NRPN is active? */ + if (chan->nrpn_active) /* NRPN is active? */ { /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */ if ((fluid_channel_get_cc (chan, NRPN_MSB) == 120) && (fluid_channel_get_cc (chan, NRPN_LSB) < 100)) { - nrpn_select = fluid_atomic_int_get (&chan->nrpn_select); + nrpn_select = chan->nrpn_select; if (nrpn_select < GEN_LAST) { @@ -1579,7 +1078,7 @@ fluid_synth_cc_LOCAL (fluid_synth_t* synth, int channum, int num) fluid_synth_set_gen_LOCAL (synth, channum, nrpn_select, val, FALSE); } - fluid_atomic_int_set (&chan->nrpn_select, 0); /* Reset to 0 */ + chan->nrpn_select = 0; /* Reset to 0 */ } } else if (fluid_channel_get_cc (chan, RPN_MSB) == 0) /* RPN is active: MSB = 0? */ @@ -1616,28 +1115,28 @@ fluid_synth_cc_LOCAL (fluid_synth_t* synth, int channum, int num) } case NRPN_MSB: fluid_channel_set_cc (chan, NRPN_LSB, 0); - fluid_atomic_int_set (&chan->nrpn_select, 0); - fluid_atomic_int_set (&chan->nrpn_active, 1); + chan->nrpn_select = 0; + chan->nrpn_active = 1; break; case NRPN_LSB: /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */ if (fluid_channel_get_cc (chan, NRPN_MSB) == 120) { if (value == 100) { - fluid_atomic_int_add (&chan->nrpn_select, 100); + chan->nrpn_select += 100; } else if (value == 101) { - fluid_atomic_int_add (&chan->nrpn_select, 1000); + chan->nrpn_select += 1000; } else if (value == 102) { - fluid_atomic_int_add (&chan->nrpn_select, 10000); + chan->nrpn_select += 10000; } else if (value < 100) { - fluid_atomic_int_add (&chan->nrpn_select, value); + chan->nrpn_select += value; } } - fluid_atomic_int_set (&chan->nrpn_active, 1); + chan->nrpn_active = 1; break; case RPN_MSB: case RPN_LSB: - fluid_atomic_int_set (&chan->nrpn_active, 0); + chan->nrpn_active = 0; break; default: return fluid_synth_modulate_voices_LOCAL (synth, channum, 1, num); @@ -1672,7 +1171,9 @@ fluid_synth_get_cc(fluid_synth_t* synth, int chan, int num, int* pval) static int fluid_synth_update_device_id (fluid_synth_t *synth, char *name, int value) { - fluid_atomic_int_set (&synth->device_id, value); + fluid_synth_api_enter(synth); + synth->device_id = value; + fluid_synth_api_exit(synth); return 0; } @@ -1963,10 +1464,7 @@ fluid_synth_all_notes_off(fluid_synth_t* synth, int chan) fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED); - if (fluid_synth_should_queue (synth)) - return fluid_synth_queue_midi_event (synth, CONTROL_CHANGE, chan, - ALL_NOTES_OFF, 0); - else return fluid_synth_all_notes_off_LOCAL (synth, chan); + return fluid_synth_all_notes_off_LOCAL (synth, chan); } /* Local synthesis thread variant of all notes off */ @@ -1994,13 +1492,11 @@ fluid_synth_all_notes_off_LOCAL(fluid_synth_t* synth, int chan) int fluid_synth_all_sounds_off(fluid_synth_t* synth, int chan) { - fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); - fluid_return_val_if_fail (chan >= 0 && chan < synth->midi_channels, FLUID_FAILED); + int result; + FLUID_API_ENTRY_CHAN(FLUID_FAILED); - if (fluid_synth_should_queue (synth)) - return fluid_synth_queue_midi_event (synth, CONTROL_CHANGE, chan, - ALL_SOUND_OFF, 0); - else return fluid_synth_all_sounds_off_LOCAL (synth, chan); + result = fluid_synth_all_sounds_off_LOCAL (synth, chan); + FLUID_API_RETURN(result); } /* Local synthesis thread variant of all sounds off */ @@ -2031,9 +1527,7 @@ fluid_synth_system_reset(fluid_synth_t* synth) int result; fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); fluid_synth_api_enter(synth); - if (fluid_synth_should_queue (synth)) - result = fluid_synth_queue_midi_event (synth, MIDI_SYSTEM_RESET, 0, 0, 0); - else result = fluid_synth_system_reset_LOCAL (synth); + result = fluid_synth_system_reset_LOCAL (synth); FLUID_API_RETURN(result); } @@ -2123,9 +1617,7 @@ fluid_synth_channel_pressure(fluid_synth_t* synth, int chan, int val) fluid_channel_set_channel_pressure (synth->channel[chan], val); - if (fluid_synth_should_queue (synth)) - result = fluid_synth_queue_midi_event (synth, CHANNEL_PRESSURE, chan, 0, 0); - else result = fluid_synth_update_channel_pressure_LOCAL (synth, chan); + result = fluid_synth_update_channel_pressure_LOCAL (synth, chan); FLUID_API_RETURN(result); } @@ -2155,9 +1647,7 @@ fluid_synth_pitch_bend(fluid_synth_t* synth, int chan, int val) fluid_channel_set_pitch_bend (synth->channel[chan], val); - if (fluid_synth_should_queue (synth)) - result = fluid_synth_queue_midi_event (synth, PITCH_BEND, chan, 0, 0); - else result = fluid_synth_update_pitch_bend_LOCAL (synth, chan); + result = fluid_synth_update_pitch_bend_LOCAL (synth, chan); FLUID_API_RETURN(result); } @@ -2205,10 +1695,7 @@ fluid_synth_pitch_wheel_sens(fluid_synth_t* synth, int chan, int val) fluid_channel_set_pitch_wheel_sensitivity (synth->channel[chan], val); - if (fluid_synth_should_queue (synth)) - result = fluid_synth_queue_midi_event (synth, RPN_LSB, chan, - RPN_PITCH_BEND_RANGE, val); - else result = fluid_synth_update_pitch_wheel_sens_LOCAL (synth, chan); + result = fluid_synth_update_pitch_wheel_sens_LOCAL (synth, chan); FLUID_API_RETURN(result); } @@ -2247,8 +1734,6 @@ fluid_synth_get_pitch_wheel_sens(fluid_synth_t* synth, int chan, int* pval) static int fluid_synth_set_preset (fluid_synth_t *synth, int chan, fluid_preset_t *preset) { -// fluid_event_queue_t *queue; -// fluid_event_queue_elem_t *event; fluid_channel_t *channel; fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); @@ -2256,24 +1741,7 @@ fluid_synth_set_preset (fluid_synth_t *synth, int chan, fluid_preset_t *preset) channel = synth->channel[chan]; -#if 0 - if (fluid_synth_should_queue (synth)) - { - event = fluid_synth_get_event_elem (synth, &queue); - if (!event) return FLUID_FAILED; - - fluid_atomic_pointer_set (&channel->shadow_preset, preset); - - event->type = FLUID_EVENT_QUEUE_ELEM_PRESET; - event->preset.channel = chan; - event->preset.preset = preset; - - fluid_event_queue_next_inptr (queue); - return FLUID_OK; - } - else -#endif - return fluid_channel_set_preset (channel, preset); + return fluid_channel_set_preset (channel, preset); } /* Get a preset by SoundFont, bank and program numbers. @@ -2698,14 +2166,8 @@ fluid_synth_set_gain(fluid_synth_t* synth, float gain) fluid_clip (gain, 0.0f, 10.0f); - fluid_atomic_float_set (&synth->gain, gain); - -#if 0 - if (fluid_synth_should_queue (synth)) - fluid_synth_queue_int_event (synth, FLUID_EVENT_QUEUE_ELEM_UPDATE_GAIN, 0); /* Integer value not actually used */ - else -#endif - fluid_synth_update_gain_LOCAL (synth); + synth->gain = gain; + fluid_synth_update_gain_LOCAL (synth); fluid_synth_api_exit(synth); } @@ -2717,7 +2179,7 @@ fluid_synth_update_gain_LOCAL(fluid_synth_t* synth) float gain; int i; - gain = fluid_atomic_float_get (&synth->gain); + gain = synth->gain; for (i = 0; i < synth->polyphony; i++) { @@ -2738,7 +2200,7 @@ fluid_synth_get_gain(fluid_synth_t* synth) fluid_return_val_if_fail (synth != NULL, 0.0); fluid_synth_api_enter(synth); - result = fluid_atomic_float_get (&synth->gain); + result = synth->gain; FLUID_API_RETURN(result); } @@ -2767,22 +2229,18 @@ fluid_synth_set_polyphony(fluid_synth_t* synth, int polyphony) fluid_return_val_if_fail (polyphony >= 1 && polyphony <= 65535, FLUID_FAILED); fluid_synth_api_enter(synth); - fluid_atomic_int_set (&synth->shadow_polyphony, polyphony); + fluid_synth_update_polyphony_LOCAL(synth, polyphony); - if (fluid_synth_should_queue (synth)) - result = fluid_synth_queue_int_event (synth, FLUID_EVENT_QUEUE_ELEM_POLYPHONY, 0); - else result = fluid_synth_update_polyphony_LOCAL (synth); FLUID_API_RETURN(result); } /* Called by synthesis thread to update the polyphony value */ static int -fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth) +fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth, int new_polyphony) { fluid_voice_t *voice; - int i, new_polyphony; + int i; - new_polyphony = fluid_atomic_int_get (&synth->shadow_polyphony); if (new_polyphony > synth->nvoice) { /* Create more voices */ fluid_voice_t** new_voices = FLUID_REALLOC(synth->voice, @@ -2825,7 +2283,7 @@ fluid_synth_get_polyphony(fluid_synth_t* synth) fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); fluid_synth_api_enter(synth); - result = fluid_atomic_int_get (&synth->shadow_polyphony); + result = synth->polyphony; FLUID_API_RETURN(result); } @@ -2847,7 +2305,7 @@ fluid_synth_get_active_voice_count(fluid_synth_t* synth) fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); fluid_synth_api_enter(synth); - result = fluid_atomic_int_get (&synth->active_voice_count); + result = synth->active_voice_count; FLUID_API_RETURN(result); } @@ -3299,26 +2757,8 @@ fluid_synth_render_blocks(fluid_synth_t* synth, int blockcount) fluid_check_fpe("fluid_sample_timer_process"); -#if 0 - /* Process queued events */ - for (i = 0; i < FLUID_MAX_EVENT_QUEUES; i++) - { - if (synth->queues[i]) - fluid_synth_process_event_queue_LOCAL (synth, synth->queues[i]); - else break; /* First NULL ends the array (values are never set to NULL) */ - } -#endif - - //fluid_rvoice_mixer_set_mix_fx(synth->eventhandler->mixer, - // !do_not_mix_fx_to_out); blockcount = fluid_rvoice_mixer_render(synth->eventhandler->mixer, blockcount); -#if 0 - /* Signal return queue thread if there are any events pending */ - if (fluid_atomic_int_get (&synth->return_queue->count) > 0) - fluid_cond_signal (synth->return_queue_cond); -#endif - /* Testcase, that provokes a denormal floating point error */ #if 0 {float num=1;while (num != 0){num*=0.5;};}; @@ -3328,161 +2768,6 @@ fluid_synth_render_blocks(fluid_synth_t* synth, int blockcount) return blockcount; } -#if 0 -/* Core thread function (processes voices in parallel to primary synthesis thread) */ -static void -fluid_synth_core_thread_func (void* data) -{ - fluid_synth_t *synth = data; - fluid_voice_t *voice; - int i, count, start_index; - - /* We do this, rather than adding an "if (first_run)" statement to the while loop */ - fluid_cond_mutex_lock (synth->core_mutex); /* ++ Lock core variables */ - synth->core_inprogress++; - fluid_cond_mutex_unlock (synth->core_mutex); /* -- Unlock core variables */ - - /* Loop until delete_fluid_synth() kills off core threads */ - while (synth->cores_active) - { - fluid_cond_mutex_lock (synth->core_mutex); /* ++ Lock core variables */ - - synth->core_inprogress--; - - /* Wakeup primary synthesis thread if it is waiting for last and we are it */ - if (synth->core_waiting_for_last && synth->core_inprogress == 0) - fluid_cond_signal (synth->core_wait_last_cond); - - /* Wait until there is core work */ - while (!synth->core_work && synth->cores_active) - fluid_cond_wait (synth->core_cond, synth->core_mutex); - - if (!synth->cores_active) - { - fluid_cond_mutex_unlock (synth->core_mutex); /* -- Unlock core variables */ - break; - } - - synth->core_inprogress++; - - fluid_cond_mutex_unlock (synth->core_mutex); /* -- Unlock core variables */ - - /* Voice processing loop (lock free) */ - while (TRUE) - { - /* Look for next active voice to process (in a lock free manner) */ - do - { - i = fluid_atomic_int_get (&synth->core_voice_index); - - for (start_index = i; i < synth->polyphony; i++) - { - voice = synth->voice[i]; - - if (_PLAYING (voice)) - { - if (fluid_atomic_int_compare_and_exchange (&synth->core_voice_index, - start_index, i + 1)) - goto got_voice; - - break; /* compare and exchange failed (another thread grabbed the voice first) */ - } - } - } - while (i < synth->polyphony); - - /* No more voices to process */ - fluid_atomic_int_set (&synth->core_voice_index, synth->polyphony); - fluid_atomic_int_set (&synth->core_work, FALSE); - break; - -got_voice: - - /* Synthesize the voice */ - count = fluid_voice_write (voice, &synth->core_bufs[i * FLUID_BUFSIZE]); - - /* Assign the processed voice to the same voicebuf index (if there was any audio) */ - if (count > 0) synth->core_voice_processed[i] = voice; - } /* while (TRUE) - Lock free voice processing loop */ - } /* while (synth->cores_active) */ -} -#endif - -/* Process events in an event queue */ -static FLUID_INLINE void -fluid_synth_process_event_queue_LOCAL (fluid_synth_t *synth, - fluid_event_queue_t *queue) -{ - fluid_event_queue_elem_t *event; - - while ((event = fluid_event_queue_get_outptr (queue))) - { - switch (event->type) - { - case FLUID_EVENT_QUEUE_ELEM_MIDI: - switch (event->midi.type) - { - case NOTE_ON: - fluid_synth_noteon_LOCAL (synth, event->midi.channel, - event->midi.param1, event->midi.param2); - break; - case NOTE_OFF: - fluid_synth_noteoff_LOCAL (synth, event->midi.channel, - event->midi.param1); - break; - case CONTROL_CHANGE: - fluid_synth_cc_LOCAL (synth, event->midi.channel, event->midi.param1); - break; - case MIDI_SYSTEM_RESET: - fluid_synth_system_reset_LOCAL (synth); - break; - case CHANNEL_PRESSURE: - fluid_synth_update_channel_pressure_LOCAL (synth, event->midi.channel); - break; - case PITCH_BEND: - fluid_synth_update_pitch_bend_LOCAL (synth, event->midi.channel); - break; - case RPN_LSB: - switch (event->midi.param1) - { - case RPN_PITCH_BEND_RANGE: - fluid_synth_update_pitch_wheel_sens_LOCAL (synth, event->midi.channel); - break; - } - break; - } - break; - case FLUID_EVENT_QUEUE_ELEM_UPDATE_GAIN: - fluid_synth_update_gain_LOCAL (synth); - break; - case FLUID_EVENT_QUEUE_ELEM_POLYPHONY: - fluid_synth_update_polyphony_LOCAL (synth); - break; - case FLUID_EVENT_QUEUE_ELEM_GEN: - fluid_synth_set_gen_LOCAL (synth, event->gen.channel, event->gen.param, - event->gen.value, event->gen.absolute); - break; - case FLUID_EVENT_QUEUE_ELEM_PRESET: - fluid_channel_set_preset (synth->channel[event->preset.channel], - event->preset.preset); - break; - case FLUID_EVENT_QUEUE_ELEM_STOP_VOICES: - fluid_synth_stop_LOCAL (synth, event->ival); - break; - case FLUID_EVENT_QUEUE_ELEM_SET_TUNING: - fluid_synth_set_tuning_LOCAL (synth, event->set_tuning.channel, - event->set_tuning.tuning, event->set_tuning.apply); - break; - case FLUID_EVENT_QUEUE_ELEM_REPL_TUNING: - fluid_synth_replace_tuning_LOCAL (synth, event->repl_tuning.old_tuning, - event->repl_tuning.new_tuning, - event->repl_tuning.apply, TRUE); - break; - } - - fluid_event_queue_next_outptr (queue); - } -} static int fluid_synth_update_overflow (fluid_synth_t *synth, char *name, fluid_real_t value) @@ -3615,8 +2900,7 @@ fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan, } if (fluid_voice_init (voice, sample, channel, key, vel, - synth->storeid, ticks, - fluid_atomic_float_get (&synth->gain)) != FLUID_OK) { + synth->storeid, ticks, synth->gain) != FLUID_OK) { FLUID_LOG(FLUID_WARN, "Failed to initialize voice"); FLUID_API_RETURN(NULL); } @@ -4173,7 +3457,7 @@ fluid_synth_get_channel_preset(fluid_synth_t* synth, int chan) FLUID_API_ENTRY_CHAN(NULL); channel = synth->channel[chan]; - result = fluid_atomic_pointer_get (&channel->shadow_preset); + result = channel->preset; fluid_synth_api_exit(synth); return result; } @@ -4204,7 +3488,7 @@ fluid_synth_get_channel_info (fluid_synth_t *synth, int chan, FLUID_API_ENTRY_CHAN(FLUID_FAILED); channel = synth->channel[chan]; - preset = fluid_atomic_pointer_get (&channel->shadow_preset); + preset = channel->preset; if (preset) { @@ -4740,7 +4024,6 @@ double fluid_synth_get_cpu_load(fluid_synth_t* synth) { fluid_return_val_if_fail (synth != NULL, 0); - // TODO: Should this one continue to be atomic? return fluid_atomic_float_get (&synth->cpu_load); } @@ -4791,25 +4074,7 @@ fluid_synth_replace_tuning_LOCK (fluid_synth_t* synth, fluid_tuning_t *tuning, if (old_tuning) { if (!fluid_tuning_unref (old_tuning, 1)) /* -- unref old tuning */ { /* Replace old tuning if present */ -#if 0 - if (fluid_synth_should_queue (synth)) - { - event = fluid_synth_get_event_elem (synth, &queue); - - if (event) - { - fluid_tuning_ref (tuning); /* ++ ref new tuning for event */ - - event->type = FLUID_EVENT_QUEUE_ELEM_REPL_TUNING; - event->repl_tuning.apply = apply; - event->repl_tuning.old_tuning = old_tuning; - event->repl_tuning.new_tuning = tuning; - fluid_event_queue_next_inptr (queue); - } - } - else -#endif - fluid_synth_replace_tuning_LOCAL (synth, old_tuning, tuning, apply, FALSE); + fluid_synth_replace_tuning_LOCAL (synth, old_tuning, tuning, apply, FALSE); } } @@ -4842,49 +4107,11 @@ fluid_synth_replace_tuning_LOCAL (fluid_synth_t *synth, fluid_tuning_t *old_tuni } /* Send unref old tuning event if any unrefs */ -#if 0 - if (old_tuning_unref > 0) - { - event = fluid_event_queue_get_inptr (synth->return_queue); - - if (event) - { - event->type = FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING; - event->unref_tuning.tuning = old_tuning; - event->unref_tuning.count = old_tuning_unref; - fluid_event_queue_next_inptr (synth->return_queue); - } - else - { /* Just unref it in synthesis thread if queue is full */ - fluid_tuning_unref (old_tuning, old_tuning_unref); - FLUID_LOG (FLUID_ERR, "Synth return event queue full"); - } - } -#else if (old_tuning && old_tuning_unref) fluid_tuning_unref (old_tuning, old_tuning_unref); -#endif if (!unref_new || !new_tuning) return; -#if 0 - /* Send new tuning unref if requested (for replace queue event for example) */ - event = fluid_event_queue_get_inptr (synth->return_queue); - - if (event) - { - event->type = FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING; - event->unref_tuning.tuning = new_tuning; - event->unref_tuning.count = 1; - fluid_event_queue_next_inptr (synth->return_queue); - } - else - { /* Just unref it in synthesis thread if queue is full */ - fluid_tuning_unref (new_tuning, 1); - FLUID_LOG (FLUID_ERR, "Synth return event queue full"); - } -#else fluid_tuning_unref (new_tuning, 1); -#endif } /* Update voice tunings in realtime */ @@ -5161,29 +4388,8 @@ fluid_synth_activate_tuning(fluid_synth_t* synth, int chan, int bank, int prog, if (!tuning) FLUID_API_RETURN(FLUID_FAILED); -#if 0 - if (fluid_synth_should_queue (synth)) - { - event = fluid_synth_get_event_elem (synth, &queue); - - if (event) - { - fluid_tuning_ref (tuning); /* ++ ref new tuning for event */ - - event->type = FLUID_EVENT_QUEUE_ELEM_SET_TUNING; - event->set_tuning.apply = apply; - event->set_tuning.channel = chan; - event->set_tuning.tuning = tuning; - fluid_event_queue_next_inptr (queue); - } - else retval = FLUID_FAILED; - } - else -#endif - { - fluid_tuning_ref (tuning); /* ++ ref new tuning for following function */ - retval = fluid_synth_set_tuning_LOCAL (synth, chan, tuning, apply); - } + fluid_tuning_ref (tuning); /* ++ ref new tuning for following function */ + retval = fluid_synth_set_tuning_LOCAL (synth, chan, tuning, apply); fluid_tuning_unref (tuning, 1); /* -- unref for outside of lock */ @@ -5195,7 +4401,6 @@ static int fluid_synth_set_tuning_LOCAL (fluid_synth_t *synth, int chan, fluid_tuning_t *tuning, int apply) { -// fluid_event_queue_elem_t *event; fluid_tuning_t *old_tuning; fluid_channel_t *channel; @@ -5209,24 +4414,7 @@ fluid_synth_set_tuning_LOCAL (fluid_synth_t *synth, int chan, /* Send unref old tuning event */ if (old_tuning) { -#if 0 - event = fluid_event_queue_get_inptr (synth->return_queue); - - if (event) - { - event->type = FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING; - event->unref_tuning.tuning = old_tuning; - event->unref_tuning.count = 1; - fluid_event_queue_next_inptr (synth->return_queue); - } - else - { /* Just unref it in synthesis thread if queue is full */ - fluid_tuning_unref (old_tuning, 1); - FLUID_LOG (FLUID_ERR, "Synth return event queue full"); - } -#else fluid_tuning_unref (old_tuning, 1); -#endif } @@ -5260,30 +4448,11 @@ fluid_synth_reset_tuning(fluid_synth_t* synth, int chan) int fluid_synth_deactivate_tuning(fluid_synth_t* synth, int chan, int apply) { - //fluid_event_queue_elem_t *event; - //fluid_event_queue_t *queue; int retval = FLUID_OK; FLUID_API_ENTRY_CHAN(FLUID_FAILED); -#if 0 - if (fluid_synth_should_queue (synth)) - { - event = fluid_synth_get_event_elem (synth, &queue); - - if (event) - { - event->type = FLUID_EVENT_QUEUE_ELEM_SET_TUNING; - event->set_tuning.apply = apply; - event->set_tuning.channel = chan; - event->set_tuning.tuning = NULL; - fluid_event_queue_next_inptr (queue); - } - else retval = FLUID_FAILED; - } - else -#endif - retval = fluid_synth_set_tuning_LOCAL (synth, chan, NULL, apply); + retval = fluid_synth_set_tuning_LOCAL (synth, chan, NULL, apply); FLUID_API_RETURN(retval); } @@ -5325,11 +4494,8 @@ fluid_synth_tuning_iteration_next(fluid_synth_t* synth, int* bank, int* prog) b = (p >> 8) & 0xFF; p &= 0xFF; - //fluid_rec_mutex_lock (synth->mutex); /* ++ lock tunings */ - if (!synth->tuning) { - //fluid_rec_mutex_unlock (synth->mutex); /* -- unlock tunings */ FLUID_API_RETURN(0); } @@ -5354,8 +4520,6 @@ fluid_synth_tuning_iteration_next(fluid_synth_t* synth, int* bank, int* prog) } } - //fluid_rec_mutex_unlock (synth->mutex); /* -- unlock tunings */ - FLUID_API_RETURN(0); } @@ -5378,8 +4542,6 @@ fluid_synth_tuning_dump(fluid_synth_t* synth, int bank, int prog, fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); fluid_synth_api_enter(synth); - //fluid_rec_mutex_lock (synth->mutex); /* ++ lock tunings */ - tuning = fluid_synth_get_tuning (synth, bank, prog); if (tuning) @@ -5394,8 +4556,6 @@ fluid_synth_tuning_dump(fluid_synth_t* synth, int bank, int prog, FLUID_MEMCPY (pitch, fluid_tuning_get_all (tuning), 128 * sizeof (double)); } - //fluid_rec_mutex_unlock (synth->mutex); /* unlock tunings */ - FLUID_API_RETURN(tuning ? FLUID_OK : FLUID_FAILED); } @@ -5526,18 +4686,10 @@ fluid_synth_getint(fluid_synth_t* synth, const char* name, int* val) int fluid_synth_set_gen(fluid_synth_t* synth, int chan, int param, float value) { -// int result; fluid_return_val_if_fail (param >= 0 && param < GEN_LAST, FLUID_FAILED); FLUID_API_ENTRY_CHAN(FLUID_FAILED); -#if 0 - if (fluid_synth_should_queue (synth)) { - result = fluid_synth_queue_gen_event (synth, chan, param, value, FALSE); - FLUID_API_RETURN(result); - } - else -#endif - fluid_synth_set_gen_LOCAL (synth, chan, param, value, FALSE); + fluid_synth_set_gen_LOCAL (synth, chan, param, value, FALSE); FLUID_API_RETURN(FLUID_OK); } @@ -5584,17 +4736,12 @@ fluid_synth_set_gen2(fluid_synth_t* synth, int chan, int param, float value, int absolute, int normalized) { float v; - int result; fluid_return_val_if_fail (param >= 0 && param < GEN_LAST, FLUID_FAILED); FLUID_API_ENTRY_CHAN(FLUID_FAILED); v = normalized ? fluid_gen_scale(param, value) : value; - if (fluid_synth_should_queue (synth)) { - result = (fluid_synth_queue_gen_event (synth, chan, param, v, absolute)); - FLUID_API_RETURN(result); - } - else fluid_synth_set_gen_LOCAL (synth, chan, param, v, absolute); + fluid_synth_set_gen_LOCAL (synth, chan, param, v, absolute); FLUID_API_RETURN(FLUID_OK); } @@ -5722,12 +4869,8 @@ fluid_synth_stop(fluid_synth_t* synth, unsigned int id) int result; fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); fluid_synth_api_enter(synth); - if (fluid_synth_should_queue (synth)) - result = fluid_synth_queue_int_event (synth, FLUID_EVENT_QUEUE_ELEM_STOP_VOICES, id); - else { - fluid_synth_stop_LOCAL (synth, id); - result = FLUID_OK; - } + fluid_synth_stop_LOCAL (synth, id); + result = FLUID_OK; FLUID_API_RETURN(result); } diff --git a/fluidsynth/src/synth/fluid_synth.h b/fluidsynth/src/synth/fluid_synth.h index 54b1c353..fae03f55 100644 --- a/fluidsynth/src/synth/fluid_synth.h +++ b/fluidsynth/src/synth/fluid_synth.h @@ -105,91 +105,31 @@ typedef struct _fluid_sfont_info_t { /* * fluid_synth_t * - * Mutual exclusion notes: + * Mutual exclusion notes (as of 1.1.2): * - * Set only once on init: - * ---------------------- - * verbose - * dump - * sample_rate (will be runtime change-able in the future) - * min_note_length_ticks - * midi_channels - * audio_channels - * audio_groups - * effects_channels - * start - * channel[] (Contents change) - * nvoice - * voice[] (Contents change) - * nbuf - * left_buf[], right_buf[] (Contents change) - * fx_left_buf[], fx_right_buf[] (Contents change) - * LADSPA_FxUnit (Contents change) - * cores - * core_threads[] - * bank_select (FIXME: pending implementation of SYSEX midi mode changes) + * All variables are considered belongning to the "public API" thread, + * which processes all MIDI, except for: * - * Single thread use only (modify only prior to synthesis): - * loaders<> - * midi_router + * ticks_since_start - atomic, set by rendering thread only + * cpu_load - atomic, set by rendering thread only + * cur, curmax, dither_index - used by rendering thread only + * LADSPA_FxUnit - same instance copied in rendering thread. Synchronising handled internally (I think...?). * - * Mutex protected: - * settings{} (has its own mutex) - * sfont_info<> - * tuning - * sfont_id - * reverb_roomsize, reverb_damping, reverb_width, reverb_level - * chorus_nr, chorus_level, chorus_speed, chorus_depth, chorus_type - * - * Atomic operations: - * ---------------------- - * with_reverb - * with_chorus - * state - * gain - * cpu_load - * noteid - * storeid - * outbuf - * sample_timers - * - * Only synth thread changes (atomic operations for non-synth thread reads) - * ------------------------- - * ticks - * reverb{} - * chorus{} - * cur - * dither_index - * polyphony - * active_voice_count */ struct _fluid_synth_t { -#if 0 - fluid_thread_id_t synth_thread_id; /**< ID of the synthesis thread or FLUID_THREAD_ID_NULL if not yet set */ - fluid_private_t thread_queues; /**< Thread private data for event queues for each non-synthesis thread queuing events */ - fluid_event_queue_t *queues[FLUID_MAX_EVENT_QUEUES]; /**< Thread event queues (NULL for unused elements) */ -#endif - - fluid_rec_mutex_t mutex; /**< Lock for multi-thread sensitive variables (not used by synthesis process) */ + fluid_rec_mutex_t mutex; /**< Lock for public API */ int use_mutex; /**< Use mutex for all public API functions? */ - int public_api_count; /**< How many times the mutex is currently locked */ -#if 0 - fluid_list_t *queue_pool; /**< List of event queues whose threads have been destroyed and which can be re-used */ - fluid_event_queue_t *return_queue; /**< Event queue for events from synthesis thread to non-synthesis threads (memory frees, etc) */ - fluid_thread_t *return_queue_thread; /**< Return event queue processing thread */ - fluid_cond_mutex_t *return_queue_mutex; /**< Mutex for return queue condition */ - fluid_cond_t *return_queue_cond; /**< Return queue thread synchronization condition */ -#endif + int public_api_count; /**< How many times the mutex is currently locked */ + fluid_settings_t* settings; /**< the synthesizer settings */ int device_id; /**< Device ID used for SYSEX messages */ int polyphony; /**< Maximum polyphony */ - int shadow_polyphony; /**< Maximum polyphony shadow value (for non-synth threads) */ - int with_reverb; /**< Should the synth use the built-in reverb unit? */ - int with_chorus; /**< Should the synth use the built-in chorus unit? */ - int verbose; /**< Turn verbose mode on? */ - int dump; /**< Dump events to stdout to hook up a user interface? */ + int with_reverb; /**< Should the synth use the built-in reverb unit? */ + int with_chorus; /**< Should the synth use the built-in chorus unit? */ + int verbose; /**< Turn verbose mode on? */ + int dump; /**< Dump events to stdout to hook up a user interface? */ double sample_rate; /**< The sample rate */ int midi_channels; /**< the number of MIDI channels (>= 16) */ int bank_select; /**< the style of Bank Select MIDI messages */ @@ -214,17 +154,8 @@ struct _fluid_synth_t int active_voice_count; /**< count of active voices */ unsigned int noteid; /**< the id is incremented for every new note. it's used for noteoff's */ unsigned int storeid; -// int nbuf; /**< How many audio buffers are used? (depends on nr of audio channels / groups)*/ fluid_rvoice_eventhandler_t* eventhandler; -/* - fluid_real_t** left_buf; - fluid_real_t** right_buf; - fluid_real_t** fx_left_buf; - fluid_real_t** fx_right_buf; - fluid_revmodel_t* reverb; - fluid_chorus_t* chorus; -*/ float reverb_roomsize; /**< Shadow of reverb roomsize */ float reverb_damping; /**< Shadow of reverb damping */ float reverb_width; /**< Shadow of reverb width */ @@ -251,23 +182,6 @@ struct _fluid_synth_t unsigned int min_note_length_ticks; /**< If note-offs are triggered just after a note-on, they will be delayed */ int cores; /**< Number of CPU cores (1 by default) */ -#if 0 - fluid_thread_t **core_threads; /**< Array of core threads (cores - 1 in length) */ - unsigned char cores_active; /**< TRUE if core slave threads should remain active, FALSE to terminate them */ - - /* Multi-core variables (protected by core_mutex) */ - fluid_cond_mutex_t *core_mutex; /**< Mutex to protect all core_ variables and use with core_cond and core_wait_last_cond */ - fluid_cond_t *core_cond; /**< Thread condition for signaling core slave threads */ - int core_work; /**< Boolean: TRUE if there is work, FALSE otherwise */ - - /* Used in a lockless atomic fashion */ - int core_voice_index; /**< Next voice index to process */ - fluid_voice_t **core_voice_processed; /**< Array for processed voices */ - fluid_real_t *core_bufs; /**< Block containing audio buffers for each voice (FLUID_BUFSIZE in length each) */ - int core_inprogress; /**< Count of secondary core threads in progress */ - int core_waiting_for_last; /**< Boolean: Set to TRUE if primary synthesis thread is waiting for last slave thread to finish */ - fluid_cond_t *core_wait_last_cond; /**< Thread condition for signaling primary synthesis thread when last slave thread finishes */ -#endif #ifdef LADSPA fluid_LADSPA_FxUnit_t* LADSPA_FxUnit; /**< Effects unit for LADSPA support */ diff --git a/fluidsynth/src/synth/fluid_voice.c b/fluidsynth/src/synth/fluid_voice.c index 7350a076..aae5ffb1 100644 --- a/fluidsynth/src/synth/fluid_voice.c +++ b/fluidsynth/src/synth/fluid_voice.c @@ -214,6 +214,9 @@ fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample, * of IIR filters, position in sample etc) is initialized. */ int i; + if (voice->sample) + fluid_voice_off(voice); + voice->id = id; voice->chan = fluid_channel_get_num(channel); voice->key = (unsigned char) key; @@ -406,8 +409,8 @@ void fluid_voice_start(fluid_voice_t* voice) voice->status = FLUID_VOICE_ON; - /* Increment voice count atomically, for non-synth thread read access */ - fluid_atomic_int_add (&voice->channel->synth->active_voice_count, 1); + /* Increment voice count */ + voice->channel->synth->active_voice_count++; } void @@ -1212,8 +1215,8 @@ fluid_voice_off(fluid_voice_t* voice) voice->sample = NULL; } - /* Decrement voice count atomically, for non-synth thread read access */ - fluid_atomic_int_add (&voice->channel->synth->active_voice_count, -1); + /* Decrement voice count */ + voice->channel->synth->active_voice_count--; return FLUID_OK; }