WAVES.JS
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:
- audioContext, the audio context used
- all parameter attributes, to initialize the parameter values
.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:
-
audioContext, the audio context used
-
all parameter attributes, to initialize the parameter values
.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:
- audioContext, the audio context used
- all parameter attributes, to initialize the parameter values
.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.