#!/usr/bin/env python3
"""Огибающая и 32 полосы спектра трека по кадрам 60 к/с -> web/music.js (для аудио-реактивных сцен).
  python3 tools/pm_music_env.py audio/music_C.mp3 --offset 0.05
offset: сколько секунд срезать в начале трека (сдвиг бочки на сетку ролика), тот же срез делает сведение.
"""
import json, sys
import numpy as np, librosa

src = sys.argv[1]
off = float(sys.argv[sys.argv.index("--offset") + 1]) if "--offset" in sys.argv else 0.0
y, sr = librosa.load(src, sr=22050, mono=True, offset=off)
hop = sr // 60
rms = librosa.feature.rms(y=y, frame_length=2048, hop_length=hop)[0]
S = np.abs(librosa.stft(y, n_fft=2048, hop_length=hop))
freqs = librosa.fft_frequencies(sr=sr, n_fft=2048)
edges = np.geomspace(40, 10000, 33)
bands = np.stack([S[(freqs >= edges[i]) & (freqs < edges[i + 1])].mean(axis=0) for i in range(32)])
bands = np.log1p(bands * 4)
bands = bands / (np.percentile(bands, 98, axis=1, keepdims=True) + 1e-9)
r = rms / (np.percentile(rms, 98) + 1e-9)
n = min(len(r), bands.shape[1])
out = {"fps": 60, "offset": off, "rms": [round(float(min(1.2, v)), 3) for v in r[:n]],
       "bands": [[round(float(min(1.2, v)), 2) for v in bands[:, i]] for i in range(n)]}
open("web/music.js", "w").write("window.MUSIC = " + json.dumps(out, separators=(",", ":")) + ";\n")
print("кадров", n, "размер", len(json.dumps(out)) // 1024, "КБ")
