소스 검색

feat: document WS-03 parameters and align outputDrive validation

tags/v0.9.0
Jan Svabenik 1 개월 전
부모
커밋
c888186e30
4개의 변경된 파일129개의 추가작업 그리고 15개의 파일을 삭제
  1. +18
    -12
      docs/pro-runtime-hardening-workboard.md
  2. +108
    -0
      docs/ws-03-parameter-inventory.md
  3. +2
    -2
      internal/app/engine.go
  4. +1
    -1
      internal/app/engine_test.go

+ 18
- 12
docs/pro-runtime-hardening-workboard.md 파일 보기

@@ -82,7 +82,7 @@ Kein „ist im Kopf klar“. Der Stand kommt hier rein.

# WS-03 — Semantische Korrektheit und harte Config-/Runtime-Konsistenz
**Priorität:** P0
**Gesamtstatus:** TODO
**Gesamtstatus:** IN PROGRESS

## Ziel
Ein einziger, eindeutig definierter Parameterraum. Jeder Wert hat exakt eine Bedeutung und identische Constraints in Config, HTTP-API, Runtime und Telemetrie.
@@ -93,13 +93,13 @@ Wenn Semantik und Grenzwerte nicht sauber vereinheitlicht sind, bauen spätere R
## Aufgaben

### WS-03-T1 — Parameterinventar erstellen
- **Status:** TODO
- **Owner:** offen
- **Status:** VERIFIED
- **Owner:** Builder A
- **Code-Orte:**
- `internal/config/config.go`
- `internal/app/engine.go`
- `internal/control/control.go`
- ggf. weitere betroffene Pakete
- `internal/offline/generator.go`
- **Ziel:**
Alle öffentlich und intern verwendeten Parameter inventarisieren mit:
- Name
@@ -114,25 +114,27 @@ Wenn Semantik und Grenzwerte nicht sauber vereinheitlicht sind, bauen spätere R
- Wo leben heute implizite Parameter, die nicht sauber dokumentiert sind?
- Welche Runtime-Werte sind abgeleitet statt direkt konfigurierbar?
- **Nachweis:**
- Parameterinventar im Repo vorhanden
- referenzierbar für Config/API/Runtime
- `docs/ws-03-parameter-inventory.md` enthält das inventarisierte Parameter-Tableau und referenziert Config/Control/Engine.
- Live-Nutzung über `internal/control/control.go` → `LivePatch` dokumentiert.
- **Restrisiken:**
- versteckte Semantik in Helper-Funktionen übersehen

### WS-03-T2 — Validation vereinheitlichen
- **Status:** TODO
- **Owner:** offen
- **Status:** VERIFIED
- **Owner:** Builder A
- **Code-Orte:**
- `internal/config/config.go`
- `internal/app/engine.go`
- `internal/app/engine_test.go`
- `internal/control/control.go`
- **Ziel:**
`Config.Validate()`, Runtime-Update-Pfade und API-Patch-Validierung dürfen nicht divergieren.
- **Bereits bekannter Startpunkt:**
- `fm.outputDrive`
- **Nachweis:**
- bekannte Inkonsistenzen beseitigt
- Tests für gemeinsame Grenzwerte vorhanden
- CFG-SEM-001: `outputDrive`-Validation in `Engine.UpdateConfig` jetzt 0..10 (wie `Config.Validate`).
- Tests (`go test ./...`) fangen neue Range ab und besitzen aktualisierten `engine_test`-Check.
- Live-Patch fließt durch `txBridge` und `LivePatch` (control) → `LiveConfigUpdate`.
- **Restrisiken:**
- weitere Inkonsistenzen erst beim Inventar sichtbar

@@ -155,10 +157,14 @@ Wenn Semantik und Grenzwerte nicht sauber vereinheitlicht sind, bauen spätere R
- unsaubere Migration bestehender Statusantworten

