diff --git a/tools/chatgui-android/doc/ARCHITECTURE.md b/tools/chatgui-android/doc/ARCHITECTURE.md index 8f88e3ca..a2490abc 100644 --- a/tools/chatgui-android/doc/ARCHITECTURE.md +++ b/tools/chatgui-android/doc/ARCHITECTURE.md @@ -235,6 +235,24 @@ feed/pull workers и маршрутом Android Telecom; DSP и сетевой Вызовы lifecycle DSP выполняются после остановки его внешних feed/pull callers. Контракты PCM/PTS: `src/call/call_audio.h`, `src/radio/radio_audio.h`, `jni_bridge/android_jni_bridge.h`. +`RadioPttHolds` на main хранит по одному ручному удержанию BUTTON/OVERLAY/VOLUME. +Повтор press того же источника идемпотентен; несколько volume-клавиш агрегирует +Activity и отпускает общий VOLUME после последней клавиши. Release возвращает +true только при удалении последнего владельца; неизвестное отпускание не гасит +чужую передачу. Cancel возвращает отсутствие владельцев также для уже пустого +набора: это позволяет отменить хвост передачи после release. Null снимает всех. +Агрегатор не управляет VAD, аудио или таймерами; их владелец — RadioAudioEngine. + +`RadioTalkState` хранит отдельный снимок говорящих для активной группы. Включение/ +смена канала создаёт новый снимок, выключение устанавливает groupId=0. Событие 43 +разбирается строго как 19 little-endian байтов: group/node/stream/on; ID ненулевые, +stream=0..65535, on=0/1. Неверное событие возвращает null и логируется ViewModel. +START/STOP обновляет только набор node ID своей группы; чужая группа и повтор +состояния сохраняют прежний объект. В C radio_talker_on заменяет stream одного +узла без STOP старого потока, поэтому stream не является ключом UI-набора. +Индикатор речи не зависит от обновления таблицы участников или локального mute; +выключенная рация игнорирует события. Эти снимки не управляют ручным PTT. + Live stream bridge владеет одним publisher и независимыми viewers поверх общих `stream_publisher`/`stream_viewer`. UI использует session IDs, не inst/ua. Данные идут через pull, а каталог источников — через CHAT_EVT_STREAM_SOURCES.