OLD | NEW |
| (Empty) |
1 <!DOCTYPE html> | |
2 <html> | |
3 | |
4 <head> | |
5 <script src="../resources/js-test.js"></script> | |
6 <script src="resources/compatibility.js"></script> | |
7 <script src="resources/audit-util.js"></script> | |
8 <script src="resources/audio-testing.js"></script> | |
9 </head> | |
10 | |
11 <body> | |
12 <script> | |
13 description('Test method chaining feature of AudioNode.connect() method.'); | |
14 window.jsTestIsAsync = true; | |
15 | |
16 // AudioNode dictionary with associated arguments. | |
17 var nodeDictionary = [ | |
18 { name: 'Analyser' }, | |
19 { name: 'BiquadFilter' }, | |
20 { name: 'BufferSource' }, | |
21 { name: 'ChannelMerger', args: [6] }, | |
22 { name: 'ChannelSplitter', args: [6] }, | |
23 { name: 'Convolver' }, | |
24 { name: 'Delay', args: [] }, | |
25 { name: 'DynamicsCompressor' }, | |
26 { name: 'Gain' }, | |
27 { name: 'Oscillator' }, | |
28 { name: 'Panner' }, | |
29 { name: 'ScriptProcessor', args: [512, 1, 1] }, | |
30 { name: 'StereoPanner' }, | |
31 { name: 'WaveShaper' } | |
32 ]; | |
33 | |
34 | |
35 function verifyReturnedNode(config) { | |
36 if (config.destination === config.returned) { | |
37 testPassed('The return value of ' + config.desc + ' matches the destinat
ion ' + | |
38 config.returned.constructor.name + '.'); | |
39 } else { | |
40 testFailed('The return value of ' + config.desc + ' does NOT match the d
estination ' + | |
41 config.destination.constructor.name + '.'); | |
42 } | |
43 } | |
44 | |
45 // Test utility for batch method checking: in order to test 3 method | |
46 // signatures, so we create 3 dummy destinations. | |
47 // 1) .connect(GainNode) | |
48 // 2) .connect(BiquadFilterNode, output) | |
49 // 3) .connect(ChannelMergerNode, output, input) | |
50 function testConnectMethod(context, options) { | |
51 var source = context['create' + options.name].apply(context, options.args)
; | |
52 var sourceName = source.constructor.name; | |
53 | |
54 var destination1 = context.createGain(); | |
55 verifyReturnedNode({ | |
56 source: source, | |
57 destination: destination1, | |
58 returned: source.connect(destination1), | |
59 desc: sourceName + '.connect(' + destination1.constructor.name + ')' | |
60 }); | |
61 | |
62 var destination2 = context.createBiquadFilter(); | |
63 verifyReturnedNode({ | |
64 source: source, | |
65 destination: destination2, | |
66 returned: source.connect(destination2, 0), | |
67 desc: sourceName + '.connect(' + destination2.constructor.name + ', 0)' | |
68 }); | |
69 | |
70 var destination3 = context.createChannelMerger(); | |
71 verifyReturnedNode({ | |
72 source: source, | |
73 destination: destination3, | |
74 returned: source.connect(destination3, 0, 1), | |
75 desc: sourceName + '.connect(' + destination3.constructor.name + ', 0, 1
)' | |
76 }); | |
77 } | |
78 | |
79 | |
80 var audit = Audit.createTaskRunner(); | |
81 | |
82 // Task: testing entries from the dictionary. | |
83 audit.defineTask('from-dictionary', function (done) { | |
84 var context = new AudioContext(); | |
85 | |
86 for (var i = 0; i < nodeDictionary.length; i++) | |
87 testConnectMethod(context, nodeDictionary[i]); | |
88 | |
89 done(); | |
90 }); | |
91 | |
92 // Task: testing Media* nodes. | |
93 audit.defineTask('media-group', function (done) { | |
94 var context = new AudioContext(); | |
95 | |
96 // Test MediaElementSourceNode needs an <audio> element. | |
97 var mediaElement = document.createElement('audio'); | |
98 testConnectMethod(context, { name: 'MediaElementSource', args: [mediaEleme
nt] }); | |
99 | |
100 testConnectMethod(context, { name: 'MediaStreamDestination' }); | |
101 | |
102 // MediaStreamSourceNode requires 'stream' object to be constructed, which | |
103 // is a part of MediaStreamDestinationNode. | |
104 var streamDestination = context.createMediaStreamDestination(); | |
105 var stream = streamDestination.stream; | |
106 testConnectMethod(context, { name: 'MediaStreamSource', args: [stream] }); | |
107 | |
108 done(); | |
109 }); | |
110 | |
111 // Task: test the exception thrown by invalid operation. | |
112 audit.defineTask('invalid-operation', function (done) { | |
113 var contextA = new AudioContext(); | |
114 var contextB = new AudioContext(); | |
115 var gain1 = contextA.createGain(); | |
116 var gain2 = contextA.createGain(); | |
117 | |
118 // Test if the first connection throws correctly. The first gain node does | |
119 // not have the second output, so it should throw. | |
120 Should('Connecting with an invalid output', function () { | |
121 gain1.connect(gain2, 1).connect(contextA.destination); | |
122 }).throw('IndexSizeError'); | |
123 | |
124 // Test if the second connection throws correctly. The contextB's | |
125 // destination is not compatible with the nodes from contextA, thus the | |
126 // first connection succeeds but the second one should throw. | |
127 Should('Connecting to a node from the different context', function () { | |
128 gain1.connect(gain2).connect(contextB.destination); | |
129 }).throw('SyntaxError'); | |
130 | |
131 done(); | |
132 }); | |
133 | |
134 // Task: verify if the method chaining actually works. | |
135 audit.defineTask('verification', function (done) { | |
136 // We pick the lowest sample rate allowed to run the test efficiently. | |
137 var context = new OfflineAudioContext(1, 128, 3000); | |
138 | |
139 var constantBuffer = createConstantBuffer(context, 1, 1.0); | |
140 | |
141 var source = context.createBufferSource(); | |
142 source.buffer = constantBuffer; | |
143 source.loop = true; | |
144 | |
145 var gain1 = context.createGain(); | |
146 gain1.gain.value = 0.5; | |
147 var gain2 = context.createGain(); | |
148 gain2.gain.value = 0.25; | |
149 | |
150 source.connect(gain1).connect(gain2).connect(context.destination); | |
151 source.start(); | |
152 | |
153 context.startRendering().then(function (buffer) { | |
154 Should('The output of chained connection of gain nodes', buffer.getChann
elData(0)) | |
155 .beConstantValueOf(0.125); | |
156 }).then(done); | |
157 }); | |
158 | |
159 audit.defineTask('finish', function (done) { | |
160 finishJSTest(); | |
161 done(); | |
162 }); | |
163 | |
164 audit.runTasks( | |
165 'from-dictionary', | |
166 'media-group', | |
167 'invalid-operation', | |
168 'verification', | |
169 'finish' | |
170 ); | |
171 | |
172 successfullyParsed = true; | |
173 </script> | |
174 </body> | |
175 | |
176 </html> | |
OLD | NEW |