"""Analüüsi SDR++ helisalvestust: tase, kahin vs signaal, kõne vs muusika.
Kasutus: python listen.py salvestus.wav [veel.wav ...]

Kalibreering (2026-09-18, väike teleskoopantenn toas):
  tühi sagedus  -> flatness ~0.45, dynamics ~1 dB   => "kahin"
  muusikajaam   -> flatness ~0.15, bass>0.5         => "muusika"
"""
import sys, wave
import numpy as np


def load(path):
    with wave.open(path, "rb") as w:
        rate, ch, n = w.getframerate(), w.getnchannels(), w.getnframes()
        data = np.frombuffer(w.readframes(n), dtype=np.int16).astype(np.float32) / 32768.0
    if ch > 1:
        data = data.reshape(-1, ch).mean(axis=1)
    return rate, data


def analyse(path):
    rate, x = load(path)
    dur = len(x) / rate
    rms = np.sqrt(np.mean(x ** 2))
    peak = np.abs(x).max()

    # 50 ms kaadrite valjus -> dünaamika ja pausid
    fl = int(rate * 0.05)
    frames = x[: len(x) // fl * fl].reshape(-1, fl)
    frms = np.sqrt(np.mean(frames ** 2, axis=1)) + 1e-9
    fdb = 20 * np.log10(frms)
    dyn = np.percentile(fdb, 95) - np.percentile(fdb, 10)
    pause_ratio = np.mean(fdb < np.percentile(fdb, 95) - 20)

    # spekter
    spec = np.abs(np.fft.rfft(x * np.hanning(len(x)))) ** 2
    freqs = np.fft.rfftfreq(len(x), 1 / rate)
    p = spec / spec.sum()
    centroid = (freqs * p).sum()
    band = lambda a, b: p[(freqs >= a) & (freqs < b)].sum()
    lo, mid, hi = band(0, 300), band(300, 3400), band(3400, 15000)
    # spektraalne lamedus 300-8000 Hz: ~1 = valge müra, ~0 = tonaalne
    m = (freqs >= 300) & (freqs < 8000)
    flat = np.exp(np.mean(np.log(spec[m] + 1e-12))) / (np.mean(spec[m]) + 1e-12)

    if rms < 0.005:
        verdict = "vaikus / heli puudub"
    elif flat > 0.3 and dyn < 6:
        verdict = "kahin (mürarohke, jaama pole)"
    elif dyn > 18 and pause_ratio > 0.15 and mid > 0.6:
        verdict = "tõenäoliselt kõne"
    elif dyn < 14 and lo > 0.25:
        verdict = "tõenäoliselt muusika"
    else:
        verdict = "signaal on, kõne/muusika ebaselge"

    print(f"file: {path}")
    print(f"kestus {dur:.1f}s  rate {rate}  RMS {20*np.log10(rms+1e-9):.1f} dBFS  peak {20*np.log10(peak+1e-9):.1f} dBFS")
    print(f"dynamics(95-10pct) {dyn:.1f} dB  pause_ratio {pause_ratio:.2f}  flatness {flat:.3f}")
    print(f"centroid {centroid:.0f} Hz  bass<300 {lo:.2f}  voice300-3400 {mid:.2f}  hi>3400 {hi:.2f}")
    print(f"VERDICT: {verdict}")


if __name__ == "__main__":
    for f in sys.argv[1:]:
        analyse(f)
