Move Android VAD activation to the radio toolbar
This commit is contained in:
1 parent
099c9b7eac
commit
9ff1f5645f
6 files changed
+29
-15
No files matched your search
@@ -349,6 +349,7 @@ class ConfigProvider(private val context: Context) {
|
||||
}
|
||||
|
||||
val radioOverlayEnabled: Flow<Boolean> = context.dataStore.data.map { it[radioOverlayKey] ?: false }
|
||||
val radioVadEnabled: Flow<Boolean> = context.dataStore.data.map { (it[radioVadEnabledKey] ?: 0) != 0 }
|
||||
|
||||
@Volatile private var radioOverlayCached = false
|
||||
@Volatile private var radioOverlayLoaded = false
|
||||
|
||||
@@ -249,7 +249,7 @@ private fun RadioPttButton(
|
||||
}
|
||||
}
|
||||
|
||||
/* Единый выбор входа/выхода и переключатель плавающей PTT-кнопки. */
|
||||
/* Единый выбор входа/выхода, VAD и плавающая PTT-кнопка. */
|
||||
@Composable
|
||||
private fun RadioSourceBar(viewModel: ChatViewModel) {
|
||||
val radioAuto by viewModel.radioAuto.collectAsState()
|
||||
@@ -260,6 +260,7 @@ private fun RadioSourceBar(viewModel: ChatViewModel) {
|
||||
val provider = ChatApplication.instance.configProvider
|
||||
val scope = rememberCoroutineScope()
|
||||
val overlayEnabled by provider.radioOverlayEnabled.collectAsState(initial = provider.getRadioOverlay())
|
||||
val vadEnabled by provider.radioVadEnabled.collectAsState(initial = provider.getInt("radio.vad_enabled") != 0)
|
||||
val overlayShown by RadioOverlayService.isShown.collectAsState()
|
||||
val overlayStatus by RadioOverlayService.status.collectAsState()
|
||||
|
||||
@@ -299,6 +300,10 @@ private fun RadioSourceBar(viewModel: ChatViewModel) {
|
||||
}
|
||||
}
|
||||
VerticalDivider(modifier = Modifier.height(32.dp), color = Color(0xFF344550))
|
||||
RadioControlButton(null, stringResource(if (vadEnabled) R.string.disable_vad else R.string.enable_vad),
|
||||
vadEnabled, text = stringResource(R.string.vad_button)) {
|
||||
viewModel.setRadioVad(!vadEnabled)
|
||||
}
|
||||
RadioControlButton(null, stringResource(R.string.floating_ptt), overlayShown, floating = true) {
|
||||
scope.launch {
|
||||
if (overlayEnabled && !overlayShown) RadioOverlayService.requestPermissions()
|
||||
@@ -317,7 +322,7 @@ private fun RadioSourceBar(viewModel: ChatViewModel) {
|
||||
@Composable
|
||||
private fun RadioControlButton(
|
||||
icon: ImageVector?, label: String, active: Boolean,
|
||||
centerIcon: ImageVector? = null, bluetooth: Boolean = false, floating: Boolean = false, onClick: () -> Unit
|
||||
centerIcon: ImageVector? = null, bluetooth: Boolean = false, floating: Boolean = false, text: String? = null, onClick: () -> Unit
|
||||
) {
|
||||
IconToggleButton(
|
||||
checked = active,
|
||||
@@ -327,6 +332,10 @@ private fun RadioControlButton(
|
||||
containerColor = Color(0xFF24323D), contentColor = Color(0xFFAEBCC8),
|
||||
checkedContainerColor = Color(0xFF1F6FEB), checkedContentColor = Color.White)
|
||||
) {
|
||||
if (text != null) {
|
||||
Text(text, fontSize = 12.sp, modifier = Modifier.semantics { contentDescription = label })
|
||||
return@IconToggleButton
|
||||
}
|
||||
if (floating) {
|
||||
RadioFloatingIcon(label)
|
||||
return@IconToggleButton
|
||||
|
||||
@@ -567,24 +567,11 @@ private fun RadioSettingsTab() {
|
||||
modifier = Modifier.padding(16.dp).verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
var vadEnabled by remember { mutableStateOf(provider.getInt("radio.vad_enabled") != 0) }
|
||||
var vadThreshold by remember { mutableStateOf(provider.getInt("radio.vad_threshold")) }
|
||||
var vadHangover by remember { mutableStateOf(provider.getInt("radio.vad_hangover_ms")) }
|
||||
var vadCompMaxGain by remember { mutableStateOf(provider.getInt("radio.vad_compressor_max_gain_db")) }
|
||||
val vadActive by RadioAudioEngine.instance().vadActiveFlow.collectAsState()
|
||||
Text(stringResource(R.string.radio_vad), style = MaterialTheme.typography.titleMedium)
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(stringResource(R.string.enable_vad), modifier = Modifier.weight(1f))
|
||||
Switch(checked = vadEnabled, onCheckedChange = { enabled ->
|
||||
vadEnabled = enabled
|
||||
scope.launch {
|
||||
provider.setValue("radio.vad_enabled", if (enabled) "1" else "0")
|
||||
NativeLib.setChatSetting("radio_vad_enabled", if (enabled) "1" else "0")
|
||||
if (enabled) RadioOverlayService.requestPermissions() else RadioOverlayService.sync(ChatApplication.instance)
|
||||
RadioAudioEngine.instance().reconfigure()
|
||||
}
|
||||
})
|
||||
}
|
||||
Text(stringResource(if (vadActive) R.string.vad_active else R.string.vad_inactive),
|
||||
style = MaterialTheme.typography.bodySmall)
|
||||
Text(stringResource(R.string.vad_screen_hint),
|
||||
|
||||
@@ -661,6 +661,19 @@ class ChatViewModel : ViewModel() {
|
||||
radioAudio.talkEnd()
|
||||
}
|
||||
|
||||
/** Переключатель авто-PTT на панели рации: сохранить выбор и перенастроить захват. */
|
||||
fun setRadioVad(enabled: Boolean) {
|
||||
if (!_radioActive.value) return
|
||||
viewModelScope.launch {
|
||||
val ctx = ChatApplication.instance
|
||||
ctx.configProvider.setValue("radio.vad_enabled", if (enabled) "1" else "0")
|
||||
NativeLib.setChatSetting("radio_vad_enabled", if (enabled) "1" else "0")
|
||||
LogManager.addLog("INFO", "RadioAudio", "Panel VAD enabled=$enabled channel=$radioChannelId")
|
||||
if (enabled) RadioOverlayService.requestPermissions() else RadioOverlayService.sync(ctx)
|
||||
radioAudio.reconfigure()
|
||||
}
|
||||
}
|
||||
|
||||
/** Ручной выбор выхода рации (динамик/гарнитура) — синхронизирует вход. */
|
||||
fun setRadioRoute(r: AudioRoute) {
|
||||
if (!_radioActive.value) return
|
||||
|
||||
Reference in new issue
Block a user