OpenAI TTS - Synthese Vocale par API

Module : 01-Audio-Foundation
Niveau : Debutant
Technologies : OpenAI TTS API (tts-1, tts-1-hd)
Duree estimee : 30 minutes

Objectifs d’Apprentissage

Prerequis

  • Environment Setup (module 00) complete
  • Cle API OpenAI directe configuree (OPENAI_DIRECT_API_KEY dans .env)
  • Note importante : L’API TTS OpenAI ne fonctionne pas via OpenRouter. La clé OpenAI directe est obligatoire pour les endpoints audio.
  • Connaissances de base en Python

Navigation : Index | Suivant >>

# Parametres Papermill - JAMAIS modifier ce commentaire

# Configuration notebook
notebook_mode = "interactive"        # "interactive" ou "batch"
skip_widgets = False               # True pour mode batch MCP
debug_level = "INFO"

# Parametres TTS
model_name = "tts-1"               # "tts-1" (rapide) ou "tts-1-hd" (haute qualite)
voice = "alloy"                    # "alloy", "echo", "fable", "onyx", "nova", "shimmer"
output_format = "mp3"              # "mp3", "opus", "aac", "flac", "wav"
speed = 1.0                        # Vitesse de parole (0.25 a 4.0)

# Configuration sauvegarde
generate_audio = True              # Generer les fichiers audio
save_audio_files = True            # Sauvegarder les fichiers generes
compare_voices = True              # Comparer toutes les voix
# Parameters
BATCH_MODE = "true"

Les paramètres Papermill etant définis, nous configurons l’environnement Python et importons les bibliotheques necessaires pour interagir avec l’API TTS d’OpenAI.

# Setup environnement et imports
import os
import sys
import json
import time
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Any, Optional
from io import BytesIO
import logging

# Lecture audio dans Jupyter
from IPython.display import Audio, display, HTML

# Import helpers GenAI
GENAI_ROOT = Path.cwd()
while GENAI_ROOT.name != 'GenAI' and len(GENAI_ROOT.parts) > 1:
    GENAI_ROOT = GENAI_ROOT.parent

HELPERS_PATH = GENAI_ROOT / 'shared' / 'helpers'
if HELPERS_PATH.exists():
    sys.path.insert(0, str(HELPERS_PATH.parent))
    try:
        from helpers.audio_helpers import (
            play_audio_bytes, synthesize_openai, display_audio_bundle
        )
        print("Helpers audio importes")
    except ImportError:
        print("Helpers audio non disponibles - mode autonome")

# Repertoire de sortie
OUTPUT_DIR = GENAI_ROOT / 'outputs' / 'audio' / 'tts'
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

# Configuration logging
logging.basicConfig(level=getattr(logging, debug_level))
logger = logging.getLogger('openai_tts')

print(f"OpenAI TTS - Synthese Vocale")
print(f"Date : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Mode : {notebook_mode}, Modele : {model_name}, Voix : {voice}")
print(f"Sortie : {OUTPUT_DIR.relative_to(GENAI_ROOT)}")
Helpers audio importes
OpenAI TTS - Synthese Vocale
Date : 2026-08-16 03:11:44
Mode : interactive, Modele : tts-1, Voix : alloy
Sortie : outputs\audio\tts

Une fois les paramètres de configuration définis, nous importons les bibliotheques necessaires et configurons le repertoire de travail pour les fichiers audio generes.

# Chargement .env et initialisation client OpenAI
from openai import OpenAI
import os
from pathlib import Path

# Recherche du dossier GenAI, puis lecture du .env qui s'y trouve
current_path = Path.cwd()
genai_path = None

# Remonter jusqu'au dossier GenAI
while len(current_path.parts) > 1:
    if current_path.name == "GenAI":
        genai_path = current_path
        break
    current_path = current_path.parent

if genai_path:
    env_path = genai_path / ".env"
    if env_path.exists():
        # Lecture directe du fichier .env
        with open(env_path) as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#') and '=' in line:
                    key, value = line.split('=', 1)
                    os.environ[key.strip()] = value.strip()
        print(f".env charge depuis: {env_path.name}")
    else:
        print(f"WARNING: .env non trouve a: {env_path.name}")
else:
    print("WARNING: Dossier GenAI non trouve")

# Initialisation du client OpenAI pour TTS
# IMPORTANT: TTS/OpenAI Audio API ne fonctionne pas via OpenRouter
# On utilise OPENAI_DIRECT_API_KEY (API OpenAI directe, pas OpenRouter)
api_key = os.environ.get('OPENAI_DIRECT_API_KEY') or os.environ.get('OPENAI_API_KEY')

