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 } // ClassFreqConfigs maps each traffic class to its synthesis parameters. // Frequencies use musical intervals per D-02/D-03. Harmonics per D-05/D-06. // Pan positions per D-12. var ClassFreqConfigs = map[classify.TrafficClass]FreqConfig{ classify.ClassICMP: {BaseHz: 65.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.4}, {3, 0.15}}, Pan: 0.0}, classify.ClassDNS: {BaseHz: 110.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.5}, {3, 0.25}}, Pan: -0.2}, classify.ClassHTTPS: {BaseHz: 175.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.6}, {3, 0.3}}, Pan: 0.2}, classify.ClassHTTP: {BaseHz: 220.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.5}, {4, 0.2}}, Pan: -0.35}, classify.ClassSSH: {BaseHz: 330.0, Harmonics: []HarmonicDef{{1, 1.0}, {3, 0.6}, {5, 0.3}}, Pan: 0.35}, classify.ClassSMTP: {BaseHz: 440.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.3}, {3, 0.1}}, Pan: -0.55}, classify.ClassNTP: {BaseHz: 520.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.25}}, Pan: 0.55}, classify.ClassDHCP: {BaseHz: 600.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.35}, {3, 0.15}}, Pan: -0.75}, classify.ClassOtherTCP: {BaseHz: 700.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.2}}, Pan: 0.75}, classify.ClassOtherUDP: {BaseHz: 780.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.2}}, Pan: -0.75}, // D-05: Unknown buckets in 850-1100 Hz dissonant range, detuned intervals // D-06: Same dissonant harmonic character {1,1.0},{2,0.8},{3,0.4} for all 4 classify.ClassUnknown1: {BaseHz: 862.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: 0.6}, classify.ClassUnknown2: {BaseHz: 920.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: -0.6}, classify.ClassUnknown3: {BaseHz: 981.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: 0.9}, classify.ClassUnknown4: {BaseHz: 1047.0, Harmonics: []HarmonicDef{{1, 1.0}, {2, 0.8}, {3, 0.4}}, Pan: -0.9}, }