Merge branch 'fluid_atomic' of git://github.com/VolcanoMobile/fluidsynth into VolcanoMobile-fluid_atomic

This commit is contained in:
derselbst 2017-10-27 15:58:54 +02:00
commit db373f168f
15 changed files with 74 additions and 73 deletions

View file

@ -115,7 +115,7 @@ struct _fluid_ladspa_fx_t
fluid_rec_mutex_t api_mutex;
int state;
fluid_atomic_int_t state;
int pending_deactivation;
fluid_cond_mutex_t *run_finished_mutex;
@ -189,7 +189,7 @@ fluid_ladspa_fx_t *new_fluid_ladspa_fx(fluid_real_t sample_rate, int audio_group
/* Setup recursive mutex to protect access to public API */
fluid_rec_mutex_init(fx->api_mutex);
fx->state = FLUID_LADSPA_INACTIVE;
fluid_atomic_int_set(&fx->state, FLUID_LADSPA_INACTIVE);
/* add 0.5 to minimize overall casting error */
fx->sample_rate = (unsigned long)(sample_rate + 0.5);

View file

@ -44,7 +44,7 @@
typedef struct {
fluid_midi_driver_t driver;
HMIDIIN hmidiin;
int closing; /* Set to TRUE when closing driver, to prevent endless SYSEX lockup loop */
fluid_atomic_int_t closing; /* Set to TRUE when closing driver, to prevent endless SYSEX lockup loop */
fluid_thread_t *sysExAddThread; /* Thread for SYSEX re-add thread */
fluid_cond_mutex_t *mutex; /* Lock for condition */
@ -54,7 +54,7 @@ typedef struct {
MIDIHDR sysExHdrs[MIDI_SYSEX_BUF_COUNT];
/* TRUE for each MIDIHDR buffer which should be re-added to MIDI device */
int sysExHdrAdd[MIDI_SYSEX_BUF_COUNT];
fluid_atomic_int_t sysExHdrAdd[MIDI_SYSEX_BUF_COUNT];
/* Sysex data buffer */
unsigned char sysExBuf[MIDI_SYSEX_BUF_COUNT * MIDI_SYSEX_MAX_SIZE];
@ -129,7 +129,7 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
dev->hmidiin = NULL;
dev->driver.handler = handler;
dev->driver.data = data;
dev->closing = FALSE;
fluid_atomic_int_set (&dev->closing, FALSE);
/* get the device name. if none is specified, use the default device. */
if(fluid_settings_dupstr(settings, "midi.winmidi.device", &devname) != FLUID_OK || !devname) {
@ -181,7 +181,7 @@ new_fluid_winmidi_driver(fluid_settings_t* settings,
/* Prepare and add SYSEX buffers */
for (i = 0; i < MIDI_SYSEX_BUF_COUNT; i++)
{
dev->sysExHdrAdd[i] = FALSE;
fluid_atomic_int_set (&dev->sysExHdrAdd[i], FALSE);
hdr = &dev->sysExHdrs[i];
hdr->lpData = &dev->sysExBuf[i * MIDI_SYSEX_MAX_SIZE];
@ -305,7 +305,7 @@ fluid_winmidi_callback(HMIDIIN hmi, UINT wMsg, DWORD_PTR dwInstance,
break;
case MIM_LONGDATA: /* SYSEX data */
if (dev->closing) break; /* Prevent MIM_LONGDATA endless loop, don't re-add buffer if closing */
if (fluid_atomic_int_get (&dev->closing)) break; /* Prevent MIM_LONGDATA endless loop, don't re-add buffer if closing */
pMidiHdr = (LPMIDIHDR)dwParam1;
data = (unsigned char *)(pMidiHdr->lpData);

View file

@ -42,7 +42,7 @@
/* Private data for SEQUENCER */
struct _fluid_sequencer_t {
unsigned int startMs;
int currentMs;
fluid_atomic_int_t currentMs;
int useSystemTimer;
double scale; // ticks per second
fluid_list_t* clients;

View file

@ -229,7 +229,7 @@ new_fluid_rvoice_eventhandler(int is_threadsafe, int queuesize,
* that too many events are dispatched too early, causing incorrectly timed audio
*/
eventhandler->is_threadsafe = TRUE;
eventhandler->queue_stored = 0;
fluid_atomic_int_set(&eventhandler->queue_stored, 0);
eventhandler->finished_voices = new_fluid_ringbuffer(finished_voices_size,
sizeof(fluid_rvoice_t*));

View file

@ -50,7 +50,7 @@ void fluid_rvoice_event_dispatch(fluid_rvoice_event_t* event);
struct _fluid_rvoice_eventhandler_t {
int is_threadsafe; /* False for optimal performance, true for atomic operations */
fluid_ringbuffer_t* queue; /**< List of fluid_rvoice_event_t */
int queue_stored; /**< Extras pushed but not flushed */
fluid_atomic_int_t queue_stored; /**< Extras pushed but not flushed */
fluid_ringbuffer_t* finished_voices; /**< return queue from handler, list of fluid_rvoice_t* */
fluid_rvoice_mixer_t* mixer;
};

View file

@ -45,7 +45,7 @@ struct _fluid_mixer_buffers_t {
fluid_rvoice_t** finished_voices; /* List of voices who have finished */
int finished_voice_count;
int ready; /**< Atomic: buffers are ready for mixing */
fluid_atomic_int_t ready; /**< Atomic: buffers are ready for mixing */
int buf_blocks; /**< Number of blocks allocated in the buffers */
@ -87,8 +87,8 @@ struct _fluid_rvoice_mixer_t {
#ifdef ENABLE_MIXER_THREADS
// int sleeping_threads; /**< Atomic: number of threads currently asleep */
// int active_threads; /**< Atomic: number of threads in the thread loop */
int threads_should_terminate; /**< Atomic: Set to TRUE when threads should terminate */
int current_rvoice; /**< Atomic: for the threads to know next voice to */
fluid_atomic_int_t threads_should_terminate; /**< Atomic: Set to TRUE when threads should terminate */
fluid_atomic_int_t current_rvoice; /**< Atomic: for the threads to know next voice to */
fluid_cond_t* wakeup_threads; /**< Signalled when the threads should wake up */
fluid_cond_mutex_t* wakeup_threads_m; /**< wakeup_threads mutex companion */
fluid_cond_t* thread_ready; /**< Signalled from thread, when the thread has a buffer ready for mixing */

View file

@ -116,7 +116,7 @@ static void fluid_synth_stop_LOCAL (fluid_synth_t *synth, unsigned int id);
*/
/* has the synth module been initialized? */
static int fluid_synth_initialized = 0;
static fluid_atomic_int_t fluid_synth_initialized = 0;
static void fluid_synth_init(void);
static void init_dither(void);
@ -274,8 +274,6 @@ fluid_version_str (void)
static void
fluid_synth_init(void)
{
fluid_synth_initialized++;
#ifdef TRAP_ON_FPE
/* Turn on floating point exception traps */
feenableexcept (FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);
@ -441,18 +439,12 @@ fluid_synth_init(void)
static FLUID_INLINE unsigned int fluid_synth_get_ticks(fluid_synth_t* synth)
{
if (synth->eventhandler->is_threadsafe)
return fluid_atomic_int_get(&synth->ticks_since_start);
else
return synth->ticks_since_start;
return fluid_atomic_int_get(&synth->ticks_since_start);
}
static FLUID_INLINE void fluid_synth_add_ticks(fluid_synth_t* synth, int val)
{
if (synth->eventhandler->is_threadsafe)
fluid_atomic_int_add((int*) &synth->ticks_since_start, val);
else
synth->ticks_since_start += val;
fluid_atomic_int_add(&synth->ticks_since_start, val);
}
@ -557,9 +549,11 @@ new_fluid_synth(fluid_settings_t *settings)
double gain;
int i, nbuf;
int with_ladspa = 0;
int with_reverb = 0;
int with_chorus = 0;
/* initialize all the conversion tables and other stuff */
if (fluid_synth_initialized == 0)
if (fluid_atomic_int_compare_and_exchange(&fluid_synth_initialized, 0, 1))
{
char buf[64];
if (fluid_settings_str_equal (settings, "synth.volenv", "compliant"))
@ -597,8 +591,10 @@ new_fluid_synth(fluid_settings_t *settings)
synth->settings = settings;
fluid_settings_getint(settings, "synth.reverb.active", &synth->with_reverb);
fluid_settings_getint(settings, "synth.chorus.active", &synth->with_chorus);
fluid_settings_getint(settings, "synth.reverb.active", &with_reverb);
fluid_atomic_int_set(&synth->with_reverb, with_reverb);
fluid_settings_getint(settings, "synth.chorus.active", &with_chorus);
fluid_atomic_int_set(&synth->with_chorus, with_chorus);
fluid_settings_getint(settings, "synth.verbose", &synth->verbose);
fluid_settings_getint(settings, "synth.polyphony", &synth->polyphony);
@ -680,7 +676,7 @@ new_fluid_synth(fluid_settings_t *settings)
synth->sfont_info = NULL;
synth->sfont_hash = new_fluid_hashtable (NULL, NULL);
synth->noteid = 0;
synth->ticks_since_start = 0;
fluid_atomic_int_set(&synth->ticks_since_start, 0);
synth->tuning = NULL;
fluid_private_init(synth->tuning_iter);
@ -765,8 +761,8 @@ new_fluid_synth(fluid_settings_t *settings)
fluid_synth_update_overflow(synth, "", 0.0f);
fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_polyphony,
synth->polyphony, 0.0f);
fluid_synth_set_reverb_on(synth, synth->with_reverb);
fluid_synth_set_chorus_on(synth, synth->with_chorus);
fluid_synth_set_reverb_on(synth, fluid_atomic_int_get(&synth->with_reverb));
fluid_synth_set_chorus_on(synth, fluid_atomic_int_get(&synth->with_chorus));
synth->cur = FLUID_BUFSIZE;
synth->curmax = 0;
@ -2751,7 +2747,7 @@ fluid_synth_nwrite_float(fluid_synth_t* synth, int len,
synth->cur = num;
time = fluid_utime() - time;
cpu_load = 0.5 * (synth->cpu_load + time * synth->sample_rate / len / 10000.0);
cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
fluid_atomic_float_set (&synth->cpu_load, cpu_load);
if (!synth->eventhandler->is_threadsafe)
@ -2862,7 +2858,7 @@ fluid_synth_write_float(fluid_synth_t* synth, int len,
synth->cur = l;
time = fluid_utime() - time;
cpu_load = 0.5 * (synth->cpu_load + time * synth->sample_rate / len / 10000.0);
cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
fluid_atomic_float_set (&synth->cpu_load, cpu_load);
if (!synth->eventhandler->is_threadsafe)
@ -2987,7 +2983,7 @@ fluid_synth_write_s16(fluid_synth_t* synth, int len,
fluid_profile(FLUID_PROF_WRITE, prof_ref);
time = fluid_utime() - time;
cpu_load = 0.5 * (synth->cpu_load + time * synth->sample_rate / len / 10000.0);
cpu_load = 0.5 * (fluid_atomic_float_get(&synth->cpu_load) + time * synth->sample_rate / len / 10000.0);
fluid_atomic_float_set (&synth->cpu_load, cpu_load);
if (!synth->eventhandler->is_threadsafe)
@ -3995,16 +3991,16 @@ fluid_synth_set_reverb_full(fluid_synth_t* synth, int set, double roomsize,
fluid_synth_api_enter(synth);
if (set & FLUID_REVMODEL_SET_ROOMSIZE)
fluid_atomic_float_set (&synth->reverb_roomsize, roomsize);
synth->reverb_roomsize = roomsize;
if (set & FLUID_REVMODEL_SET_DAMPING)
fluid_atomic_float_set (&synth->reverb_damping, damping);
synth->reverb_damping = damping;
if (set & FLUID_REVMODEL_SET_WIDTH)
fluid_atomic_float_set (&synth->reverb_width, width);
synth->reverb_width = width;
if (set & FLUID_REVMODEL_SET_LEVEL)
fluid_atomic_float_set (&synth->reverb_level, level);
synth->reverb_level = level;
/* finally enqueue an rvoice event to the mixer to actual update reverb */
ret = fluid_rvoice_eventhandler_push5(synth->eventhandler,
@ -4026,7 +4022,7 @@ fluid_synth_get_reverb_roomsize(fluid_synth_t* synth)
double result;
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->reverb_roomsize);
result = synth->reverb_roomsize;
FLUID_API_RETURN(result);
}
@ -4042,7 +4038,7 @@ fluid_synth_get_reverb_damp(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->reverb_damping);
result = synth->reverb_damping;
FLUID_API_RETURN(result);
}
@ -4058,7 +4054,7 @@ fluid_synth_get_reverb_level(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->reverb_level);
result = synth->reverb_level;
FLUID_API_RETURN(result);
}
@ -4074,7 +4070,7 @@ fluid_synth_get_reverb_width(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->reverb_width);
result = synth->reverb_width;
FLUID_API_RETURN(result);
}
@ -4186,19 +4182,19 @@ fluid_synth_set_chorus_full(fluid_synth_t* synth, int set, int nr, double level,
fluid_synth_api_enter(synth);
if (set & FLUID_CHORUS_SET_NR)
fluid_atomic_int_set (&synth->chorus_nr, nr);
synth->chorus_nr = nr;
if (set & FLUID_CHORUS_SET_LEVEL)
fluid_atomic_float_set (&synth->chorus_level, level);
synth->chorus_level = level;
if (set & FLUID_CHORUS_SET_SPEED)
fluid_atomic_float_set (&synth->chorus_speed, speed);
synth->chorus_speed = speed;
if (set & FLUID_CHORUS_SET_DEPTH)
fluid_atomic_float_set (&synth->chorus_depth, depth_ms);
synth->chorus_depth = depth_ms;
if (set & FLUID_CHORUS_SET_TYPE)
fluid_atomic_int_set (&synth->chorus_type, type);
synth->chorus_type = type;
ret = fluid_rvoice_eventhandler_push5(synth->eventhandler,
fluid_rvoice_mixer_set_chorus_params,
@ -4220,7 +4216,7 @@ fluid_synth_get_chorus_nr(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_int_get (&synth->chorus_nr);
result = synth->chorus_nr;
FLUID_API_RETURN(result);
}
@ -4236,7 +4232,7 @@ fluid_synth_get_chorus_level(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->chorus_level);
result = synth->chorus_level;
FLUID_API_RETURN(result);
}
@ -4252,7 +4248,7 @@ fluid_synth_get_chorus_speed_Hz(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->chorus_speed);
result = synth->chorus_speed;
FLUID_API_RETURN(result);
}
@ -4268,7 +4264,7 @@ fluid_synth_get_chorus_depth_ms(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_float_get (&synth->chorus_depth);
result = synth->chorus_depth;
FLUID_API_RETURN(result);
}
@ -4284,7 +4280,7 @@ fluid_synth_get_chorus_type(fluid_synth_t* synth)
fluid_return_val_if_fail (synth != NULL, 0.0);
fluid_synth_api_enter(synth);
result = fluid_atomic_int_get (&synth->chorus_type);
result = synth->chorus_type;
FLUID_API_RETURN(result);
}

View file

@ -113,8 +113,8 @@ struct _fluid_synth_t
fluid_settings_t* settings; /**< the synthesizer settings */
int device_id; /**< Device ID used for SYSEX messages */
int polyphony; /**< Maximum polyphony */
int with_reverb; /**< Should the synth use the built-in reverb unit? */
int with_chorus; /**< Should the synth use the built-in chorus unit? */
fluid_atomic_int_t with_reverb; /**< Should the synth use the built-in reverb unit? */
fluid_atomic_int_t with_chorus; /**< Should the synth use the built-in chorus unit? */
int verbose; /**< Turn verbose mode on? */
double sample_rate; /**< The sample rate */
int midi_channels; /**< the number of MIDI channels (>= 16) */
@ -124,7 +124,7 @@ struct _fluid_synth_t
Typically equal to audio_channels. */
int effects_channels; /**< the number of effects channels (>= 2) */
int state; /**< the synthesizer state */
unsigned int ticks_since_start; /**< the number of audio samples since the start */
fluid_atomic_uint_t ticks_since_start; /**< the number of audio samples since the start */
unsigned int start; /**< the start in msec, as returned by system clock */
fluid_overflow_prio_t overflow; /**< parameters for overflow priority (aka voice-stealing) */
@ -142,22 +142,22 @@ struct _fluid_synth_t
unsigned int storeid;
fluid_rvoice_eventhandler_t* eventhandler;
float reverb_roomsize; /**< Shadow of reverb roomsize */
float reverb_damping; /**< Shadow of reverb damping */
float reverb_width; /**< Shadow of reverb width */
float reverb_level; /**< Shadow of reverb level */
double reverb_roomsize; /**< Shadow of reverb roomsize */
double reverb_damping; /**< Shadow of reverb damping */
double reverb_width; /**< Shadow of reverb width */
double reverb_level; /**< Shadow of reverb level */
int chorus_nr; /**< Shadow of chorus number */
float chorus_level; /**< Shadow of chorus level */
float chorus_speed; /**< Shadow of chorus speed */
float chorus_depth; /**< Shadow of chorus depth */
double chorus_level; /**< Shadow of chorus level */
double chorus_speed; /**< Shadow of chorus speed */
double chorus_depth; /**< Shadow of chorus depth */
int chorus_type; /**< Shadow of chorus type */
int cur; /**< the current sample in the audio buffers to be output */
int curmax; /**< current amount of samples present in the audio buffers */
int dither_index; /**< current index in random dither value buffer: fluid_synth_(write_s16|dither_s16) */
float cpu_load; /**< CPU load in percent (CPU time required / audio synthesized time * 100) */
fluid_atomic_float_t cpu_load; /**< CPU load in percent (CPU time required / audio synthesized time * 100) */
fluid_tuning_t*** tuning; /**< 128 banks of 128 programs for the tunings */
fluid_private_t tuning_iter; /**< Tuning iterators per each thread */

View file

@ -48,7 +48,7 @@ fluid_tuning_t* new_fluid_tuning(const char* name, int bank, int prog)
tuning->pitch[i] = i * 100.0;
}
tuning->refcount = 1; /* Start with a refcount of 1 */
fluid_atomic_int_set(&tuning->refcount, 1); /* Start with a refcount of 1 */
return tuning;
}
@ -86,7 +86,7 @@ fluid_tuning_duplicate (fluid_tuning_t *tuning)
for (i = 0; i < 128; i++)
new_tuning->pitch[i] = tuning->pitch[i];
new_tuning->refcount = 1; /* Start with a refcount of 1 */
fluid_atomic_int_set(&new_tuning->refcount, 1); /* Start with a refcount of 1 */
return new_tuning;
}

View file

@ -39,7 +39,7 @@ struct _fluid_tuning_t {
int bank;
int prog;
double pitch[128]; /* the pitch of every key, in cents */
int refcount; /* Tuning reference count */
fluid_atomic_int_t refcount; /* Tuning reference count */
};
fluid_tuning_t* new_fluid_tuning(const char* name, int bank, int prog);

View file

@ -389,7 +389,7 @@ new_fluid_hashtable_full (fluid_hash_func_t hash_func,
hashtable->nnodes = 0;
hashtable->hash_func = hash_func ? hash_func : fluid_direct_hash;
hashtable->key_equal_func = key_equal_func;
hashtable->ref_count = 1;
fluid_atomic_int_set(&hashtable->ref_count, 1);
hashtable->key_destroy_func = key_destroy_func;
hashtable->value_destroy_func = value_destroy_func;
hashtable->nodes = FLUID_ARRAY (fluid_hashnode_t*, hashtable->size);
@ -616,7 +616,7 @@ fluid_hashtable_t*
fluid_hashtable_ref (fluid_hashtable_t *hashtable)
{
fluid_return_val_if_fail (hashtable != NULL, NULL);
fluid_return_val_if_fail (hashtable->ref_count > 0, hashtable);
fluid_return_val_if_fail (fluid_atomic_int_get(&hashtable->ref_count) > 0, hashtable);
fluid_atomic_int_add (&hashtable->ref_count, 1);
return hashtable;
@ -637,7 +637,7 @@ void
fluid_hashtable_unref (fluid_hashtable_t *hashtable)
{
fluid_return_if_fail (hashtable != NULL);
fluid_return_if_fail (hashtable->ref_count > 0);
fluid_return_if_fail (fluid_atomic_int_get(&hashtable->ref_count) > 0);
if (fluid_atomic_int_exchange_and_add (&hashtable->ref_count, -1) - 1 == 0)
{
@ -662,7 +662,7 @@ void
delete_fluid_hashtable (fluid_hashtable_t *hashtable)
{
fluid_return_if_fail (hashtable != NULL);
fluid_return_if_fail (hashtable->ref_count > 0);
fluid_return_if_fail (fluid_atomic_int_get(&hashtable->ref_count) > 0);
fluid_hashtable_remove_all (hashtable);
fluid_hashtable_unref (hashtable);
@ -753,7 +753,7 @@ fluid_hashtable_insert_internal (fluid_hashtable_t *hashtable, void *key,
unsigned int key_hash;
fluid_return_if_fail (hashtable != NULL);
fluid_return_if_fail (hashtable->ref_count > 0);
fluid_return_if_fail (fluid_atomic_int_get(&hashtable->ref_count) > 0);
node_ptr = fluid_hashtable_lookup_node (hashtable, key, &key_hash);

View file

@ -65,7 +65,7 @@ struct _fluid_hashtable_t
fluid_hashnode_t **nodes;
fluid_hash_func_t hash_func;
fluid_equal_func_t key_equal_func;
volatile int ref_count;
fluid_atomic_int_t ref_count;
fluid_destroy_notify_t key_destroy_func;
fluid_destroy_notify_t value_destroy_func;
fluid_rec_mutex_t mutex; // Optionally used in other modules (fluid_settings.c for example)

View file

@ -67,7 +67,7 @@ new_fluid_ringbuffer (int count, int elementsize)
queue->totalcount = count;
queue->elementsize = elementsize;
queue->count = 0;
fluid_atomic_int_set(&queue->count, 0);
queue->in = 0;
queue->out = 0;

View file

@ -30,7 +30,7 @@ struct _fluid_ringbuffer_t
{
char *array; /**< Queue array of arbitrary size elements */
int totalcount; /**< Total count of elements in array */
int count; /**< Current count of elements */
fluid_atomic_int_t count; /**< Current count of elements */
int in; /**< Index in queue to store next pushed element */
int out; /**< Index in queue of next popped element */
int elementsize; /**< Size of each element */

View file

@ -180,6 +180,11 @@ typedef guint32 uint32;
//typedef gint64 sint64;
//typedef guint64 uint64;
/** Atomic types */
typedef int fluid_atomic_int_t;
typedef unsigned int fluid_atomic_uint_t;
typedef float fluid_atomic_float_t;
/***************************************************************
*