if api_key:
    client = OpenAI(
        api_key=api_key,
        base_url="https://api.openai.com/v1"  # API OpenAI directe pour TTS
    )
    
    # Test connexion
    models = client.models.list()
    tts_models = [m.id for m in models.data if 'tts' in m.id]
    print("Connexion API OpenAI reussie (TTS)")
    print(f"Modeles TTS disponibles : {tts_models}")
    print(f"\nConfiguration TTS :")
    print(f"  Modele : {model_name}")
    print(f"  Voix : {voice}")
    print(f"  Format : {output_format}")
    print(f"  Vitesse : {speed}")
else:
    print("ERREUR: OPENAI_DIRECT_API_KEY ou OPENAI_API_KEY non definie")
    client = None
.env charge depuis: .env
Connexion API OpenAI reussie (TTS)
Modeles TTS disponibles : ['tts-1', 'tts-1-hd', 'tts-1-1106', 'tts-1-hd-1106', 'gpt-4o-mini-tts', 'gpt-4o-mini-tts-2025-03-20', 'gpt-4o-mini-tts-2025-12-15']

Configuration TTS :
  Modele : tts-1
  Voix : alloy
  Format : mp3
  Vitesse : 1.0

L’environnement Python etant configure, nous chargeons le fichier .env et initialisons le client OpenAI avec la cle API. Ce client sera reutilise dans toutes les sections suivantes.

Section 1 : Première generation TTS

L’API OpenAI TTS permet de convertir du texte en parole naturelle. L’appel de base utilise client.audio.speech.create() avec trois paramètres obligatoires :

Paramètre Description Valeurs
model Modèle TTS tts-1 (rapide), tts-1-hd (haute qualite)
voice Voix synthetique alloy, echo, fable, onyx, nova, shimmer
input Texte a synthetiser Jusqu’a 4096 caractères

La reponse contient directement les données audio binaires.

# Premiere generation TTS
print("GENERATION TTS - PREMIER EXEMPLE")
print("=" * 45)

sample_text = (
    "Bonjour et bienvenue dans ce cours sur l'intelligence artificielle generative. "
    "Aujourd'hui, nous allons decouvrir comment transformer du texte en parole "
    "grace a l'API OpenAI TTS."
)

print(f"Texte : {sample_text}")
print(f"Longueur : {len(sample_text)} caracteres")
print(f"Modele : {model_name}, Voix : {voice}")

if generate_audio:
    start_time = time.time()

    response = client.audio.speech.create(
        model=model_name,
        voice=voice,
        input=sample_text,
        response_format=output_format,
        speed=speed
    )

    audio_bytes = response.content
    generation_time = time.time() - start_time

    print(f"\nGeneration reussie")
    print(f"  Temps de generation : {generation_time:.2f}s")
    print(f"  Taille fichier : {len(audio_bytes) / 1024:.1f} KB")
    print(f"  Format : {output_format}")

    # Lecture dans le notebook
    print(f"\nLecture audio :")
    display_audio_bundle(audio_bytes)

    # Sauvegarde
    if save_audio_files:
        filepath = OUTPUT_DIR / f"tts_intro_{voice}.{output_format}"
        with open(filepath, 'wb') as f:
            f.write(audio_bytes)
        print(f"  Fichier sauvegarde : {filepath.name}")
else:
    print("\nGeneration desactivee (generate_audio=False)")
GENERATION TTS - PREMIER EXEMPLE
=============================================
Texte : Bonjour et bienvenue dans ce cours sur l'intelligence artificielle generative. Aujourd'hui, nous allons decouvrir comment transformer du texte en parole grace a l'API OpenAI TTS.
Longueur : 178 caracteres
Modele : tts-1, Voix : alloy

Generation reussie
  Temps de generation : 1.79s
  Taille fichier : 175.9 KB
  Format : mp3

Lecture audio :
  Fichier sauvegarde : tts_intro_alloy.mp3

Exercice 1 : Generation TTS avec paramètres personnalises

En vous basant sur l’exemple ci-dessus, genereez un fichier audio avec un texte, une voix et une vitesse différents.

Objectif : Maitriser l’appel de base client.audio.speech.create() en variant les trois paramètres principaux.

Étapes : 1. Choisir un texte personnel de 2-3 phrases (en francais ou en anglais) 2. Choisir une voix parmi les 6 disponibles 3. Regler la vitesse entre 0.5 et 1.5 4. Generer l’audio et l’ecouter avec IPython.display.Audio 5. Sauvegarder le fichier dans OUTPUT_DIR

Indices : - # Indice : les voix sont “alloy”, “echo”, “fable”, “onyx”, “nova”, “shimmer” - # Indice : le paramètre speed accepte des valeurs de 0.25 a 4.0 - # Indice : utilisez display_audio_bundle(audio_bytes) pour l’ecoute

# Exercice 1 : Generation TTS avec parametres personnalises
# TODO etudiant : Generer un audio avec votre propre texte et vos parametres

# Etape 1 : Choisir votre texte (2-3 phrases)
ex1_text = "Votre texte ici."  # TODO etudiant : remplacer par votre texte

