Arduino ide code for edge impulse esp32_contineous using esp32s3 devkit c1 and inmp441

Hello everyone, i am totally stuck. i trained a wake word model and it has some impressive output so i downloaded it's library(int8 quantized version) and started to try their example code of esp32_contineous code that they provide with the bundle. after a tweaking , also can not able to get atleast 10% of confidence output from the code- here is the code i am trying- #define EIDSP_QUANTIZE_FILTERBANK 0
#include <axxele_final_wake_word_inferencing.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/i2s.h"

#define LED_GPIO_PIN GPIO_NUM_38

typedef struct {
int16_t *buffer;
uint8_t buf_ready;
uint32_t buf_count;
uint32_t n_samples;
} inference_t;

static inference_t inference;
static const uint32_t sample_buffer_size = 2048;
static signed short sampleBuffer[sample_buffer_size];
static bool debug_nn = false;
static bool record_status = true;

bool led_on = false;
unsigned long led_start_time = 0;

void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("Edge Impulse Inferencing Demo");

ei_printf("Inferencing settings:\n");
ei_printf("\tInterval: ");
ei_printf_float((float)EI_CLASSIFIER_INTERVAL_MS);
ei_printf(" ms.\n");
ei_printf("\tFrame size: %d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
ei_printf("\tSample length: %d ms.\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16);
ei_printf("\tNo. of classes: %d\n", sizeof(ei_classifier_inferencing_categories) / sizeof(ei_classifier_inferencing_categories[0]));

ei_printf("\nStarting continuous inference in 2 seconds...\n");
ei_sleep(2000);

if (microphone_inference_start(EI_CLASSIFIER_RAW_SAMPLE_COUNT) == false) {
    ei_printf("ERR: Could not allocate audio buffer (size %d), this could be due to the window length of your model\r\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT);
    return;
}



gpio_set_direction(LED_GPIO_PIN, GPIO_MODE_OUTPUT);

ei_printf("Recording...\n");

}

void loop() {
bool m = microphone_inference_record();
if (!m) {
ei_printf("ERR: Failed to record audio...\n");
return;
}

signal_t signal;
signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT;
signal.get_data = &microphone_audio_signal_get_data;
ei_impulse_result_t result = { 0 };

EI_IMPULSE_ERROR r = run_classifier(&signal, &result, debug_nn);
if (r != EI_IMPULSE_OK) {
    ei_printf("ERR: Failed to run classifier (%d)\n", r);
    return;
}

// Print the predictions
ei_printf("Predictions ");
ei_printf("(DSP: %d ms., Classification: %d ms., Anomaly: %d ms.)",
    result.timing.dsp, result.timing.classification, result.timing.anomaly);
ei_printf(": \n");
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
    ei_printf("    %s: ", result.classification[ix].label);
    ei_printf_float(result.classification[ix].value);
    ei_printf("\n");
}

// Check if "axxele" is detected and its value is >= 0.5
if (strcmp(result.classification[0].label, "axxele") == 0 && result.classification[0].value >= 0.5) {
    // Turn on the built-in LED and start the timer
    led_on = true;
    led_start_time = millis();
    gpio_set_level(LED_GPIO_PIN, 1);
}

// Check if the LED has been on for 3 seconds
if (led_on && millis() - led_start_time >= 3000) {
    
    led_on = false;
    gpio_set_level(LED_GPIO_PIN, 0);
}

}

static void audio_inference_callback(uint32_t n_bytes) {
for(int i = 0; i < n_bytes>>1; i++) {
inference.buffer[inference.buf_count++] = sampleBuffer[i];

    if(inference.buf_count >= inference.n_samples) {
      inference.buf_count = 0;
      inference.buf_ready = 1;
    }
}

}

static void capture_samples(void* arg) {
const int32_t i2s_bytes_to_read = (uint32_t)arg;
size_t bytes_read = i2s_bytes_to_read;

while (record_status) {
    /* read data at once from i2s */
    i2s_read((i2s_port_t)1, (void*)sampleBuffer, i2s_bytes_to_read, &bytes_read, 100);

    if (bytes_read <= 0) {
        ei_printf("Error in I2S read : %d", bytes_read);
    }
    else {
        if (bytes_read < i2s_bytes_to_read) {
            ei_printf("Partial I2S read");
        }

        // Scale the data (otherwise the sound is too quiet)
        for (int x = 0; x < i2s_bytes_to_read/2; x++) {
            sampleBuffer[x] = (int16_t)(sampleBuffer[x]) * 8;
        }

        if (record_status) {
            audio_inference_callback(i2s_bytes_to_read);
        }
        else {
            break;
        }
    }
}
vTaskDelete(NULL);

}

static bool microphone_inference_start(uint32_t n_samples) {
inference.buffer = (int16_t *)malloc(n_samples * sizeof(int16_t));

if(inference.buffer == NULL) {
    return false;
}

inference.buf_count  = 0;
inference.n_samples  = n_samples;
inference.buf_ready  = 0;

if (i2s_init(EI_CLASSIFIER_FREQUENCY)) {
    ei_printf("Failed to start I2S!");
}

ei_sleep(100);

record_status = true;

xTaskCreate(capture_samples, "CaptureSamples", 1024 * 32, (void*)sample_buffer_size, 10, NULL);

return true;

}

static bool microphone_inference_record(void) {
bool ret = true;

while (inference.buf_ready == 0) {
    delay(10);
}

inference.buf_ready = 0;
return ret;

}

static int microphone_audio_signal_get_data(size_t offset, size_t length, float *out_ptr) {
numpy::int16_to_float(&inference.buffer[offset], out_ptr, length);

return 0;

}

static void microphone_inference_end(void) {
i2s_deinit();
ei_free(inference.buffer);
}

static int i2s_init(uint32_t sampling_rate) {
// Start listening for audio: MONO @ 8/16KHz
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = sampling_rate,
.bits_per_sample = (i2s_bits_per_sample_t)16,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = 0,
.dma_buf_count = 8,
.dma_buf_len = 512,
.use_apll = false,
.tx_desc_auto_clear = true,
.fixed_mclk = -1,
};
i2s_pin_config_t pin_config = {
.bck_io_num = 6, // IIS_SCLK
.ws_io_num = 5, // IIS_LCLK
.data_out_num = -1, // IIS_DSIN
.data_in_num = 4, // IIS_DOUT
};
esp_err_t ret = 0;

ret = i2s_driver_install((i2s_port_t)1, &i2s_config, 0, NULL);
if (ret != ESP_OK) {
ei_printf("Error in i2s_driver_install");
}

ret = i2s_set_pin((i2s_port_t)1, &pin_config);
if (ret != ESP_OK) {
ei_printf("Error in i2s_set_pin");
}

ret = i2s_zero_dma_buffer((i2s_port_t)1);
if (ret != ESP_OK) {
ei_printf("Error in initializing dma buffer with 0");
}

return int(ret);
}

