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