diff --git a/cmd/netsynth/main.go b/cmd/netsynth/main.go index f727191..6c0ed14 100644 --- a/cmd/netsynth/main.go +++ b/cmd/netsynth/main.go @@ -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 }