feat(synth): add LFO modulation, ADSR envelopes, pentatonic tuning, and soft limiter

Replace static EMA-smoothed drones with an evolving ambient soundscape:
- ADSR envelope system with sustained (2s attack, 4s release) and bursty
  (30ms attack, no sustain) modes per protocol group
- LFO pitch wobble and amplitude tremolo with incommensurable rates per
  group (Eno technique) so modulation patterns never repeat
- C major pentatonic frequency tuning (just intonation) — any combination
  of active protocols sounds consonant
- tanh soft limiter on master output prevents clipping
- Sync all documentation: README, PROJECT.md, ARCHITECTURE.md, v1.2
  requirements traceability

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-27 19:38:58 +01:00
co-authored by Claude Opus 4.6
parent 494385b528
commit 6b2db48339
14 changed files with 824 additions and 255 deletions
+13 -7
View File
@@ -10,7 +10,7 @@ Network traffic patterns are instantly recognizable as distinct sounds — a pin
## Current State
**v1.2 shipped.** 35 built-in traffic classes across 9 protocol families (Infrastructure, Web, Mail, Remote Access, File Transfer, Database, Discovery, VoIP, Unknown). Major-second frequency ladder (65-3250 Hz) with family-coherent sound design. Group-ordered `--print-config` with section headers. `[groups]` TOML config for reassigning protocols to different sound families. ~6,000 lines of Go across 7 packages, full test suite green.
**v1.2 shipped.** 35 built-in traffic classes across 9 protocol families (Infrastructure, Web, Mail, Remote Access, File Transfer, Database, Discovery, VoIP, Unknown). C major pentatonic frequency tuning (just intonation, 65-6534 Hz) with ADSR envelope shaping (sustained vs bursty modes), LFO pitch/tremolo modulation (Eno technique with incommensurable rates), and tanh soft limiter. Group-ordered `--print-config` with section headers. `[groups]` TOML config for reassigning protocols to different sound families. ~6,500 lines of Go across 7 packages, full test suite green.
Tech stack: gopacket/gopacket v1.5.0, packetcap/go-pcap (pure Go capture), sjzar/go-lame v0.0.9 (embedded LAME), spf13/cobra v1.10.2, BurntSushi/toml v1.6.0.
@@ -25,8 +25,8 @@ All v1.0 + v1.1 + v1.2 requirements validated (45 total). Full pipeline: capture
- Auto-cluster unrecognized traffic into 4 hash-bucketed unknown classes with distinct tones
- Aggregate traffic into 500ms time windows driving amplitude evolution
- End-to-end pipeline: capture -> classify -> synthesize -> MP3 output
- Map each traffic class to a distinct ambient/drone layer (sine oscillators + EMA smoothing)
- Stereo mixing with constant-power panning, no distortion
- Map each traffic class to a distinct ambient layer with ADSR envelopes, LFO modulation, and pentatonic tuning
- Stereo mixing with constant-power panning and tanh soft limiting
- MP3 encoding via embedded LAME, zero-packet guard
- CLI with `-i`, `-o`, `--list-interfaces`, `--verbose`, `--filter`, `--read` flags
- BPF capture filter for scoping live traffic
@@ -49,8 +49,11 @@ All v1.0 + v1.1 + v1.2 requirements validated (45 total). Full pipeline: capture
- Removed stale constants and future-proofed test bounds for extensibility
- 21 new protocol classifications: Mail (IMAP, POP3, SMTP-sub), File Transfer (FTP, SMB, TFTP), Remote Access (RDP, Telnet, VNC), Database (MySQL, PostgreSQL, Redis, MongoDB), Discovery (mDNS, SSDP, SNMP), VoIP (SIP), Web (QUIC/HTTP3), Infrastructure (LDAP, Kerberos, Syslog)
- No regression in existing 14 protocol classifications
- Major-second frequency ladder with family-coherent waveforms and group field on FreqConfig
- Auto-assign frequency range moved to 2500-4000 Hz (collision-free with built-ins)
- C major pentatonic frequency tuning (just intonation) with family-coherent waveforms and group field on FreqConfig
- ADSR envelope system: sustained protocols (2s attack, 4s release) and bursty protocols (30ms attack, no sustain)
- LFO modulation: per-group incommensurable pitch wobble and amplitude tremolo (Eno technique)
- Tanh soft limiter on master output prevents clipping
- Auto-assign frequency range moved to 5000-8000 Hz (collision-free with built-ins)
- Group-ordered `--print-config` output with section headers
- `[groups]` TOML config for protocol-to-group reassignment
@@ -62,7 +65,7 @@ All v1.0 + v1.1 + v1.2 requirements validated (45 total). Full pipeline: capture
- Real-time audio playback — file output only
- GUI or web interface — CLI only
- Rhythmic/percussive output — ambient/drone style only
- Fully rhythmic/beat-based output — ambient style with percussive accents for bursty protocols
- Stereo position configuration — add in future if requested
## Context
@@ -93,7 +96,10 @@ All v1.0 + v1.1 + v1.2 requirements validated (45 total). Full pipeline: capture
| go-lame (embedded C) over shine-mp3 | Better quality, smaller files, acceptable CGo tradeoff | Good |
| Hand-rolled synthesis over audio libraries | 20 lines of oscillator code, no unnecessary dependencies | Good |
| Hash-bucketed unknowns over k-means | Deterministic, zero-config, sufficient for v1 audio distinction | Good |
| Major-second frequency ladder | Musical interval spacing prevents critical band masking between family members | Good |
| C major pentatonic tuning (just intonation) | Any combination of active tones sounds consonant; replaced major-second ladder | Good |
| ADSR envelopes over pure EMA | Sustained flows get ambient pads; bursty protocols get percussive accents | Good |
| LFO with incommensurable rates | Eno technique ensures soundscape never repeats; each group has unique modulation | Good |
| Tanh soft limiter over hard clipping | Preserves dynamics while preventing distortion during traffic spikes | Good |
| Group field as string (not enum) | Extensible for new family names without code changes | Good |
| Ordered []Rule classifier over switch | Configurable, extensible, first-match-wins semantics | Good |
| 500ms window duration | Balances temporal resolution against snapshot frequency for synthesis | Good |
+10 -10
View File
@@ -34,17 +34,17 @@ Requirements for extended protocol coverage milestone. Each maps to roadmap phas
### Frequency Design
- [ ] **FREQ-01**: All traffic classes (existing + new) are redistributed into group-coherent frequency bands using musical interval ratios (not fixed Hz steps)
- [ ] **FREQ-02**: Within-family protocols are separated by at least a major second interval (ratio 1.122) to avoid critical band masking
- [ ] **FREQ-03**: The full frequency allocation table is designed and documented before any FreqConfig code is written
- [x] **FREQ-01**: All traffic classes (existing + new) are redistributed into group-coherent frequency bands using musical interval ratios (not fixed Hz steps)
- [x] **FREQ-02**: Within-family protocols are separated by at least a major second interval (ratio 1.122) to avoid critical band masking
- [x] **FREQ-03**: The full frequency allocation table is designed and documented before any FreqConfig code is written
- [x] **FREQ-04**: Auto-assign frequency range for user custom classes is updated to avoid collision with new built-in frequencies
### Group System
- [ ] **GRP-01**: Each traffic class belongs to a named group (Infrastructure, Web, Mail, File Transfer, Remote Access, Database, Discovery, VoIP)
- [x] **GRP-01**: Each traffic class belongs to a named group (Infrastructure, Web, Mail, File Transfer, Remote Access, Database, Discovery, VoIP)
- [x] **GRP-02**: `--print-config` output organizes classes by group with section headers
- [x] **GRP-03**: Users can define `[groups]` in TOML config to reassign protocols to different sound families
- [ ] **GRP-04**: FreqConfig gains a `Group` field that drives group-aware frequency allocation and config output
- [x] **GRP-04**: FreqConfig gains a `Group` field that drives group-aware frequency allocation and config output
## Future Requirements
@@ -77,12 +77,12 @@ Which phases cover which requirements. Updated during roadmap creation.
| Requirement | Phase | Status |
|-------------|-------|--------|
| CLEAN-01 | Phase 8 | Complete |
| FREQ-01 | Phase 9 | Pending |
| FREQ-02 | Phase 9 | Pending |
| FREQ-03 | Phase 9 | Pending |
| FREQ-01 | Phase 9 | Complete |
| FREQ-02 | Phase 9 | Complete |
| FREQ-03 | Phase 9 | Complete |
| FREQ-04 | Phase 9 | Complete |
| GRP-01 | Phase 9 | Pending |
| GRP-04 | Phase 9 | Pending |
| GRP-01 | Phase 9 | Complete |
| GRP-04 | Phase 9 | Complete |
| PROTO-01 | Phase 10 | Complete |
| PROTO-02 | Phase 10 | Complete |
| PROTO-03 | Phase 10 | Complete |
+70 -5
View File
@@ -471,20 +471,85 @@ Frequency assignments must be validated by ear, not just by looking at Hz values
| Frequency collisions | None | Possible if not planned |
| AllClasses() iteration | 14 items, trivial | 32 items, still trivial |
| PrintConfig output lines | ~60 lines | ~130 lines |
| EMA smoothing convergence | No change | No change (per-layer, independent) |
| ADSR envelope convergence | No change | No change (per-layer, independent) |
| NewBank construction time | Negligible | Negligible |
The main practical change is perceptual loudness: with 32 layers each at 3.1% gain, the ambient mix becomes quieter when many protocols are active simultaneously. This is acceptable and matches the ambient/drone aesthetic. The `WhisperFloor` mechanism ensures inactive layers contribute minimally, so sessions with only 5-6 active protocols still sound full.
The main practical change is perceptual loudness: with 32 layers each at ~2.6% gain (accounting for tremolo headroom), the ambient mix becomes quieter when many protocols are active simultaneously. This is acceptable and matches the ambient aesthetic. The ADSR envelope system ensures inactive layers fade to silence, while the soft limiter prevents distortion when many protocols spike simultaneously.
---
## Synthesis Layer: Envelope + LFO + Soft Limiter (post-v1.2)
The original synthesis pipeline used pure EMA (exponential moving average) smoothing and static oscillators, producing continuous drones. This was replaced with a richer signal chain to create an evolving ambient soundscape:
### Signal Chain per Layer
```
Oscillator → ADSR Envelope → LFO Modulation → Per-layer Gain → Stereo Pan → Soft Limiter → Mix
```
### ADSR Envelope System (`synth/envelope.go`)
Replaces the single-coefficient EMA with a four-stage envelope state machine:
| Parameter | Sustained Protocols | Bursty Protocols |
|-----------|--------------------|--------------------|
| Attack | 2.0s (slow fade-in) | 0.03s (fast onset) |
| Decay | 1.0s (slight dip) | 0.3s (rapid drop) |
| Sustain | 85% of peak | 0% (no sustain) |
| Release | 4.0s (long tail) | 1.5s (medium tail) |
Protocol categorization via `FreqConfig.Bursty` flag:
- **Sustained** (Bursty=false): HTTPS, HTTP, QUIC, SSH, SMTP, IMAP, databases — produce ambient pads
- **Bursty** (Bursty=true): ICMP, DNS, NTP, DHCP, mDNS, SSDP, SNMP, LDAP, Kerberos, Syslog — produce percussive accents
The envelope wraps traffic-rate EMA: during Sustain phase, the EMA-smoothed traffic rate modulates amplitude within the sustain level, preserving the original volume-follows-traffic behavior.
### LFO Modulation (`synth/lfo.go`)
Each Layer has two LFOs:
1. **Pitch LFO** — Modulates oscillator frequency by +/- 0.05-0.15 semitones. Creates subtle detuning that makes drones "breathe".
2. **Tremolo LFO** — Modulates amplitude by +/- 8-20%. Creates gentle pulsing.
Group-specific LFO rates use **incommensurable periods** (Eno technique) so combined modulation never repeats:
| Group | Pitch Rate (Hz) | Tremolo Rate (Hz) |
|-------|----------------|-------------------|
| Infrastructure | 0.031 | 0.053 |
| Web | 0.043 | 0.071 |
| Mail | 0.037 | 0.059 |
| Remote Access | 0.029 | 0.047 |
| File Transfer | 0.041 | 0.067 |
| Database | 0.023 | 0.083 |
| VoIP | 0.019 | 0.091 |
| Unknown | 0.053 | 0.037 |
### Pentatonic Frequency Tuning
The original major-second ladder was replaced with **C major pentatonic (just intonation)**: C D E G A across octaves 2-8 (ratios 1/1, 9/8, 5/4, 3/2, 5/3). This guarantees that any subset of simultaneously active protocols produces consonant intervals — no dissonant beating.
### Soft Limiter (`synth/bank.go`)
A `tanh`-based soft limiter on the master stereo output replaces hard clipping. Combined with tremolo-headroom-aware gain (`1 / (N × 1.2)`), this preserves dynamics while preventing distortion during traffic spikes.
### Integration Points
- `FreqConfig.Bursty` (config.go) → selects `SustainedEnvParams` vs `BurstyEnvParams` in `NewLayer()`
- `FreqConfig.Group` (config.go) selects `LFOConfig` via `LFOConfigForGroup()` in `NewLayer()`
- `Layer.AdvanceSample()` (layer.go) → applies pitch LFO to oscillator freq, generates sample, applies envelope, applies tremolo
- `OscillatorBank.RenderWindow()` (bank.go) → applies per-layer gain + pan, then `softLimit()` on each stereo frame
---
## Sources
- Direct code inspection: `synth/config.go`, `synth/bank.go`, `synth/layer.go`, `synth/oscillator.go`, `classify/types.go`, `classify/rules.go`, `classify/classifier.go`, `config/config.go`, `encode/mp3.go`, `cmd/netsynth/main.go` — HIGH confidence
- Musical interval theory (detuning, harmonic relationships): HIGH confidence — standard acoustic physics
- Direct code inspection: `synth/config.go`, `synth/bank.go`, `synth/layer.go`, `synth/oscillator.go`, `synth/lfo.go`, `synth/envelope.go`, `classify/types.go`, `classify/rules.go`, `classify/classifier.go`, `config/config.go`, `encode/mp3.go`, `cmd/netsynth/main.go` — HIGH confidence
- Musical interval theory (detuning, harmonic relationships, pentatonic scales): HIGH confidence — standard acoustic physics
- Brian Eno incommensurable-period technique: HIGH confidence — well-documented generative music principle
- v1.2 protocol list: determined from feature research (see FEATURES.md for rationale on which protocols to include)
---
*Architecture research for: NetSynth v1.2 — extended protocol coverage with grouped families*
*Researched: 2026-03-27*
*Updated: 2026-03-27 — added synthesis layer documentation (ADSR, LFO, pentatonic, soft limiter)*