mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
perf(tr): устранение GUI-фриза ~100мс на TX→RX (живой TX-DSP поток)
TX-DSP поток (TTXDSPThread) больше не пересоздаётся на каждом T/R — он
создаётся один раз и живёт весь сеанс, на приём/передачу переключается
флагом FTXActive (поток при False просто Continue, не трогает канал/ring).
Тердаун перенесён в TWDSPEngine.Close. Раньше Terminate+WaitFor+Free на
каждом отпускании PTT давал фиксированные ~100мс пустого join-оверхеда
pthread_join, блокируя GUI-поток. Итог: 206→106мс, крупные фризы ушли.
Остаток ~106мс = плавный WDSP fade-out TXA (SetChannelState dmode=1) —
оставлен как есть (dmode=0 дал бы trailing key-click в эфир).
Попутно:
- MainForm: убраны прямые PbSpectrum.Invalidate из drag/wheel VFO/центра —
кадр рисует таймер по FSpectrumDirty (FPS-гейт; прямой Invalidate давал
GL-кадр на каждое событие мыши мимо гейта → треск в HDMI-звуке AMD APU).
- AudioOutput: const-секция после {$ENDIF} блока PA-констант.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+22
-18
@@ -1259,6 +1259,17 @@ begin
|
||||
FreeAndNil(FDSPThread);
|
||||
end;
|
||||
|
||||
// TX-DSP поток живёт весь сеанс (не пересоздаётся на T/R) — гасим его здесь,
|
||||
// до закрытия WDSP-каналов (он зовёт fexchange0 на TXA_CHAN).
|
||||
FTXActive := False;
|
||||
if Assigned(FTXThread) then
|
||||
begin
|
||||
FTXThread.Terminate;
|
||||
RTLEventSetEvent(FTXMicSem);
|
||||
FTXThread.WaitFor;
|
||||
FreeAndNil(FTXThread);
|
||||
end;
|
||||
|
||||
// Закрываем WDSP-каналы слайсов (записи FSlices сохраняем — переоткроются в Open).
|
||||
FSliceLock.Enter;
|
||||
try
|
||||
@@ -2130,37 +2141,30 @@ end;
|
||||
|
||||
procedure TWDSPEngine.SetTXRun(Run: Boolean);
|
||||
begin
|
||||
FTXActive := Run;
|
||||
FDispPos := 0;
|
||||
FTXDispPos := 0;
|
||||
if Run then
|
||||
FActiveDisplayID := TX_DISP_ID
|
||||
else
|
||||
FActiveDisplayID := RX_DISP_ID;
|
||||
|
||||
if Run then
|
||||
begin
|
||||
if FInitialized then
|
||||
SetChannelState(TXA_CHAN, 1, 0); // run, no delay
|
||||
// Сброс mic ring buffer и запуск TX потока
|
||||
FActiveDisplayID := TX_DISP_ID;
|
||||
// Сброс mic ring ДО активации, чтобы простаивавший поток не прочитал старое.
|
||||
FTXMicHead := 0;
|
||||
FTXMicTail := 0;
|
||||
if FInitialized then
|
||||
SetChannelState(TXA_CHAN, 1, 0); // run, no delay
|
||||
// TX-DSP поток создаётся ОДИН раз и живёт весь сеанс. НЕ пересоздаём на каждом
|
||||
// T/R: join (WaitFor) давал фиксированные ~100 мс фриза GUI на отпускании PTT.
|
||||
// При FTXActive=False поток простаивает (см. TTXDSPThread.Execute: Continue).
|
||||
if not Assigned(FTXThread) then
|
||||
begin
|
||||
FTXThread := TTXDSPThread.Create(Self);
|
||||
FTXThread.Priority := tpHighest;
|
||||
end;
|
||||
FTXActive := True; // активируем последним
|
||||
end else begin
|
||||
FTXActive := False; // поток уходит в простой (не трогает канал/ring)
|
||||
FActiveDisplayID := RX_DISP_ID;
|
||||
if FInitialized then
|
||||
SetChannelState(TXA_CHAN, 0, 1); // stop, with slew
|
||||
// Останавливаем TX поток
|
||||
if Assigned(FTXThread) then
|
||||
begin
|
||||
FTXThread.Terminate;
|
||||
RTLEventSetEvent(FTXMicSem);
|
||||
FTXThread.WaitFor;
|
||||
FreeAndNil(FTXThread);
|
||||
end;
|
||||
SetChannelState(TXA_CHAN, 0, 1); // stop, with slew (поток уже idle)
|
||||
FTXMicHead := 0;
|
||||
FTXMicTail := 0;
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user