http://github/wavesjs
$ npm install wavesjs/waves-audio
$ npm install wavesjs/waves-lfo
$ npm install wavesjs/waves-ui

Audio

Audio Context

This modules provides a global unique audio context singleton as the default audio context used by the components of the Waves Audio lirbary and applications using the library.

Usage

var wavesAudio = require('waves-audio');
var audioContext = wavesAudio.audioContext;

Audio Time Engine

This is the base class for all audio related time engine components. It is used to handle audio related events such as the playback of a media stream. It extends the TimeEngine class by the standard web audio node methods connect and disconnect.

Usage

// ES6 and CommonJS
var wavesAudio = require('waves-audio');

class MyEngine extends wavesAudio.AudioTimeEngine {
  constructor() {
    // call AudioTimeEngine super-class constructor
    super();

    // ...
  }
}
// ES5 and CommonJS
var wavesAudio = require('waves-audio');

function MyEngine() {
  // call AudioTimeEngine super-class constructor
  wavesAudio.AudioTimeEngine.call(this);

  // ...
}

// extend AudioTimeEngine prototype
MyEngine.prototype = Object.create(wavesAudio.AudioTimeEngine.prototype, {
  constructor: {
    value: MyEngine,
  },
});

// engine methods
MyEngine.prototype.itsMethod = function() {
  // ...
};

Example

This example shows a scheduled AudioTimeEngine repeating the waveform of a given vowel – cut outof a voice recording – at a given frequency.

https://cdn.rawgit.com/wavesjs/audio/master/examples/audio-time-engine.html

Attributes

outputNode :Object = null

Output audio node. By default the connect method connects a given node to this output node.

Methods

.connect (target:Object) : this

Connect to an audio node (e.g. audioContext.destination).

.disconnect (connection:Object) : this

Disconnect from the conection passed as a parameter.

Granular Engine

Granular synthesis TimeEngine implementing the scheduled interface.

Usage

var wavesAudio = require('waves-audio');
var scheduler = wavesAudio.getScheduler();
var granularEngine = new wavesAudio.GranularEngine();

scheduler.add(granularEngine);

Example

This example shows a GranularEngine (with a few parameter controls) driven by a Scheduler and a PlayControl.

https://cdn.rawgit.com/wavesjs/audio/master/examples/granular-engine.html

Attributes

buffer :AudioBuffer = null

Audio buffer.

periodAbs :Number = 0.01

Absolute grain period in seconds.

periodRel :Number = 0

Grain period relative to absolute duration.

periodVar :Number = 0

Amout of random grain period variation relative to grain period.

position :Number = 0

Grain position (onset time in audio buffer) in seconds.

positionVar :Number = 0.003

Amount of random grain position variation in seconds.

durationAbs :Number = 0.1

Absolute grain duration in seconds.

durationRel :Number = 0

Grain duration relative to grain period (i.e grain overlap).

attackAbs :Number = 0

Absolute attack time in seconds.

attackRel :Number = 0.5

Attack time relative to grain duration.

releaseAbs :Number = 0

Absolute release time in seconds.

releaseRel :Number = 0.5

Release time relative to grain duration.

resampling :Number = 0

Grain resampling in cent.

resamplingVar :Number = 0

Amount of random resampling variation in cent.

resamplingVar :Number = 0

Linear grain gain factor.

centered :Boolean = true

Whether the grain position refers to the center of the grain (or to the beginning).

cyclic :Boolean = false

Whether the audio buffer and grain position are considered as cyclic.

currentPosition :Number = this.position

Current position.

wrapAroundExtension :Number = 0

Portion at the end of the audio buffer that has been copied from the beginning to assure cyclic behavior. This attribute corresponds to the wrapAroundExtension option of the load method of the AudioBufferLoader and SuperLoader).

bufferDuration :Number = this.buffer.duration

Duration of the current audio buffer (i.e. buffer attribute) excluding the wrapAroundExtension.

Methods

.constuctor (options:Object = {})

The constructor accepts a set of options:

.advanceTime (time:Number)

Implementation of the scheduled TimeEngine interface.

.trigger (time:Number = this.audioContext.currentTime) : Number

Trigger a single grain with the current parameters at the given audio time. Returns the current grain period (i.e. time until next grain).

Metronome

Metronome audio engine. It extends Time Engine as a transported interface.

Usage

