Skip to content

Instantly share code, notes, and snippets.

@jsantell
Created May 21, 2014 21:44
Show Gist options
  • Select an option

  • Save jsantell/7d526a051aa03e7ed8c7 to your computer and use it in GitHub Desktop.

Select an option

Save jsantell/7d526a051aa03e7ed8c7 to your computer and use it in GitHub Desktop.
example AudioObserver consumer
/**
* Mock up of observers consuming the notifications for the web audio API
* explaining in:
* https://bugzilla.mozilla.org/show_bug.cgi?id=980506#c25
*/
// Use SDK observer
// resource://gre/modules/commonjs/sdk/system/events.js
const { on, off } = require("sdk/system/events");
// Let's say this object is instantiated on every new document load
// and takes a `nsIDOMWindow` argument.
function AudioTool (window) {
// `contexts` will be a hash of context IDs that map to a `Set` of audio nodes
// related to that context. This is for illustrative purposes of showing
// all the data returned from the observer service
let contexts = {};
// Called when `new AudioContext()` occurs in any document
on("web-audio:create-audio-context", ({subject, type, data}) => {
// If subject does not match the window for the current document's toolbox,
// ignore it. Same goes for all the listeners here for the most part.
if (subject !== window) return;
// `data` from the Observer just has the ID of the AudioContext
// NICE TO HAVE: data for `sampleRate` and `currentTime` (currentTime not useful
// in this context, but if we have a `get-context-data` notification, it'd have
// the same information).
//
// We also need the destination node ID as after context creation,
// another node would be created and connect to the destination, which
// will require an ID for that node
let { contextID, destinationID } = data;
// Create a new Set for audio node IDs within this context.
contexts[data.contextID] = new Set();
contexts[contextID].add(destinationID);
});
// Called when a new AudioNode is created from a context.
on("web-audio:create-audio-node", ({subject, type, data}) => {
if (subject !== window) return;
// Returns values of both the AudioContext ID and the AudioNode ID
// from the ObserverService. Also a `type` which is a string referring
// to the type of node created, i.e. 'OscillatorNode'
let { contextID, nodeID, type } = data;
contexts[contextID].add(nodeID);
});
// Called when an AudioNode connects to either another AudioNode
// or an AudioParam
on("web-audio:connect-audio-node", ({subject, type, data}) => {
if (subject !== window) return;
// Returns values of both the AudioContext ID, the ID of the
// source node connecting, and the ID of the target of that connection.
// If `paramName` defined, then this is connecting to `targetID`'s
// AudioParam by the name of `paramName`.
//
// Maybe AudioParams should have their own ID, but they can also be referenced
// by their Node's ID along with the property name.
//
// osc.connect(gain);
// -> contextID = "ID-for-context"
// -> sourceID = "ID-for-Osc-Node"
// -> targetID = "ID-for-Gain-Node"
// -> paramName = undefined
//
// osc.connect(biquadFilter.frequency)
// -> contextID = "ID-for-context"
// -> sourceID = "ID-for-Osc-Node"
// -> targetID = "ID-for-BiquadFilter-Node"
// -> paramName = "frequency"
// `output` and `input` refer to index used during `node.connect(target, output, input)`
let { contextID, sourceID, targetID, paramName, output, input } = data;
if (paramName === undefined) {
doSomethingWithConnectToNode(sourceID, targetID)
}
else {
doSomethingWithConnectToParam(sourceID, targetID, paramName)
}
});
// Called when an AudioNode disconnects from all of it's connections
on("web-audio:disconnect-audio-node", ({subject, type, data}) => {
if (subject !== window) return;
// Same return information as `web-audio:connect-audio-node`, minus `input`
let { contextID, sourceID, targetID, paramName, output } = data;
if (paramName === undefined) {
doSomethingWithDisconnectToNode(sourceID, targetID)
}
else {
doSomethingWithDisconnectToParam(sourceID, targetID, paramName)
}
});
// Called when an AudioNode is destroyed/GC'd (AudioNode::DestroyMediaStream?)
on("web-audio:destroy-audio-node", ({subject, type, data}) => {
if (subject !== window) return;
let { contextID, nodeID } = data;
contexts[contextID].remove(nodeID);
});
/**
* Follow up Bugs/notifications:
* `web-audio:get-context-properties`
* `web-audio:get-node-properties`
* `web-audio:set-node-properties`
* `web-audio:automation-scheduled`
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment