# -*- coding: utf-8 -*-
"""Ejemplo 20: Filtros BiQuad (9 tipos de filtro)."""

import sys
import time
import ctypes
from basskit.dlls.bass import bass
from basskit.dlls.bass_fx import bass_fx
from basskit.constantes.bass import BASS_UNICODE, BASS_STREAM_DECODE, BASS_SAMPLE_FLOAT
from basskit.constantes.bass_fx import (
	BASS_FX_FREESOURCE, BASS_FX_BFX_BQF,
	BASS_BFX_BQF_LOWPASS, BASS_BFX_BQF_HIGHPASS, BASS_BFX_BQF_BANDPASS,
	BASS_BFX_BQF_NOTCH, BASS_BFX_BQF_ALLPASS, BASS_BFX_BQF_PEAKINGEQ,
	BASS_BFX_BQF_LOWSHELF, BASS_BFX_BQF_HIGHSHELF,
)
from basskit.estructuras.addons import BASS_BFX_BQF

FILTROS = [
	(BASS_BFX_BQF_LOWPASS, "Lowpass 2kHz", 2000, 0),
	(BASS_BFX_BQF_HIGHPASS, "Highpass 500Hz", 500, 0),
	(BASS_BFX_BQF_BANDPASS, "Bandpass 1kHz", 1000, 0),
	(BASS_BFX_BQF_NOTCH, "Notch 1kHz", 1000, 0),
	(BASS_BFX_BQF_ALLPASS, "Allpass 1kHz", 1000, 0),
	(BASS_BFX_BQF_PEAKINGEQ, "PeakingEQ 1kHz +10dB", 1000, 10),
	(BASS_BFX_BQF_LOWSHELF, "LowShelf 300Hz +8dB", 300, 8),
	(BASS_BFX_BQF_HIGHSHELF, "HighShelf 4kHz +8dB", 4000, 8),
]


def main():
	print("=== Filtros BiQuad (8 tipos) ===\n")
	if len(sys.argv) < 2:
		print("Uso: python 20_filtros_biquad.py <archivo_audio>")
		return

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

	bass.BASS_ChannelPlay(stream, 0)
	print(f"Reproduciendo: {sys.argv[1]}\n")

	print("[0] Sin filtro - 3 seg")
	time.sleep(3)

	for i, (tipo, nombre, freq, gain) in enumerate(FILTROS, 1):
		fx = bass.BASS_ChannelSetFX(stream, BASS_FX_BFX_BQF, 0)
		if fx:
			p = BASS_BFX_BQF()
			p.lFilter = tipo
			p.fCenter = float(freq)
			p.fGain = float(gain)
			p.fBandwidth = 2.5
			p.fQ = 0
			p.fS = 0
			p.lChannel = -1
			bass.BASS_FXSetParameters(fx, ctypes.byref(p))
			print(f"[{i}/{len(FILTROS)}] {nombre} - 3 seg")
			time.sleep(3)
			bass.BASS_ChannelRemoveFX(stream, fx)
		else:
			print(f"[{i}/{len(FILTROS)}] {nombre} - error")

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


if __name__ == "__main__":
	main()
