diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/audio/AudioLink.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/audio/AudioLink.kt index 675ab79..51f73fc 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/audio/AudioLink.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/audio/AudioLink.kt @@ -233,7 +233,19 @@ class AudioLink( startStream() } + /** + * Guards starting and stopping. [start] starts the stream at once for head units that never + * answer the focus request, and the car's answer arrives on another thread and starts it + * too: without this both got through, so the car got Start twice and two AAC encoders, and a + * 2014 head unit dropped the connection on the first audio. + */ + private val startLock = Any() + private fun startStream() { + synchronized(startLock) { startStreamLocked() } + } + + private fun startStreamLocked() { if (!ready || started) return sendOnChannel( MSG_START, @@ -252,6 +264,10 @@ class AudioLink( } override fun stop() { + synchronized(startLock) { stopLocked() } + } + + private fun stopLocked() { if (!started) return started = false synchronized(ackLock) { ackLock.notifyAll() } diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/DirectionsVoice.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/DirectionsVoice.kt index 5e5960d..4aaeda0 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/DirectionsVoice.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/DirectionsVoice.kt @@ -87,16 +87,26 @@ object DirectionsVoice { running = false } + /** Why the last turn wasn't spoken, so the log says it once rather than every tick. */ + private var silentBecause: String? = null + + private fun quiet(reason: String) { + if (silentBecause == reason) return + silentBecause = reason + GearslipLog.i("guidance: not speaking - $reason") + } + private fun tick() { - if (!CarSettings.speakDirections.value) return val turn = NavTurn.current() if (turn == null) { turnKey = null return } - if (turn.rerouting) return + if (!CarSettings.speakDirections.value) return quiet("Spoken directions is off in the car's Settings") + if (turn.rerouting) return quiet("the map app is rerouting") val step = turn.step - val instruction = instruction(step) ?: return + val instruction = instruction(step) ?: return quiet("the map app gave this turn no words") + silentBecause = null val meters = turn.distance?.let(NavTurn::toMeters) val close = (turn.seconds != null && turn.seconds <= NEAR_SECONDS) || (meters != null && meters <= NEAR_METERS)