Skip to content

kylestetz/adsr-envelope

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ADSR ENVELOPE

Build Status NPM Version License

ADSR Envelope

Installation

Node.js

npm install adsr-envelope

Online Demo

ADSR

ADSREnvelope

API

ADSREnvelope

  • constructor(opts: object = {})
    • attackTime: number default: 0.01 (10msec)
    • decayTime: number default: 0.3 (300msec)
    • sustainLevel: number default: 0.5
    • releaseTime: number default: 1 (1sec)
    • gateTime: number default: Infinity
    • sustainTime: number
    • duration: number
    • peakLevel: number default: 1
    • epsilon: number default: 0.001
    • attackCurve: string default: lin
      • lin or exp (linear or exponential)
    • decayCurve: string default: lin
      • lin or exp (linear or exponential)
    • releaseCurve: string default: lin
      • lin or exp (linear or exponential)

Instance Attributes

  • duration: number
  • attackTime: number
  • decayTime: number
  • sustainTime: number
  • sustainLevel: number
  • releaseTime: number
  • gateTime: number
  • peakLevel: number
  • epsilon: number
  • attackCurve: string
  • decayCurve: string
  • releaseCurve: string

Instance Methods

  • valueAt(time: number = 0): number
  • applyTo(audioParam: AudioParam, playbackTime: number = 0): self
  • getWebAudioAPIMethods(playbackTime: number = 0): Array[]
  • clone(): ADSREnvelope

Example

sequencer style

import ADSREnvelope from "adsr-envelope";

let audioContext = new AudioContext();
let oscillator = audioContext.createOscillator();
let gain = audioContext.createGain();
let adsr = new ADSREnvelope({
  attackTime: 0.5,
  decayTime: 0.25,
  sustainLevel: 0.8,
  releaseTime: 2.5,
  gateTime: 6,
  releaseCurve: "exp",
});

adsr.applyTo(gain.gain, audioContext.currentTime);

console.log(adsr.getWebAudioAPIMethods());
// [
//   [ "setValueAtTime", 0, 0 ],
//   [ "linearRampToValueAtTime", 1, 0.5 ],
//   [ "linearRampToValueAtTime", 0.8, 0.75],
//   [ "setValueAtTime", 0.8, 6 ],
//   [ "exponentialRampToValueAtTime", 0.001, 8.5 ],
// ]

oscillator.start(audioContext.currentTime);
oscillator.stop(audioContext.currentTime + adsr.duration);

oscillator.connect(gain);
gain.connect(audioContext.destination);

noteOn / noteOff style

import ADSREnvelope from "adsr-envelope";

let audioContext = new AudioContext();
let adsr = new ADSREnvelope({
  attackTime: 0.5,
  decayTime: 0.25,
  sustainLevel: 0.8,
  releaseTime: 2.5,
  gateTime: 6,
  releaseCurve: "exp",
});
let noteMap = {};

class Note {
  constructor(audioContext, noteNumber, envelope) {
    this.audioContext = audioContext;
    this.noteNumber = noteNumber;
    this.envelope = envelope;
    this.startTime = 0;
    this.oscillator = audioContext.createOscillator();
    this.gain = audioContext.createGain();

    this.oscillator.frequency.value = midicps(noteNumber);
    this.oscillator.onended = () => {
      this.oscillator.disconnect();
      this.gain.disconnect();
    };

    this.oscillator.connect(this.gain);
    this.gain.connect(audioContext.destination);
  }

  noteOn(playbackTime = this.audioContext.currentTime) {
    this.startTime = playbackTime;
    this.envelope.gateTime = Infinity;
    this.envelope.applyTo(this.gain.gain, playbackTime);
    this.oscillator.start(playbackTime);
  }

  noteOff(playbackTime = this.audioContext.currentTime) {
    this.gain.gain.cancelScheduledValues(this.startTime);

    this.envelope.gateTime = playbackTime - this.startTime;
    this.envelope.applyTo(this.gain.gain, this.startTime);

    this.oscillator.stop(this.startTime + this.envelope.duration);
  }
}

midiKeyboard.on("noteOn", ({ noteNumber }) => {
  if (noteMap[noteNumber]) {
    noteMap[noteNumber].noteOff();
  }

  noteMap[noteNumber] = new Note(audioContext, noteNumber, adsr.clone());
  noteMap[noteNumber].noteOn();
});
midiKeyboard.on("noteOff", ({ noteNumber }) => {
  if (noteMap[noteNumber]) {
    noteMap[noteNumber].noteOff();
  }
  noteMap[noteNumber] = null;
});

License

MIT

Packages

No packages published

Languages

  • JavaScript 90.2%
  • HTML 9.8%