adsr-gain-node
Version:
A simple and small nodejs module for creating an adsr gain node
111 lines (92 loc) • 3.06 kB
JavaScript
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;