fix(09-01): add TestGroupFieldPopulated, fix oscillator normalization, update tests
- Add TestGroupFieldPopulated test to verify all ClassFreqConfigs have non-empty Group (GRP-01) - Change TestHarmonicsNonEmpty threshold from < 2 to < 1 (accepts single-harmonic sine entries) - Fix oscillator Advance() to use math.Abs(h.Amplitude) for normalization weight accumulation: triangle wave uses alternating-sign amplitudes; signed sum underestimates totalWeight causing output to exceed [-1,1] bounds when using WaveformPresetHarmonics (Rule 1 bug fix) - Update TestStereoPan to use ClassSSH (pan=-0.7) instead of ClassDHCP (pan changed to 0.1) - Update TestNewBankCustomConfigNoClip: passes after oscillator normalization fix - Fix TestLoadPartialOverrideFrequency: derive expected WaveformType from defaults (not hardcoded 0) - Fix TestAutoFreqSkipsBuiltins: derive expected HTTPS BaseHz from defaults (150.0 in Phase 9)
This commit is contained in:
+4
-1
@@ -15,12 +15,15 @@ func NewOscillator(freq float64, sampleRate int) *Oscillator {
|
||||
}
|
||||
|
||||
// Advance returns one sample: fundamental + harmonics summed and normalized to [-1, 1].
|
||||
// Normalization uses sum of absolute amplitudes so that alternating-sign harmonic series
|
||||
// (e.g. triangle wave) are correctly bounded. Without math.Abs, signed cancellation
|
||||
// produces an inflated normalization denominator that causes output to exceed [-1, 1].
|
||||
func (o *Oscillator) Advance(harmonics []HarmonicDef) float64 {
|
||||
sum := 0.0
|
||||
totalWeight := 0.0
|
||||
for _, h := range harmonics {
|
||||
sum += h.Amplitude * math.Sin(2*math.Pi*o.phase*float64(h.Ratio))
|
||||
totalWeight += h.Amplitude
|
||||
totalWeight += math.Abs(h.Amplitude)
|
||||
}
|
||||
o.phase += o.freq / o.sr
|
||||
if o.phase >= 1.0 {
|
||||
|
||||
Reference in New Issue
Block a user