mirror of
https://github.com/twinksoftware/Gearslip.git
synced 2026-11-10 16:02:25 +01:00
car mic: open a voice session and name the codec before asking for the car's microphone
This commit is contained in:
1 parent
8912e88406
commit
1cd3d6f856
2 files changed
+19
-4
No files matched your search
@@ -513,7 +513,14 @@ class GearslipRunner(
|
|||||||
}
|
}
|
||||||
val config = mic.configs.first()
|
val config = mic.configs.first()
|
||||||
log.i("car microphone: channel=${mic.serviceId} ${mic.codecName} ${config.sampleRate}Hz/${config.bits}bit/x${config.channels}")
|
log.i("car microphone: channel=${mic.serviceId} ${mic.codecName} ${config.sampleRate}Hz/${config.bits}bit/x${config.channels}")
|
||||||
CarMic.current = CarMic(mic) { id, body -> send(id, body, encrypted = true, channel = mic.serviceId) }
|
CarMic.current = CarMic(
|
||||||
|
mic,
|
||||||
|
sendOnChannel = { id, body -> send(id, body, encrypted = true, channel = mic.serviceId) },
|
||||||
|
// VoiceSessionNotification { status = 1 START, 2 END }, on the control channel.
|
||||||
|
voiceSession = { start ->
|
||||||
|
send(MSG_VOICE_SESSION_NOTIFICATION, Protobuf.varintField(1, if (start) 1L else 2L), encrypted = true)
|
||||||
|
},
|
||||||
|
)
|
||||||
openChannel(mic.serviceId)
|
openChannel(mic.serviceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1244,6 +1251,7 @@ class GearslipRunner(
|
|||||||
const val MSG_PING_RESPONSE = 12
|
const val MSG_PING_RESPONSE = 12
|
||||||
const val MSG_BYEBYE_REQUEST = 15
|
const val MSG_BYEBYE_REQUEST = 15
|
||||||
const val MSG_BYEBYE_RESPONSE = 16
|
const val MSG_BYEBYE_RESPONSE = 16
|
||||||
|
const val MSG_VOICE_SESSION_NOTIFICATION = 17
|
||||||
const val MSG_CHANNEL_OPEN_REQUEST = 7
|
const val MSG_CHANNEL_OPEN_REQUEST = 7
|
||||||
const val MSG_CHANNEL_OPEN_RESPONSE = 8
|
const val MSG_CHANNEL_OPEN_RESPONSE = 8
|
||||||
|
|
||||||
|
|||||||
@@ -12,17 +12,21 @@ import java.util.concurrent.TimeUnit
|
|||||||
*
|
*
|
||||||
* -> CHANNEL_OPEN_REQUEST <- CHANNEL_OPEN_RESPONSE
|
* -> CHANNEL_OPEN_REQUEST <- CHANNEL_OPEN_RESPONSE
|
||||||
* -> Setup { config_index } <- Config
|
* -> Setup { config_index } <- Config
|
||||||
|
* -> VoiceSessionNotification { START } (control channel)
|
||||||
* -> MicrophoneRequest { open } <- MicrophoneResponse { status, session_id }
|
* -> MicrophoneRequest { open } <- MicrophoneResponse { status, session_id }
|
||||||
* <- Data { 8-byte timestamp, PCM }... -> Ack { session_id, ack }
|
* <- Data { 8-byte timestamp, PCM }... -> Ack { session_id, ack }
|
||||||
* -> MicrophoneRequest { open = false }
|
* -> MicrophoneRequest { open = false }
|
||||||
|
* -> VoiceSessionNotification { END }
|
||||||
*
|
*
|
||||||
* The channel opens with the session, but the car only records between [start] and [stop].
|
* The channel opens with the session, but the car only records between [start] and [stop], and
|
||||||
|
* only inside a voice session: the 2024 VW answered a bare MicrophoneRequest with status -7.
|
||||||
* Speech wants 16 kHz mono; a car that records at a multiple of that is averaged down to it, and
|
* Speech wants 16 kHz mono; a car that records at a multiple of that is averaged down to it, and
|
||||||
* one that doesn't isn't used, so voice falls back to the phone's microphone.
|
* one that doesn't isn't used, so voice falls back to the phone's microphone.
|
||||||
*/
|
*/
|
||||||
class CarMic(
|
class CarMic(
|
||||||
private val service: ServiceDiscovery.AudioService,
|
private val service: ServiceDiscovery.AudioService,
|
||||||
private val sendOnChannel: (messageId: Int, body: ByteArray) -> Unit,
|
private val sendOnChannel: (messageId: Int, body: ByteArray) -> Unit,
|
||||||
|
private val voiceSession: (start: Boolean) -> Unit,
|
||||||
) {
|
) {
|
||||||
val channelId get() = service.serviceId
|
val channelId get() = service.serviceId
|
||||||
|
|
||||||
@@ -43,7 +47,8 @@ class CarMic(
|
|||||||
val status = Protobuf.readInt32Field(body, 1) ?: 0
|
val status = Protobuf.readInt32Field(body, 1) ?: 0
|
||||||
GearslipLog.i("mic: <- ChannelOpenResponse: status=$status")
|
GearslipLog.i("mic: <- ChannelOpenResponse: status=$status")
|
||||||
if (status != 0) return
|
if (status != 0) return
|
||||||
sendOnChannel(MSG_SETUP, Protobuf.varintField(1, 0L))
|
// Setup { type = the codec }, as for audio: 0 got UNEXPECTED_MESSAGE from the VW.
|
||||||
|
sendOnChannel(MSG_SETUP, Protobuf.varintField(1, service.codecType.toLong()))
|
||||||
ready = usable
|
ready = usable
|
||||||
if (!usable) {
|
if (!usable) {
|
||||||
GearslipLog.w(
|
GearslipLog.w(
|
||||||
@@ -97,6 +102,7 @@ class CarMic(
|
|||||||
chunks.clear()
|
chunks.clear()
|
||||||
packets = 0
|
packets = 0
|
||||||
listening = true
|
listening = true
|
||||||
|
voiceSession(true)
|
||||||
sendOnChannel(MSG_MIC_REQUEST, Protobuf.varintField(1, 1L) + Protobuf.varintField(4, 1L))
|
sendOnChannel(MSG_MIC_REQUEST, Protobuf.varintField(1, 1L) + Protobuf.varintField(4, 1L))
|
||||||
GearslipLog.i("mic: -> MicrophoneRequest(open)")
|
GearslipLog.i("mic: -> MicrophoneRequest(open)")
|
||||||
return true
|
return true
|
||||||
@@ -109,7 +115,8 @@ class CarMic(
|
|||||||
if (!listening) return
|
if (!listening) return
|
||||||
listening = false
|
listening = false
|
||||||
sendOnChannel(MSG_MIC_REQUEST, Protobuf.varintField(1, 0L))
|
sendOnChannel(MSG_MIC_REQUEST, Protobuf.varintField(1, 0L))
|
||||||
GearslipLog.i("mic: -> MicrophoneRequest(close) after $packets packets")
|
voiceSession(false)
|
||||||
|
GearslipLog.i("mic: -> MicrophoneRequest(close) after $packets packets, voice session ended")
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
Reference in new issue
Block a user