<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Krunal Chavda</title>
    <description>The latest articles on DEV Community by Krunal Chavda (@krunal16c).</description>
    <link>https://dev.to/krunal16c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3571695%2Fec5d6390-95e1-44a9-9b80-9e15c6d78f4c.jpeg</url>
      <title>DEV Community: Krunal Chavda</title>
      <link>https://dev.to/krunal16c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/krunal16c"/>
    <language>en</language>
    <item>
      <title>Reachy Mini Not Speaking</title>
      <dc:creator>Krunal Chavda</dc:creator>
      <pubDate>Thu, 05 Mar 2026 20:39:00 +0000</pubDate>
      <link>https://dev.to/krunal16c/reachy-mini-not-speaking-5dcc</link>
      <guid>https://dev.to/krunal16c/reachy-mini-not-speaking-5dcc</guid>
      <description>&lt;h2&gt;
  
  
  Reachy Mini Not Speaking in Reachy Mini Conversation App— GStreamer DeviceMonitor Fails Without PipeWire/PulseAudio
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Before you jump in
&lt;/h2&gt;

&lt;p&gt;Make sure to check that you have not run out OpenAI api credits or reachy is not on low battery. Sometimes both of those issues lead him to act differently. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Your Reachy Mini Wireless robot connects to the OpenAI Realtime API successfully, dances, plays emotions, and calls tools autonomously — but it never speaks or responds to your voice. The robot appears to be "talking to itself," cycling through idle behaviors like &lt;code&gt;do_nothing reason=contemplating existence&lt;/code&gt; with zero speech interaction.&lt;/p&gt;

&lt;p&gt;The system logs show the conversation app launching cleanly with the session connected, but two critical warnings buried in the startup output reveal the root cause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARNING reachy_mini.media.audio_gstreamer:470 | No Source audio card found.
WARNING reachy_mini.media.audio_gstreamer:470 | No Sink audio card found.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Source means no microphone input. No Sink means no speaker output. The Realtime API session is alive on the control channel, but no audio flows in either direction — so the model never hears you and never generates speech.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Confusing Part
&lt;/h2&gt;

&lt;p&gt;Here's what makes this bug hard to diagnose: the audio hardware works perfectly at the OS level.&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;arecord -l&lt;/code&gt; and &lt;code&gt;aplay -l&lt;/code&gt; shows "Reachy Mini Audio" as card 0 with both capture and playback subdevices. Recording and playing back audio via ALSA command-line tools works fine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;arecord &lt;span class="nt"&gt;-d&lt;/span&gt; 3 &lt;span class="nt"&gt;-f&lt;/span&gt; S16_LE &lt;span class="nt"&gt;-r&lt;/span&gt; 16000 /tmp/test.wav
aplay /tmp/test.wav
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GStreamer can also use the ALSA device directly with no issues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gst-launch-1.0 alsasrc &lt;span class="nv"&gt;device&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hw:0 num-buffers&lt;span class="o"&gt;=&lt;/span&gt;10 &lt;span class="o"&gt;!&lt;/span&gt; fakesink
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the hardware is fine, ALSA is fine, and GStreamer can talk to the card. The problem is specifically in how the Reachy Mini SDK discovers the audio device.&lt;/p&gt;

&lt;h2&gt;
  
  
  Root Cause
&lt;/h2&gt;

&lt;p&gt;The SDK's audio backend (&lt;code&gt;reachy_mini/media/audio_gstreamer.py&lt;/code&gt;) uses GStreamer's &lt;code&gt;Gst.DeviceMonitor&lt;/code&gt; to enumerate audio devices. The &lt;code&gt;_get_audio_device()&lt;/code&gt; method creates a monitor, filters for &lt;code&gt;Audio/Source&lt;/code&gt; or &lt;code&gt;Audio/Sink&lt;/code&gt;, and then iterates through discovered devices looking for one named "Reachy Mini Audio."&lt;/p&gt;

&lt;p&gt;The detection logic tries multiple property fields in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;node.name&lt;/code&gt; — for PipeWire&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;device.api&lt;/code&gt; / &lt;code&gt;device.id&lt;/code&gt; — for Windows (WASAPI)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unique-id&lt;/code&gt; — for macOS&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;udev.id&lt;/code&gt; + &lt;code&gt;device.profile.name&lt;/code&gt; — for Linux PulseAudio&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;device.string&lt;/code&gt; — for Linux ALSA fallback&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The problem: &lt;strong&gt;GStreamer's DeviceMonitor returns zero devices when neither PipeWire nor PulseAudio is running.&lt;/strong&gt; The Reachy Mini Wireless runs a minimal Debian installation on a Raspberry Pi 4 with pure ALSA — no audio server layer. When the monitor finds nothing to enumerate, the method falls through to the warning log and returns &lt;code&gt;None&lt;/code&gt;, leaving the conversation app with no audio capability.&lt;/p&gt;

