Playing Audio Through Reachy 2023’s Speaker: What the SDK Doesn’t Tell You

The SDK Gap You’ll Hit Right Away

If you’re looking at Reachy 2 documentation and expecting reachy.audio.play_audio_file() to work on a Reachy 2023, it won’t. The Reachy 2023 uses the older reachy-sdk, and that SDK has no built-in audio module at all. The reachy.audio namespace was introduced in reachy2-sdk for the 2024 Reachy 2 platform. Two different robots, two different SDKs, two completely different audio stories.

That’s not a dead end. It just means going a layer lower than the SDK.

What Hardware You’re Working With

Reachy 2023 has a speaker mounted in the torso and a microphone array in the head. The onboard computer runs Linux, and audio is handled through standard ALSA devices. You don’t need any Reachy-specific library to get sound out of it — standard Python audio tooling works fine once you’re on the machine.

Step 1: Confirm the Speaker Is Accessible via SSH

Before writing any Python, SSH into the robot and test with aplay. This rules out hardware and ALSA config issues before you add Python into the mix:

ssh [email protected]
aplay -l
aplay /usr/share/sounds/alsa/Front_Center.wav

If you hear output, the hardware path is clear. If not, that’s something to sort at the ALSA level first — no Python wrapper will fix a missing or mis-configured audio device.

Step 2: Play Audio from Python

Once the device is confirmed, Python audio playback is standard Linux work. Two approaches that hold up well in practice:

sounddevice + soundfile

import sounddevice as sd
import soundfile as sf

data, samplerate = sf.read('your_audio.wav')
sd.play(data, samplerate)
sd.wait()  # block until playback finishes

This pair handles .wav and .flac natively, and .ogg if the Vorbis codec is present on the system (typical on Ubuntu-based Jetson images).

pygame (simpler for one-off playback)

import pygame
pygame.mixer.init()
pygame.mixer.music.load('your_audio.mp3')
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
    pygame.time.Clock().tick(10)

pygame’s mixer supports .wav and .mp3 out of the box and is easier to set up if you already have it in your environment. Less control over low-level device selection, but fine for most use cases.

What ReachyAudio Actually Shows You

The ReachyAudio project by Romain Maure is the most complete community reference for audio on older Reachy platforms. It was built as an EPFL semester project and uses PyAudio with the wave module for playback, pyttsx3 for offline text-to-speech, and gTTS for online TTS. It also handles voice activity detection and microphone direction-of-arrival estimation.

Don’t install it blindly expecting everything to work — it’s Python 3.7 era code with no recent maintenance. But the ReachyAudioPlayerRecorder class and its playAudio() method are worth reading for how it handles PyAudio device selection. That’s the part that translates directly to your situation.

If You’re on Reachy 2 Instead

If you’re running the newer Reachy 2 platform with reachy2-sdk, audio is a first-class SDK feature. The sequence is clean:

from reachy2_sdk import ReachySDK

reachy = ReachySDK(host='your-reachy-ip')

# Upload a file from your local machine to the robot
reachy.audio.upload_audio_file('/path/to/sample.ogg')

# Check what's already on the robot
print(reachy.audio.get_audio_files())

# Play
reachy.audio.play_audio_file('sample.ogg')

# Stop early if needed
reachy.audio.stop_playing()

Supported playback formats: .wav, .mp3, .ogg. For recording from the microphones, only .ogg is currently supported.

One catch: files uploaded via the SDK land in a temporary folder on the robot’s internal computer and are wiped at every reboot. There’s no persistent storage yet. If you need files available on startup, upload them as part of your initialization script.

Running Audio Alongside Motion

Worth knowing for Reachy 2: play_audio_file() is non-blocking by default. You can queue a head motion and start audio in the same code sequence without threads. Call stop_playing() explicitly if you need to cut playback short — it won’t stop on its own when a motion finishes.

For Reachy 2023 using the direct Python approach, non-blocking playback is straightforward with sounddevice: just drop the sd.wait() call and the audio runs in a background stream while your main thread continues.

Sources

Related Articles

Similar Posts