I apologise for anything lacking in my explanation/request for help; I have tried to be thorough; I'm a junior and have no recourse to assistance/advice in my company.
I finally got my setup working after adapting some I2S code -- reading the mic, FFTing it etc accurately to a pure tone played on a speaker.
Then... my mic started returning the same value e.g. `1070517748` for every sample (which when FFT'd, results in a 0 for every frequency's corresponding amplitude bucket). No crashes, no errors be it ESP_ERR or memory allocation issues.
My confusion is that, as far as I can tell, I haven't actually changed anything between when I got it working and when it broke... but I am extremely limited in the equipment and testing resources available to me. I would be enormously grateful for any pointers as to where this is going wrong, because previously I got this code giving me working audio!
Setup: INMP441 with an ESP32S3 dev kit.
https://imgur.com/a/5m75PuA
Things I've done:
- checked pins
- changed mic
- changed ESP32S3
- changed pin positions
- error checked the bytes-read (4096 being read)
- error checked the `esp_err_t` returned by `i2s_read()` (ESP_OK returned)
- Reverted to older, working commit (it has stopped working!)
- // ___________BUFFER HANDLING___________
- #define I2S_DMA_BUFFER_COUNT 4
- #define I2S_DMA_BUFFER_LENGTH 1024
- // ___________SAMPLE RATE HANDLING___________
- #define I2S_SAMPLE_RATE 3000
- // ___________INMP441 I2S microphone connections___________
- // These are defined in config.cpp
- extern i2s_pin_config_t I2S_MIC_PINS;
- extern i2s_config_t I2S_MIC_CONFIG;
- extern i2s_port_t I2S_MIC_PORT;
- #define I2S_MIC_WS 4
- #define I2S_MIC_SD 6
- #define I2S_MIC_SCK 5
- #include "config.h"
- i2s_port_t I2S_MIC_PORT = I2S_NUM_0;
- i2s_pin_config_t I2S_MIC_PINS = {
- .bck_io_num = I2S_MIC_SCK,
- .ws_io_num = I2S_MIC_WS,
- .data_out_num = I2S_PIN_NO_CHANGE,
- .data_in_num = I2S_MIC_SD,
- };
- i2s_config_t I2S_MIC_CONFIG = {
- .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
- .sample_rate = I2S_SAMPLE_RATE,
- .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
- .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
- .communication_format = I2S_COMM_FORMAT_STAND_I2S,
- .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
- .dma_buf_count = I2S_DMA_BUFFER_COUNT,
- .dma_buf_len = I2S_DMA_BUFFER_LENGTH,
- .use_apll = false, /* "Audio Phase-Locked Loop" */
- .tx_desc_auto_clear = false, /* helps in avoiding noise in case of underflow/data unavailability */
- .fixed_mclk = 0,
- };
- static const char* TAG = "I2S MIC";
- static i2s_port_t m_micPort;
- esp_err_t mic_init(i2s_port_t port, i2s_pin_config_t pins, i2s_config_t config)
- {
- esp_err_t ret = i2s_driver_install(port, &config, 0, NULL);
- if (ret != ESP_OK) {
- err_log_allOutputs(TAG, "i2s_driver_install", &ret, NULL);
- return ret;
- }
- sleep(0.05);
- ret = i2s_set_pin(port, &pins);
- if (ret != ESP_OK) {
- err_log_allOutputs(TAG, "i2s_set_pin", &ret, NULL);
- return ret;
- }
- sleep(0.05);
- ret = i2s_start(port);
- if (ret != ESP_OK) {
- err_log_allOutputs(TAG, "i2s_start", &ret, NULL);
- return ret;
- }
- m_micPort = port;
- return ret;
- }
- esp_err_t mic_deinit(void)
- {
- esp_err_t ret = i2s_driver_uninstall(m_micPort);
- if (ret != ESP_OK) {
- err_log_allOutputs(TAG, "mic_deinit", &ret, NULL);
- ESP_ERROR_CHECK_WITHOUT_ABORT(ret);
- }
- return ret;
- }
- int mic_read(i2s_port_t port, int16_t *samples, int count)
- {
- int32_t *raw_samples = (int32_t *)malloc(sizeof(int32_t) * count);
- size_t bytes_read = 0;
- esp_err_t result = i2s_read(port, raw_samples, sizeof(int32_t) * count, &bytes_read, portMAX_DELAY);
- // here some checking prints to serial
- int samples_read = bytes_read / sizeof(int32_t);
- for (int i = 0; i < samples_read; i++) {
- samples[i] = (raw_samples[i] & 0xFFFFFFF0) >> 11;
- }
- free(raw_samples);
- return samples_read;
- }
I am setting up and running like this (error checks et all stripped out):
- mic_init(I2S_MIC_PORT, I2S_MIC_PINS, I2S_MIC_CONFIG);
- ...
- int16_t* audioSamples = mic_allocateBuffer(samplesLen);
- int samplesRead = mic_read(I2S_MIC_PORT, audioSamples, I2S_DMA_BUFFER_LENGTH);
- ...
- mic_deinit();