static int i2s_deinit(void) {
i2s_driver_uninstall((i2s_port_t)1); //stop & destroy i2s driver
return 0;
}

#if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_MICROPHONE
#error "Invalid model for current sensor."
#endif

Any help or any kind of hints also is much appreaciated.(trained on two class- axxele and noise).

Are you using a Nano ESP32 or a generic ESP32 board ?

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the < CODE/ > icon above the compose window) to make it easier to read and copy for examination

https://forum.arduino.cc/t/how-to-get-the-best-out-of-this-forum

Please post your full sketch, using code tags when you do

Posting your code using code tags prevents parts of it being interpreted as HTML coding and makes it easier to copy for examination

In my experience the easiest way to tidy up the code and add the code tags is as follows

Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.

It is also helpful to post error messages in code tags as it makes it easier to scroll through them and copy them for examination

#define EIDSP_QUANTIZE_FILTERBANK   0
#include <axxele_final_wake_word_inferencing.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/i2s.h"

#define LED_GPIO_PIN    GPIO_NUM_38
#define SAMPLE_RATE     EI_CLASSIFIER_FREQUENCY  // Typically 16000
#define DEBUG_MODE      true  // Enable detailed serial prints

typedef struct {
    int16_t *buffer;
    uint8_t buf_ready;
    uint32_t buf_count;
    uint32_t n_samples;
} inference_t;

