mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 865234 - Part 1: Add DOM bindings for the channel mixing attributes; r=roc
This commit is contained in:
parent
d93f90db4c
commit
13fd72e30d
@ -75,7 +75,10 @@ public:
|
||||
};
|
||||
|
||||
AnalyserNode::AnalyserNode(AudioContext* aContext)
|
||||
: AudioNode(aContext)
|
||||
: AudioNode(aContext,
|
||||
1,
|
||||
ChannelCountMode::Explicit,
|
||||
ChannelInterpretation::Speakers)
|
||||
, mFFTSize(2048)
|
||||
, mMinDecibels(-100.)
|
||||
, mMaxDecibels(-30.)
|
||||
|
@ -403,7 +403,10 @@ public:
|
||||
};
|
||||
|
||||
AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext)
|
||||
: AudioNode(aContext)
|
||||
: AudioNode(aContext,
|
||||
2,
|
||||
ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers)
|
||||
, mLoopStart(0.0)
|
||||
, mLoopEnd(0.0)
|
||||
, mOffset(0.0)
|
||||
|
@ -16,7 +16,10 @@ namespace dom {
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(AudioDestinationNode, AudioNode)
|
||||
|
||||
AudioDestinationNode::AudioDestinationNode(AudioContext* aContext, MediaStreamGraph* aGraph)
|
||||
: AudioNode(aContext)
|
||||
: AudioNode(aContext,
|
||||
2,
|
||||
ChannelCountMode::Explicit,
|
||||
ChannelInterpretation::Speakers)
|
||||
{
|
||||
mStream = aGraph->CreateAudioNodeStream(new AudioNodeEngine(this),
|
||||
MediaStreamGraph::EXTERNAL_STREAM);
|
||||
|
@ -41,8 +41,14 @@ AudioNode::Release()
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AudioNode)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
|
||||
AudioNode::AudioNode(AudioContext* aContext)
|
||||
AudioNode::AudioNode(AudioContext* aContext,
|
||||
uint32_t aChannelCount,
|
||||
ChannelCountMode aChannelCountMode,
|
||||
ChannelInterpretation aChannelInterpretation)
|
||||
: mContext(aContext)
|
||||
, mChannelCount(aChannelCount)
|
||||
, mChannelCountMode(aChannelCountMode)
|
||||
, mChannelInterpretation(aChannelInterpretation)
|
||||
{
|
||||
MOZ_ASSERT(aContext);
|
||||
nsDOMEventTargetHelper::BindToOwner(aContext->GetParentObject());
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define AudioNode_h_
|
||||
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/AudioNodeBinding.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "EnableWebAudioCheck.h"
|
||||
@ -78,7 +79,10 @@ protected:
|
||||
virtual ~AudioNode();
|
||||
|
||||
public:
|
||||
explicit AudioNode(AudioContext* aContext);
|
||||
AudioNode(AudioContext* aContext,
|
||||
uint32_t aChannelCount,
|
||||
ChannelCountMode aChannelCountMode,
|
||||
ChannelInterpretation aChannelInterpretation);
|
||||
|
||||
// This should be idempotent (safe to call multiple times).
|
||||
virtual void DestroyMediaStream();
|
||||
@ -119,6 +123,28 @@ public:
|
||||
virtual uint32_t NumberOfInputs() const { return 1; }
|
||||
virtual uint32_t NumberOfOutputs() const { return 1; }
|
||||
|
||||
uint32_t ChannelCount() const { return mChannelCount; }
|
||||
void SetChannelCount(uint32_t aChannelCount)
|
||||
{
|
||||
mChannelCount = aChannelCount;
|
||||
}
|
||||
ChannelCountMode ChannelCountModeValue() const
|
||||
{
|
||||
return mChannelCountMode;
|
||||
}
|
||||
void SetChannelCountModeValue(ChannelCountMode aMode)
|
||||
{
|
||||
mChannelCountMode = aMode;
|
||||
}
|
||||
ChannelInterpretation ChannelInterpretationValue() const
|
||||
{
|
||||
return mChannelInterpretation;
|
||||
}
|
||||
void SetChannelInterpretationValue(ChannelInterpretation aMode)
|
||||
{
|
||||
mChannelInterpretation = aMode;
|
||||
}
|
||||
|
||||
struct InputNode {
|
||||
~InputNode()
|
||||
{
|
||||
@ -174,6 +200,9 @@ private:
|
||||
// exact matching entry, since mOutputNodes doesn't include the port
|
||||
// identifiers and the same node could be connected on multiple ports.
|
||||
nsTArray<nsRefPtr<AudioNode> > mOutputNodes;
|
||||
uint32_t mChannelCount;
|
||||
ChannelCountMode mChannelCountMode;
|
||||
ChannelInterpretation mChannelInterpretation;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -171,7 +171,10 @@ private:
|
||||
};
|
||||
|
||||
BiquadFilterNode::BiquadFilterNode(AudioContext* aContext)
|
||||
: AudioNode(aContext)
|
||||
: AudioNode(aContext,
|
||||
2,
|
||||
ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers)
|
||||
, mType(BiquadFilterType::Lowpass)
|
||||
, mFrequency(new AudioParam(this, SendFrequencyToStream, 350.f))
|
||||
, mDetune(new AudioParam(this, SendDetuneToStream, 0.f))
|
||||
|
@ -271,7 +271,10 @@ public:
|
||||
};
|
||||
|
||||
DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay)
|
||||
: AudioNode(aContext)
|
||||
: AudioNode(aContext,
|
||||
2,
|
||||
ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers)
|
||||
, mDelay(new AudioParam(this, SendDelayToStream, 0.0f))
|
||||
{
|
||||
DelayNodeEngine* engine = new DelayNodeEngine(this, aContext->Destination());
|
||||
|
@ -177,7 +177,10 @@ private:
|
||||
};
|
||||
|
||||
DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext)
|
||||
: AudioNode(aContext)
|
||||
: AudioNode(aContext,
|
||||
2,
|
||||
ChannelCountMode::Explicit,
|
||||
ChannelInterpretation::Speakers)
|
||||
, mThreshold(new AudioParam(this, SendThresholdToStream, -24.f))
|
||||
, mKnee(new AudioParam(this, SendKneeToStream, 30.f))
|
||||
, mRatio(new AudioParam(this, SendRatioToStream, 12.f))
|
||||
|
@ -95,7 +95,10 @@ public:
|
||||
};
|
||||
|
||||
GainNode::GainNode(AudioContext* aContext)
|
||||
: AudioNode(aContext)
|
||||
: AudioNode(aContext,
|
||||
2,
|
||||
ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers)
|
||||
, mGain(new AudioParam(this, SendGainToStream, 1.0f))
|
||||
{
|
||||
GainNodeEngine* engine = new GainNodeEngine(this, aContext->Destination());
|
||||
|
@ -174,7 +174,10 @@ public:
|
||||
};
|
||||
|
||||
PannerNode::PannerNode(AudioContext* aContext)
|
||||
: AudioNode(aContext)
|
||||
: AudioNode(aContext,
|
||||
2,
|
||||
ChannelCountMode::Clamped_max,
|
||||
ChannelInterpretation::Speakers)
|
||||
// Please keep these default values consistent with PannerNodeEngine::PannerNodeEngine above.
|
||||
, mPanningModel(PanningModelTypeValues::HRTF)
|
||||
, mDistanceModel(DistanceModelTypeValues::Inverse)
|
||||
|
@ -359,7 +359,10 @@ ScriptProcessorNode::ScriptProcessorNode(AudioContext* aContext,
|
||||
uint32_t aBufferSize,
|
||||
uint32_t aNumberOfInputChannels,
|
||||
uint32_t aNumberOfOutputChannels)
|
||||
: AudioNode(aContext)
|
||||
: AudioNode(aContext,
|
||||
2,
|
||||
ChannelCountMode::Explicit,
|
||||
ChannelInterpretation::Speakers)
|
||||
, mSharedBuffers(new SharedBuffers())
|
||||
, mBufferSize(aBufferSize ?
|
||||
aBufferSize : // respect what the web developer requested
|
||||
|
@ -31,6 +31,10 @@ addLoadEvent(function() {
|
||||
source.connect(analyser);
|
||||
analyser.connect(destination);
|
||||
|
||||
is(analyser.channelCount, 1, "analyser node has 2 input channels by default");
|
||||
is(analyser.channelCountMode, "explicit", "Correct channelCountMode for the analyser node");
|
||||
is(analyser.channelInterpretation, "speakers", "Correct channelCountInterpretation for the analyser node");
|
||||
|
||||
is(analyser.fftSize, 2048, "Correct default value for fftSize");
|
||||
is(analyser.frequencyBinCount, 1024, "Correct default value for frequencyBinCount");
|
||||
expectException(function() {
|
||||
|
@ -41,6 +41,9 @@ addLoadEvent(function() {
|
||||
near(filter.detune.defaultValue, 0, "Correct default value for filter detune");
|
||||
near(filter.Q.defaultValue, 1, "Correct default value for filter Q");
|
||||
near(filter.gain.defaultValue, 0, "Correct default value for filter gain");
|
||||
is(filter.channelCount, 2, "Biquad filter node has 2 input channels by default");
|
||||
is(filter.channelCountMode, "max", "Correct channelCountMode for the biquad filter node");
|
||||
is(filter.channelInterpretation, "speakers", "Correct channelCountInterpretation for the biquad filter node");
|
||||
|
||||
// Make sure that we can set all of the valid type values
|
||||
var types = [
|
||||
|
@ -46,6 +46,9 @@ addLoadEvent(function() {
|
||||
delay.delayTime.value = 0.5;
|
||||
is(delay.delayTime.value, 0.5, "Correct initial value");
|
||||
is(delay.delayTime.defaultValue, 0, "Correct default value");
|
||||
is(delay.channelCount, 2, "delay node has 2 input channels by default");
|
||||
is(delay.channelCountMode, "max", "Correct channelCountMode for the delay node");
|
||||
is(delay.channelInterpretation, "speakers", "Correct channelCountInterpretation for the delay node");
|
||||
|
||||
var delay2 = context.createDelay(2);
|
||||
is(delay2.delayTime.value, 0, "Correct initial value");
|
||||
|
@ -34,6 +34,10 @@ addLoadEvent(function() {
|
||||
source.connect(compressor);
|
||||
compressor.connect(destination);
|
||||
|
||||
is(compressor.channelCount, 2, "compressor node has 2 input channels by default");
|
||||
is(compressor.channelCountMode, "explicit", "Correct channelCountMode for the compressor node");
|
||||
is(compressor.channelInterpretation, "speakers", "Correct channelCountInterpretation for the compressor node");
|
||||
|
||||
// Verify default values
|
||||
with (compressor) {
|
||||
near(threshold.defaultValue, -24, "Correct default value for threshold");
|
||||
|
@ -46,6 +46,9 @@ addLoadEvent(function() {
|
||||
gain.gain.value = 0.5;
|
||||
is(gain.gain.value, 0.5, "Correct initial value");
|
||||
is(gain.gain.defaultValue, 1.0, "Correct default value");
|
||||
is(gain.channelCount, 2, "gain node has 2 input channels by default");
|
||||
is(gain.channelCountMode, "max", "Correct channelCountMode for the gain node");
|
||||
is(gain.channelInterpretation, "speakers", "Correct channelCountInterpretation for the gain node");
|
||||
|
||||
source.start(0);
|
||||
sp.onaudioprocess = function(e) {
|
||||
|
@ -43,6 +43,9 @@ addLoadEvent(function() {
|
||||
near(panner.coneInnerAngle, 360, "Correct default value for cone inner angle");
|
||||
near(panner.coneOuterAngle, 360, "Correct default value for cone outer angle");
|
||||
near(panner.coneOuterGain, 0, "Correct default value for cone outer gain");
|
||||
is(panner.channelCount, 2, "panner node has 2 input channels by default");
|
||||
is(panner.channelCountMode, "clamped-max", "Correct channelCountMode for the panner node");
|
||||
is(panner.channelInterpretation, "speakers", "Correct channelCountInterpretation for the panner node");
|
||||
|
||||
panner.setPosition(1, 1, 1);
|
||||
panner.setOrientation(1, 1, 1);
|
||||
|
@ -44,6 +44,10 @@ addLoadEvent(function() {
|
||||
context.createScriptProcessor(255);
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
|
||||
is(sourceSP.channelCount, 2, "script processor node has 2 input channels by default");
|
||||
is(sourceSP.channelCountMode, "explicit", "Correct channelCountMode for the script processor node");
|
||||
is(sourceSP.channelInterpretation, "speakers", "Correct channelCountInterpretation for the script processor node");
|
||||
|
||||
function findFirstNonZeroSample(buffer) {
|
||||
for (var i = 0; i < buffer.length; ++i) {
|
||||
if (buffer.getChannelData(0)[i] != 0) {
|
||||
|
@ -25,6 +25,9 @@ addLoadEvent(function() {
|
||||
is(destination.context, context, "Destination node has proper context");
|
||||
is(destination.numberOfInputs, 1, "Destination node has 1 inputs");
|
||||
is(destination.numberOfOutputs, 0, "Destination node has 0 outputs");
|
||||
is(destination.channelCount, 2, "Destination node has 2 input channels by default");
|
||||
is(destination.channelCountMode, "explicit", "Correct channelCountMode for the destination node");
|
||||
is(destination.channelInterpretation, "speakers", "Correct channelCountInterpretation for the destination node");
|
||||
ok(destination instanceof EventTarget, "AudioNodes must be EventTargets");
|
||||
|
||||
testWith(context, buffer, destination, function(source) {
|
||||
@ -84,6 +87,9 @@ function createNode(context, buffer, destination) {
|
||||
is(source.loopStart, 0, "Correct default value for loopStart");
|
||||
is(source.loopEnd, 0, "Correct default value for loopEnd");
|
||||
ok(!source.buffer, "Source node should not have a buffer when it's created");
|
||||
is(source.channelCount, 2, "source node has 2 input channels by default");
|
||||
is(source.channelCountMode, "max", "Correct channelCountMode for the source node");
|
||||
is(source.channelInterpretation, "speakers", "Correct channelCountInterpretation for the source node");
|
||||
|
||||
source.buffer = buffer;
|
||||
ok(source.buffer, "Source node should have a buffer now");
|
||||
|
@ -116,6 +116,10 @@ DOMInterfaces = {
|
||||
|
||||
'AudioNode' : {
|
||||
'concrete': False,
|
||||
'binaryNames': {
|
||||
'channelCountMode': 'channelCountModeValue',
|
||||
'channelInterpretation': 'channelInterpretationValue',
|
||||
},
|
||||
},
|
||||
|
||||
'AudioParam' : {
|
||||
|
@ -10,6 +10,17 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
enum ChannelCountMode {
|
||||
"max",
|
||||
"clamped-max",
|
||||
"explicit"
|
||||
};
|
||||
|
||||
enum ChannelInterpretation {
|
||||
"speakers",
|
||||
"discrete"
|
||||
};
|
||||
|
||||
[PrefControlled]
|
||||
interface AudioNode : EventTarget {
|
||||
|
||||
@ -26,5 +37,10 @@ interface AudioNode : EventTarget {
|
||||
readonly attribute unsigned long numberOfInputs;
|
||||
readonly attribute unsigned long numberOfOutputs;
|
||||
|
||||
// Channel up-mixing and down-mixing rules for all inputs.
|
||||
attribute unsigned long channelCount;
|
||||
attribute ChannelCountMode channelCountMode;
|
||||
attribute ChannelInterpretation channelInterpretation;
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user