- Создание пана: 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>
Несколько панадаптеров в главном окне (кнопка «⊞», до MAX_PANS):
- TPanafallPanel: регион в стеке (StackTop/Height), шапка с «×»,
pan-aware ViewWindow, FirstSliceId; явный crArrow GL-канвам
(WA_NativeWindow-поверхность на Wayland навсегда наследует курсор
момента создания — прилипала «рука» кнопки «⊞»)
- MainForm: FPans[]/LayoutPanStack (доли + межпанные сплиттеры с живым
призраком), создание/закрытие панов (DDC+слайс+вьюха), пиксели панов
из display-потока под FPanCbLock, рендер по dirty в тике
- Мышь панов N: Ctrl+ЛКМ = слайс, drag маркера = ретюн слайса,
drag фона = live-ретюн DDC (гистерезис 4px), клик = тюн слайса пана
(PanClickTune, снап 100 Гц), флаг-диспетчер только на спектре
- Сплиттер спектр/водопад: drag-математика от региона пана
(FSplitTopOff/FSplitAvailH из Layout), OnSplitterMoved у панов N
- Паны живут в Run-сессии, умирают на STOP
Проверено юзером на экране (3 раунда фидбека) + e2e против hpsdrsim.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- общая IQ-очередь с TIQQueueItem.PanId (64→256 слотов); DSP-поток
диспетчеризует пан-пакеты в PushPanItemToDSP: декод, feed анализатора
PAN_DISP_BASE+PanId, аккумулятор, ProcessSlicesFor(PanId) под FSliceLock
- пан-анализаторы: Create/DestroyPanAnalyzer + ApplyPanAnalyzerSettings
(rate пана, без зума — пан-зум в 3.3+), живут в OpenAnalyzer/CloseAnalyzer,
общие настройки дисплея перекатываются (ReapplyPanDisplaySettings)
- слайсы в панах: TSliceChan.PanId, AddSlice(..., APanId), OpenSliceChannel
от rate/блока своего пана, SliceDSPRateFor (WFM от rate пана); блок пана
= FAudioBufSize*Rate/FAudioRate => аудио-блок слайсов неизменен
- выдача пикселей: OnPanSpectrum/OnPanWaterfall(PanId,...) из display-потока,
GetPixels пана под FSliceLock, колбэки вне лока
- MAX_PANS=4 переехал в WDSPEngine (единый движок/контроллер/UI)
- контроллер: AddPanDDC создаёт пан в движке до включения DDC, RemovePanDDC
убирает слайсы (со звуковухами)+движок+DDC, гейт/NCO слайсов от центра
своего пана, ретюн пана двигает его слайсы
- смоук-тест на libwdsp без железа ALL PASS: пик спектра пана точно на месте,
слайс пана выдал 1 кГц RMS 0.68, главный тракт жив, RemovePan чисто
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- TBackendCaps: MaxPans/IndependentPanFreq (HPSDR 4/True, Pluto 1/False);
SetPanDDC/SetPanDDCFreq — виртуальные no-op в TRadioBackend
- HPSDRNetwork: ConfigureDDCs → кэш главного DDC + RebuildDDCSpecific
(главный + активные пан-DDC, каждый со своим rate/ADC); SendFullHP пишет
частотные слова всех активных пан-DDC; хелпер DDCBaseIndex; сброс
пан-состояния в Connect
- RadioController: MAX_PANS=4, PAN_DDC_RATES 192/384/768; AddPanDDC/
RemovePanDDC/SetPanDDCFreq/PanDDC* (аллокатор hw-индексов от FActiveDDC+1,
обратный маппинг FDDCPanMap); OnDDCIQ роутит пан-DDC → PushPanIQ;
паны гасятся в StopRunning, пул сбрасывается в StartRunning
- WDSPEngine: PushPanIQ — заглушка-дроп (аккумулятор/анализатор — этап 3.2)
- фикс: StartRunning не включал Saturn (BoardType 10) в список плат с
DDCBase=2 — на Saturn гейт FActiveDDC ждал бы IQ с DDC0
- doc/SLICES_PLAN.md: статус 3.1 + B1 проверена на экране
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Record grounded data-path analysis, per-DDC/RX2 deltas, the soft-vs-hard
WDSP channel split, preliminary decisions (4-6 hard DDCs, static first),
and the UI concept (edge markers, slices rail, ADC badge). Marked as a
work-in-progress draft.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Independent RX slices sharing one panadapter: each has its own
freq/mode/filter/AGC/NR-NB-SNB-ANF, S-meter, volume and sound card.
VFO A = main receiver; B+ are soft fan-out WDSP channels within the
captured span (ideal for Pluto/QO-100; HW DDC path is Stage 3).
- WDSPEngine: soft fan-out (TSliceChan, ProcessSlices in DSP thread,
per-slice NCO/mode/filter/AGC/NR/NB/SNB/ANF + S-meter, OnSliceAudio),
FSliceLock serialises add/remove/set vs DSP; reopened on rate change.
- RadioController: TCtrlSlice with its own TAudioOutput/device,
Add/Remove/SetSlice*, RefreshSliceShifts keeps slices on target Hz
across centre changes. Slice letters start at 'B' (A = main receiver).
- UI: per-slice flags (VfoOverlay) with letter badge/close, filter-band
markers in BOTH GL and CPU renderers, drag-retune, wheel; flags placed
beside the filter band with flip, like the main flag. Ctrl+click adds.
- Main flag (slice A) visible whenever the left panel is hidden OR any
slice exists; synced with panel-driven DSP/mode/AGC changes.
- Perf: S-meter decoupled from flag chrome cache (FMeterDirty +
meter-only RefreshMeter via EnsureRendered); InvalidateVfoOverlay
avoids global overlay-cache churn on meter ticks.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>