From 45834692a75ec7c8f0784cc59e22f3ee5ec1c4eb Mon Sep 17 00:00:00 2001 From: evgeny Date: Mon, 26 Oct 2026 15:33:11 +0100 Subject: [PATCH] Document headless PCM framing defect and independent codec ownership --- src/call/call_audio.h | 3 ++- src/call/call_headless.h | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/call/call_audio.h b/src/call/call_audio.h index fa59c1d4..f3d148cd 100644 --- a/src/call/call_audio.h +++ b/src/call/call_audio.h @@ -1,7 +1,8 @@ #ifndef CALL_AUDIO_H #define CALL_AUDIO_H -// call_audio.h — сервисный аудио-движок P2P-звонка (единый для desktop/Android/headless). +// call_audio.h — общий аудио-движок P2P-звонка для frontend с захватом/воспроизведением (desktop/Android). +// TCP-сервис готового PCM имеет собственные кодеки и описан отдельно в call_headless.h. // // Владеет Opus codec, адаптивным джиттер-буфером (call_jitter: кодированные // кадры + SoundTouch time-stretch на pull) и тонами (глитч при сталле / завершение). diff --git a/src/call/call_headless.h b/src/call/call_headless.h index 56900c38..1fad4bdf 100644 --- a/src/call/call_headless.h +++ b/src/call/call_headless.h @@ -11,6 +11,11 @@ // type = 0x02 FRAME (PCM int16 mono 48k, 960 сэмплов = 1920 байт) // клиент → ядро = PCM захвата (кодируется и шлётся пиру); // ядро → клиент = PCM воспроизведения (декодированный Opus пира) +// call_id хранится в порядке байтов хоста, len — старший байт первым; PCM — native int16_t. +// Это отдельный сервис с кодеками instance, без DSP/jitter движка call_audio.h. +// Все вызовы и callbacks выполняются в потоке ua; клиент обеспечивает темп и воспроизведение. +// Известный дефект 26.10.2026: переполнение исходящей очереди может оставить заголовок +// без PCM и нарушить фрейминг. Аудит/план исправления — doc/call_audit_findings.txt,раздел11. #ifndef CALL_HEADLESS_H #define CALL_HEADLESS_H @@ -28,8 +33,13 @@ struct UTUN_INSTANCE; extern "C" { #endif +/* Запустить IPv4/TCP listener bind_ip:port и зарегистрировать приём Opus в call.c. + * ua — loop instance; inst должен иметь call_init. port=0 выбирает ОС. + * Один работающий listener на inst; повтор init не меняет адрес. 0 = успех, -1 = ошибка. + * При ошибке вызывающий выполняет destroy, включая частично созданный контекст. */ int call_headless_init(struct UASYNC* ua, struct UTUN_INSTANCE* inst, const char* bind_ip, int port); +/* Снять callback, отменить таймер и освободить listener/клиентов/кодеки до call_destroy и destroy ua. NULL допустим. */ void call_headless_destroy(struct UTUN_INSTANCE* inst); // port=0 при init выбирает ОС; 0 для остановленной службы или при ошибке. uint16_t call_headless_get_port(struct UTUN_INSTANCE* inst);