Created
May 21, 2014 21:44
-
-
Save jsantell/7d526a051aa03e7ed8c7 to your computer and use it in GitHub Desktop.
example AudioObserver consumer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * 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