diff --git a/fluidsynth/src/fluid_alsa.c b/fluidsynth/src/fluid_alsa.c index 7ba8ea31..64a3568b 100644 --- a/fluidsynth/src/fluid_alsa.c +++ b/fluidsynth/src/fluid_alsa.c @@ -296,6 +296,10 @@ new_fluid_alsa_audio_driver2(fluid_settings_t* settings, FLUID_LOG(FLUID_ERR, "Software setup failed."); } + if (snd_pcm_nonblock(dev->pcm, 0) != 0) { + FLUID_LOG(FLUID_ERR, "Failed to set the audio device to blocking mode"); + goto error_recovery; + } /* Create the audio thread */ dev->thread = new_fluid_thread (fluid_alsa_formats[i].run, dev, realtime_prio, FALSE); @@ -326,16 +330,8 @@ int delete_fluid_alsa_audio_driver(fluid_audio_driver_t* p) if (dev->thread) fluid_thread_join (dev->thread); - if (dev->pcm) { - snd_pcm_state_t state = snd_pcm_state(dev->pcm); - if ((state == SND_PCM_STATE_RUNNING) - || (state == SND_PCM_STATE_XRUN) - || (state == SND_PCM_STATE_SUSPENDED) - || (state == SND_PCM_STATE_PAUSED)) { - snd_pcm_drop(dev->pcm); - } + if (dev->pcm) snd_pcm_close (dev->pcm); - } FLUID_FREE(dev); @@ -390,11 +386,6 @@ static void fluid_alsa_audio_run_float (void *d) return; } - if (snd_pcm_nonblock(dev->pcm, 0) != 0) { /* double negation */ - FLUID_LOG(FLUID_ERR, "Failed to set the audio device to blocking mode"); - goto error_recovery; - } - if (snd_pcm_prepare(dev->pcm) != 0) { FLUID_LOG(FLUID_ERR, "Failed to prepare the audio device"); goto error_recovery; @@ -474,11 +465,6 @@ static void fluid_alsa_audio_run_s16 (void *d) handle[0] = left; handle[1] = right; - if (snd_pcm_nonblock(dev->pcm, 0) != 0) { /* double negation */ - FLUID_LOG(FLUID_ERR, "Failed to set the audio device to blocking mode"); - goto error_recovery; - } - if (snd_pcm_prepare(dev->pcm) != 0) { FLUID_LOG(FLUID_ERR, "Failed to prepare the audio device"); goto error_recovery; diff --git a/fluidsynth/src/fluid_chan.c b/fluidsynth/src/fluid_chan.c index 067d9f59..f253bab2 100644 --- a/fluidsynth/src/fluid_chan.c +++ b/fluidsynth/src/fluid_chan.c @@ -36,8 +36,6 @@ #define SFONT_MASKVAL 0xFFE00000 -#define SETCC(_c,_n,_v) _c->cc[_n] = _v - static void fluid_channel_init(fluid_channel_t* chan); @@ -137,26 +135,26 @@ fluid_channel_init_ctrl(fluid_channel_t* chan, int is_all_ctrl_off) continue; } - SETCC(chan, i, 0); + fluid_channel_set_cc (chan, i, 0); } } else { for (i = 0; i < 128; i++) { - SETCC(chan, i, 0); + fluid_channel_set_cc (chan, i, 0); } } /* Set RPN controllers to NULL state */ - SETCC(chan, RPN_LSB, 127); - SETCC(chan, RPN_MSB, 127); + fluid_channel_set_cc (chan, RPN_LSB, 127); + fluid_channel_set_cc (chan, RPN_MSB, 127); /* Set NRPN controllers to NULL state */ - SETCC(chan, NRPN_LSB, 127); - SETCC(chan, NRPN_MSB, 127); + fluid_channel_set_cc (chan, NRPN_LSB, 127); + fluid_channel_set_cc (chan, NRPN_MSB, 127); /* Expression (MSB & LSB) */ - SETCC(chan, EXPRESSION_MSB, 127); - SETCC(chan, EXPRESSION_LSB, 127); + fluid_channel_set_cc (chan, EXPRESSION_MSB, 127); + fluid_channel_set_cc (chan, EXPRESSION_LSB, 127); if (!is_all_ctrl_off) { @@ -164,19 +162,19 @@ fluid_channel_init_ctrl(fluid_channel_t* chan, int is_all_ctrl_off) /* Just like panning, a value of 64 indicates no change for sound ctrls */ for (i = SOUND_CTRL1; i <= SOUND_CTRL10; i++) { - SETCC(chan, i, 64); + fluid_channel_set_cc (chan, i, 64); } /* Volume / initial attenuation (MSB & LSB) */ - SETCC(chan, VOLUME_MSB, 100); - SETCC(chan, VOLUME_LSB, 0); + fluid_channel_set_cc (chan, VOLUME_MSB, 100); + fluid_channel_set_cc (chan, VOLUME_LSB, 0); /* Pan (MSB & LSB) */ - SETCC(chan, PAN_MSB, 64); - SETCC(chan, PAN_LSB, 0); + fluid_channel_set_cc (chan, PAN_MSB, 64); + fluid_channel_set_cc (chan, PAN_LSB, 0); /* Reverb */ - /* SETCC(chan, EFFECTS_DEPTH1, 40); */ + /* fluid_channel_set_cc (chan, EFFECTS_DEPTH1, 40); */ /* Note: although XG standard specifies the default amount of reverb to be 40, most people preferred having it at zero. See http://lists.gnu.org/archive/html/fluid-dev/2009-07/msg00016.html */ diff --git a/fluidsynth/src/fluid_chan.h b/fluidsynth/src/fluid_chan.h index 1af7007a..f6658bcd 100644 --- a/fluidsynth/src/fluid_chan.h +++ b/fluidsynth/src/fluid_chan.h @@ -108,8 +108,6 @@ void fluid_channel_set_bank_lsb(fluid_channel_t* chan, int banklsb); void fluid_channel_set_bank_msb(fluid_channel_t* chan, int bankmsb); void fluid_channel_get_sfont_bank_prog(fluid_channel_t* chan, int *sfont, int *bank, int *prog); -void fluid_channel_set_cc(fluid_channel_t* chan, int num, int val); -int fluid_channel_get_cc(fluid_channel_t* chan, int num); int fluid_channel_get_num(fluid_channel_t* chan); void fluid_channel_set_interp_method(fluid_channel_t* chan, int new_method); int fluid_channel_get_interp_method(fluid_channel_t* chan); diff --git a/fluidsynth/src/fluid_synth.c b/fluidsynth/src/fluid_synth.c index 8547f8e7..7cc7ad65 100644 --- a/fluidsynth/src/fluid_synth.c +++ b/fluidsynth/src/fluid_synth.c @@ -56,8 +56,7 @@ 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); static int fluid_synth_damp_voices_LOCAL(fluid_synth_t* synth, int chan); -static int fluid_synth_cc_real(fluid_synth_t* synth, int channum, int num, - int value, int noqueue); +static int fluid_synth_cc_real(fluid_synth_t* synth, int channum, int num, int noqueue); static int fluid_synth_update_device_id (fluid_synth_t *synth, char *name, int value); static int fluid_synth_sysex_midi_tuning (fluid_synth_t *synth, const char *data, @@ -532,6 +531,7 @@ 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); @@ -1370,21 +1370,24 @@ fluid_synth_cc(fluid_synth_t* synth, int chan, int num, int val) fluid_return_val_if_fail (num >= 0 && num <= 127, FLUID_FAILED); fluid_return_val_if_fail (val >= 0 && val <= 127, FLUID_FAILED); - fluid_synth_cc_real (synth, chan, num, val, FALSE); + if (synth->verbose) + FLUID_LOG(FLUID_INFO, "cc\t%d\t%d\t%d", chan, num, val); + + fluid_channel_set_cc (synth->channel[chan], num, val); + + fluid_synth_cc_real (synth, chan, num, FALSE); return FLUID_OK; } -/* Local synthesis thread variant of MIDI CC set function. - * NOTE: Gets called out of synthesis context for BANK_SELECT_MSB and - * BANK_SELECT_LSB events, since they should be processed immediately. */ +/* Local synthesis thread variant of MIDI CC set function. */ static int -fluid_synth_cc_real (fluid_synth_t* synth, int channum, int num, int value, - int noqueue) +fluid_synth_cc_real (fluid_synth_t* synth, int channum, int num, int noqueue) { fluid_channel_t* chan = synth->channel[channum]; int nrpn_select, nrpn_active = 0; int rpn_msb = 0, rpn_lsb = 0; + int value; /* nrpn_active, rpn_msb and rpn_lsb may get used multiple times, read them * once atomically if they are needed */ @@ -1405,12 +1408,9 @@ fluid_synth_cc_real (fluid_synth_t* synth, int channum, int num, int value, && num != BANK_SELECT_MSB && num != BANK_SELECT_LSB && !(num == DATA_ENTRY_MSB && !nrpn_active && rpn_msb == 0 && (rpn_lsb == RPN_TUNING_PROGRAM_CHANGE || rpn_lsb == RPN_TUNING_BANK_SELECT))) - return fluid_synth_queue_midi_event (synth, CONTROL_CHANGE, channum, num, value); + return fluid_synth_queue_midi_event (synth, CONTROL_CHANGE, channum, num, 0); - if (synth->verbose) - FLUID_LOG(FLUID_INFO, "cc\t%d\t%d\t%d", channum, num, value); - - fluid_channel_set_cc (chan, num, value); + value = fluid_channel_get_cc (chan, num); switch (num) { case SUSTAIN_SWITCH: @@ -1948,8 +1948,6 @@ fluid_synth_modulate_voices_LOCAL(fluid_synth_t* synth, int chan, int is_cc, int * Update voices on a MIDI channel after all MIDI controllers have been changed. * @param synth FluidSynth instance * @param chan MIDI channel number (0 to MIDI channel count - 1) - * @param is_cc Boolean value indicating if ctrl is a CC controller or not - * @param ctrl MIDI controller value * @return FLUID_OK on success, FLUID_FAILED otherwise */ static int @@ -2502,16 +2500,16 @@ fluid_synth_set_gain(fluid_synth_t* synth, float gain) static void fluid_synth_update_gain_LOCAL(fluid_synth_t* synth) { + fluid_voice_t *voice; float gain; int i; gain = fluid_atomic_float_get (&synth->gain); - for (i = 0; i < synth->polyphony; i++) { - fluid_voice_t* voice = synth->voice[i]; - if (_PLAYING(voice)) { - fluid_voice_set_gain(voice, gain); - } + for (i = 0; i < synth->polyphony; i++) + { + voice = synth->voice[i]; + if (_PLAYING (voice)) fluid_voice_set_gain (voice, gain); } } @@ -2551,7 +2549,7 @@ fluid_synth_set_polyphony(fluid_synth_t* synth, int polyphony) fluid_return_val_if_fail (synth != NULL, FLUID_FAILED); fluid_return_val_if_fail (polyphony >= 16 && polyphony <= synth->nvoice, FLUID_FAILED); - fluid_atomic_int_set (&synth->polyphony, polyphony); + fluid_atomic_int_set (&synth->shadow_polyphony, polyphony); if (fluid_synth_should_queue (synth)) return fluid_synth_queue_int_event (synth, FLUID_EVENT_QUEUE_ELEM_POLYPHONY, 0); @@ -2562,16 +2560,16 @@ fluid_synth_set_polyphony(fluid_synth_t* synth, int polyphony) static int fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth) { - int i, polyphony; + fluid_voice_t *voice; + int i; - polyphony = fluid_atomic_int_get (&synth->polyphony); + synth->polyphony = fluid_atomic_int_get (&synth->shadow_polyphony); /* turn off any voices above the new limit */ - for (i = polyphony; i < synth->nvoice; i++) { - fluid_voice_t* voice = synth->voice[i]; - if (_PLAYING(voice)) { - fluid_voice_off(voice); - } + for (i = synth->polyphony; i < synth->nvoice; i++) + { + voice = synth->voice[i]; + if (_PLAYING (voice)) fluid_voice_off (voice); } return FLUID_OK; @@ -2586,7 +2584,7 @@ fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth) int fluid_synth_get_polyphony(fluid_synth_t* synth) { - return fluid_atomic_int_get (&synth->polyphony); + return fluid_atomic_int_get (&synth->shadow_polyphony); } /** @@ -2990,9 +2988,8 @@ fluid_synth_one_block(fluid_synth_t* synth, int do_not_mix_fx_to_out) int count; fluid_profile_ref_var (prof_ref); - /* Assign ID of synthesis thread, if not already set */ - if (synth->synth_thread_id == FLUID_THREAD_ID_NULL) - synth->synth_thread_id = fluid_thread_get_id (); + /* Assign ID of synthesis thread */ + synth->synth_thread_id = fluid_thread_get_id (); fluid_check_fpe("??? Just starting up ???"); @@ -3314,8 +3311,7 @@ fluid_synth_process_event_queue_LOCAL (fluid_synth_t *synth, break; case CONTROL_CHANGE: /* Pass TRUE for noqueue, since event should never get re-queued */ - fluid_synth_cc_real (synth, event->midi.channel, event->midi.param1, - event->midi.param2, TRUE); + fluid_synth_cc_real (synth, event->midi.channel, event->midi.param1, TRUE); break; case MIDI_SYSTEM_RESET: fluid_synth_system_reset_LOCAL (synth); @@ -3522,8 +3518,9 @@ fluid_synth_alloc_voice(fluid_synth_t* synth, fluid_sample_t* sample, int chan, channel = synth->channel[chan]; } - if (fluid_voice_init(voice, sample, channel, key, vel, - synth->storeid, synth->ticks, synth->gain) != FLUID_OK) { + if (fluid_voice_init (voice, sample, channel, key, vel, + synth->storeid, synth->ticks, + fluid_atomic_float_get (&synth->gain)) != FLUID_OK) { FLUID_LOG(FLUID_WARN, "Failed to initialize voice"); return NULL; } diff --git a/fluidsynth/src/fluid_synth.h b/fluidsynth/src/fluid_synth.h index 020b787d..67c81c56 100644 --- a/fluidsynth/src/fluid_synth.h +++ b/fluidsynth/src/fluid_synth.h @@ -162,7 +162,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 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? */ diff --git a/fluidsynth/src/fluid_sys.c b/fluidsynth/src/fluid_sys.c index 521eb211..8040462e 100644 --- a/fluidsynth/src/fluid_sys.c +++ b/fluidsynth/src/fluid_sys.c @@ -736,10 +736,14 @@ delete_fluid_timer (fluid_timer_t *timer) int fluid_timer_join (fluid_timer_t *timer) { + int auto_destroy; + if (timer->thread) { + auto_destroy = timer->auto_destroy; fluid_thread_join (timer->thread); - timer->thread = NULL; + + if (!auto_destroy) timer->thread = NULL; } return FLUID_OK;