Reachy Mini documentation
Sound TTS (with head wobbling)
Get Started
Reachy Mini (Wireless)
Getting startedHardwareUsageMedia Advanced ControlsResetInstall Daemon from BranchDevelopment WorkflowReflash the ISO
Reachy Mini Lite
Simulation
Software guide
SDK OverviewInstallationCore ConceptsQuickstart GuidePython SDKAI IntegrationsBuilding & Publishing AppsREST APIJavaScript SDK & Web AppsMedia ArchitectureGStreamer Installation
Help and support
Examples
Minimal demoLook atHead TrackingSequenceGoto Interpolation PlaygroundIMUCompliant Mode DemoRecorded MovesRerun ViewerTake PictureJoystick ControllerHead Position GUISound Direction of ArrivalSound PlaybackSound RecordingSound TTS (with head wobbling)Custom Media Manager
Integrations
API
Sound TTS (with head wobbling)
This example synthesises speech from text via ResembleAI’s Chatterbox Multilingual TTS Hugging Face Space, plays the returned audio on Reachy Mini, and wobbles the head in sync with the speech.
Chatterbox supports zero-shot voice cloning: pass a short reference audio file and the synthesis matches that voice. 23 languages are supported.
Usage:
# Default English voice
uv run python examples/sound_tts.py --text "Hello, I can wobble my head!"
# Different language
uv run python examples/sound_tts.py --text "Bonjour, je suis Reachy Mini" --lang fr
# Clone a voice from a local sample
uv run python examples/sound_tts.py \
--text "Hello world" \
--ref-audio ~/Downloads/my_voice.wavOptions:
--text <str>: Text to synthesize (max 300 chars per request).--lang <code>: ISO 639-1 language code. Supported:ar,da,de,el,en,es,fi,fr,he,hi,it,ja,ko,ms,nl,no,pl,pt,ru,sv,sw,tr,zh.--ref-audio <path|url>: Reference audio for zero-shot voice cloning. Local paths and URLs both work; defaults to a Gradio sample voice.
Synthesis runs on the Space’s shared GPU and typically takes 60–90 s per sentence.
import argparse
import os
import time
import gi
from gradio_client import Client, handle_file
gi.require_version("Gst", "1.0")
gi.require_version("GstPbutils", "1.0")
from gi.repository import Gst, GstPbutils # noqa: E402
from reachy_mini import ReachyMini # noqa: E402
HF_SPACE = "ResembleAI/Chatterbox-Multilingual-TTS"
LANGUAGES = [
"ar", "da", "de", "el", "en", "es", "fi", "fr", "he", "hi", "it",
"ja", "ko", "ms", "nl", "no", "pl", "pt", "ru", "sv", "sw", "tr", "zh",
]
DEFAULT_REF_AUDIO = (
"https://github.com/gradio-app/gradio/raw/main/test/test_files/audio_sample.wav"
)
def synthesize(text: str, lang: str, ref_audio: str) -> str:
"""Submit *text* to Chatterbox; return a path to a local audio file."""
if not ref_audio.startswith(("http://", "https://")):
ref_audio = os.path.expanduser(ref_audio)
client = Client(HF_SPACE)
audio_path = client.predict(
text_input=text,
language_id=lang,
audio_prompt_path_input=handle_file(ref_audio),
api_name="/generate_tts_audio",
)
return str(audio_path)
def probe_duration_s(path: str) -> float:
"""Return the media duration of *path* in seconds via GStreamer."""
Gst.init([])
disc = GstPbutils.Discoverer.new(10 * Gst.SECOND)
info = disc.discover_uri(f"file://{path}")
return float(info.get_duration() / Gst.SECOND)
def main(text: str, lang: str, ref_audio: str) -> None:
"""Synthesize *text*, play it on Reachy Mini with wobbling enabled."""
print(f"Synthesizing {len(text)} chars ({lang}) with Chatterbox...")
audio_path = synthesize(text, lang, ref_audio)
duration = probe_duration_s(audio_path)
print(f"Got {audio_path} ({duration:.1f}s)")
with ReachyMini(log_level="INFO") as mini:
mini.enable_wobbling()
mini.media.play_sound(audio_path)
time.sleep(duration + 0.5)
mini.disable_wobbling()
print("Done.")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Chatterbox Multilingual TTS + head wobbler demo.",
)
parser.add_argument(
"--text",
type=str,
default="Hello, I am Reachy Mini. Let me wobble my head while I speak.",
help="Text to synthesize (max 300 chars per request).",
)
parser.add_argument(
"--lang",
type=str,
default="en",
choices=LANGUAGES,
help="Language code (ISO 639-1).",
)
parser.add_argument(
"--ref-audio",
type=str,
default=DEFAULT_REF_AUDIO,
help="Reference audio (URL or local path) for zero-shot voice cloning.",
)
args = parser.parse_args()
main(
text=args.text,
lang=args.lang,
ref_audio=args.ref_audio,
)