2026-03-26 11:57:43 +01:00
|
|
|
package synth_test
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
"github.com/netsynth/netsynth/classify"
|
|
|
|
|
"github.com/netsynth/netsynth/synth"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestAllClassesHaveConfig(t *testing.T) {
|
|
|
|
|
for _, class := range classify.AllClasses() {
|
|
|
|
|
if _, ok := synth.ClassFreqConfigs[class]; !ok {
|
|
|
|
|
t.Errorf("class %q has no entry in ClassFreqConfigs", class)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFrequenciesInRange(t *testing.T) {
|
2026-03-27 08:54:34 +01:00
|
|
|
const nyquist = float64(synth.SampleRate) / 2.0 // 22050 Hz
|
2026-03-26 11:57:43 +01:00
|
|
|
for class, cfg := range synth.ClassFreqConfigs {
|
2026-03-27 08:54:34 +01:00
|
|
|
if cfg.BaseHz <= 0 {
|
|
|
|
|
t.Errorf("class %q BaseHz=%.1f must be positive", class, cfg.BaseHz)
|
|
|
|
|
}
|
|
|
|
|
if cfg.BaseHz >= nyquist {
|
|
|
|
|
t.Errorf("class %q BaseHz=%.1f exceeds Nyquist (%.1f Hz)", class, cfg.BaseHz, nyquist)
|
2026-03-26 11:57:43 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFrequenciesUnique(t *testing.T) {
|
|
|
|
|
seen := make(map[float64]classify.TrafficClass)
|
|
|
|
|
for class, cfg := range synth.ClassFreqConfigs {
|
|
|
|
|
if prev, exists := seen[cfg.BaseHz]; exists {
|
|
|
|
|
t.Errorf("classes %q and %q share the same BaseHz=%.1f", prev, class, cfg.BaseHz)
|
|
|
|
|
}
|
|
|
|
|
seen[cfg.BaseHz] = class
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestHarmonicsNonEmpty(t *testing.T) {
|
|
|
|
|
for class, cfg := range synth.ClassFreqConfigs {
|
2026-03-27 14:15:27 +01:00
|
|
|
if len(cfg.Harmonics) < 1 {
|
|
|
|
|
t.Errorf("class %q has no harmonics (got %d)", class, len(cfg.Harmonics))
|
2026-03-26 11:57:43 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPanPositionsInRange(t *testing.T) {
|
|
|
|
|
for class, cfg := range synth.ClassFreqConfigs {
|
|
|
|
|
if cfg.Pan < -1.0 || cfg.Pan > 1.0 {
|
|
|
|
|
t.Errorf("class %q Pan=%.2f is out of range [-1.0, 1.0]", class, cfg.Pan)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-26 13:11:24 +01:00
|
|
|
|
2026-03-27 08:54:34 +01:00
|
|
|
func TestClassFreqConfigsMatchAllClasses(t *testing.T) {
|
2026-03-26 17:38:37 +01:00
|
|
|
if len(synth.ClassFreqConfigs) != len(classify.AllClasses()) {
|
|
|
|
|
t.Errorf("ClassFreqConfigs has %d entries but AllClasses() has %d entries",
|
|
|
|
|
len(synth.ClassFreqConfigs), len(classify.AllClasses()))
|
2026-03-26 13:11:24 +01:00
|
|
|
}
|
|
|
|
|
}
|
2026-03-27 14:15:27 +01:00
|
|
|
|
|
|
|
|
func TestGroupFieldPopulated(t *testing.T) {
|
|
|
|
|
for class, cfg := range synth.ClassFreqConfigs {
|
|
|
|
|
if cfg.Group == "" {
|
|
|
|
|
t.Errorf("class %q has empty Group field in ClassFreqConfigs", class)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|