Skip to content

stream protocol for I2SIn#11064

Merged
dhalbert merged 3 commits into
adafruit:mainfrom
FoamyGuy:audioi2sin_streaming_protocol
Jun 23, 2026
Merged

stream protocol for I2SIn#11064
dhalbert merged 3 commits into
adafruit:mainfrom
FoamyGuy:audioi2sin_streaming_protocol

Conversation

@FoamyGuy

@FoamyGuy FoamyGuy commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

This allows audioi2sin.I2SIn to be used in effects chains with various audio modules, and to be piped to an output source like AudioOut or USBMicrophone. Prior to this change I2SIn has only a simple record() API.

I tested with this basic code that passes audio from the I2S mic to USB as a microphone to the host computer, turning the MCU into a functional USB microphone.

import board
import audioi2sin
import usb_audio

usb_mic = usb_audio.usb_microphone

with audioi2sin.I2SIn(board.D5, board.D6, board.D9,
                      sample_rate=16000, bit_depth=16) as i2s_mic:

    usb_mic.play(i2s_mic)

    try:
        while True:
            pass
    except KeyboardInterrupt:
        pass

I also successfully tested a version with a handful of effects between the input and output so the device acts as a voice changer. I verified the original record API .wav file example works as expected as well.

@FoamyGuy

Copy link
Copy Markdown
Collaborator Author

The streaming protocol depends on audiocore. The latest commit disables audioi2sin on builds without audiocore to resolve those failing builds. Most of those were esp32 c3/c6 devices.

The memento (esp32s3) also had it disabled so I turned off audioi2sin to match. However, it may be worth revisiting that device, I did try a quick test build with audio enabled and it seemed to fit. I did no further testing, but I wondered if many of the modules disabled on that device were unable to fit before the OTA portion of flash was made available and now some of them could fit. I'm not certain how to interpret the values printed during a build, but many of the larger chunks were not close to full it seems.

@dhalbert dhalbert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good -- I did not go over the buffering code in full detail, but it is working well.

@dhalbert dhalbert merged commit 55e7735 into adafruit:main Jun 23, 2026
266 checks passed
Comment thread shared-bindings/audioi2sin/I2SIn.c
Comment thread shared-bindings/audioi2sin/I2SIn.c
Comment thread ports/raspberrypi/common-hal/audioi2sin/I2SIn.h
mp_obj_base_t base;
// MUST be first so I2SIn can be used directly as an audiosample source.
audiosample_base_t base;
uint32_t sample_rate;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be replaced by self->base.sample_rate.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the raspberrypi port the values for self->base.sample_rate and self->sample_rate end up being slightly different due to the pio clock frequency. The adjusted one is set here: https://github.com/FoamyGuy/circuitpython/blob/78d44093eae7f3b3d459bd4d836ee7140d560f41/ports/raspberrypi/common-hal/audioi2sin/I2SIn.c#L268

and comment here tries to explain the rational: https://github.com/FoamyGuy/circuitpython/blob/78d44093eae7f3b3d459bd4d836ee7140d560f41/ports/raspberrypi/common-hal/audioi2sin/I2SIn.c#L288-L293

Without this fix in place there was some sort of audible artifact in the captured sound.

Comment thread ports/raspberrypi/common-hal/audioi2sin/I2SIn.h
Comment thread shared-bindings/audioi2sin/I2SIn.c
Comment thread shared-bindings/audioi2sin/I2SIn.c
@dhalbert

Copy link
Copy Markdown
Collaborator

@relic-se Thanks for the more detailed review. I wanted to merge this to get it in and in use, but I agree it would be good to regularize the code. @FoamyGuy another cleanup PR later would be fine.

@relic-se

Copy link
Copy Markdown

@relic-se Thanks for the more detailed review. I wanted to merge this to get it in and in use, but I agree it would be good to regularize the code. @FoamyGuy another cleanup PR later would be fine.

I hadn't actually finished my review yet and was still going through the buffer code and other port implementations. I figured I'd just put it here now since y'all merged it. I'm fine with that, and I'm working on revisiting the PDMIn implementation to follow along these changes. I might roll in some cleanup along the way.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants