Files
linux-voice-assistant/docs/linux-voice-assistant-xvf3800.md
T

11 KiB
Raw Blame History

Linux Voice Assistant with ReSpeaker XVF3800 4‑Mic Array — Installation & Configuration Guide

Drafted with ChatGPT based on existing linux-voice-assistant-2mic-install.md and community test results from the XVF3800 integration Discussion.

This guide shows how to use the Seeed ReSpeaker XVF3800 USB 4‑Mic Array with the linux-voice-assistant (LVA) project on Raspberry Pi or other Linux hosts.

Unlike the ReSpeaker 2‑Mic HAT, the XVF3800 is a USB Audio Class 2.0 device: it acts as a “smart microphone + speaker” front end with built‑in AEC, beamforming, noise suppression, AGC, and echo‑canceling speakerphone processing.

LVA treats the XVF3800 as a standard USB mic/speaker:

  • Audio in: 16 kHz, 16‑bit, 2‑channel PCM (downmixed to mono by the audio stack)
  • Audio out: 16 kHz, 16‑bit, 2‑channel PCM via the XVF3800 headphone jack / speaker

No custom kernel drivers are required. Plug it in, select it as your audio device in LVA’s config.json, and it will “just work” as a high‑quality mic for wake word and ESPHome streaming.


Prerequisites

  • A Linux host (e.g., Raspberry Pi 4/5) running one of:
    • Raspberry Pi OS (Bookworm or Trixie)
    • Debian 13 (trixie) or similar
    • Other modern Linux with PipeWire or PulseAudio
  • Python 3.11+ recommended
  • ReSpeaker XVF3800 4‑Mic Array, connected via its XMOS USB‑C port
  • Network access to your Home Assistant instance
  • The linux-voice-assistant repository checked out (optionally on the XVF3800 branch)

1. Get the code (XVF3800 branch)

If you don’t already have the project cloned, you can pull the dedicated XVF3800 branch:

cd ~
git clone --branch XVF3800 --single-branch https://github.com/imonlinux/linux-voice-assistant.git
cd linux-voice-assistant

If you already have the repository, you can switch branches:

cd ~/linux-voice-assistant
git fetch origin
git checkout XVF3800

Set up the project (creates a virtualenv, installs dependencies, etc.):

cd ~/linux-voice-assistant
script/setup

Tip: If you use a different username than pi, adjust paths accordingly.


2. Connect and verify the XVF3800

2.1 Plug in the board

  1. Connect the XVF3800 to your Pi/host using the XMOS USB‑C port (the one next to the 3.5 mm audio jack).
  2. If you want local audio output, connect the XVF3800’s headphone jack to an external powered speaker.

2.2 Confirm ALSA sees the device

arecord -l
aplay   -l

You should see entries similar to:

**** List of CAPTURE Hardware Devices ****
card 3: Array [reSpeaker XVF3800 4-Mic Array], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

**** List of PLAYBACK Hardware Devices ****
card 3: Array [reSpeaker XVF3800 4-Mic Array], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

The exact card index (3 above) may differ on your system.

2.3 Quick arecord test (optional)

Replace 3 with your card number:

arecord -D plughw:3,0 -c 2 -r 16000 -f S16_LE -d 5 -vv /tmp/xvf3800-test.wav
aplay /tmp/xvf3800-test.wav

You should hear your voice through your default playback device, confirming that:

  • The XVF3800 is streaming at 16 kHz, 16‑bit, stereo, and
  • ALSA can capture from it reliably.

3. PipeWire / PulseAudio device mapping

On a PipeWire or PulseAudio system, check how the XVF3800 shows up at the graph level:

pactl list short sources
pactl list short sinks

Typical output:

# Sources
309 alsa_input.usb-Seeed_Studio_reSpeaker_XVF3800_4-Mic_Array_...-00.analog-stereo PipeWire s16le 2ch 16000Hz RUNNING

# Sinks
308 alsa_output.usb-Seeed_Studio_reSpeaker_XVF3800_4-Mic_Array_...-00.analog-stereo PipeWire s16le 2ch 16000Hz SUSPENDED

Key points:

  • The XVF3800 appears as an analog stereo source/sink (2ch 16000 Hz).
  • LVA will use these devices through the soundcard library.

4. LVA’s view of the XVF3800 (input/output devices)

From the project root, use LVA’s helper flags to inspect devices:

cd ~/linux-voice-assistant
script/run -- --list-input-devices
script/run -- --list-output-devices

Example output:

Input devices

[0] reSpeaker XVF3800 4-Mic Array Analog Stereo
Output devices

auto: Autoselect device
pipewire: Default (pipewire)
pipewire/alsa_output.usb-Seeed_Studio_reSpeaker_XVF3800_4-Mic_Array_...analog-stereo: reSpeaker XVF3800 4-Mic Array Analog Stereo
...

Take note of:

  • The input device name for the XVF3800 (e.g. reSpeaker XVF3800 4-Mic Array Analog Stereo)
  • The output device you want to use (often pipewire or the specific XVF “analog‑stereo” sink)

5. Configure LVA audio for XVF3800

Edit the main config:

nano ~/linux-voice-assistant/linux_voice_assistant/config.json

Add or update the audio section:

"audio": {
  "input_device": "reSpeaker XVF3800 4-Mic Array Analog Stereo",
  "output_device": "pipewire",
  "input_block_size": 1024
}

Examples:

  • If you want both input and output on the XVF3800:

    "audio": {
      "input_device": "reSpeaker XVF3800 4-Mic Array Analog Stereo",
      "output_device": "pipewire/alsa_output.usb-Seeed_Studio_reSpeaker_XVF3800_4-Mic_Array_101991441253700076-00.analog-stereo",
      "input_block_size": 1024
    }
    
  • If you only want to use the XVF3800 as a mic (and another device for playback), set output_device to your preferred sink from --list-output-devices.

