UNPKG

tone

Version:

A Web Audio framework for making interactive music in the browser.

103 lines 4.92 kB
import * as tslib_1 from "tslib"; import { ToneAudioWorklet } from "../core/context/ToneAudioWorklet"; import { Effect } from "./Effect"; import { Gain } from "../core/context/Gain"; import { optionsFromArguments } from "../core/util/Defaults"; import { connectSeries } from "../core/context/ToneAudioNode"; import { Param } from "../core/context/Param"; /** * BitCrusher down-samples the incoming signal to a different bit depth. * Lowering the bit depth of the signal creates distortion. Read more about BitCrushing * on [Wikipedia](https://en.wikipedia.org/wiki/Bitcrusher). * @example * import { BitCrusher, Synth } from "tone"; * // initialize crusher and route a synth through it * const crusher = new BitCrusher(4).toDestination(); * const synth = new Synth().connect(crusher); * synth.triggerAttackRelease("C2", 2); * * @category Effect */ var BitCrusher = /** @class */ (function (_super) { tslib_1.__extends(BitCrusher, _super); function BitCrusher() { var _this = _super.call(this, optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"])) || this; _this.name = "BitCrusher"; var options = optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]); _this._bitCrusherWorklet = new BitCrusherWorklet({ context: _this.context, bits: options.bits, }); // connect it up _this.connectEffect(_this._bitCrusherWorklet); _this.bits = _this._bitCrusherWorklet.bits; return _this; } BitCrusher.getDefaults = function () { return Object.assign(Effect.getDefaults(), { bits: 4, frequencyReduction: 0.5, }); }; BitCrusher.prototype.dispose = function () { _super.prototype.dispose.call(this); this._bitCrusherWorklet.dispose(); return this; }; return BitCrusher; }(Effect)); export { BitCrusher }; /** * Internal class which creates an AudioWorklet to do the bit crushing */ var BitCrusherWorklet = /** @class */ (function (_super) { tslib_1.__extends(BitCrusherWorklet, _super); function BitCrusherWorklet() { var _this = _super.call(this, optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments)) || this; _this.name = "BitCrusherWorklet"; _this.workletOptions = { numberOfInputs: 1, numberOfOutputs: 1, }; var options = optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments); _this.input = new Gain({ context: _this.context }); _this.output = new Gain({ context: _this.context }); var dummyGain = _this.context.createGain(); _this.bits = new Param({ context: _this.context, value: options.bits, units: "positive", minValue: 1, maxValue: 16, param: dummyGain.gain, swappable: true, }); return _this; } BitCrusherWorklet.getDefaults = function () { return Object.assign(ToneAudioWorklet.getDefaults(), { bits: 12, }); }; BitCrusherWorklet.prototype._audioWorkletName = function () { return "bit-crusher"; }; BitCrusherWorklet.prototype._audioWorklet = function () { return /* javascript */ " \n\t\tregisterProcessor(\"" + this._audioWorkletName() + "\", class extends AudioWorkletProcessor {\n\t\t\tstatic get parameterDescriptors () {\n\t\t\t\treturn [{\n\t\t\t\t\tname: 'bits',\n\t\t\t\t\tdefaultValue: 12,\n\t\t\t\t\tminValue: 1,\n\t\t\t\t\tmaxValue: 16\n\t\t\t\t}];\n\t\t\t}\n\t\t\t\n\t\t\tprocess (inputs, outputs, parameters) {\n\t\t\t\tconst input = inputs[0];\n\t\t\t\tconst output = outputs[0];\n\t\t\t\tif (input && output && input.length === output.length) {\n\t\t\t\t\tconst bits = parameters.bits;\n\t\t\t\t\tfor (let channelNum = 0; channelNum < input.length; channelNum++) {\n\t\t\t\t\t\tconst inputChannel = input[channelNum];\n\t\t\t\t\t\tfor (let index = 0; index < inputChannel.length; index++) {\n\t\t\t\t\t\t\tconst value = inputChannel[index];\n\t\t\t\t\t\t\tconst step = bits.length > 1 ? Math.pow(0.5, bits[index]) : Math.pow(0.5, bits[0]);\n\t\t\t\t\t\t\tconst val = step * Math.floor(value / step + 0.5);\n\t\t\t\t\t\t\toutput[channelNum][index] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t});\n\t\t"; }; BitCrusherWorklet.prototype.onReady = function (node) { connectSeries(this.input, node, this.output); // @ts-ignore var bits = node.parameters.get("bits"); this.bits.setParam(bits); }; BitCrusherWorklet.prototype.dispose = function () { _super.prototype.dispose.call(this); this.input.dispose(); this.output.dispose(); this.bits.dispose(); return this; }; return BitCrusherWorklet; }(ToneAudioWorklet)); //# sourceMappingURL=BitCrusher.js.map