Commit 2cae7658 authored by rtoy@chromium.org's avatar rtoy@chromium.org

Test resampling of AudioBuffers that have a different sample rate from the context

This is a follow up that adds a simple layout test to test
https://codereview.chromium.org/201673004/

This test creates an audio context at 48 kHz and a 3 kHz sine wave in
an AudioBuffer that is played through the context. The test verifies
that the output is sufficiently close to the expected sine wave output.

BUG=344375

Review URL: https://codereview.chromium.org/213153003

git-svn-id: svn://svn.chromium.org/blink/trunk@170197 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent eab8cdbd
Test resampling of an AudioBuffer at 3000 Hz
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS Peak error between actual and reference data below threshold of 0.11.
PASS SNR exceeds threshold of 22.35 dB.
PASS AudioBuffer resampling is accurate for buffer rate of 3000 Hz.
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script src="resources/compatibility.js"></script>
<script src="resources/audio-testing.js"></script>
<script src="../resources/js-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
// These are global to make debugging a little easier.
var context;
var buffer;
var source;
var renderedData;
var trueData;
var signalEnergy;
var noiseEnergy;
var maxError;
// Context sample rate.
var sampleRate = 48000;
// The sample rate of the buffer.
var bufferRate = 3000;
// The audio buffer is a sine wave of this frequency.
var toneFrequency = 440;
// How long test is
var lengthInSeconds = 0.5;
// The maximum allowed peak error between the actual and true output. This value was
// experimentally determined for the given bufferRate.
var peakThreshold = 0.11;
// The minimum SNR allowed between the actual and true output.
var snrThreshold = 22.35;
description("Test resampling of an AudioBuffer at " + bufferRate + " Hz");
function log10(x) {
return Math.log(x)/Math.LN10;
}
// Generate a sine wave in an AudioBuffer using the given |freq|. The AudioBuffer has the
// sample rate of |rate|.
function createSineBuffer(context, freq, rate) {
var buf = context.createBuffer(1, lengthInSeconds * rate, rate);
var omega = 2 * Math.PI * freq / rate;
var signal = buf.getChannelData(0);
var length = signal.length;
for (var k = 0; k < length; ++k)
signal[k] = Math.sin(omega * k);
return buf;
}
// Check the output against the expected output.
function checkResult(event) {
renderedData = event.renderedBuffer.getChannelData(0);
var length = renderedData.length;
// Generate a reference sine wave at the context rate
var trueReference = createSineBuffer(context, toneFrequency, context.sampleRate);
trueData = trueReference.getChannelData(0);
// To compare the actual output against the reference, we compute the peak error and the
// SNR between the two.
signalEnergy = 0;
noiseEnergy = 0;
maxError = -1;
var success = true;
// Compute the peak error and the SNR.
for (var k = 0; k < length / 2; ++k) {
var diff = renderedData[k] - trueData[k];
noiseEnergy += diff * diff;
signalEnergy += trueData[k] * trueData[k];
if (Math.abs(diff) > maxError)
maxError = Math.abs(diff);
}
var snr;
if (noiseEnergy == 0)
snr = 1000;
else
snr = 10 * log10(signalEnergy / noiseEnergy);
if (maxError < peakThreshold) {
testPassed("Peak error between actual and reference data below threshold of " +
peakThreshold + ".");
} else {
testFailed("Peak error of " + maxError + " exceeds threshold of " +
peakThreshold + ".");
success = false;
}
if (snr > snrThreshold) {
testPassed("SNR exceeds threshold of " + snrThreshold + " dB.");
} else {
testFailed("SNR of " + snr + " is below the threshold of " + snrThreshold + ".");
success = false;
}
if (success)
testPassed("AudioBuffer resampling is accurate for buffer rate of " +
bufferRate + " Hz.");
else
testFailed("AudioBuffer resampling is not accurate enough for buffer rate of " +
bufferRate + " Hz.");
finishJSTest();
}
function runTest() {
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
window.jsTestIsAsync = true;
context = new OfflineAudioContext(1, lengthInSeconds * sampleRate, sampleRate);
// Create a sine wave in a buffer that's different from the context rate to test
// resampling.
buffer = createSineBuffer(context, toneFrequency, bufferRate);
source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start();
context.oncomplete = checkResult;
context.startRendering();
}
runTest();
successfullyParsed = true;
</script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment