diff --git a/fluidsynth/include/fluidsynth/voice.h b/fluidsynth/include/fluidsynth/voice.h index f19d9a3a..f28e1dc3 100644 --- a/fluidsynth/include/fluidsynth/voice.h +++ b/fluidsynth/include/fluidsynth/voice.h @@ -52,14 +52,16 @@ FLUIDSYNTH_API void fluid_voice_gen_set(fluid_voice_t* voice, int gen, float val FLUIDSYNTH_API float fluid_voice_gen_get(fluid_voice_t* voice, int gen); FLUIDSYNTH_API void fluid_voice_gen_incr(fluid_voice_t* voice, int gen, float val); -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); +FLUIDSYNTH_API unsigned int fluid_voice_get_id(const fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_is_playing(const fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_is_on(const fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_is_sustained(const fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_is_sostenuto(const fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_get_channel(const fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_get_actual_key(const fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_get_key(const fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_get_actual_velocity(const fluid_voice_t* voice); +FLUIDSYNTH_API int fluid_voice_get_velocity(const fluid_voice_t* voice); FLUIDSYNTH_API int fluid_voice_optimize_sample(fluid_sample_t* s); diff --git a/fluidsynth/src/synth/fluid_mod.c b/fluidsynth/src/synth/fluid_mod.c index d33a844a..fb14cab6 100644 --- a/fluidsynth/src/synth/fluid_mod.c +++ b/fluidsynth/src/synth/fluid_mod.c @@ -179,10 +179,10 @@ fluid_mod_get_source_value(const unsigned char mod_src, val = *range; break; case FLUID_MOD_VELOCITY: - val = voice->vel; + val = fluid_voice_get_actual_velocity(voice); break; case FLUID_MOD_KEY: - val = voice->key; + val = fluid_voice_get_actual_key(voice); break; case FLUID_MOD_KEYPRESSURE: val = fluid_channel_get_key_pressure (chan); diff --git a/fluidsynth/src/synth/fluid_synth.c b/fluidsynth/src/synth/fluid_synth.c index 4e609381..a81a0dda 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 (fluid_voice_is_on(voice) && (voice->chan == chan) && (voice->key == key)) { + if (fluid_voice_is_on(voice) && (fluid_voice_get_channel(voice) == chan) && (fluid_voice_get_key(voice) == key)) { if (synth->verbose) { int used_voices = 0; int k; @@ -990,7 +990,7 @@ fluid_synth_noteoff_LOCAL(fluid_synth_t* synth, int chan, int key) } } FLUID_LOG(FLUID_INFO, "noteoff\t%d\t%d\t%d\t%05d\t%.3f\t%d", - voice->chan, voice->key, 0, voice->id, + fluid_voice_get_channel(voice), fluid_voice_get_key(voice), 0, fluid_voice_get_id(voice), (fluid_curtime() - synth->start) / 1000.0f, used_voices); } /* if verbose */ @@ -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) && fluid_voice_is_sustained(voice)) + if ((fluid_voice_get_channel(voice) == 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) && fluid_voice_is_sostenuto(voice)) + if ((fluid_voice_get_channel(voice) == 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 (fluid_voice_is_playing(voice) && ((-1 == chan) || (chan == voice->chan))) + if (fluid_voice_is_playing(voice) && ((-1 == chan) || (chan == fluid_voice_get_channel(voice)))) 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 (fluid_voice_is_playing(voice) && ((-1 == chan) || (chan == voice->chan))) + if (fluid_voice_is_playing(voice) && ((-1 == chan) || (chan == fluid_voice_get_channel(voice)))) fluid_voice_off(voice); } return FLUID_OK; @@ -1656,7 +1656,7 @@ fluid_synth_modulate_voices_LOCAL(fluid_synth_t* synth, int chan, int is_cc, int for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (voice->chan == chan) + if (fluid_voice_get_channel(voice) == chan) fluid_voice_modulate(voice, is_cc, ctrl); } return FLUID_OK; @@ -1677,7 +1677,7 @@ fluid_synth_modulate_voices_all_LOCAL(fluid_synth_t* synth, int chan) for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (voice->chan == chan) + if (fluid_voice_get_channel(voice) == chan) fluid_voice_modulate_all(voice); } return FLUID_OK; @@ -3025,7 +3025,7 @@ fluid_synth_free_voice_by_kill_LOCAL(fluid_synth_t* synth) voice = synth->voice[best_voice_index]; FLUID_LOG(FLUID_DBG, "Killing voice %d, index %d, chan %d, key %d ", - voice->id, best_voice_index, voice->chan, voice->key); + fluid_voice_get_id(voice), best_voice_index, fluid_voice_get_channel(voice), fluid_voice_get_key(voice)); fluid_voice_off(voice); return voice; @@ -3142,7 +3142,7 @@ fluid_synth_kill_by_exclusive_class_LOCAL(fluid_synth_t* synth, * class and is not part of the same noteon event (voice group), then kill it */ if (fluid_voice_is_playing(existing_voice) - && existing_voice->chan == new_voice->chan + && fluid_voice_get_channel(existing_voice) == fluid_voice_get_channel(new_voice) && (int)_GEN (existing_voice, GEN_EXCLUSIVECLASS) == excl_class && fluid_voice_get_id (existing_voice) != fluid_voice_get_id(new_voice)) fluid_voice_kill_excl(existing_voice); @@ -4067,12 +4067,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 (fluid_voice_is_playing(voice) - && (voice->chan == chan) - && (voice->key == key) + && (fluid_voice_get_channel(voice) == chan) + && (fluid_voice_get_key(voice) == key) && (fluid_voice_get_id(voice) != synth->noteid)) { /* Id of voices that was sustained by sostenuto */ if(fluid_voice_is_sostenuto(voice)) - synth->storeid = voice->id; + synth->storeid = fluid_voice_get_id(voice); /* Force the voice into release stage (pedaling is ignored) */ fluid_voice_release(voice); } @@ -4850,7 +4850,7 @@ fluid_synth_set_gen_LOCAL (fluid_synth_t* synth, int chan, int param, float valu for (i = 0; i < synth->polyphony; i++) { voice = synth->voice[i]; - if (voice->chan == chan) + if (fluid_voice_get_channel(voice) == chan) fluid_voice_set_param (voice, param, value, absolute); } } diff --git a/fluidsynth/src/synth/fluid_voice.c b/fluidsynth/src/synth/fluid_voice.c index 4774862f..58c74abe 100644 --- a/fluidsynth/src/synth/fluid_voice.c +++ b/fluidsynth/src/synth/fluid_voice.c @@ -481,10 +481,10 @@ fluid_voice_calculate_gen_pitch(fluid_voice_t* voice) tuning = fluid_channel_get_tuning (voice->channel); x = fluid_tuning_get_pitch (tuning, (int)(voice->root_pitch / 100.0f)); voice->gen[GEN_PITCH].val = voice->gen[GEN_SCALETUNE].val / 100.0f * - (fluid_tuning_get_pitch (tuning, voice->key) - x) + x; + (fluid_tuning_get_pitch (tuning, fluid_voice_get_actual_key(voice)) - x) + x; } else { voice->gen[GEN_PITCH].val = voice->gen[GEN_SCALETUNE].val - * (voice->key - voice->root_pitch / 100.0f) + voice->root_pitch; + * (fluid_voice_get_actual_key(voice) - voice->root_pitch / 100.0f) + voice->root_pitch; } } @@ -636,7 +636,7 @@ calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base, * will cause (60-72)*100=-1200 timecents of time variation. * The time is cut in half. */ - timecents = (_GEN(voice, gen_base) + _GEN(voice, gen_key2base) * (60.0 - voice->key)); + timecents = (_GEN(voice, gen_base) + _GEN(voice, gen_key2base) * (60.0 - fluid_voice_get_actual_key(voice))); /* Range checking */ if (is_decay){ @@ -889,11 +889,17 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen) * * There is a flag, which should indicate, whether a generator is * enabled or not. But here we rely on the default value of -1. - * */ + */ + + /* 2017-09-02: do not change the voice's key here, otherwise it will + * never be released on a noteoff event + */ +#if 0 x = _GEN(voice, GEN_KEYNUM); if (x >= 0){ voice->key = x; } +#endif break; case GEN_VELOCITY: @@ -903,11 +909,18 @@ fluid_voice_update_param(fluid_voice_t* voice, int gen) * value. Non-realtime controller. * * There is a flag, which should indicate, whether a generator is - * enabled or not. But here we rely on the default value of -1. */ + * enabled or not. But here we rely on the default value of -1. + */ + /* 2017-09-02: do not change the voice's velocity here, user + * fluid_voice_get_actual_velocity() to get the value of this generator + * if active. + */ +#if 0 x = _GEN(voice, GEN_VELOCITY); if (x > 0) { voice->vel = x; } +#endif break; case GEN_MODENVTOPITCH: @@ -1395,7 +1408,7 @@ fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode) * * Otherwise the voice has finished playing. */ -unsigned int fluid_voice_get_id(fluid_voice_t* voice) +unsigned int fluid_voice_get_id(const fluid_voice_t* voice) { return voice->id; } @@ -1405,7 +1418,7 @@ unsigned int fluid_voice_get_id(fluid_voice_t* voice) * @param voice Voice instance * @return TRUE if playing, FALSE otherwise */ -int fluid_voice_is_playing(fluid_voice_t* voice) +int fluid_voice_is_playing(const fluid_voice_t* voice) { return (voice->status == FLUID_VOICE_ON) || fluid_voice_is_sustained(voice) @@ -1419,7 +1432,7 @@ int fluid_voice_is_playing(fluid_voice_t* voice) * @return TRUE if on, FALSE otherwise * @since 1.1.7 */ -int fluid_voice_is_on(fluid_voice_t* voice) +int fluid_voice_is_on(const fluid_voice_t* voice) { return (voice->status == FLUID_VOICE_ON && !voice->has_noteoff); } @@ -1430,7 +1443,7 @@ int fluid_voice_is_on(fluid_voice_t* voice) * @return TRUE if sustained, FALSE otherwise * @since 1.1.7 */ -int fluid_voice_is_sustained(fluid_voice_t* voice) +int fluid_voice_is_sustained(const fluid_voice_t* voice) { return (voice->status == FLUID_VOICE_SUSTAINED); } @@ -1441,7 +1454,7 @@ int fluid_voice_is_sustained(fluid_voice_t* voice) * @return TRUE if sostenuto, FALSE otherwise * @since 1.1.7 */ -int fluid_voice_is_sostenuto(fluid_voice_t* voice) +int fluid_voice_is_sostenuto(const fluid_voice_t* voice) { return (voice->status == FLUID_VOICE_HELD_BY_SOSTENUTO); } @@ -1452,7 +1465,7 @@ int fluid_voice_is_sostenuto(fluid_voice_t* voice) * @return The channel assigned to this voice * @since 1.1.7 */ -int fluid_voice_get_channel(fluid_voice_t* voice) +int fluid_voice_get_channel(const fluid_voice_t* voice) { return voice->chan; } @@ -1465,7 +1478,7 @@ int fluid_voice_get_channel(fluid_voice_t* voice) * @return The midi key this voice is playing at * @since 1.1.7 */ -int fluid_voice_get_actual_key(fluid_voice_t* voice) +int fluid_voice_get_actual_key(const fluid_voice_t* voice) { fluid_real_t x = _GEN(voice, GEN_KEYNUM); if (x >= 0) @@ -1485,7 +1498,7 @@ int fluid_voice_get_actual_key(fluid_voice_t* voice) * @return The midi key of the noteon event that originally turned on this voice * @since 1.1.7 */ -int fluid_voice_get_key(fluid_voice_t* voice) +int fluid_voice_get_key(const fluid_voice_t* voice) { return voice->key; } @@ -1498,7 +1511,7 @@ int fluid_voice_get_key(fluid_voice_t* voice) * @return The midi velocity this voice is playing at * @since 1.1.7 */ -int fluid_voice_get_actual_velocity(fluid_voice_t* voice) +int fluid_voice_get_actual_velocity(const fluid_voice_t* voice) { fluid_real_t x = _GEN(voice, GEN_VELOCITY); if (x > 0) @@ -1518,7 +1531,7 @@ int fluid_voice_get_actual_velocity(fluid_voice_t* voice) * @return The midi velocity which originally turned on this voice * @since 1.1.7 */ -int fluid_voice_get_velocity(fluid_voice_t* voice) +int fluid_voice_get_velocity(const fluid_voice_t* voice) { return voice->vel; }