X-Git-Url: https://git.r.bdr.sh/rbdr/r.bdr.sh/blobdiff_plain/bd7473dd12925b32132a9113118361010baa2978..2c6986306e9a5c8ef18f264c158e6cf9cb3bd2df:/jekyll/js/unlimited_pizza/pepperoni.js diff --git a/jekyll/js/unlimited_pizza/pepperoni.js b/jekyll/js/unlimited_pizza/pepperoni.js index d874243..12dca9d 100644 --- a/jekyll/js/unlimited_pizza/pepperoni.js +++ b/jekyll/js/unlimited_pizza/pepperoni.js @@ -1,32 +1,92 @@ +'use strict'; + Class(UnlimitedPizza, "Pepperoni").inherits(Widget)({ INNER_HTML : ' \ - \ +Record. \
\
\
\
\
\ - X \ + Clear recording. \
\ \ +
\ + \ + \ + \ + \ + \ +
\
\ ', - PAUSE : '▐▐', - RECORD : '⬤', + PAUSE : 'Pause.', + RECORD : 'Record.', prototype : { maxSize : 1048576, recording : false, source : null, recorder : null, context : null, + _delayNode : null, + _bandPassFilterNode : null, + _hiPassFilterNode : null, + _loPassFilterNode : null, + _convolverNode : null, + _distortionNode : null, + _activatedNodes : null, workerPath : '/js/vendor/recorderjs/recorderWorker.js', init : function init(config) { + var channels, frameCount, reverbBuffer, request, requestHandler; + Widget.prototype.init.call(this, config); if (!this.context) { this.context = new (window.AudioContext || window.webkitAudioContext)(); } + this._delayNode = this.context.createDelay(1.0); + this._bandPassFilterNode = this.context.createBiquadFilter(); + this._hiPassFilterNode = this.context.createBiquadFilter(); + this._loPassFilterNode = this.context.createBiquadFilter(); + this._convolverNode = this.context.createConvolver(); + this._distortionNode = this.context.createWaveShaper(); + + this._distortionNode.curve = this._generateDistortion(400); + this._distortionNode.oversample = '4x'; + + this._activatedNodes = []; + + // config lo pass + this._loPassFilterNode.type = "lowpass"; + this._loPassFilterNode.frequency.value = 1000; + this._loPassFilterNode.gain.value = 25; + + // config hi pass + this._hiPassFilterNode.type = "highpass"; + this._hiPassFilterNode.frequency.value = 3000; + this._hiPassFilterNode.gain.value = 25; + + // config band pass + this._bandPassFilterNode.type = "bandpass"; + this._bandPassFilterNode.frequency.value = 2000; + this._bandPassFilterNode.gain.value = 25; + + requestHandler = function bufferFile(ev) { + var request = ev.target; + console.log("Reverb loading"); + this.context.decodeAudioData(request.response, function(buffer){ + console.log("Reverb loaded"); + this._convolverNode.buffer = buffer; + }.bind(this)); + }.bind(this); + + request = new XMLHttpRequest(); + request.open('GET', '/reverb.ogg', true); + request.responseType = 'arraybuffer'; + request.addEventListener('load', requestHandler, false); + request.send(); + if (!this.source) { this._getUserMedia({ audio : true @@ -40,6 +100,7 @@ Class(UnlimitedPizza, "Pepperoni").inherits(Widget)({ this.audioElement = this.element.find('audio'); this.progressBarContainer = this.element.find('.record-progress-bar-container'); this.progressBar = this.element.find('.record-progress-bar'); + this.switches = this.element.find('.filter-switch'); this._bindEvents(); }, @@ -91,6 +152,8 @@ Class(UnlimitedPizza, "Pepperoni").inherits(Widget)({ }, _bindEvents : function bindEvents() { + var pepperoni = this; + this.controlButton.on('click', function () { if (this.recording) { this.stop(); @@ -104,6 +167,63 @@ Class(UnlimitedPizza, "Pepperoni").inherits(Widget)({ this.clear(); } }.bind(this)) + + this.switches.on('change', function (ev) { + if (!pepperoni.source) { + this.checked = false; + return false; + } + switch (this.name) { + case 'delay-filter': + if (this.checked) { + pepperoni._addNode(pepperoni._delayNode); + } else { + pepperoni._removeNode(pepperoni._delayNode); + } + break; + + case 'hipass-filter': + if (this.checked) { + pepperoni._addNode(pepperoni._hiPassFilterNode); + } else { + pepperoni._removeNode(pepperoni._hiPassFilterNode); + } + break; + + case 'bandpass-filter': + if (this.checked) { + pepperoni._addNode(pepperoni._bandPassFilterNode); + } else { + pepperoni._removeNode(pepperoni._bandPassFilterNode); + } + break; + + case 'lopass-filter': + if (this.checked) { + pepperoni._addNode(pepperoni._loPassFilterNode); + } else { + pepperoni._removeNode(pepperoni._loPassFilterNode); + } + break; + + case 'reverb-filter': + if (this.checked) { + pepperoni._addNode(pepperoni._convolverNode); + } else { + pepperoni._removeNode(pepperoni._convolverNode); + } + break; + + case 'distort-filter': + if (this.checked) { + pepperoni._addNode(pepperoni._distortionNode); + } else { + pepperoni._removeNode(pepperoni._distortionNode); + } + + break; + } + }); }, _onRecording : function _onRecording(buffer) { @@ -143,6 +263,72 @@ Class(UnlimitedPizza, "Pepperoni").inherits(Widget)({ }.bind(this)); }, + _addNode : function _addNode(node) { + var i; + + i = this._activatedNodes.length; + + this._activatedNodes.push(node); + + if (i === 0) { + this.source.disconnect(); + this.source.connect(node); + } else { + this._activatedNodes[i - 1].disconnect(); + this._activatedNodes[i - 1].connect(node); + } + + node.connect(this.recorder.node); + this.recorder.context = node.context; + this.recorder.node.connect(this.recorder.context.destination) + + console.log("Adding: ", node); + }, + + _removeNode : function _removeNode(node) { + var i; + + i = this._activatedNodes.indexOf(node); + + node.disconnect(); + + if (i === 0 && i + 1 === this._activatedNodes.length) { + // It was the only one, connect source to recorder. + this.source.disconnect(); + this.source.connect(this.recorder.node); + } else if (i === 0) { + // Normal 0 case, connect source to node. Recorder stays the same + this.source.disconnect(); + this.source.connect(this._activatedNodes[i+1]); + } else if (i + 1 === this._activatedNodes.length) { + // It's not the 0 case, but we need to reconnect to recorder. + this._activatedNodes[i - 1].disconnect(); + this._activatedNodes[i - 1].connect(this.recorder.node); + } else { + // Normal case, connect previous node to node + this._activatedNodes[i - 1].disconnect(); + this._activatedNodes[i - 1].connect(this._activatedNodes[i + 1]); + } + + this._activatedNodes.splice(i, 1); + + console.log("Removing: ", node); + }, + + _generateDistortion : function generateDistortion(amount) { + var k = typeof amount === 'number' ? amount : 50, + n_samples = 44100, + curve = new Float32Array(n_samples), + deg = Math.PI / 180, + i = 0, + x; + for ( ; i < n_samples; ++i ) { + x = i * 2 / n_samples - 1; + curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) ); + } + return curve; + }, + // Normalize get user media _getUserMedia : (navigator.getUserMedia || navigator.webkitGetUserMedia ||