| @@ -82,108 +82,72 @@ Verantwortung: | |||||
| --- | --- | ||||
| ## Phase-1-Umbau (dieser Arbeitslauf) | |||||
| ## Phase-1-Umbau | |||||
| ### Phase-1 Status (closure) | |||||
| ### Phase-1 Status | |||||
| - Architekturgrundlage, Config-Modell und Arbitration/Admission-Surface sind umgesetzt. | - Architekturgrundlage, Config-Modell und Arbitration/Admission-Surface sind umgesetzt. | ||||
| - Abschlussfokus: Tests/Edge-Cases, API/Debug-Surface glaetten, Docs klar ziehen. | |||||
| - Keine neuen Scheduler- oder Multi-Resolution-Ausbauschritte in Phase 1. | |||||
| ### A. Benennung / Projektidentität | |||||
| - Projektname auf `sdr-wideband-suite` umstellen | |||||
| - README auf Zielbild anpassen | |||||
| ### B. Konfigurationsmodell vorbereiten | |||||
| Neue Konfig-Teile einführen: | |||||
| - `pipeline.mode` | |||||
| - `surveillance.*` | |||||
| - `refinement.*` | |||||
| - `resources.*` | |||||
| - optionale `profiles.*` | |||||
| Zusatz: | |||||
| - `refinement.detail_fft_size` für einen eigenständigen Detailpfad (Refinement-FFT) neben der Surveillance-FFT | |||||
| Wichtig: | |||||
| - Abwärtskompatibilität zur bisherigen Config möglichst erhalten | |||||
| - bisherige Felder weiterhin nutzbar | |||||
| ### C. Analyse von UI trennen | |||||
| - `fft_size` als primär **analysis/surveillance**-Parameter behandeln | |||||
| - UI-seitige Bin-/FPS-Wünsche als reine Presentation-Ebene behandeln | |||||
| - klare Trennung im Code etablieren | |||||
| ### D. Candidate-/Refinement-Modell einziehen | |||||
| - neue Candidate-/Refinement-Datentypen einführen | |||||
| - zunächst mit CPU-/bestehendem GPU-Extraction-Pfad implementieren | |||||
| - Detector bleibt vorerst Kern der Candidate-Erzeugung | |||||
| - Refiner sitzt danach explizit als eigener Schritt in der Pipeline | |||||
| - Refinement-Workitems mit expliziten Ausführungsparametern (FFT/Span/Stage) | |||||
| ### E. Pipeline-Orchestrierung modularisieren | |||||
| - `runDSP()` entflechten | |||||
| - Schritte explizit machen: | |||||
| - ingest | |||||
| - spectrum | |||||
| - detect | |||||
| - refine | |||||
| - classify | |||||
| - track | |||||
| - present | |||||
| - record | |||||
| - Gemeinsame Arbitration-/Budget-Sicht für refinement/record/decode zentralisieren (Admission + Queue/Hold + Debug-Surface) -- umgesetzt via zentralem Arbiter im Pipeline-Paket + normalisierter Reason-Taxonomie; künftige Phase: tieferer Scheduler/Intent-Budget-Override | |||||
| ### F. Dokumentierte Betriebsprofile | |||||
| - initiale Profile definieren, z. B.: | |||||
| - `legacy` | |||||
| - `wideband-balanced` | |||||
| - `wideband-aggressive` | |||||
| - `archive` | |||||
| ### G. Tests / Build grün halten | |||||
| - Go tests ausführen | |||||
| - Build testen | |||||
| - erst danach commit/push | |||||
| - Phase 1 ist als Meilenstein abgeschlossen. | |||||
| ### Kernpunkte | |||||
| - Projektname auf `sdr-wideband-suite` umgestellt | |||||
| - neues Konfigurationsmodell für `pipeline`, `surveillance`, `refinement`, `resources`, `profiles` | |||||
| - Analyse klarer von Presentation getrennt | |||||
| - explizites Candidate-/Refinement-Modell eingeführt | |||||
| - `runDSP()` in klarere Schritte zerlegt | |||||
| - gemeinsame Arbitration-/Budget-Sicht für refinement/record/decode zentralisiert | |||||
| - initiale Betriebsprofile dokumentiert | |||||
| - Tests/Build grün gehalten | |||||
| --- | --- | ||||
| ## Spätere Phasen | |||||
| ## Phase-2-Umbau | |||||
| ### Phase 2 | |||||
| - echte mehrstufige Surveillance-Resolution-Engine | |||||
| - GPU-seitige Reduction/Decimation | |||||
| - UI-Detailfenster an Refinement koppeln | |||||
| ### Phase-2 Status | |||||
| - Phase 2 ist als Meilenstein abgeschlossen. | |||||
| Phase-2 Status (Wave E): | |||||
| - Derived-detection Governance: detection vs support-only klarer (Policy + Debug) | |||||
| - Fused candidate evidence summaries mit Rollen/Kindern und Support-Only Hinweis | |||||
| - Surveillance-Level Summaries berichten Rollen/Kind (Primary/Derived/Support/Presentation) | |||||
| ### Gelandete Wellen | |||||
| - **Wave A**: operative Surveillance-Level, decimated/derived spectra, Level-Set und API-Sicht | |||||
| - **Wave B**: derived candidate pass, primary/derived fusion, candidate evidence | |||||
| - **Wave C**: level-aware candidate semantics und konservatives evidence-aware scoring | |||||
| - **Wave D**: detection governance, Rollen für detection/support/presentation, derived-detection policy | |||||
| - **Wave E**: Konsolidierung von detection/support semantics, fused candidate summaries, Debug/API/Docs | |||||
| ### Phase 3 | |||||
| - Scheduler/Priority/Budget-Engine | |||||
| - Kandidatenpriorisierung | |||||
| - automatische Decoder-Slot-Vergabe | |||||
| ### Ergebnis | |||||
| - echte mehrstufige Surveillance-Resolution-Grundlage | |||||
| - derived detection governance und support-only Semantik | |||||
| - fused candidate evidence summaries | |||||
| - Level-Rollen und Debug-Sicht sind operativ sichtbar | |||||
| Phase-3 Status (Wave 3E): | |||||
| - Wave 3A: Priority-Scoring + BudgetModel scaffolding integriert | |||||
| - Wave 3B: Arbitration/Admission + Hold/Displacement-Logik für Refinement/Record/Decode | |||||
| - Wave 3C: Pressure-Summaries + Decision-Queue-Stats + Reason-Taxonomie + Tests (Hold/Displacement) | |||||
| - Wave 3E: Konservative cross-resource Rebalance-Schicht (Refinement/Record/Decode) mit profil-/intent-spezifischem Schutz, Debug-Surface und Szenario-Tests | |||||
| --- | |||||
| ### Phase 4 | |||||
| - breitbandige Multi-Span-Profile | |||||
| - 20-80 MHz konkrete Betriebsmodi | |||||
| - adaptive Quality-of-Service | |||||
| ## Phase-3-Umbau | |||||
| ### Phase-3 Status | |||||
| - Phase 3 ist als konservativer Runtime-Intelligence-Meilenstein abgeschlossen. | |||||
| ### Gelandete Wellen | |||||
| - **Wave 3A**: Priority-Tiers, Admission-Classes, reichere Reason-Familien | |||||
| - **Wave 3B**: Budget-Preferences, Effective-Budgets, Pressure-Summaries | |||||
| - **Wave 3C**: Hold-Protection, opportunistic displacement, displaced-by-hold, harmonisierte Reason-Taxonomie | |||||
| - **Wave 3D**: family-aware tier floors, intent-aware hold behavior, family-priority Runtime-Semantik | |||||
| - **Wave 3E**: konservative cross-resource Rebalance für refinement/record/decode mit profil-/intent-spezifischem Schutz | |||||
| ### Ergebnis | |||||
| - refinement / record / decode sprechen eine gemeinsame Admission-/Priority-Sprache | |||||
| - pressure ist sichtbar und verhaltenswirksam | |||||
| - hold / protection / displacement sind erklärbar | |||||
| - signal-family priorities greifen in echte Runtime-Entscheidungen ein | |||||
| - conservative adaptive rebalance verschiebt Ressourcen zwischen refinement / record / decode | |||||
| --- | --- | ||||
| ## Erfolgskriterien für Phase 1 | |||||
| ## Spätere Phasen | |||||
| - Fork existiert als neues Repo | |||||
| - Projekt ist logisch als Wideband-Fork positioniert | |||||
| - neue Architekturbegriffe sind im Code und in der Config sichtbar | |||||
| - bestehende Kernfunktionen bleiben lauffähig | |||||
| - Grundlage für spätere skalierbare, autonome Arbeitsweise ist gelegt | |||||
| ### Phase 4 | |||||
| - breitbandige Multi-Span-Profile | |||||
| - 20-80 MHz konkrete Betriebsmodi | |||||
| - adaptive Quality-of-Service | |||||
| - weitere Scheduler-/Betriebsintelligenz über die konservative Phase-3-Rebalance hinaus | |||||
| --- | --- | ||||
| @@ -13,7 +13,8 @@ Go-based SDR analysis engine and live spectrum/waterfall UI, evolved from the or | |||||
| - WFM stereo + RDS baseband | - WFM stereo + RDS baseband | ||||
| - Mock mode for testing without hardware | - Mock mode for testing without hardware | ||||
| - Phase-1 architecture foundation complete: explicit pipeline/surveillance/refinement/resources config model plus candidate/refinement/admission scaffolding | - Phase-1 architecture foundation complete: explicit pipeline/surveillance/refinement/resources config model plus candidate/refinement/admission scaffolding | ||||
| - Phase-2 (in progress): derived detection governance, multi-resolution support levels, fused candidate evidence summaries | |||||
| - Phase-2 milestone complete: multi-resolution surveillance levels, derived detection governance, support levels, and fused candidate evidence summaries | |||||
| - Phase-3 milestone complete: conservative runtime prioritization/admission/pressure/hold/displacement/rebalance behavior across refinement, record, and decode | |||||
| --- | --- | ||||
| @@ -1,157 +1,240 @@ | |||||
| bands: | bands: | ||||
| - name: 40m | |||||
| start_hz: 7.0e6 | |||||
| end_hz: 7.2e6 | |||||
| center_hz: 7.1e6 | |||||
| - name: uk-fm-broadcast | |||||
| start_hz: 87.5e6 | |||||
| end_hz: 108.0e6 | |||||
| center_hz: 99.5e6 | |||||
| sample_rate: 2048000 | sample_rate: 2048000 | ||||
| fft_size: 2048 | |||||
| gain_db: 30 | |||||
| fft_size: 4096 | |||||
| gain_db: 32 | |||||
| tuner_bw_khz: 1536 | tuner_bw_khz: 1536 | ||||
| use_gpu_fft: true | use_gpu_fft: true | ||||
| agc: false | |||||
| dc_block: false | |||||
| iq_balance: false | |||||
| classifier_mode: combined | |||||
| agc: true | |||||
| dc_block: true | |||||
| iq_balance: true | |||||
| pipeline: | pipeline: | ||||
| mode: wideband-balanced | mode: wideband-balanced | ||||
| profile: wideband-balanced | |||||
| goals: | goals: | ||||
| intent: wideband-surveillance | |||||
| monitor_start_hz: 7.0e6 | |||||
| monitor_end_hz: 7.2e6 | |||||
| monitor_span_hz: 200000 | |||||
| signal_priorities: ["hf-voice", "digital", "cw"] | |||||
| auto_record_classes: [] | |||||
| auto_decode_classes: [] | |||||
| intent: broadcast-monitoring | |||||
| monitor_start_hz: 88.0e6 | |||||
| monitor_end_hz: 108.0e6 | |||||
| monitor_span_hz: 20000000 | |||||
| signal_priorities: ["wfm", "rds", "broadcast", "digital"] | |||||
| auto_record_classes: ["wfm"] | |||||
| auto_decode_classes: ["rds"] | |||||
| surveillance: | surveillance: | ||||
| analysis_fft_size: 2048 | |||||
| frame_rate: 15 | |||||
| strategy: single-resolution | |||||
| analysis_fft_size: 4096 | |||||
| frame_rate: 12 | |||||
| strategy: multi-resolution | |||||
| display_bins: 2048 | display_bins: 2048 | ||||
| display_fps: 15 | |||||
| display_fps: 12 | |||||
| derived_detection: auto | |||||
| refinement: | refinement: | ||||
| enabled: true | enabled: true | ||||
| max_concurrent: 8 | |||||
| detail_fft_size: 2048 | |||||
| max_concurrent: 16 | |||||
| detail_fft_size: 4096 | |||||
| min_candidate_snr_db: 0 | min_candidate_snr_db: 0 | ||||
| min_span_hz: 0 | |||||
| max_span_hz: 0 | |||||
| min_span_hz: 80000 | |||||
| max_span_hz: 250000 | |||||
| auto_span: true | auto_span: true | ||||
| resources: | |||||
| prefer_gpu: true | |||||
| max_refinement_jobs: 16 | |||||
| max_recording_streams: 8 | |||||
| max_decode_jobs: 8 | |||||
| decision_hold_ms: 2000 | |||||
| profiles: | profiles: | ||||
| - name: legacy | - name: legacy | ||||
| description: Current single-band pipeline behavior | description: Current single-band pipeline behavior | ||||
| surveillance: | surveillance: | ||||
| analysis_fft_size: 2048 | analysis_fft_size: 2048 | ||||
| strategy: single-resolution | strategy: single-resolution | ||||
| display_bins: 2048 | |||||
| display_fps: 15 | |||||
| derived_detection: auto | |||||
| resources: | resources: | ||||
| prefer_gpu: false | |||||
| max_refinement_jobs: 8 | max_refinement_jobs: 8 | ||||
| max_recording_streams: 16 | max_recording_streams: 16 | ||||
| max_decode_jobs: 16 | max_decode_jobs: 16 | ||||
| decision_hold_ms: 2000 | decision_hold_ms: 2000 | ||||
| refinement: | refinement: | ||||
| enabled: true | |||||
| max_concurrent: 8 | max_concurrent: 8 | ||||
| detail_fft_size: 2048 | detail_fft_size: 2048 | ||||
| min_candidate_snr_db: 0 | |||||
| min_span_hz: 0 | |||||
| max_span_hz: 0 | |||||
| auto_span: true | |||||
| pipeline: | pipeline: | ||||
| mode: legacy | mode: legacy | ||||
| profile: legacy | |||||
| goals: | goals: | ||||
| intent: general-monitoring | intent: general-monitoring | ||||
| - name: wideband-balanced | - name: wideband-balanced | ||||
| description: Prepared baseline for scalable wideband surveillance | |||||
| description: Baseline multi-resolution wideband surveillance | |||||
| surveillance: | surveillance: | ||||
| analysis_fft_size: 4096 | analysis_fft_size: 4096 | ||||
| frame_rate: 12 | |||||
| strategy: multi-resolution | strategy: multi-resolution | ||||
| display_bins: 2048 | |||||
| display_fps: 12 | |||||
| derived_detection: auto | |||||
| resources: | resources: | ||||
| prefer_gpu: true | |||||
| max_refinement_jobs: 16 | max_refinement_jobs: 16 | ||||
| max_recording_streams: 16 | max_recording_streams: 16 | ||||
| max_decode_jobs: 12 | max_decode_jobs: 12 | ||||
| decision_hold_ms: 2000 | decision_hold_ms: 2000 | ||||
| refinement: | refinement: | ||||
| enabled: true | |||||
| max_concurrent: 16 | max_concurrent: 16 | ||||
| detail_fft_size: 4096 | detail_fft_size: 4096 | ||||
| min_candidate_snr_db: 0 | |||||
| min_span_hz: 4000 | min_span_hz: 4000 | ||||
| max_span_hz: 200000 | max_span_hz: 200000 | ||||
| auto_span: true | |||||
| pipeline: | pipeline: | ||||
| mode: wideband-balanced | mode: wideband-balanced | ||||
| profile: wideband-balanced | |||||
| goals: | goals: | ||||
| intent: wideband-surveillance | intent: wideband-surveillance | ||||
| signal_priorities: ["digital", "wfm"] | |||||
| - name: wideband-aggressive | - name: wideband-aggressive | ||||
| description: Higher surveillance/refinement budgets for future broad-span monitoring | |||||
| description: Higher surveillance/refinement budgets for dense wideband monitoring | |||||
| surveillance: | surveillance: | ||||
| analysis_fft_size: 8192 | analysis_fft_size: 8192 | ||||
| frame_rate: 10 | |||||
| strategy: multi-resolution | strategy: multi-resolution | ||||
| display_bins: 4096 | |||||
| display_fps: 10 | |||||
| derived_detection: auto | |||||
| resources: | resources: | ||||
| prefer_gpu: true | |||||
| max_refinement_jobs: 32 | max_refinement_jobs: 32 | ||||
| max_recording_streams: 24 | max_recording_streams: 24 | ||||
| max_decode_jobs: 16 | max_decode_jobs: 16 | ||||
| decision_hold_ms: 2000 | decision_hold_ms: 2000 | ||||
| refinement: | refinement: | ||||
| enabled: true | |||||
| max_concurrent: 32 | max_concurrent: 32 | ||||
| detail_fft_size: 8192 | detail_fft_size: 8192 | ||||
| min_candidate_snr_db: 0 | |||||
| min_span_hz: 6000 | min_span_hz: 6000 | ||||
| max_span_hz: 250000 | max_span_hz: 250000 | ||||
| auto_span: true | |||||
| pipeline: | pipeline: | ||||
| mode: wideband-aggressive | mode: wideband-aggressive | ||||
| profile: wideband-aggressive | |||||
| goals: | goals: | ||||
| intent: high-density-wideband-surveillance | intent: high-density-wideband-surveillance | ||||
| signal_priorities: ["digital", "wfm", "trunk"] | |||||
| - name: archive | - name: archive | ||||
| description: Record-first monitoring profile | description: Record-first monitoring profile | ||||
| surveillance: | surveillance: | ||||
| analysis_fft_size: 4096 | analysis_fft_size: 4096 | ||||
| frame_rate: 12 | |||||
| strategy: single-resolution | strategy: single-resolution | ||||
| display_bins: 2048 | |||||
| display_fps: 12 | |||||
| derived_detection: auto | |||||
| resources: | resources: | ||||
| prefer_gpu: true | |||||
| max_refinement_jobs: 12 | max_refinement_jobs: 12 | ||||
| max_recording_streams: 24 | max_recording_streams: 24 | ||||
| max_decode_jobs: 12 | max_decode_jobs: 12 | ||||
| decision_hold_ms: 2500 | decision_hold_ms: 2500 | ||||
| refinement: | refinement: | ||||
| enabled: true | |||||
| max_concurrent: 12 | max_concurrent: 12 | ||||
| detail_fft_size: 4096 | detail_fft_size: 4096 | ||||
| min_candidate_snr_db: 0 | |||||
| min_span_hz: 4000 | min_span_hz: 4000 | ||||
| max_span_hz: 200000 | max_span_hz: 200000 | ||||
| auto_span: true | |||||
| pipeline: | pipeline: | ||||
| mode: archive | mode: archive | ||||
| profile: archive | |||||
| goals: | goals: | ||||
| intent: archive-and-triage | intent: archive-and-triage | ||||
| resources: | |||||
| prefer_gpu: true | |||||
| max_refinement_jobs: 8 | |||||
| max_recording_streams: 16 | |||||
| max_decode_jobs: 16 | |||||
| decision_hold_ms: 2000 | |||||
| signal_priorities: ["wfm", "nfm", "digital"] | |||||
| - name: digital-hunting | |||||
| description: Digital-first refinement and decode focus | |||||
| surveillance: | |||||
| analysis_fft_size: 4096 | |||||
| frame_rate: 12 | |||||
| strategy: multi-resolution | |||||
| display_bins: 2048 | |||||
| display_fps: 12 | |||||
| derived_detection: auto | |||||
| resources: | |||||
| prefer_gpu: true | |||||
| max_refinement_jobs: 16 | |||||
| max_recording_streams: 12 | |||||
| max_decode_jobs: 16 | |||||
| decision_hold_ms: 2000 | |||||
| refinement: | |||||
| enabled: true | |||||
| max_concurrent: 16 | |||||
| detail_fft_size: 4096 | |||||
| min_candidate_snr_db: 0 | |||||
| min_span_hz: 3000 | |||||
| max_span_hz: 120000 | |||||
| auto_span: true | |||||
| pipeline: | |||||
| mode: digital-hunting | |||||
| profile: digital-hunting | |||||
| goals: | |||||
| intent: digital-surveillance | |||||
| signal_priorities: ["ft8", "wspr", "fsk", "psk", "dmr"] | |||||
| detector: | detector: | ||||
| threshold_db: -20 | |||||
| min_duration_ms: 250 | |||||
| hold_ms: 500 | |||||
| ema_alpha: 0.2 | |||||
| hysteresis_db: 3 | |||||
| threshold_db: -55 | |||||
| min_duration_ms: 120 | |||||
| hold_ms: 1200 | |||||
| ema_alpha: 0.35 | |||||
| hysteresis_db: 6 | |||||
| min_stable_frames: 3 | min_stable_frames: 3 | ||||
| gap_tolerance_ms: 500 | |||||
| cfar_enabled: true | |||||
| cfar_guard_cells: 2 | |||||
| cfar_train_cells: 16 | |||||
| cfar_rank: 24 | |||||
| cfar_scale_db: 6 | |||||
| gap_tolerance_ms: 1200 | |||||
| cfar_mode: GOSCA | |||||
| cfar_guard_hz: 15000 | |||||
| cfar_train_hz: 120000 | |||||
| cfar_guard_cells: 3 | |||||
| cfar_train_cells: 24 | |||||
| cfar_rank: 36 | |||||
| cfar_scale_db: 7 | |||||
| cfar_wrap_around: true | |||||
| edge_margin_db: 4 | |||||
| max_signal_bw_hz: 250000 | |||||
| merge_gap_hz: 12000 | |||||
| class_history_size: 10 | |||||
| class_switch_ratio: 0.6 | |||||
| recorder: | recorder: | ||||
| enabled: true | |||||
| enabled: false | |||||
| min_snr_db: 10 | min_snr_db: 10 | ||||
| min_duration: 1s | min_duration: 1s | ||||
| max_duration: 300s | max_duration: 300s | ||||
| preroll_ms: 500 | preroll_ms: 500 | ||||
| record_iq: true | |||||
| record_audio: true | |||||
| record_iq: false | |||||
| record_audio: false | |||||
| auto_demod: true | auto_demod: true | ||||
| auto_decode: false | auto_decode: false | ||||
| max_disk_mb: 0 | max_disk_mb: 0 | ||||
| output_dir: "data/recordings" | |||||
| output_dir: data/recordings | |||||
| class_filter: [] | class_filter: [] | ||||
| ring_seconds: 8 | ring_seconds: 8 | ||||
| deemphasis_us: 50 | |||||
| extraction_fir_taps: 101 | |||||
| extraction_bw_mult: 1.2 | |||||
| decoder: | decoder: | ||||
| ft8_cmd: "C:/WSJT/wsjtx-2.7.0-rc6/bin/jt9.exe -8 {audio}" | |||||
| wspr_cmd: "C:/WSJT/wsjtx-2.7.0-rc6/bin/wsprd.exe {audio}" | |||||
| dmr_cmd: "tools/dsd-neo/bin/dsd-neo.exe -fs -i {audio} -s {sr} -o null" | |||||
| dstar_cmd: "tools/dsd-neo/bin/dsd-neo.exe -fd -i {audio} -s {sr} -o null" | |||||
| fsk_cmd: "tools/fsk/fsk_decoder --iq {iq} --sample-rate {sr}" | |||||
| psk_cmd: "tools/psk/psk_decoder --iq {iq} --sample-rate {sr}" | |||||
| web_addr: ":8080" | |||||
| event_path: "data/events.jsonl" | |||||
| frame_rate: 15 | |||||
| ft8_cmd: C:/WSJT/wsjtx-2.7.0-rc6/bin/jt9.exe -8 {audio} | |||||
| wspr_cmd: C:/WSJT/wsjtx-2.7.0-rc6/bin/wsprd.exe {audio} | |||||
| dmr_cmd: tools/dsd-neo/bin/dsd-neo.exe -fs -i {audio} -s {sr} -o null | |||||
| dstar_cmd: tools/dsd-neo/bin/dsd-neo.exe -fd -i {audio} -s {sr} -o null | |||||
| fsk_cmd: tools/fsk/fsk_decoder --iq {iq} --sample-rate {sr} | |||||
| psk_cmd: tools/psk/psk_decoder --iq {iq} --sample-rate {sr} | |||||
| web_addr: :8080 | |||||
| event_path: data/events.jsonl | |||||
| frame_rate: 12 | |||||
| waterfall_lines: 200 | waterfall_lines: 200 | ||||
| web_root: "web" | |||||
| web_root: web | |||||