fix(eq): re-apply the equalizer after an audio-focus interruption
The equalizer stopped applying after another app interrupted audio (e.g. a navigation app's voice prompt): play a station with EQ working, let the prompt speak, resume -- the audio sounds flat until the station is re-tapped. debeReaplicarEcualizador only re-attaches the equalizer when the native player session id actually changes. A short transient interruption keeps the SAME session (no id rotation), so that trigger never fires, while Android's AudioEffect framework can let a higher-priority client silently disable this app's effect instance in the meantime. Add reaplicarEcualizador() to ObjetivoAudioInterrumpible, implemented as a thin delegate to the existing _activarEcualizador() (already the correct idempotent setEnabled + re-push-gains path). ServicioAudioSession calls it on resume-from-pause (after reanudar()) and on un-duck (after setAtenuado(false)) -- additive to the existing session-id trigger, not a replacement. The method takes no argument, so it can only re-assert whatever enabled/disabled state the handler already holds -- an interruption cycle with the equalizer OFF stays OFF.
This commit is contained in:
@@ -1006,6 +1006,16 @@ class PluriWaveAudioHandler extends BaseAudioHandler
|
||||
await _player.setVolume(_volumenEfectivo);
|
||||
}
|
||||
|
||||
/// Fix "EQ Re-Apply After Audio-Focus Interruption": thin delegate to the
|
||||
/// existing [_activarEcualizador] (already does the correct idempotent
|
||||
/// `setEnabled` + re-push-gains work, already re-asserts the CURRENT
|
||||
/// [_ecualizadorActivo] rather than forcing it on). Called by
|
||||
/// [ServicioAudioSession] on resume-from-pause and on un-duck — see that
|
||||
/// interface member's doc for why the existing session-id-change trigger
|
||||
/// misses this case.
|
||||
@override
|
||||
Future<void> reaplicarEcualizador() => _activarEcualizador();
|
||||
|
||||
@override
|
||||
Future<void> play() {
|
||||
_intencionReproducir = true;
|
||||
|
||||
@@ -20,6 +20,20 @@ abstract class ObjetivoAudioInterrumpible {
|
||||
|
||||
/// Temporarily lowers ("ducks") the output volume without pausing.
|
||||
Future<void> setAtenuado(bool atenuado);
|
||||
|
||||
/// Re-attaches the equalizer effect and re-pushes the current preset's
|
||||
/// gains (fix "EQ Re-Apply After Audio-Focus Interruption"). Called after
|
||||
/// resuming from a transient interruption pause and after un-ducking,
|
||||
/// because Android's AudioEffect framework can let a higher-priority
|
||||
/// client silently disable this app's effect instance while the
|
||||
/// underlying player session id never changes — the existing session-id
|
||||
/// rotation trigger (`ServicioAudio.debeReaplicarEcualizador`) therefore
|
||||
/// never fires for a SHORT interruption (e.g. a nav-app voice prompt).
|
||||
/// Idempotent and cheap (a `setEnabled` plus band `setGain` calls); takes
|
||||
/// no argument by design — it re-asserts whatever enabled/disabled state
|
||||
/// the handler ALREADY holds, so a caller here can never force the
|
||||
/// equalizer on. Never restarts or repositions playback.
|
||||
Future<void> reaplicarEcualizador();
|
||||
}
|
||||
|
||||
/// Wrapper around `package:audio_session` (S3-R1): configures the session
|
||||
@@ -84,11 +98,18 @@ class ServicioAudioSession {
|
||||
switch (evento.type) {
|
||||
case AudioInterruptionType.duck:
|
||||
await _objetivo.setAtenuado(false);
|
||||
// Un-ducking never rotates the native player session id, so the
|
||||
// session-id-change trigger never fires for this case — re-assert
|
||||
// here too (belt-and-braces, additive to that trigger).
|
||||
await _objetivo.reaplicarEcualizador();
|
||||
case AudioInterruptionType.pause:
|
||||
// Transient loss ended and the OS says we may resume.
|
||||
if (_pausadoPorInterrupcion) {
|
||||
_pausadoPorInterrupcion = false;
|
||||
await _objetivo.reanudar();
|
||||
// Same rationale as the duck branch above: a short transient
|
||||
// interruption keeps the SAME player session id.
|
||||
await _objetivo.reaplicarEcualizador();
|
||||
}
|
||||
case AudioInterruptionType.unknown:
|
||||
// Permanent focus loss: never auto-resume.
|
||||
|
||||
Reference in New Issue
Block a user