diff --git a/fluidsynth/include/fluidsynth/voice.h b/fluidsynth/include/fluidsynth/voice.h index e053c7dc..f19d9a3a 100644 --- a/fluidsynth/include/fluidsynth/voice.h +++ b/fluidsynth/include/fluidsynth/voice.h @@ -54,6 +54,9 @@ FLUIDSYNTH_API void fluid_voice_gen_incr(fluid_voice_t* voice, int gen, float va FLUIDSYNTH_API unsigned int fluid_voice_get_id(fluid_voice_t* voice); FLUIDSYNTH_API int fluid_voice_is_playing(fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_is_on(fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_is_sustained(fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_is_sostenuto(fluid_voice_t* voice); FLUIDSYNTH_API int fluid_voice_get_channel(fluid_voice_t* voice); FLUIDSYNTH_API int fluid_voice_get_key(fluid_voice_t* voice); FLUIDSYNTH_API int fluid_voice_get_velocity(fluid_voice_t* voice); diff --git a/fluidsynth/src/synth/fluid_synth.c b/fluidsynth/src/synth/fluid_synth.c index 4e08dc84..1c484040 100644 --- a/fluidsynth/src/synth/fluid_synth.c +++ b/fluidsynth/src/synth/fluid_synth.c @@ -980,7 +980,7 @@ fluid_synth_noteoff_LOCAL(fluid_synth_t* synth, int chan, int key) for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (_ON(voice) && (voice->chan == chan) && (voice->key == key)) { + if (fluid_voice_is_on(voice) && (voice->chan == chan) && (voice->key == key)) { if (synth->verbose) { int used_voices = 0; int k; @@ -1013,7 +1013,7 @@ fluid_synth_damp_voices_by_sustain_LOCAL(fluid_synth_t* synth, int chan) for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if ((voice->chan == chan) && _SUSTAINED(voice)) + if ((voice->chan == chan) && fluid_voice_is_sustained(voice)) fluid_voice_release(voice); } @@ -1031,7 +1031,7 @@ fluid_synth_damp_voices_by_sostenuto_LOCAL(fluid_synth_t* synth, int chan) for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if ((voice->chan == chan) && _HELD_BY_SOSTENUTO(voice)) + if ((voice->chan == chan) && fluid_voice_is_sostenuto(voice)) fluid_voice_release(voice); } @@ -1528,7 +1528,7 @@ fluid_synth_all_notes_off_LOCAL(fluid_synth_t* synth, int chan) for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (_PLAYING(voice) && ((-1 == chan) || (chan == voice->chan))) + if (fluid_voice_is_playing(voice) && ((-1 == chan) || (chan == voice->chan))) fluid_voice_noteoff(voice); } return FLUID_OK; @@ -1566,7 +1566,7 @@ fluid_synth_all_sounds_off_LOCAL(fluid_synth_t* synth, int chan) for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (_PLAYING(voice) && ((-1 == chan) || (chan == voice->chan))) + if (fluid_voice_is_playing(voice) && ((-1 == chan) || (chan == voice->chan))) fluid_voice_off(voice); } return FLUID_OK; @@ -1627,7 +1627,7 @@ fluid_synth_system_reset_LOCAL(fluid_synth_t* synth) for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (_PLAYING(voice)) + if (fluid_voice_is_playing(voice)) fluid_voice_off(voice); } @@ -2259,7 +2259,7 @@ fluid_synth_update_gain_LOCAL(fluid_synth_t* synth) for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (_PLAYING (voice)) fluid_voice_set_gain (voice, gain); + if (fluid_voice_is_playing(voice)) fluid_voice_set_gain (voice, gain); } } @@ -2336,7 +2336,7 @@ fluid_synth_update_polyphony_LOCAL(fluid_synth_t* synth, int new_polyphony) for (i = synth->polyphony; i < synth->nvoice; i++) { voice = synth->voice[i]; - if (_PLAYING (voice)) fluid_voice_off (voice); + if (fluid_voice_is_playing(voice)) fluid_voice_off (voice); } fluid_synth_update_mixer(synth, fluid_rvoice_mixer_set_polyphony, @@ -3132,7 +3132,7 @@ fluid_synth_kill_by_exclusive_class_LOCAL(fluid_synth_t* synth, /* If voice is playing, on the same channel, has same exclusive * class and is not part of the same noteon event (voice group), then kill it */ - if (_PLAYING(existing_voice) + if (fluid_voice_is_playing(existing_voice) && existing_voice->chan == new_voice->chan && (int)_GEN (existing_voice, GEN_EXCLUSIVECLASS) == excl_class && fluid_voice_get_id (existing_voice) != fluid_voice_get_id(new_voice)) @@ -3699,7 +3699,7 @@ fluid_synth_get_voicelist(fluid_synth_t* synth, fluid_voice_t* buf[], int bufsiz for (i = 0; i < synth->polyphony && count < bufsize; i++) { fluid_voice_t* voice = synth->voice[i]; - if (_PLAYING(voice) && (id < 0 || (int)voice->id == id)) + if (fluid_voice_is_playing(voice) && (id < 0 || (int)voice->id == id)) buf[count++] = voice; } @@ -4057,12 +4057,12 @@ fluid_synth_release_voice_on_same_note_LOCAL(fluid_synth_t* synth, int chan, for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (_PLAYING(voice) + if (fluid_voice_is_playing(voice) && (voice->chan == chan) && (voice->key == key) && (fluid_voice_get_id(voice) != synth->noteid)) { /* Id of voices that was sustained by sostenuto */ - if(_HELD_BY_SOSTENUTO(voice)) + if(fluid_voice_is_sostenuto(voice)) synth->storeid = voice->id; /* Force the voice into release stage (pedaling is ignored) */ fluid_voice_release(voice); @@ -4273,7 +4273,7 @@ fluid_synth_update_voice_tuning_LOCAL (fluid_synth_t *synth, fluid_channel_t *ch { voice = synth->voice[i]; - if (_ON (voice) && (voice->channel == channel)) + if (fluid_voice_is_on(voice) && (voice->channel == channel)) { fluid_voice_calculate_gen_pitch (voice); fluid_voice_update_param (voice, GEN_PITCH); @@ -5018,7 +5018,7 @@ fluid_synth_stop_LOCAL (fluid_synth_t *synth, unsigned int id) for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (_ON(voice) && (fluid_voice_get_id (voice) == id)) + if (fluid_voice_is_on(voice) && (fluid_voice_get_id (voice) == id)) fluid_voice_noteoff(voice); } } diff --git a/fluidsynth/src/synth/fluid_voice.c b/fluidsynth/src/synth/fluid_voice.c index 0d1138ae..b919b253 100644 --- a/fluidsynth/src/synth/fluid_voice.c +++ b/fluidsynth/src/synth/fluid_voice.c @@ -318,7 +318,7 @@ fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample, int fluid_voice_set_output_rate(fluid_voice_t* voice, fluid_real_t value) { - if (_PLAYING(voice)) + if (fluid_voice_is_playing(voice)) fluid_voice_off(voice); voice->output_rate = value; @@ -407,7 +407,7 @@ fluid_voice_write (fluid_voice_t* voice, fluid_real_t *dsp_buf) if (result == -1) return 0; - if ((result < FLUID_BUFSIZE) && _PLAYING(voice)) /* Voice finished by itself */ + if ((result < FLUID_BUFSIZE) && fluid_voice_is_playing(voice)) /* Voice finished by itself */ fluid_voice_off(voice); return result; @@ -1199,6 +1199,8 @@ fluid_voice_release(fluid_voice_t* voice) /* * fluid_voice_noteoff + * + * Sending a noteoff event will advance the envelopes to section 5 (release). */ int fluid_voice_noteoff(fluid_voice_t* voice) @@ -1243,7 +1245,7 @@ fluid_voice_kill_excl(fluid_voice_t* voice){ unsigned int at_tick; - if (!_PLAYING(voice)) { + if (!fluid_voice_is_playing(voice)) { return FLUID_OK; } @@ -1399,13 +1401,49 @@ unsigned int fluid_voice_get_id(fluid_voice_t* voice) } /** - * Check if a voice is still playing. + * Check if a voice is producing sound. This is also true after a voice received a noteoff as it may be playing in release phase. * @param voice Voice instance * @return TRUE if playing, FALSE otherwise */ int fluid_voice_is_playing(fluid_voice_t* voice) { - return _PLAYING(voice); + return (voice->status == FLUID_VOICE_ON) + || fluid_voice_is_sustained(voice) + || fluid_voice_is_sostenuto(voice); + +} + +/** + * Check if a voice is ON. A voice is ON, if it has not yet received a noteoff event. + * @param voice Voice instance + * @return TRUE if on, FALSE otherwise + * @since 1.1.7 + */ +int fluid_voice_is_on(fluid_voice_t* voice) +{ + return (voice->status == FLUID_VOICE_ON && !voice->has_noteoff); +} + +/** + * Check if a voice is sustained. + * @param voice Voice instance + * @return TRUE if sustained, FALSE otherwise + * @since 1.1.7 + */ +int fluid_voice_is_sustained(fluid_voice_t* voice) +{ + return (voice->status == FLUID_VOICE_SUSTAINED); +} + +/** + * Check if a voice is held by sostenuto. + * @param voice Voice instance + * @return TRUE if sostenuto, FALSE otherwise + * @since 1.1.7 + */ +int fluid_voice_is_sostenuto(fluid_voice_t* voice) +{ + return (voice->status == FLUID_VOICE_HELD_BY_SOSTENUTO); } /** @@ -1628,7 +1666,7 @@ fluid_voice_get_overflow_prio(fluid_voice_t* voice, } else if (voice->has_noteoff) { /* Noteoff has */ this_voice_prio += score->released; - } else if (_SUSTAINED(voice) || _HELD_BY_SOSTENUTO(voice)) { + } else if (fluid_voice_is_sustained(voice) || fluid_voice_is_sostenuto(voice)) { /* This voice is still active, since the sustain pedal is held down. * Consider it less important than non-sustained channels. * This decision is somehow subjective. But usually the sustain pedal diff --git a/fluidsynth/src/synth/fluid_voice.h b/fluidsynth/src/synth/fluid_voice.h index 4474d9a4..6bf523b2 100644 --- a/fluidsynth/src/synth/fluid_voice.h +++ b/fluidsynth/src/synth/fluid_voice.h @@ -183,19 +183,6 @@ fluid_voice_unlock_rvoice(fluid_voice_t* voice) voice->can_access_rvoice = 1; } - -#define fluid_voice_set_id(_voice, _id) { (_voice)->id = (_id); } - -#define _PLAYING(voice) (((voice)->status == FLUID_VOICE_ON) || \ - _SUSTAINED(voice) || \ - _HELD_BY_SOSTENUTO(voice) ) - -/* A voice is 'ON', if it has not yet received a noteoff - * event. Sending a noteoff event will advance the envelopes to - * section 5 (release). */ -#define _ON(voice) ((voice)->status == FLUID_VOICE_ON && !voice->has_noteoff) -#define _SUSTAINED(voice) ((voice)->status == FLUID_VOICE_SUSTAINED) -#define _HELD_BY_SOSTENUTO(voice) ((voice)->status == FLUID_VOICE_HELD_BY_SOSTENUTO) #define _AVAILABLE(voice) ((voice)->can_access_rvoice && \ (((voice)->status == FLUID_VOICE_CLEAN) || ((voice)->status == FLUID_VOICE_OFF))) //#define _RELEASED(voice) ((voice)->chan == NO_CHANNEL)