Tone.js/Tone/signal/BitCrusher.js
2014-06-20 00:38:14 -04:00

123 lines
No EOL
2.5 KiB
JavaScript

define(["Tone/core/Tone"], function(Tone){
/**
* downsample incoming signal
* inspiration from https://github.com/jaz303/bitcrusher/blob/master/index.js
*
* @constructor
* @extends {Tone}
* @param {number=} bits
* @param {number=} frequency
*/
Tone.BitCrusher = function(bits, frequency){
Tone.call(this);
/**
* @private
* @type {number}
*/
this._bits = this.defaultArg(bits, 8);
/**
* @private
* @type {number}
*/
this._frequency = this.defaultArg(frequency, 0.5);
/**
* @private
* @type {number}
*/
this._step = 2 * Math.pow(0.5, this._bits);
/**
* @private
* @type {number}
*/
this._invStep = 1/this._step;
/**
* @private
* @type {number}
*/
this._phasor = 0;
/**
* @private
* @type {number}
*/
this._last = 0;
/**
* @private
* @type {ScriptProcessorNode}
*/
this._crusher = this.context.createScriptProcessor(this.bufferSize, 1, 1);
this._crusher.onaudioprocess = this._audioprocess.bind(this);
//connect it up
this.chain(this.input, this._crusher, this.output);
};
Tone.extend(Tone.BitCrusher);
/**
* @private
* @param {AudioProcessingEvent} event
*/
Tone.BitCrusher.prototype._audioprocess = function(event){
//cache the values used in the loop
var phasor = this._phasor;
var freq = this._frequency;
var invStep = this._invStep;
var last = this._last;
var step = this._step;
var input = event.inputBuffer.getChannelData(0);
var output = event.outputBuffer.getChannelData(0);
for (var i = 0, len = output.length; i < len; i++) {
phasor += freq;
if (phasor >= 1) {
phasor -= 1;
last = step * ((input[i] * invStep) | 0 + 0.5);
}
output[i] = last;
}
//set the values for the next loop
this._phasor = phasor;
this._last = last;
};
/**
* set the bit rate
*
* @param {number} bits
*/
Tone.BitCrusher.prototype.setBits = function(bits){
this._bits = bits;
this._step = 2 * Math.pow(0.5, this._bits);
this._invStep = 1/this._step;
};
/**
* set the frequency
* @param {number} freq
*/
Tone.BitCrusher.prototype.setFrequency = function(freq){
this._frequency = freq;
};
/**
* clean up
*/
Tone.BitCrusher.prototype.dispose = function(){
this.input.disconnect();
this.output.disconnect();
this._crusher.disconnect();
this.input = null;
this.output = null;
this._crusher = null;
};
return Tone.BitCrusher;
});