Giter Site home page Giter Site logo

envelope-generator's Introduction

Envelope Generator Test status

Basic ADSR envelope generator for web audio. A demo is running here.

  • The release stage exists as a separate GainNode, so the envelope doesn't need to keep track of its output gain internally.
  • Uses the voltage idea from mmckegg/adsr.

Example

npm install --save envelope-generator
import Envelope from 'envelope-generator';

let context = new AudioContext();
let osc = context.createOscillator();

let gain = context.createGain();

let env = new Envelope(context, {
  attackTime: 0.1,
  decayTime: 3,
  sustainLevel: 0.4,
  releaseTime: 0.1
});

env.connect(gain.gain);

var startAt = context.currentTime;

var releaseAt = startAt + 0.5;

osc.start(startAt);
env.start(startAt);

env.release(releaseAt);

let stopAt = env.getReleaseCompleteTime();
osc.stop(stopAt);
env.stop(stopAt);

Usage

Constructor

The constructor accepts two arguments: an AudioContext and a settings object. All settings are optional, but you will probably want to set at least attackTime, decayTime, sustainLevel, and releaseTime.

  • All ...Time properties are in seconds
  • All curve, attackCurve, decayCurve, and releaseCurve properties default to "linear", with "exponential" the alternative.
  • attackCurve, decayCurve, and releaseCurve override their respective curves
  • Passing an initialValueCurve will determine the shape of the curve usually covered by the attack and decay sections of an envelope, overriding any other curve values.
  • Passing a releaseValueCurve will determine the shape of the release, overriding any other release curve value.
  • Both initialValueCurve and releaseValueCurve are expected to be normalized, i.e. not extending outside of the bounds [0, 1]. This is relatively intuitive for the initialValueCurve, but ensure that your releaseValueCurve also starts at a value of 1 to avoid any jumps in the sound. The reason for this is that these two curves are applied in series.
  • The sampleRate property applies to initialValueCurve and releaseValueCurve, allowing them to be expressed in a sampleRate different from that of the context.
let context = new AudioContext();
let settings = {
  curve: "linear",
  attackCurve: "linear",
  decayCurve: "linear",
  releaseCurve: "linear",
  initialValueCurve: Float32Array,
  releaseValueCurve: Float32Array,
  sampleRate: 44100,
  delayTime: 0,
  startLevel: 0,
  maxLevel: 1,
  attackTime: 0.1,
  holdTime: 0,
  decayTime: 0,
  sustainLevel: 0.5,
  releaseTime: 1
};
let env = new Envelope(context, settings)

connect

The connect method should be attached directly to AudioParams:

let osc = context.createOscillator();
let gainNode = context.createGain();
let env = new Envelope(context, settings);
env.connect(gainNode.gain);

start

The start method triggers the attack and decay stages of the envelope:

let osc = context.createOscillator();
let gainNode = context.createGain();
let env = new Envelope(context, settings);
env.connect(gainNode.gain);

osc.start(context.currentTime);
env.start(context.currentTime);

release

The release method triggers the release stage of the envelope:

let osc = context.createOscillator();
let gainNode = context.createGain();
let env = new Envelope(context, settings);
env.connect(gainNode.gain);

osc.start(context.currentTime);
env.start(context.currentTime);

// Release the envelope after 1 second
env.release(context.currentTime + 1);

getReleaseCompleteTime

Releasing the envelope isn't the same as stopping the sound source. Once release has been called, getReleaseCompleteTime() will return the time that the envelope finishes its release stage. If this is an amp envelope, and the startLevel (i.e., where the envelope will release to) is 0, getReleaseCompleteTime() is when your sound source is guaranteed to be silent and can be stopped:

let osc = context.createOscillator();
let gainNode = context.createGain();
let env = new Envelope(context, settings);
env.connect(gainNode.gain);

osc.start(context.currentTime);
env.start(context.currentTime);

env.release(context.currentTime + 1);

// Stop the oscillator once the envelope has completed.
osc.stop(env.getReleaseCompleteTime());

stop

Because they are generating a signal, envelopes need to be stopped as well as released. This should coincide with when the actual sound source is stopped.

let osc = context.createOscillator();
let gainNode = context.createGain();
let env = new Envelope(context, settings);
env.connect(gainNode.gain);

osc.start(context.currentTime);
env.start(context.currentTime);

env.release(context.currentTime + 1);

// Stop the oscillator once the envelope has completed.
let stopAt = env.getReleaseCompleteTime();
osc.stop(stopAt);
env.stop(stopAt);

envelope-generator's People

Contributors

itsjoesullivan avatar

Stargazers

Sean Stevens avatar It's Mikita avatar Farouk avatar Aarón Maldonado avatar  avatar  avatar sonopictorial avatar Scott J avatar  avatar Masiro avatar  avatar Eli Sherer avatar François Georgy avatar Bhaskar C avatar Dan avatar Steven Nguyen avatar Jordan Sitkin avatar Micah avatar Thomas Dobber avatar rchk avatar Benjamin Saphier avatar Brian Ginsburg avatar Martin Wittmann avatar Brendan Bruce avatar Tyler Van Hoomissen avatar David Granström avatar Yoshiya Hinosawa avatar Sean Voeller avatar Lucas Aragno avatar Joshua Comeau avatar  avatar Karim Ratib avatar Mark Feltner avatar ◬ avatar Dmitry Iv. avatar

Watchers

◬ avatar James Cloos avatar  avatar Masiro avatar J△MΞS avatar

Forkers

adamopanast

envelope-generator's Issues

Does this still work?

It looks like this repo hasn't been touched in a while. I'm wondering if it still works. I couldn't hear any sounds on the demo page and it's not working in my code.

From my understanding from following this tutorial, it seems that you create a chain of connections:

oscillator.connect(gainNode);
gainNode.connect(context.destination);

But in your sample code in the readme, it doesn't look like you create a chain. The oscillator isn't hooked up at all.

Am I missing something?

Clicks when starting the envelope

Image of waveform in Audacity

I'm getting clicks at the start of every sound. This is the code I'm using atm, on Firefox 49.0, OS X (El Capitan).

    var cumT = this.audioCtx.currentTime;
    var oscillator = this.audioCtx.createOscillator();
    oscillator.type = 'sine';
    oscillator.frequency.value = this.wave.frequency;
    var gain = this.audioCtx.createGain();
    var volume = this.audioCtx.createGain();
    oscillator.connect(gain);
    gain.connect(volume);
    volume.gain.value = 0.5;
    volume.connect(this.audioCtx.destination);
    oscillator.start(cumT);
    var stopAt = cumT;
    for (var t = 0; t < timings.length; t += 1) {
        var duration = timings[t] / 1000;
        if (duration > 0) {
            // oscillator.connect(this.audioCtx.destination);
            var env = new Envelope(this.audioCtx, {
                    // curve: "exponential",
                    attackTime: 0.03,
                    // decayTime: 1.0,
                    sustainLevel: 1.0,
                    releaseTime: 0.03,
                    startLevel: 0.0
                });
            gain.gain.value = 0;
            env.connect(gain.gain);
            gain.gain.value = 0;
            env.start(cumT);
            cumT += duration;
            // oscillator.stop(cumT);
            env.release(cumT);
            stopAt = env.getReleaseCompleteTime();
            env.stop(stopAt);
        } else {
            cumT += -duration;
        }
    }
    oscillator.stop(stopAt);

Any idea how to solve this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.