usb_audio – Stream audio to a host computer via USB

This makes your CircuitPython device identify to the host computer as a USB Audio Class (UAC2) microphone: the board is the audio source and streams samples to the host over a USB isochronous IN endpoint.

This mode requires 1 IN endpoint and 2 interfaces. Generally, microcontrollers have a limit on the number of endpoints. If you exceed the number of endpoints, CircuitPython will automatically enter Safe Mode. Even in this case, you may be able to enable USB audio by also disabling other USB functions, such as usb_hid or usb_midi.

To enable this mode, you must configure the audio format in boot.py and then use the usb_microphone singleton instance in code.py.

# boot.py
import usb_audio
usb_audio.enable(sample_rate=16000, channel_count=1, bits_per_sample=16)
# code.py
import time
import usb_audio
import synthio

# usb_audio.usb_microphone is a singleton instance (created by enable() above),
# not a class you construct. It is a consumer of an audio sample, just like
# audioio.AudioOut: the samples it pulls are streamed to the host PC instead
# of to a pin.
mic = usb_audio.usb_microphone
synth = synthio.Synthesizer(sample_rate=16000, channel_count=1)
mic.play(synth, loop=True)

c_major_scale = [60, 62, 64, 65, 67, 69, 71, 72]
try:
    while True:
        for note in c_major_scale:
            synth.press(note)
            time.sleep(0.1)
            synth.release(note)
            time.sleep(0.05)
except KeyboardInterrupt:
    pass
mic.stop()

The sample_rate and channel_count of the sample played must match the values passed to enable, and the sample must be 16-bit signed; otherwise play raises a ValueError.

This interface is experimental and may change without notice even in stable versions of CircuitPython.

