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"]
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 ?
Le TTS multi-locuteurs reçoit toutes les répliques dans une seule requête. Le modèle enchaîne les voix et les pauses naturellement, sans montage.
É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'oral | Pourquoi |
|---|---|---|
| « Cde n° 4521 » | « la commande 4521 » ou « quarante-cinq vingt et un » | les abréviations sont lues lettre à lettre ou mal |
| liste à puces | phrases courtes reliées par « puis », « ensuite » | une liste ne s'entend pas |
| 3 informations par phrase | 1 information par phrase | la 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 :
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)
Phrases courtes et équivalent texte aident tout le monde, y compris les personnes en situation de handicap. Une URL ou une liste à puces ne s'entend pas bien : envoyez-les par écrit.
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 :
- 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. - Générer chaque réplique avec
voix.ttset 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