chaosmail / soundio

A live Graph Object Model for the Web Audio API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Soundio

Soundio is a Graph Object Model for Web Audio processing graphs. It provides an API for creating, manipulating and observing graphs, and a JSONify-able structure for exporting and importing them.

Soundio is the library that powers sound.io.

Dependencies and tests

Soundio is in development. It is currently dependent on three repos that can be installed as git submodules:

Install with submodules:

git clone https://github.com/soundio/soundio.git
cd soundio
git submodule update --init

Tests use Karma. To run tests:

npm install
karma start

Soundio(data, options)

Soundio data is an object that looks something like this:

var data = {
	objects: [
		{ id: 0, type: "input" },
		{ id: 1, type: "flange", frequency: 0.33, feedback: 0.9, delay: 0.16 },
		{ id: 2, type: "output" }
	],
	
	connections: [
		{ source: 0, destination: 1 },
		{ source: 1, destination: 2 }
	],

	midi: [
		{ message: [176, 8], object: 1, property: "frequency" }
	]
};

It contains three arrays, objects, connections and midi. objects is a collection of audio objects (an audio object is a wrapper for one or more Web Audio nodes). Audio objects must have an id and type, while other properties depend on the type. connections is a collection of objects defining connections between the audio objects, and midi defines routes for incoming MIDI messages.

Call Soundio with this data to set it up as an audio graph:

var soundio = Soundio(data);

Turn your volume down a bit, enable the mic when prompted by the browser, and you will hear your voice being flanged. Changes to object properties are reflected 'live' in the Web Audio graph.

The resulting object, soundio, has the same structure as data, so the graph can be converted back to data with:

JSON.stringify(soundio);

This means you can export an audio graph you have made at, say, sound.io – open the console and run this line – and import it into your own web page – call Soundio() with the data.

Soundio also accepts an options object with one option. Where you have an existing AudioContext, pass it in to avoid creating a new one:

var soundio = Soundio(data, {
		audio: AudioContext
	});

soundio

soundio.create(data)

Create objects from data. As with Soundio(data), but soundio.create(data) adds objects, connections and midi routes to the existing graph.

soundio.clear()

Remove and destroy all objects and connections.

soundio.destroy()

Removes and destroys all objects and connections, disconnects any media inputs from soundio's input, and disconnects soundio's output from audio destination.

soundio.objects

A collecton of audio objects. An audio object controls one or more audio nodes. In soundio, audio objects have an id and a type. name is optional. Other properties depend on the type.

var flanger = soundio.objects.find(1);

{
    id: 7,
    type: "flange",
    frequency: 256
}

Changes to flanger.frequency are reflected immediately in the Web Audio graph.

flanger.frequency = 480;

// flanger.automate(name, value, time, curve)
flanger.automate('frequency', 2400, audio.currentTime + 0.8, 'exponential');

For more about audio objects see github.com/soundio/audio-object.

soundio.objects.create(type, settings)

Create an audio object.

type is a string.

These audio objects connect to the sound card input and output respectively:

  • "input"
  • "output"

These audio objects wrap sub-graphs of audio nodes and are kind of equivalent to plugins in a DAW:

  • "compress"
  • "filter"
  • "flange"
  • "loop"
  • "saturate"
  • "send"

These audio objects wrap single Web Audio nodes and can be useful for testing:

  • "biquad filter"
  • "compressor"
  • "convolver"
  • "delay"
  • "oscillator"
  • "waveshaper"

settings depend on the type of audio object being created.

Returns the created audio object. Created objects can also be found in soundio.objects, as well as in soundio.inputs and soundio.outputs if they are of type "input" or "output" respectively.

soundio.objects.delete(object || id)

Destroy an audio object in the graph. Both the object and any connections to or from the object are destroyed.

soundio.objects.find(id || query)

soundio.objects.query(query)

soundio.connections

A collection of connections between the audio objects in the graph. A connection has a source and a destination that point to ids of objects in soundio.objects:

{
	source: 7,
	destination: 12
}

In addition a connection can define a named output node on the source object and/or a named input node on the destination object:

{
	source: 7,
	output: "send",
	destination: 12,
	input: "default"
}

soundio.connections.create(data)

Connect two objects. data must have source and destination defined. Naming an output or input is optional. They will default to "default".

soundio.connections.create({
    source: 7,
    output: "send",
    destination: 12
});

soundio.connections.delete(query)

Removes all connections whose properties are equal to the properties defined in the query object. For example, disconnect all connections to object with id 3:

soundio.connections.query({ destination: 3 });

soundio.connections.query(query)

Returns an array of all objects in connections whose properties are equal to the properties defined in the query object. For example, get all connections from object with id 6:

soundio.connections.query({ source: 6 });

soundio.clock

An instance of Clock, which requires the repo github.com/soundio/clock. If Clock is not found, soundio.clock is undefined.

soundio.clock is a Collection of tempo data that maps a beat clock against the audio context's time clock. It is a library of properties and methods for scheduling function calls. It is also an AudioObject with two output nodes, "rate" and "duration", for syncing Web Audio parameters to the tempo.

.time

