
# Debugging

## Explanation of the audio system:

The Linux audio stack consists of multiple layers working together:

```
┌─────────────────────────────────────────────────────────────┐
│                     HOST SYSTEM                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              User Applications                      │    │
│  │  (Browser, Media Player, Voice Assistant, etc.)     │    │
│  └────────────────┬────────────────────────────────────┘    │
│                   │                                         │
│  ┌────────────────▼────────────────────────────────────┐    │
│  │         PipeWire / PulseAudio                       │    │
│  │         (Sound Server)                              │    │
│  │  - Audio mixing & routing                           │    │
│  │  - Device abstraction                               │    │
│  │  - Network audio support                            │    │
│  │  - Per-application volume control                   │    │
│  └────────────────┬────────────────────────────────────┘    │
│                   │                                         │
│  ┌────────────────▼────────────────────────────────────┐    │
│  │              ALSA                                   │    │
│  │  (Advanced Linux Sound Architecture)                │    │
│  │  - Kernel-level audio driver framework              │    │
│  │  - Direct hardware access                           │    │
│  │  - Controls: /dev/snd/                              │    │
│  └────────────────┬────────────────────────────────────┘    │
│                   │                                         │
│  ┌────────────────▼────────────────────────────────────┐    │
│  │           Hardware (Sound Card)                     │    │
│  │   ┌─────────┐  ┌─────────┐  ┌───────────────────┐   │    │
│  │   │Microphon│  │ Speaker │  │   DSP/Codec       │   │    │
│  │   └─────────┘  └─────────┘  └───────────────────┘   │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  LVA_XDG_RUNTIME_DIR=/run/user/1000                             │
│  └── Socket: /run/user/1000/pipewire-0                      │
│      Socket: /run/user/1000/pulse/native                    │
└─────────────────────────────────────────────────────────────┘
                              │
                              │ Device Passthrough
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                   DOCKER CONTAINER                          │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              Container Process                      │    │
│  │  (Linux Voice Assistant)                            │    │
│  │                                                     │    │
│  │  Accesses audio via:                                │    │
│  │  - PipeWire/PulseAudio client library               │    │
│  │  - Uses same LVA_XDG_RUNTIME_DIR socket path            │    │
│  │                                                     │    │
│  │  Environment Variables:                             │    │
│  │  - LVA_XDG_RUNTIME_DIR=/run/user/1000 (host path)       │    │
│  │  - AUDIO_INPUT_DEVICE="default"                     │    │
│  │  - AUDIO_OUTPUT_DEVICE="default"                    │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  Device Access:                                             │
│  - Socket: /run/user/1000/pipewire-0 (volume mount)         │
│  - Socket: /run/user/1000/pulse/native (volume mount)       │
└─────────────────────────────────────────────────────────────┘
```

### How it works:

1. **Host Layer**:
   - ALSA provides kernel drivers for audio hardware
   - PipeWire/PulseAudio sits on top of ALSA as a sound server
   - Applications connect to PipeWire/PulseAudio, not directly to ALSA, otherwhise the container would need access to the ALSA devices. If you use ALSA only only one application can connect to the device at a time.

2. **Docker Integration**:
   - The LVA_XDG_RUNTIME_DIR socket must be mounted from host to container
   - The container user must have matching UID/GID with host user or the audio group is added.

3. **Communication Flow**:
   ```
   Container App → PipeWire Client Library → Host PipeWire/PulseAudio
         ↓                                         ↓
   (via mounted socket)                    (via ALSA drivers)
         ↓                                         ↓
   ┌─────────────────────────────────────────────────────┐
   │              Audio Data flows to Hardware           │
   └─────────────────────────────────────────────────────┘
   ```

4. **Key Configuration Points**:
   - `LVA_XDG_RUNTIME_DIR` must point to host's runtime directory
   - Container user UID/GID should match host user

### Docker Compose Example:

```yaml
services:
  voice-assistant:
    image: ghcr.io/ohf-voice/linux-voice-assistant:latest
    environment:
      - LVA_XDG_RUNTIME_DIR=/run/user/1000
      - AUDIO_INPUT_DEVICE=default
      - AUDIO_OUTPUT_DEVICE=default
    volumes:
      - /run/user/1000:/run/user/1000:rw
    devices:
      - /dev/snd:/dev/snd
    group_add:
      - audio
```


## List available audio devices:

To list available audio devices, run:

```bash
# List audio devices
docker run --rm -it -e LIST_DEVICES="1" ghcr.io/florian-asche/linux-voice-assistant:develop-final-docker-version
```

Update the `.env` file with your device names:

``` ini
AUDIO_INPUT_DEVICE="default"
AUDIO_OUTPUT_DEVICE="default"
```


## Pipewire runtime directory (Optional):

If you work with the root user, you need to:
``` sh
export LVA_XDG_RUNTIME_DIR=/run/user/${USERLVA_USER_ID
```

💡 **Note:** Replace `$USERLVA_USER_IDth your actual user id that you want to run the voice assistant.


## Troubleshooting:

### Audio Device Not Found:

If the container cannot access audio devices, ensure:

1. The USERLVA_USER_ID`.env` matches your actual users ID (run `id -u $USER` to check)
2. The LVA_XDG_RUNTIME_DIR path exists on the host

### Permission Denied Errors:

tbd

### Low Audio Quality:

If you experience audio quality issues:

1. Check the audio device settings with `alsamixer`
2. Try setting `AUDIO_INPUT_DEVICE` and `AUDIO_OUTPUT_DEVICE` explicitly
3. Adjust the microphone gain in your system settings


## More debugging documentation:

See [PiCompose](https://github.com/florian-asche/PiCompose/blob/main/docs/pipewire_debugging.md) for more debugging information.
