mirror of
https://github.com/Tonejs/Tone.js
synced 2024-11-16 08:38:00 +00:00
130 lines
No EOL
2.8 KiB
JavaScript
130 lines
No EOL
2.8 KiB
JavaScript
define(["Tone/core/Tone", "Tone/effect/Effect"], function(Tone){
|
|
|
|
/**
|
|
* @class downsample incoming signal
|
|
* inspiration from https://github.com/jaz303/bitcrusher/blob/master/index.js
|
|
*
|
|
* @constructor
|
|
* @extends {Tone.Effect}
|
|
* @param {number=} bits
|
|
* @param {number=} frequency
|
|
*/
|
|
Tone.BitCrusher = function(bits, frequency){
|
|
|
|
Tone.Effect.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.connectEffect(this._crusher);
|
|
};
|
|
|
|
Tone.extend(Tone.BitCrusher, Tone.Effect);
|
|
|
|
/**
|
|
* @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;
|
|
};
|
|
|
|
/**
|
|
* set all of the parameters with an object
|
|
* @param {Object} params
|
|
*/
|
|
Tone.BitCrusher.prototype.set = function(params){
|
|
if (!this.isUndef(params.frequency)) this.setFrequency(params.frequency);
|
|
if (!this.isUndef(params.bits)) this.setBits(params.bits);
|
|
Tone.Effect.prototype.set.call(this, params);
|
|
};
|
|
|
|
/**
|
|
* clean up
|
|
*/
|
|
Tone.BitCrusher.prototype.dispose = function(){
|
|
Tone.Effect.prototype.dispose.call(this);
|
|
this._crusher.disconnect();
|
|
this._crusher = null;
|
|
};
|
|
|
|
return Tone.BitCrusher;
|
|
}); |