Available on these boards
  • 0xCB Gemini
  • 0xCB Helios
  • 42. Keebs Frood
  • 8086 RP2040 Interfacer
  • 8086 USB Interposer
  • ARAMCON Badge 2019
  • ARAMCON2 Badge
  • Adafruit CLUE nRF52840 Express
  • Adafruit Circuit Playground Bluefruit
  • Adafruit Feather Bluefruit Sense
  • Adafruit Feather RP2040
  • Adafruit Feather RP2040 Adalogger
  • Adafruit Feather RP2040 CAN
  • Adafruit Feather RP2040 DVI
  • Adafruit Feather RP2040 Prop-Maker
  • Adafruit Feather RP2040 RFM
  • Adafruit Feather RP2040 Scorpio
  • Adafruit Feather RP2040 ThinkInk
  • Adafruit Feather RP2040 USB Host
  • Adafruit Feather RP2350
  • Adafruit Feather RP2350 Adalogger
  • Adafruit Feather nRF52840 Express
  • Adafruit Floppsy RP2040
  • Adafruit Fruit Jam
  • Adafruit ItsyBitsy RP2040
  • Adafruit ItsyBitsy nRF52840 Express
  • Adafruit KB2040
  • Adafruit LED Glasses Driver nRF52840
  • Adafruit Macropad RP2040
  • Adafruit Metro RP2040
  • Adafruit Metro RP2350
  • Adafruit Metro nRF52840 Express
  • Adafruit QT Py RP2040
  • Adafruit QT2040 Trinkey
  • Adafruit Tinychad RP2350
  • Archi RP2040
  • Arduino Nano RP2040 Connect
  • BBQ20KBD
  • BLOK
  • BastBLE
  • Bradán Lane STUDIO Explorer Badge
  • COSMO-Pico
  • Challenger NB RP2040 WiFi
  • Challenger RP2040 LTE
  • Challenger RP2040 LoRa
  • Challenger RP2040 SD/RTC
  • Challenger RP2040 SubGHz
  • Challenger RP2040 WiFi
  • Challenger RP2040 WiFi/BLE
  • Challenger+ RP2350 BConnect
  • Challenger+ RP2350 WiFi6/BLE5
  • Cytron EDU PICO 2
  • Cytron EDU PICO W
  • Cytron IRIV IO Controller
  • Cytron MOTION 2350 Pro
  • Cytron Maker Nano RP2040
  • Cytron Maker Pi RP2040
  • Cytron Maker Uno RP2040
  • Datanoise PicoADK
  • Datanoise PicoADK V2
  • E-Fidget
  • ELECFREAKS PICO:ED
  • Electrolama minik
  • EncoderPad RP2040
  • Fig Pi
  • HEIA-FR Picomo V2
  • HEIA-FR Picomo V3
  • HXR.DK SAO Digital Multimeter
  • Hack Club Sprig
  • HiiBot BlueFi
  • LILYGO T-DISPLAY
  • MakerDiary nRF52840 MDK
  • Makerdiary M60 Keyboard
  • Makerdiary Pitaya Go
  • Makerdiary nRF52840 Connect Kit
  • Makerdiary nRF52840 M.2 Developer Kit
  • Maple Computing Elite-Pi
  • Melopero Shake RP2040
  • Music Thing Modular Workshop Computer
  • Noise Nugget 2040
  • OMNIMO nRF52840
  • Oak Dev Tech BREAD2040
  • Oak Dev Tech Cast-Away RP2040
  • Oak Dev Tech RPGA Feather
  • Open Hardware Summit 2020 Badge
  • Orpheus Pico
  • PCA10056 nRF52840-DK
  • PCBCupid Glyph Mini 2040
  • PROVES Kit v4
  • Pajenicko PicoPad
  • Particle Argon
  • Particle Boron
  • Particle Xenon
  • Pimoroni Badger 2040
  • Pimoroni Badger 2040 W
  • Pimoroni Badger 2350
  • Pimoroni Explorer
  • Pimoroni Inky Frame 5.7
  • Pimoroni Inky Frame 7.3
  • Pimoroni Interstate 75
  • Pimoroni Keybow 2040
  • Pimoroni Motor 2040
  • Pimoroni PGA2040
  • Pimoroni PGA2350
  • Pimoroni Pico DV Base W
  • Pimoroni Pico LiPo (16MB)
  • Pimoroni Pico LiPo (4MB)
  • Pimoroni Pico Plus 2
  • Pimoroni Pico Plus 2 W
  • Pimoroni Pico dv Base
  • Pimoroni PicoSystem
  • Pimoroni Plasma 2040
  • Pimoroni Plasma 2040W
  • Pimoroni Plasma 2350
  • Pimoroni Plasma 2350W
  • Pimoroni Servo 2040
  • Pimoroni Tiny 2040 (2MB)
  • Pimoroni Tiny 2040 (8MB)
  • Pimoroni Tiny 2350
  • Pimoroni Tiny FX
  • PyKey 18 Numpad
  • PyKey 44 Ergo
  • PyKey 60
  • PyKey 87 TKL
  • RF.Guru RP2040
  • RP2.65-F
  • RP2040 Stamp
  • RP2350 Stamp
  • RP2350 Stamp XL
  • Raspberry Breadstick
  • Raspberry Pi Pico
  • Raspberry Pi Pico 2
  • Raspberry Pi Pico 2 W
  • Raspberry Pi Pico W
  • Seeed XIAO nRF52840 Sense
  • Seeeduino XIAO RP2040
  • Seeeduino XIAO RP2350
  • Silicognition LLC RP2040-Shim
  • SparkFun MicroMod RP2040 Processor
  • SparkFun MicroMod nRF52840 Processor
  • SparkFun Pro Micro RP2040
  • SparkFun Pro Micro RP2350
  • SparkFun Thing Plus - RP2040
  • SparkFun Thing Plus RP2350
  • Studiolab Pico Expander
  • TG-Watch
  • TinkeringTech ScoutMakes Azul
  • TinyCircuits Thumby
  • TinyCircuits Thumby Color
  • VCC-GND Studio YD RP2040
  • W5100S-EVB-Pico
  • W5100S-EVB-Pico2
  • W5500-EVB-Pico
  • W5500-EVB-Pico2
  • WK-50 Trackball Keyboard
  • WSC-1450
  • Waveshare RP2040-GEEK
  • Waveshare RP2040-LCD-0.96
  • Waveshare RP2040-LCD-1.28
  • Waveshare RP2040-One
  • Waveshare RP2040-PiZero
  • Waveshare RP2040-Plus (16MB)
  • Waveshare RP2040-Plus (4MB)
  • Waveshare RP2040-TOUCH-LCD-1.28
  • Waveshare RP2040-Tiny
  • Waveshare RP2040-Zero
  • Waveshare RP2350-GEEK
  • Waveshare RP2350-LCD-0.96
  • Waveshare RP2350-LCD-1.28
  • Waveshare RP2350-One
  • Waveshare RP2350-Plus
  • Waveshare RP2350-TOUCH-LCD-1.28
  • Waveshare RP2350-Tiny
  • Waveshare RP2350-Zero
  • WeAct Studio Pico
  • WeAct Studio Pico 16MB
  • WeAct Studio RP2350B Core
  • WisdPi Ardu2040M
  • WisdPi Tiny RP2040
  • iLabs Challenger 840
  • nullbits Bit-C PRO
  • splitkb.com Liatris
  • takayoshiotake Octave RP2040
  • uGame22

