docs(05-01): complete waveform types plan summary and state updates

This commit is contained in:
2026-03-26 17:35:54 +01:00
parent 716ffa82ee
commit 5e31da5442
4 changed files with 102 additions and 21 deletions
@@ -0,0 +1,78 @@
---
phase: 05-waveform-types-and-bank-decoupling
plan: "01"
subsystem: synth
tags: [waveform, additive-synthesis, bandlimiting, enum, tdd]
dependency_graph:
requires: []
provides: [WaveformType enum, WaveformPresetHarmonics, NewLayer waveform resolution]
affects: [synth/config.go, synth/layer.go]
tech_stack:
added: []
patterns: [TDD red-green, bandlimited additive synthesis, zero-value backward compat]
key_files:
created:
- synth/waveform_test.go
modified:
- synth/config.go
- synth/layer.go
decisions:
- "ClassFreqConfigs converted from positional to named struct literals (required by new WaveformType field)"
- "FreqConfig.WaveformType zero value is WaveformCustom, ensuring all existing entries auto-preserve hand-tuned harmonics"
metrics:
duration: "~3 min"
completed_date: "2026-03-26"
tasks: 2
files: 3
requirements:
- WAVE-01
- WAVE-02
---
# Phase 5 Plan 01: Waveform Types and WaveformPresetHarmonics Summary
WaveformType enum with four bandlimited presets (sine, square, sawtooth, triangle) added to synth package with construction-time resolution in NewLayer.
## What Was Built
- **`WaveformType int` enum** in `synth/config.go` with five constants: `WaveformCustom` (0), `WaveformSine`, `WaveformSquare`, `WaveformSawtooth`, `WaveformTriangle`
- **`WaveformPresetHarmonics(wt, baseHz, sampleRate)`** function that generates bandlimited harmonic series — all partials below Nyquist (sampleRate/2)
- **`FreqConfig.WaveformType` field** added; zero value `WaveformCustom` ensures full backward compatibility with all 14 existing `ClassFreqConfigs` entries
- **`NewLayer` waveform resolution** — presets resolved at construction time, stored in `Layer.Config.Harmonics`, so `AdvanceSample` requires no changes
- **`synth/waveform_test.go`** with 12 tests covering all preset shapes, bandlimit enforcement, odd-only ratios, consecutive ratios, nil return for Custom, regression vs hand-tuned harmonics, and NewLayer construction behavior
## Tasks Completed
| Task | Description | Commit | Files |
|------|-------------|--------|-------|
| 1 (RED) | Failing waveform tests | 88dee31 | synth/waveform_test.go |
| 1 (GREEN) | WaveformType enum + WaveformPresetHarmonics | 82d1e37 | synth/config.go |
| 2 | Wire waveform resolution into NewLayer + 3 more tests | 7f64714 | synth/layer.go, synth/waveform_test.go |
## Verification
- `go test ./synth/... -v`: 41 tests, all pass (28 existing + 12 new waveform + 1 regression)
- `go test ./encode/...`: 3 tests pass (no regressions)
- `go vet ./synth/...`: clean
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] ClassFreqConfigs positional struct literals broken by new field**
- **Found during:** Task 1 GREEN phase
- **Issue:** Adding `WaveformType WaveformType` field to `FreqConfig` caused compile errors on all 14 positional struct literals in `ClassFreqConfigs` ("too few values in struct literal")
- **Fix:** Converted all 14 entries from positional `{65.0, []HarmonicDef{...}, 0.0}` syntax to named field `{BaseHz: 65.0, Harmonics: []HarmonicDef{...}, Pan: 0.0}` syntax. WaveformType field implicitly zero (WaveformCustom), preserving hand-tuned harmonics as per D-03.
- **Files modified:** synth/config.go (ClassFreqConfigs block)
- **Commit:** 82d1e37
## Known Stubs
None — all waveform preset logic is fully implemented and wired.
## Self-Check: PASSED
- synth/waveform_test.go: FOUND
- synth/config.go (WaveformType): FOUND (verified by go test passing)
- synth/layer.go (NewLayer resolution): FOUND (verified by TestNewLayerResolvesWaveformPreset)
- Commits 88dee31, 82d1e37, 7f64714: all present in git log