Hey there! I recently delved into exploring the web audio API and put together a simple synthesizer to get familiar with its features. However, I've encountered an issue where the audio gets distorted when subjected to intense sound input. If anyone well-versed in the API could spare a moment to glance over my code and point out any glaring mistakes or omissions that might be causing this distortion problem, it would be greatly appreciated. The problem persists across Safari, Chrome, and Firefox browsers. You can check out the demo version HERE. Thanks a bunch for any assistance!
// initializing a new audio session.
var context = new (window.webkitAudioContext || window.AudioContext || window.mozAudioContext)
function playSound(note) {
oscillator = context.createOscillator();
// create volume controller
var gainNode = context.createGain();
// connect signal to default audio output (speakers)
oscillator.connect(gainNode);
gainNode.connect(context.destination);
// adjust frequency by 50%, 100%, or 200%
var octave = document.getElementById('octave').value;
// set oscillator frequency
oscillator.frequency.value = frequencies[note] * octave;
// set oscillator wave type
oscillator.type = document.getElementById('waveSelect').value;
// initialize gain at 0 and ramp up quickly to avoid audible pop
gainNode.gain.value = 0;
var quickFadeIn = gainNode.gain.setTargetAtTime(1, context.currentTime, 0.1);
// start the oscillator after a slight delay
oscillator.start(context.currentTime + 0.05);
/**
* AUDIO EFFECTS
*/
function delayNode() {
// implement delay effect
var delay = context.createDelay();
delay.delayTime.value = 0.5;
gainNode;
quickFadeIn;
// create feedback loop
oscillator.connect(gainNode);
gainNode.connect(delay);
delay.connect(gainNode);
delay.connect(context.destination);
// reduce gain
quickFadeOut;
}
function distortionNode() {
// apply distortion effect using createWaveShaper
var distortion = context.createWaveShaper();
// generate distortion curve based on provided amount
function makeDistortionCurve(amount) {
//...
};
distortion.curve = makeDistortionCurve(500);
distortion.oversample = '4x';
gainNode;
quickFadeIn;
oscillator.connect(gainNode);
gainNode.connect(distortion);
distortion.connect(context.destination);
// decrease gain
quickFadeOut;
}
if (document.getElementById('toggleDelay').value == 'true'){delayNode();}
if (document.getElementById('toggleDistortion').value == 'true'){distortionNode();}
// determine note duration
var sustain = parseFloat(document.getElementById('sustain').value);
// stop the oscillator smoothly to prevent click sound
var quickFadeOut = gainNode.gain.setTargetAtTime(0, context.currentTime + sustain, 0.0015);
// change key color on keypress
// ...
}
// functionality for the second keyboard follows similar logic as playSound()
// reveal second keyboard section
function displayKeyboard2(lowersynth, uppersynth) {
//...
}