97 lines
3.6 KiB
Python
97 lines
3.6 KiB
Python
"""Configuration centrale d'InkFlow.
|
|
|
|
Toutes les constantes (chemins, identifiants de modeles MLX, parametres par
|
|
defaut) sont regroupees ici pour rester facilement surchargeables via variables
|
|
d'environnement.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
# --- Racines du projet -------------------------------------------------------
|
|
# config.py est dans backend/inkflow/, la racine projet est donc deux niveaux
|
|
# au-dessus de backend/.
|
|
BACKEND_DIR = Path(__file__).resolve().parents[1]
|
|
PROJECT_ROOT = BACKEND_DIR.parent
|
|
|
|
|
|
def _env_path(var: str, default: Path) -> Path:
|
|
return Path(os.environ.get(var, default)).expanduser().resolve()
|
|
|
|
|
|
# Donnees de travail (etat par livre : json, db, wav intermediaires)
|
|
DATA_DIR = _env_path("INKFLOW_DATA_DIR", PROJECT_ROOT / "data")
|
|
# Sortie finale (1 dossier par livre, 1 mp3 par chapitre)
|
|
OUTPUT_DIR = _env_path("INKFLOW_OUTPUT_DIR", PROJECT_ROOT / "output")
|
|
# Banque de voix de reference (clips + metadata.json)
|
|
VOICEBANK_DIR = _env_path("INKFLOW_VOICEBANK_DIR", PROJECT_ROOT / "voicebank")
|
|
# Echantillons fournis
|
|
SAMPLES_DIR = PROJECT_ROOT / "samples"
|
|
|
|
# --- Modeles MLX (HuggingFace mlx-community) ---------------------------------
|
|
# Analyse de texte : Gemma via mlx-lm.
|
|
GEMMA_MODEL = os.environ.get(
|
|
"INKFLOW_GEMMA_MODEL", "mlx-community/gemma-3-4b-it-4bit"
|
|
)
|
|
|
|
# TTS : Qwen3-TTS (rendu final, clonage) et Kokoro (preview rapide).
|
|
QWEN3_TTS_MODEL = os.environ.get(
|
|
"INKFLOW_QWEN3_MODEL", "mlx-community/Qwen3-TTS-12Hz-1.7B-Base-8bit"
|
|
)
|
|
KOKORO_MODEL = os.environ.get(
|
|
"INKFLOW_KOKORO_MODEL", "mlx-community/Kokoro-82M-bf16"
|
|
)
|
|
|
|
# --- Parametres TTS ----------------------------------------------------------
|
|
DEFAULT_LANGUAGE = os.environ.get("INKFLOW_LANGUAGE", "French")
|
|
# Code langue Kokoro (misaki) : 'f' = francais.
|
|
KOKORO_LANG_CODE = os.environ.get("INKFLOW_KOKORO_LANG", "f")
|
|
# Voix Kokoro par defaut pour les previews / mono-narrateur rapide.
|
|
KOKORO_DEFAULT_VOICE = os.environ.get("INKFLOW_KOKORO_VOICE", "ff_siwis")
|
|
# Voix Qwen3 par defaut (narrateur) si aucun clip de reference fourni.
|
|
QWEN3_DEFAULT_VOICE = os.environ.get("INKFLOW_QWEN3_VOICE", "Chelsie")
|
|
|
|
# Frequence d'echantillonnage cible pour la concatenation (Hz). Les backends
|
|
# renvoient leur propre sr ; postprocess reechantillonne au besoin.
|
|
TARGET_SAMPLE_RATE = int(os.environ.get("INKFLOW_SAMPLE_RATE", "24000"))
|
|
|
|
# Encodage mp3 final.
|
|
MP3_BITRATE = os.environ.get("INKFLOW_MP3_BITRATE", "128k")
|
|
# Cible de normalisation loudness (LUFS approx via pydub gain).
|
|
TARGET_DBFS = float(os.environ.get("INKFLOW_TARGET_DBFS", "-18.0"))
|
|
|
|
|
|
def book_data_dir(book_slug: str) -> Path:
|
|
"""Dossier de travail pour un livre (artefacts intermediaires)."""
|
|
return DATA_DIR / book_slug
|
|
|
|
|
|
def book_output_dir(book_title: str) -> Path:
|
|
"""Dossier de sortie final pour un livre (mp3 par chapitre)."""
|
|
return OUTPUT_DIR / book_title
|
|
|
|
|
|
def ensure_dirs() -> None:
|
|
for d in (DATA_DIR, OUTPUT_DIR, VOICEBANK_DIR):
|
|
d.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
def setup_espeak() -> None:
|
|
"""Localise libespeak-ng pour phonemizer (requis par Kokoro non-anglais).
|
|
|
|
phonemizer ne trouve pas toujours la lib installee via brew ; on pointe
|
|
explicitement PHONEMIZER_ESPEAK_LIBRARY si la variable n'est pas deja fixee.
|
|
"""
|
|
if os.environ.get("PHONEMIZER_ESPEAK_LIBRARY"):
|
|
return
|
|
candidates = [
|
|
"/opt/homebrew/lib/libespeak-ng.dylib",
|
|
"/usr/local/lib/libespeak-ng.dylib",
|
|
"/opt/homebrew/lib/libespeak-ng.1.dylib",
|
|
]
|
|
for path in candidates:
|
|
if os.path.exists(path):
|
|
os.environ["PHONEMIZER_ESPEAK_LIBRARY"] = path
|
|
return
|