Browse Source

Document independent call audio startup and delivery reserve

master
evgeny 2 weeks ago
parent
commit
fbf50b093d
  1. 19
      doc/chat_call_arch.md
  2. 6
      doc/tasks.md

19
doc/chat_call_arch.md

@ -116,19 +116,26 @@ GUI запускает аудиоустройство по CALL_ACCEPTED. При
устройство останавливается перед `call_audio_release`. Явное завершение звонка прекращает
воспроизведение накопленной речи и включает тон завершения — на обеих платформах.
Android останавливает гудки до настройки звонкового аудиотракта. После выбора маршрута
и создания AudioRecord поток захвата начинает отправку, затем создаётся и запускается AudioTrack.
Ошибка подготовки playback останавливает и дожидается уже запущенного захвата через общий `stop()`.
capture/play потоки независимо создают и запускают AudioRecord/AudioTrack; каждый сразу обслуживает своё направление.
`start()` подтверждает запуск подготовки, ошибки устройств передаются владельцу на main через `onFailure`.
Ошибка любого направления завершает звонок. Общий `stop()` отменяет подготовку, разблокирует I/O и ждёт оба потока
до освобождения Android-устройств и native-аудиостека. Отдельные locks защищают подготовку/остановку каждого устройства.
Замер AEC планируется через 300мс после готовности обоих направлений и не задерживает воспроизведение.
Маршрутизатор использует один снимок входных/выходных устройств; обновляет его при старте,
событиях устройств/BT-профиля и явной переоценке. По завершении снимок освобождается.
INFO-логи Android показывают длительности настройки режима, маршрута, создания/старта устройств
и время первого кадра захвата. Общий `call_audio` логирует время ожидания первого PCM.
INFO-логи Android показывают длительности настройки режима, регистрации callback, BT-профиля, выбора маршрута,
создания/старта устройств, первого чтения микрофона и первой записи в AudioTrack, а также готовность другого направления.
Общий `call_audio` логирует время ожидания первого PCM; запись в AudioTrack может содержать начальную тишину.
## 7. Буфер звонка и восстановление
`call_jitter` независим от `radio_jitter`: рация сохраняет свои правила задержки и сброса.
Буфер звонка хранит до 750 кодированных кадров (15с): 10с перебоя и 5с запаса.
Целевой запас — `clamp(max-min, 60, max_reserve_ms)` мс: десять секундных интервалов
хранят минимум и максимум глубины, старые интервалы истекают по монотонным часам.
Целевой запас — `clamp(max-min, 60, max_reserve_ms)` мс по изменению задержки доставки:
на входящем кадре накапливается разность интервалов приёма и отправки, десять секундных интервалов хранят её экстремумы.
Отправитель уже передаёт timestamp в CALL_MEDIA; смещение часов пиров исключается, переполнение uint32 учитывается.
Подготовка местного аудиоустройства и ускоренное воспроизведение очереди не изменяют оценку доставки.
Минимум/максимум глубины очереди для GUI собираются отдельно в аудиопотоке за те же десять секунд.
Верхний предел задаётся `call_jitter_max_reserve_ms`: 500–2000 мс, по умолчанию 1000 мс.
Настройка есть в аудиопараметрах desktop и Android и применяется к следующему звонку.
Начальное и повторное накопление ждёт этот запас; увеличение запаса не прерывает текущую речь.

6
doc/tasks.md

@ -85,6 +85,12 @@
callback, BT-профиля и применения маршрута; отдельно проверить первый AudioRecord.read.
На SM входящий буфер за время подготовки вырос до 1149мс и к концу звонка снизился
до 570мс; ускорение старта playback также сократит начальное накопление.
Реализован независимый запуск AudioTrack и AudioRecord в play/capture потоках;
частичный старт отменяется до освобождения устройств/native. AEC измеряется после готовности обоих.
Добавлены callbackMs/btProfileMs/applyMs/refreshMs, длительность первого read и время первой записи playback.
Резерв теперь зависит от изменения задержки доставки по timestamps CALL_MEDIA, отдельно от глубины очереди;
стартовое накопление и догон не повышают запас. Сохранность FIFO и uint32 wrap проверяются регрессиями.
Сборки ядра, Qt и Android успешны. Выигрыш по времени требует пробного звонка с новой версией.
[ ] **Гонка invite-файла в test_chat_join_e2e** — `wait_file()` проверяет только
существование файла, а `wf()` создаёт его до записи. Читатель иногда получает

Loading…
Cancel
Save