From ddb43bd8e01a89fd1af923f4147cc8e07683dfa2 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 12 May 2020 11:37:14 +0200 Subject: [PATCH] Fixing play mode to "last priority played" and kliing oldest notes at the end of available free sound generators. Fixing wrong setting of polyphony at startup. --- MicroDexed.ino | 6 ++++-- UI.hpp | 4 ++-- dexed.cpp | 40 +++++++++++++++++++++++++++++++++++----- dexed.h | 1 + source_microdexed.h | 4 ++++ 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/MicroDexed.ino b/MicroDexed.ino index 338f613..d376685 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -1381,7 +1381,9 @@ void initial_values_from_eeprom(bool init) MicroDexed[instance_id]->controllers.refresh(); MicroDexed[instance_id]->setOPs(configuration.dexed[instance_id].op_enabled); MicroDexed[instance_id]->doRefreshVoice(); - + MicroDexed[instance_id]->setOPs(configuration.dexed[instance_id].op_enabled); + MicroDexed[instance_id]->setMaxNotes(configuration.dexed[instance_id].polyphony); + #if defined(USE_FX) //chorus_mixer[instance_id]->gain(0, 1.0 - pseudo_log_curve(mapfloat(configuration.fx.chorus_level[instance_id], CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0), true)); //chorus_mixer[instance_id]->gain(1, pseudo_log_curve(mapfloat(configuration.fx.chorus_level[instance_id], CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0), true)); @@ -1400,7 +1402,7 @@ void initial_values_from_eeprom(bool init) reverb_mixer_r.gain(instance_id, configuration.fx.reverb_send[instance_id] / 100.0); reverb_mixer_l.gain(instance_id, configuration.fx.reverb_send[instance_id] / 100.0); #endif - MicroDexed[instance_id]->setOPs(configuration.dexed[instance_id].op_enabled); + dexed_level[instance_id]->gain(mapfloat(configuration.dexed[instance_id].sound_intensity, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 0.0, SOUND_INTENSITY_AMP_MAX)); } diff --git a/UI.hpp b/UI.hpp index eb4bc45..9925adc 100644 --- a/UI.hpp +++ b/UI.hpp @@ -1927,15 +1927,15 @@ void UI_func_polyphony(uint8_t param) if (poly_instance_id == 0) { + MicroDexed[0]->setMaxNotes(configuration.dexed[0].polyphony); sprintf(poly_value_string, "%2d", configuration.dexed[0].polyphony); lcd.show(1, 3, 2, poly_value_string); - MicroDexed[0]->setMaxNotes(configuration.dexed[0].polyphony); } else { + MicroDexed[1]->setMaxNotes(configuration.dexed[1].polyphony); sprintf(poly_value_string, "%2d", configuration.dexed[1].polyphony); lcd.show(1, 13, 2, poly_value_string); - MicroDexed[1]->setMaxNotes(configuration.dexed[1].polyphony); } } diff --git a/dexed.cpp b/dexed.cpp index 9a05013..971c3f6 100644 --- a/dexed.cpp +++ b/dexed.cpp @@ -67,6 +67,7 @@ Dexed::Dexed(int rate) voices[i].keydown = false; voices[i].sustained = false; voices[i].live = false; + voices[i].key_pressed_timer = 0; } max_notes = MAX_NOTES; @@ -115,9 +116,6 @@ void Dexed::getSamples(uint16_t n_samples, int16_t* buffer) uint8_t note; float sumbuf[n_samples]; - if (max_notes == 0) - return; - if (refreshVoice) { for (i = 0; i < max_notes; i++) @@ -198,13 +196,37 @@ void Dexed::keydown(int16_t pitch, uint8_t velo) { voices[i].sustained = sustain; voices[i].live = true; voices[i].dx7_note->init(data, pitch, velo, pitch, porta, &controllers); + voices[i].key_pressed_timer = millis(); return; } } } - for (uint8_t i = 0; i < max_notes; i++) + for (uint8_t i = 0; i <= max_notes; i++) { + if (i == max_notes) + { + uint32_t min_timer = 0xffff; + + if (monoMode) + break; + + // no free sound slot found, so use the oldest note slot + for (uint8_t n = 0; n < max_notes; n++) + { + if (voices[n].key_pressed_timer < min_timer) + { + min_timer = voices[n].key_pressed_timer; + note = n; + } + } + voices[note].keydown = false; + voices[note].sustained = false; + voices[note].live = false; + voices[note].key_pressed_timer = 0; + keydown_counter--; + } + if (!voices[note].keydown) { currentNote = (note + 1) % max_notes; @@ -216,6 +238,8 @@ void Dexed::keydown(int16_t pitch, uint8_t velo) { voices[note].dx7_note->init(data, pitch, velo, srcnote, porta, &controllers); if ( data[136] ) voices[note].dx7_note->oscSync(); + voices[i].key_pressed_timer = millis(); + keydown_counter++; break; } else @@ -225,6 +249,7 @@ void Dexed::keydown(int16_t pitch, uint8_t velo) { note = (note + 1) % max_notes; } + if (keydown_counter == 0) lfo.keydown(); @@ -254,6 +279,8 @@ void Dexed::keyup(int16_t pitch) { if (pitch < 0) // for disabling the oldest note when cpu overload is detected { voices[currentNote].keydown = false; + voices[currentNote].key_pressed_timer = 0; + if (--max_notes == currentNote) currentNote = 0; } @@ -266,6 +293,8 @@ void Dexed::keyup(int16_t pitch) { for (note = 0; note < max_notes; note++) { if ( voices[note].midi_note == pitch && voices[note].keydown ) { voices[note].keydown = false; + voices[note].key_pressed_timer = 0; + break; } } @@ -287,6 +316,7 @@ void Dexed::keyup(int16_t pitch) { if ( highNote != -1 && voices[note].live ) { voices[note].live = false; + voices[note].key_pressed_timer = 0; voices[target].live = true; voices[target].dx7_note->transferState(*voices[note].dx7_note); } @@ -412,7 +442,7 @@ void Dexed::setMaxNotes(uint8_t n) { { notesOff(); max_notes = n; - panic(); + //panic(); controllers.refresh(); } } diff --git a/dexed.h b/dexed.h index c6ec2af..7544a6c 100644 --- a/dexed.h +++ b/dexed.h @@ -52,6 +52,7 @@ struct ProcessorVoice { bool keydown; bool sustained; bool live; + uint32_t key_pressed_timer; Dx7Note *dx7_note; }; diff --git a/source_microdexed.h b/source_microdexed.h index e57d6b3..2cb23dd 100644 --- a/source_microdexed.h +++ b/source_microdexed.h @@ -11,6 +11,10 @@ class AudioSourceMicroDexed : public AudioStream, public Dexed { uint16_t render_time_max = 0; AudioSourceMicroDexed(int sample_rate) : AudioStream(0, NULL), Dexed(sample_rate) { }; void update(void) { + + if (max_notes == 0) + return; + if (in_update) { xrun++; return;