# Guia de Callbacks

## Concepto

Los callbacks son funciones Python que BASS llama en momentos especificos
(cuando necesita datos, cuando ocurre un evento, etc.). En basskit se
definen como tipos `ctypes.WINFUNCTYPE`.

## Regla critica: mantener referencias

**BASS almacena punteros a las funciones callback.** Si Python recolecta
la funcion con el garbage collector, BASS intentara llamar a un puntero
invalido y el programa se colgara.

```python
from basskit.callbacks.bass import STREAMPROC, mantener_callback

@STREAMPROC
def mi_callback(handle, buffer, length, user):
    # ... generar audio ...
    return length

# IMPORTANTE: mantener referencia
mantener_callback(mi_callback)
```

## Tipos de callback disponibles

### BASS core (callbacks/bass.py)
| Tipo | Uso |
|------|-----|
| STREAMPROC | Generar datos para un stream personalizado |
| DOWNLOADPROC | Recibir datos descargados de una URL |
| SYNCPROC | Notificacion de eventos de sincronizacion |
| DSPPROC | Procesar datos de audio (DSP) |
| RECORDPROC | Recibir datos de grabacion |
| FILECLOSEPROC | Cerrar archivo personalizado |
| FILELENPROC | Obtener longitud de archivo personalizado |
| FILEREADPROC | Leer datos de archivo personalizado |
| FILESEEKPROC | Buscar en archivo personalizado |

### Add-ons (callbacks/addons.py)
| Tipo | Uso |
|------|-----|
| BPMPROCESSPROC | Progreso de deteccion BPM |
| BPMPROC | BPM detectado |
| BPMBEATPROC | Beat detectado |
| ENCODEPROC | Datos del encoder |
| ENCODENOTIFYPROC | Notificacion del encoder |
| WASAPIPROC | Datos WASAPI |
| WASAPINOTIFYPROC | Notificacion de dispositivo WASAPI |
| CLIENTCONNECTPROC | Cliente WMA conectado/desconectado |
| MIDIINPROC | Datos MIDI de entrada |
| MIDIFILTERPROC | Filtrado de eventos MIDI |

## Ejemplo completo: DSP personalizado

```python
from basskit.dlls.bass import bass
from basskit.callbacks.bass import DSPPROC, mantener_callback
import ctypes

@DSPPROC
def efecto_volumen(handle, channel, buffer, length, user):
    # Reducir volumen al 50%
    datos = (ctypes.c_float * (length // 4)).from_address(buffer)
    for i in range(len(datos)):
        datos[i] *= 0.5

mantener_callback(efecto_volumen)

# Asignar al canal
dsp_handle = bass.BASS_ChannelSetDSP(canal, efecto_volumen, None, 0)
```

## Limpiar callbacks

```python
from basskit.callbacks.bass import limpiar_callbacks

# Al terminar (antes de BASS_Free)
limpiar_callbacks()
```
