CircuitPython Audio Out

The Circuit Playground Express has some nice built in audio output capabilities.

There are two ways to get audio output, one is via the small built in speaker. The other is by using alligator clips to connect a headphone or speaker to the A0 pin.

The speaker is over here, its small but can make some loud sounds! You can ENABLE or disable the speaker. If you disable the speaker, audio will only come out the A0 pin. If you enable the speaker, audio will come out from both!

If you want to connect a speaker or headphones, use two alligator clips and connect GND to the sleeve of the headphone, and A0 to the tip

Basic Tones

We can start by making simple tones. We will play sine waves. We first generate a single period of a sine wave in python, with the math.sin function, and stick it into sine_wave.

Then we enable the speaker by setting the SPEAKER_ENABLE pin to be an output and True.

We can create the audio object with this line that sets the output pin and you give it the sample array

sample = audioio.AudioOut(board.SPEAKER, sine_wave)

Since you can change the sample rate (higher samples mean higher frequencies, higher quality but more memory usage) you should set that next:

sample.frequency = SAMPLERATE

Finally you can run - if you only want to play the sample once, call as is. If you want it to loop the sample, which we definitely do so its one long tone, pass in loop=True

You can then do whatever you like, the tone will play in the background until you call sample.stop()

import array
import math
import time

import audioio
import board
from digitalio import DigitalInOut, Direction

FREQUENCY = 440  # 440 Hz middle 'A'
SAMPLERATE = 8000  # 8000 samples/second, recommended!

# Generate one period of sine wav.
sine_wave = array.array("H", [0] * length)
for i in range(length):
    sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15)

# enable the speaker
spkrenable = DigitalInOut(board.SPEAKER_ENABLE)
spkrenable.direction = Direction.OUTPUT
spkrenable.value = True

sample = audioio.AudioOut(board.SPEAKER, sine_wave)
sample.frequency = SAMPLERATE  # keep playing the sample over and over
time.sleep(1)  # until...
sample.stop()  # we tell the board to stop

Playing Audio Files

Tones are lovely but lets play some music! You can drag-and-drop audio files onto the CIRCUITPY drive and then play them with a Python command

Here's the two files we're going to play:

Click to download, and save them onto your CIRCUITPY drive, alongside your and lib files

This is the example code we'll be using

import audioio
import board
from digitalio import DigitalInOut, Direction, Pull

# enable the speaker
spkrenable = DigitalInOut(board.SPEAKER_ENABLE)
spkrenable.direction = Direction.OUTPUT
spkrenable.value = True

# make the 2 input buttons
buttonA = DigitalInOut(board.BUTTON_A)
buttonA.direction = Direction.INPUT
buttonA.pull = Pull.DOWN

buttonB = DigitalInOut(board.BUTTON_B)
buttonB.direction = Direction.INPUT
buttonB.pull = Pull.DOWN

# The two files assigned to buttons A & B
audiofiles = ["rimshot.wav", "laugh.wav"]

def play_file(filename):
    print("playing file " + filename)
    f = open(filename, "rb")
    a = audioio.AudioOut(board.A0, f)
    while a.playing:

while True:
    if buttonA.value:
    if buttonB.value:

This example creates two input buttons using the onboard buttons, then has a helper that will:

  1. open a file on the disk drive with f = open(filename, "rb")
  2. create the audio playback object with a = audioio.AudioOut(board.A0, f)
  3. and finally play it until its done:
    while a.playing:

 Upload the code then try pressing the two buttons one at a time to create your own laugh track!

If you want to use your own sound files, you can! Record, sample, remix, or simply download files from a sound file sight, such as Then, to make sure you have the files converted to the proper specifications, check out this guide here that'll show you how! Spoiler alert: you'll need to make a small, 22Khz (or lower), 16 bit PCM, mono  .wav file!

Last updated on Apr 24, 2018 Published on Oct 12, 2017