mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
fix(tci,cat): резерв бюджета переезжает писателю; строгий разбор полей ZZ-команд
Три замечания по79132f1. 1. [P2] Лимит памяти рекордеров обходился при SAVE. Take собирал сплошную копию записи, а DropData тут же возвращал исходные куски в бюджет — копия жила дальше в асинхронном TTCIWavWriter уже неучтённой. Один SAVE поднимал настоящее потребление примерно вдвое, а на медленном или зависшем сетевом каталоге очередь writer-потоков и их буферов росла мимо потолка вовсе. Теперь копия НАСЛЕДУЕТ резерв кусков, из которых собрана: Take отдаёт его out-параметром Reserved, писатель держит до конца записи и отпускает в ReleaseData — ровно один раз, сколько бы путей выхода ни было у Execute. Новых денег у бюджета копия не берёт, так что потолок теперь считает и очередь сохранений тоже. 2. [P2] Пять ZZ-команд проверяли длину поля, но не содержимое: StrToIntDef(s, 0) превращал любую нечисловую пару символов в индекс 0. ZZBSxx; переключал диапазон на нулевой вместо ?;, ZZBMxx; и ZZAUxx;/ZZBPxx; двигали VFO, ZZFIxx; выбирал фильтр 0. Разбор приведён к идиоме ZZFL/ZZFH: TryStrToInt, иначе ошибка формата. 3. [P3] Сообщение об отказе запуска TCI звало в Settings → Advanced, а настройки там уже не живут — вкладка CAT (переезд был вde0830f). Стенд 194/194: Take отдаёт резерв размером с копию, после Take занят ровно он, писатель возвращает его по окончании. Без фикса первая проверка краснеет. GUI (--ws=qt6) и демон зелёные. doc/TCI.md §2.5 и сводка стенда, doc/CAT_STATUS.md — таблица разбора. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+6
-2
@@ -2999,6 +2999,7 @@ var
|
||||
Rx, Sec, Rate: Integer;
|
||||
Path, Req: string;
|
||||
Data: TTCIPcm;
|
||||
Held: Int64; // байты бюджета, уходящие писателю вместе с Data
|
||||
Old, New_: TTCIRecorder;
|
||||
begin
|
||||
if not TCITryArgInt(M, 0, Rx) or not ValidRx(Rx) then
|
||||
@@ -3085,6 +3086,7 @@ begin
|
||||
// потом снимаем с него данные: копия кольца — это десятки мегабайт, и делать
|
||||
// её под локом DSP-потока нельзя.
|
||||
Data := nil;
|
||||
Held := 0;
|
||||
Rate := TCI_AUDIO_ENGINE_RATE;
|
||||
FStreamLock.Enter;
|
||||
try
|
||||
@@ -3095,7 +3097,9 @@ begin
|
||||
end;
|
||||
if Old <> nil then
|
||||
begin
|
||||
Data := Old.Take;
|
||||
// ★Резерв бюджета переезжает вместе с данными: копию держит писатель, и
|
||||
// отпустит её он же. Иначе SAVE был бы дырой в потолке памяти.
|
||||
Data := Old.Take(Held);
|
||||
Rate := Old.Rate;
|
||||
Old.Free;
|
||||
end;
|
||||
@@ -3106,7 +3110,7 @@ begin
|
||||
end;
|
||||
// Пишет отдельный поток: файл может быть в десятки мегабайт, а мы сейчас в
|
||||
// потоке клиента, который в это время не читает свой сокет.
|
||||
TTCIWavWriter.Create(Path, Data, Rate);
|
||||
TTCIWavWriter.Create(Path, Data, Rate, Held);
|
||||
end;
|
||||
|
||||
procedure TTCIAdapter.DropClientRecorders(C: TTCIClient);
|
||||
|
||||
Reference in New Issue
Block a user