From 0c58c12d0f01170f061429a573705f6a4883f9d5 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 30 Apr 2023 20:58:06 +0200 Subject: [PATCH] audio fastpath: reduce filter delay - reduced filter strength, which also reduces delays - increased I2S buffer count, and reduced I2S cycle time to recover from delays faster. --- usermods/audioreactive/audio_reactive.h | 13 +++++++++++++ usermods/audioreactive/audio_source.h | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index 05305671..a4807016 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -254,7 +254,11 @@ constexpr SRate_t SAMPLE_RATE = 22050; // Base sample rate in Hz - 22Khz //constexpr SRate_t SAMPLE_RATE = 16000; // 16kHz - use if FFTtask takes more than 20ms. Physical sample time -> 32ms //constexpr SRate_t SAMPLE_RATE = 20480; // Base sample rate in Hz - 20Khz is experimental. Physical sample time -> 25ms //constexpr SRate_t SAMPLE_RATE = 10240; // Base sample rate in Hz - previous default. Physical sample time -> 50ms +#ifdef WLEDMM_FASTPATH #define FFT_MIN_CYCLE 21 // minimum time before FFT task is repeated. Use with 22Khz sampling +#else +#define FFT_MIN_CYCLE 15 // reduce min time, to allow faster catch-up when I2S is lagging +#endif //#define FFT_MIN_CYCLE 30 // Use with 16Khz sampling //#define FFT_MIN_CYCLE 23 // minimum time before FFT task is repeated. Use with 20Khz sampling //#define FFT_MIN_CYCLE 46 // minimum time before FFT task is repeated. Use with 10Khz sampling @@ -1129,8 +1133,13 @@ class AudioReactive : public Usermod { { float sampleAdj; // Gain adjusted sample value float tmpSample; // An interim sample variable used for calculatioins. +#ifdef WLEDMM_FASTPATH + constexpr float weighting = 0.35f; // slightly reduced filter strength, to reduce audio latency + constexpr float weighting2 = 0.25f; +#else const float weighting = 0.2f; // Exponential filter weighting. Will be adjustable in a future release. const float weighting2 = 0.073f; // Exponential filter weighting, for rising signal (a bit more robust against spikes) +#endif const int AGC_preset = (soundAgc > 0)? (soundAgc-1): 0; // make sure the _compiler_ knows this value will not change while we are inside the function static bool isFrozen = false; static bool haveSilence = true; @@ -1732,7 +1741,11 @@ class AudioReactive : public Usermod { // get AGC sensitivity and sound pressure static unsigned long lastEstimate = 0; +#ifdef WLEDMM_FASTPATH + if (millis() - lastEstimate > 7) { +#else if (millis() - lastEstimate > 12) { +#endif lastEstimate = millis(); agcSensitivity = getSensitivity(); if (limiterOn) diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index 088574d3..084c8215 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -180,8 +180,13 @@ class I2SSource : public AudioSource { #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0) .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S), //.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, +#ifdef WLEDMM_FASTPATH + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3, // seems to reduce noise + .dma_buf_count = 28, // 160ms buffer (128 * dma_buf_count / sampleRate) +#else .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, .dma_buf_count = 8, +#endif .dma_buf_len = _blockSize, .use_apll = 0, //.fixed_mclk = 0,