# Service Voice - Skull Pi

Service Python de synthèse vocale (TTS), lecture MP3 et génération de signaux jaw sync pour le projet Skull Pi.

## 🎯 Fonctionnalités

- **TTS français** avec eSpeak-NG
- **Lecture MP3** avec génération RMS temps réel
- **Jaw Sync** : visèmes depuis phonèmes ou RMS audio
- **Communication MQTT** avec le système Skull Pi
- **Configuration dynamique** des paramètres jaw sync
- **Contrôles audio** : play, pause, stop, loop

## 📋 Prérequis Système

### Raspberry Pi Zero 2 W

```bash
# Audio
sudo apt install alsa-utils pulseaudio pulseaudio-utils

# TTS
sudo apt install espeak-ng espeak-ng-data

# MP3/Audio processing
sudo apt install ffmpeg

# MQTT
sudo apt install mosquitto mosquitto-clients

# Python dev
sudo apt install python3-dev python3-pip python3-venv
```

### Permissions audio

```bash
sudo usermod -a -G audio,pulse,pulse-access skull
```

## 🚀 Installation

### 1. Structure des dossiers

```bash
sudo mkdir -p /opt/Skull/{apps,logs,bin,venv,assets/audio}
sudo chown -R skull:skull /opt/Skull
```

### 2. Environment virtuel

```bash
cd /opt/Skull
python3 -m venv venv
source venv/bin/activate
pip install -r apps/voice/requirements.txt
```

### 3. Service systemd

```bash
sudo cp skull-voice.service /etc/systemd/system/
sudo cp skull-voice.sh /opt/Skull/bin/
sudo chmod +x /opt/Skull/bin/skull-voice.sh
sudo systemctl daemon-reload
sudo systemctl enable skull-voice
```

## 🔧 Configuration

### Variables d'environnement

```bash
# /etc/systemd/system/skull-voice.service
Environment=MQTT_HOST=127.0.0.1
Environment=MQTT_PORT=1883
Environment=LOG_LEVEL=INFO
Environment=SAMPLE_RATE=22050
```

### Configuration jaw sync par défaut

```json
{
  "gain": 1.0,
  "smoothing": 0.3,
  "latency_ms": 120
}
```

## 📡 API MQTT

### Topics d'entrée

#### TTS

```bash
mosquitto_pub -t voice/tts -m '{
  "text": "Bonjour, comment allez-vous ?",
  "voice": "fr",
  "spd": 1.0,
  "pitch": 1.0
}'
```

#### MP3

```bash
# Lecture
mosquitto_pub -t voice/mp3/play -m '{
  "file": "/opt/Skull/assets/audio/song.mp3",
  "loop": false
}'

# Contrôles
mosquitto_pub -t voice/mp3/pause -m "pause"
mosquitto_pub -t voice/mp3/resume -m "resume"
mosquitto_pub -t voice/mp3/stop -m "stop"
```

#### Configuration jaw sync

```bash
mosquitto_pub -t voice/jaw/config -m '{
  "gain": 1.5,
  "smoothing": 0.4,
  "latency_ms": 100
}'
```

### Topics de sortie

#### Visèmes (TTS avec phonèmes)

```json
{
  "ts_ms": 1640995200000,
  "id": 12,
  "dur_ms": 80
}
```

#### RMS (MP3 ou fallback TTS)

```json
{
  "ts_ms": 1640995200000,
  "rms": 0.45
}
```

#### État du service

```json
{
  "playing": true,
  "src": "tts",
  "file": null
}
```

#### Capacités (retained)

```json
{
  "tts": "espeak-ng",
  "lang": "fr",
  "mp3": true,
  "jaw_sync": true
}
```

## 🎮 Utilisation

### Démarrage du service

```bash
sudo systemctl start skull-voice
sudo systemctl status skull-voice
```

### Logs

```bash
# Logs systemd
journalctl -u skull-voice -f

# Logs JSON
tail -f /opt/Skull/logs/voice.log | jq .
```

### Test manuel

