# -*- coding: utf-8 -*-
"""Ejemplo 23: Medicion de loudness EBU R128 (BASSloud)."""

import sys
import time
import ctypes
from basskit.dlls.bass import bass
from basskit.dlls.addons import bassloud
from basskit.constantes.bass import BASS_UNICODE, BASS_SAMPLE_FLOAT
from basskit.constantes.addons import (
	BASS_LOUDNESS_CURRENT, BASS_LOUDNESS_INTEGRATED,
	BASS_LOUDNESS_RANGE, BASS_LOUDNESS_TRUEPEAK,
)


def main():
	print("=== Medicion de Loudness EBU R128 ===\n")
	if len(sys.argv) < 2:
		print("Uso: python 23_loudness.py <archivo_audio>")
		return

	v = bassloud.BASS_Loudness_GetVersion()
	print(f"BASSloud version: {(v>>24)&0xFF}.{(v>>16)&0xFF}.{(v>>8)&0xFF}.{v&0xFF}")

	bass.BASS_Init(-1, 44100, 0, 0, None)
	ruta = sys.argv[1].encode("utf-16-le") + b"\x00\x00"
	stream = bass.BASS_StreamCreateFile(0, ruta, 0, 0, BASS_UNICODE | BASS_SAMPLE_FLOAT)
	if stream == 0:
		print(f"Error: {bass.BASS_ErrorGetCode()}")
		bass.BASS_Free()
		return

	# Iniciar medicion con todos los modos
	flags = BASS_LOUDNESS_CURRENT | BASS_LOUDNESS_INTEGRATED | BASS_LOUDNESS_RANGE | BASS_LOUDNESS_TRUEPEAK
	loud = bassloud.BASS_Loudness_Start(stream, flags, 0)
	if loud == 0:
		print(f"Error loudness: {bass.BASS_ErrorGetCode()}")
		bass.BASS_Free()
		return

	bass.BASS_ChannelPlay(stream, 0)
	print(f"\nAnalizando: {sys.argv[1]}")
	print("Presiona Ctrl+C para detener.\n")
	print(f"{'Momentaneo':>12} {'Integrada':>12} {'Rango':>12} {'True Peak':>12}")
	print("-" * 52)

	try:
		while bass.BASS_ChannelIsActive(stream) == 1:
			val = ctypes.c_float()

			bassloud.BASS_Loudness_GetLevel(loud, BASS_LOUDNESS_CURRENT, ctypes.byref(val))
			mom = val.value

			bassloud.BASS_Loudness_GetLevel(loud, BASS_LOUDNESS_INTEGRATED, ctypes.byref(val))
			integ = val.value

			bassloud.BASS_Loudness_GetLevel(loud, BASS_LOUDNESS_RANGE, ctypes.byref(val))
			rango = val.value

			bassloud.BASS_Loudness_GetLevel(loud, BASS_LOUDNESS_TRUEPEAK, ctypes.byref(val))
			peak = val.value

			print(f"\r{mom:>10.1f} dB {integ:>10.1f} dB {rango:>10.1f} LU {peak:>10.1f} dB", end="", flush=True)
			time.sleep(0.3)
	except KeyboardInterrupt:
		pass

	# Resultado final
	val = ctypes.c_float()
	bassloud.BASS_Loudness_GetLevel(loud, BASS_LOUDNESS_INTEGRATED, ctypes.byref(val))
	print(f"\n\n=== Resultado Final ===")
	print(f"  Loudness Integrada: {val.value:.1f} LUFS")

	bassloud.BASS_Loudness_GetLevel(loud, BASS_LOUDNESS_RANGE, ctypes.byref(val))
	print(f"  Rango de Loudness:  {val.value:.1f} LU")

	bassloud.BASS_Loudness_GetLevel(loud, BASS_LOUDNESS_TRUEPEAK, ctypes.byref(val))
	print(f"  True Peak:          {val.value:.1f} dBFS")

	bassloud.BASS_Loudness_Stop(loud)
	bass.BASS_StreamFree(stream)
	bass.BASS_Free()
	print("\nFin del ejemplo.")


if __name__ == "__main__":
	main()