usb_audio.usb_microphone: USBMicrophone | None

The shared USBMicrophone singleton instance, or None until usb_audio.enable() has configured an input (microphone) stream in boot.py. USBMicrophone is exposed only as a type; you do not construct it.

usb_audio.usb_speaker: USBSpeaker | None

The shared USBSpeaker singleton instance, or None until usb_audio.enable() has configured an output (speaker) stream in boot.py. USBSpeaker is exposed only as a type; you do not construct it.

usb_audio.enable(sample_rate: int = 16000, channel_count: int = 1, bits_per_sample: int = 16, microphone: bool = True, speaker: bool = False) None

Enable the USB audio interface with the given PCM format.

This function may only be used from boot.py.

Parameters:
  • sample_rate (int) – Samples per second of the streamed audio.

  • channel_count (int) – Number of channels. Only mono (1) is supported initially.

  • bits_per_sample (int) – Bits per signed PCM sample. Only 16 is supported initially.

  • microphone (bool) – Present a microphone (audio flows board -> host). Enabled by default.

  • speaker (bool) – Present a speaker (audio flows host -> board).

Enabling both microphone and speaker presents a combined headset. At least one of the two must be enabled.

class usb_audio.USBMicrophone

Streams an audio sample to the host computer as a USB Audio Class microphone.

A USBMicrophone is a consumer of an audio sample, exactly like audioio.AudioOut, audiobusio.I2SOut and audiopwmio.PWMAudioOut. The samples it pulls are streamed to the host PC over USB rather than to a pin, so the board appears as a microphone.

You cannot create an instance of usb_audio.USBMicrophone.

There is a single shared instance, available as usb_audio.usb_microphone once usb_audio.enable() has configured an input (microphone) stream in boot.py. Until then usb_audio.usb_microphone is None.

__enter__() USBMicrophone

No-op used by Context Managers.

__exit__() None

Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for more info.

play(sample: circuitpython_typing.AudioSample, *, loop: bool = False) None

Streams the sample to the host once when loop=False and continuously when loop=True. Does not block. Use playing to block.

Sample must be an audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer, audiomp3.MP3Decoder or synthio.Synthesizer.

stop() None

Stops streaming and resets to the start of the sample.

playing: bool

True when an audio sample is being streamed even if paused. (read-only)

pause() None

Stops streaming temporarily while remembering the position. Use resume to resume.

resume() None

Resumes streaming after pause().

paused: bool

True when streaming is paused. (read-only)

class usb_audio.USBSpeaker

Plays audio streamed from the host computer as a USB Audio Class speaker.

A USBSpeaker is a source of audio samples, exactly like audiocore.RawSample or audiocore.WaveFile. The host PC streams audio to the board over USB, and the USBSpeaker hands that audio to a consumer such as audiobusio.I2SOut, audiopwmio.PWMAudioOut or audioio.AudioOut (optionally through the effect modules), so the board appears as a speaker.

You cannot create an instance of usb_audio.USBSpeaker.

There is a single shared instance, available as usb_audio.usb_speaker once usb_audio.enable() has configured an output (speaker) stream in boot.py. Until then usb_audio.usb_speaker is None.

# boot.py
import usb_audio
usb_audio.enable(sample_rate=16000, channel_count=1, bits_per_sample=16,
                 microphone=False, speaker=True)
# code.py
import board
import usb_audio
import audiobusio

spk = usb_audio.usb_speaker
out = audiobusio.I2SOut(board.I2S_BIT_CLOCK, board.I2S_WORD_SELECT, board.I2S_DATA)
out.play(spk, loop=True)
while True:
    pass
read(destination: circuitpython_typing.WriteableBuffer, destination_length: int) int

Copies up to destination_length of the most recent samples streamed from the host into destination, for analysis such as an audio-reactive effect or VU meter. This does not block: it returns whatever the host has delivered so far, which may be fewer than destination_length samples (or zero when the host is not streaming).

destination must be an array.array of 16-bit signed samples (typecode "h"), matching the negotiated speaker format.

Reading consumes the samples, so a USBSpeaker being read this way should not also be passed to an output backend’s play() at the same time.

Returns:

The number of samples copied into destination.

__enter__() USBSpeaker

No-op used by Context Managers.

__exit__() None

Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for more info.

connected: bool

True while the host is streaming audio to this speaker. (read-only)

sample_rate: int

The sample rate negotiated with the host in boot.py. (read-only)

bits_per_sample: int

The bit depth negotiated with the host in boot.py. (read-only)

channel_count: int

The number of channels negotiated with the host in boot.py. (read-only)