static inference_t inference;
static const uint32_t sample_buffer_size = 2048;
static signed short sampleBuffer[sample_buffer_size];
static bool record_status = true;
static bool led_on = false;
static unsigned long led_start_time = 0;

// DC offset removal variables
static int32_t dc_offset = 0;
static const float dc_alpha = 0.95f;

void setup() {
    Serial.begin(115200);
    while (!Serial);
    Serial.println("\nEdge Impulse Wake Word Detection\n");

    // Print model info
    ei_printf("Inferencing settings:\n");
    ei_printf("\tInterval: %.2f ms\n", (float)EI_CLASSIFIER_INTERVAL_MS);
    ei_printf("\tFrame size: %d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
    ei_printf("\tSample length: %d ms\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16);
    ei_printf("\tNo. of classes: %d\n", sizeof(ei_classifier_inferencing_categories) / 
              sizeof(ei_classifier_inferencing_categories[0]));

    // Initialize microphone
    if (!microphone_inference_start(EI_CLASSIFIER_RAW_SAMPLE_COUNT)) {
        ei_printf("ERR: Failed to allocate audio buffer\n");
        while(1);
    }

    // Setup LED
    gpio_set_direction(LED_GPIO_PIN, GPIO_MODE_OUTPUT);
    ei_printf("Ready - waiting for wake word...\n");
}

void loop() {
    if (!microphone_inference_record()) {
        ei_printf("ERR: Audio recording failed\n");
        return;
    }

    signal_t signal;
    signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT;
    signal.get_data = &microphone_audio_signal_get_data;

    ei_impulse_result_t result = {0};
    EI_IMPULSE_ERROR err = run_classifier(&signal, &result, DEBUG_MODE);
    
    if (err != EI_IMPULSE_OK) {
        ei_printf("ERR: Classification failed (%d)\n", err);
        return;
    }

    // Print predictions
    ei_printf("Predictions (DSP: %d ms, Class: %d ms):\n",
              result.timing.dsp, result.timing.classification);
              
    for (size_t i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
        ei_printf("  %s: %.3f\n", result.classification[i].label, 
                  result.classification[i].value);
    }

    // Trigger LED if wake word detected
    if (result.classification[0].value >= 0.5) {
        led_on = true;
        led_start_time = millis();
        gpio_set_level(LED_GPIO_PIN, 1);
        ei_printf("Wake word detected!\n");
    }

    // Turn off LED after 3 seconds
    if (led_on && (millis() - led_start_time >= 3000)) {
        led_on = false;
        gpio_set_level(LED_GPIO_PIN, 0);
    }
}

// Audio callback functions
static void audio_inference_callback(uint32_t n_bytes) {
    for (int i = 0; i < n_bytes>>1; i++) {
        inference.buffer[inference.buf_count++] = sampleBuffer[i];

        if (inference.buf_count >= inference.n_samples) {
            inference.buf_count = 0;
            inference.buf_ready = 1;
        }
    }
}

static void capture_samples(void* arg) {
    const uint32_t i2s_bytes_to_read = (uint32_t)arg;
    size_t bytes_read = 0;

    while (record_status) {
        // Read from I2S
        i2s_read((i2s_port_t)1, (void*)sampleBuffer, i2s_bytes_to_read, &bytes_read, portMAX_DELAY);

        if (bytes_read <= 0) {
            ei_printf("I2S Read Error: %d\n", bytes_read);
            continue;
        }

        if (DEBUG_MODE) {
            ei_printf("Raw Samples: ");
            for (int i = 0; i < 5; i++) {  // Print first 5 samples
                ei_printf("%d ", sampleBuffer[i]);
            }
            ei_printf("\n");
        }

        // Process audio samples
        for (int x = 0; x < bytes_read/2; x++) {
            // DC offset removal
            dc_offset = (int32_t)(dc_alpha * dc_offset + (1.0f - dc_alpha) * sampleBuffer[x]);
            sampleBuffer[x] = (int16_t)(sampleBuffer[x] - dc_offset) * 8;  // Apply gain
        }

        if (record_status) {
            audio_inference_callback(bytes_read);
        }
    }
    vTaskDelete(NULL);
}

// Microphone interface
static bool microphone_inference_start(uint32_t n_samples) {
    inference.buffer = (int16_t *)malloc(n_samples * sizeof(int16_t));
    if (!inference.buffer) return false;

    inference.buf_count = 0;
    inference.n_samples = n_samples;
    inference.buf_ready = 0;

    if (i2s_init(SAMPLE_RATE)) {
        ei_printf("Failed to initialize I2S!\n");
        return false;
    }

    ei_sleep(100);
    xTaskCreate(capture_samples, "CaptureSamples", 1024 * 32, 
               (void*)sample_buffer_size, 10, NULL);
    return true;
}

static bool microphone_inference_record(void) {
    while (inference.buf_ready == 0) {
        delay(1);
    }
    inference.buf_ready = 0;
    return true;
}

static int microphone_audio_signal_get_data(size_t offset, size_t length, float *out_ptr) {
    numpy::int16_to_float(&inference.buffer[offset], out_ptr, length);
    return 0;
}

static void microphone_inference_end(void) {
    i2s_deinit();
    free(inference.buffer);
}

// I2S Configuration
static int i2s_init(uint32_t sampling_rate) {
    i2s_config_t i2s_config = {
        .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
        .sample_rate = sampling_rate,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
        .communication_format = I2S_COMM_FORMAT_I2S,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 8,
        .dma_buf_len = 512,
        .use_apll = true,       // Better clock stability
        .tx_desc_auto_clear = false,
        .fixed_mclk = 0
    };

    i2s_pin_config_t pin_config = {
        .bck_io_num = 6,    // BCKL
        .ws_io_num = 5,
        .data_out_num = -1,      // LRCL
        .data_in_num = 4   // DOUT
       
    };

    // Install and configure I2S driver
    esp_err_t ret = i2s_driver_install((i2s_port_t)1, &i2s_config, 0, NULL);
    if (ret != ESP_OK) {
        ei_printf("I2S driver install failed: %d\n", ret);
        return 1;
    }

    ret = i2s_set_pin((i2s_port_t)1, &pin_config);
    if (ret != ESP_OK) {
        ei_printf("I2S pin config failed: %d\n", ret);
        return 1;
    }

    i2s_zero_dma_buffer((i2s_port_t)1);
    return 0;
}

static int i2s_deinit(void) {
    i2s_driver_uninstall((i2s_port_t)1);
    return 0;
}

#if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_MICROPHONE
#error "Invalid model for current sensor."
#endif

I am using ESP32S3 devkit C1-n8r8 from espressif

kindly see the code-

“ i downloaded it's library(int8 quantized version) and started to try their example “

Where did you download this library and example from?

Link?

i have trained my model on edge impulse

edge impulse ? This is a site or software?

kindly google youself mate

I moved your topic to a more appropriate forum category @sa0if.

The Nano Family > Nano ESP32 category you chose is only used for discussions directly related to the Arduino Nano ESP32 board.

In the future, when creating a topic please take the time to pick the forum category that best suits the subject of your question. There is an "About the _____ category" topic at the top of each category that explains its purpose.

Thanks in advance for your cooperation.

thanks mate. will try to remember this

Thank you very much.

I thought about checking the library to help you, but thanks to your kindness...

Until next time,

this is not a library issue mate, what i believe this is a i2s configuration issue. i tested the tflite model that was generated by edge impulse online with a live classification with a device that i have not used to collect samples eaither but to my surprise it detected the wake word as well as the noise perfectly.

I am sorry mate. please don't mind. been stuck for two days straight without having a clue what's to be done. Sorry again

You forgot to Auto Format the code, it is hard to read code with such deep indentation.