Compressed audio can be a nice alternative to uncompressed WAV files - especially when you have a small filesystem like that on many CircuitPython boards: those WAV files get pretty big fast! Thanks to the expiration of the MP3 patent pool, we can now include MP3 decoding as a core CircuitPython capability and you can even play multiple MP3s at a time!
CircuitPython supports any MP3 file you like. We've found that mono and stereo files from 32kbit/s to 128kbit/s work, with sample rates from 16kHz to 44.1kHz. The DAC output on the SAMD51 M4 is just 12-bit so there's not much point in using higher bitrates.
We're going to play one short mp3 file, wait for a button to be pressed, and then play a second short mp3 file. Use the same wiring as the other audio examples.
Because creating an MP3Decoder object takes a lot of memory, it's best to do this just once when your program starts, and then call the open() function of the MP3Decoder when you want to play a different file. Otherwise, you may encounter the dreaded MemoryError.
In the example below, click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, open the directory CircuitPython_Essentials/CircuitPython_Audio_Out_MP3/ and then click on the directory that matches the version of CircuitPython you're using and copy the contents of that directory to your CIRCUITPY drive.
Your CIRCUITPY
# SPDX-FileCopyrightText: 2020 Jeff Epler for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""CircuitPython Essentials Audio Out MP3 Example"""
import board
import digitalio
from audiomp3 import MP3Decoder
try:
from audioio import AudioOut
except ImportError:
try:
from audiopwmio import PWMAudioOut as AudioOut
except ImportError:
pass # not always supported by every board!
button = digitalio.DigitalInOut(board.A1)
button.switch_to_input(pull=digitalio.Pull.UP)
# The listed mp3files will be played in order
mp3files = ["slow.mp3", "happy.mp3"]
# You have to specify some mp3 file when creating the decoder
mp3 = open(mp3files[0], "rb")
decoder = MP3Decoder(mp3)
audio = AudioOut(board.A0)
while True:
for filename in mp3files:
# Updating the .file property of the existing decoder
# helps avoid running out of memory (MemoryError exception)
decoder.file = open(filename, "rb")
audio.play(decoder)
print("playing", filename)
# This allows you to do other things while the audio plays!
while audio.playing:
pass
print("Waiting for button press to continue!")
while button.value:
pass
Page last edited August 28, 2025
Text editor powered by tinymce.