diff --git a/doc/call_video.txt b/doc/call_video.txt index f079a8d9..09ea8bb9 100644 --- a/doc/call_video.txt +++ b/doc/call_video.txt @@ -36,9 +36,9 @@ call_id, video_generation и request_id; одно исполнение и пос Порядок реализации [+] История первых ACK 500мс/50мс и снимок payload send_q/inflight отдельного сервиса. [ ] Проверки интеграции счётчиков: retransmit, duplicate ACK, reset, UDP/STCP. -[ ] Проверка переноса аудиопозиции через SoundTouch при темпе 1.0..1.6. +[!] Проверка переноса аудиопозиции выявила дрейф feed/tempo; см. результаты ниже. [ ] H.265 runtime bitrate: поддерживаемый backend без циклического пересоздания. -[ ] Общий регулятор с детерминированными сценариями. +[+] Общий регулятор с детерминированными сценариями (пока не подключён к звонку). [ ] Протокол возможностей/формата, видеофрагменты, сборка, A/V scheduler. [ ] Общие capture PTS и отображение позиции аудиоустройства в исходное время. [ ] ChatGUI: движок, окно и настройки; Android: движок, JNI, сервис и экран. @@ -51,3 +51,28 @@ call_id, video_generation и request_id; одно исполнение и пос пробами. Очереди остаются ограниченными при отсутствии ACK и остановке decoder. Видео следует аудио при догоне, underrun, смене устройства и формате видеотрека. Завершение звонка безопасно во время переключения камеры, bitrate и decoder. + +Проверка SoundTouch, 14.10.2026 +test_soundtouch_clock сравнивает положение реальных четырёхсэмпловых фрагментов +в выходном сигнале с двумя вариантами временной шкалы. 60с входа, mono 48kHz, +sequence=20ms, seek=10ms, overlap=4ms — параметры существующего call_jitter. +Максимальная ошибка feed/tempo / consumed-input, мс: + постоянный темп 1.6: 14.208 / 14.271 + плавный цикл 1.0..1.6 (шаг 0.012/20ms): 29.550 / 13.723 + стресс, переключение 1.0/1.6 каждые 20ms: 938.104 / 14.462 +Стресс не воспроизводит ограничение темпа звонка, а проверяет отсутствие накопления. +Проблема: setTempo меняет обработку ещё не потреблённого входа; номинальные интервалы +frames/tempo, записанные при feed, не описывают фактический выход. Поэтому копировать +этот способ из stream_playback_audio в звонки нельзя. Изменений звука/буфера нет. + +Варианты следующего шага: +1. Минимальный: шкала по фактически потреблённому входу и произведённому выходу, + с поправкой на seek-window. Тест показал <15мс на трёх сценариях, но это ещё не + доказанная граница для речи/Opus/разных блоков. Нужны эти проверки и явный допуск. +2. Более строгий: SoundTouch публикует соответствие исходных участков выходным + непосредственно в TDStretch. Позволяет учитывать выбранный WSOLA offset без + вычисления по косвенным счётчикам; потребует небольшого расширения bundled API. + Overlap смешивает два участка, поэтому даже здесь нужно определить правило PTS. + Рекомендуется для общего A/V clock: не меняет звук, исключает накопительный дрейф. +Далее шкала отображается через реально проигранные позиции устройства; тоны/тишина +не двигают её. Продолжение видео остановлено до выбора точного контракта этой шкалы. diff --git a/tools/chatgui/CMakeLists.txt b/tools/chatgui/CMakeLists.txt index db366af7..ea550b9c 100644 --- a/tools/chatgui/CMakeLists.txt +++ b/tools/chatgui/CMakeLists.txt @@ -445,6 +445,10 @@ target_include_directories(test_call_jitter PRIVATE ${CMAKE_SOURCE_DIR}/../../sr target_link_libraries(test_call_jitter PRIVATE utun_voice utun pthread) add_test(NAME test_call_jitter COMMAND test_call_jitter) +add_executable(test_soundtouch_clock tests/test_soundtouch_clock.cpp) +target_link_libraries(test_soundtouch_clock PRIVATE utun_voice utun pthread) +add_test(NAME test_soundtouch_clock COMMAND test_soundtouch_clock) + # тест аудио-движка рации (per-source jitter + микшер + soft-clip) add_executable(test_radio_audio tests/test_radio_audio.cpp