Bug 1134079 - Supply audio node definitions directly from the client if the webaudio actor server does not support it (like on older versions of FxOS). r=vp

This commit is contained in:
Jordan Santell 2015-02-23 12:47:00 +01:00
parent dda6fdfa37
commit a137b66eae
4 changed files with 124 additions and 121 deletions

View File

@ -61,8 +61,15 @@ let WebAudioEditorController = {
// with CSS
gDevTools.on("pref-changed", this._onThemeChange);
// Store the AudioNode definitions from the WebAudioFront
AUDIO_NODE_DEFINITION = yield gFront.getDefinition();
// Store the AudioNode definitions from the WebAudioFront, if the method exists.
// If not, get the JSON directly. Using the actor method is preferable so the client
// knows exactly what methods are supported on the server.
let actorHasDefinition = yield gTarget.actorHasMethod("webaudio", "getDefinition");
if (actorHasDefinition) {
AUDIO_NODE_DEFINITION = yield gFront.getDefinition();
} else {
AUDIO_NODE_DEFINITION = require("devtools/server/actors/utils/audionodes.json");
}
}),
/**

View File

@ -0,0 +1,107 @@
{
"OscillatorNode": {
"properties": {
"type": {},
"frequency": {
"param": true
},
"detune": {
"param": true
}
}
},
"GainNode": {
"properties": { "gain": { "param": true }}
},
"DelayNode": {
"properties": { "delayTime": { "param": true }}
},
"AudioBufferSourceNode": {
"properties": {
"buffer": { "Buffer": true },
"playbackRate": {
"param": true
},
"loop": {},
"loopStart": {},
"loopEnd": {}
}
},
"ScriptProcessorNode": {
"properties": { "bufferSize": { "readonly": true }}
},
"PannerNode": {
"properties": {
"panningModel": {},
"distanceModel": {},
"refDistance": {},
"maxDistance": {},
"rolloffFactor": {},
"coneInnerAngle": {},
"coneOuterAngle": {},
"coneOuterGain": {}
}
},
"ConvolverNode": {
"properties": {
"buffer": { "Buffer": true },
"normalize": {}
}
},
"DynamicsCompressorNode": {
"properties": {
"threshold": { "param": true },
"knee": { "param": true },
"ratio": { "param": true },
"reduction": {},
"attack": { "param": true },
"release": { "param": true }
}
},
"BiquadFilterNode": {
"properties": {
"type": {},
"frequency": { "param": true },
"Q": { "param": true },
"detune": { "param": true },
"gain": { "param": true }
}
},
"WaveShaperNode": {
"properties": {
"curve": { "Float32Array": true },
"oversample": {}
}
},
"AnalyserNode": {
"properties": {
"fftSize": {},
"minDecibels": {},
"maxDecibels": {},
"smoothingTimeConstant": {},
"frequencyBinCount": { "readonly": true }
}
},
"AudioDestinationNode": {
"unbypassable": true
},
"ChannelSplitterNode": {
"unbypassable": true
},
"ChannelMergerNode": {
"unbypassable": true
},
"MediaElementAudioSourceNode": {},
"MediaStreamAudioSourceNode": {},
"MediaStreamAudioDestinationNode": {
"unbypassable": true,
"properties": {
"stream": { "MediaStream": true }
}
},
"StereoPannerNode": {
"properties": {
"pan": {}
}
}
}

View File

@ -16,7 +16,7 @@ const { ThreadActor } = require("devtools/server/actors/script");
const AutomationTimeline = require("./utils/automation-timeline");
const { on, once, off, emit } = events;
const { types, method, Arg, Option, RetVal } = protocol;
const AUDIO_NODE_DEFINITION = require("devtools/server/actors/utils/audionodes.json");
const ENABLE_AUTOMATION = false;
const AUTOMATION_GRANULARITY = 2000;
const AUTOMATION_GRANULARITY_MAX = 6000;
@ -42,118 +42,6 @@ const NODE_ROUTING_METHODS = [
"connect", "disconnect"
];
const NODE_PROPERTIES = {
"OscillatorNode": {
"properties": {
"type": {},
"frequency": {
"param": true
},
"detune": {
"param": true
}
}
},
"GainNode": {
"properties": { "gain": { "param": true }}
},
"DelayNode": {
"properties": { "delayTime": { "param": true }}
},
// TODO deal with figuring out adding `detune` AudioParam
// for AudioBufferSourceNode, which is in the spec
// but not yet added in implementation
// bug 1116852
"AudioBufferSourceNode": {
"properties": {
"buffer": { "Buffer": true },
"playbackRate": {
"param": true
},
"loop": {},
"loopStart": {},
"loopEnd": {}
}
},
"ScriptProcessorNode": {
"properties": { "bufferSize": { "readonly": true }}
},
"PannerNode": {
"properties": {
"panningModel": {},
"distanceModel": {},
"refDistance": {},
"maxDistance": {},
"rolloffFactor": {},
"coneInnerAngle": {},
"coneOuterAngle": {},
"coneOuterGain": {}
}
},
"ConvolverNode": {
"properties": {
"buffer": { "Buffer": true },
"normalize": {},
}
},
"DynamicsCompressorNode": {
"properties": {
"threshold": { "param": true },
"knee": { "param": true },
"ratio": { "param": true },
"reduction": {},
"attack": { "param": true },
"release": { "param": true }
}
},
"BiquadFilterNode": {
"properties": {
"type": {},
"frequency": { "param": true },
"Q": { "param": true },
"detune": { "param": true },
"gain": { "param": true }
}
},
"WaveShaperNode": {
"properties": {
"curve": { "Float32Array": true },
"oversample": {}
}
},
"AnalyserNode": {
"properties": {
"fftSize": {},
"minDecibels": {},
"maxDecibels": {},
"smoothingTimeConstant": {},
"frequencyBinCount": { "readonly": true },
}
},
"AudioDestinationNode": {
"unbypassable": true
},
"ChannelSplitterNode": {
"unbypassable": true
},
"ChannelMergerNode": {
"unbypassable": true
},
"MediaElementAudioSourceNode": {},
"MediaStreamAudioSourceNode": {},
"MediaStreamAudioDestinationNode": {
"unbypassable": true,
"properties": {
"stream": { "MediaStream": true }
}
},
"StereoPannerNode": {
"properties": {
"pan": {}
}
}
};
/**
* An Audio Node actor allowing communication to a specific audio node in the
* Audio Context graph.
@ -189,7 +77,7 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
}
// Create automation timelines for all AudioParams
Object.keys(NODE_PROPERTIES[this.type].properties || {})
Object.keys(AUDIO_NODE_DEFINITION[this.type].properties || {})
.filter(isAudioParam.bind(null, node))
.forEach(paramName => {
this.automation[paramName] = new AutomationTimeline(node[paramName].defaultValue);
@ -252,7 +140,7 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
return;
}
let bypassable = !NODE_PROPERTIES[this.type].unbypassable;
let bypassable = !AUDIO_NODE_DEFINITION[this.type].unbypassable;
if (bypassable) {
node.passThrough = enable;
}
@ -345,7 +233,7 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
* Name of the AudioParam whose flags are desired.
*/
getParamFlags: method(function (param) {
return ((NODE_PROPERTIES[this.type] || {}).properties || {})[param];
return ((AUDIO_NODE_DEFINITION[this.type] || {}).properties || {})[param];
}, {
request: { param: Arg(0, "string") },
response: { flags: RetVal("nullable:primitive") }
@ -356,7 +244,7 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({
* corresponding to a property name and current value of the audio node.
*/
getParams: method(function (param) {
let props = Object.keys(NODE_PROPERTIES[this.type].properties || {});
let props = Object.keys(AUDIO_NODE_DEFINITION[this.type].properties || {});
return props.map(prop =>
({ param: prop, value: this.getParam(prop), flags: this.getParamFlags(prop) }));
}, {
@ -618,7 +506,7 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({
* flags.
*/
getDefinition: method(function () {
return NODE_PROPERTIES;
return AUDIO_NODE_DEFINITION;
}, {
response: { definition: RetVal("json") }
}),
@ -833,7 +721,7 @@ let WebAudioActor = exports.WebAudioActor = protocol.ActorClass({
*/
_instrumentParams: function (node) {
let type = getConstructorName(node);
Object.keys(NODE_PROPERTIES[type].properties || {})
Object.keys(AUDIO_NODE_DEFINITION[type].properties || {})
.filter(isAudioParam.bind(null, node))
.forEach(paramName => {
let param = node[paramName];

View File

@ -74,6 +74,7 @@ EXTRA_JS_MODULES.devtools.server.actors += [
EXTRA_JS_MODULES.devtools.server.actors.utils += [
'actors/utils/actor-registry-utils.js',
'actors/utils/audionodes.json',
'actors/utils/automation-timeline.js',
'actors/utils/make-debugger.js',
'actors/utils/map-uri-to-addon-id.js',