From e9205c88fae477ba98f5fb297dcff124f609537b Mon Sep 17 00:00:00 2001 From: Jose Date: Fri, 25 Apr 2025 08:57:10 +0200 Subject: [PATCH] Dynamic rangelimit on serial --- src/main.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 3df1c9c..8b230eb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include #include +#include // you shouldn't need to change these settings #define SAMPLE_BUFFER_SIZE 512 @@ -11,13 +12,67 @@ #define I2S_MIC_LEFT_RIGHT_CLOCK 9 #define I2S_MIC_SERIAL_DATA 10 +// Add sample history tracking for range limiting +#define HISTORY_DURATION_MS 3000 // 3 seconds history +#define SAMPLES_PER_MS (SAMPLE_RATE / 1000) +#define HISTORY_SIZE (HISTORY_DURATION_MS * SAMPLES_PER_MS) + +class AudioLevelTracker { +public: + AudioLevelTracker() { + resetMaxLevel(); + } + + void updateMaxLevel(int32_t sample) { + uint32_t currentTime = millis(); + + // Remove old samples (older than 10 seconds) + while (!sampleHistory.empty() && + (currentTime - sampleHistory.front().timestamp) > HISTORY_DURATION_MS) { + sampleHistory.pop_front(); + } + + // Add new sample + int32_t absValue = abs(sample); + SamplePoint newPoint = {currentTime, absValue}; + sampleHistory.push_back(newPoint); + + // Update maximum + maxLevel = 0; + for (const auto& point : sampleHistory) { + if (point.value > maxLevel) { + maxLevel = point.value; + } + } + } + + int32_t getMaxLevel() const { + return maxLevel; + } + + void resetMaxLevel() { + maxLevel = 0; + sampleHistory.clear(); + } + +private: + struct SamplePoint { + uint32_t timestamp; + int32_t value; + }; + std::deque sampleHistory; + int32_t maxLevel; +}; + +AudioLevelTracker audioLevelTracker; + // don't mess around with this i2s_config_t i2s_config = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), .sample_rate = SAMPLE_RATE, .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, - .communication_format = I2S_COMM_FORMAT_I2S, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, // Updated from I2S_COMM_FORMAT_I2S .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, .dma_buf_count = 4, .dma_buf_len = 1024, @@ -48,17 +103,24 @@ void loop() size_t bytes_read = 0; i2s_read(I2S_NUM_0, raw_samples, sizeof(int32_t) * SAMPLE_BUFFER_SIZE, &bytes_read, portMAX_DELAY); int samples_read = bytes_read / sizeof(int32_t); - // dump the samples out to the serial channel. + + // Calculate dynamic range limit based on max level from last 10 seconds + int32_t currentMaxLevel = audioLevelTracker.getMaxLevel(); + int32_t rangelimit = currentMaxLevel > 0 ? currentMaxLevel : 20000; // fallback to default if no history + + // dump the samples out to the serial channel for (int i = 0; i < samples_read; i++) { - // False print statements to "lock range" on serial plotter display - // Change rangelimit value to adjust "sensitivity" - int rangelimit = 2000000; + // Update the max level tracker with current sample + audioLevelTracker.updateMaxLevel(raw_samples[i]); + + // Print range limits for plotter Serial.print(rangelimit * -1); Serial.print(" "); Serial.print(rangelimit); Serial.print(" "); + // Print the actual sample Serial.printf("%ld\n", raw_samples[i]); } } \ No newline at end of file