Reconstruction propre de l'ancien projet Dictée. Bundle id neuf (cloud.mrtechlab.zonza), chemin de build unique vers /Applications (plus jamais de builds /tmp enregistrés dans LaunchServices). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
47 lines
1.7 KiB
Python
47 lines
1.7 KiB
Python
"""Unités pures de Zonza — aucune dépendance matérielle.
|
||
|
||
Tout ce qui est ici est testable sans micro, sans clavier, sans modèle.
|
||
"""
|
||
|
||
import re
|
||
|
||
CONFIG = {
|
||
"model": "mlx-community/whisper-medium",
|
||
"language": "fr",
|
||
"hotkey": "<cmd>+<ctrl>+d", # Cmd+Ctrl+D (libre : ni macOS ni VS Code ne l'utilisent)
|
||
"sounds": True,
|
||
"min_duration_s": 0.3,
|
||
"max_duration_s": 120.0, # sécurité : arrêt auto après 2 min (fenêtre jamais figée)
|
||
"sample_rate": 16000,
|
||
"fps": 30,
|
||
"circle_base_radius": 20.0,
|
||
"circle_amplitude": 30.0,
|
||
"circle_color_rgb": (0.40, 0.50, 0.95),
|
||
"level_gain": 8.0, # amplification du niveau brut pour l'animation
|
||
"level_attack": 0.6, # lissage à la montée (0–1, proche de 1 = très réactif)
|
||
"level_release": 0.15, # lissage à la descente (plus petit = retombée douce)
|
||
"wave_rings": 3, # nombre d'anneaux d'onde concentriques
|
||
"wave_speed": 0.04, # vitesse de propagation des anneaux par frame
|
||
}
|
||
|
||
|
||
def validate_config(config):
|
||
"""Valide la config ; lève ValueError si une valeur est aberrante."""
|
||
if config["min_duration_s"] < 0:
|
||
raise ValueError("min_duration_s doit être >= 0")
|
||
if config["sample_rate"] <= 0:
|
||
raise ValueError("sample_rate doit être > 0")
|
||
if not config["hotkey"]:
|
||
raise ValueError("hotkey ne peut pas être vide")
|
||
|
||
|
||
def is_long_enough(num_samples, sample_rate, min_duration_s):
|
||
"""Renvoie True si l'enregistrement dépasse le seuil de durée minimal."""
|
||
duration_s = num_samples / sample_rate
|
||
return duration_s >= min_duration_s
|
||
|
||
|
||
def clean_transcript(text):
|
||
"""Nettoie le texte de Whisper : trim + espaces/retours multiples écrasés."""
|
||
return re.sub(r"\s+", " ", text).strip()
|