09a1c98514
- pocket_server.py (Produktions-TTS mit Stimmen-Waechter), text_norm, Bench-/Diag-Skripte - lucy-f5: f5_server/f5_test/bench_dml (DirectML-Experiment, Phase C/D offen) - .gitignore: venvs/Modelle/Audio/Logs der beiden Ordner + box_recon/gemma_swap-Scratch Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
45 lines
1.9 KiB
Python
45 lines
1.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Verifiziert die 'Stimme wurde männlich'-Hypothese: misst F0 (Grundfrequenz) vieler Generierungen
|
|
bei temp 0.9 vs 0.7. Weiblich (Saber-Klon) ~180-240Hz, männlich-Drift (Default 'juergen') ~100-140Hz.
|
|
Sucht Ausreißer = Stimm-Identitäts-Kollaps."""
|
|
import os, numpy as np, librosa, soundfile as sf
|
|
from pocket_tts import TTSModel
|
|
|
|
BASE = r"F:\Coding Stuff\mission-control-2\client\lucy-tts"
|
|
src,_ = librosa.load(os.path.join(BASE,"ref.mp3"), sr=24000, mono=True)
|
|
srt,_ = librosa.effects.trim(src, top_db=30); ref=os.path.join(BASE,"ref.wav")
|
|
sf.write(ref, srt[:int(18*24000)], 24000)
|
|
LEAD="Tja. "
|
|
TEXTS = [
|
|
"Hallo Commander, ich höre dich.",
|
|
"Natürlich, Commander, das mache ich sofort.",
|
|
"Die Hitze in Hamburg ist heute wirklich heftig.",
|
|
"Klar, ich kümmere mich gleich darum für dich.",
|
|
"Guten Morgen, Commander, alles läuft sauber.",
|
|
"Das Backup ist durchgelaufen, keine Fehler.",
|
|
]
|
|
|
|
def median_f0(a, sr):
|
|
f0,_,_ = librosa.pyin(a, fmin=80, fmax=400, sr=sr, frame_length=1024)
|
|
v = f0[~np.isnan(f0)]
|
|
return float(np.median(v)) if v.size else float("nan")
|
|
|
|
def run(temp):
|
|
m = TTSModel.load_model(language="german_24l", lsd_decode_steps=6, temp=temp)
|
|
vs = m.get_state_for_audio_prompt(ref); sr=m.sample_rate
|
|
print(f"=== temp={temp} ===", flush=True)
|
|
f0s=[]
|
|
for i,t in enumerate(TEXTS):
|
|
a = m.generate_audio(vs, LEAD+t, frames_after_eos=4)
|
|
a = a.numpy() if hasattr(a,"numpy") else np.asarray(a)
|
|
a = np.asarray(a,dtype=np.float32).reshape(-1)
|
|
f0 = median_f0(a, sr); f0s.append(f0)
|
|
flag = " <<< MÄNNLICH?" if (f0==f0 and f0<150) else ""
|
|
print(f" [{i}] F0={f0:6.1f}Hz{flag} ({t[:30]})", flush=True)
|
|
arr=np.array([x for x in f0s if x==x])
|
|
print(f" -> median {np.median(arr):.0f}Hz, min {arr.min():.0f}, max {arr.max():.0f}", flush=True)
|
|
|
|
run(0.9)
|
|
run(0.7)
|
|
print("F0_DONE")
|