5.1 How channels are handled (important detail)

The XVF3800 exposes itself as a 2‑channel source (stereo, 16 kHz). Internally, the LVA AudioEngine uses the soundcard library and always requests 1 channel from the selected input device:

with self.mic.recorder(
    samplerate=16000,
    channels=1,
    blocksize=self.block_size,
) as mic_in:
    audio_chunk_array = mic_in.record(self.block_size).reshape(-1)
    ...

This has two important implications:

  1. The audio stack (PipeWire/PulseAudio/ALSA) takes care of converting from the XVF3800’s 2‑channel stream to a mono stream before LVA sees it.
  2. LVA’s wake‑word engines and ESPHome streaming always receive 16 kHz mono PCM (int16), regardless of whether the underlying hardware is mono or stereo.

In practice:

You do not need any XVF3800‑specific code changes in the audio engine.
Selecting the XVF3800 as the audio.input_device is sufficient; LVA will process it as a mono mic just like other devices.


6. Start LVA as a user-mode service

The service setup is identical to other configurations (2‑Mic, etc.). Assuming you want LVA to run as a user‑mode systemd service:

6.1 Enable linger for your user (e.g. pi)

sudo loginctl enable-linger pi

6.2 Install the systemd user service

mkdir -p ~/.config/systemd/user
cp ~/linux-voice-assistant/service/linux-voice-assistant.service    ~/.config/systemd/user/linux-voice-assistant.service

6.3 Enable & start

systemctl --user daemon-reload
systemctl --user enable --now linux-voice-assistant.service

Check status:

systemctl --user status linux-voice-assistant --no-pager -l

Look for log lines indicating:

  • LVA connected to Home Assistant
  • Wake‑word engine initialized
  • Satellite streaming started on wake word

7. Acoustic Echo Cancellation (AEC) considerations

The XVF3800 already implements hardware AEC / echo‑canceling speakerphone processing. In many cases, you can rely only on the XVF3800’s built‑in AEC and skip the PipeWire/PulseAudio module-echo-cancel setup.

You have three practical options:

  • Do not load any user‑mode echo‑cancel module.
  • Set input_device to the XVF3800 source (or an echo‑cancel source that wraps it, if your system has one by default).
  • Play media (music, games, etc.) through the XVF3800 or another output and test:
    • Wake word recognition reliability
    • STT quality in noisy playback conditions

If it works well, this is the simplest and most CPU‑efficient setup.

7.2 Combine XVF3800 with software AEC

If you already have a PipeWire/PulseAudio echo‑cancel device configured, you can route XVF3800 through it:

  1. Create an echo‑cancel source/sink pair (see install_pipewire.md or install_pulseaudio.md).

  2. Use script/run --list-input-devices / --list-output-devices to find names like Echo-Cancel Source and pipewire/echo-cancel-sink.

  3. Point LVA at those devices in config.json:

    "audio": {
      "input_device": "Echo-Cancel Source",
      "input_block_size": 1024,
      "output_device": "pipewire/echo-cancel-sink"
    }
    

This stacks XVF3800’s hardware processing with additional software AEC. It may help in particularly difficult acoustic environments, at the cost of some complexity and CPU.

You can also run without any AEC (hardware or software) if:

  • You use headphones instead of speakers, or
  • The device isn’t playing audio while listening (e.g. strictly microphone‑only role).

In that case, you can treat XVF3800 as “just another USB mic” and ignore its speakerphone capabilities.


8. Troubleshooting & debug tips

8.1 Check that LVA sees the XVF3800

Re‑run:

cd ~/linux-voice-assistant
script/run -- --list-input-devices
script/run -- --list-output-devices

If reSpeaker XVF3800 4-Mic Array Analog Stereo doesn’t appear:

  • Check arecord -l / aplay -l again.

  • Ensure the XVF3800 is connected to the XMOS USB‑C port and powered.

  • Check lsusb for a device with 2886:001a:

    lsusb | grep -i 2886
    

8.2 Tail the LVA logs

journalctl --user -u linux-voice-assistant.service -f

Look for:

  • “Audio engine started.”
  • “Opening audio input device: reSpeaker XVF3800 4-Mic Array Analog Stereo”
  • Wake‑word detection lines (MicroWakeWord / OpenWakeWord)

8.3 Optional: XVF3800 probe script

On the XVF3800 branch, there is a small probe script in tests/xvf3800_probe.py that can be used to inspect how the audio backend opens the device.

For example:

cd ~/linux-voice-assistant
python tests/xvf3800_probe.py --device "reSpeaker XVF3800 4-Mic Array Analog Stereo"

This will print:

  • The device list from the soundcard backend
  • The samplerate and channel count used when opening the stream
  • The shape and dtype of the recorded buffer

It’s mainly a debug tool for development and Discussion threads; you don’t need it for normal operation.


9. Next steps: LEDs, button, and DOA integration

This document covers audio‑only integration for the XVF3800. The board also has:

  • A 12‑LED WS2812 ring
  • A hardware mute button and mute LED
  • Direction‑of‑arrival (DOA) and voice activity indicators

Future work in the LVA project may add an optional Xvf3800Controller that:

  • Talks to the XVF3800 over USB using a Python SDK (pyusb or HID)
  • Publishes DOA, VAD, and mute button events to LVA’s internal event bus
  • Synchronizes mute state and LED behavior between XVF3800, LVA, and Home Assistant

For now, the important takeaway is:

As soon as the XVF3800 is selected as the input device in config.json, the Linux Voice Assistant can use it as a high‑quality microphone front end with no additional code changes.