var wavesAudio = require('waves-audio');
var scheduler = wavesAudio.getScheduler();
var metronome = new wavesAudio.Metronome({period: 0.333});

scheduler.add(metronome);

Example

https://cdn.rawgit.com/wavesjs/audio/master/examples/metronome.html

Attributes

period :Number = 1

Metronome period in seconds.

phase :Number = 0

Metronome phase when driven through transported interface [0, 1[.

clickFreq :Number = 600

Click sound frequency.

clickAttack :Number = 0.002

Click sound attack time.

clickRelease :Number = 0.098

Click sound release time.

clickRelease :Number = 0

Linear gain factor.

Methods

.constuctor (options:Object = {})

The constructor accepts a set of options:

.advanceTime (time:Number)

Implementation of the scheduled TimeEngine interface.

.syncPosition (time:Number, position:Number, speed:Number)

Implementation of the transported TimeEngine interface.

.advancePosition (time:Number, position:Number, speed:Number)

Implementation of the transported TimeEngine interface.

.trigger (time:Number)

Trigger metronome click at a given time.

Play Control

Extends Time Engine to provide playback control of a Time Engine instance.

Usage

var wavesAudio = require('waves-audio');
var playerEngine = wavesAudio.PlayerEngine();
var playControl = new wavesAudio.PlayControl(playerEngine);

playControl.start();

Example

https://cdn.rawgit.com/wavesjs/audio/master/examples/play-control.html

Methods

.constuctor (engine:Object)

The Time Engine instance should be passed to the constructor.

.currentTime () : Number

Returns the current master time.

.currentPosition () : Number

Returns the current master position.

.loop (enable:Boolean) : Boolean

If enable is provided sets the play control loop behavior, otherwise returns its value.

.setLoopBoundaries (start:Number, end:Number)

Sets loop start and end time.

.loopStart (startTime:Number) : Number

If startTime is provided sets loop start value, otherwise returns its value.

.loopEnd (endTime:Number) : Number

If startTime is provided sets loop start value, otherwise returns its value.

.syncSpeed (time:Number, position:Number, speed:Number, seek:Boolean = false)

Implementation of the speed-controlled interface.

.start ()

Starts playback.

.pause ()

Pauses playback and stays at the same position.

.stop ()

Stops playback and seeks to initial (0) position.

.speed (speed:Number) : Number

If speed if provided, sets the playback speed. The speed value should be non-zero between -16 and -1/16 or between 1/16 and 16. Otherwise, returns the current playing speed.

.seek (position:Number)

Sets playing position.

.clear ()

Remove time engine from the transport.

Player Engine

Used with a buffer to serve audio files.

var wavesAudio = require('waves-audio');
var playerEngine = wavesAudio.PlayerEngine();
var playControl = new wavesAudio.PlayControl(playerEngine);

playControl.start();

Example

https://cdn.rawgit.com/wavesjs/audio/master/examples/player-engine.html

Attributes

transport :Object = null

Refers to a transport object when added to one.

buffer :AudioBuffer = buffer

The audio buffer. Default as the object passed in the constructor.

fadeTime :Number = 0.005

Fade time for chaining segments (e.g. in start, stop, and seek).

wrapAroundExtension :Number = 0

Portion at the end of the audio buffer that has been copied from the beginning to assure cyclic behavior. This attribute corresponds to the wrapAroundExtension option of the load method of the AudioBufferLoader and SuperLoader).

outputNode :Number = gainNode

On instanciation an output gain node is created. Every tick should pass through this node.

Methods

.constuctor (buffer:Object = null)

An audio buffer instance should be passed to the constructor in order to serve audio content.

.syncSpeed (time:Number, position:Number, speed:Number, seek:Boolean = false)

Implementation of the speed-controlled interface.

.cyclic (cyclic:Boolean) : Boolean

If cyclic is provided sets whether the audio buffer is considered as cyclic. Otherwise, returns whether the audio buffer is considered as cyclic.

.gain (value:Number) : Number

If value is provided, sets audio node gain value. Otherwise, returns the gain value.

Priority Queue

Used by Scheduler and Transport to handle events or callbacks by priority.

Attributes

reverse :Boolean = false

Wheter the queue should be reversed or not.

Methods

.insert (object:Object, time:Number, sort:Boolean = true)

Insert an object to the queue. Using false as the third arguments prevents sorting for each element.

.move (object:Object, time:Number)

Move an object to another time in the queue.

.remove (object:Object)

Remove an object from the queue.

.clear ()

Clear queue.

.head () : Object

Returns the first item in the queue of null if empty.

.time () : Number

Returns the time reference of the first object in the queue or Infinity if empty.

Scheduler

The Scheduler class implements a master for time engines (see TimeEngine or AudioTimeEngine) that implement the scheduled interface such as the Metronome and the GranularEngine. A Scheduler can also schedule simple callback functions. The class is based on recursive calls to setTimeOut and uses the audioContext.currentTime as logical passed to the advanceTime methods of the scheduled engines or to the scheduled callback functions. It extends the SchedulingQueue class that itself includes a PriorityQueue to assure the order of the scheduled engines (see SimpleScheduler for a simplified scheduler implementation without PriorityQueue).

To get a unique instance of Scheduler as the global scheduler of an application, the getScheduler factory function should be used. The function accepts an audio context as optional argument and uses the Waves default audio context (see Audio Context) as default. The factory creates a single scheduler for each audio context.

Usage

var wavesAudio = require('waves-audio');
var scheduler = wavesAudio.getScheduler();

scheduler.add(myEngine);

Example

This example shows three Metronome engines running in a Scheduler.

https://cdn.rawgit.com/wavesjs/audio/master/examples/scheduler.html

Attributes

period :Number = 0.025

Value for setTimeout period.

lookahead :Number = 0.1

Lookahead time (>= period).

Methods

.currentTime () : Number

Returns scheduler current time including lookahead.

.add (engineOrCallback:TimeEngine|Function, time:Number = this.currentTime) : Object

Add a TimeEngine or a simple callback function to the scheduler at an optionally given time. Whether the add method is called with a TimeEngine or a callback function it returns a TimeEngine that can be used as argument of the methods remove and resetEngineTime. A TimeEngine added to a scheduler has to implement the scheduled interface. The callback function added to a scheduler will be called at the given time and with the given time as argument. The callback can return a new scheduling time (i.e. the next time when it will be called) or it can return Infinity to suspend scheduling without removing the function from the scheduler. A function that does not return a value (or returns null or 0) is removed from the scheduler and cannot be used as argument of the methods remove and resetEngineTime anymore.

.remove (engine:Object)

Remove a TimeEngine from the scheduler that has been added to the scheduler using the add method.

.resetEngineTime (engine:Object, time:Number)

Reschedule a scheduled time engine at a given time.

.clear ()

Remove all schdeduled callbacks and engines from the scheduler.

Segment Engine

Used with a buffer to serve audio files via granular synthesis. The engine implements the “scheduled” and “transported” interfaces. When “scheduled”, the engine generates segments more or less periodically (controlled by the periodAbs, periodRel, and perioVar attributes). When “transported”, the engine generates segments at the position of their onset time.

Usage

var wavesAudio = require('waves-audio');
var scheduler = wavesAudio.getScheduler();
var segmentEngine = new wavesAudio.SegmentEngine();

scheduler.add(segmentEngine);

Example

This example shows a SegmentEngine with a few parameter controls running in a Scheduler.

https://cdn.rawgit.com/wavesjs/audio/master/examples/segment-engine.html

Attributes

buffer :AudioBuffer = buffer

Audio buffer.

% assign attribute = ‘periodAbs’ %}

