ホワイトノイズの生成 | ScriptProcessorNode

START / STOP
(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;
        }

        // for legacy browsers
        context.createScriptProcessor = context.createScriptProcessor || context.createJavaScriptNode;

        // for selecting optimized buffer size
        var getBufferSize = function() {
            if (/(Win(dows )?NT 6\.2)/.test(navigator.userAgent)) {
                return 1024;  // Windows 8
            } else if (/(Win(dows )?NT 6\.1)/.test(navigator.userAgent)) {
                return 1024;  // Windows 7
            } else if (/(Win(dows )?NT 6\.0)/.test(navigator.userAgent)) {
                return 2048;  // Windows Vista
            } else if (/Win(dows )?(NT 5\.1|XP)/.test(navigator.userAgent)) {
                return 4096;  // Windows XP
            } else if (/Mac|PPC/.test(navigator.userAgent)) {
                return 1024;  // Mac OS X
            } else if (/Linux/.test(navigator.userAgent)) {
                return 8192;  // Linux
            } else if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
                return 2048;  // iOS
            } else {
                return 16384;  // Otherwise
            }
        };

        // Create the instance of ScriptProcessorNode
        var processor = context.createScriptProcessor(getBufferSize(), 2, 2);

        // for iOS
        var dummy = context.createBufferSource();

        var volume = document.getElementById('range-volume').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) {
                // Start onaudioprocess event

                // (AudioBufferSourceNode ->) ScriptProcessorNode (Input) -> AudioDestinationNode (Output)
                dummy.connect(processor);
                processor.connect(context.destination);

                processor.onaudioprocess = function(event) {
                    // Get the instance of Float32Array for output data (Array size equals buffer size)
                    var outputLs = event.outputBuffer.getChannelData(0);  // Left  channel
                    var outputRs = event.outputBuffer.getChannelData(1);  // Right channel

                    for (var i = 0; i < this.bufferSize; i++) {
                        outputLs[i] = volume * (2 * (Math.random() - 0.5));  // between -1 and 1
                        outputRs[i] = volume * (2 * (Math.random() - 0.5));  // between -1 and 1
                    }
                };

                isStop = false;
                this.innerHTML = '<span class="icon-pause"></span>';
            } else {
                // Stop onaudioprocess event
                processor.disconnect();
                processor.onaudioprocess = null;

                isStop = true;
                this.innerHTML = '<span class="icon-start"></span>';
            }
        }, false);

        // Control Volume (without GainNode)
        document.getElementById('range-volume').addEventListener('input', function() {
            var min = 0;
            var max = 1;

            if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) {
                volume = this.valueAsNumber;
                document.getElementById('output-volume').textContent = this.value;
            }
        }, false);
    };

    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;
})();