← How-Tos
electronics Jul 18, 2026 ◑ 43 views ◯ 5 min read

ESP32 I2S Audio: Playing and Recording Sound with a MAX98357A DAC and INMP441 Microphone

esp32i2saudiomax98357ainmp441microphonedacspeakerarduinofreertoshowto

Most ESP32 audio tutorials stop at "play a tone with the built-in DAC," which sounds thin and is limited to two low-quality analog output pins. I2S (Inter-IC Sound) is the actual path to decent audio on the ESP32 โ€” a dedicated hardware peripheral that streams digital audio directly to a DAC/amp chip or from a digital microphone, with no CPU-heavy bit-banging and real audio quality. This guide covers wiring and code for both playback (MAX98357A I2S DAC/amp) and recording (INMP441 I2S MEMS microphone) on the same board.

Why I2S Instead of Analog

Hardware Overview

ModuleFunctionInterfaceTypical cost class MAX98357AI2S digital input, Class-D mono amp output, drives a speaker directlyI2S in (BCLK, LRC, DIN), speaker outBreakout board, a few dollars INMP441I2S MEMS digital microphoneI2S out (SCK, WS, SD)Breakout board, a few dollars

Wiring โ€” Both Modules on One ESP32

Because the ESP32 has two I2S peripherals, wire the mic and the amp to separate pin sets rather than trying to share one bus:

MAX98357A pinESP32 pin (I2S0) BCLKGPIO27 LRC (WS)GPIO25 DINGPIO26 GAINLeave floating for 9dB default, or tie to GND/VDD per datasheet for other gain steps SD (shutdown)Tie high (3.3V) to enable, or drive from a GPIO to mute/unmute in software VIN / GND5V and GND โ€” the amp output stage wants 5V for real speaker volume, not 3.3V INMP441 pinESP32 pin (I2S1) SCK (BCLK)GPIO14 WSGPIO15 SD (data out)GPIO32 L/RTie to GND for left channel (mono capture, the standard wiring for a single mic) VDD / GND3.3V and GND โ€” this module is 3.3V only, do not feed it 5V

Playback Code (Arduino IDE)

Install the ESP32-audioI2S library (or use the ESP-IDF native driver/i2s.h for a lower-level approach). A minimal WAV-from-SPIFFS playback sketch:

#include "Audio.h" Audio audio; void setup() { Serial.begin(115200); SPIFFS.begin(true); audio.setPinout(27, 25, 26); // BCLK, LRC, DIN audio.setVolume(12); // 0-21 audio.connecttoFS(SPIFFS, "/chime.wav"); } void loop() { audio.loop(); }

For streaming from an SD card instead of SPIFFS, swap connecttoFS(SPIFFS, ...) for the SD-card variant the library exposes โ€” the I2S pinout call and playback loop structure stay the same.

Recording Code (Arduino IDE, ESP-IDF driver)

#include "driver/i2s.h" #define I2S_WS 15 #define I2S_SD 32 #define I2S_SCK 14 #define I2S_PORT I2S_NUM_1 void setup() { Serial.begin(115200); i2s_config_t config = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), .sample_rate = 16000, .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 = 8, .dma_buf_len = 256 }; i2s_pin_config_t pins = { .bck_io_num = I2S_SCK, .ws_io_num = I2S_WS, .data_out_num = I2S_PIN_NO_CHANGE, .data_in_num = I2S_SD }; i2s_driver_install(I2S_PORT, &config, 0, NULL); i2s_set_pin(I2S_PORT, &pins); } void loop() { int32_t samples[256]; size_t bytes_read; i2s_read(I2S_PORT, samples, sizeof(samples), &bytes_read, portMAX_DELAY); // samples now hold raw mic data โ€” write to SD as WAV, stream over WiFi, or feed to a VAD/wake-word routine }

The INMP441 outputs 24-bit data left-justified in a 32-bit word โ€” shift and mask accordingly if you're processing samples rather than just writing them straight to a WAV container.

Project Ideas This Unlocks

Power and Noise Notes

Troubleshooting

SymptomLikely cause No sound from speakerSD (shutdown) pin not pulled high, or BCLK/LRC/DIN pins swapped Distorted or clipped audioVolume set too high in software, or 3.3V powering the amp instead of 5V Mic reads all zeros or silenceL/R pin not tied to GND (or VDD, if you intended right-channel), or WS/SCK swapped Static/whine synced to WiFi transmitMissing decoupling capacitor, or I2S wiring running parallel to the antenna trace Playback stuttersSPIFFS/SD read speed bottleneck โ€” increase DMA buffer count/size, or move the audio file to a faster SD card

Once both directions are working independently, combining them into a full duplex system (record and play simultaneously, e.g. for a real intercom) mostly comes down to running both I2S peripherals concurrently in separate FreeRTOS tasks pinned to different cores โ€” see this site's dual-core ESP32 FreeRTOS content for that pattern.