summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html
blob: 56d0787b7673b11d903de23159b49ba15b85c1f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<!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:
https://searchfox.org/mozilla-central/source/dom/media/webaudio/test/test_mediaElementAudioSourceNode.html
-->

<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>