From 20221e4c24fa969894e12799ca6f2a555193426d Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Sun, 2 Dec 2018 10:05:04 +0100 Subject: [PATCH] Fixed bad latency (about 50ms!) with a bad but woking hack. Now the latency is at about 5.5ms. Added a screenshot from latency measurement. --- MicroDexed.ino | 10 +++++++--- doc/MicroDexed_Latency.png | Bin 0 -> 19133 bytes 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 doc/MicroDexed_Latency.png diff --git a/MicroDexed.ino b/MicroDexed.ino index c93a5fb..2d18004 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -118,6 +118,7 @@ uint8_t effect_delay_time = 0; uint8_t effect_delay_feedback = 0; uint8_t effect_delay_volume = 0; bool effect_delay_sync = 0; +elapsedMicros fill_audio_buffer; #ifdef MASTER_KEY_MIDI bool master_key_enabled = false; @@ -330,16 +331,18 @@ void setup() void loop() { int16_t* audio_buffer; // pointer to AUDIO_BLOCK_SAMPLES * int16_t - const uint16_t audio_block_time_ms = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES); + const uint16_t audio_block_time_us = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES); // Main sound calculation - if (queue1.available()) + if (queue1.available() && fill_audio_buffer > audio_block_time_us-10) { + fill_audio_buffer = 0; + audio_buffer = queue1.getBuffer(); elapsedMicros t1; dexed->getSamples(AUDIO_BLOCK_SAMPLES, audio_buffer); - if (t1 > audio_block_time_ms) // everything greater 2.9ms is a buffer underrun! + if (t1 > audio_block_time_us) // everything greater 2.9ms is a buffer underrun! xrun++; if (t1 > render_time_max) render_time_max = t1; @@ -364,6 +367,7 @@ void loop() // MIDI input handling handle_input(); + #ifdef I2C_DISPLAY // UI if (master_timer >= TIMER_UI_HANDLING_MS) diff --git a/doc/MicroDexed_Latency.png b/doc/MicroDexed_Latency.png new file mode 100644 index 0000000000000000000000000000000000000000..fc5301d69e7b134672ceb5f26101655a43c0d69d GIT binary patch literal 19133 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