Lesson 4 — Générer la voix

Dialogue à deux voix, chiffres et accessibilité

5 min read

This content is not translated yet. Showing the original version.

Dialogue à deux voix, chiffres et accessibilité

Un dialogue en une seule requête

Le TTS multi-locuteurs produit un seul fichier dans lequel deux voix se répondent. La configuration associe chaque nom de locuteur à une voix ; le contenu est une liste de Parts, une par réplique, chacune étiquetée par son locuteur dans speech_metadata.speaker.

flowchart TB
  J["appel_fictif.json"] --> L1["Part : Agent, accueillante"]
  J --> L2["Part : Client, agacé"]
  J --> L3["Part : Agent, rassurante"]
  V["voices : Agent=Kore, Client=Puck"] --> CFG["MultiSpeakerVoiceConfig"]
  L1 --> REQ["generate_content"]
  L2 --> REQ
  L3 --> REQ
  CFG --> REQ
  REQ --> W["appel.wav : un seul fichier, deux voix"]
files/voix.py
def tts_dialogue(c, lines: list[dict], voices: dict[str, str], path: str) -> float:
    """Plusieurs voix (2 maximum) : une Part par réplique, chacune étiquetée avec son locuteur."""
    from google.genai import types
    parts = [types.Part(text=l["text"], speech_metadata=types.SpeechMetadata(
        speaker=l["speaker"], style=l.get("style"))) for l in lines]
    cfg = types.GenerateContentConfig(
        response_modalities=["AUDIO"],
        speech_config=types.SpeechConfig(multi_speaker_voice_config=types.MultiSpeakerVoiceConfig(
            speaker_voice_configs=[types.SpeakerVoiceConfig(speaker=s, voice_config=_voice(v))
                                   for s, v in voices.items()])))
    r = with_retry(lambda: c.models.generate_content(
        model=TTS_MODEL, contents=[types.Content(role="user", parts=parts)], config=cfg))
    return save_wav(r.candidates[0].content.parts[0].inline_data.data, path)

Le script de l'appel vit dans un fichier de données, appel_fictif.json : changer le scénario ne demande aucune ligne de code.

Combien de requêtes faut-il pour produire un appel de 7 répliques à deux voix avec tts_dialogue ?

Écrire pour l'oreille

Un texte lu n'est pas un texte écrit. Quelques règles, valables pour le message de rappel comme pour un serveur vocal :

À l'écritÀ l'oralPourquoi
« Cde n° 4521 »« la commande 4521 » ou « quarante-cinq vingt et un »les abréviations sont lues lettre à lettre ou mal
liste à pucesphrases courtes reliées par « puis », « ensuite »une liste ne s'entend pas
3 informations par phrase1 information par phrasela mémoire auditive est courte
« cf. e-mail »« vous recevrez un e-mail ce soir »pas de renvoi visuel
URL complète« sur notre site, rubrique Commandes »personne ne retient une URL entendue

C'est pourquoi la consigne du compte rendu (projet final) demande explicitement un reponse_vocale « sans liste, phrases simples faciles à écouter ».

Accessibilité : la voix comme alternative

Le TTS rend un service lisible par qui ne peut pas lire l'écran : personnes aveugles ou malvoyantes, dyslexiques, ou simplement occupées (au volant). Le W3C (voir les références) rappelle que l'accessibilité consiste à offrir plusieurs moyens d'accéder à la même information.

  • Proposez toujours l'équivalent texte d'un message vocal (et inversement, la transcription d'un appel).
  • Laissez le choix de la vitesse et la possibilité de réécouter.
  • Ne faites pas de la voix le seul canal pour une information importante (un numéro de suivi se lit, il ne s'écoute pas).

Résultat obtenu

Sortie réelle du 2026-10-15 du projet final, étape 1 (7 répliques, voix Kore et Puck) :

[1] appel.wav : 41.1 s d'audio (gemini-3.8-flash-tts)
Durées (s) : {'1_tts_appel': 13.9, ...}

Écoutez le résultat :

Faux appel au service client, deux voix synthétiques

Le même script a produit 38,4 s, 38,5 s puis 41,1 s lors de trois exécutions : le rythme varie d'une génération à l'autre.

Quelles pratiques améliorent un message vocal de rappel ? (plusieurs réponses)

Exercice : un troisième personnage

Votre scénario veut faire intervenir un superviseur en plus de l'agent et du client. Le TTS multi-locuteurs accepte deux voix au maximum. Que faites-vous ?

Voir la solution

Deux options simples :

  1. Découper l'appel en segments de deux voix au plus (agent + client, puis agent + superviseur), générer chaque segment, puis concaténer les PCM avec le module wave (même fréquence, même format) : lire les trames de chaque fichier et les écrire à la suite dans un nouveau WAV.
  2. Générer chaque réplique avec voix.tts et sa voix propre, puis concaténer. Plus de requêtes, moins de naturel dans l'enchaînement, mais aucune limite de personnages.

Dans les deux cas, ajoutez un court silence (par exemple 300 ms de zéros) entre les segments pour éviter un raccord abrupt.

Je sais faire

  • Générer un dialogue à deux voix avec speech_metadata.speaker
  • Décrire un scénario d'appel dans un fichier de données plutôt que dans le code
  • Réécrire un texte pour qu'il soit compris à l'oreille
  • Citer trois bonnes pratiques d'accessibilité pour un service vocal
Next