# 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 voixOpenAI 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_KEYdans.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 >>
# 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 :
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 decodageMultilinguisme transparent : Le texte francais est traite correctement sans paramètre de langue explicite - le modèle detecte automatiquement la langue
Lecture directe dans le notebook :
IPython.display.Audio()permet l’ecoute immediate sans telechargementsSauvegarde 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 :
- Formats de sortie : L’API peut generer directement 5 formats audio différents sans conversion post-production
- Contrôle de vitesse : Le paramètre
speedpermet 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
- Reconnaissance vocale (01-2-OpenAI-Whisper-STT) : Comprendre le chemin inverse
- Opérations audio (01-3-Basic-Audio-Opérations) : Manipuler les fichiers audio
- Whisper local (01-4-Whisper-Local) : Deporter le traitement
- Kokoro TTS (01-5-Kokoro-TTS-Local) : Alternative open-source