package synth_test import ( "testing" "github.com/netsynth/netsynth/synth" ) func TestEMAAmplitudeRise(t *testing.T) { cfg2 := synth.FreqConfig{ BaseHz: 440.0, Harmonics: []synth.HarmonicDef{{Ratio: 1, Amplitude: 1.0}}, Pan: 0.0, } layer := synth.NewLayer(cfg2, synth.SampleRate, 1.0) // Force the layer to have been seen and set target to 1.0 layer.UpdateTarget(100, 100) // After 1 second (SampleRate samples) with tau=1.0, currentAmp should be > 0.5 // EMA: after tau seconds, amplitude reaches ~63% of target for i := 0; i < synth.SampleRate; i++ { layer.AdvanceSample() } if layer.CurrentAmp() <= 0.5 { t.Errorf("expected currentAmp > 0.5 after 1 second rise, got %.4f", layer.CurrentAmp()) } } func TestEMAAmplitudeDecay(t *testing.T) { cfg := synth.FreqConfig{ BaseHz: 440.0, Harmonics: []synth.HarmonicDef{{Ratio: 1, Amplitude: 1.0}}, Pan: 0.0, } layer := synth.NewLayer(cfg, synth.SampleRate, 1.0) // Set up: layer has been seen (currentAmp starts at 1.0) and target is whisper floor // We'll manually prime by updating target with 100/100 first then re-route to whisper layer.UpdateTarget(100, 100) // mark as seen, target=1.0 // Force currentAmp to 1.0 by running a few cycles at target 1.0 for i := 0; i < synth.SampleRate*3; i++ { layer.AdvanceSample() } // Now decay: set count=0 (whisper floor kicks in) layer.UpdateTarget(0, 100) // After 1 second, currentAmp should be < 0.5 for i := 0; i < synth.SampleRate; i++ { layer.AdvanceSample() } if layer.CurrentAmp() >= 0.5 { t.Errorf("expected currentAmp < 0.5 after 1 second decay, got %.4f", layer.CurrentAmp()) } } func TestWhisperFloor(t *testing.T) { cfg := synth.FreqConfig{ BaseHz: 440.0, Harmonics: []synth.HarmonicDef{{Ratio: 1, Amplitude: 1.0}}, Pan: 0.0, } layer := synth.NewLayer(cfg, synth.SampleRate, 1.0) // Mark layer as seen by passing count=1, then set count=0 layer.UpdateTarget(1, 100) layer.UpdateTarget(0, 100) // Target should be whisper floor (not zero) because seen=true if layer.TargetAmp() < synth.WhisperFloor { t.Errorf("expected targetAmp >= WhisperFloor (%.2f) for seen layer at zero count, got %.4f", synth.WhisperFloor, layer.TargetAmp()) } } func TestWhisperFloorNotSeenIsZero(t *testing.T) { cfg := synth.FreqConfig{ BaseHz: 440.0, Harmonics: []synth.HarmonicDef{{Ratio: 1, Amplitude: 1.0}}, Pan: 0.0, } layer := synth.NewLayer(cfg, synth.SampleRate, 1.0) // Never seen — UpdateTarget with zero count layer.UpdateTarget(0, 100) if layer.TargetAmp() != 0.0 { t.Errorf("expected targetAmp == 0.0 for unseen layer, got %.4f", layer.TargetAmp()) } }