Files
gurix bb9f9a7944 docs(02-03): complete MP3 encoder and output flag plan
- Create 02-03-SUMMARY.md with TDD flow documentation
- Update STATE.md: advance to last plan, 100% progress, add decisions
- Update ROADMAP.md: phase 02 complete (3/3 plans)
- Mark requirements OUT-01, OUT-02, OUT-03 complete
2026-03-26 12:09:47 +01:00

4.3 KiB

phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
02-audio-synthesis-engine 03 encode
mp3
encoding
go-lame
cli
output-flag
tdd
requires provides affects
02-01
02-02
encode/mp3.go
encode/mp3_test.go
cmd/netsynth/-o-flag
cmd/netsynth/main.go
added patterns
github.com/sjzar/go-lame (used directly)
go-lame LameWriter API
zero-packet guard before file creation
TDD red-green workflow
created modified
encode/mp3.go
encode/mp3_test.go
cmd/netsynth/main.go
EncodeMP3 and RunSynthesis separated into distinct functions to enable independent testing of raw-frame encoding vs full pipeline
RunSynthesis takes []classify.WindowSnapshot slice (not channel) — caller collects from channel enabling zero-packet check before file creation
Zero-packet guard checks totalPackets BEFORE os.Create to ensure no empty file is left on disk
Snapshot accumulator uses _ = collectedSnapshots to suppress unused variable error without importing encode package prematurely
duration completed tasks_completed files_created files_modified
3min 2026-03-26 2 2 1

Phase 2 Plan 3: MP3 Encoder and Output Flag Summary

One-liner: MP3 encoder via go-lame (44100 Hz, 128 kbps) with ffprobe-validated tests, zero-packet guard, and -o CLI flag with timestamp default.

What Was Built

Task 1: MP3 encoder package (TDD)

encode/mp3.go implements two functions:

  • EncodeMP3(outputPath string, frames [][2]float64, sampleRate int) error — Creates an MP3 file from stereo PCM frames using go-lame's LameWriter. Sets 44100 Hz input/output sample rate, 128 kbps bitrate, stereo (2 channels), quality 5. Calls InitParams() after all Set* calls (required by go-lame API). Writes all PCM bytes in a single call.

  • RunSynthesis(snapshots []classify.WindowSnapshot, outputPath string) error — Orchestrates the full pipeline: checks total packet count (zero-packet guard before file creation), creates OscillatorBank with tau=1.0, renders each snapshot via bank.RenderWindow, concatenates all frames, and calls EncodeMP3.

encode/mp3_test.go implements three tests, all ffprobe-validated:

  • TestMP3Valid — 3 synthetic snapshots (ICMP=50+DNS=30, HTTPS=200, SSH=10+HTTP=80) through full pipeline; ffprobe confirms MP3 format, duration > 0
  • TestZeroPacketError — empty slice and zero-count snapshots return error containing "no packets"; output file does not exist on disk
  • TestEncodeMP3DirectBytes — 44100 frames of 440 Hz sine wave encoded directly; ffprobe confirms MP3 output

Task 2: -o output flag and snapshot accumulator stub

cmd/netsynth/main.go additions:

  • var outputPath string package-level var
  • -o/--output Cobra flag with descriptive help text
  • Timestamp default resolution: netsynth-<20060102-150405>.mp3 format when flag omitted
  • Snapshot accumulator loop collects []classify.WindowSnapshot alongside existing totals accumulation
  • TODO(phase-3) comment marking the synthesis integration point

Test Results

ok  github.com/netsynth/netsynth/aggregate  0.145s
ok  github.com/netsynth/netsynth/capture    0.009s
ok  github.com/netsynth/netsynth/classify   0.007s
ok  github.com/netsynth/netsynth/cmd/netsynth 0.021s
ok  github.com/netsynth/netsynth/encode     0.283s
ok  github.com/netsynth/netsynth/synth      0.680s

Deviations from Plan

None — plan executed exactly as written.

Commits

Hash Type Description
ed3a562 test Add failing tests for MP3 encoder and RunSynthesis (RED)
f221963 feat Implement MP3 encoder package with RunSynthesis orchestrator (GREEN)
a65dfcd feat Wire -o output flag and snapshot accumulator stub into CLI

Phase 2 Completion

This plan completes Phase 2 (audio-synthesis-engine). The full synthesis chain is now validated end-to-end:

WindowSnapshot -> OscillatorBank.RenderWindow -> [][2]float64 -> StereoFramesToInt16Bytes -> go-lame LameWriter -> MP3 file

Phase 3 will wire encode.RunSynthesis(collectedSnapshots, outputPath) into the live capture pipeline.

Self-Check

Files created/modified:

  • encode/mp3.go: EXISTS
  • encode/mp3_test.go: EXISTS
  • cmd/netsynth/main.go: MODIFIED

Commits verified: ed3a562, f221963, a65dfcd