mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
feat(slices): независимый rate панадаптеров (селектор в шапке)
- Создание пана: rate наследуется от главного с клампом ≤768к (вне сетки → 384к); за сменой rate главного паны не следуют - Клик по «NNN kHz» в шапке пана N → меню полной сетки железа (PanRateAllowed = Caps.RatePresets ∩ кратные 48 кГц; захардкоженный PAN_DDC_RATES удалён) - WDSPEngine.SetPanRate: под FSliceLock пересбор аккумулятора/анализатора пана + переоткрытие слайс-каналов на новом rate (state сохраняется) - RadioController.SetPanDDCRate: движок → реконфиг DDC (SetPanDDC) → кламп слайсов к новой полосе; FPanADC[] хранится (база под 3.4) - Шапка: rate отдельным лейблом (у панов N кликабелен, акцент/рука) Смоук-тест без железа ALL PASS (тон: спектр+аудио слайса живы через 384→192→768). Проверено юзером на экране. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -509,6 +509,9 @@ type
|
||||
function AddPan(PanId, RateHz: Integer): Boolean;
|
||||
// Убирает пан вместе с его слайсами (аудио-выходы слайсов — забота вызывающего).
|
||||
procedure RemovePan(PanId: Integer);
|
||||
// Смена rate живого пана: пересбор аккумулятора/анализатора + переоткрытие
|
||||
// WDSP-каналов его слайсов на новом входном rate (state слайсов сохраняется).
|
||||
function SetPanRate(PanId, RateHz: Integer): Boolean;
|
||||
function PanActive(PanId: Integer): Boolean;
|
||||
|
||||
// --- Мультислайсы (софт-fan-out) ---
|
||||
@@ -2220,6 +2223,41 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWDSPEngine.SetPanRate(PanId, RateHz: Integer): Boolean;
|
||||
var s: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
if (PanId < 1) or (PanId >= MAX_PANS) then Exit;
|
||||
// Те же требования кратности, что в AddPan.
|
||||
if (RateHz < FAudioRate) or (RateHz mod FAudioRate <> 0) then Exit;
|
||||
FSliceLock.Enter;
|
||||
try
|
||||
if not FPans[PanId].Active then Exit;
|
||||
if FPans[PanId].Rate = RateHz then Exit(True);
|
||||
// Анализатор держит старый rate — снести до пересбора аккумулятора.
|
||||
DestroyPanAnalyzer(PanId);
|
||||
FPans[PanId].Rate := RateHz;
|
||||
FPans[PanId].BufSize := FAudioBufSize * (RateHz div FAudioRate);
|
||||
SetLength(FPans[PanId].AccI, FPans[PanId].BufSize);
|
||||
SetLength(FPans[PanId].AccQ, FPans[PanId].BufSize);
|
||||
FPans[PanId].AccPos := 0;
|
||||
FPans[PanId].DispPos := 0;
|
||||
AllocSliceBuffers; // FSliceIn/Out под новый макс. блок
|
||||
if FAnalyzerOpen then CreatePanAnalyzer(PanId);
|
||||
// Слайсы пана: их каналы открыты с InRate/InSize пана — переоткрываем
|
||||
// (OpenSliceChannel восстанавливает mode/filter/AGC/DSP из записи слайса).
|
||||
for s := 0 to MAX_SLICES - 1 do
|
||||
if FSlices[s].Active and (FSlices[s].PanId = PanId) then
|
||||
begin
|
||||
CloseSliceChannel(s);
|
||||
OpenSliceChannel(s);
|
||||
end;
|
||||
Result := True;
|
||||
finally
|
||||
FSliceLock.Leave;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWDSPEngine.PanActive(PanId: Integer): Boolean;
|
||||
begin
|
||||
Result := (PanId >= 1) and (PanId < MAX_PANS) and FPans[PanId].Active;
|
||||
|
||||
Reference in New Issue
Block a user