Reverb and Chorus no longer queuing, to fix performance issues and now set under mutex.

This commit is contained in:
Josh Green 2009-12-16 02:48:07 +00:00
parent 93475f4d4c
commit a66d020aca
2 changed files with 20 additions and 170 deletions

View file

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

View file

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