Bug 855990 - Part 1: Implement the DOM bindings to AnalyserNode; r=bzbarsky

This commit is contained in:
Ehsan Akhgari 2013-03-31 23:41:14 -04:00
Родитель f3c9c56774
Коммит 9930599736
10 изменённых файлов: 316 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,110 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/AnalyserNode.h"
#include "mozilla/dom/AnalyserNodeBinding.h"
#include "AudioNodeEngine.h"
#include "AudioNodeStream.h"
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS_INHERITED0(AnalyserNode, AudioNode)
class AnalyserNodeEngine : public AudioNodeEngine
{
public:
virtual void ProduceAudioBlock(AudioNodeStream* aStream,
const AudioChunk& aInput,
AudioChunk* aOutput,
bool* aFinished)
{
*aOutput = aInput;
}
};
AnalyserNode::AnalyserNode(AudioContext* aContext)
: AudioNode(aContext)
, mFFTSize(2048)
, mMinDecibels(-100.)
, mMaxDecibels(-30.)
, mSmoothingTimeConstant(.8)
{
mStream = aContext->Graph()->CreateAudioNodeStream(new AnalyserNodeEngine(),
MediaStreamGraph::INTERNAL_STREAM);
}
AnalyserNode::~AnalyserNode()
{
DestroyMediaStream();
}
JSObject*
AnalyserNode::WrapObject(JSContext* aCx, JSObject* aScope)
{
return AnalyserNodeBinding::Wrap(aCx, aScope, this);
}
void
AnalyserNode::SetFftSize(uint32_t aValue, ErrorResult& aRv)
{
// Disallow values that are either less than 2 or not a power of 2
if (aValue < 2 ||
(aValue & (aValue - 1)) != 0) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
mFFTSize = aValue;
}
void
AnalyserNode::SetMinDecibels(double aValue, ErrorResult& aRv)
{
if (aValue >= mMaxDecibels) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
mMinDecibels = aValue;
}
void
AnalyserNode::SetMaxDecibels(double aValue, ErrorResult& aRv)
{
if (aValue <= mMinDecibels) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
mMaxDecibels = aValue;
}
void
AnalyserNode::SetSmoothingTimeConstant(double aValue, ErrorResult& aRv)
{
if (aValue < 0 || aValue > 1) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
mSmoothingTimeConstant = aValue;
}
void
AnalyserNode::GetFloatFrequencyData(Float32Array& aArray)
{
}
void
AnalyserNode::GetByteFrequencyData(Uint8Array& aArray)
{
}
void
AnalyserNode::GetByteTimeDomainData(Uint8Array& aArray)
{
}
}
}

Просмотреть файл

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef AnalyserNode_h_
#define AnalyserNode_h_
#include "AudioNode.h"
namespace mozilla {
namespace dom {
class AudioContext;
class AnalyserNode : public AudioNode
{
public:
explicit AnalyserNode(AudioContext* aContext);
virtual ~AnalyserNode();
NS_DECL_ISUPPORTS_INHERITED
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE;
virtual bool SupportsMediaStreams() const MOZ_OVERRIDE
{
return true;
}
void GetFloatFrequencyData(Float32Array& aArray);
void GetByteFrequencyData(Uint8Array& aArray);
void GetByteTimeDomainData(Uint8Array& aArray);
uint32_t FftSize() const
{
return mFFTSize;
}
void SetFftSize(uint32_t aValue, ErrorResult& aRv);
uint32_t FrequencyBinCount() const
{
return FftSize() / 2;
}
double MinDecibels() const
{
return mMinDecibels;
}
void SetMinDecibels(double aValue, ErrorResult& aRv);
double MaxDecibels() const
{
return mMaxDecibels;
}
void SetMaxDecibels(double aValue, ErrorResult& aRv);
double SmoothingTimeConstant() const
{
return mSmoothingTimeConstant;
}
void SetSmoothingTimeConstant(double aValue, ErrorResult& aRv);
private:
uint32_t mFFTSize;
double mMinDecibels;
double mMaxDecibels;
double mSmoothingTimeConstant;
};
}
}
#endif

Просмотреть файл

