diff --git a/MicroDexed.ino b/MicroDexed.ino index aebf63e..d68d092 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -123,6 +123,7 @@ uint8_t effect_delay_feedback = 0; uint8_t effect_delay_volume = 0; bool effect_delay_sync = 0; elapsedMicros fill_audio_buffer; +elapsedMillis control_rate; #ifdef SHOW_CPU_LOAD_MSEC elapsedMillis cpu_mem_millis; @@ -335,6 +336,13 @@ void loop() // MIDI input handling check_midi_devices(); + // Shutdown unused voices + if (control_rate > CONTROL_RATE_MS) + { + control_rate = 0; + uint8_t shutdown_voices = dexed->getNumNotesPlaying(); + } + #ifdef I2C_DISPLAY // UI if (master_timer >= TIMER_UI_HANDLING_MS) @@ -355,7 +363,7 @@ void loop() } /****************************************************************************** - * MIDI MESSAGE HANDLER + MIDI MESSAGE HANDLER ******************************************************************************/ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { @@ -654,9 +662,9 @@ void handleSystemReset(void) } /****************************************************************************** - * END OF MIDI MESSAGE HANDLER + END OF MIDI MESSAGE HANDLER ******************************************************************************/ - + bool checkMidiChannel(byte inChannel) { // check for MIDI channel diff --git a/config.h b/config.h index 77d4b90..6d2d771 100644 --- a/config.h +++ b/config.h @@ -60,7 +60,8 @@ //* DEXED AND EFECTS SETTINGS //************************************************************************************************* #define DEXED_ENGINE DEXED_ENGINE_MODERN // DEXED_ENGINE_MARKI // DEXED_ENGINE_OPL - +#define CONTROL_RATE_MS 200 + // EFFECTS #define FILTER_MAX_FREQ 10000 diff --git a/dexed.cpp b/dexed.cpp index 8a0a99e..33b3eee 100644 --- a/dexed.cpp +++ b/dexed.cpp @@ -63,7 +63,7 @@ Dexed::Dexed(int rate) voices[i].live = false; } - max_notes = 16; + max_notes = MAX_NOTES; currentNote = 0; resetControllers(); controllers.masterTune = 0; @@ -391,6 +391,51 @@ uint8_t Dexed::getMaxNotes(void) return max_notes; } +uint8_t Dexed::getNumNotesPlaying(void) +{ + uint8_t op_carrier = controllers.core->get_carrier_operators(data[134]); // look for carriers + uint8_t i; + + for (i = 0; i < max_notes; i++) + { + if (voices[i].live == true) + { + uint8_t op_amp = 0; + uint8_t op_carrier_num = 0; + + memset(&voiceStatus, 0, sizeof(VoiceStatus)); + + voices[i].dx7_note->peekVoiceStatus(voiceStatus); + + for (uint8_t op = 0; op < 6; op++) + { + uint8_t op_bit = static_cast(pow(2, op)); + + if ((op_carrier & op_bit) > 0) + { + { + // this voice is a carrier! + op_carrier_num++; + + if (voiceStatus.amp[op] <= 1069 && voiceStatus.ampStep[op] == 4) // this voice produces no audio output + op_amp++; + } + } + if (op_amp == op_carrier_num) + { + // all carrier-operators are silent -> disable the voice + voices[i].live = false; + voices[i].sustained = false; + voices[i].keydown = false; + Serial.print("Voice shutdown ["); + Serial.print(i,DEC); + Serial.println(F("]")); + } + } + } + } +} + bool Dexed::loadSysexVoice(uint8_t* new_data) { uint8_t* p_data = data; diff --git a/dexed.h b/dexed.h index 02a7383..de22102 100644 --- a/dexed.h +++ b/dexed.h @@ -160,6 +160,7 @@ class Dexed void keydown(uint8_t pitch, uint8_t velo); void setSustain(bool sustain); bool getSustain(void); + uint8_t getNumNotesPlaying(void); ProcessorVoice voices[MAX_NOTES]; Controllers controllers; @@ -190,6 +191,7 @@ class Dexed bool monoMode; bool refreshVoice; uint8_t engineType; + VoiceStatus voiceStatus; Lfo lfo; FmCore* engineMsfa; EngineMkI* engineMkI;