Skip to content

ESP32-C3: support audio file playback (SPI SD card and I2S audio out) (QEMU-297)#158

Draft
dragonx wants to merge 4 commits into
espressif:esp-developfrom
oroblancoinc:oro_i2s
Draft

ESP32-C3: support audio file playback (SPI SD card and I2S audio out) (QEMU-297)#158
dragonx wants to merge 4 commits into
espressif:esp-developfrom
oroblancoinc:oro_i2s

Conversation

@dragonx

@dragonx dragonx commented Jul 2, 2026

Copy link
Copy Markdown

Description

This PR adds just enough support to emulate audio playback from SD card on an emulated esp32-c3, specifically with MicroPython 1.26/1.27 (haven't tested 1.28 yet).

We add GDMA support for SPI2 read, and verified that mounting and reading a FAT16 SD card image works in MicroPython.

I2S0 output has been tested using the MicroPython I2S class, and has been tested with very limited scenarios: 16-bit, 44.1/48kHz, mono and stereo, that's all.

The emulated I2S0 device has an optional chardev sink for the PCM it drains from the I2S TX DMA stream. Attach any QEMU chardev with:

-chardev <backend>,id=i2s -global driver=esp32c3.i2s,property=chardev,value=i2s

Capture to a file for offline inspection:

-chardev file,id=i2s,path=/tmp/i2s_out.pcm -global driver=esp32c3.i2s,property=chardev,value=i2s

Or stream live over a (websocket-capable) socket, e.g.:

-chardev socket,id=i2s,host=127.0.0.1,port=5002,server=on,wait=off,websocket=on -global driver=esp32c3.i2s,property=chardev,value=i2s

The stream is raw interleaved signed 16-bit little-endian PCM at the configured sample rate / channel count. Buffer consumption is paced to ~real time from the I2S clock registers, so the capture runs at roughly the audio's natural duration.

Testing

Tested with micropython 1.26/1.27. A FAT SD Card image was created with multiple MP3 files, and mounted using:

            self.sd = SDCard(
                sck=Pin(self.SD_SCLK),
                mosi=Pin(self.SD_MOSI),
                miso=Pin(self.SD_MISO),
                cs=Pin(self.SD_CS),
            )
            vfs.mount(vfs.VfsFat(self.sd), "/sdcard")  # esp-adf seems to require the /sdcard name

I2S was initialized in MicroPython:

            i2s = I2S(
                0,
                sck=Pin(self.DAC_BCLK),
                ws=Pin(self.DAC_WCLK),
                sd=Pin(self.DAC_DIN),
                mode=I2S.TX,
                bits=16,
                format=I2S.MONO,
                rate=48000,
                ibuf=4096,
            )

MP3 files were decoded and played back using the esp-adf library.

Gabriel Chang added 3 commits February 24, 2026 21:44
Currently only verified support for 16 bit output, in mono and stereo,
and at 44.1kHz and 48kHz.
- Enable SPI2 DMA for reading from SD card
- fix issue with GDMA int register stride
- fix issue with deferred delivery in intmatrix
- Pull up SPI MISO line when idle, setting it to 0x0 caused driver to
  interpret as SD card being busy.
@github-actions github-actions Bot changed the title ESP32-C3: support audio file playback (SPI SD card and I2S audio out) ESP32-C3: support audio file playback (SPI SD card and I2S audio out) (QEMU-297) Jul 2, 2026
# Conflicts:
#	hw/riscv/esp32c3_intmatrix.c
#	hw/ssi/meson.build
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants