mirror of
https://github.com/Tonejs/Tone.js
synced 2024-11-17 00:58:09 +00:00
126 lines
No EOL
2.6 KiB
JavaScript
126 lines
No EOL
2.6 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;
|
|
};
|
|
|
|
/**
|
|
* pointer to the parent's dipose method
|
|
* @private
|
|
*/
|
|
Tone.BitCrusher.prototype._effectDispose = Tone.Effect.prototype.dispose;
|
|
|
|
/**
|
|
* clean up
|
|
*/
|
|
Tone.BitCrusher.prototype.dispose = function(){
|
|
this._effectDispose();
|
|
this._crusher.disconnect();
|
|
this._crusher = null;
|
|
};
|
|
|
|
return Tone.BitCrusher;
|
|
}); |