```bash
# Écoute tous les topics
mosquitto_sub -t 'voice/#' -v &
mosquitto_sub -t 'audio/#' -v &

# Test TTS
mosquitto_pub -t voice/tts -m '{"text":"Salut les humains !"}'

# Test MP3 (placez un fichier test)
cp /path/to/test.mp3 /opt/Skull/assets/audio/
mosquitto_pub -t voice/mp3/play -m '{"file":"/opt/Skull/assets/audio/test.mp3"}'
```

### Configuration jaw sync dynamique

```bash
# Augmenter le gain
mosquitto_pub -t voice/jaw/config -m '{"gain":2.0}'

# Smoothing plus fort (mouvement plus fluide)
mosquitto_pub -t voice/jaw/config -m '{"smoothing":0.7}'

# Réduire latence
mosquitto_pub -t voice/jaw/config -m '{"latency_ms":80}'
```

## 🧪 Tests

```bash
cd /opt/Skull/apps/voice

# Tests unitaires
python -m pytest tests/ -v

# Couverture de code
python -m pytest tests/ --cov=voice --cov-report=html

# Tests spécifiques
python -m pytest tests/test_tts.py -v
python -m pytest tests/test_jaw_sync.py -v
```

### Tests avec hardware audio

```bash
# Skip tests nécessitant du matériel audio
python -m pytest tests/ -m "not audio"
```

## 📊 Métriques et Monitoring

### Critères de performance

- **TTS** : < 500ms pour phrase de 3 mots
- **MP3 RMS** : calculé en ≤ 50ms par frame
- **Corrélation RMS** : > 0.8 avec signal audio réel

### Logs de métriques

```json
{
  "timestamp": 1640995200.123,
  "level": "INFO",
  "module": "voice.tts",
  "message": "TTS synthèse terminée: 15 chars",
  "synthesis_time_ms": 245,
  "phonemes_count": 8,
  "duration_ms": 890
}
```

## 🐛 Dépannage

### Problèmes courants

#### Pas de son

```bash
# Test système audio
aplay /usr/share/sounds/alsa/Front_Left.wav

# Vérif PulseAudio
pulseaudio --check -v

# Permissions
groups $USER | grep -E "(audio|pulse)"
```

#### MQTT non connecté

```bash
# Test connexion
mosquitto_pub -h 127.0.0.1 -p 1883 -t test -m "hello"

# Service mosquitto
sudo systemctl status mosquitto
```

#### eSpeak-NG manquant

```bash
# Installation
sudo apt install espeak-ng espeak-ng-data

# Test
espeak-ng -v fr "Bonjour test"
```

### Logs de debug

```bash
# Mode debug
sudo systemctl edit skull-voice

[Service]
Environment=LOG_LEVEL=DEBUG
```

## 🔬 Architecture Interne

### Modules principaux

- **`service.py`** : Orchestration générale
- **`tts.py`** : Synthèse vocale eSpeak-NG
- **`mp3.py`** : Lecture MP3 avec pygame
- **`jaw_sync.py`** : Traitement RMS et visèmes
- **`mqtt_handler.py`** : Communication MQTT
- **`audio.py`** : Interface système audio

### Jaw Sync

- **Visèmes** : Mapping phonèmes → IDs (0-15)
- **RMS** : Filtre passe-bande 200-3000Hz
- **Smoothing** : EMA configurable
- **Latence** : Buffer configurable

### Threading

- Thread principal : MQTT + coordination
- Thread TTS : synthèse + visèmes
- Thread MP3 : lecture + RMS streaming

## 📄 Licence

MIT - Voir fichier LICENSE

## 🤝 Contribution

1. Fork le projet
2. Créer branche feature (`git checkout -b feature/AmazingFeature`)
3. Tests et linting (`ruff check && mypy voice/`)
4. Commit (`git commit -m 'Add AmazingFeature'`)
5. Push (`git push origin feature/AmazingFeature`)
6. Pull Request

---

**Skull Pi Team** - Service Voice v1.0.0