buffer :Number = 0.1

Absolute segment period in sec.

periodRel :Number = 0

Segment period relative to inter-segment distance.

periodVar :Number = 0

Amout of random segment period variation relative to segment period.

positionArray :Array = [0.0]

Array of random segment segment positions in seconds.

positionVar :Number = 0

Amount of random segment position variation in seconds.

durationArray :Array = [0.0]

Array of segment durations in seconds.

durationAbs :Number = 0

Absolute segment duration in seconds.

durationRel :Number = 1

Segment duration relative to the duration determined by the durationArray or inter-segment distance.

offsetArray :Array = [0.0]

Array of segment offsets in seconds. If greate than 0, the segment’s reference position is after the given segment position. Otherwise, the given segment position is the segment’s reference position and the duration has to be corrected by the offset.

offsetAbs :Number = -0.005

Absolute segment offset in seconds. The offset determines the actual reference position of the segment. More precisely, it corresponds to the offset of the segment’s reference position in respect to the given segment position. A positive offset indicates the segment’s reference position after the segment position (i.e. at position + offset). If the offset is negative, the segment position refers to the segment’s reference position, but the segment actually starts by the given offset earlier (i.e. at position + offset). Consequently, also the segment’s actual duration is by the given offset longer (i.e. position - offset).

offsetRel :Number = 0

