summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface')
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html183
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic.html57
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html111
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html54
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-gain.html50
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html43
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-output.html44
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-scale.html51
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analysernode.html237
9 files changed, 830 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html
new file mode 100644
index 0000000000..a9aa483151
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html
@@ -0,0 +1,183 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ Test Constructor: AnalyserNode
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/webaudio/resources/audit-util.js"></script>
+ <script src="/webaudio/resources/audit.js"></script>
+ <script src="/webaudio/resources/audionodeoptions.js"></script>
+ </head>
+ <body>
+ <script id="layout-test-code">
+ let context;
+
+ let audit = Audit.createTaskRunner();
+
+ audit.define('initialize', (task, should) => {
+ context = initializeContext(should);
+ task.done();
+ });
+
+ audit.define('invalid constructor', (task, should) => {
+ testInvalidConstructor(should, 'AnalyserNode', context);
+ task.done();
+ });
+
+ audit.define('default constructor', (task, should) => {
+ let prefix = 'node0';
+ let node = testDefaultConstructor(should, 'AnalyserNode', context, {
+ prefix: prefix,
+ numberOfInputs: 1,
+ numberOfOutputs: 1,
+ channelCount: 2,
+ channelCountMode: 'max',
+ channelInterpretation: 'speakers'
+ });
+
+ testDefaultAttributes(should, node, prefix, [
+ {name: 'fftSize', value: 2048},
+ {name: 'frequencyBinCount', value: 1024},
+ {name: 'minDecibels', value: -100}, {name: 'maxDecibels', value: -30},
+ {name: 'smoothingTimeConstant', value: 0.8}
+ ]);
+
+ task.done();
+ });
+
+ audit.define('test AudioNodeOptions', (task, should) => {
+ testAudioNodeOptions(should, context, 'AnalyserNode');
+ task.done();
+ });
+
+ audit.define('constructor with options', (task, should) => {
+ let options = {
+ fftSize: 32,
+ maxDecibels: 1,
+ minDecibels: -13,
+ // Choose a value that can be represented the same as a float and as a
+ // double.
+ smoothingTimeConstant: 0.125
+ };
+
+ let node;
+ should(
+ () => {
+ node = new AnalyserNode(context, options);
+ },
+ 'node1 = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
+ .notThrow();
+
+ should(node instanceof AnalyserNode, 'node1 instanceof AnalyserNode')
+ .beEqualTo(true);
+ should(node.fftSize, 'node1.fftSize').beEqualTo(options.fftSize);
+ should(node.maxDecibels, 'node1.maxDecibels')
+ .beEqualTo(options.maxDecibels);
+ should(node.minDecibels, 'node1.minDecibels')
+ .beEqualTo(options.minDecibels);
+ should(node.smoothingTimeConstant, 'node1.smoothingTimeConstant')
+ .beEqualTo(options.smoothingTimeConstant);
+
+ task.done();
+ });
+
+ audit.define('construct invalid options', (task, should) => {
+ let node;
+
+ should(
+ () => {
+ node = new AnalyserNode(context, {fftSize: 33});
+ },
+ 'node = new AnalyserNode(c, { fftSize: 33 })')
+ .throw(DOMException, 'IndexSizeError');
+ should(
+ () => {
+ node = new AnalyserNode(context, {maxDecibels: -500});
+ },
+ 'node = new AnalyserNode(c, { maxDecibels: -500 })')
+ .throw(DOMException, 'IndexSizeError');
+ should(
+ () => {
+ node = new AnalyserNode(context, {minDecibels: -10});
+ },
+ 'node = new AnalyserNode(c, { minDecibels: -10 })')
+ .throw(DOMException, 'IndexSizeError');
+ should(
+ () => {
+ node = new AnalyserNode(context, {smoothingTimeConstant: 2});
+ },
+ 'node = new AnalyserNode(c, { smoothingTimeConstant: 2 })')
+ .throw(DOMException, 'IndexSizeError');
+ should(function() {
+ node = new AnalyserNode(context, {frequencyBinCount: 33});
+ }, 'node = new AnalyserNode(c, { frequencyBinCount: 33 })').notThrow();
+ should(node.frequencyBinCount, 'node.frequencyBinCount')
+ .beEqualTo(1024);
+
+ task.done();
+ });
+
+ audit.define('setting min/max', (task, should) => {
+ let node;
+
+ // Recall the default values of minDecibels and maxDecibels are -100,
+ // and -30, respectively. Setting both values in the constructor should
+ // not signal an error in any of the following cases.
+ let options = {minDecibels: -10, maxDecibels: 20};
+ should(
+ () => {
+ node = new AnalyserNode(context, options);
+ },
+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
+ .notThrow();
+
+ options = {maxDecibels: 20, minDecibels: -10};
+ should(
+ () => {
+ node = new AnalyserNode(context, options);
+ },
+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
+ .notThrow();
+
+ options = {minDecibels: -200, maxDecibels: -150};
+ should(
+ () => {
+ node = new AnalyserNode(context, options);
+ },
+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
+ .notThrow();
+
+ options = {maxDecibels: -150, minDecibels: -200};
+ should(
+ () => {
+ node = new AnalyserNode(context, options);
+ },
+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
+ .notThrow();
+
+ // But these should signal because minDecibel > maxDecibel
+ options = {maxDecibels: -150, minDecibels: -10};
+ should(
+ () => {
+ node = new AnalyserNode(context, options);
+ },
+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
+ .throw(DOMException, 'IndexSizeError');
+
+ options = {minDecibels: -10, maxDecibels: -150};
+ should(
+ () => {
+ node = new AnalyserNode(context, options);
+ },
+ 'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
+ .throw(DOMException, 'IndexSizeError');
+
+ task.done();
+ });
+
+ audit.run();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic.html
new file mode 100644
index 0000000000..e176d6111e
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-basic.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ realtimeanalyser-basic.html
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/webaudio/resources/audit-util.js"></script>
+ <script src="/webaudio/resources/audit.js"></script>
+ </head>
+ <body>
+ <script id="layout-test-code">
+ let context = 0;
+
+ let audit = Audit.createTaskRunner();
+
+ audit.define('Basic AnalyserNode test', function(task, should) {
+ context = new AudioContext();
+ let analyser = context.createAnalyser();
+
+ should(analyser.numberOfInputs, 'Number of inputs for AnalyserNode')
+ .beEqualTo(1);
+
+ should(analyser.numberOfOutputs, 'Number of outputs for AnalyserNode')
+ .beEqualTo(1);
+
+ should(analyser.minDecibels, 'Default minDecibels value')
+ .beEqualTo(-100);
+
+ should(analyser.maxDecibels, 'Default maxDecibels value')
+ .beEqualTo(-30);
+
+ should(
+ analyser.smoothingTimeConstant,
+ 'Default smoothingTimeConstant value')
+ .beEqualTo(0.8);
+
+ let expectedValue = -50 - (1 / 3);
+ analyser.minDecibels = expectedValue;
+
+ should(analyser.minDecibels, 'node.minDecibels = ' + expectedValue)
+ .beEqualTo(expectedValue);
+
+ expectedValue = -40 - (1 / 3);
+ analyser.maxDecibels = expectedValue;
+
+ should(analyser.maxDecibels, 'node.maxDecibels = ' + expectedValue)
+ .beEqualTo(expectedValue);
+
+ task.done();
+ });
+
+ audit.run();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html
new file mode 100644
index 0000000000..043bd5890a
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ realtimeanalyser-fft-scaling.html
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/webaudio/resources/audit-util.js"></script>
+ <script src="/webaudio/resources/audit.js"></script>
+ </head>
+ <body>
+ <div id="description"></div>
+ <div id="console"></div>
+ <script id="layout-test-code">
+ let audit = Audit.createTaskRunner();
+
+ // The number of analysers. We have analysers from size for each of the
+ // possible sizes of 2^5 to 2^15 for a total of 11.
+ let numberOfAnalysers = 11;
+ let sampleRate = 44100;
+ let nyquistFrequency = sampleRate / 2;
+
+ // Frequency of the sine wave test signal. Should be high enough so that
+ // we get at least one full cycle for the 32-point FFT. This should also
+ // be such that the frequency should be exactly in one of the FFT bins for
+ // each of the possible FFT sizes.
+ let oscFrequency = nyquistFrequency / 16;
+
+ // The actual peak values from each analyser. Useful for examining the
+ // actual peak values.
+ let peakValue = new Array(numberOfAnalysers);
+
+ // For a 0dBFS sine wave, we would expect the FFT magnitude to be 0dB as
+ // well, but the analyzer node applies a Blackman window (to smooth the
+ // estimate). This reduces the energy of the signal so the FFT peak is
+ // less than 0dB. The threshold value given here was determined
+ // experimentally.
+ //
+ // See https://code.google.com/p/chromium/issues/detail?id=341596.
+ let peakThreshold = [
+ -14.43, -13.56, -13.56, -13.56, -13.56, -13.56, -13.56, -13.56, -13.56,
+ -13.56, -13.56
+ ];
+
+ function checkResult(order, analyser, should) {
+ return function() {
+ let index = order - 5;
+ let fftSize = 1 << order;
+ let fftData = new Float32Array(fftSize);
+ analyser.getFloatFrequencyData(fftData);
+
+ // Compute the frequency bin that should contain the peak.
+ let expectedBin =
+ analyser.frequencyBinCount * (oscFrequency / nyquistFrequency);
+
+ // Find the actual bin by finding the bin containing the peak.
+ let actualBin = 0;
+ peakValue[index] = -1000;
+ for (k = 0; k < analyser.frequencyBinCount; ++k) {
+ if (fftData[k] > peakValue[index]) {
+ actualBin = k;
+ peakValue[index] = fftData[k];
+ }
+ }
+
+ should(actualBin, (1 << order) + '-point FFT peak position')
+ .beEqualTo(expectedBin);
+
+ should(
+ peakValue[index], (1 << order) + '-point FFT peak value in dBFS')
+ .beGreaterThanOrEqualTo(peakThreshold[index]);
+ }
+ }
+
+ audit.define(
+ {
+ label: 'FFT scaling tests',
+ description: 'Test Scaling of FFT in AnalyserNode'
+ },
+ async function(task, should) {
+ let tests = [];
+ for (let k = 5; k <= 15; ++k)
+ await runTest(k, should);
+ task.done();
+ });
+
+ function runTest(order, should) {
+ let context = new OfflineAudioContext(1, 1 << order, sampleRate);
+ // Use a sine wave oscillator as the reference source signal.
+ let osc = context.createOscillator();
+ osc.type = 'sine';
+ osc.frequency.value = oscFrequency;
+ osc.connect(context.destination);
+
+ let analyser = context.createAnalyser();
+ // No smoothing to simplify the analysis of the result.
+ analyser.smoothingTimeConstant = 0;
+ analyser.fftSize = 1 << order;
+ osc.connect(analyser);
+
+ osc.start();
+ return context.startRendering().then(() => {
+ checkResult(order, analyser, should)();
+ });
+ }
+
+ audit.run();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html
new file mode 100644
index 0000000000..7ee6a2237e
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-sizing.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ realtimeanalyser-fft-sizing.html
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/webaudio/resources/audit-util.js"></script>
+ <script src="/webaudio/resources/audit.js"></script>
+ </head>
+ <body>
+ <script id="layout-test-code">
+ let audit = Audit.createTaskRunner();
+
+ function doTest(fftSize, illegal, should) {
+ let c = new OfflineAudioContext(1, 1000, 44100);
+ let a = c.createAnalyser();
+ let message = 'Setting fftSize to ' + fftSize;
+ let tester = function() {
+ a.fftSize = fftSize;
+ };
+
+ if (illegal) {
+ should(tester, message).throw(DOMException, 'IndexSizeError');
+ } else {
+ should(tester, message).notThrow();
+ }
+ }
+
+ audit.define(
+ {
+ label: 'FFT size test',
+ description: 'Test that re-sizing the FFT arrays does not fail.'
+ },
+ function(task, should) {
+ doTest(-1, true, should);
+ doTest(0, true, should);
+ doTest(1, true, should);
+ for (let i = 2; i <= 0x20000; i *= 2) {
+ if (i >= 32 && i <= 32768)
+ doTest(i, false, should);
+ else
+ doTest(i, true, should);
+ doTest(i + 1, true, should);
+ }
+
+ task.done();
+ });
+
+ audit.run();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-gain.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-gain.html
new file mode 100644
index 0000000000..dff51a74c5
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-gain.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+promise_test(function() {
+ // fftSize <= bufferSize so that the time domain data is full of input after
+ // processing the buffer.
+ const fftSize = 32;
+ const bufferSize = 128;
+
+ var context = new OfflineAudioContext(1, bufferSize, 48000);
+
+ var analyser1 = context.createAnalyser();
+ analyser1.fftSize = fftSize;
+ analyser1.connect(context.destination);
+ var analyser2 = context.createAnalyser();
+ analyser2.fftSize = fftSize;
+
+ var gain = context.createGain();
+ gain.gain.value = 2.0;
+ gain.connect(analyser1);
+ gain.connect(analyser2);
+
+ // Create a DC input to make getFloatTimeDomainData() output consistent at
+ // any time.
+ var buffer = context.createBuffer(1, 1, context.sampleRate);
+ buffer.getChannelData(0)[0] = 1.0 / gain.gain.value;
+ var source = context.createBufferSource();
+ source.buffer = buffer;
+ source.loop = true;
+ source.connect(gain);
+ source.start();
+
+ return context.startRendering().then(function(buffer) {
+ assert_equals(buffer.getChannelData(0)[0], 1.0, "analyser1 output");
+
+ var data = new Float32Array(1);
+ analyser1.getFloatTimeDomainData(data);
+ assert_equals(data[0], 1.0, "analyser1 time domain data");
+ analyser2.getFloatTimeDomainData(data);
+ assert_equals(data[0], 1.0, "analyser2 time domain data");
+ });
+}, "Test effect of AnalyserNode on GainNode output");
+ </script>
+</head>
+</body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html
new file mode 100644
index 0000000000..ab0fe6b2d6
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test AnalyserNode when the input is silent</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ setup({ single_test: true });
+ var ac = new AudioContext();
+ var analyser = ac.createAnalyser();
+ var constant = ac.createConstantSource();
+ var sp = ac.createScriptProcessor(2048, 1, 1);
+
+ constant.offset.value = 0.0;
+
+ constant.connect(analyser).connect(ac.destination);
+
+ constant.connect(sp).connect(ac.destination);
+
+ var buf = new Float32Array(analyser.frequencyBinCount);
+ var iteration_count = 10;
+ sp.onaudioprocess = function() {
+ analyser.getFloatFrequencyData(buf);
+ var correct = true;
+ for (var i = 0; i < buf.length; i++) {
+ correct &= buf[i] == -Infinity;
+ }
+ assert_true(!!correct, "silent input process -Infinity in decibel bins");
+ if (!iteration_count--) {
+ sp.onaudioprocess = null;
+ constant.stop();
+ ac.close();
+ done();
+ }
+ };
+
+ constant.start();
+ </script>
+</head>
+</body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-output.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-output.html
new file mode 100644
index 0000000000..43d56b8990
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-output.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>AnalyserNode output</title>
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/webaudio/js/helpers.js"></script>
+ <script>
+setup({ single_test: true });
+
+var gTest = {
+ length: 2048,
+ numberOfChannels: 1,
+ createGraph: function(context) {
+ var source = context.createBufferSource();
+
+ var analyser = context.createAnalyser();
+
+ source.buffer = this.buffer;
+
+ source.connect(analyser);
+
+ source.start(0);
+ return analyser;
+ },
+ createExpectedBuffers: function(context) {
+ this.buffer = context.createBuffer(1, 2048, context.sampleRate);
+ for (var i = 0; i < 2048; ++i) {
+ this.buffer.getChannelData(0)[i] = Math.sin(
+ 440 * 2 * Math.PI * i / context.sampleRate
+ );
+ }
+
+ return [this.buffer];
+ }
+};
+
+runTest("AnalyserNode output");
+ </script>
+</head>
+</body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-scale.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-scale.html
new file mode 100644
index 0000000000..904b14bede
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analyser-scale.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test AnalyserNode when the input is scaled</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ setup({ single_test: true });
+
+ var context = new AudioContext();
+
+ var gain = context.createGain();
+ var analyser = context.createAnalyser();
+ var osc = context.createOscillator();
+
+ osc.connect(gain);
+ gain.connect(analyser);
+
+ osc.start();
+
+ var array = new Uint8Array(analyser.frequencyBinCount);
+
+ function getAnalyserData() {
+ gain.gain.setValueAtTime(currentGain, context.currentTime);
+ analyser.getByteTimeDomainData(array);
+ var inrange = true;
+ var max = -1;
+ for (var i = 0; i < array.length; i++) {
+ if (array[i] > max) {
+ max = Math.abs(array[i] - 128);
+ }
+ }
+ if (max <= currentGain * 128) {
+ assert_true(true, "Analyser got scaled data for " + currentGain);
+ currentGain = tests.shift();
+ if (currentGain == undefined) {
+ done();
+ return;
+ }
+ }
+ requestAnimationFrame(getAnalyserData);
+ }
+
+ var tests = [1.0, 0.5, 0.0];
+ var currentGain = tests.shift();
+ requestAnimationFrame(getAnalyserData);
+ </script>
+</head>
+</body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analysernode.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analysernode.html
new file mode 100644
index 0000000000..e8325388d1
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/test-analysernode.html
@@ -0,0 +1,237 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ function testNode() {
+ 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);
+
+ assert_equals(
+ analyser.channelCount,
+ 2,
+ "analyser node has 2 input channels by default"
+ );
+ assert_equals(
+ analyser.channelCountMode,
+ "max",
+ "Correct channelCountMode for the analyser node"
+ );
+ assert_equals(
+ analyser.channelInterpretation,
+ "speakers",
+ "Correct channelCountInterpretation for the analyser node"
+ );
+
+ assert_equals(
+ analyser.fftSize,
+ 2048,
+ "Correct default value for fftSize"
+ );
+ assert_equals(
+ analyser.frequencyBinCount,
+ 1024,
+ "Correct default value for frequencyBinCount"
+ );
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 0;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 1;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 8;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 100;
+ }); // non-power of two
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 2049;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 4097;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 8193;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 16385;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 32769;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.fftSize = 65536;
+ });
+ analyser.fftSize = 1024;
+ assert_equals(
+ analyser.frequencyBinCount,
+ 512,
+ "Correct new value for frequencyBinCount"
+ );
+
+ assert_equals(
+ analyser.minDecibels,
+ -100,
+ "Correct default value for minDecibels"
+ );
+ assert_equals(
+ analyser.maxDecibels,
+ -30,
+ "Correct default value for maxDecibels"
+ );
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.minDecibels = -30;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.minDecibels = -29;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.maxDecibels = -100;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.maxDecibels = -101;
+ });
+
+ assert_true(
+ Math.abs(analyser.smoothingTimeConstant - 0.8) < 0.001,
+ "Correct default value for smoothingTimeConstant"
+ );
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.smoothingTimeConstant = -0.1;
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser.smoothingTimeConstant = 1.1;
+ });
+ analyser.smoothingTimeConstant = 0;
+ analyser.smoothingTimeConstant = 1;
+ }
+
+ function testConstructor() {
+ var context = new AudioContext();
+
+ var analyser = new AnalyserNode(context);
+ assert_equals(
+ analyser.channelCount,
+ 2,
+ "analyser node has 2 input channels by default"
+ );
+ assert_equals(
+ analyser.channelCountMode,
+ "max",
+ "Correct channelCountMode for the analyser node"
+ );
+ assert_equals(
+ analyser.channelInterpretation,
+ "speakers",
+ "Correct channelCountInterpretation for the analyser node"
+ );
+
+ assert_equals(
+ analyser.fftSize,
+ 2048,
+ "Correct default value for fftSize"
+ );
+ assert_equals(
+ analyser.frequencyBinCount,
+ 1024,
+ "Correct default value for frequencyBinCount"
+ );
+ assert_equals(
+ analyser.minDecibels,
+ -100,
+ "Correct default value for minDecibels"
+ );
+ assert_equals(
+ analyser.maxDecibels,
+ -30,
+ "Correct default value for maxDecibels"
+ );
+ assert_true(
+ Math.abs(analyser.smoothingTimeConstant - 0.8) < 0.001,
+ "Correct default value for smoothingTimeConstant"
+ );
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 0 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 1 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 8 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 100 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 2049 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 4097 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 8193 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 16385 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 32769 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { fftSize: 65536 });
+ });
+ analyser = new AnalyserNode(context, { fftSize: 1024 });
+ assert_equals(
+ analyser.frequencyBinCount,
+ 512,
+ "Correct new value for frequencyBinCount"
+ );
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { minDecibels: -30 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { minDecibels: -29 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { maxDecibels: -100 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { maxDecibels: -101 });
+ });
+
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { smoothingTimeConstant: -0.1 });
+ });
+ assert_throws_dom("INDEX_SIZE_ERR", function() {
+ analyser = new AnalyserNode(context, { smoothingTimeConstant: -1.1 });
+ });
+ analyser = new AnalyserNode(context, { smoothingTimeConstant: 0 });
+ analyser = new AnalyserNode(context, { smoothingTimeConstant: 1 });
+ }
+ test(testNode, "Test AnalyserNode API");
+ test(testConstructor, "Test AnalyserNode's ctor API");
+ </script>
+</head>
+</body>
+</html>