UNPKG

adsr-gain-node

Version:

A simple and small nodejs module for creating an adsr gain node

111 lines (92 loc) 3.06 kB
function AdsrGainNode(ctx) { this.ctx = ctx; this.mode = 'exponentialRampToValueAtTime'; // this.mode = 'linearRampToValueAtTime'; this.options = { attackAmp: 0.1, decayAmp: 0.3, sustainAmp: 0.7, releaseAmp: 0.01, attackTime: 0.1, decayTime: 0.2, sustainTime: 1.0, releaseTime: 3.4, autoRelease: true }; /** * Set options or use defaults * @param {object} options */ this.setOptions = function (options) { this.options = Object.assign(this.options, options); }; this.gainNode this.audioTime /** * Get a gain node from defined options * @param {float} audioTime an audio context time stamp */ this.getGainNode = (audioTime) => { this.gainNode = this.ctx.createGain(); this.audioTime = audioTime // Firefox does not like 0 -> therefor 0.0000001 this.gainNode.gain.setValueAtTime(0.0000001, audioTime) // Attack this.gainNode.gain[this.mode]( this.options.attackAmp, audioTime + this.options.attackTime) // Decay this.gainNode.gain[this.mode]( this.options.decayAmp, audioTime + this.options.attackTime + this.options.decayTime) // Sustain this.gainNode.gain[this.mode]( this.options.sustainAmp, audioTime + this.options.attackTime + this.options.sustainTime) // Check if auto-release // Then calculate when note should stop if (this.options.autoRelease) { this.gainNode.gain[this.mode]( this.options.releaseAmp, audioTime + this.releaseTime() ) // Disconnect the gain node this.disconnect(audioTime + this.releaseTime()) } return this.gainNode; }; /** * Release the note dynamicaly * E.g. if your are making a keyboard, and you want the note * to be released according to current audio time + the ADSR release time */ this.releaseNow = () => { this.gainNode.gain[this.mode]( this.options.releaseAmp, this.ctx.currentTime + this.options.releaseTime) this.disconnect(this.options.releaseTime) } /** * Get release time according to the adsr release time */ this.releaseTime = function() { return this.options.attackTime + this.options.decayTime + this.options.sustainTime + this.options.releaseTime } /** * Get release time according to 'now' */ this.releaseTimeNow = function () { return this.ctx.currentTime + this.releaseTime() } /** * * @param {float} disconnectTime the time when gainNode should disconnect */ this.disconnect = (disconnectTime) => { setTimeout( () => { this.gainNode.disconnect(); }, disconnectTime * 1000); }; } module.exports = AdsrGainNode;