diff --git a/src/lib/audio/effects/volume-effect.js b/src/lib/audio/effects/volume-effect.js index 0cfcd64152c151ce156e9a1a594cdb11550b5ca5..a5d12a98709803008326227f4a61df0098b59763 100644 --- a/src/lib/audio/effects/volume-effect.js +++ b/src/lib/audio/effects/volume-effect.js @@ -14,8 +14,16 @@ class VolumeEffect { this.gain.gain.setValueAtTime(volume, endSeconds); this.gain.gain.exponentialRampToValueAtTime(1.0, endSeconds + this.rampLength); + // Use a waveshaper node to prevent sample values from exceeding -1 or 1. + // Without this, gain can cause samples to exceed this range, then they + // are clipped on save, and the sound is distorted on load. + this.waveShaper = this.audioContext.createWaveShaper(); + this.waveShaper.curve = new Float32Array([-1, 1]); + this.waveShaper.oversample = 'none'; + this.input.connect(this.gain); - this.gain.connect(this.output); + this.gain.connect(this.waveShaper); + this.waveShaper.connect(this.output); } }