mediaElementAudioSourceToScriptProcessorTest.html (4844B)
1 <!doctype html> 2 3 <!-- 4 Tests that a create MediaElementSourceNode that is passed through 5 a script processor passes the stream data. 6 The script processor saves the input buffers it gets to a temporary 7 array, and after the playback has stopped, the contents are compared 8 to those of a loaded AudioBuffer with the same source. 9 10 Somewhat similiar to a test from Mozilla: 11 https://searchfox.org/mozilla-central/source/dom/media/webaudio/test/test_mediaElementAudioSourceNode.html 12 --> 13 14 <html class="a"> 15 <head> 16 <title>MediaElementAudioSource interface test (to scriptProcessor)</title> 17 <script src="/resources/testharness.js"></script> 18 <script src="/resources/testharnessreport.js"></script> 19 <script src="/webaudio/js/helpers.js"></script> 20 <script src="/webaudio/js/buffer-loader.js"></script> 21 </head> 22 <body class="a"> 23 <div id="log"></div> 24 <script> 25 var elementSourceTest = async_test(function(elementSourceTest) { 26 27 var src = '/webaudio/resources/sin_440Hz_-6dBFS_1s.wav'; 28 var BUFFER_SIZE = 2048; 29 var context = null; 30 var actualBufferArrayC0 = new Float32Array(0); 31 var actualBufferArrayC1 = new Float32Array(0); 32 var audio = null, source = null, processor = null 33 34 function loadExpectedBuffer(event) { 35 bufferLoader = new BufferLoader( 36 context, 37 [src], 38 elementSourceTest.step_func(bufferLoadCompleted) 39 ); 40 bufferLoader.load(); 41 }; 42 43 function bufferLoadCompleted(buffer) { 44 runTests(buffer); 45 }; 46 47 function concatTypedArray(arr1, arr2) { 48 var result = new Float32Array(arr1.length + arr2.length); 49 result.set(arr1); 50 result.set(arr2, arr1.length); 51 return result; 52 } 53 54 // Create Audio context. The reference wav file is sampled at 44.1 kHz so 55 // use the same rate for the context to remove extra resampling that might 56 // be required. 57 context = new AudioContext({sampleRate: 44100}); 58 59 // Create an audio element, and a media element source 60 audio = document.createElement('audio'); 61 audio.src = src; 62 source = context.createMediaElementSource(audio); 63 64 function processListener (e) { 65 actualBufferArrayC0 = concatTypedArray(actualBufferArrayC0, e.inputBuffer.getChannelData(0)); 66 actualBufferArrayC1 = concatTypedArray(actualBufferArrayC1, e.inputBuffer.getChannelData(1)); 67 } 68 69 // Create a processor node to copy the input to the actual buffer 70 processor = context.createScriptProcessor(BUFFER_SIZE); 71 source.connect(processor); 72 processor.connect(context.destination); 73 let audioprocessListener = elementSourceTest.step_func(processListener); 74 processor.addEventListener('audioprocess', audioprocessListener); 75 76 context.addEventListener('statechange', elementSourceTest.step_func(() => { 77 assert_equals(context.state, "running", "context.state"); 78 audio.play(); 79 }), {once: true}); 80 81 // When media playback ended, save the begin to compare with expected buffer 82 audio.addEventListener("ended", elementSourceTest.step_func(function(e) { 83 // Setting a timeout since we need audioProcess event to run for all samples 84 window.setTimeout(elementSourceTest.step_func(loadExpectedBuffer), 50); 85 })); 86 87 function runTests(expected) { 88 source.disconnect(); 89 processor.disconnect(); 90 91 // firefox seems to process events after disconnect 92 processor.removeEventListener('audioprocess', audioprocessListener) 93 94 // Note: the expected result is from a mono source file. 95 var expectedBuffer = expected[0]; 96 97 // Trim the actual elements because we don't have a fine-grained 98 // control over the start and end time of recording the data. 99 var actualTrimmedC0 = trimEmptyElements(actualBufferArrayC0); 100 var actualTrimmedC1 = trimEmptyElements(actualBufferArrayC1); 101 var expectedLength = trimEmptyElements(expectedBuffer.getChannelData(0)).length; 102 103 // Test that there is some data. 104 test(function() { 105 assert_greater_than(actualTrimmedC0.length, 0, 106 "processed data array (C0) length greater than 0"); 107 assert_greater_than(actualTrimmedC1.length, 0, 108 "processed data array (C1) length greater than 0"); 109 }, "Channel 0 processed some data"); 110 111 // Test the actual contents of the 1st and second channel. 112 test(function() { 113 assert_array_approx_equals( 114 actualTrimmedC0, 115 trimEmptyElements(expectedBuffer.getChannelData(0)), 116 1e-4, 117 "comparing expected and rendered buffers (channel 0)"); 118 assert_array_approx_equals( 119 actualTrimmedC1, 120 trimEmptyElements(expectedBuffer.getChannelData(0)), 121 1e-4, 122 "comparing expected and rendered buffers (channel 1)"); 123 }, "All data processed correctly"); 124 125 elementSourceTest.done(); 126 }; 127 }, "Element Source tests completed"); 128 </script> 129 </body> 130 </html>