1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
<!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 ("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 ("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.5);
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.")
// Allow for a 15% margin of error in the pitch detector, to reduce test
// flakiness. Since our tests speed up and slow down by a factor of 2,
// this should be plenty of leeway, without causing false negatives.
assert_approx_equals(pitch.value, expectedPitch, expectedPitch*0.15,
"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>
|