OLD | NEW |
| (Empty) |
1 <!doctype html> | |
2 <html> | |
3 <head> | |
4 <script src="../resources/js-test.js"></script> | |
5 <script src="resources/compatibility.js"></script> | |
6 <script src="resources/audit-util.js"></script> | |
7 <script src="resources/audio-testing.js"></script> | |
8 <title>Test Analyser.getByteTimeDomainData()</title> | |
9 </head> | |
10 | |
11 <body> | |
12 <script> | |
13 description("Test AnalyserNode getByteTimeDomainData"); | |
14 window.jsTestIsAsync = true; | |
15 | |
16 var sampleRate = 48000; | |
17 // The size of the analyser frame. Anything larger than 128 is ok, but sh
ould be long enough | |
18 // to capture the peaks of the oscillator waveform. | |
19 var fftSize = 256; | |
20 // Number of frames to render. Should be greater than the fftSize, but is
otherwise | |
21 // arbitrary. | |
22 var renderFrames = 2 * fftSize; | |
23 | |
24 var audit = Audit.createTaskRunner(); | |
25 | |
26 // Test that getByteTimeDomainData returns the correct values. This test
depends on | |
27 // getFloatTimeDomainData returning the correct data (for which there is a
lready a test). | |
28 audit.defineTask("byte-data", function (done) { | |
29 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | |
30 | |
31 // Create a sawtooth as the signal under test. A sine wave or triangle
wave would probably | |
32 // also work. | |
33 var src = context.createOscillator(); | |
34 src.type = "sawtooth"; | |
35 // Choose a frequency high enough that we get at least a full period in
one analyser fftSize | |
36 // frame. Otherwise, the frequency is arbitrary. | |
37 src.frequency.value = 440; | |
38 | |
39 // Gain node to make sure the signal goes somewhat above 1, for testing
clipping. | |
40 var gain = context.createGain(); | |
41 gain.gain.value = 1.5; | |
42 | |
43 // The analyser node to test | |
44 var analyser = context.createAnalyser(); | |
45 analyser.fftSize = fftSize; | |
46 | |
47 // Connect the graph. | |
48 src.connect(gain); | |
49 gain.connect(analyser); | |
50 analyser.connect(context.destination); | |
51 | |
52 // Stop rendering after one analyser frame so we can grab the data. | |
53 context.suspend(fftSize / sampleRate).then(function () { | |
54 var floatData = new Float32Array(fftSize); | |
55 var byteData = new Uint8Array(fftSize); | |
56 | |
57 analyser.getFloatTimeDomainData(floatData); | |
58 analyser.getByteTimeDomainData(byteData); | |
59 | |
60 // Use the float data to compute the expected value for the byte data. | |
61 var expected = new Float32Array(fftSize); | |
62 for (var k = 0; k < fftSize; ++k) { | |
63 // It's important to do Math.fround to match the single-precision fl
oat in the | |
64 // implementation! | |
65 var value = Math.fround(128 * Math.fround(1 + floatData[k])); | |
66 // Clip the result to lie in the range [0, 255]. | |
67 expected[k] = Math.floor(Math.min(255, Math.max(0, value))); | |
68 } | |
69 | |
70 // Find the first index of the first sample that exceeds +1 or -1. Th
e test MUST have at | |
71 // least one such value. | |
72 var indexMax = floatData.findIndex(function (x) { return x > 1; }); | |
73 var indexMin = floatData.findIndex(function (x) { return x < -1; }); | |
74 | |
75 Should("Index of first sample greater than +1", indexMax, { | |
76 brief: true | |
77 }).beGreaterThanOrEqualTo(0); | |
78 Should("Index of first sample less than -1", indexMin, { | |
79 brief: true | |
80 }).beGreaterThanOrEqualTo(0); | |
81 | |
82 // Verify explicitly that clipping happened correctly at the above ind
ices. | |
83 Should("Clip " + floatData[indexMax].toPrecision(6) + ": byteData[" +
indexMax + "]", | |
84 byteData[indexMax]).beEqualTo(255); | |
85 Should("Clip " + floatData[indexMin].toPrecision(6) + ": byteData[" +
indexMin + "]", | |
86 byteData[indexMin]).beEqualTo(0); | |
87 | |
88 // Verify that all other samples are computed correctly. | |
89 Should("Byte data", byteData).beEqualToArray(expected); | |
90 }).then(context.resume.bind(context)) | |
91 | |
92 src.start(); | |
93 context.startRendering().then(done); | |
94 }); | |
95 | |
96 audit.defineTask("finish", function (done) { | |
97 finishJSTest(); | |
98 done(); | |
99 }); | |
100 | |
101 audit.runTasks(); | |
102 </script> | |
103 </body> | |
104 </html> | |
OLD | NEW |