# Gestion d'une sortie voix par python

![tag](python)
![category](developpement)

Parfois avoir une sortie voix suite à l'entrée de texte par exemple est un moyens simple de rendre disponible l'info

j'ai trouver un module python qui ralise ce **textToSpeech** il se nomme **piper tts**

son installation est simple

- on installe le module python
- on télécharge un modèle de voix (disponible [ici](https://rhasspy.github.io/piper-samples/))

et par la suite on a accès à la commande **piper**

```bash
pip install piper-tts
python3 -m piper.download_voices fr_FR-upmc-medium
```

Il existe bien un moyen en full python pour générer un fichier wav

> 🧠 **NOTE :**
> Il existe une version serveur ... on peut par la suite intérroger le serveur pour fournir à partir d'un texte un fichier wav


```python
import wave
from piper import PiperVoice

voice = PiperVoice.load("/path/to/en_US-lessac-medium.onnx")
with wave.open("test.wav", "wb") as wav_file:
    voice.synthesize_wav("Welcome to the world of speech synthesis!", wav_file)
```

mais je n'ai pas trouvé de moyen pour faire jouer ce fichier en mode streaming

j'utilise donc plutôt cette fonction qui appelle des outils en ligne de commande

```python
import subprocess

def speak(text):
    p1 = subprocess.Popen(
        ["piper", "--model", "fr_FR-upmc-medium.onnx", "--output_file", "-"],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE
    )

    audio, _ = p1.communicate(text.encode())

    subprocess.run(["aplay"], input=audio)

speak("Bienvenue dans ce monde")

```

On peut en faite le faire en pur python

il faut installer des modules supplémentaires

```bash
pip install sounddevice
```


```python
import wave
import numpy as np
import sounddevice as sd
from piper import PiperVoice

MODEL_PATH = "./fr_FR-upmc-medium.onnx"

voice = PiperVoice.load(MODEL_PATH)


def speak(text):
    # 1. Générer le wav
    wav_path = "tmp.wav"

    with wave.open(wav_path, "wb") as wav_file:
        voice.synthesize_wav(text, wav_file)

    # 2. Lire le wav avec sounddevice
    with wave.open(wav_path, "rb") as wf:
        sample_rate = wf.getframerate()
        frames = wf.readframes(wf.getnframes())

        audio = np.frombuffer(frames, dtype=np.int16)

        sd.play(audio, sample_rate)
        sd.wait()


# TEST
speak("ok j'ai compris")
```

et enfin un script sans fichier temporaire

```python
import numpy as np
import sounddevice as sd
from piper import PiperVoice

voice = PiperVoice.load("./fr_FR-upmc-medium.onnx")

def speak(text):
    audio_chunks = []

    for chunk in voice.synthesize(text):
        audio_chunks.append(chunk.audio_int16_bytes)

    audio = b"".join(audio_chunks)

    audio_np = np.frombuffer(audio, dtype=np.int16)

    sd.play(audio_np, 22050)  # fréquence souvent 22050 ou celle du modèle
    sd.wait()

speak("juste un test sans fichier pour voir")
```