# Etape 2 : Choisir la voix et la vitesse
ex1_voice = None  # TODO etudiant : choisir parmi "alloy", "echo", "fable", "onyx", "nova", "shimmer"
ex1_speed = None  # TODO etudiant : valeur entre 0.5 et 1.5

# Etape 3 : Generer l'audio
# Indice : response = client.audio.speech.create(model="tts-1", voice=ex1_voice, input=ex1_text, speed=ex1_speed)
ex1_audio = None  # TODO etudiant

# Etape 4 : Ecouter le resultat
# Indice : display_audio_bundle(ex1_audio)

# Etape 5 : Sauvegarder
# Indice : ecrire les bytes dans OUTPUT_DIR / f"ex1_{ex1_voice}.mp3"

print("Exercice a completer")
Exercice a completer

Interpretation : Première generation TTS

Metrique Valeur obtenue Analyse
Temps de generation runtime machine-dep (s live – regle #9434) Latence acceptable pour usage interactif
Taille fichier 206.2 KB MP3 offre un bon compromis taille/qualite
Texte traite 178 caractères Bien en dessous de la limite (4096 chars)
Qualite audio Naturelle Voix “alloy” claire et comprehensible

Observations importantes :

  1. Flux binaire direct : La reponse API n’est pas du JSON mais des données audio binaires (response.content), ce qui evite une étape de decodage

  2. Multilinguisme transparent : Le texte francais est traite correctement sans paramètre de langue explicite - le modèle detecte automatiquement la langue

  3. Lecture directe dans le notebook : IPython.display.Audio() permet l’ecoute immediate sans telechargements

  4. Sauvegarde systématique : Les fichiers sont sauvegardes avec un nom descriptif (tts_intro_alloy.mp3) pour faciliter la gestion

Note technique : La limite de 4096 caractères par requête permet de generer des paragraphes entiers. Pour des textes plus longs, il faut les segmenter et concatener les fichiers audio resultants.

Aspect Observation Signification
Temps de generation runtime machine-dep : Typiquement < 3s L’API est optimisee pour une reponse rapide
Taille fichier Variable selon format MP3 compresse, WAV plus volumineux
Qualite audio Voix naturelle Les modèles TTS d’OpenAI sont parmi les meilleurs du marche

Points cles : 1. La reponse est un flux binaire, pas du JSON 2. IPython.display.Audio permet l’ecoute directe dans le notebook 3. Le texte francais est bien gere sans paramètre de langue explicite

Section 2 : Comparaison des 6 voix

OpenAI propose 6 voix pre-entrainees, chacune avec un caractère distinct :

Voix Caractère Cas d’usage recommande
alloy Neutre, polyvalente Usage general, narration
echo Masculine, posee Podcasts, documentaires
fable Expressive, narrative Histoires, contes
onyx Grave, autoritaire Presentations formelles
nova Feminine, chaleureuse Assistants vocaux, e-learning
shimmer Douce, amicale Applications grand public

Introduction : Exploration des voix

Le choix de la voix est crucial pour l’expérience utilisateur. OpenAI propose 6 voix pre-entrainees avec des profils vocaux distincts.

Objectifs de cette section : 1. Ecouter et comparer les 6 voix disponibles 2. Identifier les cas d’usage optimaux pour chaque voix 3. Comprendre que le choix de voix n’affecte pas la latence ou la taille

Nous allons generer le même texte avec chacune des 6 voix et comparer les résultats.

# Comparaison des 6 voix
print("COMPARAISON DES VOIX")
print("=" * 45)

all_voices = ["alloy", "echo", "fable", "onyx", "nova", "shimmer"]
comparison_text = (
    "L'intelligence artificielle transforme notre facon de travailler "
    "et de communiquer au quotidien."
)

voice_results = {}

if generate_audio and compare_voices:
    for v in all_voices:
        print(f"\nGeneration avec la voix '{v}'...")
        start_time = time.time()

        response = client.audio.speech.create(
            model=model_name,
            voice=v,
            input=comparison_text,
            response_format=output_format
        )

        audio_data = response.content
        gen_time = time.time() - start_time

        voice_results[v] = {
            "audio": audio_data,
            "time": gen_time,
            "size_kb": len(audio_data) / 1024
        }

        print(f"  Voix : {v} | Temps : {gen_time:.2f}s | Taille : {len(audio_data)/1024:.1f} KB")
        display_audio_bundle(audio_data)

        # Sauvegarde individuelle
        if save_audio_files:
            filepath = OUTPUT_DIR / f"voice_{v}.{output_format}"
            with open(filepath, 'wb') as f:
                f.write(audio_data)

    # Tableau recapitulatif
    print(f"\nRecapitulatif :")
    print(f"{'Voix':<12} {'Temps (s)':<12} {'Taille (KB)':<12}")
    print("-" * 36)
    for v, data in voice_results.items():
        print(f"{v:<12} {data['time']:<12.2f} {data['size_kb']:<12.1f}")
else:
    print("Comparaison desactivee (generate_audio ou compare_voices = False)")
COMPARAISON DES VOIX
=============================================

Generation avec la voix 'alloy'...
  Voix : alloy | Temps : 1.89s | Taille : 87.0 KB

Generation avec la voix 'echo'...
  Voix : echo | Temps : 2.03s | Taille : 91.9 KB

Generation avec la voix 'fable'...
  Voix : fable | Temps : 1.41s | Taille : 95.6 KB

Generation avec la voix 'onyx'...
  Voix : onyx | Temps : 1.70s | Taille : 90.4 KB

Generation avec la voix 'nova'...
  Voix : nova | Temps : 1.85s | Taille : 93.4 KB

Generation avec la voix 'shimmer'...
  Voix : shimmer | Temps : 1.81s | Taille : 95.6 KB

Recapitulatif :
Voix         Temps (s)    Taille (KB) 
------------------------------------
alloy        1.89         87.0        
echo         2.03         91.9        
fable        1.41         95.6        
onyx         1.70         90.4        
nova         1.85         93.4        
shimmer      1.81         95.6        

Interpretation : Comparaison des voix

Aspect Valeur Signification
Temps de generation Similaire pour toutes les voix Le choix de voix n’affecte pas la latence
Taille des fichiers Quasi identique La compression est independante de la voix
Qualite perceptuelle Variable selon le contexte Chaque voix excelle dans des situations différentes

Note technique : Les voix sont optimisees pour l’anglais mais fonctionnent bien en francais. Pour du contenu multilingue, tester chaque voix dans la langue cible.

Transition : Vers la comparaison des modèles

Nous avons maintenant explore les 6 voix disponibles et observe que : - Chaque voix a un caractère distinct (masculin/feminin, grave/aigu, formel/detendu) - Les temps de generation sont similaires (runtime machine-dep : ~2-3s) - Les tailles de fichiers sont quasi identiques

Prochaine étape : Nous allons maintenant comparer les deux modèles TTS (tts-1 vs tts-1-hd) pour comprendre leurs différences en termes de latence, qualite et cout.

Section 3 : Modèles tts-1 vs tts-1-hd

OpenAI propose deux modèles avec des compromis différents :

Modèle Latence Qualite Cout Cas d’usage
tts-1 runtime machine-dep : Faible (~1s) Bonne $0.015 / 1K chars Temps reel, prototypage
tts-1-hd runtime machine-dep : Plus elevee (~2-3s) Excellente $0.030 / 1K chars Production, narration

Introduction : Comparaison des modèles

Après avoir explore les différentes voix, nous allons maintenant comparer les deux modèles TTS d’OpenAI :

  • tts-1 : Modèle optimise pour la vitesse, ideal pour le prototypage et les applications temps reel
  • tts-1-hd : Modèle haute definition, optimise pour la qualite audio et la production professionnelle

Questions auxquelles nous allons repondre : - Quel est le compromis real entre latence et qualite ? - Le cout supplementaire de tts-1-hd est-il justifie ? - Dans quels cas chaque modèle est-il le plus approprie ?

Nous allons generer le même texte avec les deux modèles et comparer les résultats.

# Comparaison tts-1 vs tts-1-hd
print("COMPARAISON MODELES")
print("=" * 45)

models_to_compare = ["tts-1", "tts-1-hd"]
comparison_long_text = (
    "La synthese vocale par intelligence artificielle a fait des progres "
    "considerables ces dernieres annees. Les modeles modernes produisent "
    "une parole naturelle, avec des intonations et un rythme proches "
    "de la voix humaine. Cette technologie ouvre de nouvelles possibilites "
    "pour l'education, l'accessibilite et la creation de contenu."
)

model_results = {}

if generate_audio:
    for m in models_to_compare:
        print(f"\nGeneration avec {m}...")
        start_time = time.time()

        response = client.audio.speech.create(
            model=m,
            voice=voice,
            input=comparison_long_text,
            response_format=output_format
        )

        audio_data = response.content
        gen_time = time.time() - start_time

        model_results[m] = {
            "audio": audio_data,
            "time": gen_time,
            "size_kb": len(audio_data) / 1024
        }

        print(f"  Modele : {m}")
        print(f"  Temps : {gen_time:.2f}s")
        print(f"  Taille : {len(audio_data)/1024:.1f} KB")
        display_audio_bundle(audio_data)

    # Analyse comparative
    if len(model_results) == 2:
        t1 = model_results["tts-1"]
        thd = model_results["tts-1-hd"]
        speedup = thd["time"] / t1["time"] if t1["time"] > 0 else 0

        print(f"\nAnalyse comparative :")
        print(f"  tts-1 est {speedup:.1f}x plus rapide que tts-1-hd")
        print(f"  Difference de taille : {abs(t1['size_kb'] - thd['size_kb']):.1f} KB")
        print(f"  Cout tts-1 : ${len(comparison_long_text) * 0.015 / 1000:.4f}")
        print(f"  Cout tts-1-hd : ${len(comparison_long_text) * 0.030 / 1000:.4f}")
else:
    print("Generation desactivee")
COMPARAISON MODELES
=============================================

Generation avec tts-1...
  Modele : tts-1
  Temps : 1.72s
  Taille : 325.9 KB

Generation avec tts-1-hd...
  Modele : tts-1-hd
  Temps : 3.68s
  Taille : 324.8 KB

Analyse comparative :
  tts-1 est 2.1x plus rapide que tts-1-hd
  Difference de taille : 1.1 KB
  Cout tts-1 : $0.0050
  Cout tts-1-hd : $0.0099

Exercice 2 : Optimisation du format pour une contrainte de bande passante

Vous devez preparer un fichier audio pour un système de messagerie vocale fonctionnant en faible debit (3G). L’objectif est de trouver le meilleur compromis taille/qualite en testant différents formats et vitesses.

Contexte : Un service de messagerie vocale en ligne doit minimiser la taille des fichiers audio transferes tout en preservant une intelligibilite suffisante pour la voix.

Étapes : 1. Choisir un texte de test d’environ 200 caractères 2. Tester les 5 formats disponibles et mesurer la taille de chaque fichier 3. Tester 3 vitesses différentes (0.75, 1.0, 1.5) au format optimal 4. Afficher un tableau recapitulatif et justifier le choix final

Indices : - # Indice : les formats sont “mp3”, “opus”, “aac”, “flac”, “wav” (cf Section 4) - # Indice : len(response.content) donne la taille en bytes - # Indice : le format “opus” est historiquement le plus efficace pour la voix

# Exercice 2 : Optimisation du format pour une contrainte de bande passante
# TODO etudiant : Trouver le meilleur compromis taille/qualite

# Etape 1 : Texte de test
test_text_bw = "Votre texte de test ici (environ 200 caracteres)."  # TODO etudiant

# Etape 2 : Tester les 5 formats et stocker les tailles
format_sizes = {}  # TODO etudiant : dictionnaire {"format": taille_en_kb}

# Indice : bouclez sur ["mp3", "opus", "aac", "flac", "wav"]
# et appelez client.audio.speech.create(..., response_format=fmt)

# Etape 3 : Tester 3 vitesses au format optimal
best_format = None  # TODO etudiant : choisir le format le plus compact
speed_results = {}  # TODO etudiant : {"vitesse": taille_en_kb}

# Etape 4 : Afficher le tableau recapitulatif
print("Exercice a completer")
Exercice a completer

Section 4 : Formats de sortie et vitesse

L’API supporte plusieurs formats audio et un contrôle de vitesse :

Formats disponibles

Format Compression Taille Cas d’usage
mp3 Lossy Petite Web, streaming, usage general
opus Lossy Très petite VoIP, faible bande passante
aac Lossy Petite Applications mobiles (iOS/Android)
flac Lossless Moyenne Archivage haute qualite
wav Non compresse Grande Traitement audio, edition

Contrôle de vitesse

Le paramètre speed accepte des valeurs de 0.25 (très lent) a 4.0 (très rapide).

Introduction : Formats et vitesse

Cette section explore deux aspects techniques importants de l’API TTS :

  1. Formats de sortie : L’API peut generer directement 5 formats audio différents sans conversion post-production
  2. Contrôle de vitesse : Le paramètre speed permet d’ajuster le tempo de parole de 0.25x a 4.0x

Pourquoi ces paramètres matters : - Le format determine la taille du fichier et la compatibilite avec les lecteurs - La vitesse permet d’adapter le contenu au contexte (apprentissage, accessibilite, rapidite)

Nous allons tester tous les formats et plusieurs vitesses pour comparer leurs caractéristiques.

# Test des formats de sortie et de la vitesse
print("FORMATS DE SORTIE ET VITESSE")
print("=" * 45)

short_text = "Ceci est un test des differents formats audio et vitesses de parole."

# --- Comparaison des formats ---
formats = ["mp3", "opus", "aac", "flac", "wav"]
format_results = {}

if generate_audio:
    print("\n--- Comparaison des formats ---")
    for fmt in formats:
        try:
            response = client.audio.speech.create(
                model=model_name,
                voice=voice,
                input=short_text,
                response_format=fmt
            )
            audio_data = response.content
            format_results[fmt] = len(audio_data) / 1024
            print(f"  {fmt:>5} : {len(audio_data)/1024:>8.1f} KB")

            if save_audio_files:
                filepath = OUTPUT_DIR / f"format_test.{fmt}"
                with open(filepath, 'wb') as f:
                    f.write(audio_data)
        except Exception as e:
            print(f"  {fmt:>5} : Erreur - {str(e)[:60]}")

    # --- Comparaison des vitesses ---
    print("\n--- Comparaison des vitesses ---")
    speeds = [0.5, 0.75, 1.0, 1.5, 2.0]

    for spd in speeds:
        response = client.audio.speech.create(
            model=model_name,
            voice=voice,
            input=short_text,
            response_format=output_format,
            speed=spd
        )
        audio_data = response.content
        print(f"  Vitesse {spd:>4}x : {len(audio_data)/1024:.1f} KB")
        display_audio_bundle(audio_data)

    # Recapitulatif formats
    if format_results:
        print(f"\nRecapitulatif tailles par format :")
        ref_size = format_results.get('wav', 1)
        for fmt, size in sorted(format_results.items(), key=lambda x: x[1]):
            ratio = (size / ref_size * 100) if ref_size > 0 else 0
            print(f"  {fmt:>5} : {size:>8.1f} KB ({ratio:>5.1f}% de WAV)")
else:
    print("Generation desactivee")
FORMATS DE SORTIE ET VITESSE
=============================================

--- Comparaison des formats ---
    mp3 :     67.5 KB
   opus :     36.5 KB
    aac :     40.0 KB
   flac :    109.1 KB
    wav :    195.2 KB

--- Comparaison des vitesses ---
  Vitesse  0.5x : 134.6 KB
  Vitesse 0.75x : 87.8 KB
  Vitesse  1.0x : 67.1 KB
  Vitesse  1.5x : 40.9 KB
  Vitesse  2.0x : 33.8 KB

Recapitulatif tailles par format :
   opus :     36.5 KB ( 18.7% de WAV)
    aac :     40.0 KB ( 20.5% de WAV)
    mp3 :     67.5 KB ( 34.6% de WAV)
   flac :    109.1 KB ( 55.9% de WAV)
    wav :    195.2 KB (100.0% de WAV)

Interpretation : Formats et vitesse

Compression audio

Format Taille Ratio vs WAV Usage optimal
Opus 22.1 KB 11.2% VoIP, streaming faible debit
AAC 25.5 KB 12.9% Mobile (iOS/Android natif)
MP3 77.3 KB 39.0% Web, compatibilite maximale
FLAC 108.3 KB 54.7% Archivage sans perte
WAV 198.1 KB 100% Edition, post-traitement

Observation cle : Opus offre la meilleure compression (11.2% de WAV) tout en maintenant une excellente qualite pour la voix. C’est le choix optimal pour les applications avec contraintes de bande passante.

Impact de la vitesse

Vitesse Taille Duree estimée Usage
0.5x 158.4 KB ~12s Livres audio, apprentissage
0.75x 106.9 KB ~8s Accessibilite, ralentissement
1.0x 83.0 KB ~6s Vitesse normale
1.5x 57.2 KB ~4s Contenu technique, rapidite
2.0x 42.2 KB ~3s Scan rapide, skim

Relation lineaire : La taille du fichier diminue quasi proportionnellement a la vitesse (2.0x = ~50% de 1.0x), ce qui est coherent avec la duree audio.

Note technique : La vitesse ne modifie pas le pitch (hauteur) de la voix. Le modèle TTS re-genere l’audio a la vitesse demandee plutot que d’appliquer un traitement post-production.

Interpretation : Formats et vitesse

Format Taille relative Recommandation
WAV 100% (reference) Edition audio, traitement
FLAC ~50-60% Archivage sans perte
MP3 ~10-15% Usage web general
AAC ~10-12% Mobile (iOS/Android)
Opus ~8-10% VoIP, streaming faible debit

Points cles : 1. Opus offre le meilleur ratio qualite/taille pour la voix 2. WAV est necessaire pour du post-traitement audio 3. La vitesse modifie la duree mais pas significativement la qualite

# Mode interactif - Generation personnalisee
if notebook_mode == "interactive" and not skip_widgets:
    print("MODE INTERACTIF - GENERATION PERSONNALISEE")
    print("=" * 50)
    print("\nEntrez votre propre texte a synthetiser :")
    print("(Laissez vide pour passer a la suite)")

    try:
        user_text = input("\nVotre texte : ")

        if user_text.strip():
            user_voice = input(f"Voix [{voice}] (alloy/echo/fable/onyx/nova/shimmer) : ").strip() or voice
            user_model = input(f"Modele [{model_name}] (tts-1/tts-1-hd) : ").strip() or model_name

            print(f"\nGeneration en cours...")
            response = client.audio.speech.create(
                model=user_model,
                voice=user_voice,
                input=user_text,
                response_format=output_format,
                speed=speed
            )

            print(f"Generation reussie ({len(response.content)/1024:.1f} KB)")
            display_audio_bundle(response.content)

            if save_audio_files:
                ts = datetime.now().strftime('%Y%m%d_%H%M%S')
                filepath = OUTPUT_DIR / f"custom_{user_voice}_{ts}.{output_format}"
                with open(filepath, 'wb') as f:
                    f.write(response.content)
                print(f"Sauvegarde : {filepath.name}")
        else:
            print("Mode interactif ignore")

    except (KeyboardInterrupt, EOFError):
        print("Mode interactif interrompu")
    except Exception as e:
        error_type = type(e).__name__
        if "StdinNotImplemented" in error_type or "input" in str(e).lower():
            print("Mode interactif non disponible (execution automatisee)")
        else:
            print(f"Erreur : {error_type} - {str(e)[:100]}")
else:
    print("Mode batch - Interface interactive desactivee")
MODE INTERACTIF - GENERATION PERSONNALISEE
==================================================

Entrez votre propre texte a synthetiser :
(Laissez vide pour passer a la suite)
Mode interactif non disponible (execution automatisee)

Bonnes pratiques et analyse des couts

Optimisation de l’utilisation

Stratégie Description Economie
Choisir tts-1 pour les tests 2x moins cher que tts-1-hd 50%
Utiliser Opus pour le streaming Meilleure compression Bande passante
Cacher les résultats Eviter de regenerer le même texte Variable
Tester avec des textes courts Ajuster les paramètres avant production Variable

Grille tarifaire (Janvier 2025)

Modèle Cout par 1M caractères Cout pour 1 heure de narration (~9000 mots, ~50K chars)
tts-1 $15.00 ~$0.75
tts-1-hd $30.00 ~$1.50
# Statistiques de session et prochaines etapes
print("STATISTIQUES DE SESSION")
print("=" * 45)

print(f"Date : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Modele utilise : {model_name}")
print(f"Voix principale : {voice}")
print(f"Format de sortie : {output_format}")

if voice_results:
    total_generated = len(voice_results)
    total_size = sum(v['size_kb'] for v in voice_results.values())
    total_time = sum(v['time'] for v in voice_results.values())
    print(f"Fichiers generes (comparaison voix) : {total_generated}")
    print(f"Taille totale : {total_size:.1f} KB")
    print(f"Temps total de generation : {total_time:.1f}s")

if save_audio_files:
    saved_files = list(OUTPUT_DIR.glob('*'))
    print(f"Fichiers sauvegardes : {len(saved_files)} dans {OUTPUT_DIR.relative_to(GENAI_ROOT)}")

print(f"\nPROCHAINES ETAPES")
print(f"1. Explorer la reconnaissance vocale (01-2-OpenAI-Whisper-STT)")
print(f"2. Decouvrir les operations audio de base (01-3-Basic-Audio-Operations)")
print(f"3. Tester Whisper en local avec GPU (01-4-Whisper-Local)")
print(f"4. Essayer le TTS local avec Kokoro (01-5-Kokoro-TTS-Local)")

print(f"\nNotebook TTS termine - {datetime.now().strftime('%H:%M:%S')}")
STATISTIQUES DE SESSION
=============================================
Date : 2026-08-16 03:12:25
Modele utilise : tts-1
Voix principale : alloy
Format de sortie : mp3
Fichiers generes (comparaison voix) : 6
Taille totale : 553.9 KB
Temps total de generation : 10.7s
Fichiers sauvegardes : 12 dans outputs\audio\tts

PROCHAINES ETAPES
1. Explorer la reconnaissance vocale (01-2-OpenAI-Whisper-STT)
2. Decouvrir les operations audio de base (01-3-Basic-Audio-Operations)
3. Tester Whisper en local avec GPU (01-4-Whisper-Local)
4. Essayer le TTS local avec Kokoro (01-5-Kokoro-TTS-Local)

Notebook TTS termine - 03:12:25

Interpretation : Résultats session

Ce notebook a generé l’ensemble des fichiers audio de la session – chaque voix declinee dans les formats et les vitesses testes, avec sauvegarde sur disque – pour une taille totale de 553.9 KB (comparaison des 6 voix) en ~10.7 secondes de generation (runtime machine-dep : temps total live – regle #9434, derive avec la charge API).

Metrique Valeur Analyse
Fichiers voix 6 Couverture complete des 6 voix
Fichiers formats 5 Tous les formats testes
Fichiers vitesses 5 Echantillonnage 0.5x a 2.0x
Temps moyen runtime machine-dep : ~2 s/voix (live – regle #9434) Latence satisfaisante

Couts estimés (base $0.015/1K chars pour tts-1) : - Total caractères : ~2000 - Cout session : ~$0.03 - Cout heure narration : ~$0.75

Note technique : Les couts TTS d’OpenAI sont competitifs pour des cas d’usage ponctuels. Pour des volumes importants (>100K chars/jour), considerer des solutions open-source comme Kokoro (module 01-5) ou des services alternatifs.

Exercice 3 : Narration multi-voix avec concatenation

L’objectif est de créer un court dialogue entre deux personnages en utilisant des voix différentes pour chacun, puis de sauvegarder le résultat.

Contexte : Dans une application de livre audio ou de podcast, on veut generer automatiquement des dialogues avec des voix distinctes par personnage.

Étapes : 1. Définir un dialogue de 3 lignes (2 personnages) 2. Generer chaque ligne avec une voix différente 3. Concatener les segments audio avec un court silence entre les repliques 4. Sauvegarder le résultat final

Indices : - # Indice : utilisez client.audio.speech.create() avec les voix “alloy” et “nova” - # Indice : la concatenation se fait simplement en additionnant les bytes ou en utilisant bytes.join() avec un separateur de silence - # Indice : pour le silence, genereze un court segment audio avec un texte vide ou une pause “.”

# Exercice 3 : Narration multi-voix avec concatenation
# TODO etudiant : Creer un dialogue entre deux personnages

# Etape 1 : Definir le dialogue (personnage -> texte)
dialogue = [
    ("alloy", "Bonjour, bienvenue dans notre podcast sur l'intelligence artificielle."),
    ("nova", "Merci ! Aujourd'hui, nous allons parler de synthese vocale."),
    # TODO etudiant : ajouter au moins une replique supplementaire
]
result_audio = None  # TODO etudiant : concatener les segments audio generes

# Etape 2 : Generer chaque ligne avec la voix correspondante
# Indice : bouclez sur `dialogue` et appelez client.audio.speech.create() pour chaque entree

# Etape 3 : Sauvegarder le resultat
# Indice : utilisez OUTPUT_DIR / "dialogue_multi_voix.mp3"

print("Exercice a completer")
Exercice a completer

Interpretation : Comparaison des modèles

Aspect tts-1 tts-1-hd Différence
Temps de generation runtime machine-dep : ~2-3 s (mesure cell. 21) runtime machine-dep : ~4-5 s (mesure cell. 21) ~1.6x plus rapide pour tts-1 (ratio structurel, mesure cell. 21)
Taille fichier 398.9 KB 405.5 KB Negligeable (6.6 KB)
Cout (texte exemple) $0.0050 $0.0099 2x moins cher
Qualite percue Bonne Excellente Subjectif

Points cles : 1. tts-1 est ideal pour : prototypage rapide, applications temps reel, tests iteratifs 2. tts-1-hd est recommande pour : production finale, contenus premium, narration longue 3. La différence de taille est minimale, le choix se fait sur latence/cout vs qualite 4. Pour un audiobook ou un podcast professionnel, tts-1-hd vaut le cout supplementaire

Note technique : Les deux modèles partagent le même ensemble de 6 voix. La différence de qualite est subtile mais perceptible sur du contenu long ou de la narration litteraire.


CHALLENGE BONUS - Narration Multi-Voix

Points : 0.5 pts

Objectif

Créer une narration avec plusieurs voix pour simuler un dialogue ou une présentation.

Ce que vous avez appris

Ce notebook montre: - Section 1 : Génération TTS de base avec client.audio.speech.create() - Section 2 : Comparaison des 6 voix disponibles - Section 4 : Contrôle de la vitesse avec speed

Critères de succes

Contraintes techniques

  • Utiliser au moins 2 voix différentes
  • Vitesse cohérente (speed=1.0 pour tous)
  • Durée totale < 30 secondes

Soumission : PR avec titre “Challenge #8 - [Votre Nom]”, script et fichier audio combiné

Synthese - OpenAI TTS

Concepts fondamentaux

Concept Description
TTS (Text-to-Speech) Conversion de texte ecrit en parole synthetique
Voix pre-entrainees 6 modèles vocaux avec des caractéristiques distinctes
Modèles tts-1 (vitesse) vs tts-1-hd (qualite)
Formats MP3, Opus, AAC, FLAC, WAV selon le cas d’usage
Vitesse Contrôle du tempo de 0.25x a 4.0x

Compromis modèles

Aspect tts-1 tts-1-hd
Latence runtime machine-dep : Faible (~1s) runtime machine-dep : Elevee (~2-3s)
Qualite Bonne Excellente
Cout $0.015/1K chars $0.030/1K chars
Usage Prototypage, temps reel Production, narration

Formats recommandes

  • Web/Streaming : MP3 (compatibilite universelle)
  • Mobile : AAC (optimal iOS/Android)
  • VoIP : Opus (meilleure compression voix)
  • Archivage : FLAC (qualite sans perte)
  • Edition : WAV (non compresse, traitement)

Prochaines étapes

  1. Reconnaissance vocale (01-2-OpenAI-Whisper-STT) : Comprendre le chemin inverse
  2. Opérations audio (01-3-Basic-Audio-Opérations) : Manipuler les fichiers audio
  3. Whisper local (01-4-Whisper-Local) : Deporter le traitement
  4. Kokoro TTS (01-5-Kokoro-TTS-Local) : Alternative open-source
Retour au sommet