Code cleanup, and remove unnecessary atomicy and shadow variables,

now that the new architecture is in place.
This commit is contained in:
David Henningsson 2010-10-17 10:20:57 +00:00
parent 2e16dd1a46
commit 2479c03b78
5 changed files with 108 additions and 1127 deletions

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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