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.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# 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 this** — `flutter_audio_output` is unmaintained, `audio_session` lacks device identity
|
||||
|
||||
## Recommended Approach
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user