mirror of
https://github.com/twinksoftware/Gearslip.git
synced 2026-11-10 16:02:25 +01:00
start car audio as soon as the head unit answers setup
This commit is contained in:
1 parent
dd3b845c7f
commit
be981b0899
1 file changed
+27
-18
@@ -60,14 +60,14 @@ class AudioLink(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The 2018 Uconnect answers our Setup with a two-byte message we cannot identify (id 255, no
|
* The 2018 Uconnect and a Dacia ULC 4.5 both answer our Setup with a two-byte message we
|
||||||
* body) rather than the AVChannelSetupResponse the video channel gets, so the sink never
|
* cannot identify (id 255, no body) rather than the AVChannelSetupResponse the video channel
|
||||||
* reaches READY and no audio is ever sent.
|
* gets, so the sink never reaches READY. [MSG_SETUP_ANSWER] takes that as the go-ahead.
|
||||||
*
|
*
|
||||||
* Service discovery already told us everything that message would have: the sink is PCM at
|
* Service discovery already told us everything a Config would have: the sink's rate, channels
|
||||||
* 48000Hz stereo and it has exactly one configuration. So rather than wait forever for a
|
* and its one configuration. So for a car that answers nothing at all, wait a moment and then
|
||||||
* message that is not coming, assume the advertised configuration and carry on. If that guess
|
* assume the advertised configuration. If that guess is wrong the head unit simply will not
|
||||||
* is wrong the head unit simply will not ack, which the write path already reports.
|
* ack, which the write path already reports.
|
||||||
*/
|
*/
|
||||||
private fun armConfigFallback() {
|
private fun armConfigFallback() {
|
||||||
val timer = Thread({
|
val timer = Thread({
|
||||||
@@ -76,19 +76,25 @@ class AudioLink(
|
|||||||
} catch (e: InterruptedException) {
|
} catch (e: InterruptedException) {
|
||||||
return@Thread
|
return@Thread
|
||||||
}
|
}
|
||||||
if (ready) return@Thread
|
useAdvertisedSink("no usable Config after ${CONFIG_WAIT_MS}ms")
|
||||||
GearslipLog.w(
|
|
||||||
"audio: no usable Config after ${CONFIG_WAIT_MS}ms - falling back to the sink the " +
|
|
||||||
"head unit advertised (${sampleRate}Hz x$channels, config_index=0, max_unacked=$maxUnacked)",
|
|
||||||
)
|
|
||||||
configIndex = 0
|
|
||||||
ready = true
|
|
||||||
CarAudio.attach(this)
|
|
||||||
}, "gearslip-audio-config").apply { isDaemon = true }
|
}, "gearslip-audio-config").apply { isDaemon = true }
|
||||||
configTimer = timer
|
configTimer = timer
|
||||||
timer.start()
|
timer.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
private fun useAdvertisedSink(why: String) {
|
||||||
|
if (ready) return
|
||||||
|
configTimer?.interrupt()
|
||||||
|
GearslipLog.i(
|
||||||
|
"audio: $why - using the sink the head unit advertised " +
|
||||||
|
"(${sampleRate}Hz x$channels, config_index=0, max_unacked=$maxUnacked)",
|
||||||
|
)
|
||||||
|
configIndex = 0
|
||||||
|
ready = true
|
||||||
|
CarAudio.attach(this)
|
||||||
|
}
|
||||||
|
|
||||||
fun onMessage(messageId: Int, body: ByteArray) {
|
fun onMessage(messageId: Int, body: ByteArray) {
|
||||||
when (messageId) {
|
when (messageId) {
|
||||||
MSG_CHANNEL_OPEN_RESPONSE -> opened(Protobuf.readInt32Field(body, 1) ?: 0)
|
MSG_CHANNEL_OPEN_RESPONSE -> opened(Protobuf.readInt32Field(body, 1) ?: 0)
|
||||||
@@ -123,8 +129,10 @@ class AudioLink(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whatever the head unit answers Setup with, we need its bytes to identify it.
|
// Whatever else the head unit answers Setup with, we need its bytes to identify it.
|
||||||
else -> {
|
else -> if (messageId == MSG_SETUP_ANSWER && body.isEmpty()) {
|
||||||
|
useAdvertisedSink("<- empty Setup answer (id $messageId)")
|
||||||
|
} else {
|
||||||
GearslipLog.i("audio: <- unhandled message id=$messageId (${body.size} bytes)")
|
GearslipLog.i("audio: <- unhandled message id=$messageId (${body.size} bytes)")
|
||||||
GearslipLog.hex(" audio msg", body, limit = 64)
|
GearslipLog.hex(" audio msg", body, limit = 64)
|
||||||
}
|
}
|
||||||
@@ -243,6 +251,7 @@ class AudioLink(
|
|||||||
private const val MSG_STOP = 32770
|
private const val MSG_STOP = 32770
|
||||||
private const val MSG_CONFIG = 32771
|
private const val MSG_CONFIG = 32771
|
||||||
private const val MSG_ACK = 32772
|
private const val MSG_ACK = 32772
|
||||||
|
private const val MSG_SETUP_ANSWER = 255
|
||||||
private const val STATUS_READY = 2
|
private const val STATUS_READY = 2
|
||||||
private const val FOCUS_GAIN = 1
|
private const val FOCUS_GAIN = 1
|
||||||
private const val FOCUS_RELEASE = 4
|
private const val FOCUS_RELEASE = 4
|
||||||
@@ -251,7 +260,7 @@ class AudioLink(
|
|||||||
private const val SESSION_ID = 2
|
private const val SESSION_ID = 2
|
||||||
private const val STALL_MS = 2_000L
|
private const val STALL_MS = 2_000L
|
||||||
private const val CHUNK_LOG_EVERY = 200 // about every four seconds
|
private const val CHUNK_LOG_EVERY = 200 // about every four seconds
|
||||||
private const val CONFIG_WAIT_MS = 2_500L
|
private const val CONFIG_WAIT_MS = 1_000L
|
||||||
|
|
||||||
private val FOCUS_STATES = mapOf(
|
private val FOCUS_STATES = mapOf(
|
||||||
1 to "GAIN", 2 to "GAIN_TRANSIENT", 3 to "LOSS", 4 to "LOSS_TRANSIENT",
|
1 to "GAIN", 2 to "GAIN_TRANSIENT", 3 to "LOSS", 4 to "LOSS_TRANSIENT",
|
||||||
|
|||||||
Reference in new issue
Block a user