&lt;p&gt;You can confirm this by running a quick Python check on the robot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;gi&lt;/span&gt;
&lt;span class="n"&gt;gi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Gst&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;gi.repository&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Gst&lt;/span&gt;
&lt;span class="n"&gt;Gst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;monitor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Gst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DeviceMonitor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Audio/Source&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_devices&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;  &lt;span class="c1"&gt;# Returns empty list
&lt;/span&gt;&lt;span class="n"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;The fix is a two-line patch to &lt;code&gt;audio_gstreamer.py&lt;/code&gt; that adds an ALSA hardware fallback when the DeviceMonitor fails to find any devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;/venvs/apps_venv/lib/python3.12/site-packages/reachy_mini/media/audio_gstreamer.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Line ~470 — find:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;device_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; audio card found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Replace with:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;device_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; audio card found via DeviceMonitor, falling back to ALSA hw:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hw:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells the SDK to use the first ALSA hardware device directly when the GStreamer DeviceMonitor can't enumerate devices. Since the Reachy Mini Audio board is always card 0, &lt;code&gt;hw:0&lt;/code&gt; is the correct device identifier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-Step
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;SSH into your Reachy Mini:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh pollen@reachy-mini.local
   &lt;span class="c"&gt;# Password: root&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Back up the original file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cp&lt;/span&gt; /venvs/apps_venv/lib/python3.12/site-packages/reachy_mini/media/audio_gstreamer.py &lt;span class="se"&gt;\&lt;/span&gt;
      /venvs/apps_venv/lib/python3.12/site-packages/reachy_mini/media/audio_gstreamer.py.bak
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Edit the file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nano /venvs/apps_venv/lib/python3.12/site-packages/reachy_mini/media/audio_gstreamer.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jump to line 470 (&lt;code&gt;Ctrl+Shift+_&lt;/code&gt;, type &lt;code&gt;470&lt;/code&gt;, Enter). Replace the warning line as shown above.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Save (&lt;code&gt;Ctrl+O&lt;/code&gt;, Enter) and exit (&lt;code&gt;Ctrl+X&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart the daemon and conversation app:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart reachy-mini-daemon.service
   &lt;span class="nb"&gt;sleep &lt;/span&gt;10
   reachy-mini-conversation-app &lt;span class="nt"&gt;--gradio&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify the logs now show:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   No Source audio card found via DeviceMonitor, falling back to ALSA hw:0
   No Sink audio card found via DeviceMonitor, falling back to ALSA hw:0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of the previous dead-end warning, the app now has a valid audio device and can send/receive audio through the OpenAI Realtime API.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Tell If You Have This Bug
&lt;/h2&gt;

&lt;p&gt;You likely have this issue if all of the following are true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your Reachy Mini is the &lt;strong&gt;Wireless&lt;/strong&gt; version (RPi-based, onboard compute)&lt;/li&gt;
&lt;li&gt;The conversation app connects to OpenAI successfully (you see "Realtime session updated successfully" in the logs)&lt;/li&gt;
&lt;li&gt;The robot moves, dances, and plays emotions on its own but &lt;strong&gt;never speaks or responds to voice&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Running &lt;code&gt;arecord -l&lt;/code&gt; shows the "Reachy Mini Audio" device&lt;/li&gt;
&lt;li&gt;Running &lt;code&gt;pactl&lt;/code&gt; returns "command not found" (no PulseAudio)&lt;/li&gt;
&lt;li&gt;Running &lt;code&gt;systemctl --user status pipewire&lt;/code&gt; returns "not found" (no PipeWire)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This patch assumes the Reachy Mini Audio board is always ALSA card 0 (&lt;code&gt;hw:0&lt;/code&gt;). If you have additional USB audio devices connected, the card number may differ — check with &lt;code&gt;cat /proc/asound/cards&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The fix is applied to the installed Python package and will be overwritten by SDK updates. After updating the Reachy Mini SDK, you may need to reapply the patch.&lt;/li&gt;
&lt;li&gt;A more robust upstream fix could install PipeWire as a lightweight audio server, or modify the SDK's fallback logic to query ALSA directly when the DeviceMonitor returns no devices.&lt;/li&gt;
&lt;li&gt;Consider opening an issue on the &lt;a href="https://github.com/pollen-robotics/reachy_mini" rel="noopener noreferrer"&gt;reachy_mini GitHub repository&lt;/a&gt; referencing this workaround so it can be addressed in a future release.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Environment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Robot:&lt;/strong&gt; Reachy Mini Wireless&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OS:&lt;/strong&gt; Debian 13 (Trixie) on Raspberry Pi 4&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio hardware:&lt;/strong&gt; Pollen Robotics Reachy Mini Audio (XVF3800-based USB audio)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio stack:&lt;/strong&gt; Pure ALSA (no PipeWire, no PulseAudio)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK:&lt;/strong&gt; reachy_mini (installed in &lt;code&gt;/venvs/apps_venv/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conversation app:&lt;/strong&gt; reachy_mini_conversation_app with OpenAI gpt-realtime&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>iot</category>
      <category>linux</category>
      <category>openai</category>
    </item>
  </channel>
</rss>
