package synth import "github.com/netsynth/netsynth/classify" const ( SampleRate = 44100 // D-13: CD quality WindowMs = 500 // matches aggregate.DefaultWindowMs SamplesPerWindow = SampleRate * WindowMs / 1000 // 22050 WhisperFloor = 0.03 // D-08/D-09: 3% of max amplitude ) // WaveformType selects the harmonic preset for a synthesis layer. // The zero value WaveformCustom preserves existing hand-tuned harmonics in FreqConfig.Harmonics. type WaveformType int const ( WaveformCustom WaveformType = iota // zero value: use FreqConfig.Harmonics as-is WaveformSine // pure fundamental, single harmonic WaveformSquare // odd harmonics with 1/k amplitude (bandlimited) WaveformSawtooth // all harmonics with 1/k amplitude (bandlimited) WaveformTriangle // odd harmonics with alternating 1/k^2 amplitude (bandlimited) ) // WaveformPresetHarmonics returns the bandlimited harmonic series for the given waveform type // at the given base frequency and sample rate. Returns nil for WaveformCustom. // All returned harmonics are below Nyquist (sampleRate/2). func WaveformPresetHarmonics(wt WaveformType, baseHz float64, sampleRate int) []HarmonicDef { nyquist := float64(sampleRate) / 2.0 switch wt { case WaveformCustom: return nil case WaveformSine: return []HarmonicDef{{Ratio: 1, Amplitude: 1.0}} case WaveformSquare: var harmonics []HarmonicDef for k := 1; float64(k)*baseHz < nyquist; k += 2 { harmonics = append(harmonics, HarmonicDef{Ratio: k, Amplitude: 1.0 / float64(k)}) } return harmonics case WaveformSawtooth: var harmonics []HarmonicDef for k := 1; float64(k)*baseHz < nyquist; k++ { harmonics = append(harmonics, HarmonicDef{Ratio: k, Amplitude: 1.0 / float64(k)}) } return harmonics case WaveformTriangle: var harmonics []HarmonicDef sign := 1.0 for k := 1; float64(k)*baseHz < nyquist; k += 2 { harmonics = append(harmonics, HarmonicDef{Ratio: k, Amplitude: sign / float64(k*k)}) sign = -sign } return harmonics default: return nil } } // HarmonicDef defines one partial in an additive synthesizer. type HarmonicDef struct { Ratio int // harmonic number: 1=fundamental, 2=octave, 3=fifth+octave, etc. Amplitude float64 // relative weight } // FreqConfig holds synthesis parameters for one traffic class. type FreqConfig struct { BaseHz float64 Harmonics []HarmonicDef Pan float64 // [-1, 1]: -1=full left, 0=center, +1=full right WaveformType WaveformType // zero value WaveformCustom uses Harmonics as-is Group string // sound family: "Infrastructure", "Web", "Mail", "Remote Access", "Unknown", etc. Bursty bool // true for event-like protocols (DNS, ICMP, NTP) — fast attack, no sustain } // Frequency Allocation Table — C Major Pentatonic, Just Intonation // // Scale: C D E G A across octaves 2-7 (ratios 1/1, 9/8, 5/4, 3/2, 5/3) // Any combination of active tones is consonant — no dissonant intervals possible. // // Slot Note Hz Class Group Waveform Pan Bursty // 0 C2 65.4 ICMP Infrastructure Triangle -0.3 yes // 1 D2 73.6 NTP Infrastructure Triangle -0.1 yes // 2 E2 81.8 DHCP Infrastructure Triangle 0.1 yes // 3 G2 98.0 mDNS Infrastructure Triangle 0.3 yes // 4 A2 109.0 SSDP Infrastructure Triangle -0.2 yes // 5 C3 130.8 SNMP Infrastructure Triangle 0.2 yes // 6 D3 146.8 DNS Infrastructure Triangle 0.0 yes // 7 E3 163.5 HTTPS Web Sawtooth -0.4 no // 8 G3 196.0 HTTP Web Sawtooth -0.3 no // 9 A3 218.0 QUIC Web Sawtooth -0.2 no // 10 C4 261.6 SMTP Mail Triangle 0.2 no // 11 D4 293.7 IMAP Mail Triangle 0.3 no // 12 E4 327.0 POP3 Mail Triangle 0.4 no // 13 G4 392.0 SMTP-sub Mail Triangle 0.5 no // 14 A4 436.0 SSH Remote Access Square -0.7 no // 15 C5 523.3 RDP Remote Access Square -0.6 no // 16 D5 587.3 Telnet Remote Access Square -0.5 no // 17 E5 654.1 VNC Remote Access Square -0.4 no // 18 G5 784.0 FTP File Transfer Square 0.5 no // 19 A5 872.1 SMB File Transfer Square 0.6 no // 20 C6 1046.5 TFTP File Transfer Square 0.7 no // 21 D6 1174.7 unknown-1 Unknown Custom -0.9 no // 22 E6 1308.1 unknown-2 Unknown Custom 0.9 no // 23 G6 1568.0 unknown-3 Unknown Custom -0.7 no // 24 A6 1744.2 unknown-4 Unknown Custom 0.7 no // 25 C7 2093.0 other-TCP Unknown Custom -0.5 no // 26 D7 2349.3 other-UDP Unknown Custom 0.5 no // 27 E7 2616.1 MySQL Database Sawtooth -0.4 no // 28 G7 3136.0 PostgreSQL Database Sawtooth -0.2 no // 29 A7 3488.4 Redis Database Sawtooth 0.2 no // 30 C8 4186.0 MongoDB Database Sawtooth 0.4 no // 31 D8 4704.0 SIP VoIP Sine 0.0 no // // Auto-assign range: [5000, 8000] Hz (see config/config.go) // LDAP, Kerberos, Syslog: assigned to pentatonic slots in octave 3 (infrastructure) // ClassFreqConfigs maps each traffic class to its synthesis parameters. // Frequencies: C Major Pentatonic (just intonation) across octaves 2-8. // Pan positions per D-12. Group field drives family-aware config output (GRP-04). var ClassFreqConfigs = map[classify.TrafficClass]FreqConfig{ // --- Infrastructure (Triangle, C2-D3, bursty) --- classify.ClassICMP: { BaseHz: 65.4, // C2 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 65.4, SampleRate), Pan: -0.3, Group: "Infrastructure", Bursty: true, }, classify.ClassNTP: { BaseHz: 73.6, // D2 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 73.6, SampleRate), Pan: -0.1, Group: "Infrastructure", Bursty: true, }, classify.ClassDHCP: { BaseHz: 81.8, // E2 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 81.8, SampleRate), Pan: 0.1, Group: "Infrastructure", Bursty: true, }, classify.ClassMDNS: { BaseHz: 98.0, // G2 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 98.0, SampleRate), Pan: 0.3, Group: "Infrastructure", Bursty: true, }, classify.ClassSSDP: { BaseHz: 109.0, // A2 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 109.0, SampleRate), Pan: -0.2, Group: "Infrastructure", Bursty: true, }, classify.ClassSNMP: { BaseHz: 130.8, // C3 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 130.8, SampleRate), Pan: 0.2, Group: "Infrastructure", Bursty: true, }, classify.ClassDNS: { BaseHz: 146.8, // D3 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 146.8, SampleRate), Pan: 0.0, Group: "Infrastructure", Bursty: true, }, // --- Web (Sawtooth, E3-A3, sustained) --- classify.ClassHTTPS: { BaseHz: 163.5, // E3 WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 163.5, SampleRate), Pan: -0.4, Group: "Web", }, classify.ClassHTTP: { BaseHz: 196.0, // G3 WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 196.0, SampleRate), Pan: -0.3, Group: "Web", }, classify.ClassQUIC: { BaseHz: 218.0, // A3 WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 218.0, SampleRate), Pan: -0.2, Group: "Web", }, // --- Mail (Triangle, C4-G4) --- classify.ClassSMTP: { BaseHz: 261.6, // C4 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 261.6, SampleRate), Pan: 0.2, Group: "Mail", }, classify.ClassIMAP: { BaseHz: 293.7, // D4 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 293.7, SampleRate), Pan: 0.3, Group: "Mail", }, classify.ClassPOP3: { BaseHz: 327.0, // E4 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 327.0, SampleRate), Pan: 0.4, Group: "Mail", }, classify.ClassSMTPSub: { BaseHz: 392.0, // G4 WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 392.0, SampleRate), Pan: 0.5, Group: "Mail", }, // --- Remote Access (Square, A4-E5) --- classify.ClassSSH: { BaseHz: 436.0, // A4 WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 436.0, SampleRate), Pan: -0.7, Group: "Remote Access", }, classify.ClassRDP: { BaseHz: 523.3, // C5 WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 523.3, SampleRate), Pan: -0.6, Group: "Remote Access", }, classify.ClassTelnet: { BaseHz: 587.3, // D5 WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 587.3, SampleRate), Pan: -0.5, Group: "Remote Access", }, classify.ClassVNC: { BaseHz: 654.1, // E5 WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 654.1, SampleRate), Pan: -0.4, Group: "Remote Access", }, // --- File Transfer (Square, G5-C6) --- classify.ClassFTP: { BaseHz: 784.0, // G5 WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 784.0, SampleRate), Pan: 0.5, Group: "File Transfer", }, classify.ClassSMB: { BaseHz: 872.1, // A5 WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 872.1, SampleRate), Pan: 0.6, Group: "File Transfer", }, classify.ClassTFTP: { BaseHz: 1046.5, // C6 WaveformType: WaveformSquare, Harmonics: WaveformPresetHarmonics(WaveformSquare, 1046.5, SampleRate), Pan: 0.7, Group: "File Transfer", }, // --- Unknown (Custom harmonics, D6-D7) --- // Dissonant harmonic character {1,1.0},{2,0.8},{3,0.4} retained for all Unknown entries. classify.ClassUnknown1: { BaseHz: 1174.7, // D6 Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: -0.9, Group: "Unknown", }, classify.ClassUnknown2: { BaseHz: 1308.1, // E6 Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: 0.9, Group: "Unknown", }, classify.ClassUnknown3: { BaseHz: 1568.0, // G6 Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: -0.7, Group: "Unknown", }, classify.ClassUnknown4: { BaseHz: 1744.2, // A6 Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: 0.7, Group: "Unknown", }, classify.ClassOtherTCP: { BaseHz: 2093.0, // C7 Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: -0.5, Group: "Unknown", }, classify.ClassOtherUDP: { BaseHz: 2349.3, // D7 Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: 0.5, Group: "Unknown", }, // --- Database (Sawtooth, E7-C8) --- classify.ClassMySQL: { BaseHz: 2616.1, // E7 WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 2616.1, SampleRate), Pan: -0.4, Group: "Database", }, classify.ClassPostgreSQL: { BaseHz: 3136.0, // G7 WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 3136.0, SampleRate), Pan: -0.2, Group: "Database", }, classify.ClassRedis: { BaseHz: 3488.4, // A7 WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 3488.4, SampleRate), Pan: 0.2, Group: "Database", }, classify.ClassMongoDB: { BaseHz: 4186.0, // C8 WaveformType: WaveformSawtooth, Harmonics: WaveformPresetHarmonics(WaveformSawtooth, 4186.0, SampleRate), Pan: 0.4, Group: "Database", }, // --- VoIP (Sine, D8) --- classify.ClassSIP: { BaseHz: 4704.0, // D8 WaveformType: WaveformSine, Harmonics: WaveformPresetHarmonics(WaveformSine, 4704.0, SampleRate), Pan: 0.0, Group: "VoIP", }, // --- Infrastructure auto-assigned (Triangle, pentatonic upper octaves) --- classify.ClassLDAP: { BaseHz: 5232.0, // E8 — auto-assign range WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 5232.0, SampleRate), Pan: -0.2, Group: "Infrastructure", Bursty: true, }, classify.ClassKerberos: { BaseHz: 5878.0, // G8 (approx) — auto-assign range WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 5878.0, SampleRate), Pan: 0.0, Group: "Infrastructure", Bursty: true, }, classify.ClassSyslog: { BaseHz: 6534.0, // A8 (approx) — auto-assign range WaveformType: WaveformTriangle, Harmonics: WaveformPresetHarmonics(WaveformTriangle, 6534.0, SampleRate), Pan: 0.2, Group: "Infrastructure", Bursty: true, }, }