Files
pluriwave/openspec/changes/multi-device-eq/explore.md
T
FreeTLab bccc5c48b8
Build & Deploy PluriWave / Análisis de código (push) Successful in 38s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m30s
docs(openspec): add SDD artifact trail for recent alarm and EQ changes
Persist the exploration, proposal, spec, design, tasks, and
verify/archive reports produced during the multi-device EQ,
alarm-countdown, and notification-visual-polish SDD cycles.
2026-07-04 12:42:11 +02:00

2.6 KiB
Raw Blame History

Exploration: Multi-Device Equalizer

Current State

  • Per-station EQ exists: Map<String, PresetEcualizador> in SharedPreferences keyed by station UUID
  • No device detection or per-device EQ
  • EQ is Android-only via just_audio's AndroidEqualizer
  • 3 existing platform channels in MainActivity.kt (visualizer, alarm, file_actions)
  • ServicioAudioSession handles interruptions/becoming-noisy only — no device identity

Key Findings

  1. EQ must be swapped in software on device change — no native per-device EQ hook exists
  2. BT MAC available via AudioManager.getDevices()AudioDeviceInfo.getAddress() (API 23+). Does NOT require BLUETOOTH_CONNECT permission
  3. _recrearPlayer() resets AndroidEqualizer on every source change — re-application must use device+station resolved preset
  4. iOS EQ is a no-op but device tracking via AVAudioSession.currentRoute is possible
  5. No Flutter package covers thisflutter_audio_output is unmaintained, audio_session lacks device identity

Custom platform channel pluriwave/audio_devices (Approach A):

  • Android: AudioManager.getDevices() + AudioDeviceCallback
  • iOS: AVAudioSession.currentRoute + routeChangeNotification
  • Dart bridge: ServicioDispositivoAudio with Stream<DispositivoAudio> and Future<List<DispositivoAudio>>

Resolution Hierarchy

1. presetsMatriz["stationUuid:deviceId"]   ← station × device (most specific)
2. presetsEmisoraMap[stationUuid]           ← station-only (existing)
3. presetsDispositivo[deviceId]             ← device-only
4. presetPrincipal                          ← global default (existing)

Persistence

New SharedPreferences keys (additive):

  • eq_multi_device_enabled_v1 → bool
  • eq_preset_por_dispositivo_v1 → JSON Map<deviceId, preset>
  • eq_presets_matriz_v1 → JSON Map<"stationUuid:deviceId", preset>

Affected Files

Area Files
Model NEW dispositivo_audio.dart
Service NEW servicio_dispositivo_audio.dart, extend servicio_ecualizador.dart, extend servicio_audio.dart, extend servicio_export_import.dart
State Extend estado_ecualizador.dart
Native Extend MainActivity.kt, NEW AudioDevicesPlugin.swift
UI Extend pantalla_ajustes.dart
Tests Extend existing + new test files

Risks

  • Android minSdk must be ≥ 23 (likely already gated by AndroidEqualizer)
  • iOS uid instability: use portType+portName as fallback key
  • Backup v3 import must degrade gracefully in v2 builds
  • Feature toggle OFF = zero regression invariant