Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

  • This test has a WPT meta file that expects 2 subtest issues.
  • This WPT test may be referenced by the following Test IDs:
    • /webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html - WPT Dashboard Interop Dashboard
<!doctype html>
<!--
Tests that a create MediaElementSourceNode that is passed through
a script processor passes the stream data.
The the script processor saves the input buffers it gets to a temporary
array, and after the playback has stopped, the contents are compared
to those of a loaded AudioBuffer with the same source.
Somewhat similiar to a test from Mozilla:
-->
<html class="a">
<head>
<title>MediaElementAudioSource interface test (to scriptProcessor)</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webaudio/js/helpers.js"></script>
<script src="/webaudio/js/buffer-loader.js"></script>
</head>
<body class="a">
<div id="log"></div>
<script>
var elementSourceTest = async_test(function(elementSourceTest) {
var src = '/webaudio/resources/sin_440Hz_-6dBFS_1s.wav';
var BUFFER_SIZE = 2048;
var context = null;
var actualBufferArrayC0 = new Float32Array(0);
var actualBufferArrayC1 = new Float32Array(0);
var audio = null, source = null, processor = null
function loadExpectedBuffer(event) {
bufferLoader = new BufferLoader(
context,
[src],
elementSourceTest.step_func(bufferLoadCompleted)
);
bufferLoader.load();
};
function bufferLoadCompleted(buffer) {
runTests(buffer);
};
function concatTypedArray(arr1, arr2) {
var result = new Float32Array(arr1.length + arr2.length);
result.set(arr1);
result.set(arr2, arr1.length);
return result;
}
// Create Audio context. The reference wav file is sampled at 44.1 kHz so
// use the same rate for the context to remove extra resampling that might
// be required.
context = new AudioContext({sampleRate: 44100});
// Create an audio element, and a media element source
audio = document.createElement('audio');
audio.src = src;
source = context.createMediaElementSource(audio);
function processListener (e) {
actualBufferArrayC0 = concatTypedArray(actualBufferArrayC0, e.inputBuffer.getChannelData(0));
actualBufferArrayC1 = concatTypedArray(actualBufferArrayC1, e.inputBuffer.getChannelData(1));
}
// Create a processor node to copy the input to the actual buffer
processor = context.createScriptProcessor(BUFFER_SIZE);
source.connect(processor);
processor.connect(context.destination);
let audioprocessListener = elementSourceTest.step_func(processListener);
processor.addEventListener('audioprocess', audioprocessListener);
context.addEventListener('statechange', elementSourceTest.step_func(() => {
assert_equals(context.state, "running", "context.state");
audio.play();
}), {once: true});
// When media playback ended, save the begin to compare with expected buffer
audio.addEventListener("ended", elementSourceTest.step_func(function(e) {
// Setting a timeout since we need audioProcess event to run for all samples
window.setTimeout(elementSourceTest.step_func(loadExpectedBuffer), 50);
}));
function runTests(expected) {
source.disconnect();
processor.disconnect();
// firefox seems to process events after disconnect
processor.removeEventListener('audioprocess', audioprocessListener)
// Note: the expected result is from a mono source file.
var expectedBuffer = expected[0];
// Trim the actual elements because we don't have a fine-grained
// control over the start and end time of recording the data.
var actualTrimmedC0 = trimEmptyElements(actualBufferArrayC0);
var actualTrimmedC1 = trimEmptyElements(actualBufferArrayC1);
var expectedLength = trimEmptyElements(expectedBuffer.getChannelData(0)).length;
// Test that there is some data.
test(function() {
assert_greater_than(actualTrimmedC0.length, 0,
"processed data array (C0) length greater than 0");
assert_greater_than(actualTrimmedC1.length, 0,
"processed data array (C1) length greater than 0");
}, "Channel 0 processed some data");
// Test the actual contents of the 1st and second channel.
test(function() {
assert_array_approx_equals(
actualTrimmedC0,
trimEmptyElements(expectedBuffer.getChannelData(0)),
1e-4,
"comparing expected and rendered buffers (channel 0)");
assert_array_approx_equals(
actualTrimmedC1,
trimEmptyElements(expectedBuffer.getChannelData(0)),
1e-4,
"comparing expected and rendered buffers (channel 1)");
}, "All data processed correctly");
elementSourceTest.done();
};
}, "Element Source tests completed");
</script>
</body>
</html>