Skip to content

CompositeAudioNode

Hongchan Choi edited this page Apr 30, 2016 · 5 revisions

CompositeAudioNode

This snippet demonstrates how to define a custom AudioNode by compositing built-in AudioNodes with ES6 class syntax.

Live Demo

(1) Define CompositeAudioNode. A custom composite node can be derived from this prototype.

class CompositeAudioNode {  

  get _isCompositeAudioNode () {
    return true;
  }
  
  constructor (context, options) {
    this.context = context;
    this._input = this.context.createGain();
    this._output = this.context.createGain();
  }
  
  connect () {
    this._output.connect.apply(this._output, arguments);
  }
  
  disconnect () {
    this._output.disconnect.apply(this._output, arguments);
  }
}

(2) Override AudioNode.prototype.connect.

AudioNode.prototype._connect = AudioNode.prototype.connect;
AudioNode.prototype.connect = function () {
  var args = Array.prototype.slice.call(arguments);
  if (args[0]._isCompositeAudioNode)
    args[0] = args[0]._input;
  
  this._connect.apply(this, args);
};

(3) Create a custom composite node from the prototype. Inject the new node name into AudioContext.prototype if you like.

class MyCompositeNode extends CompositeAudioNode {

  get gain () {
    return this._amp.gain;
  }

  constructor (context, options) {
    super(context, options);

    // Do stuffs below.
    this._amp = this.context.createGain();
    this._input.connect(this._amp);
    this._amp.connect(this._output);
  }
}

// Inject the new class into AudioContext prototype.
AudioContext.prototype.createMyCompositeNode =
OfflineAudioContext.prototype.createMyCompositeNode = function (options) {
  return new MyCompositeNode(this, options);
};

(4) Use it in the code.

var context = new AudioContext();
var myCompNode = context.createMyCompositeNode();
var oscNode = context.createOscillator();
var gainNode = context.createGain();

myCompNode.gain.value = 0.25;

oscNode.connect(myCompNode);
myCompNode.connect(gainNode);
gainNode.connect(context.destination);

oscNode.start();
oscNode.stop(1.0);

Future work

  • Design AudioParam encapsulation.
  • How to use AudioNodeDescriptor in the class definition.