| @@ -55,7 +55,7 @@ Current patchable runtime fields via `POST /config`: | |||||
| ## Dry run | ## Dry run | ||||
| The dry-run mode generates a synthetic, hardware-free frame summary based on the current config. | The dry-run mode generates a synthetic, hardware-free frame summary based on the current config. | ||||
| It is intended as a no-hardware smoke path for the CLI and config/control-adjacent logic. | |||||
| It now reports the active source label as well, so dry-run output is less disconnected from the offline/sim paths. | |||||
| The HTTP control plane also exposes `GET /dry-run` for quick inspection of the currently effective no-hardware summary. | The HTTP control plane also exposes `GET /dry-run` for quick inspection of the currently effective no-hardware summary. | ||||
| @@ -19,6 +19,7 @@ type FrameSummary struct { | |||||
| PilotLevel float64 `json:"pilotLevel"` | PilotLevel float64 `json:"pilotLevel"` | ||||
| RDSInjection float64 `json:"rdsInjection"` | RDSInjection float64 `json:"rdsInjection"` | ||||
| OutputDrive float64 `json:"outputDrive"` | OutputDrive float64 `json:"outputDrive"` | ||||
| Source string `json:"source"` | |||||
| PreviewSamples []float64 `json:"previewSamples"` | PreviewSamples []float64 `json:"previewSamples"` | ||||
| } | } | ||||
| @@ -32,6 +33,10 @@ func Generate(cfg cfgpkg.Config) FrameSummary { | |||||
| } | } | ||||
| preview[i] = sign * base * float64(i+1) / 16.0 | preview[i] = sign * base * float64(i+1) / 16.0 | ||||
| } | } | ||||
| source := "tones" | |||||
| if cfg.Audio.InputPath != "" { | |||||
| source = cfg.Audio.InputPath | |||||
| } | |||||
| return FrameSummary{ | return FrameSummary{ | ||||
| Mode: "dry-run", | Mode: "dry-run", | ||||
| FrequencyMHz: cfg.FM.FrequencyMHz, | FrequencyMHz: cfg.FM.FrequencyMHz, | ||||
| @@ -42,6 +47,7 @@ func Generate(cfg cfgpkg.Config) FrameSummary { | |||||
| PilotLevel: cfg.FM.PilotLevel, | PilotLevel: cfg.FM.PilotLevel, | ||||
| RDSInjection: cfg.FM.RDSInjection, | RDSInjection: cfg.FM.RDSInjection, | ||||
| OutputDrive: cfg.FM.OutputDrive, | OutputDrive: cfg.FM.OutputDrive, | ||||
| Source: source, | |||||
| PreviewSamples: preview, | PreviewSamples: preview, | ||||
| } | } | ||||
| } | } | ||||
| @@ -17,6 +17,18 @@ func TestGenerate(t *testing.T) { | |||||
| if len(frame.PreviewSamples) != 16 { | if len(frame.PreviewSamples) != 16 { | ||||
| t.Fatalf("unexpected preview length: %d", len(frame.PreviewSamples)) | t.Fatalf("unexpected preview length: %d", len(frame.PreviewSamples)) | ||||
| } | } | ||||
| if frame.Source != "tones" { | |||||
| t.Fatalf("unexpected source: %s", frame.Source) | |||||
| } | |||||
| } | |||||
| func TestGenerateUsesInputPathAsSource(t *testing.T) { | |||||
| cfg := cfgpkg.Default() | |||||
| cfg.Audio.InputPath = "demo.wav" | |||||
| frame := Generate(cfg) | |||||
| if frame.Source != "demo.wav" { | |||||
| t.Fatalf("unexpected source: %s", frame.Source) | |||||
| } | |||||
| } | } | ||||
| func TestWriteJSONFile(t *testing.T) { | func TestWriteJSONFile(t *testing.T) { | ||||