mirror of
https://github.com/servo/servo.git
synced 2025-10-04 02:29:12 +01:00
101 lines
3.6 KiB
HTML
101 lines
3.6 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<title>Test Extrapolation at end of AudibBuffer in an AudioBufferSourceNode</title>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/webaudio/resources/audit-util.js"></script>
|
|
<script src="/webaudio/resources/audit.js"></script>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
let audit = Audit.createTaskRunner();
|
|
|
|
const sampleRate = 48000;
|
|
|
|
// For testing we only need a few render quanta.
|
|
const renderSamples = 512
|
|
|
|
// Sample rate for our buffers. This is the lowest sample rate that is
|
|
// required to be supported.
|
|
const bufferRate = 8000;
|
|
|
|
// Number of samples in each AudioBuffer; this is fairly arbitrary but
|
|
// should be less than a render quantum.
|
|
const bufferLength = 30;
|
|
|
|
// Frequency of the sine wave for testing.
|
|
const frequency = 440;
|
|
|
|
audit.define(
|
|
{
|
|
label: 'interpolate',
|
|
description: 'Interpolation of AudioBuffers to context sample rate'
|
|
},
|
|
(task, should) => {
|
|
// The first channel is for the interpolated signal, and the second
|
|
// channel is for the reference signal from an oscillator.
|
|
let context = new OfflineAudioContext({
|
|
numberOfChannels: 2,
|
|
length: renderSamples,
|
|
sampleRate: sampleRate
|
|
});
|
|
|
|
let merger = new ChannelMergerNode(
|
|
context, {numberOfChannels: context.destination.channelCount});
|
|
merger.connect(context.destination);
|
|
|
|
// Create a set of AudioBuffers which are samples from a pure sine
|
|
// wave with frequency |frequency|.
|
|
const nBuffers = Math.floor(context.length / bufferLength);
|
|
const omega = 2 * Math.PI * frequency / bufferRate;
|
|
|
|
let frameNumber = 0;
|
|
let startTime = 0;
|
|
|
|
for (let k = 0; k < nBuffers; ++k) {
|
|
// let buffer = context.createBuffer(1, bufferLength,
|
|
// bufferRate);
|
|
let buffer = new AudioBuffer(
|
|
{length: bufferLength, sampleRate: bufferRate});
|
|
let data = buffer.getChannelData(0);
|
|
for (let n = 0; n < bufferLength; ++n) {
|
|
data[n] = Math.sin(omega * frameNumber);
|
|
++frameNumber;
|
|
}
|
|
// Create a source using this buffer and start it at the end of
|
|
// the previous buffer.
|
|
let src = new AudioBufferSourceNode(context, {buffer: buffer});
|
|
|
|
src.connect(merger, 0, 0);
|
|
src.start(startTime);
|
|
startTime += buffer.duration;
|
|
}
|
|
|
|
// Create the reference sine signal using an oscillator.
|
|
let osc = new OscillatorNode(
|
|
context, {type: 'sine', frequency: frequency});
|
|
osc.connect(merger, 0, 1);
|
|
osc.start(0);
|
|
|
|
context.startRendering()
|
|
.then(audioBuffer => {
|
|
let actual = audioBuffer.getChannelData(0);
|
|
let expected = audioBuffer.getChannelData(1);
|
|
|
|
should(actual, 'Interpolated sine wave')
|
|
.beCloseToArray(expected, {absoluteThreshold: 9.0348e-2});
|
|
|
|
// Compute SNR between them.
|
|
let snr = 10 * Math.log10(computeSNR(actual, expected));
|
|
|
|
should(snr, `SNR (${snr.toPrecision(4)} dB)`)
|
|
.beGreaterThanOrEqualTo(37.17);
|
|
})
|
|
.then(() => task.done());
|
|
});
|
|
|
|
audit.run();
|
|
</script>
|
|
</body>
|
|
</html>
|