## WS-03 Entscheidungslog
- Noch leer
| Datum | Entscheidung | Notiz |
|---|---|---|
| 2026-04-05 | CFG-SEM-001: `fm.outputDrive` | Live-Validierung auf 0..10 angeglichen, Tests angepasst, Parameterinventar dokumentiert. |

## WS-03 Verifikation
- Noch leer
| Datum | Fokus | Ergebnis |
|---|---|---|
| 2026-04-05 | `go test ./...` | ✅ Bestätigt `Engine.UpdateConfig`, `LivePatch` und Parameter-Range sowie Inventar-Dokumentation. |

---



+ 108
- 0
docs/ws-03-parameter-inventory.md 파일 보기

@@ -0,0 +1,108 @@
# WS-03 Parameterinventar — Semantik & Runtime-Konsistenz

> Repo-grounded Übersicht der öffentlich sichtbaren und runtime-relevanten Parameter aus `internal/config`, `internal/control`, `internal/app/engine` und dem HTTP-API-Stack.

## Ziel

Dieses Dokument liefert einen festen Referenzpunkt für WS-03:
1. Welche Parameter konfiguriert werden können (JSON + CLI + HTTP).
2. Welche Wertebereiche und Einheiten sie haben.
3. Welche davon live per HTTP-Patch übernommen werden.
4. Wo im Code die Validierung, Anwendung und Telemetrie lebt.

Alle Angaben beziehen sich direkt auf die `Config`-Definition (`internal/config/config.go`), den Control-Server (`internal/control/control.go`) und die Engine-Live-Updates (`internal/app/engine.go`, `internal/offline/generator.go`).

---

## 1. Control-Plane & Backend (requires restart)

| Parameter | Typ | Default | Range / Einheit | Hot reload | Beschreibung & Code-Referenzen |
|---|---|---|---|---|---|
| `control.listenAddress` | `string` | `"127.0.0.1:8088"` | `<host>:<port>` | ❌ (Server-Neustart) | HTTP-Server-Bindadresse, `cmd/fmrtx/main.go` startet Listen mit `cfg.Control.ListenAddress`. |
| `backend.kind` | `string` | `"file"` | `file` / `pluto` / `soapy` | ❌ | Wahl des TX-Backends; `selectDriver` (cmd/fmrtx/main.go) entscheidet darauf basierend. |
| `backend.device` | `string` | `""` | SoapySDR/Pluto device string | ❌ | Wird an `platform.SoapyConfig.Device` weitergegeben. |
| `backend.deviceSampleRateHz` | `float64` | `0` | >0 Hz (0 = fallback auf `fm.compositeRateHz`) | ❌ | Treibt `cfg.EffectiveDeviceRate()` und damit Treiber-Konfiguration (`cmd/fmrtx/main.go`). |
| `backend.uri` / `deviceArgs` | `string` / `map[string]string` | `""` / `nil` | Driver-spezifisch | ❌ | Zusätzliche Soapy-Parameter, weitergereicht an `platform.SoapyConfig`. |

> `backend.*` dürfen zur Konfiguration gepatcht werden, gelten aber erst nach Neustart des TX-Modus.

---

## 2. Audio-Quelle (reload requires restart)

| Parameter | Typ | Default | Range | Hot reload | Referenzen |
|---|---|---|---|---|---|
| `audio.inputPath` | `string` | `""` | Pfad zu WAV-Dateien | ❌ | `offline/generator.sourceFor` entscheidet, ob WAV oder interne Töne genutzt werden; `audio.LoadWAVSource`. |
| `audio.gain` | `float64` | `1.0` | `0..4` | ❌ | Verstärkt vor Pre-Emphasis (`generator.NewPreEmphasizedSource`, `docs/DSP-CHAIN.md`). |
| `audio.toneLeftHz`, `toneRightHz` | `float64` | `1000`, `1600` | >0 Hz | ❌ | Fallback-Tonquelle (`audio.NewConfiguredToneSource`). |
| `audio.toneAmplitude` | `float64` | `0.4` | `0..1` | ❌ | Amplitude der internen Töne, skaliert vor DSP. |

