android radio: preserve output route on reconfigure, link input/output settings
This commit is contained in:
1 parent
15958a078e
commit
745ec3dbd2
2 files changed
+43
-3
No files matched your search
@@ -126,6 +126,7 @@ class RadioAudioEngine {
|
||||
active = false
|
||||
releaseLocked(false)
|
||||
active = true
|
||||
router.setAutoHeadset(true) /* дефолт «авто» только на свежий старт/смену группы */
|
||||
setupAudio()
|
||||
}
|
||||
|
||||
@@ -157,7 +158,6 @@ class RadioAudioEngine {
|
||||
|
||||
/* Маршрут выхода: автоследование за гарнитурой (воткнули → HEADSET, вынули → SPEAKER). */
|
||||
router.fallbackRoute = AudioRoute.SPEAKER
|
||||
router.setAutoHeadset(true)
|
||||
router.start()
|
||||
|
||||
// ── AudioRecord (захват) с откатом стерео→моно ──
|
||||
@@ -382,6 +382,7 @@ class RadioAudioEngine {
|
||||
val ch = captureChannels
|
||||
val frame = FRAME_SAMPLES * ch
|
||||
val buf = ShortArray(frame)
|
||||
var frameN = 0L
|
||||
while (active) {
|
||||
val rec = audioRecord ?: break
|
||||
if (rec.recordingState != AudioRecord.RECORDSTATE_RECORDING) {
|
||||
@@ -404,6 +405,12 @@ class RadioAudioEngine {
|
||||
}
|
||||
read += n
|
||||
}
|
||||
/* диагностика крос-девайс входа/выхода: куда реально роутится захват + уровень сигнала */
|
||||
if (frameN < 10 || frameN % 100L == 0L) {
|
||||
LogManager.addLog("DEBUG", "RadioAudio",
|
||||
"cap routed=${rec.routedDevice?.type ?: "-"} frame=$frameN rmsDb=${rmsDb(buf)} input=${inputSource()} route=${route()}")
|
||||
}
|
||||
frameN++
|
||||
if ((talking || vadMode) && !NativeLib.radioAudioFeed(groupId, buf)) {
|
||||
LogManager.addLog("WARN", "RadioAudio", "radioAudioFeed returned false")
|
||||
}
|
||||
@@ -411,6 +418,14 @@ class RadioAudioEngine {
|
||||
LogManager.addLog("DEBUG", "RadioAudio", "capture loop done")
|
||||
}
|
||||
|
||||
/** RMS захваченного кадра в dBFS (0 = полная шкала; тишина ~ -90). */
|
||||
private fun rmsDb(buf: ShortArray): Int {
|
||||
var sum = 0L
|
||||
for (s in buf) sum += s.toLong() * s.toLong()
|
||||
val rms = Math.sqrt(sum.toDouble() / buf.size)
|
||||
return if (rms < 1.0) -120 else (20.0 * Math.log10(rms / 32768.0)).toInt()
|
||||
}
|
||||
|
||||
private fun playLoop() {
|
||||
val frame = FRAME_SAMPLES * PLAY_CHANNELS
|
||||
val buf = ShortArray(frame)
|
||||
|
||||
@@ -860,22 +860,47 @@ class ChatViewModel : ViewModel() {
|
||||
radioAudio.talkEnd()
|
||||
}
|
||||
|
||||
/** Ручной выбор выхода рации (динамик/гарнитура). */
|
||||
/** Ручной выбор выхода рации (динамик/гарнитура) — синхронизирует вход. */
|
||||
fun setRadioRoute(r: AudioRoute) {
|
||||
if (!_radioActive.value) return
|
||||
_radioAuto.value = false
|
||||
radioAudio.setRoute(r)
|
||||
_radioRoute.value = radioAudio.route()
|
||||
val linkedInput = when (r) {
|
||||
AudioRoute.SPEAKER -> RadioAudioEngine.INPUT_BUILTIN
|
||||
AudioRoute.HEADSET -> when {
|
||||
_wiredInputAvailable.value -> RadioAudioEngine.INPUT_WIRED
|
||||
_btInputAvailable.value -> RadioAudioEngine.INPUT_BT
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
if (linkedInput != null && linkedInput != _radioInputSource.value) {
|
||||
_radioInputSource.value = linkedInput
|
||||
viewModelScope.launch {
|
||||
ChatApplication.instance.configProvider.setRadioInputSource(linkedInput)
|
||||
radioAudio.reconfigure()
|
||||
}
|
||||
}
|
||||
LogManager.addLog("INFO", "VM", "setRadioRoute -> ${radioAudio.route()}")
|
||||
}
|
||||
|
||||
/** Ручной выбор входного устройства рации (выключает авто). */
|
||||
/** Ручной выбор входного устройства рации — синхронизирует выход. */
|
||||
fun setRadioInputSource(src: Int) {
|
||||
if (!_radioActive.value) return
|
||||
val clamped = src.coerceIn(RadioAudioEngine.INPUT_AUTO, RadioAudioEngine.INPUT_BT)
|
||||
if (clamped == _radioInputSource.value) return
|
||||
_radioAuto.value = false
|
||||
_radioInputSource.value = clamped
|
||||
val linkedRoute = when (clamped) {
|
||||
RadioAudioEngine.INPUT_BUILTIN -> AudioRoute.SPEAKER
|
||||
RadioAudioEngine.INPUT_WIRED, RadioAudioEngine.INPUT_BT -> AudioRoute.HEADSET
|
||||
else -> null
|
||||
}
|
||||
if (linkedRoute != null) {
|
||||
radioAudio.setRoute(linkedRoute)
|
||||
_radioRoute.value = radioAudio.route()
|
||||
}
|
||||
viewModelScope.launch {
|
||||
ChatApplication.instance.configProvider.setRadioInputSource(clamped)
|
||||
radioAudio.reconfigure()
|
||||
|
||||
Reference in new issue
Block a user