Fix handling of very short notes in Monosynth.

(cherry picked from commit 5965d9922a0753e2dce4f743a23b9512be01a7ac)
This commit is contained in:
Krzysztof Foltman
2010-09-12 00:24:45 +01:00
committed by Tobias Doerffel
parent 342ea2ba05
commit 4b92af788b
2 changed files with 41 additions and 18 deletions

View File

@@ -88,6 +88,8 @@ public:
int32_t last_stretch1;
/// Next note to play on the next calculate_step
int queue_note_on;
/// Whether the queued note has been already released
bool queue_note_on_and_off;
/// Velocity of the next note to play
float queue_vel;
/// Integer value for modwheel (0-16383, read from CC1 - MSBs and CC33 - LSBs)
@@ -122,6 +124,8 @@ public:
static void precalculate_waves(progress_report_iface *reporter);
void set_sample_rate(uint32_t sr);
void delayed_note_on();
/// Release a note (physically), called from note-off handler or when note-off has been scheduled after note-on (very short queued note)
void end_note();
/// Handle MIDI Note On message (does not immediately trigger a note, as it must start on
/// boundary of step_size samples).
void note_on(int note, int vel);

View File

@@ -76,6 +76,7 @@ void monosynth_audio_module::activate() {
stack.clear();
last_pwshift1 = last_pwshift2 = 0;
last_stretch1 = 65536;
queue_note_on_and_off = false;
}
waveform_family<MONOSYNTH_WAVE_BITS> *monosynth_audio_module::waves;
@@ -433,6 +434,12 @@ void monosynth_audio_module::delayed_note_on()
queue_note_on = -1;
float modsrc[modsrc_count] = { 1, velocity, inertia_pressure.get_last(), modwheel_value, envelope1.value, envelope2.value, 0.5+0.5*lfo1.last, 0.5+0.5*lfo2.last};
calculate_modmatrix(moddest, moddest_count, modsrc);
if (queue_note_on_and_off)
{
end_note();
queue_note_on_and_off = false;
}
}
void monosynth_audio_module::set_sample_rate(uint32_t sr) {
@@ -629,6 +636,7 @@ void monosynth_audio_module::apply_fadeout()
void monosynth_audio_module::note_on(int note, int vel)
{
queue_note_on = note;
queue_note_on_and_off = false;
last_key = note;
queue_vel = vel / 127.f;
stack.push(note);
@@ -637,29 +645,40 @@ void monosynth_audio_module::note_on(int note, int vel)
void monosynth_audio_module::note_off(int note, int vel)
{
stack.pop(note);
if (note == queue_note_on)
{
queue_note_on_and_off = true;
return;
}
// If releasing the currently played note, try to get another one from note stack.
if (note == last_key) {
if (stack.count())
{
last_key = note = stack.nth(stack.count() - 1);
start_freq = freq;
target_freq = freq = dsp::note_to_hz(note);
porta_time = 0;
set_frequency();
if (!(legato & 1)) {
envelope1.note_on();
envelope2.note_on();
stopping = false;
running = true;
}
return;
}
gate = false;
envelope1.note_off();
envelope2.note_off();
end_note();
}
}
void monosynth_audio_module::end_note()
{
if (stack.count())
{
int note;
last_key = note = stack.nth(stack.count() - 1);
start_freq = freq;
target_freq = freq = dsp::note_to_hz(note);
porta_time = 0;
set_frequency();
if (!(legato & 1)) {
envelope1.note_on();
envelope2.note_on();
stopping = false;
running = true;
}
return;
}
gate = false;
envelope1.note_off();
envelope2.note_off();
}
void monosynth_audio_module::channel_pressure(int value)
{
inertia_pressure.set_inertia(value * (1.0 / 127.0));