Diese Parameter sind nur im JSON/HTTP-Config sichtbar, aber nicht live per `LiveConfigUpdate` (keine `LivePatch`-Felder). Ein Restart der TX-Engine ist nötig.

---

## 3. FM-DSP Parameter (häufig hot-reloadable)

| Parameter | Typ | Default | Range / Einheit | Hot reload | Beschreibung & Code-Referenzen |
|---|---|---|---|---|---|
| `fm.frequencyMHz` | `float64` | `100.0` | `65..110` MHz | ✅ (LivePatch → Engine.UpdateConfig) | Ruft `Engine.pendingFreq` auf, `driver.Tune` wird zwischen Chunks ausgeführt (`internal/app/engine.go`, `control.LivePatch`). |
| `fm.outputDrive` | `float64` | `0.5` | `0..10` (empfohlen `1..4`) | ✅ | Multiplikator vor Limiter/Klipps (`generator.GenerateFrame`, `docs/DSP-CHAIN.md`). Validierung: `internal/config/config.go` + `Engine.UpdateConfig` (CFG-SEM-001 behoben, nun 0..10). |
| `fm.stereoEnabled` | `bool` | `true` | — | ✅ | Schaltet Stereo-Encode und Pilot (Intern `offpkg.Generator`). |
| `fm.pilotLevel` | `float64` | `0.09` | `0..0.2` (9% ±75 kHz) | ✅ | Pilot-Addition nach Composite-Clipper (`generator.GenerateFrame`). |
| `fm.rdsInjection` | `float64` | `0.04` | `0..0.15` | ✅ | RDS-Träger am Ende der Kette (`generator.GenerateFrame`). |
| `fm.preEmphasisTauUS` | `float64` | `50` | `0` / `50` / `75` µs | ❌ | Pre-Emphasis-Filter vor Tonquelle (`NewPreEmphasizedSource`). |
| `fm.limiterEnabled` | `bool` | `true` | — | ✅ | Aktiviert StereoLimiter (`dsp.NewStereoLimiter`). |
| `fm.limiterCeiling` | `float64` | `1.0` | `0..2` | ✅ | Maximalwert für Clips und Composite Sättigung. |
| `fm.bs412Enabled` | `bool` | `false` | — | ❌ | Optionaler ITU-R BS.412 MPX Power Limiter (`dsp.NewBS412Limiter`). |
| `fm.bs412ThresholdDBr` | `float64` | `0` | beliebig (dBr) | ❌ | Grenzwert für BS.412-Limiter. |
| `fm.mpxGain` | `float64` | `1.0` | `0.1..5` | ❌ | Hardware-Calibration für effective Deviation (`generator.init`, `FMModulator`). |
| `fm.maxDeviationHz` | `float64` | `75000` | `0..150000` Hz | ❌ | Steuert `FMModulator.MaxDeviation`. |
| `fm.compositeRateHz` | `int` | `228000` | — | ❌ | Setzt DSP-Sample-Rate, beeinflusst `generator` + `Engine` (`cfg.EffectiveDeviceRate`). |
| `fm.fmModulationEnabled` | `bool` | `true` | — | ❌ | Schaltet `dsp.FMModulator`; beim Split-Rate-Modus wird es automatisch deaktiviert. |

> Hot-reload-fähige Felder kommen in `LiveConfigUpdate`. Parameter wie `preEmphasisTauUS`, `bs412*`, `mpxGain` bleiben nur nach Neustart gültig und können via `/config` gepatched werden, aber nicht live übernommen.

---

## 4. RDS & Telemetrie

