|
|
|
|
@ -72,7 +72,12 @@ internal class CallAudioOutput private constructor(
|
|
|
|
|
|
|
|
|
|
companion object { |
|
|
|
|
fun open(manager: AudioManager, deviceId: Int, tryFast: Boolean): CallAudioOutput { |
|
|
|
|
if (tryFast && Build.VERSION.SDK_INT >= 31) { |
|
|
|
|
val type = if (Build.VERSION.SDK_INT >= 31) |
|
|
|
|
manager.availableCommunicationDevices.firstOrNull { it.id == deviceId }?.type else null |
|
|
|
|
// Samsung MMAP подтверждает wired headset в HAL, но звук остаётся в speaker. |
|
|
|
|
// Быстрый backend включаем только для проверенного физического выхода; гарнитуры ведёт AudioTrack. |
|
|
|
|
val fastRoute = type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER |
|
|
|
|
if (tryFast && fastRoute && Build.VERSION.SDK_INT >= 31) { |
|
|
|
|
val handle = CallOutputNative.open(deviceId) |
|
|
|
|
if (handle != 0L) return CallAudioOutput(null, handle, manager).also { CallOutputNative.sample(handle, it.sample) } |
|
|
|
|
} |
|
|
|
|
@ -86,7 +91,7 @@ internal class CallAudioOutput private constructor(
|
|
|
|
|
.setBufferSizeInBytes((min * 2).coerceAtLeast(3840)).setTransferMode(AudioTrack.MODE_STREAM) |
|
|
|
|
.setPerformanceMode(AudioTrack.PERFORMANCE_MODE_LOW_LATENCY).build() |
|
|
|
|
if (track.state != AudioTrack.STATE_INITIALIZED) { track.release(); error("AudioTrack not initialized") } |
|
|
|
|
LogManager.addLog("INFO", "CallAudio", "output fallback=AudioTrack device=$deviceId tryFast=$tryFast") |
|
|
|
|
LogManager.addLog("INFO", "CallAudio", "output fallback=AudioTrack device=$deviceId type=$type tryFast=$tryFast fastRoute=$fastRoute") |
|
|
|
|
return CallAudioOutput(track, 0, manager) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|