docs(slices): mark Stages 1+2 done, record what shipped

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 23:51:12 +03:00
co-authored by Claude Opus 4.8
parent 1527b0f849
commit a53c12b5aa
+35 -6
View File
@@ -1,9 +1,38 @@
# Мультислайсы (несколько приёмных фильтров, как во FlexRadio) # Мультислайсы (несколько приёмных фильтров, как во FlexRadio)
Статус: **план; UI-каркас флага слайса уже сделан** (см. «Что уже готово»), Статус: **Этапы 1 + 2 РЕАЛИЗОВАНЫ и ЗАКОММИЧЕНЫ** (ветка `feature/multislice`,
DSP/роутинг (Этапы 1/3) — не начаты. Ничего не коммитить без явной просьбы. коммит `1527b0f`; проверено на эфире). Этап 3 (аппаратные DDC для слайса вне
захваченной полосы) — не начат. Ниже: что вошло по факту + дизайн/остаток.
## Что уже готово ## Что реализовано (Этапы 1 + 2)
- **WDSPEngine** — софтовый fan-out: `TSliceChan` + `FSlices[0..MAX_SLICES-1]`
(`MAX_SLICES=6`), свои WDSP-каналы (`SLICE_CHAN_BASE=2`), `ProcessSlices` в
DSP-потоке (свежая копия IQ на канал, свой NCO/mode/filter/AGC/NR/NB/SNB/ANF +
S-метр → `OnSliceAudio`), `FSliceLock` сериализует add/remove/set vs DSP,
переоткрытие после смены sample rate.
- **RadioController** — `TCtrlSlice` (абс. `TargetHz`, буква, свой `TAudioOutput`/
звуковуха), `Add/Remove/SetSlice*`, `RefreshSliceShifts` держит слайсы на
`TargetHz` при смене центра, гейт `SliceFitsCapture` (вне полосы = Этап 3).
Буквы доп. слайсов начинаются с `'B'` (A = главный приёмник).
- **UI** — по флагу `TVfoOverlay` на слайс (буква-бейдж, «×», fly-out MODE/DSP/AUD,
vol/mute/split/TX, S-метр), маркеры полосы фильтра слайса в **обоих** рендерерах
(GL `DrawSliceFilterMarkers` + CPU), drag-ретюн несущей, колесо над флагом,
позиционирование СБОКУ от полосы фильтра с флипом (как у главного флага).
Ctrl+ЛКМ по спектру = добавить слайс. Флаг главного (A) виден когда скрыта
левая панель ЛИБО есть слайсы B+ (синхронизируется с правками с левой панели).
- **Перф** — S-метр развязан с кэшем «хрома» флага (`FMeterDirty` + meter-only
`RefreshMeter` через `EnsureRendered`); `InvalidateVfoOverlay` не дёргает
глобальный перезалив оверлеев на тик метра.
Остаток/риски (не сделано): персист слайсов в `Settings` (список + устройство);
per-slice AGC-Top (сейчас общий с главным); полноценный мультислайс-TX (пока TX
только главный); Этап 3 (HW DDC). Исходный план/дизайн — ниже без изменений.
## Предыстория (UI-каркас до мультислайса — исторично)
> Ниже — состояние ДО реализации Этапа 2 (одиночный флаг, захардкоженная `'A'`).
> Актуальное состояние см. в «Что реализовано» выше. Оставлено как контекст.
`VfoOverlay.pas` переделан в **«флаг слайса»** в стиле SmartSDR (6 коммитов `VfoOverlay.pas` переделан в **«флаг слайса»** в стиле SmartSDR (6 коммитов
`4a92256..a04c592`, уже в `main`). Это ровно UI-управление одним слайсом из `4a92256..a04c592`, уже в `main`). Это ровно UI-управление одним слайсом из
@@ -92,7 +121,7 @@ end;
## Порядок работ ## Порядок работ
### Этап 1 — Софтовый fan-out в WDSPEngine (backend-agnostic) ### Этап 1 — Софтовый fan-out в WDSPEngine (backend-agnostic) ✅ РЕАЛИЗОВАН
Даёт слайсы сразу на Pluto/QO-100 (единственный режим) и на HPSDR для слайсов Даёт слайсы сразу на Pluto/QO-100 (единственный режим) и на HPSDR для слайсов
внутри видимой полосы. Pluto уже пушит IQ через тот же DDC-конвейер, поэтому внутри видимой полосы. Pluto уже пушит IQ через тот же DDC-конвейер, поэтому
@@ -117,7 +146,7 @@ fan-out живёт в движке и не зависит от бэкенда.
Проверка Этапа 1: Pluto/QO-100 — 2 слайса (VFO + маяк-монитор), звук в две разные Проверка Этапа 1: Pluto/QO-100 — 2 слайса (VFO + маяк-монитор), звук в две разные
звуковухи, независимые режимы/полосы. Сборка: `lazbuild --ws=qt6 ewsdr.lpr`. звуковухи, независимые режимы/полосы. Сборка: `lazbuild --ws=qt6 ewsdr.lpr`.
### Этап 2 — UI слайсов на водопаде + выбор устройства ### Этап 2 — UI слайсов на водопаде + выбор устройства ✅ РЕАЛИЗОВАН (кроме персиста)
Каркас флага слайса уже сделан (см. «Что уже готово»): один `TVfoOverlay` со всеми Каркас флага слайса уже сделан (см. «Что уже готово»): один `TVfoOverlay` со всеми
пикерами и per-flag выбором устройства. Остаётся размножить его на N слайсов и пикерами и per-flag выбором устройства. Остаётся размножить его на N слайсов и
@@ -143,7 +172,7 @@ fan-out живёт в движке и не зависит от бэкенда.
- Персист: список слайсов в `Settings.pas` (per-band или глобально — решить), включая - Персист: список слайсов в `Settings.pas` (per-band или глобально — решить), включая
`DeviceIndex`/имя устройства каждого флага. `DeviceIndex`/имя устройства каждого флага.
### Этап 3 — Аппаратные DDC для openHPSDR (слайс куда угодно по КВ) ### Этап 3 — Аппаратные DDC для openHPSDR (слайс куда угодно по КВ) ⏳ НЕ НАЧАТ
Апгрейд поверх общего каркаса; нужен только чтобы ставить слайс ВНЕ захваченной Апгрейд поверх общего каркаса; нужен только чтобы ставить слайс ВНЕ захваченной
полосы. Плита ~на 70% есть: полосы. Плита ~на 70% есть: