Chromium Code Reviews| Index: LayoutTests/webaudio/audionode-disconnect.html |
| diff --git a/LayoutTests/webaudio/audionode-disconnect.html b/LayoutTests/webaudio/audionode-disconnect.html |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..858fd7431858aaae7a570c95db25402385ff2192 |
| --- /dev/null |
| +++ b/LayoutTests/webaudio/audionode-disconnect.html |
| @@ -0,0 +1,257 @@ |
| +<!DOCTYPE html> |
| +<html> |
| + |
| +<head> |
| + <script src="../resources/js-test.js"></script> |
| + <script src="resources/compatibility.js"></script> |
| + <script src="resources/audio-testing.js"></script> |
| +</head> |
| + |
| +<body> |
| + <script> |
| + description('Test disconnect() method on AudioNode destination.'); |
| + window.jsTestIsAsync = true; |
| + |
| + var audit = Audit.createTaskRunner(); |
| + |
| + // Task 1: test disconnect() method. |
| + audit.defineTask('disconnect()', function (done) { |
| + |
| + // Create fan-out connections from a source node to multiple gain nodes. |
| + // Then test if disconnecting all the connections works. |
|
Raymond Toy
2015/02/12 19:45:52
This still doesn't explain the test to me. I had t
hongchan
2015/02/13 01:16:56
Thanks. Done.
|
| + var context = new OfflineAudioContext(1, 128, 44100); |
| + var source = context.createBufferSource(); |
| + var buffer1ch = createTestingBuffer(context, 1, 128); |
| + var gain1 = context.createGain(); |
| + var gain2 = context.createGain(); |
| + var gain3 = context.createGain(); |
| + |
| + source.buffer = buffer1ch; |
| + |
| + source.connect(gain1); |
| + source.connect(gain2); |
| + source.connect(gain3); |
| + gain1.connect(context.destination); |
| + gain2.connect(context.destination); |
| + gain3.connect(context.destination); |
| + source.start(); |
| + |
| + // This disconnects everything. |
| + source.disconnect(); |
| + |
| + context.startRendering().then(function (buffer) { |
| + var channelData = buffer.getChannelData(0); |
| + |
| + // With everything disconnected, the result should be zero. |
| + Should.haveValueInChannel(0, channelData); |
| + |
| + }).then(done); |
| + }); |
| + |
| + // Task 2: test disconnect(output) method. |
| + audit.defineTask('disconnect(output)', function (done) { |
| + |
| + // Create multiple connections from each output of a ChannelSplitter |
| + // to a gain node. Then test if disconnecting a single output of splitter |
| + // works correctly. |
|
Raymond Toy
2015/02/12 19:45:52
"works correctly" is too vague. Say "is actually
hongchan
2015/02/13 01:16:56
Done.
|
| + var context = new OfflineAudioContext(1, 128, 44100); |
| + var source = context.createBufferSource(); |
| + var buffer3ch = createTestingBuffer(context, 3, 128); |
|
Raymond Toy
2015/02/12 19:45:53
Can createTestingBuffer be renamed to createTestin
hongchan
2015/02/13 01:16:56
Done.
|
| + var splitter = context.createChannelSplitter(3); |
| + var sum = context.createGain(); |
| + |
| + source.buffer = buffer3ch; |
| + |
| + source.connect(splitter); |
| + splitter.connect(sum, 0); |
| + splitter.connect(sum, 1); |
| + splitter.connect(sum, 2); |
| + sum.connect(context.destination); |
| + source.start(); |
| + |
| + // This disconnects the second output. |
| + splitter.disconnect(1); |
| + |
| + // There is no output #3. Exception should be thrown. |
| + Should.throwWithType('IndexSizeError', function () { |
| + splitter.disconnect(3); |
| + }); |
| + |
| + // Disconnecting the output already disconnected should not throw. |
| + Should.notThrow(function () { |
| + splitter.disconnect(1); |
| + }); |
|
Raymond Toy
2015/02/12 19:45:52
Can these exception tests be put in a separate tes
hongchan
2015/02/13 01:16:56
Moving all exception checks to dom-exception.html.
|
| + |
| + context.startRendering().then(function (buffer) { |
|
Raymond Toy
2015/02/12 19:45:53
I don't know what the actual style should be, but
hongchan
2015/02/13 01:16:56
Hmm. I am following the style from various JS proj
|
| + var channelData = buffer.getChannelData(0); |
| + |
| + // The rendered channel should contain 4. (= 1 + 0 + 3) |
| + Should.haveValueInChannel(4, channelData); |
| + |
| + }).then(done); |
| + }); |
| + |
| + // Task 3: test disconnect(AudioNode) method. |
| + audit.defineTask('disconnect(AudioNode)', function (done) { |
| + |
| + // Connect a source to multiple gain nodes. Then test if disconnecting a |
| + // single destination selectively works correctly. |
| + var context = new OfflineAudioContext(1, 128, 44100); |
| + var source = context.createBufferSource(); |
| + var buffer1ch = createTestingBuffer(context, 1, 128); |
| + var gain1 = context.createGain(); |
| + var gain2 = context.createGain(); |
| + var gain3 = context.createGain(); |
| + var orphan = context.createGain(); |
| + |
| + source.buffer = buffer1ch; |
| + |
| + source.connect(gain1); |
| + source.connect(gain2); |
| + source.connect(gain3); |
| + gain1.connect(context.destination); |
| + gain2.connect(context.destination); |
| + gain3.connect(context.destination); |
| + source.start(); |
| + |
| + source.disconnect(gain2); |
| + |
| + // gain2 is already disconnected. Exception should be thrown. |
| + Should.throwWithType('InvalidAccessError', function () { |
| + gain1.disconnect(gain2); |
| + }); |
| + |
| + // gain1 and orphan are not connected. Exception should not be thrown. |
| + Should.throwWithType('InvalidAccessError', function () { |
| + gain1.disconnect(orphan); |
| + }); |
|
Raymond Toy
2015/02/12 19:45:53
As above, can these exception tests be moved somew
hongchan
2015/02/13 01:16:57
Done.
|
| + |
| + context.startRendering().then(function (buffer) { |
| + var channelData = buffer.getChannelData(0); |
| + |
| + // The |sum| gain node should produce value 2. (1 + 0 + 1 = 2) |
| + Should.haveValueInChannel(2, channelData); |
| + |
| + }).then(done); |
| + }); |
| + |
| + // Task 4: test disconnect(AudioNode, output) method. |
| + audit.defineTask('disconnect(AudioNode, output)', function (done) { |
| + |
| + // Connect a 2-channel buffer [1, 2] to a ChannelSplitter, then connect |
|
Raymond Toy
2015/02/12 19:45:53
What does the notation [1, 2] mean?
hongchan
2015/02/13 01:16:56
They are constant values for each channel. I thoug
|
| + // the splitter to 2 gain nodes as shown below: |
| + // (1) splitter#0 => gain1 |
| + // (2) splitter#0 => gain2 |
| + // (3) splitter#1 => gain2 |
| + // Then disconnect (2) and verify if the selective disconnection on a |
| + // specified output of the destination node works correctly. |
| + var context = new OfflineAudioContext(1, 128, 44100); |
| + var source = context.createBufferSource(); |
| + var buffer2ch = createTestingBuffer(context, 2, 128); |
| + var splitter = context.createChannelSplitter(2); |
| + var gain1 = context.createGain(); |
| + var gain2 = context.createGain(); |
| + var orphan = context.createGain(); |
| + |
| + source.buffer = buffer2ch; |
| + |
| + source.connect(splitter); |
| + splitter.connect(gain1, 0); // gain1 gets [1] |
| + splitter.connect(gain2, 0); // gain2 gets [1 + 2] |
|
Raymond Toy
2015/02/12 19:45:53
What does gain gets [1] and [1 + 2] mean?
hongchan
2015/02/13 01:16:57
The incoming signal into gain1 is [1] and gain2 is
|
| + splitter.connect(gain2, 1); |
| + gain1.connect(context.destination); |
| + gain2.connect(context.destination); |
| + source.start(); |
| + |
| + splitter.disconnect(gain2, 0); // Now gain2 gets [2] |
| + |
| + // There is no output #2 in the splitter. An exception should be thrown. |
| + Should.throwWithType('IndexSizeError', function () { |
| + splitter.disconnect(gain2, 2); |
| + }); |
| + |
| + // No valid connection to |orphan|. An exception should be thrown. |
| + Should.throwWithType('InvalidAccessError', function () { |
| + splitter.disconnect(orphan, 0); |
| + }); |
|
Raymond Toy
2015/02/12 19:45:52
Again, move these tests somewhere else.
hongchan
2015/02/13 01:16:56
Done.
hongchan
2015/02/13 01:16:56
Done.
|
| + |
| + context.startRendering().then(function (buffer) { |
| + var channelData0 = buffer.getChannelData(0); |
| + |
| + // The sum of gain1 and gain2 should produce value 3. (= 1 + 2) |
| + Should.haveValueInChannel(3, channelData0); |
| + |
| + }).then(done); |
| + }); |
| + |
| + // Task 5: test disconnect(AudioNode, output, input) method. |
| + audit.defineTask('disconnect(AudioNode, output, input)', function (done) { |
| + |
| + // Create a 3-channel buffer [1, 2, 3] and then pass it through a splitter |
| + // and a merger. Each input/output of the splitter and the merger is |
| + // connected in a sequential order as shown below. |
| + // (1) splitter#0 => merger#0 |
| + // (2) splitter#1 => merger#1 |
| + // (3) splitter#2 => merger#2 |
| + // Then disconnect (3) and verify if each channel contains [1] and [2] |
| + // respectively. |
| + var context = new OfflineAudioContext(3, 128, 44100); |
| + var source = context.createBufferSource(); |
| + var buffer3ch = createTestingBuffer(context, 3, 128); |
| + var splitter = context.createChannelSplitter(3); |
| + var merger = context.createChannelMerger(3); |
| + var orphan = context.createGain(); |
| + |
| + context.destination.channelCount = 3; |
| + context.destination.channelCountMode = 'explicit'; |
|
Raymond Toy
2015/02/12 19:45:52
Are these actually necessary? The offline context
hongchan
2015/02/13 01:16:56
Removing.
|
| + source.buffer = buffer3ch; |
| + |
| + source.connect(splitter); |
| + splitter.connect(merger, 0, 0); |
| + splitter.connect(merger, 1, 1); |
| + splitter.connect(merger, 2, 2); |
| + merger.connect(context.destination); |
| + source.start(); |
| + |
| + splitter.disconnect(merger, 2, 2); |
| + |
| + // Orphan doesn't have a connection. An exception should be thrown. |
| + Should.throwWithType('InvalidAccessError', function () { |
| + splitter.disconnect(orphan, 0, 0); |
| + }); |
| + |
| + // The output index is out of bound. An exception should be thrown. |
| + Should.throwWithType('IndexSizeError', function () { |
| + splitter.disconnect(merger, 3, 0); |
| + }); |
| + |
| + context.startRendering().then(function (buffer) { |
| + var channelData0 = buffer.getChannelData(0); |
| + var channelData1 = buffer.getChannelData(1); |
| + |
| + // Each channel should have [1] and [2] respectively. |
| + Should.haveValueInChannel(1, channelData0); |
| + Should.haveValueInChannel(2, channelData1); |
|
Raymond Toy
2015/02/12 19:45:52
What about channel 2? It should be zero, right?
hongchan
2015/02/13 01:16:56
Done.
|
| + |
| + }).then(done); |
| + }); |
| + |
| + audit.defineTask('finish', function (done) { |
| + finishJSTest(); |
| + done(); |
| + }); |
| + |
| + audit.runTasks( |
| + 'disconnect()', |
| + 'disconnect(output)', |
| + 'disconnect(AudioNode)', |
| + 'disconnect(AudioNode, output)', |
| + 'disconnect(AudioNode, output, input)', |
| + 'finish' |
| + ); |
| + |
| + successfullyParsed = true; |
| + </script> |
| +</body> |
| + |
| +</html> |