(function() { var onDOMContentLoaded = function() { window.AudioContext = window.AudioContext || window.webkitAudioContext; try { // Create the instance of AudioContext var context = new AudioContext(); } catch (error) { window.alert(error.message + ' : Please use Chrome or Safari.'); return; } // Create the instance of OscillatorNode var oscillator = context.createOscillator(); // for Input var lfo = context.createOscillator(); // for LFO // for legacy browsers context.createGain = context.createGain || context.createGainNode; // Create the instance of GainNode var gain = context.createGain(); // for Volume var depth = context.createGain(); // for LFO // Parameters for the instance of OscillatorNode var type = oscillator.type; var frequency = oscillator.frequency.value; var detune = oscillator.detune.value; // Parameters for LFO var lfos ={ type : document.getElementById('form-lfo-type').elements['radio-lfo-type'][0].value, depth : document.getElementById('range-depth').valueAsNumber, rate : document.getElementById('range-rate').valueAsNumber }; // Flag for starting or stopping sound var isStop = true; /* * Event Listener */ // Start or Stop sound document.querySelector('button').addEventListener(EventWrapper.CLICK, function() { if (isStop) { // Create the instance of OscillatorNode oscillator = context.createOscillator(); lfo = context.createOscillator(); // for legacy browsers oscillator.start = oscillator.start || oscillator.noteOn; oscillator.stop = oscillator.stop || oscillator.noteOff; lfo.start = lfo.start || lfo.noteOn; lfo.stop = lfo.stop || lfo.noteOff; // OscillatorNode (Input) -> GainNode (Volume) -> AudioDestinationNode (Output) oscillator.connect(gain) gain.connect(context.destination); // OscillatorNode (LFO) -> GainNode (Depth) -> frequency (AudioParam) lfo.connect(depth); depth.connect(oscillator.frequency); // Set parameters oscillator.type = type; oscillator.detune.value = detune; // Set parameters for LFO lfo.type = lfos.type; oscillator.frequency.value = frequency; depth.gain.value = lfos.depth; lfo.frequency.value = lfos.rate; // Start sound oscillator.start(0); // Start LFO lfo.start(0); isStop = false; this.innerHTML = '<span class="icon-pause"></span>'; } else { // Stop sound oscillator.stop(0); // Stop LFO lfo.stop(0); isStop = true; this.innerHTML = '<span class="icon-start"></span>'; } }, false); // Control Volume document.getElementById('range-volume').addEventListener('input', function() { var min = gain.gain.minValue || 0; var max = gain.gain.maxValue || 1; if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) { gain.gain.value = this.valueAsNumber; document.getElementById('output-volume').textContent = this.value; } }, false); // Select type document.getElementById('form-wave-type').addEventListener('change', function() { for (var i = 0, len = this.elements['radio-wave-type'].length; i < len; i++) { if (this.elements['radio-wave-type'][i].checked) { oscillator.type = type = (typeof oscillator.type === 'string') ? this.elements['radio-wave-type'][i].value : i; break; } } }, false); // Control frequency document.getElementById('range-frequency').addEventListener('input', function() { var min = oscillator.frequency.minValue || 0; var max = oscillator.frequency.maxValue || 100000; if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) { oscillator.frequency.value = frequency = this.valueAsNumber; document.getElementById('output-frequency').textContent = this.value; } }, false); // Control detune document.getElementById('range-detune').addEventListener('input', function() { var min = oscillator.detune.minValue || -4800; var max = oscillator.detune.maxValue || 4800; if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) { oscillator.detune.value = detune = this.valueAsNumber; document.getElementById('output-detune').textContent = this.value; } }, false); // Select LFO Type document.getElementById('form-lfo-type').addEventListener('change', function() { for (var i = 0, len = this.elements['radio-lfo-type'].length; i < len; i++) { if (this.elements['radio-lfo-type'][i].checked) { lfo.type = lfos.type = (typeof lfo.type === 'string') ? this.elements['radio-lfo-type'][i].value : i; break; } } }, false); // Control Depth document.getElementById('range-depth').addEventListener('input', function() { depth.gain.value = lfos.depth = this.valueAsNumber; document.getElementById('output-depth').textContent = this.value; }, false); // Control Rate document.getElementById('range-rate').addEventListener('input', function() { var min = lfo.frequency.minValue || 0; var max = lfo.frequency.maxValue || 100000; if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) { lfo.frequency.value = lfos.rate = this.valueAsNumber; document.getElementById('output-rate').textContent = this.value; } }, false); // Output frequency in the instance of OscillatorNode window.setInterval(function() { console.log(oscillator.frequency.value); }, 500); }; if ((document.readyState === 'interactive') || (document.readyState === 'complete')) { onDOMContentLoaded(); } else { document.addEventListener('DOMContentLoaded', onDOMContentLoaded, true); } })();
function EventWrapper(){ } (function(){ var click = ''; var start = ''; var move = ''; var end = ''; // Touch Panel ? if (/iPhone|iPad|iPod|Android/.test(navigator.userAgent)) { click = 'click'; start = 'touchstart'; move = 'touchmove'; end = 'touchend'; } else { click = 'click'; start = 'mousedown'; move = 'mousemove'; end = 'mouseup'; } EventWrapper.CLICK = click; EventWrapper.START = start; EventWrapper.MOVE = move; EventWrapper.END = end; })();