4 <script src="../resources/js-test.js"></script>
5 <script src="resources/compatibility.js"></script>
6 <script type="text/javascript" src="resources/audio-testing.js"></script>
11 <div id="description"></div>
12 <div id="console"></div>
15 description("Tests ScriptProcessorNode.");
17 var sampleRate = 44100.0;
18 var outputChannels = 6;
19 var playbackTime = 0.0;
21 // For the current implementation of ScriptProcessorNode, when it works with OfflineAudioContext (which runs much faster
22 // than real-time) the event.inputBuffer might be overwrite again before onaudioprocess ever get chance to be called.
23 // We carefully arrange the renderLengthInFrames and bufferSize to have exactly the same value to avoid this issue.
24 var renderLengthInFrames = 512;
29 function createBuffer(context, length) {
30 var audioBuffer = context.createBuffer(2, length, sampleRate);
31 var n = audioBuffer.length;
32 var dataL = audioBuffer.getChannelData(0);
33 var dataR = audioBuffer.getChannelData(1);
35 for (var i = 0; i < n; ++i) {
43 function processAudioData(event) {
44 playbackTime = event.playbackTime;
45 var expectedTime = context.currentTime + (bufferSize / context.sampleRate);
46 var allowedTimeGap = 0.0000001;
48 // There may be a little time gap which is from different thread operation
49 // between currentTime when main thread fires onaudioprocess() and currenTime when read in JS
50 // since currentTime is continuously increasing on audio thread.
51 shouldBeCloseTo("playbackTime", expectedTime, allowedTimeGap, true);
53 buffer = event.outputBuffer;
54 if (buffer.numberOfChannels != outputChannels)
55 testFailed("numberOfOutputChannels doesn't match!");
57 if (buffer.length != bufferSize)
58 testFailed("numberOfOutputChannels doesn't match!");
60 buffer = event.inputBuffer;
61 var bufferDataL = buffer.getChannelData(0);
62 var bufferDataR = buffer.getChannelData(1);
65 // Go through every sample and make sure it's all -1 for the left-channel, and all +1 for the right-channel.
66 for (var i = 0; i < buffer.length; ++i) {
67 if (bufferDataL[i] != -1 || bufferDataR[i] != 1) {
74 testPassed("onaudioprocess was called with correct data.");
76 testFailed("onaudioprocess was called with wrong data.");
80 function doBufferSizeTest(size) {
82 var jsnode = context.createScriptProcessor(size, 1, 1);
83 testPassed("Successfully created ScriptProcessorNode with bufferSize = " + size + ".");
85 testFailed("Failed to create ScriptProcessorNode with bufferSize = " + size + ".");
90 if (window.testRunner) {
91 testRunner.dumpAsText();
92 testRunner.waitUntilDone();
95 window.jsTestIsAsync = true;
97 // Create offline audio context.
98 context = new OfflineAudioContext(2, renderLengthInFrames, sampleRate);
101 var jsnode = context.createScriptProcessor(512, 0, 0);
102 testFailed("Exception should be thrown when both numberOfInputChannels and numberOfOutputChannels are zero.");
104 testPassed("Exception was thrown when both numberOfInputChannels and numberOfOutputChannels are zero.");
108 var jsnode = context.createScriptProcessor(512, 1, 0);
109 testPassed("Successfully created ScriptProcessorNode with numberOfInputChannels = 1 and numberOfOutputChannels = 0.");
111 testFailed("Exception should not be thrown when numberOfInputChannels = 1 and numberOfOutputChannels = 0.");
115 var jsnode = context.createScriptProcessor(512, 2, 0);
116 testPassed("Successfully created ScriptProcessorNode with numberOfInputChannels = 2 and numberOfOutputChannels = 0.");
118 testFailed("Exception should not be thrown when numberOfInputChannels = 2 and numberOfOutputChannels = 0.");
122 var jsnode = context.createScriptProcessor(512, 0, 1);
123 testPassed("Successfully created ScriptProcessorNode with numberOfInputChannels = 0 and numberOfOutputChannels = 1.");
125 testFailed("Exception should not be thrown when numberOfInputChannels = 0 and numberOfOutputChannels = 1.");
129 var jsnode = context.createScriptProcessor(512, 0, 2);
130 testPassed("Successfully created ScriptProcessorNode with numberOfInputChannels = 0 and numberOfOutputChannels = 2.");
132 testFailed("Exception should not be thrown when numberOfInputChannels = 0 and numberOfOutputChannels = 2.");
136 var jsnode = context.createScriptProcessor(511, 1, 1);
137 testFailed("Exception should be thrown for illegal bufferSize.");
139 testPassed("Exception was thrown for illegal bufferSize.");
142 doBufferSizeTest(256);
143 doBufferSizeTest(512);
144 doBufferSizeTest(1024);
145 doBufferSizeTest(2048);
146 doBufferSizeTest(4096);
147 doBufferSizeTest(8192);
148 doBufferSizeTest(16384);
150 var sourceBuffer = createBuffer(context, renderLengthInFrames);
152 var bufferSource = context.createBufferSource();
153 bufferSource.buffer = sourceBuffer;
155 var jsnode = context.createScriptProcessor(bufferSize, 2, outputChannels);
157 bufferSource.connect(jsnode);
158 jsnode.connect(context.destination);
159 jsnode.onaudioprocess = processAudioData;
161 bufferSource.start(0);
162 context.oncomplete = finishJSTest;
163 context.startRendering();