summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html')
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html221
1 files changed, 221 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html b/testing/web-platform/tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html
new file mode 100644
index 0000000000..0b09edd4a7
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audionode-interface/audionode-disconnect-audioparam.html
@@ -0,0 +1,221 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ audionode-disconnect-audioparam.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 renderQuantum = 128;
+
+ let sampleRate = 44100;
+ let renderDuration = 0.5;
+ let disconnectTime = 0.5 * renderDuration;
+
+ let audit = Audit.createTaskRunner();
+
+ // Calculate the index for disconnection.
+ function getDisconnectIndex(disconnectTime) {
+ let disconnectIndex = disconnectTime * sampleRate;
+ disconnectIndex = renderQuantum *
+ Math.floor((disconnectIndex + renderQuantum - 1) / renderQuantum);
+ return disconnectIndex;
+ }
+
+ // Get the index of value change.
+ function getValueChangeIndex(array, targetValue) {
+ return array.findIndex(function(element, index) {
+ if (element === targetValue)
+ return true;
+ });
+ }
+
+ // Task 1: test disconnect(AudioParam) method.
+ audit.define('disconnect(AudioParam)', (task, should) => {
+ // Creates a buffer source with value [1] and then connect it to two
+ // gain nodes in series. The output of the buffer source is lowered by
+ // half
+ // (* 0.5) and then connected to two |.gain| AudioParams in each gain
+ // node.
+ //
+ // (1) bufferSource => gain1 => gain2
+ // (2) bufferSource => half => gain1.gain
+ // (3) half => gain2.gain
+ //
+ // This graph should produce the output of 2.25 (= 1 * 1.5 * 1.5). After
+ // disconnecting (3), it should produce 1.5.
+ let context =
+ new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate);
+ let source = context.createBufferSource();
+ let buffer1ch = createConstantBuffer(context, 1, 1);
+ let half = context.createGain();
+ let gain1 = context.createGain();
+ let gain2 = context.createGain();
+
+ source.buffer = buffer1ch;
+ source.loop = true;
+ half.gain.value = 0.5;
+
+ source.connect(gain1);
+ gain1.connect(gain2);
+ gain2.connect(context.destination);
+ source.connect(half);
+
+ // Connecting |half| to both |gain1.gain| and |gain2.gain| amplifies the
+ // signal by 2.25 (= 1.5 * 1.5) because each gain node amplifies the
+ // signal by 1.5 (= 1.0 + 0.5).
+ half.connect(gain1.gain);
+ half.connect(gain2.gain);
+
+ source.start();
+
+ // Schedule the disconnection at the half of render duration.
+ context.suspend(disconnectTime).then(function() {
+ half.disconnect(gain2.gain);
+ context.resume();
+ });
+
+ context.startRendering()
+ .then(function(buffer) {
+ let channelData = buffer.getChannelData(0);
+ let disconnectIndex = getDisconnectIndex(disconnectTime);
+ let valueChangeIndex = getValueChangeIndex(channelData, 1.5);
+
+ // Expected values are: 1 * 1.5 * 1.5 -> 1 * 1.5 = [2.25, 1.5]
+ should(channelData, 'Channel #0').containValues([2.25, 1.5]);
+ should(valueChangeIndex, 'The index of value change')
+ .beEqualTo(disconnectIndex);
+ })
+ .then(() => task.done());
+ });
+
+ // Task 2: test disconnect(AudioParam, output) method.
+ audit.define('disconnect(AudioParam, output)', (task, should) => {
+ // Create a 2-channel buffer source with [1, 2] in each channel and
+ // make a serial connection through gain1 and gain 2. The make the
+ // buffer source half with a gain node and connect it to a 2-output
+ // splitter. Connect each output to 2 gain AudioParams respectively.
+ //
+ // (1) bufferSource => gain1 => gain2
+ // (2) bufferSource => half => splitter(2)
+ // (3) splitter#0 => gain1.gain
+ // (4) splitter#1 => gain2.gain
+ //
+ // This graph should produce 3 (= 1 * 1.5 * 2) and 6 (= 2 * 1.5 * 2) for
+ // each channel. After disconnecting (4), it should output 1.5 and 3.
+ let context =
+ new OfflineAudioContext(2, renderDuration * sampleRate, sampleRate);
+ let source = context.createBufferSource();
+ let buffer2ch = createConstantBuffer(context, 1, [1, 2]);
+ let splitter = context.createChannelSplitter(2);
+ let half = context.createGain();
+ let gain1 = context.createGain();
+ let gain2 = context.createGain();
+
+ source.buffer = buffer2ch;
+ source.loop = true;
+ half.gain.value = 0.5;
+
+ source.connect(gain1);
+ gain1.connect(gain2);
+ gain2.connect(context.destination);
+
+ // |source| originally is [1, 2] but it becomes [0.5, 1] after 0.5 gain.
+ // Each splitter's output will be applied to |gain1.gain| and
+ // |gain2.gain| respectively in an additive fashion.
+ source.connect(half);
+ half.connect(splitter);
+
+ // This amplifies the signal by 1.5. (= 1.0 + 0.5)
+ splitter.connect(gain1.gain, 0);
+
+ // This amplifies the signal by 2. (= 1.0 + 1.0)
+ splitter.connect(gain2.gain, 1);
+
+ source.start();
+
+ // Schedule the disconnection at the half of render duration.
+ context.suspend(disconnectTime).then(function() {
+ splitter.disconnect(gain2.gain, 1);
+ context.resume();
+ });
+
+ context.startRendering()
+ .then(function(buffer) {
+ let channelData0 = buffer.getChannelData(0);
+ let channelData1 = buffer.getChannelData(1);
+
+ let disconnectIndex = getDisconnectIndex(disconnectTime);
+ let valueChangeIndexCh0 = getValueChangeIndex(channelData0, 1.5);
+ let valueChangeIndexCh1 = getValueChangeIndex(channelData1, 3);
+
+ // Expected values are: 1 * 1.5 * 2 -> 1 * 1.5 = [3, 1.5]
+ should(channelData0, 'Channel #0').containValues([3, 1.5]);
+ should(
+ valueChangeIndexCh0,
+ 'The index of value change in channel #0')
+ .beEqualTo(disconnectIndex);
+
+ // Expected values are: 2 * 1.5 * 2 -> 2 * 1.5 = [6, 3]
+ should(channelData1, 'Channel #1').containValues([6, 3]);
+ should(
+ valueChangeIndexCh1,
+ 'The index of value change in channel #1')
+ .beEqualTo(disconnectIndex);
+ })
+ .then(() => task.done());
+ });
+
+ // Task 3: exception checks.
+ audit.define('exceptions', (task, should) => {
+ let context = new AudioContext();
+ let gain1 = context.createGain();
+ let splitter = context.createChannelSplitter(2);
+ let gain2 = context.createGain();
+ let gain3 = context.createGain();
+
+ // Connect a splitter to gain nodes and merger so we can test the
+ // possible ways of disconnecting the nodes to verify that appropriate
+ // exceptions are thrown.
+ gain1.connect(splitter);
+ splitter.connect(gain2.gain, 0);
+ splitter.connect(gain3.gain, 1);
+ gain2.connect(gain3);
+ gain3.connect(context.destination);
+
+ // gain1 is not connected to gain3.gain. Exception should be thrown.
+ should(
+ function() {
+ gain1.disconnect(gain3.gain);
+ },
+ 'gain1.disconnect(gain3.gain)')
+ .throw(DOMException, 'InvalidAccessError');
+
+ // When the output index is good but the destination is invalid.
+ should(
+ function() {
+ splitter.disconnect(gain1.gain, 1);
+ },
+ 'splitter.disconnect(gain1.gain, 1)')
+ .throw(DOMException, 'InvalidAccessError');
+
+ // When both arguments are wrong, throw IndexSizeError first.
+ should(
+ function() {
+ splitter.disconnect(gain1.gain, 2);
+ },
+ 'splitter.disconnect(gain1.gain, 2)')
+ .throw(DOMException, 'IndexSizeError');
+
+ task.done();
+ });
+
+ audit.run();
+ </script>
+ </body>
+</html>