blob: 1cf6c7639036edbc53c70ee71dc99edc6e224d58 [file] [log] [blame]
<!DOCTYPE html>
<title>Test preservesPitch.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="pitch-detector.js"></script>
<script>
// Remove when media-elements/historical.html's preservePitch prefix tests are are passing.
function getPreservesPitch(audio) {
if ("preservesPitch" in HTMLAudioElement.prototype) {
return audio.preservesPitch;
}
if ("mozPreservesPitch" in HTMLAudioElement.prototype) {
return audio.mozPreservesPitch;
}
if ("webkitPreservesPitch" in HTMLAudioElement.prototype) {
return audio.webkitPreservesPitch;
}
return undefined;
}
// Remove when media-elements/historical.html's preservePitch prefix tests are are passing.
function setPreservesPitch(audio, value) {
if ("preservesPitch" in HTMLAudioElement.prototype) {
audio.preservesPitch = value;
} else if ("mozPreservesPitch" in HTMLAudioElement.prototype) {
audio.mozPreservesPitch = value;
} else if ("webkitPreservesPitch" in HTMLAudioElement.prototype) {
audio.webkitPreservesPitch = value;
}
}
test(function(t) {
assert_true("preservesPitch" in HTMLAudioElement.prototype);
}, "Test that preservesPitch is present and unprefixed.");
test(function(t) {
let defaultAudio = document.createElement('audio');
assert_true(getPreservesPitch(defaultAudio));
setPreservesPitch(defaultAudio, false);
assert_false(getPreservesPitch(defaultAudio));
}, "Test that preservesPitch is on by default");
var audio;
function addTestCleanups(t, detector) {
t.add_cleanup(() => {
audio.pause();
audio.currentTime = 0;
});
t.add_cleanup(() => detector.cleanup());
}
function testPreservesPitch(preservesPitch, playbackRate, expectedPitch, description) {
promise_test(async t => {
let detector = getPitchDetector(audio);
addTestCleanups(t, detector);
audio.playbackRate = playbackRate;
setPreservesPitch(audio, preservesPitch);
function waitUntil(time) {
return new Promise((resolve) => {
audio.ontimeupdate = () => {
if (audio.currentTime >= time) {
resolve();
}
};
});
}
// Wait until we have played some audio. Otherwise, the detector
// might return a pitch of 0Hz.
audio.play();
await waitUntil(0.25);
var pitch = detector.detect();
// 25Hz is larger than the margin we get from 48kHz and 44.1kHz
// audio being analyzed by a FFT of size 2048. If we get something
// different, there is an error within the test's calculations (or
// we might be dealing a larger sample rate).
assert_less_than(pitch.margin, 25,
"Test error: the margin should be reasonably small.")
assert_approx_equals(pitch.value, expectedPitch, pitch.margin,
"The actual pitch should be close to the expected pitch.");
}, description);
}
var REFERENCE_PITCH = 440;
promise_test(async t => {
// Create the audio element only once, in order to lower the chances of
// tests timing out.
audio = document.createElement('audio');
// This file contains 5 seconds of a 440hz sine wave.
audio.src = "/media/sine440.mp3";
let detector = getPitchDetector(audio);
addTestCleanups(t, detector);
// The first time we run the test, we need to interact with the
// AudioContext and Audio element via user gestures.
await test_driver.bless("Play audio element", () => {
return Promise.all([audio.play(), detector.ensureStart()]);
});
}, "Setup Audio element and AudioContext")
testPreservesPitch(true, 1.0, REFERENCE_PITCH,
"The default playbackRate should not affect pitch")
testPreservesPitch(false, 1.0, REFERENCE_PITCH,
"The default playbackRate should not affect pitch, even with preservesPitch=false")
testPreservesPitch(true, 2.0, REFERENCE_PITCH,
"Speed-ups should not change the pitch when preservesPitch=true")
testPreservesPitch(true, 0.5, REFERENCE_PITCH,
"Slow-downs should not change the pitch when preservesPitch=true")
testPreservesPitch(false, 2.0, REFERENCE_PITCH*2.0,
"Speed-ups should change the pitch when preservesPitch=false")
testPreservesPitch(false, 0.5, REFERENCE_PITCH*0.5,
"Slow-downs should change the pitch when preservesPitch=false")
</script>