The current time. Gets audio.currentTime. Read-only.

.beat

The current beat. Gets clock.beatAtTime(audio.currentTime). Read-only.

.rate

The current rate, in beats per second.

.timeAtBeat(beat)

Returns the audio context time at beat.

.beatAtTime(time)

Returns the beat at time.

.automate(name, value, time)

// Move to 120bpm in 2.5 seconds
clock.automate('rate', 2, clock.time + 2.5);

Inherited from AudioObject.

.tempo(beat, tempo)

Creates a tempo change at a time given by beat. If beat is not defined, the clock creates a tempo change at the current beat.

.find(beat)

Returns tempo change found at beat or undefined.

.remove(beat)

Removes tempo change found at beat.

.on(beat, fn)

Shorthand for clock.cue(beat, fn, 0), calls fn at the beat specified (0 ms lookahead).

.cue(beat, fn)

Cue a function to be called just before beat. fn is called with the argument time, which can used to accurately schedule Web Audio changes.

clock.cue(42, function(time) {
    gainParam.setValueAtTime(time, 0.25);
    bufferSourceNode.start(time);
});

Pass in a third parameter lookahead to override the default (0.05s) lookahead:

clock.cue(44, function(time) {
    gainParam.setValueAtTime(time, 1);
    bufferSourceNode.stop(time);
}, 0.08);

.uncue(beat, fn)

Removes fn at beat from the timer queue. Either, neither or both beat and fn can be given.

Remove all cues from the timer queue:

clock.uncue();

Remove cues at beat from the timer queue:

clock.uncue(beat);

Remove cues to fire fn from the timer queue:

clock.uncue(fn);

Remove cues at beat to fire fn from the timer queue:

clock.uncue(beat, fn)

.uncueAfter(beat, fn)

Removes fn after beat from the timer queue. fn is optional.

Remove all cues after beat from the timer queue:

clock.uncueAfter(beat);

Remove all cues after beat to fire fn from the timer queue:

clock.uncueAfter(beat, fn)

.onTime(time, fn)

Shorthand for clock.cueTime(time, fn, 0), calls fn at the time specified (0 ms lookahead).

.cueTime(time, fn)

Cue a function to be called just before time. fn is called with the argument time, which can used to accurately schedule changes to Web Audio parameters:

clock.cue(42, function(time) {
    gainParam.setValueAtTime(time, 0.25);
    bufferSourceNode.start(time);
});

Pass in a third parameter lookahead to override the default (0.05s) lookahead:

clock.cue(44, fn, 0.08);

.uncueTime(time, fn)

Removes fn at time from the timer cues. Either, neither or both time and fn can be given.

Remove all cues from the timer queue:

clock.uncueTime();

Remove cues at time from the timer queue:

clock.uncueTime(time);

Remove cues to fire fn from the timer queue:

clock.uncueTime(fn);

Remove cues at time to fire fn from the timer queue:

clock.uncueTime(time, fn)

.uncueAfterTime(time, fn)

Removes fn after time from the timer queue. fn is optional.

Remove all cues after time from the timer queue:

clock.uncueAfterTime(time);

Remove all cues after time for fn from the timer queue:

clock.uncueAfterTime(time, fn)

soundio.midi

A collection of MIDI routes that make object properties controllable via incoming MIDI events. A midi route looks like this:

{
    message:   [191, 0],
    object:    AudioObject,
    property:  "gain",
    transform: "linear",
    min:       0,
    max:       1
}

soundio.midi.create(data)

Create a MIDI route from data:

soundio.midi.create({
    message:   [191, 0],
    object:    1,
    property:  "gain",
    transform: "cubic",
    min:       0,
    max:       2
});

The properties transform, min and max are optional. They default to different values depending on the type of the object.

soundio.midi.delete(query)

Removes all MIDI routes whose properties are equal to the properties defined in the query object. For example, disconnect all routes to gain properties:

soundio.midi.query({ property: "gain" });

soundio.midi.query(query)

Returns an array of all objects in soundio.midi whose properties are equal to the properties defined in the query object. For example, get all connections from object with id 6:

soundio.connections.query({ object: 6 });

Soundio

Soundio.register(type, function)

Register an audio object factory function for creating audio objects of type type.

Soundio.register('gain', function(audio, data) {
	var gainNode = audio.createGain();

	gainNode.gain.value = settings.gain;

	return AudioObject(audio, gain, gain, {
		gain: gainNode.gain
	});
});

data is an object that comes directly from data passed to soundio.objects.create(type, data) or Soundio(data). You should make sure the registered audio object correctly initialises itself from data, and JSON.stringifys back to data.

Soundio comes with the following audio object factories registered:

// Single node audio objects 
'biquad filter'
'compressor'
'convolver'
'delay'
'oscillator'
'waveshaper'

// Multi node audio objects
'compress'
'flange'
'loop'
'filter'
'saturate'
'send'

Soundio.isAudioParam(object)

Soundio.isDefined(value)

Returns true where value is not undefined or null.

About

A live Graph Object Model for the Web Audio API


Languages

Language:JavaScript 97.8%Language:HTML 2.2%