Segment offset relative to segment duration.

delay :Number = 0.005

Time by which all segments are delayed (especially to realize segments offsets).

attackAbs :Number = 0.005

Absolute attack time in seconds.

attackRel :Number = 0

Attack time relative to segment duration.

releaseAbs :Number = 0.005

Absolute release time in seconds.

releaseRel :Number = 0

Release time relative to segment duration.

resampling :Number = 0

Segment resampling in cent.

resamplingVar :Number = 0

Amount of random resampling variation in cent.

resamplingVar :Number = 0

Linear segment gain factor.

segmentIndex :Number = 0

Segment index.

cyclic :Boolean = false

Wheter the audio buffer and segment indices are considered as cyclic.

currentPosition :Number = this.position

Current position.

wrapAroundExtension :Number = 0

Portion at the end of the audio buffer that has been copied from the beginning to assure cyclic behavior. This attribute corresponds to the wrapAroundExtension option of the load method of the AudioBufferLoader and SuperLoader).

bufferDuration :Number = this.buffer.duration

Duration of the current audio buffer (i.e. buffer attribute) excluding the wrapAroundExtension.

Methods

.constuctor (options:Object = {})

The constructor accepts a set of options:

.advanceTime (time:Number)

Implementation of the scheduled TimeEngine interface.

.syncPosition (time:Number, position:Number, speed:Number)

Implementation of the transported TimeEngine interface.

.advancePosition (time:Number, position:Number, speed:Number)

Implementation of the transported TimeEngine interface.

.trigger (time:Number) : Number

Trigger a single segment with the current parameters at the given audio time. Returns the current segment period (i.e. time until next segment).

Simple Scheduler

The SimpleScheduler class implements a simplified master for time engines (see TimeEngine or AudioTimeEngine) that implement the scheduled interface such as the Metronome and the GranularEngine. The API and funtionalities of the SimpleScheduler class are identical to the Scheduler class. But, other than the Scheduler, the SimpleScheduler class does not guarantee the order of events (i.e. calls to the advanceTime method of scheduled time engines and to scheduled callback functions) within a scheduling period (see period attribute).

To get a unique instance of SimpleScheduler as the global scheduler of an application, the getSimpleScheduler factory function should be used. The function accepts an audio context as optional argument and uses the Waves default audio context (see Audio Context) as default. The factory creates a single (simple) scheduler for each audio context.

Usage

var wavesAudio = require('waves-audio');
var scheduler = wavesAudio.getSimpleScheduler();

scheduler.add(myEngine);

Example

This example shows three Metronome engines running in a SimpleScheduler.

https://cdn.rawgit.com/wavesjs/audio/master/examples/simple-scheduler.html

Time Engine

Base class for time engines

A time engine generates more or less regular events and/or plays back a media stream. It implements one or multiple interfaces to be driven by a master (i.e. a Scheduler, a Transport or a PlayControl) in synchronization with other engines. The provided interfaces are scheduled, transported, and play-controlled.

Usage

// ES6 and CommonJS
var wavesAudio = require("waves-audio");

class MyEngine extends wavesAudio.TimeEngine {
  constructor() {
    // call TimeEngine super-class constructor
    super();

    // ...
  }
}
// ES5 and CommonJS
var wavesAudio = require('waves-audio');

function MyEngine() {
  // call TimeEngine super-class constructor
  wavesAudio.TimeEngine.call(this);

  // ...
}

// extend TimeEngine prototype
MyEngine.prototype = Object.create(wavesAudio.TimeEngine.prototype, {
  constructor: {
    value: MyEngine,
  },
});

// engine methods
MyEngine.prototype.itsMethod = function() {
  // ...
};

Example

This example shows a TimeEngine running in a Scheduler that counts up at a given frequency.

https://cdn.rawgit.com/wavesjs/audio/master/examples/time-engine.html

Attributes

master :Object = null

The engine’s master.

currentTime :Number =

The time engine’s current (master) time

currentPosition :Number =

The time engine’s current (master) position

