зеркало из https://github.com/mozilla/gecko-dev.git
Bug 855990 - Part 1: Implement the DOM bindings to AnalyserNode; r=bzbarsky
This commit is contained in:
Родитель
f3c9c56774
Коммит
9930599736
|
@ -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 \
|
||||
|
|
Загрузка…
Ссылка в новой задаче