mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
feat(pans): выбор аппаратного DDC для панадаптера
Клик по «NNN kHz · DDCn» в шапке пана — кроме сетки rate теперь есть пункты «→ DDC N»: пан переезжает на другой аппаратный DDC (MovePanDDC), при этом движок, анализатор и слайсы не пересоздаются — перепрошивается только hw-индекс. Пригодилось при отладке: конкретный DDC платы может вести себя хуже соседей, и пан можно просто увести на другой. Диапазон ограничен реальными DDC железа: MaxDDCIndex = 7 (DDC8+ openHPSDR enable-бит принимает, но поток не отдаёт). Ограничение действует и в меню, и в DDCFree, и в самом MovePanDDC. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -596,6 +596,13 @@ type
|
||||
// Смена rate живого пана: движок переоткрывает аккумулятор/анализатор/слайсы,
|
||||
// DDC реконфигурируется; слайсы вне новой полосы клампятся к её краям.
|
||||
function SetPanDDCRate(PanId: Integer; RateKHz: Word): Boolean;
|
||||
// Переезд пана на другой аппаратный DDC (пан/слайсы/движок не пересоздаются,
|
||||
// меняется только hw-индекс): бывает, что конкретный DDC платы ведёт себя
|
||||
// хуже соседей — тогда пан можно просто увести на другой.
|
||||
function MovePanDDC(PanId, NewDDC: Integer): Boolean;
|
||||
function PanDDCIndex(PanId: Integer): Integer; // hw-индекс DDC пана
|
||||
function MaxDDCIndex: Integer; // последний DDC железа
|
||||
function DDCFree(DDCIdx: Integer): Boolean; // индекс свободен?
|
||||
function PanDDCActive(PanId: Integer): Boolean;
|
||||
function PanDDCFreq(PanId: Integer): Double;
|
||||
function PanDDCRateKHz(PanId: Integer): Word;
|
||||
@@ -1311,6 +1318,53 @@ begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TRadioController.MovePanDDC(PanId, NewDDC: Integer): Boolean;
|
||||
// Тот же пан (движок/анализатор/слайсы не трогаем) — только другой аппаратный
|
||||
// DDC: старый гасим, новый включаем с теми же freq/rate/ADC. Короткий разрыв IQ
|
||||
// на время реконфига — норма.
|
||||
begin
|
||||
Result := False;
|
||||
if not PanDDCActive(PanId) then Exit;
|
||||
if not Assigned(FNetwork) then Exit;
|
||||
if (NewDDC <= FActiveDDC) or (NewDDC > MaxDDCIndex) then Exit;
|
||||
if FPanDDCIdx[PanId] = NewDDC then Exit(True);
|
||||
if FDDCPanMap[NewDDC] >= 0 then Exit; // занят другим паном
|
||||
|
||||
FNetwork.SetPanDDC(FPanDDCIdx[PanId], False, 0, 0, 0);
|
||||
FDDCPanMap[FPanDDCIdx[PanId]] := -1;
|
||||
// Seq-трекинг обоих индексов начинаем заново (новый поток — новый счётчик).
|
||||
if FPanDDCIdx[PanId] <= High(FDDCSeqValid) then
|
||||
FDDCSeqValid[FPanDDCIdx[PanId]] := False;
|
||||
if NewDDC <= High(FDDCSeqValid) then
|
||||
FDDCSeqValid[NewDDC] := False;
|
||||
|
||||
FPanDDCIdx[PanId] := NewDDC;
|
||||
FDDCPanMap[NewDDC] := PanId;
|
||||
FNetwork.SetPanDDC(NewDDC, True, XvtrTranslate(FPanFreqHz[PanId]),
|
||||
FPanRateKHz[PanId], FPanADC[PanId]);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TRadioController.PanDDCIndex(PanId: Integer): Integer;
|
||||
begin
|
||||
if (PanId >= 1) and (PanId < MAX_PANS) then Result := FPanDDCIdx[PanId]
|
||||
else if PanId = 0 then Result := FActiveDDC
|
||||
else Result := -1;
|
||||
end;
|
||||
|
||||
function TRadioController.MaxDDCIndex: Integer;
|
||||
// Железо openHPSDR (Orion/Saturn) поднимает DDC0..DDC7 — DDC8 и выше молчат
|
||||
// (проверено на плате: enable-бит ставится, поток не идёт).
|
||||
begin
|
||||
Result := 7;
|
||||
end;
|
||||
|
||||
function TRadioController.DDCFree(DDCIdx: Integer): Boolean;
|
||||
begin
|
||||
Result := (DDCIdx > FActiveDDC) and (DDCIdx <= MaxDDCIndex)
|
||||
and (FDDCPanMap[DDCIdx] < 0);
|
||||
end;
|
||||
|
||||
procedure TRadioController.RemovePanDDC(PanId: Integer);
|
||||
var ddc, i: Integer;
|
||||
begin
|
||||
|
||||
Reference in New Issue
Block a user