mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-12-01 00:21:14 +00:00
Merge pull request #198 from FluidSynth/fixed_key
Fixed key notes are never released
This commit is contained in:
commit
ab5ab33d60
4 changed files with 54 additions and 39 deletions
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue