# -*- coding: utf-8 -*- """Naturalness-Sweep gegen 'Roboter/abgehackt': temperature, lsd hoch, + 2 Referenz-Fenster. Wörter sind laut Whisper alle da -> Problem ist Prosodie/Timbre, nicht Content.""" import os, time, numpy as np, soundfile as sf, librosa from pocket_tts import TTSModel BASE = r"F:\Coding Stuff\mission-control-2\client\lucy-tts" OUT = r"C:\Users\TobisPC\Desktop\lucy_natural"; os.makedirs(OUT, exist_ok=True) # Zwei Referenz-Fenster aus der EL-Saber-MP3 src, _ = librosa.load(os.path.join(BASE, "ref.mp3"), sr=24000, mono=True) srt, _ = librosa.effects.trim(src, top_db=30) ref18 = os.path.join(BASE, "ref.wav") # aktuell: erste 18s sf.write(ref18, srt[:int(18*24000)], 24000) refC = os.path.join(BASE, "ref_C.wav") # XTTS-Liebling: Sek 18..27 (9s) segC = src[int(18*24000):int(27*24000)] segCt, _ = librosa.effects.trim(segC, top_db=30) sf.write(refC, segCt, 24000) SENT = { "kurz": "Hallo Commander, ich höre dich.", "mittel":"Guten Morgen, Commander. Das Backup ist sauber durchgelaufen und es gab keine Fehler.", } def cleanup_v2(a, sr): a = np.asarray(a, dtype=np.float32).reshape(-1) if a.size == 0: return a peak = float(np.max(np.abs(a))) if peak > 0: a = a * (0.95 / peak) yt, _ = librosa.effects.trim(a, top_db=45); a = yt if yt.size else a fi = min(int(0.01*sr), a.size//2) if fi > 0: a[:fi] *= np.linspace(0.,1.,fi,dtype=np.float32) a[-fi:] *= np.linspace(1.,0.,fi,dtype=np.float32) pad = np.zeros(int(0.09*sr), dtype=np.float32) return np.concatenate([pad, a, pad]) # (tag, lsd, temp, ref) COMBOS = [ ("A_lsd6_t070_ref18", 6, 0.70, ref18), ("B_lsd6_t090_ref18", 6, 0.90, ref18), ("C_lsd6_t105_ref18", 6, 1.05, ref18), ("D_lsd8_t090_ref18", 8, 0.90, ref18), ("E_lsd12_t090_ref18",12, 0.90, ref18), ("F_lsd6_t090_refC", 6, 0.90, refC), ] for tag, lsd, temp, ref in COMBOS: t0 = time.time() m = TTSModel.load_model(language="german_24l", lsd_decode_steps=lsd, temp=temp) vs = m.get_state_for_audio_prompt(ref) sr = m.sample_rate print(f"== {tag} (load {time.time()-t0:.1f}s) ==", flush=True) for name, text in SENT.items(): t0 = time.time() audio = m.generate_audio(vs, text, frames_after_eos=4); dt = time.time()-t0 a = audio.numpy() if hasattr(audio,"numpy") else np.asarray(audio) a = cleanup_v2(a, sr); secs = a.size/sr sf.write(os.path.join(OUT, f"{tag}_{name}.wav"), a, sr) print(f" [{name:6}] gen={dt:5.2f}s audio={secs:5.2f}s RTF={dt/max(secs,0.01):.2f}", flush=True) print("NATURAL_DONE", flush=True)