The scheduled interface

The scheduled interface allows for synchronizing an engine to a monotonous time as it is provided by the Scheduler master.

.advanceTime (time:Number) : Number

The advanceTime method has to be implemented by an engine as part of the scheduled interface. The method is called by the master (e.g. the scheduler). It generates an event and to returns the time of the next event (i.e. the next call of advanceTime). The returned time has to be greater than the time received as argument of the method. In case that a TimeEngine has to generate multiple events at the same time, the engine has to implement its own loop while(event.time <= time) and return the time of the next event (if any).

.resetTime (time:Number = undefined)

The resetTime method is provided by the TimeEngine base class. An engine may call this method to reset its next event time (e.g. when a parameter is changed that influences the engine’s temporal behavior). When no argument is given, the time is reset to the current master time. When calling the method with Infinity the engine is suspended without being removed from the master.

The transported interface

The transported interface allows for synchronizing an engine to a position (i.e. media playback time) that can run forward and backward and jump as it is provided by the Transport master.

.syncPosition (time:Number, position: Number, speed: Number) : Number

The syncPositon method has to be implemented by a TimeEngine as part of the transported interface. The method syncPositon is called whenever the master of a transported engine has to (re-)synchronize the engine’s position. This is for example required when the master (re-)starts playback, jumps to an arbitrary position, and when reversing playback direction. The method returns the next position of the engine in the given playback direction (i.e. speed < 0 or speed > 0).

.advancePosition (time:Number, position: Number, speed: Number) : Number

The advancePosition method has to be implemented by a TimeEngine as part of the transported interface. The master calls the advancePositon method when the engine’s event position is reached. The method generates an event and returns the next position in the given playback direction (i.e. speed < 0 or speed > 0). The returned position has to be greater (i.e. when speed > 0) or less (i.e. when speed < 0) than the position received as argument of the method.

.resetPosition (position:Number = undefined)

The resetPosition method is provided by the TimeEngine base class. An engine may call this method to reset its next event position. When no argument is given, the time is reset to the current master time. When calling the method with Infinity the engine is suspended without being removed from the master.

The speed-controlled interface

The “speed-controlled” interface allows for syncronizing an engine that is neither driven through the scheduled nor the transported interface. The interface allows in particular to synchronize engines that assure their own scheduling (i.e. audio player or an oscillator) to the event-based scheduled and transported engines.

.syncSpeed (time:Number, position:Number, speed:Number, seek:Boolean = false)

The syncSpeed method has to be implemented by a TimeEngine as part of the speed-controlled interface. The method is called by the master whenever the playback speed changes or the position jumps arbitarily (i.e. on a seek).

Master methods

These methods are intended to be called by a TimeEngine master.

.implementsScheduled () : Boolean

Checks whether the TimeEngine implements the scheduled interface.

.implementsTransported () : Boolean

Checks whether the time engine implements the transported interface.

.implementsSpeedControlled () : Boolean

Checks whether the time engine implements the speed-controlled interface.

Transport

Provides synchronized scheduling of Time Engine instances.

Usage

var wavesAudio = require('waves-audio');
var transport = wavesAudio.Transport();
var playControl = new wavesAudio.PlayControl(transport);
var myEngine = new MyEngine();
var yourEngine = new yourEngine();

transport.add(myEngine);
transport.add(yourEngine);

playControl.start();

Example

https://cdn.rawgit.com/wavesjs/audio/master/examples/transport.html

Methods

.currentTime () : Number

Returns current master time.

.currentPosition () : Number

Returns current master position.

.resetNextPosition (nextPosition:Number)

Reset next tranport position.

.syncPosition (time:Number, position:Number, speed:Number)

Implementation of the transported time engine interface.

.advancePosition (time:Number, position:Number, speed:Number)

Implementation of the transported time engine interface.

.syncSpeed (time:Number, position:Number, speed:Number, seek:Boolean = false)

Implementation of the speed-controlled time engine interface.

.add (engine:Object, startPosition:Number = -Infinity, endPosition:Number = Infinity, offsetPosition:Number = startPosition) : Object

Adds a time engine to a specific position and returns the transported object.

Make sure the engine hasn’t already been added to the transport.

.remove (engineOrTransported:Object)

Remove a time engine from the transport.

Make sure the enging has already been added to the transport.

.clear ()

Remove all time engines from the transport.