diff --git a/fluidsynth/src/fluid_event_queue.h b/fluidsynth/src/fluid_event_queue.h index 2245709b..2197f096 100644 --- a/fluidsynth/src/fluid_event_queue.h +++ b/fluidsynth/src/fluid_event_queue.h @@ -35,8 +35,6 @@ enum fluid_event_queue_elem FLUID_EVENT_QUEUE_ELEM_GEN, /**< Generator event. Uses gen field of event value */ FLUID_EVENT_QUEUE_ELEM_PRESET, /**< Preset set event. Uses preset field of event value */ FLUID_EVENT_QUEUE_ELEM_STOP_VOICES, /**< Stop voices event. Uses ival field of event value */ - FLUID_EVENT_QUEUE_ELEM_REVERB, /**< Reverb set or return event. Uses reverb field of event value */ - FLUID_EVENT_QUEUE_ELEM_CHORUS, /**< Chorus set or return event. Uses chorus field of event value */ FLUID_EVENT_QUEUE_ELEM_FREE_PRESET, /**< Free preset return event. Uses pval field of event value */ FLUID_EVENT_QUEUE_ELEM_SET_TUNING, /**< Set tuning event. Uses set_tuning field of event value */ FLUID_EVENT_QUEUE_ELEM_REPL_TUNING, /**< Replace tuning event. Uses repl_tuning field of event value */ @@ -63,31 +61,6 @@ typedef struct fluid_preset_t *preset; /**< Preset to assign (synth thread owns) */ } fluid_event_preset_t; -/** - * Reverb assignment structure. - */ -typedef struct -{ - char set; /**< Bit 0: roomsize, 1: damping, 2: width, 3: level */ - float roomsize; - float damping; - float width; - float level; -} fluid_event_reverb_t; - -/** - * Chorus assignment structure. - */ -typedef struct -{ - char set; /**< Bit 0: nr, 1: type, 2: level, 3: speed, 4: depth */ - char nr; - char type; - float level; - float speed; - float depth; -} fluid_event_chorus_t; - /** * Tuning assignment event structure. */ @@ -138,8 +111,6 @@ typedef struct fluid_midi_event_t midi; /**< If type == FLUID_EVENT_QUEUE_ELEM_MIDI */ fluid_event_gen_t gen; /**< If type == FLUID_EVENT_QUEUE_ELEM_GEN */ fluid_event_preset_t preset; /**< If type == FLUID_EVENT_QUEUE_ELEM_PRESET */ - fluid_event_reverb_t reverb; /**< If type == FLUID_EVENT_QUEUE_ELEM_REVERB */ - fluid_event_chorus_t chorus; /**< If type == FLUID_EVENT_QUEUE_ELEM_CHORUS */ fluid_event_set_tuning_t set_tuning; /**< If type == FLUID_EVENT_QUEUE_ELEM_SET_TUNING */ fluid_event_repl_tuning_t repl_tuning; /**< If type == FLUID_EVENT_QUEUE_ELEM_REPL_TUNING */ fluid_event_unref_tuning_t unref_tuning; /**< If type == FLUID_EVENT_QUEUE_ELEM_UNREF_TUNING */ diff --git a/fluidsynth/src/fluid_synth.c b/fluidsynth/src/fluid_synth.c index 7f940723..3fba9d16 100644 --- a/fluidsynth/src/fluid_synth.c +++ b/fluidsynth/src/fluid_synth.c @@ -101,10 +101,6 @@ static fluid_sfont_info_t *new_fluid_sfont_info (fluid_synth_t *synth, fluid_sfont_t *sfont); static void fluid_synth_sfont_unref (fluid_synth_t *synth, fluid_sfont_t *sfont); static int fluid_synth_sfunload_callback(void* data, unsigned int msec); -static int fluid_synth_set_reverb_LOCAL(fluid_synth_t* synth, int set, double roomsize, - double damping, double width, double level); -static int fluid_synth_set_chorus_LOCAL(fluid_synth_t* synth, int set, int nr, float level, - float speed, float depth_ms, int type); static void fluid_synth_release_voice_on_same_note_LOCAL(fluid_synth_t* synth, int chan, int key); static fluid_tuning_t* fluid_synth_get_tuning(fluid_synth_t* synth, @@ -811,35 +807,6 @@ fluid_synth_return_event_process_thread (void* data) { switch (event->type) { - case FLUID_EVENT_QUEUE_ELEM_REVERB: /* Sync reverb shadow variables */ - if (event->reverb.set & FLUID_REVMODEL_SET_ROOMSIZE) - fluid_atomic_float_set (&synth->reverb_roomsize, event->reverb.roomsize); - - if (event->reverb.set & FLUID_REVMODEL_SET_DAMPING) - fluid_atomic_float_set (&synth->reverb_damping, event->reverb.damping); - - if (event->reverb.set & FLUID_REVMODEL_SET_WIDTH) - fluid_atomic_float_set (&synth->reverb_width, event->reverb.width); - - if (event->reverb.set & FLUID_REVMODEL_SET_LEVEL) - fluid_atomic_float_set (&synth->reverb_level, event->reverb.level); - break; - case FLUID_EVENT_QUEUE_ELEM_CHORUS: /* Sync chorus shadow variables */ - if (event->chorus.set & FLUID_CHORUS_SET_NR) - fluid_atomic_int_set (&synth->chorus_nr, event->chorus.nr); - - if (event->chorus.set & FLUID_CHORUS_SET_LEVEL) - fluid_atomic_float_set (&synth->chorus_level, event->chorus.level); - - if (event->chorus.set & FLUID_CHORUS_SET_SPEED) - fluid_atomic_float_set (&synth->chorus_speed, event->chorus.speed); - - if (event->chorus.set & FLUID_CHORUS_SET_DEPTH) - fluid_atomic_float_set (&synth->chorus_depth, event->chorus.depth); - - if (event->chorus.set & FLUID_CHORUS_SET_TYPE) - fluid_atomic_int_set (&synth->chorus_type, event->chorus.type); - break; case FLUID_EVENT_QUEUE_ELEM_FREE_PRESET: /* Preset free event */ preset = (fluid_preset_t *)(event->pval); sfont = preset->sfont; @@ -3384,16 +3351,6 @@ fluid_synth_process_event_queue_LOCAL (fluid_synth_t *synth, case FLUID_EVENT_QUEUE_ELEM_STOP_VOICES: fluid_synth_stop_LOCAL (synth, event->ival); break; - case FLUID_EVENT_QUEUE_ELEM_REVERB: - fluid_synth_set_reverb_LOCAL (synth, event->reverb.set, event->reverb.roomsize, - event->reverb.damping, event->reverb.width, - event->reverb.level); - break; - case FLUID_EVENT_QUEUE_ELEM_CHORUS: - fluid_synth_set_chorus_LOCAL (synth, event->chorus.set, event->chorus.nr, - event->chorus.level, event->chorus.speed, - event->chorus.depth, event->chorus.type); - 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); @@ -4244,6 +4201,9 @@ fluid_synth_set_reverb_preset(fluid_synth_t* synth, int num) * @param damping Reverb damping value (0.0-1.0) * @param width Reverb width value (0.0-100.0) * @param level Reverb level value (0.0-1.0) + * + * NOTE: Not realtime safe and therefore should not be called from synthesis + * context at the risk of stalling audio output. */ void fluid_synth_set_reverb(fluid_synth_t* synth, double roomsize, double damping, @@ -4262,22 +4222,22 @@ fluid_synth_set_reverb(fluid_synth_t* synth, double roomsize, double damping, * @param width Reverb width value (0.0-100.0) * @param level Reverb level value (0.0-1.0) * @return FLUID_OK on success, FLUID_FAILED otherwise + * + * NOTE: Not realtime safe and therefore should not be called from synthesis + * context at the risk of stalling audio output. */ int fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize, double damping, double width, double level) { - fluid_event_queue_t *queue; - fluid_event_queue_elem_t *event; - fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); if (!(set & FLUID_REVMODEL_SET_ALL)) set = FLUID_REVMODEL_SET_ALL; - /* Synth shadow values are set here so that they will be returned if querried, - * but shadow values are also updated via a return event to ensure they don't - * get out of sync, if this is called from synthesis and non-synthesis context. */ + /* Synth shadow values are set here so that they will be returned if querried */ + + fluid_rec_mutex_lock (synth->mutex); /* ++ Lock reverb */ if (set & FLUID_REVMODEL_SET_ROOMSIZE) fluid_atomic_float_set (&synth->reverb_roomsize, roomsize); @@ -4291,50 +4251,9 @@ fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize, if (set & FLUID_REVMODEL_SET_LEVEL) fluid_atomic_float_set (&synth->reverb_level, level); - if (fluid_synth_should_queue (synth)) - { - event = fluid_synth_get_event_elem (synth, &queue); - if (!event) return FLUID_FAILED; - - event->type = FLUID_EVENT_QUEUE_ELEM_REVERB; - event->reverb.set = set; - event->reverb.roomsize = roomsize; - event->reverb.damping = damping; - event->reverb.width = width; - event->reverb.level = level; - - fluid_event_queue_next_inptr (queue); - return FLUID_OK; - } - else return fluid_synth_set_reverb_LOCAL (synth, set, roomsize, damping, width, level); -} - -/* Local synthesis thread reverb set function */ -static int -fluid_synth_set_reverb_LOCAL(fluid_synth_t* synth, int set, double roomsize, - double damping, double width, double level) -{ - fluid_event_queue_elem_t *event; - fluid_revmodel_set (synth->reverb, set, roomsize, damping, width, level); - /* Send return reverb event to sync synth's copy of reverb parameters */ - - event = fluid_event_queue_get_inptr (synth->return_queue); - if (!event) - { - FLUID_LOG (FLUID_ERR, "Synth return event queue full"); - return FLUID_FAILED; - } - - event->type = FLUID_EVENT_QUEUE_ELEM_REVERB; - event->reverb.set = set; - event->reverb.roomsize = roomsize; - event->reverb.damping = damping; - event->reverb.width = width; - event->reverb.level = level; - - fluid_event_queue_next_inptr (synth->return_queue); + fluid_rec_mutex_unlock (synth->mutex); /* -- Unlock reverb */ return FLUID_OK; } @@ -4414,6 +4333,9 @@ fluid_synth_set_chorus_on(fluid_synth_t* synth, int on) * @param depth_ms Chorus depth (max value depends on synth sample rate, * 0.0-21.0 is safe for sample rate values up to 96KHz) * @param type Chorus waveform type (#fluid_chorus_mod) + * + * NOTE: Not realtime safe and therefore should not be called from synthesis + * context at the risk of stalling audio output. */ void fluid_synth_set_chorus(fluid_synth_t* synth, int nr, double level, @@ -4434,22 +4356,22 @@ fluid_synth_set_chorus(fluid_synth_t* synth, int nr, double level, * @param depth_ms Chorus depth (max value depends on synth sample rate, * 0.0-21.0 is safe for sample rate values up to 96KHz) * @param type Chorus waveform type (#fluid_chorus_mod) + * + * NOTE: Not realtime safe and therefore should not be called from synthesis + * context at the risk of stalling audio output. */ int fluid_synth_set_chorus_full(fluid_synth_t* synth, int set, int nr, double level, double speed, double depth_ms, int type) { - fluid_event_queue_t *queue; - fluid_event_queue_elem_t *event; - fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); if (!(set & FLUID_CHORUS_SET_ALL)) set = FLUID_CHORUS_SET_ALL; - /* Synth shadow values are set here so that they will be returned if querried, - * but shadow values are also updated via a return event to ensure they don't - * get out of sync, if this is called from synthesis and non-synthesis context. */ + /* Synth shadow values are set here so that they will be returned if querried */ + + fluid_rec_mutex_lock (synth->mutex); /* ++ Lock chorus */ if (set & FLUID_CHORUS_SET_NR) fluid_atomic_int_set (&synth->chorus_nr, nr); @@ -4466,52 +4388,9 @@ fluid_synth_set_chorus_full(fluid_synth_t* synth, int set, int nr, double level, if (set & FLUID_CHORUS_SET_TYPE) fluid_atomic_int_set (&synth->chorus_type, type); - if (fluid_synth_should_queue (synth)) - { - event = fluid_synth_get_event_elem (synth, &queue); - if (!event) return FLUID_FAILED; - - event->type = FLUID_EVENT_QUEUE_ELEM_CHORUS; - event->chorus.set = set; - event->chorus.nr = nr; - event->chorus.type = type; - event->chorus.level = level; - event->chorus.speed = speed; - event->chorus.depth = depth_ms; - - fluid_event_queue_next_inptr (queue); - return FLUID_OK; - } - else return fluid_synth_set_chorus_LOCAL (synth, set, nr, level, speed, depth_ms, type); -} - -/* Local synthesis thread version of set chorus function */ -static int -fluid_synth_set_chorus_LOCAL(fluid_synth_t* synth, int set, int nr, float level, - float speed, float depth_ms, int type) -{ - fluid_event_queue_elem_t *event; - fluid_chorus_set (synth->chorus, set, nr, level, speed, depth_ms, type); - /* Send return chorus event to sync synth's copy of chorus parameters */ - - event = fluid_event_queue_get_inptr (synth->return_queue); - if (!event) - { - FLUID_LOG (FLUID_ERR, "Synth return event queue full"); - return FLUID_FAILED; - } - - event->type = FLUID_EVENT_QUEUE_ELEM_CHORUS; - event->chorus.set = set; - event->chorus.nr = nr; - event->chorus.type = type; - event->chorus.level = level; - event->chorus.speed = speed; - event->chorus.depth = depth_ms; - - fluid_event_queue_next_inptr (synth->return_queue); + fluid_rec_mutex_unlock (synth->mutex); /* -- Unlock chorus */ return FLUID_OK; }