#!/usr/bin/env python3
"""Classifica trechos de um arquivo de áudio em FALA vs MÚSICA (determinístico, sem LLM).
Lição cara (Nathália, jun/2026): nunca confiar só em nome/timestamp pra achar o gravador de
VOZ da cerimônia — sempre VERIFICAR o conteúdo. Achado: bass/speech ratio + periodicidade do
envelope distingue bem (fala = grave baixo + sem ritmo forte; música = grave alto + periódico).
READ-ONLY (lê só, amostra com ffmpeg -ss/-t).
Uso: classify_audio_content.py <arquivo.WAV> [--every 600] [--win 12]
Saída: lista de (t0, tag, bass/speech, periodicidade) — usar pra achar ONDE no arquivo tem FALA.
"""
import sys, subprocess, argparse, warnings
import numpy as np
warnings.filterwarnings("ignore")
from scipy.io import wavfile
from scipy.signal import stft


def classify_window(path, t0, win):
    subprocess.run(["ffmpeg", "-y", "-ss", str(t0), "-t", str(win), "-i", path,
                    "-ac", "1", "-ar", "22050", "/tmp/_clf_samp.wav"], capture_output=True)
    try:
        sr, x = wavfile.read("/tmp/_clf_samp.wav")
    except Exception:
        return None
    x = x.astype(np.float64)
    if len(x) < sr:
        return None
    _, _, Z = stft(x, fs=sr, nperseg=2048)
    mag = np.abs(Z)
    freqs = np.fft.rfftfreq(2048, 1 / sr)
    speech = mag[(freqs > 300) & (freqs < 3400)].mean()
    bass = mag[(freqs > 50) & (freqs < 150)].mean()
    ratio = bass / (speech or 1e-9)
    env = mag.mean(0)
    ac = np.correlate(env - env.mean(), env - env.mean(), mode="full")[len(env) - 1:]
    ac = ac / (ac[0] or 1)
    period = ac[5:40].max() if len(ac) > 40 else 0.0
    tag = "MUSICA" if ratio > 2 and period > 0.3 else ("FALA" if ratio < 1.5 else "?")
    return tag, ratio, period


def ffdur(path):
    r = subprocess.run(["ffprobe", "-v", "error", "-show_entries", "format=duration",
                        "-of", "csv=p=0", path], capture_output=True, text=True)
    try:
        return float(r.stdout.strip())
    except ValueError:
        return 0.0


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("audio")
    ap.add_argument("--every", type=int, default=600, help="amostra a cada N segundos")
    ap.add_argument("--win", type=int, default=12, help="janela de cada amostra (s)")
    a = ap.parse_args()
    dur = ffdur(a.audio)
    print(f"{a.audio} ({dur/60:.0f}min)")
    fala = []
    for t0 in range(30, max(31, int(dur) - a.win), a.every):
        r = classify_window(a.audio, t0, a.win)
        if not r:
            continue
        tag, ratio, period = r
        print(f"  t={t0:5d}s ({t0/60:4.0f}min)  bass/speech={ratio:.1f}  periodicidade={period:.2f}  -> {tag}")
        if tag == "FALA":
            fala.append(t0)
    if fala:
        print(f"\nFALA encontrada em: {fala[0]/60:.0f}min - {fala[-1]/60:.0f}min "
              f"(usar esse trecho pra fingerprint vs espinha)")
    else:
        print("\nNenhuma FALA clara encontrada — provavelmente não é o gravador de voz.")


if __name__ == "__main__":
    main()
