Skip to content
This repository was archived by the owner on Oct 19, 2026. It is now read-only.
This repository was archived by the owner on Oct 19, 2026. It is now read-only.

I2SOut.starved() reads thousands of bytes on a clean P4 playback, and a gc.collect() makes it go down #26

Closed

Description

@bdbarnett

On the ESP32-P4 panel (ESP32_GENERIC_P4 PRE_REV3_C6_WIFI, MicroPython 1.29), I2SOut.starved() doesn't work as an underrun count. Through audiodev's audio_out() I played a looping 1 kHz RawSample at 24 kHz, with no recorder open:

play alone 1 s:                9654
3 s:                           9689
gc.collect() (4 ms):           510
after 3 more gc.collect():     1536
stop, play again, 1 s later:   9658

Starved audio can't un-happen, so the count should never go down, and a clean playback should read 0. An acoustic recording of the same kind of playback (through the panel's microphones, with the change in #25) shows no dropout at all: no 2 ms window falls below half the median envelope in six seconds.

So the number moves, but it isn't measuring silence on the wire. My guess is the wall-clock witness (due = fed0 + elapsed × byte_rate) set against fed0, which is taken at the last armed write. I haven't confirmed that. Until it's fixed, the honest underrun witness on this board is the recording, or i2s_sink_bytes() − i2s_dma_bytes() sampled over time, which stays flat to within one descriptor when nothing starves.

Activity

  1. added
    needs-boardNeeds a board on the bench (P4 panel, S3-Touch-4.3, T-Embed)
    on Oct 9, 2026
  2. bdbarnett commented on Oct 9, 2026

    @bdbarnett
    ContributorAuthor

    Fixed by #27. starved() now counts two events in the DMA's interrupt: a descriptor started empty (on_send_q_ovf), and the DMA standing still for more than two descriptor periods. It no longer subtracts what the pump has fed from where the wire is, which also carried the ring's fill level. On the P4 panel it reads 0 through clean playback, gc.collect() and recording while playing, and a planted 200 ms audiopump.park() reads 15 360 bytes (160 ms) and stays there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-boardNeeds a board on the bench (P4 panel, S3-Touch-4.3, T-Embed)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions