feat(03-02): wire RunSynthesis and add encoding feedback messages

- Add encode import to cmd/netsynth/main.go
- Remove TODO(phase-3) stub and _ = collectedSnapshots
- Print protocol summary BEFORE encoding (D-08)
- Add 'Encoding N windows to path...' status message (D-07)
- Add 'Saved path (Xs, N KB, encoded in Xs)' confirmation (D-09)
- Update Long description: remove '(in future phases)' qualifier
- Audio duration uses float64 to avoid integer truncation (Pitfall 4)
This commit is contained in:
2026-03-26 13:15:35 +01:00
parent 7f560e89d2
commit 0ab2c6e316
+19 -5
View File
@@ -15,6 +15,7 @@ import (
"github.com/netsynth/netsynth/aggregate"
"github.com/netsynth/netsynth/capture"
"github.com/netsynth/netsynth/classify"
"github.com/netsynth/netsynth/encode"
)
var (
@@ -28,7 +29,7 @@ func main() {
rootCmd := &cobra.Command{
Use: "netsynth",
Short: "Sonify live network traffic into ambient audio",
Long: "NetSynth captures network traffic, classifies it by protocol, and (in future phases) synthesizes an ambient MP3 soundscape.",
Long: "NetSynth captures network traffic, classifies it by protocol, and synthesizes an ambient MP3 soundscape.",
RunE: run,
}
@@ -96,16 +97,29 @@ func run(cmd *cobra.Command, args []string) error {
aggregate.AccumulateTotals(totals, snap)
}
// TODO(phase-3): Pass collectedSnapshots to encode.RunSynthesis(collectedSnapshots, outputPath)
_ = collectedSnapshots
// Print exit summary (CLAS-03)
// D-08: Print protocol summary BEFORE encoding — user sees stats immediately
dropped := atomic.LoadInt64(droppedPtr)
if dropped > 0 {
fmt.Fprintf(os.Stderr, "\nWarning: %d packets dropped (channel buffer full)\n", dropped)
}
aggregate.PrintSummary(os.Stderr, totals)
// D-07: Encoding status line
fmt.Fprintf(os.Stderr, "Encoding %d windows to %s...\n", len(collectedSnapshots), outputPath)
encodeStart := time.Now()
if err := encode.RunSynthesis(collectedSnapshots, outputPath); err != nil {
return fmt.Errorf("synthesis failed: %w", err)
}
encodeElapsed := time.Since(encodeStart)
// D-09: Saved confirmation with path, audio duration, file size, encoding time
audioDuration := float64(len(collectedSnapshots)) * float64(aggregate.DefaultWindowMs) / 1000.0
info, statErr := os.Stat(outputPath)
if statErr != nil {
return fmt.Errorf("stat output file: %w", statErr)
}
fmt.Fprintf(os.Stderr, "Saved %s (%.1fs, %d KB, encoded in %.1fs)\n",
outputPath, audioDuration, info.Size()/1024, encodeElapsed.Seconds())
return nil
}