FreeTLab b1bf289e0d
Build & Deploy PluriWave / Análisis de código (push) Successful in 29s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m56s
fix(eq): entregar los decibelios que pide el usuario, sin estirarlos
La app promete decibelios en cuatro sitios y no los entregaba en ninguno. El
slider abarca un +/-12 fijo, escribe el numero con su unidad debajo de cada
banda, y `equalizerBandValue` le dice literalmente "decibelios" a TalkBack. El
modelo documenta las bandas como dB y los presets de fabrica estan escritos en
dB. just_audio documenta `setGain` en decibelios y multiplica por 1000 para
llegar a milibelios sin normalizar nada: `minDecibels`/`maxDecibels` son la
CAPACIDAD del dispositivo, no una escala a la que normalizar.

Pese a eso, la ganancia se estiraba por `maxDecibels/12`. Un +6 dB llegaba como
+10 en un movil de rango ancho.

El estiramiento nunca fue una decision de diseño

Antes de a9202c6 el codigo era `setGain(preset.bandas[i])`, decibelios
literales. Ese commit metio la normalizacion sin docstring, sin test y sin nota
de diseño, y traia un fallo: 0 dB caia en el punto medio del rango, asi que un
preset PLANO realzaba. 3449e2c corrigio exactamente eso y nada mas -- su propio
mensaje dice que el objetivo era "0 dB es siempre 0" -- heredando el
estiramiento sin discutirlo. No hay ADR, spec ni comentario que lo justifique.

Lo que de verdad rompia: la portabilidad

Lo que se persiste y se exporta son los dB del usuario, sin escalar; el escalado
ocurre solo al escribir en el efecto nativo. Asi que el mismo backup suena
distinto en cada telefono, y la interfaz informa de una restauracion perfecta
mientras el audio no lo es. Peor con el rango asimetrico habitual de Android
([-12, +19]): los realces se multiplican por 1.58 y los cortes por 1.0, de modo
que el preset no solo sube de nivel, CAMBIA DE FORMA. Jazz [3, -1, -1.5, 2, 4]
se entregaba como [4.75, -1, -1.5, 3.17, 6.33]. Con presets por dispositivo, el
mismo preset se deformaba distinto en el altavoz y en el Bluetooth.

No es un clamp a secas

`db.clamp(minDecibels, maxDecibels)` habria reintroducido el fallo de 3449e2c:
en un dispositivo que reporte [+3, +19], el cero se convierte en +3 y el preset
plano vuelve a realzar. La ventana se fuerza a contener el cero, asi que se
conservan todas las invariantes ganadas -- 0 siempre es 0, el signo nunca se
invierte, el resultado nunca escapa del rango nativo, un dispositivo sin margen
en un lado no puede realzar por ese lado -- y solo desaparece el estiramiento.

Que se oye distinto: en un movil de +/-12 dB, identico a hoy. En uno de rango
ancho los realces bajan, hasta un 40% menos en dB en uno de +/-20. Los cortes
apenas se mueven, porque la forma habitual es [-12, +N] y el lado negativo ya
iba practicamente 1:1. A cambio, los seis presets de fabrica suenan por fin
igual en cualquier telefono.

Ningun preset guardado necesita migracion: lo almacenado siempre fueron los dB
del usuario.

Suite completa: 1534 pasan, 2 omitidos. flutter analyze mantiene los 5 avisos
preexistentes.
2026-09-06 00:08:09 +02:00

PluriWave

Radio mundial con ecualizador personalizable, reconocimiento de canciones y UI premium.

Features

  • +53.000 emisoras de 238 países (Radio Browser API)
  • Ecualizador por emisora — guarda tu preset favorito para cada radio
  • Reconocimiento de canciones — "¿Qué suena?" sin salir de la app
  • Timer de auto-apagado — perfecto para dormir
  • Reproducción en segundo plano — sigue sonando con la pantalla apagada
  • Favoritos — acceso rápido a emisoras preferidas
  • Compartir — envía emisoras a tus amigos
  • UI premium — Material You, visualizador de audio, animaciones fluidas

Monetización

  • 14 días PRO gratis al instalar
  • Free: radio + favoritos + timer + background (con ads)
  • PRO €2.99/año: sin ads + ecualizador + reconocimiento ilimitado

Stack

  • Frontend: Flutter (Android + iOS)
  • Radio API: Radio Browser (gratis, +53K emisoras)
  • Audio: just_audio + audio_service
  • Ecualizador: just_audio equalizer (Android nativo)
  • Reconocimiento: AudD API (1000 req/mes free)
  • Ads: Google AdMob
  • Compras: in_app_purchase

CI/CD

Workflow Gitea Actions en .gitea/workflows/ci.yml, runner macmini-flutter.

Jobs: flutter pub getflutter testbuild apk --releasebuild appbundle --release

Artifacts: APK y AAB guardados en Gitea con nombre pluriwave-apk-<sha> / pluriwave-aab-<sha>.

Notificaciones: Telegram al completar (éxito / fallo ).

Secrets necesarios en el repo:

Secret Uso
TELEGRAM_BOT_TOKEN Notificaciones CI
TELEGRAM_CHAT_ID Canal de destino

Signing: build de release usa clave debug (válido para CI interno). Para Play Store se requiere keystore como secret adicional.

Desarrollador

FreeTimeLab — freetimelab.es

Licencia

MIT

S
Description
PluriWave — Radio mundial con ecualizador, reconocimiento de canciones y UI premium
Readme
49 MiB
Languages
Dart 86%
HTML 7.1%
Kotlin 5.1%
JavaScript 1.6%
Swift 0.1%