diff --git a/app/src/main/java/dev/kaizen/app/live/AudioPipeline.kt b/app/src/main/java/dev/kaizen/app/live/AudioPipeline.kt index a43cf48..3db3c13 100644 --- a/app/src/main/java/dev/kaizen/app/live/AudioPipeline.kt +++ b/app/src/main/java/dev/kaizen/app/live/AudioPipeline.kt @@ -62,6 +62,35 @@ class AudioPipeline(private val context: Context) { @Volatile private var ducking = false @Volatile private var capturing = false + // ─── Audio Mode ─────────────────────────────────────────────────────── + + fun enterCallMode() { + previousAudioMode = audioManager.mode + audioManager.mode = AudioManager.MODE_IN_COMMUNICATION + + if (android.os.Build.VERSION.SDK_INT >= 31) { + val speaker = audioManager.availableCommunicationDevices + .firstOrNull { it.type == android.media.AudioDeviceInfo.TYPE_BUILTIN_SPEAKER } + if (speaker != null) { + audioManager.setCommunicationDevice(speaker) + Log.i(TAG, "Communication device → speaker") + } + } else { + @Suppress("DEPRECATION") + audioManager.isSpeakerphoneOn = true + } + } + + fun exitCallMode() { + if (android.os.Build.VERSION.SDK_INT >= 31) { + audioManager.clearCommunicationDevice() + } else { + @Suppress("DEPRECATION") + audioManager.isSpeakerphoneOn = false + } + audioManager.mode = previousAudioMode + } + // ─── Capture ────────────────────────────────────────────────────────── fun startCapture(scope: CoroutineScope): Boolean { @@ -92,11 +121,6 @@ class AudioPipeline(private val context: Context) { recorder = rec - previousAudioMode = audioManager.mode - audioManager.mode = AudioManager.MODE_IN_COMMUNICATION - @Suppress("DEPRECATION") - audioManager.isSpeakerphoneOn = true - if (AcousticEchoCanceler.isAvailable()) { try { aec = AcousticEchoCanceler.create(rec.audioSessionId) @@ -147,7 +171,6 @@ class AudioPipeline(private val context: Context) { aec = null recorder?.release() recorder = null - audioManager.mode = previousAudioMode } // ─── Playback ───────────────────────────────────────────────────────── @@ -220,6 +243,7 @@ class AudioPipeline(private val context: Context) { fun release() { stopCapture() stopPlayback() + exitCallMode() } // ─── Helpers ────────────────────────────────────────────────────────── diff --git a/app/src/main/java/dev/kaizen/app/live/LiveCallService.kt b/app/src/main/java/dev/kaizen/app/live/LiveCallService.kt index 0af13da..c2651b9 100644 --- a/app/src/main/java/dev/kaizen/app/live/LiveCallService.kt +++ b/app/src/main/java/dev/kaizen/app/live/LiveCallService.kt @@ -168,6 +168,7 @@ class LiveCallService : Service() { connectTimeoutJob?.cancel() _status.value = CallStatus.LISTENING + pipeline.enterCallMode() if (!pipeline.initPlayback()) { Log.e(TAG, "Playback init failed") }