Dynamic rangelimit on serial

This commit is contained in:
2025-04-25 08:57:10 +02:00
parent 4654bea268
commit e9205c88fa

View File

@@ -1,5 +1,6 @@
#include <Arduino.h>
#include <driver/i2s.h>
#include <deque>
// 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<SamplePoint> 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]);
}
}