@ -10,6 +10,7 @@
#include "nsPIDOMWindow.h"
#include "mozilla/ErrorResult.h"
#include "MediaStreamGraph.h"
#include "mozilla/dom/AnalyserNode.h"
#include "AudioDestinationNode.h"
#include "AudioBufferSourceNode.h"
#include "AudioBuffer.h"
@ -98,6 +99,13 @@ AudioContext::CreateBuffer(JSContext* aJSContext, uint32_t aNumberOfChannels,
return buffer.forget();
}
already_AddRefed<AnalyserNode>
AudioContext::CreateAnalyser()
{
nsRefPtr<AnalyserNode> analyserNode = new AnalyserNode(this);
return analyserNode.forget();
}
already_AddRefed<GainNode>
AudioContext::CreateGain()
{

Просмотреть файл

@ -38,6 +38,7 @@ struct WebAudioDecodeJob;
namespace dom {
class AnalyserNode;
class AudioBuffer;
class AudioBufferSourceNode;
class AudioDestinationNode;
@ -99,6 +100,9 @@ public:
uint32_t aLength, float aSampleRate,
ErrorResult& aRv);
already_AddRefed<AnalyserNode>
CreateAnalyser();
already_AddRefed<GainNode>
CreateGain();

Просмотреть файл

@ -16,6 +16,7 @@ FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
CPPSRCS := \
AnalyserNode.cpp \
AudioBuffer.cpp \
AudioBufferSourceNode.cpp \
AudioContext.cpp \
@ -37,6 +38,7 @@ CPPSRCS := \
EXPORTS_NAMESPACES := mozilla/dom
EXPORTS_mozilla/dom := \
AnalyserNode.h \
AudioBuffer.h \
AudioBufferSourceNode.h \
AudioContext.h \

Просмотреть файл

@ -16,6 +16,7 @@ MOCHITEST_FILES := \
test_bug827541.html \
test_bug839753.html \
test_bug845960.html \
test_analyserNode.html \
test_AudioBuffer.html \
test_AudioContext.html \
test_AudioListener.html \

Просмотреть файл

@ -0,0 +1,80 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test GainNode</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="webaudio.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
var context = new AudioContext();
var buffer = context.createBuffer(1, 2048, context.sampleRate);
for (var i = 0; i < 2048; ++i) {
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate);
}
var destination = context.destination;
var source = context.createBufferSource();
var analyser = context.createAnalyser();
source.buffer = buffer;
source.connect(analyser);
analyser.connect(destination);
is(analyser.fftSize, 2048, "Correct default value for fftSize");
is(analyser.frequencyBinCount, 1024, "Correct default value for frequencyBinCount");
expectException(function() {
analyser.fftSize = 0;
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser.fftSize = 1;
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser.fftSize = 100; // non-power of two
}, DOMException.INDEX_SIZE_ERR);
analyser.fftSize = 1024;
is(analyser.frequencyBinCount, 512, "Correct new value for frequencyBinCount");
is(analyser.minDecibels, -100, "Correct default value for minDecibels");
is(analyser.maxDecibels, -30, "Correct default value for maxDecibels");
expectException(function() {
analyser.minDecibels = -30;
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser.minDecibels = -29;
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser.maxDecibels = -100;
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser.maxDecibels = -101;
}, DOMException.INDEX_SIZE_ERR);
is(analyser.smoothingTimeConstant, 0.8, "Correct default value for smoothingTimeConstant");
expectException(function() {
analyser.smoothingTimeConstant = -0.1;
}, DOMException.INDEX_SIZE_ERR);
expectException(function() {
analyser.smoothingTimeConstant = 1.1;
}, DOMException.INDEX_SIZE_ERR);
analyser.smoothingTimeConstant = 0;
analyser.smoothingTimeConstant = 1;
SpecialPowers.clearUserPref("media.webaudio.enabled");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,37 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[PrefControlled]
interface AnalyserNode : AudioNode {
// Real-time frequency-domain data
void getFloatFrequencyData(Float32Array array);
void getByteFrequencyData(Uint8Array array);
// Real-time waveform data
void getByteTimeDomainData(Uint8Array array);
[SetterThrows, Pure]
attribute unsigned long fftSize;
[Pure]
readonly attribute unsigned long frequencyBinCount;
[SetterThrows, Pure]
attribute double minDecibels;
[SetterThrows, Pure]
attribute double maxDecibels;
[SetterThrows, Pure]
attribute double smoothingTimeConstant;
};

Просмотреть файл

@ -35,6 +35,8 @@ interface AudioContext {
[Creator]
AudioBufferSourceNode createBufferSource();
[Creator]
AnalyserNode createAnalyser();
[Creator]
GainNode createGain();
[Creator, Throws]

Просмотреть файл

@ -9,6 +9,7 @@ generated_webidl_files = \
$(NULL)
webidl_files = \
AnalyserNode.webidl \
AnimationEvent.webidl \
ArchiveReader.webidl \
ArchiveRequest.webidl \