| // For the current implementation of JavaScriptAudioNode, when it works with |
| // OfflineAudioContext (which runs much faster than real-time) the |
| // event.inputBuffer might be overwrite again before onaudioprocess ever get |
| // chance to be called. We carefully arrange the renderLengthInFrames and |
| // bufferSize to have exactly the same value to avoid this issue. |
| var renderLengthInFrames = 512; |
| var bufferSize = 512; |
| |
| var context; |
| |
| function createBuffer(context, numberOfChannels, length) { |
| let audioBuffer = context.createBuffer(numberOfChannels, length, sampleRate); |
| |
| fillData(audioBuffer, numberOfChannels, audioBuffer.length); |
| return audioBuffer; |
| } |
| |
| function processAudioData(event) { |
| buffer = event.outputBuffer; |
| if (buffer.numberOfChannels != outputChannels) |
| testFailed('numberOfOutputChannels doesn\'t match!'); |
| |
| if (buffer.length != bufferSize) |
| testFailed('length of buffer doesn\'t match!'); |
| |
| buffer = event.inputBuffer; |
| |
| let success = checkStereoOnlyData(buffer, inputChannels, buffer.length); |
| |
| if (success) { |
| testPassed('onaudioprocess was called with correct input data.'); |
| } else { |
| testFailed('onaudioprocess was called with wrong input data.'); |
| } |
| } |
| |
| function fillData(buffer, numberOfChannels, length) { |
| for (let i = 0; i < numberOfChannels; ++i) { |
| let data = buffer.getChannelData(i); |
| |
| for (let j = 0; j < length; ++j) |
| if (i < 2) |
| data[j] = i * 2 - 1; |
| else |
| data[j] = 0; |
| } |
| } |
| |
| // Both 2 to 8 upmix and 8 to 2 downmix are just directly copy the first two |
| // channels and left channels are zeroed. |
| function checkStereoOnlyData(buffer, numberOfChannels, length) { |
| for (let i = 0; i < numberOfChannels; ++i) { |
| let data = buffer.getChannelData(i); |
| |
| for (let j = 0; j < length; ++j) { |
| if (i < 2) { |
| if (data[j] != i * 2 - 1) |
| return false; |
| } else { |
| if (data[j] != 0) |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| |
| function runJSNodeTest() { |
| // Create offline audio context. |
| context = new OfflineAudioContext(2, renderLengthInFrames, sampleRate); |
| |
| let sourceBuffer = |
| createBuffer(context, sourceChannels, renderLengthInFrames); |
| |
| let bufferSource = context.createBufferSource(); |
| bufferSource.buffer = sourceBuffer; |
| |
| let scriptNode = |
| context.createScriptProcessor(bufferSize, inputChannels, outputChannels); |
| |
| bufferSource.connect(scriptNode); |
| scriptNode.connect(context.destination); |
| scriptNode.onaudioprocess = processAudioData; |
| |
| bufferSource.start(0); |
| context.oncomplete = finishJSTest; |
| context.startRendering(); |
| } |