fix(ios): output muted with A2DP, session lifecycle, mic input issues
Three bugs causing no audio output and no mic input:
1. .voiceChat mode + A2DP = output muted. The .voiceChat mode uses hardware
AEC/AGC/HPF but requires HFP-compatible routes. A2DP is NOT HFP — iOS
mutes the output because it can't set up the voice processing pipeline on
an A2DP route. Fix: use .default mode for Standard+A2DP (no hardware AEC,
but audio routes correctly). .voiceChat kept for HFP and speaker modes.
Added info warning in Settings UI for A2DP no-AEC.
2. Session lifecycle broken. stopMicStream() called deactivateAfterStreaming()
which deactivated the AVAudioSession — but the AudioEngine keeps running for
remote audio playback, so leaving voice killed all remote audio. And the
session was never activated when a remote user started talking (only on
Join Voice), so you couldn't hear anyone before joining voice. Fix:
- ensureSessionActive() replaces activateForStreaming() — idempotent, called
on Join Voice AND on .streamStarted (remote user starts talking).
- stopMicStream() no longer deactivates the session.
- deactivateSession() called only on disconnect from server.
- isSessionActive flag tracks state, updated by interruption handler.
3. setPreferredInputNumberOfChannels(1) called for mono — unnecessary (1 is
the default) and may put the session in a bad state on some devices. Fix:
only call it when stereo is explicitly selected. Also handle empty input
port ID (selecting 'Default' in the picker) correctly.
Added comprehensive route logging — after activation, logs the current output
and input route names so issues can be diagnosed from Console.app.
This commit is contained in:
@@ -89,7 +89,9 @@ final class AppState {
|
||||
}
|
||||
|
||||
func disconnect() {
|
||||
session?.stopMicStream()
|
||||
session?.client.disconnect()
|
||||
AudioSessionManager.shared.deactivateSession()
|
||||
session = nil
|
||||
connectingClient?.disconnect()
|
||||
connectingClient = nil
|
||||
@@ -163,7 +165,10 @@ final class AppState {
|
||||
}
|
||||
case .disconnected:
|
||||
if session == nil { cancelConnect() }
|
||||
else { session = nil; isConnecting = false }
|
||||
else {
|
||||
AudioSessionManager.shared.deactivateSession()
|
||||
session = nil; isConnecting = false
|
||||
}
|
||||
case .error:
|
||||
connectStatus = ev.text ?? "Unknown error"
|
||||
if session == nil { isConnecting = false }
|
||||
|
||||
Reference in New Issue
Block a user