summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface')
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html85
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html38
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-output.html207
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html50
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html135
5 files changed, 515 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html
new file mode 100644
index 0000000000..4f925df5cd
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ Basic ConstantSourceNode Tests
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../../resources/audit-util.js"></script>
+ <script src="../../resources/audit.js"></script>
+ <script src="../../resources/start-stop-exceptions.js"></script>
+ </head>
+ <body>
+ <script id="layout-test-code">
+ let context = new AudioContext();
+
+ let audit = Audit.createTaskRunner();
+
+ audit.define('createConstantSource()', (task, should) => {
+ let node;
+ let prefix = 'Factory method: ';
+
+ should(() => {
+ node = context.createConstantSource();
+ }, prefix + 'node = context.createConstantSource()').notThrow();
+ should(
+ node instanceof ConstantSourceNode,
+ prefix + 'node instance of ConstantSourceNode')
+ .beEqualTo(true);
+
+ verifyNodeDefaults(should, node, prefix);
+
+ task.done();
+ });
+
+ audit.define('new ConstantSourceNode()', (task, should) => {
+ let node;
+ let prefix = 'Constructor: ';
+
+ should(() => {
+ node = new ConstantSourceNode(context);
+ }, prefix + 'node = new ConstantSourceNode()').notThrow();
+ should(
+ node instanceof ConstantSourceNode,
+ prefix + 'node instance of ConstantSourceNode')
+ .beEqualTo(true);
+
+
+ verifyNodeDefaults(should, node, prefix);
+
+ task.done();
+ });
+
+ audit.define('start/stop exceptions', (task, should) => {
+ let node = new ConstantSourceNode(context);
+
+ testStartStop(should, node);
+ task.done();
+ });
+
+ function verifyNodeDefaults(should, node, prefix) {
+ should(node.numberOfInputs, prefix + 'node.numberOfInputs')
+ .beEqualTo(0);
+ should(node.numberOfOutputs, prefix + 'node.numberOfOutputs')
+ .beEqualTo(1);
+ should(node.channelCount, prefix + 'node.channelCount').beEqualTo(2);
+ should(node.channelCountMode, prefix + 'node.channelCountMode')
+ .beEqualTo('max');
+ should(
+ node.channelInterpretation, prefix + 'node.channelInterpretation')
+ .beEqualTo('speakers');
+
+ should(node.offset.value, prefix + 'node.offset.value').beEqualTo(1);
+ should(node.offset.defaultValue, prefix + 'node.offset.defaultValue')
+ .beEqualTo(1);
+ should(node.offset.minValue, prefix + 'node.offset.minValue')
+ .beEqualTo(Math.fround(-3.4028235e38));
+ should(node.offset.maxValue, prefix + 'node.offset.maxValue')
+ .beEqualTo(Math.fround(3.4028235e38));
+ }
+
+ audit.run();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html
new file mode 100644
index 0000000000..64bc54f21b
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ Test ConstantSourceNode onended
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <script id="layout-test-code">
+ let sampleRate = 44100.0;
+ // Number of frames that the source will run; fairly arbitrary
+ let numberOfFrames = 32;
+ // Number of frames to render; arbitrary, but should be larger than
+ // numberOfFrames;
+ let renderFrames = 16 * numberOfFrames;
+
+ let context = new OfflineAudioContext(1, renderFrames, sampleRate);
+ let src = new ConstantSourceNode(context);
+ src.connect(context.destination);
+
+ let tester = async_test('ConstantSourceNode onended event fired');
+
+ src.onended = function() {
+ tester.step(function() {
+ assert_true(true, 'ConstantSourceNode.onended fired');
+ });
+ tester.done();
+ };
+
+ src.start();
+ src.stop(numberOfFrames / context.sampleRate);
+
+ context.startRendering();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-output.html b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-output.html
new file mode 100644
index 0000000000..5990376cff
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-output.html
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ Test ConstantSourceNode Output
+ </title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../../resources/audit-util.js"></script>
+ <script src="../../resources/audit.js"></script>
+ <script src="../../resources/audioparam-testing.js"></script>
+ </head>
+ <body>
+ <script id="layout-test-code">
+ let sampleRate = 48000;
+ let renderDuration = 0.125;
+ let renderFrames = sampleRate * renderDuration;
+
+ let audit = Audit.createTaskRunner();
+
+ audit.define('constant source', (task, should) => {
+ // Verify a constant source outputs the correct (fixed) constant.
+ let context = new OfflineAudioContext(1, renderFrames, sampleRate);
+ let node = new ConstantSourceNode(context, {offset: 0.5});
+ node.connect(context.destination);
+ node.start();
+
+ context.startRendering()
+ .then(function(buffer) {
+ let actual = buffer.getChannelData(0);
+ let expected = new Float32Array(actual.length);
+ expected.fill(node.offset.value);
+
+ should(actual, 'Basic: ConstantSourceNode({offset: 0.5})')
+ .beEqualToArray(expected);
+ })
+ .then(() => task.done());
+ });
+
+ audit.define('stop before start', (task, should) => {
+ let context = new OfflineAudioContext(1, renderFrames, sampleRate);
+ let node = new ConstantSourceNode(context, {offset: 1});
+ node.connect(context.destination);
+ node.start(61 / context.sampleRate);
+ node.stop(31 / context.sampleRate);
+
+ context.startRendering()
+ .then(function(buffer) {
+ let actual = buffer.getChannelData(0);
+ should(actual,
+ "ConstantSourceNode with stop before " +
+ "start must output silence")
+ .beConstantValueOf(0);
+ })
+ .then(() => task.done());
+ });
+
+ audit.define('stop equal to start', (task, should) => {
+ let context = new OfflineAudioContext(1, renderFrames, sampleRate);
+ let node = new ConstantSourceNode(context, {offset: 1});
+ node.connect(context.destination);
+ node.start(31 / context.sampleRate);
+ node.stop(31 / context.sampleRate);
+
+ context.startRendering()
+ .then(function(buffer) {
+ let actual = buffer.getChannelData(0);
+ should(actual,
+ "ConstantSourceNode with stop equal to start " +
+ " must output silence")
+ .beConstantValueOf(0);
+ })
+ .then(() => task.done());
+ });
+
+ audit.define('start/stop', (task, should) => {
+ // Verify a constant source starts and stops at the correct time and has
+ // the correct (fixed) value.
+ let context = new OfflineAudioContext(1, renderFrames, sampleRate);
+ let node = new ConstantSourceNode(context, {offset: 1});
+ node.connect(context.destination);
+
+ let startFrame = 10;
+ let stopFrame = 300;
+
+ node.start(startFrame / context.sampleRate);
+ node.stop(stopFrame / context.sampleRate);
+
+ context.startRendering()
+ .then(function(buffer) {
+ let actual = buffer.getChannelData(0);
+ let expected = new Float32Array(actual.length);
+ // The expected output is all 1s from start to stop time.
+ expected.fill(0);
+
+ for (let k = startFrame; k < stopFrame; ++k) {
+ expected[k] = node.offset.value;
+ }
+
+ let prefix = 'start/stop: ';
+ should(actual.slice(0, startFrame),
+ prefix + 'ConstantSourceNode frames [0, ' +
+ startFrame + ')')
+ .beConstantValueOf(0);
+
+ should(actual.slice(startFrame, stopFrame),
+ prefix + 'ConstantSourceNode frames [' +
+ startFrame + ', ' + stopFrame + ')')
+ .beConstantValueOf(1);
+
+ should(
+ actual.slice(stopFrame),
+ prefix + 'ConstantSourceNode frames [' + stopFrame +
+ ', ' + renderFrames + ')')
+ .beConstantValueOf(0);
+ })
+ .then(() => task.done());
+
+ });
+
+ audit.define('basic automation', (task, should) => {
+ // Verify that automation works as expected.
+ let context = new OfflineAudioContext(1, renderFrames, sampleRate);
+ let source = context.createConstantSource();
+ source.connect(context.destination);
+
+ let rampEndTime = renderDuration / 2;
+ source.offset.setValueAtTime(0.5, 0);
+ source.offset.linearRampToValueAtTime(1, rampEndTime);
+
+ source.start();
+
+ context.startRendering()
+ .then(function(buffer) {
+ let actual = buffer.getChannelData(0);
+ let expected = createLinearRampArray(
+ 0, rampEndTime, 0.5, 1, context.sampleRate);
+
+ let rampEndFrame = Math.ceil(rampEndTime * context.sampleRate);
+ let prefix = 'Automation: ';
+
+ should(actual.slice(0, rampEndFrame),
+ prefix + 'ConstantSourceNode.linearRamp(1, 0.5)')
+ .beCloseToArray(expected, {
+ // Experimentally determined threshold.
+ relativeThreshold: 7.1610e-7
+ });
+
+ should(actual.slice(rampEndFrame),
+ prefix + 'ConstantSourceNode after ramp')
+ .beConstantValueOf(1);
+ })
+ .then(() => task.done());
+ });
+
+ audit.define('connected audioparam', (task, should) => {
+ // Verify the constant source output with connected AudioParam produces
+ // the correct output.
+ let context = new OfflineAudioContext(2, renderFrames, sampleRate)
+ context.destination.channelInterpretation = 'discrete';
+ let source = new ConstantSourceNode(context, {offset: 1});
+ let osc = context.createOscillator();
+ let merger = context.createChannelMerger(2);
+ merger.connect(context.destination);
+
+ source.connect(merger, 0, 0);
+ osc.connect(merger, 0, 1);
+ osc.connect(source.offset);
+
+ osc.start();
+ let sourceStartFrame = 10;
+ source.start(sourceStartFrame / context.sampleRate);
+
+ context.startRendering()
+ .then(function(buffer) {
+ // Channel 0 and 1 should be identical, except channel 0 (the
+ // source) is silent at the beginning.
+ let actual = buffer.getChannelData(0);
+ let expected = buffer.getChannelData(1);
+ // The expected output should be oscillator + 1 because offset
+ // is 1.
+ expected = expected.map(x => 1 + x);
+ let prefix = 'Connected param: ';
+
+ // The initial part of the output should be silent because the
+ // source node hasn't started yet.
+ should(
+ actual.slice(0, sourceStartFrame),
+ prefix + 'ConstantSourceNode frames [0, ' + sourceStartFrame +
+ ')')
+ .beConstantValueOf(0);
+ // The rest of the output should be the same as the oscillator (in
+ // channel 1)
+ should(
+ actual.slice(sourceStartFrame),
+ prefix + 'ConstantSourceNode frames [' + sourceStartFrame +
+ ', ' + renderFrames + ')')
+ .beCloseToArray(expected.slice(sourceStartFrame), 0);
+
+ })
+ .then(() => task.done());
+ });
+
+ audit.run();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html
new file mode 100644
index 0000000000..ea4a65e146
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ Test Constructor: ConstantSource
+ </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, 'ConstantSourceNode', context);
+ task.done();
+ });
+
+ audit.define('default constructor', (task, should) => {
+ let prefix = 'node0';
+ let node =
+ testDefaultConstructor(should, 'ConstantSourceNode', context, {
+ prefix: prefix,
+ numberOfInputs: 0,
+ numberOfOutputs: 1,
+ channelCount: 2,
+ channelCountMode: 'max',
+ channelInterpretation: 'speakers'
+ });
+
+ testDefaultAttributes(
+ should, node, prefix, [{name: 'offset', value: 1}]);
+
+ task.done();
+ });
+
+ audit.run();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html
new file mode 100644
index 0000000000..04f61106c1
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html
@@ -0,0 +1,135 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test the ConstantSourceNode Interface</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+test(function(t) {
+ var ac = new AudioContext();
+
+ var csn = ac.createConstantSource();
+ assert_equals(csn.offset.value, 1.0, "Default offset is 1.0");
+
+ csn = new ConstantSourceNode(ac);
+ assert_equals(csn.offset.value, 1.0, "Default offset is 1.0");
+
+ csn = new ConstantSourceNode(ac, {offset: -0.25});
+ assert_equals(csn.offset.value, -0.25, "Offset can be set during construction");
+}, "ConstantSourceNode can be constructed");
+
+test(function(t) {
+ var ac = new AudioContext();
+
+ var csn = ac.createConstantSource();
+
+ assert_throws_dom("InvalidStateError", function() {
+ csn.stop(1);
+ }, "Start must be called before stop");
+
+ assert_throws_js(RangeError, function() {
+ csn.start(-1);
+ }, "When can not be negative");
+
+ csn.start(0);
+ assert_throws_js(RangeError, function() {
+ csn.stop(-1);
+ }, "When can not be negative");
+}, "ConstantSourceNode stop and start");
+
+async_test(function(t) {
+ var ac = new OfflineAudioContext(1, 2048, 44100);
+ var csn = ac.createConstantSource();
+ csn.connect(ac.destination);
+ csn.start()
+ csn.stop(1024/44100)
+ csn.onended = function(e) {
+ t.step(function() {
+ assert_equals(e.type, "ended", "Event type should be 'ended', received: " + e.type);
+ });
+ t.done();
+ }
+ ac.startRendering();
+}, "ConstantSourceNode onended event");
+
+async_test(function(t) {
+ var ac = new OfflineAudioContext(1, 2048, 44100);
+ var csn = ac.createConstantSource();
+ csn.connect(ac.destination);
+ csn.start(512/44100)
+ csn.stop(1024/44100)
+
+ ac.oncomplete = function(e) {
+ t.step(function() {
+ var result = e.renderedBuffer.getChannelData(0);
+ for (var i = 0; i < 2048; ++i) {
+ if (i >= 512 && i < 1024) {
+ assert_equals(result[i], 1.0, "sample " + i + " should equal 1.0");
+ } else {
+ assert_equals(result[i], 0.0, "sample " + i + " should equal 0.0");
+ }
+ }
+ });
+ t.done();
+ }
+
+ ac.startRendering();
+}, "ConstantSourceNode start and stop when work");
+
+async_test(function(t) {
+ var ac = new OfflineAudioContext(1, 2048, 44100);
+ var csn = ac.createConstantSource();
+ csn.offset.value = 0.25;
+ csn.connect(ac.destination);
+ csn.start()
+
+ ac.oncomplete = function(e) {
+ t.step(function() {
+ var result = e.renderedBuffer.getChannelData(0);
+ for (var i = 0; i < 2048; ++i) {
+ assert_equals(result[i], 0.25, "sample " + i + " should equal 0.25");
+ }
+ });
+ t.done();
+ }
+
+ ac.startRendering();
+}, "ConstantSourceNode with no automation");
+
+async_test(function(t) {
+ var ac = new OfflineAudioContext(1, 2048, 44100);
+
+ var timeConstant = 2.0;
+ var offsetStart = 0.25;
+ var offsetEnd = 0.1;
+
+ var csn = ac.createConstantSource();
+ csn.offset.value = offsetStart;
+ csn.offset.setTargetAtTime(offsetEnd, 1024/ac.sampleRate, timeConstant);
+ csn.connect(ac.destination);
+ csn.start()
+
+ ac.oncomplete = function(e) {
+ t.step(function() {
+ // create buffer with expected values
+ var buffer = ac.createBuffer(1, 2048, ac.sampleRate);
+ for (var i = 0; i < 2048; ++i) {
+ if (i < 1024) {
+ buffer.getChannelData(0)[i] = offsetStart;
+ } else {
+ time = (i-1024)/ac.sampleRate;
+ buffer.getChannelData(0)[i] = offsetEnd + (offsetStart - offsetEnd)*Math.exp(-time/timeConstant);
+ }
+ }
+
+ var result = e.renderedBuffer.getChannelData(0);
+ var expected = buffer.getChannelData(0);
+ for (var i = 0; i < 2048; ++i) {
+ assert_true(Math.abs(result[i] - expected[i]) < 1.342e-6, "sample " + i + " should equal " + expected[i]);
+ }
+ });
+ t.done();
+ }
+
+ ac.startRendering();
+}, "ConstantSourceNode with automation");
+</script>