| Parameter | Typ | Default | Range | Hot reload | Beschreibung |
|---|---|---|---|---|---|
| `rds.enabled` | `bool` | `true` | — | ✅ | Aktiviert Encoder und Telemetrie (`generator.init`). |
| `rds.pi` | `string` | `"1234"` | Hex, 4 Zeichen | ❌ | Validierung `ParsePI`. |
| `rds.ps` | `string` | `"FMRTX"` | max 8 Zeichen | ✅ | Realtime-Update via `rdsp.UpdateText`. |
| `rds.radioText` | `string` | `"fm-rds-tx"` | max 64 Zeichen | ✅ | Text wird an Encoder weitergereicht. |
| `rds.pty` | `int` | `0` | `0..31` | ❌ | Wird nur bei Init in Encoder gesetzt. |

Telemetrie: `/status` (control) meldet `rdsEnabled`, `pilotLevel`, `limiterEnabled` u.a. (`internal/control/control.go`).

---

## 5. Hot-Update-Fluss

1. `POST /config` (`internal/control.control.go`) aktualisiert das Snapshot-Config und validiert mit `Config.Validate()`.
2. Für die Live-fähigen Parameter (⇓) wird ein `LivePatch` erstellt.
3. `TXController.UpdateConfig` (z.B. `txBridge`) übersetzt in `LiveConfigUpdate` und ruft `Engine.UpdateConfig`.
4. `Engine` validiert identische Bereiche (jetzt 0..10 für `outputDrive`) und schreibt in Generator-Live-Params.
5. Änderungen werden zwischen Chunks angewendet (`pendingFreq`, `generator.UpdateLive`).

| Live-Feld | Code-Quellen |
|---|---|
| `frequencyMHz` | `LiveConfigUpdate`, `Engine.pendingFreq`, `driver.Tune` |
| `outputDrive` | `Generator.LiveParams.OutputDrive`, `CFG-SEM-001 fix` |
| `stereoEnabled`, `pilotLevel`, `rdsInjection` | `generator.GenerateFrame` |
| `rdEnabled`, `limiterEnabled`, `limiterCeiling` | `LiveParams`, `Engine.UpdateConfig` |
| `PS`, `RadioText` | `generator.RDSEncoder().UpdateText` |

Dieses Inventar ist Referenz für WS-03-T1/T2 und bildet die Basis für Tests und Telemetrie.

---

## 6. Weiteres Nachweis-Tracking

- Parameterwerte validiert über `config.Config.Validate()` (`internal/config/config.go`).
- CFG-SEM-001 (`fm.outputDrive`) wird sowohl von Config als auch von Live-Update begrenzt (nun 0..10).
- Dokumentation: `docs/DSP-CHAIN.md` beschreibt die grafische Signalverkettung und damit die Bedeutung von `outputDrive`, `limiterCeiling`, `pilotLevel` und `rdsInjection`.
- Runtime-Exposition: `/status` und `/runtime` melden Sample-, Driver- und Engine-Stats (control handler).

Diese Datei gehört ab sofort zu WS-03 und sollte bei weiteren Änderungen an öffentlichen Parametern gepflegt werden.

+ 2
- 2
internal/app/engine.go 파일 보기

@@ -202,8 +202,8 @@ func (e *Engine) UpdateConfig(u LiveConfigUpdate) error {
}
}
if u.OutputDrive != nil {
if *u.OutputDrive < 0 || *u.OutputDrive > 3 {
return fmt.Errorf("outputDrive out of range (0-3)")
if *u.OutputDrive < 0 || *u.OutputDrive > 10 {
return fmt.Errorf("outputDrive out of range (0-10)")
}
}
if u.PilotLevel != nil {


+ 1
- 1
internal/app/engine_test.go 파일 보기

@@ -238,7 +238,7 @@ func TestEngineLiveUpdateValidation(t *testing.T) {
}

// Out of range drive
badDrive := 10.0
badDrive := 11.0
if err := eng.UpdateConfig(LiveConfigUpdate{OutputDrive: &badDrive}); err == nil {
t.Fatal("expected validation error for bad drive")
}


불러오는 중...
취소
저장