Skip to content

Commit

Permalink
fix #87066: Incorrect Pitch When Alternate Values Used for 'Scale Tune'
Browse files Browse the repository at this point in the history
  • Loading branch information
lasconic committed Feb 21, 2018
1 parent 8915b35 commit 3517971
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 18 deletions.
46 changes: 30 additions & 16 deletions fluid/voice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ void Voice::write(unsigned n, float* out, float* reverb, float* chorus)
float cent = pitch + modlfo_val * modlfo_to_pitch
+ viblfo_val * viblfo_to_pitch
+ modenv_val * modenv_to_pitch;
phase_incr = _fluid->ct2hz_real(cent) / root_pitch;
phase_incr = _fluid->ct2hz_real(cent) / root_pitch_hz;
}

/* if phase_incr is not advancing, set it to the minimum fraction value (prevent stuckage) */
Expand Down Expand Up @@ -749,17 +749,6 @@ void Voice::voice_start()
dest_gen->mod += modval;
}

/* The GEN_PITCH is a hack to fit the pitch bend controller into the
* modulator paradigm. Now the nominal pitch of the key is set.
* Note about SCALETUNE: SF2.01 8.1.3 says, that this generator is a
* non-realtime parameter. So we don't allow modulation (as opposed
* to _GEN(voice, GEN_SCALETUNE) When the scale tuning is varied,
* one key remains fixed. Here C3 (MIDI number 60) is used.
*/

gen[GEN_PITCH].val = _noteTuning + _fluid->getPitch(60) + (gen[GEN_SCALETUNE].val * .01 *
(_fluid->getPitch(key) - _fluid->getPitch(60)));

/* Now the generators are initialized, nominal and modulation value.
* The voice parameters (which depend on generators) are calculated
* with update_param. Processing the list of generator
Expand Down Expand Up @@ -796,6 +785,30 @@ void Voice::voice_start()
status = FLUID_VOICE_ON;
}

//---------------------------------------------------------
// fluid_voice_calculate_gen_pitch
//---------------------------------------------------------

void Voice::calculate_gen_pitch()
{
float x;
/* The GEN_PITCH is a hack to fit the pitch bend controller into the
* modulator paradigm. Now the nominal pitch of the key is set.
* Note about SCALETUNE: SF2.01 8.1.3 says, that this generator is a
* non-realtime parameter. So we don't allow modulation (as opposed
* to _GEN(voice, GEN_SCALETUNE) When the scale tuning is varied,
* one key remains fixed. Here C3 (MIDI number 60) is used.
*/
//if (channel->tuning != 0) {
/* pitch(scalekey) + scale * (pitch(key) - pitch(scalekey)) */
x = _fluid->getPitch((int)(root_pitch / 100.0f));
gen[GEN_PITCH].val = _noteTuning + (x + (gen[GEN_SCALETUNE].val / 100.0f * (_fluid->getPitch(key) - x)));
// }
//else {
// gen[GEN_PITCH].val = _noteTuning + (gen[GEN_SCALETUNE].val * (key - root_pitch / 100.0f) + root_pitch);
// }
}

/*
* calculate_hold_decay_frames
*/
Expand Down Expand Up @@ -927,10 +940,11 @@ void Voice::update_param(int _gen)
}
else {
root_pitch = sample->origpitch * 100.0f - sample->pitchadj;
}
root_pitch = _fluid->ct2hz(root_pitch);
if (sample->samplerate != 0)
root_pitch *= (float) _fluid->sample_rate / sample->samplerate;
}
root_pitch_hz = _fluid->ct2hz(root_pitch);
root_pitch_hz *= (float) _fluid->sample_rate / sample->samplerate;
/* voice pitch depends on voice root_pitch, so calculate voice pitch now */
calculate_gen_pitch();
}
break;

Expand Down
5 changes: 3 additions & 2 deletions fluid/voice.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class Voice
have to be checked. */
unsigned int ticks;

qreal amp; /* the linear amplitude */
float amp; /* the linear amplitude */
Phase phase; // the phase of the sample wave

// Temporary variables used in write()
Expand All @@ -104,7 +104,7 @@ class Voice
float attenuation; /* the attenuation in centibels */
float min_attenuation_cB; /* Estimate on the smallest possible attenuation
* during the lifetime of the voice */
float root_pitch;
float root_pitch, root_pitch_hz;

/* sample and loop start and end points (offset in sample memory). */
int start;
Expand Down Expand Up @@ -219,6 +219,7 @@ class Voice
void noteoff();
void kill_excl();
int calculate_hold_decay_frames(int gen_base, int gen_key2base, int is_decay);
void calculate_gen_pitch();

/* A voice is 'ON', if it has not yet received a noteoff
* event. Sending a noteoff event will advance the envelopes to
Expand Down

0 comments on commit 3517971

Please sign in to comment.