From ba27df8a814b51c8b9ad657975d4f0f3446bebcf Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Wed, 16 May 2018 08:35:40 +0200 Subject: [PATCH] Added function for setting max acceptable notes. Limited to 10 notes at a time to avoid xruns. --- MicroDexed.ino | 65 ++++++++++++++++++++++++---------------------- dexed.cpp | 70 ++++++++++++++++++++++++++++---------------------- dexed.h | 9 ++++--- 3 files changed, 80 insertions(+), 64 deletions(-) diff --git a/MicroDexed.ino b/MicroDexed.ino index 42f3ab9..ca22b25 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -14,14 +14,14 @@ #include #include "dexed.h" -#define AUDIO_MEM 32 +#define AUDIO_MEM 2 #define AUDIO_BUFFER_SIZE 128 #define SAMPLEAUDIO_BUFFER_SIZE 44100 #define INIT_AUDIO_QUEUE 1 //#define SHOW_DEXED_TIMING 1 #define SHOW_XRUN 1 -#define SHOW_CPU_LOAD #define SHOW_CPU_LOAD_MSEC 5000 +#define MAX_NOTES 10 #define TEST_MIDI 1 #define TEST_NOTE 40 #define TEST_VEL 60 @@ -40,7 +40,7 @@ IntervalTimer sched; void setup() { - while (!Serial) ; // wait for Arduino Serial Monitor + //while (!Serial) ; // wait for Arduino Serial Monitor Serial.begin(115200); Serial.println(F("MicroDexed based on https://github.com/asb2m10/dexed")); Serial.println(F("(c)2018 H. Wirtz")); @@ -56,7 +56,7 @@ void setup() sgtl5000_1.volume(0.2); // Initialize processor and memory measurements -#ifdef SHOW_CPU_LOAD +#ifdef SHOW_CPU_LOAD_MSEC AudioProcessorUsageMaxReset(); AudioMemoryUsageMaxReset(); #endif @@ -75,7 +75,8 @@ void setup() #endif dexed->activate(); - + dexed->setMaxNotes(MAX_NOTES); + #ifdef TEST_MIDI queue_midi_event(0x90, TEST_NOTE, TEST_VEL); // 1 @@ -89,17 +90,18 @@ void setup() queue_midi_event(0x90, TEST_NOTE + 32, TEST_VEL); // 9 queue_midi_event(0x90, TEST_NOTE + 37, TEST_VEL); // 10 queue_midi_event(0x90, TEST_NOTE + 40, TEST_VEL); // 11 - //queue_midi_event(0x90, TEST_NOTE + 44, TEST_VEL); // 12 - //queue_midi_event(0x90, TEST_NOTE + 49, TEST_VEL); // 13 - //queue_midi_event(0x90, TEST_NOTE + 52, TEST_VEL); // 14 - //queue_midi_event(0x90, TEST_NOTE + 57, TEST_VEL); // 15 - //queue_midi_event(0x90, TEST_NOTE + 60, TEST_VEL); // 16 + queue_midi_event(0x90, TEST_NOTE + 44, TEST_VEL); // 12 + queue_midi_event(0x90, TEST_NOTE + 49, TEST_VEL); // 13 + queue_midi_event(0x90, TEST_NOTE + 52, TEST_VEL); // 14 + queue_midi_event(0x90, TEST_NOTE + 57, TEST_VEL); // 15 + queue_midi_event(0x90, TEST_NOTE + 60, TEST_VEL); // 16 #endif -#ifdef SHOW_CPU_LOAD - sched.begin(cpu_and_mem_usage, SHOW_CPU_LOAD_MSEC*1000); +#ifdef SHOW_CPU_LOAD_MSEC + sched.begin(cpu_and_mem_usage, SHOW_CPU_LOAD_MSEC * 1000); #endif Serial.println(F("setup end")); + cpu_and_mem_usage(); } void loop() @@ -107,32 +109,35 @@ void loop() int16_t* audio_buffer; // pointer to 128 * int16_t bool break_for_calculation; - audio_buffer = queue1.getBuffer(); - if (audio_buffer == NULL) + while (42 == 42) // DON'T PANIC! { - Serial.println(F("audio_buffer allocation problems!")); - } + audio_buffer = queue1.getBuffer(); + if (audio_buffer == NULL) + { + Serial.println(F("audio_buffer allocation problems!")); + } - while (MIDI.read()) - { - break_for_calculation = dexed->ProcessMidiMessage(MIDI.getType(), MIDI.getData1(), MIDI.getData2()); - if (break_for_calculation == true) - break; - } + while (MIDI.read()) + { + break_for_calculation = dexed->ProcessMidiMessage(MIDI.getType(), MIDI.getData1(), MIDI.getData2()); + if (break_for_calculation == true) + break; + } #if defined(SHOW_DEXED_TIMING) || defined(SHOW_XRUN) - elapsedMicros t1; + elapsedMicros t1; #endif - dexed->GetSamples(AUDIO_BUFFER_SIZE, audio_buffer); + dexed->GetSamples(AUDIO_BUFFER_SIZE, audio_buffer); #ifdef SHOW_XRUN - uint32_t t2 = t1; - if (t2 > 2900) - Serial.println(F("xrun")); + uint32_t t2 = t1; + if (t2 > 2900) + Serial.println(F("xrun")); #endif #ifdef SHOW_DEXED_TIMING - Serial.println(t1, DEC); + Serial.println(t1, DEC); #endif - queue1.playBuffer(); + queue1.playBuffer(); + } } bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2) @@ -140,7 +145,7 @@ bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2) return (dexed->ProcessMidiMessage(type, data1, data2)); } -#ifdef SHOW_CPU_LOAD +#ifdef SHOW_CPU_LOAD_MSEC void cpu_and_mem_usage(void) { Serial.print(F("CPU:")); diff --git a/dexed.cpp b/dexed.cpp index c57dfb1..866646d 100644 --- a/dexed.cpp +++ b/dexed.cpp @@ -106,7 +106,7 @@ Dexed::~Dexed() { currentNote = -1; - for (uint8_t note = 0; note < MAX_ACTIVE_NOTES; ++note) + for (uint8_t note = 0; note < MAX_ACTIVE_NOTES; note++) delete voices[note].dx7_note; delete(engineMsfa); @@ -195,45 +195,45 @@ void Dexed::GetSamples(uint16_t n_samples, int16_t* buffer) extra_buf_size_ = i - n_samples; } -/* if (++_k_rate_counter == 0 && !monoMode) - { - uint8_t op_carrier = controllers.core->get_carrier_operators(data[134]); // look for carriers - - for (i = 0; i < max_notes; i++) + /* if (++_k_rate_counter == 0 && !monoMode) { - if (voices[i].live == true) - { - uint8_t op_amp = 0; - uint8_t op_carrier_num = 0; + uint8_t op_carrier = controllers.core->get_carrier_operators(data[134]); // look for carriers - voices[i].dx7_note->peekVoiceStatus(voiceStatus); - - for (uint8_t op = 0; op < 6; op++) + for (i = 0; i < max_notes; i++) + { + if (voices[i].live == true) { - uint8_t op_bit = static_cast(pow(2, op)); + uint8_t op_amp = 0; + uint8_t op_carrier_num = 0; - if ((op_carrier & op_bit) > 0) + voices[i].dx7_note->peekVoiceStatus(voiceStatus); + + for (uint8_t op = 0; op < 6; op++) { - // this voice is a carrier! - op_carrier_num++; + uint8_t op_bit = static_cast(pow(2, op)); + + if ((op_carrier & op_bit) > 0) + { + // this voice is a carrier! + op_carrier_num++; - //TRACE("Voice[%2d] OP [%d] amp=%ld,amp_step=%d,pitch_step=%d",i,op,voiceStatus.amp[op],voiceStatus.ampStep[op],voiceStatus.pitchStep); + //TRACE("Voice[%2d] OP [%d] amp=%ld,amp_step=%d,pitch_step=%d",i,op,voiceStatus.amp[op],voiceStatus.ampStep[op],voiceStatus.pitchStep); - if (voiceStatus.amp[op] <= 1069 && voiceStatus.ampStep[op] == 4) // this voice produces no audio output - op_amp++; + 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; + TRACE("Shutted down Voice[%2d]", i); } - } - 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; - TRACE("Shutted down Voice[%2d]", i); } } - } - } */ + } */ } bool Dexed::ProcessMidiMessage(uint8_t type, uint8_t data1, uint8_t data2) @@ -575,6 +575,16 @@ void Dexed::notes_off(void) { } } +void Dexed::setMaxNotes(uint8_t n) { + if (n <= MAX_ACTIVE_NOTES) + { + notes_off(); + max_notes = n; + panic(); + controllers.refresh(); + } +} + void Dexed::set_params(void) { /* //TRACE("Hi"); diff --git a/dexed.h b/dexed.h index 680f814..1f5f525 100644 --- a/dexed.h +++ b/dexed.h @@ -66,7 +66,9 @@ class Dexed void set_params(void); void GetSamples(uint16_t n_samples, int16_t* buffer); bool ProcessMidiMessage(uint8_t type, uint8_t data1, uint8_t data2); - + void panic(void); + void notes_off(void); + void setMaxNotes(uint8_t n); Controllers controllers; VoiceStatus voiceStatus; @@ -74,10 +76,9 @@ class Dexed //void onParam(uint8_t param_num,float param_val); void keyup(uint8_t pitch); void keydown(uint8_t pitch, uint8_t velo); - void panic(void); - void notes_off(void); - static const uint8_t MAX_ACTIVE_NOTES = 32; + + static const uint8_t MAX_ACTIVE_NOTES = 16; uint8_t max_notes = MAX_ACTIVE_NOTES; ProcessorVoice voices[MAX_ACTIVE_NOTES]; uint8_t currentNote;