mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
feat(tci): этап 2 — бинарные потоки IQ/аудио, TX-аудио и запись линейного выхода
Реализованы все четыре потока §3.4 и рекордер:
• RX_AUDIO_STREAM — тап ДО громкости и мьюта (OnDemodAudioReady): скиммеру
и цифре нужен звук приёмника, а не то, что осталось после ручки;
• LINEOUT_STREAM — тап ПОСЛЕ (OnAudioReady), то есть что слышно;
• IQ_STREAM — тап сырого IQ в движке, ОДИН вызов на накопленный блок;
• TX_AUDIO_STREAM + TX_CHRONO — TRX:0,true,tci берёт модуляцию из потока
клиента (флаг TCIMicRequested впереди web в SetMOX), маркеры времени идут
из тика по часам, аудио клиента разворачивается в 48 кГц моно в тот же
ринг, что и web-микрофон;
• LINE_OUT_RECORDER_* — кольцо int16 на приёмник, WAV пишет отдельный поток.
Тапы аудио в контроллере многоадресные (AddAudioTap): слушают, ничего не
забирая, в отличие от OnAudioConsume, которым владеет web. Блоки нарезает и
раскладывает по кольцам клиентов сам DSP-поток, в сокет пишет поток клиента —
та же дисциплина, что у команд. Порядок локов везде FSliceLock → FStreamLock.
У очереди команд и кольца блоков разная политика переполнения: команду терять
нельзя, блок потока — можно (теряется самый старый).
Пересчёт частоты многоступенчатый (TCIStreams). Одноступенчатый FIR на верхнем
пресете Pluto (5760 кГц, коэффициент 120) упирался в потолок отводов и давал
завал 1.3 дБ в полосе при подавлении зеркала 16 дБ — то есть поток IQ с
мусором. Теперь коэффициент раскладывается на множители, спецификацию фильтра
каждой ступени задаёт ИТОГОВАЯ полоса, а свёртка идёт со сложением
симметричных пар: −83 дБ на любом коэффициенте, ≈10% ядра на 5.76 МГц.
Согласование частот с железом: из пресетов Pluto 576 и 960 кГц на 384 не
делятся, поэтому отдаём наибольшую ЗАКОННУЮ частоту, делящую источник нацело
(576/960 → 192 кГц). Ответ на IQ_SAMPLERATE называет достижимое, а не просьбу
клиента, и переобъявляется без запроса при смене rate и устройства.
Приёмный буфер соединения 4 → 32 КБ: блок TX-аудио это 64 байта заголовка плюс
data[16384], а кадр крупнее буфера не собирается никогда.
Настройки TCI переехали из Advanced на вкладку CAT, справа от TCP CAT Server:
это такой же канал внешнего управления трансивером.
Стенд (scratchpad, tcitest.pas): 112 проверок, все зелёные — включая сквозной
прогон через живой WDSP (синтетический IQ → блоки RX-аудио и IQ у настоящего
WS-клиента, и обратно TX-аудио клиента → блоки TX-IQ).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+18
-1
@@ -22,6 +22,14 @@ uses
|
||||
SyncObjs, WebUtils
|
||||
{$IFDEF WINDOWS}, WinSock2{$ELSE}, Sockets{$ENDIF};
|
||||
|
||||
const
|
||||
{ Приёмный буфер соединения. 4 КБ хватало командам и web-запросам, но блок
|
||||
бинарного потока TCI (§3.4) — это заголовок 64 байта плюс data[16384],
|
||||
и кадр крупнее буфера не собирается НИКОГДА: BufLen упирается в потолок и
|
||||
разбор встаёт. Поэтому потолок держим с запасом на кадр целиком вместе с
|
||||
маской и хвостом соседнего сообщения. }
|
||||
WS_BUF_SIZE = 32768;
|
||||
|
||||
type
|
||||
TWsState = (wsHandshake, wsOpen, wsClosed);
|
||||
|
||||
@@ -30,7 +38,7 @@ type
|
||||
FSocket: TSocket;
|
||||
FState: TWsState;
|
||||
FLock: TCriticalSection;
|
||||
FBuf: array[0..4095] of Byte;
|
||||
FBuf: array[0..WS_BUF_SIZE-1] of Byte;
|
||||
FBufLen: Integer;
|
||||
FAuthed: Boolean;
|
||||
public
|
||||
@@ -55,6 +63,10 @@ type
|
||||
{ Указатель на начало буфера приёма }
|
||||
function BufData: PByte; inline;
|
||||
|
||||
{ Ёмкость приёмного буфера: разбору фреймов нужен потолок, чтобы вовремя
|
||||
закрыть соединение, а не встать намертво на несобираемом кадре. }
|
||||
function BufCapacity: Integer; inline;
|
||||
|
||||
property Socket: TSocket read FSocket;
|
||||
property State: TWsState read FState write FState;
|
||||
property Authed: Boolean read FAuthed write FAuthed;
|
||||
@@ -175,4 +187,9 @@ begin
|
||||
Result := @FBuf[0];
|
||||
end;
|
||||
|
||||
function TWsClient.BufCapacity: Integer;
|
||||
begin
|
||||
Result := SizeOf(FBuf);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user