blob: b36b5285722d1b129184485146e5ed514d6175fc [file] [log] [blame]
<!doctype html>
<html>
<head>
<script src="../resources/js-test.js"></script>
<script src="resources/compatibility.js"></script>
<script src="resources/audio-testing.js"></script>
<title>Test Multiple Calls to getFloatFrequencyData</title>
</head>
<body>
<script>
description("Test AnalyserNode getFloatFrequencyData and getByteFrequencyData");
window.jsTestIsAsync = true;
var sampleRate = 48000;
// Render enough data to run the test.
var renderFrames = 2*1024;
var renderDuration = renderFrames / sampleRate;
var audit = Audit.createTaskRunner();
audit.defineTask("test", function (done) {
var context = new OfflineAudioContext(1, renderFrames, sampleRate);
// Use sawtooth oscillator as the source because it has quite a bit of harmonic content.
// Otherwise, the type doesn't really matter.
var osc = context.createOscillator();
osc.type = "sawtooth";
// Create an analyser with 256-point FFT. The FFT size doesn't really matter much.
var analyser = context.createAnalyser();
analyser.fftSize = 256;
osc.connect(analyser);
analyser.connect(context.destination);
var success = true;
// Suspend after getting a full analyser frame. (Not really necessary, but it's nice that
// the frame doesn't include any initial zeroes.
var suspendFrame = analyser.fftSize;
context.suspend(suspendFrame / sampleRate).then(function () {
// Test successive calls to getFloatFrequencyData in the same rendering quantum.
var f1 = new Float32Array(analyser.frequencyBinCount);
var f2 = new Float32Array(analyser.frequencyBinCount);
analyser.getFloatFrequencyData(f1);
analyser.getFloatFrequencyData(f2);
success = Should("Second call to getFloatFrequencyData", f2, {
precision: 5
}).beEqualToArray(f1) && success;
}).then(context.resume.bind(context));
suspendFrame += 128;
context.suspend(suspendFrame / sampleRate).then(function () {
// Test successive calls to getByteFrequencyData in the same rendering quantum.
var f1 = new Uint8Array(analyser.frequencyBinCount);
var f2 = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(f1);
analyser.getByteFrequencyData(f2);
success = Should("Second call to getByteFrequencyData", f2)
.beEqualToArray(f1) && success;
}).then(context.resume.bind(context));
suspendFrame += 128;
context.suspend(suspendFrame / sampleRate).then(function () {
// Test calls to getFloatFrequencyData followed by getByteFrequencyData. The float data,
// when converted to byte values should be identical to the result from
// getByteFrequencyData.
var f1 = new Float32Array(analyser.frequencyBinCount);
var f2 = new Uint8Array(analyser.frequencyBinCount);
analyser.getFloatFrequencyData(f1);
analyser.getByteFrequencyData(f2);
var byteValuesFromFloat = convertFloatToByte(f1, analyser.minDecibels, analyser.maxDecibels);
success = Should("Output of getByteFrequencyData after getFloatFrequencyData",
byteValuesFromFloat)
.beEqualToArray(f2) && success;
}).then(context.resume.bind(context));
suspendFrame += 128;
context.suspend(suspendFrame / sampleRate).then(function () {
// Test calls to getByteFrequencyData followed by getFloatFrequencyData. The float data,
// when converted to byte values should be identical to the result from
// getByteFrequencyData.
var f1 = new Uint8Array(analyser.frequencyBinCount);
var f2 = new Float32Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(f1);
analyser.getFloatFrequencyData(f2);
var byteValuesFromFloat = convertFloatToByte(f2, analyser.minDecibels, analyser.maxDecibels);
success = Should(
"Output of getFloatFrequenycData (converted to byte) after getByteFrequencyData",
f1)
.beEqualToArray(byteValuesFromFloat) && success;
}).then(context.resume.bind(context));
osc.start();
context.startRendering().then(done);
});
audit.defineTask("finish", function (done) {
finishJSTest();
done();
});
audit.runTasks();
// Convert the float frequency data (in dB), |floatFreqData|, to byte values using the dB
// limits |minDecibels| and |maxDecibels|. The new byte array is returned.
function convertFloatToByte(floatFreqData, minDecibels, maxDecibels) {
var scale = 255 / (maxDecibels - minDecibels);
return floatFreqData.map(function (x) {
var value = Math.floor(scale * (x - minDecibels));
return Math.min(255, Math.max(0, value));
});
}
</script>
</body>
</html>