tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

preserves-pitch.html (4634B)


      1 <!DOCTYPE html>
      2 <title>Test preservesPitch.</title>
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <script src="/resources/testdriver.js"></script>
      6 <script src="/resources/testdriver-vendor.js"></script>
      7 <script src="pitch-detector.js"></script>
      8 <script>
      9 
     10 // Remove when media-elements/historical.html's preservePitch prefix tests are are passing.
     11 function getPreservesPitch(audio) {
     12    if ("preservesPitch" in HTMLAudioElement.prototype) {
     13        return audio.preservesPitch;
     14    }
     15    if ("webkitPreservesPitch" in HTMLAudioElement.prototype) {
     16        return audio.webkitPreservesPitch;
     17    }
     18    return undefined;
     19 }
     20 
     21 // Remove when media-elements/historical.html's preservePitch prefix tests are are passing.
     22 function setPreservesPitch(audio, value) {
     23    if ("preservesPitch" in HTMLAudioElement.prototype) {
     24        audio.preservesPitch = value;
     25    } else if ("webkitPreservesPitch" in HTMLAudioElement.prototype) {
     26        audio.webkitPreservesPitch = value;
     27    }
     28 }
     29 
     30 test(function(t) {
     31    assert_true("preservesPitch" in HTMLAudioElement.prototype);
     32 }, "Test that preservesPitch is present and unprefixed.");
     33 
     34 test(function(t) {
     35    let defaultAudio = document.createElement('audio');
     36    assert_true(getPreservesPitch(defaultAudio));
     37 
     38    setPreservesPitch(defaultAudio, false);
     39    assert_false(getPreservesPitch(defaultAudio));
     40 }, "Test that preservesPitch is on by default");
     41 
     42 
     43 var audio;
     44 
     45 function addTestCleanups(t, detector) {
     46    t.add_cleanup(() => {
     47        audio.pause();
     48        audio.currentTime = 0;
     49    });
     50    t.add_cleanup(() => detector.cleanup());
     51 }
     52 
     53 function testPreservesPitch(preservesPitch, playbackRate, expectedPitch, description) {
     54    promise_test(async t => {
     55        let detector = getPitchDetector(audio);
     56        addTestCleanups(t, detector);
     57 
     58        audio.playbackRate = playbackRate;
     59        setPreservesPitch(audio, preservesPitch);
     60 
     61        function waitUntil(time) {
     62            return new Promise((resolve) => {
     63                audio.ontimeupdate = () => {
     64                    if (audio.currentTime >= time) {
     65                        resolve();
     66                    }
     67                };
     68            });
     69        }
     70 
     71        // Wait until we have played some audio. Otherwise, the detector
     72        // might return a pitch of 0Hz.
     73        audio.play();
     74        await waitUntil(0.5);
     75 
     76        var pitch = detector.detect();
     77 
     78        // 25Hz is larger than the margin we get from 48kHz and 44.1kHz
     79        // audio being analyzed by a FFT of size 2048. If we get something
     80        // different, there is an error within the test's calculations (or
     81        // we might be dealing a larger sample rate).
     82        assert_less_than(pitch.margin, 25,
     83            "Test error: the margin should be reasonably small.")
     84 
     85        // Allow for a 15% margin of error in the pitch detector, to reduce test
     86        // flakiness. Since our tests speed up and slow down by a factor of 2,
     87        // this should be plenty of leeway, without causing false negatives.
     88        assert_approx_equals(pitch.value, expectedPitch, expectedPitch*0.15,
     89            "The actual pitch should be close to the expected pitch.");
     90 
     91    }, description);
     92 }
     93 
     94 var REFERENCE_PITCH = 440;
     95 
     96 promise_test(async t => {
     97    // Create the audio element only once, in order to lower the chances of
     98    // tests timing out.
     99    audio = document.createElement('audio');
    100 
    101    // This file contains 5 seconds of a 440hz sine wave.
    102    audio.src = "/media/sine440.mp3";
    103 
    104    let detector = getPitchDetector(audio);
    105    addTestCleanups(t, detector);
    106 
    107    // The first time we run the test, we need to interact with the
    108    // AudioContext and Audio element via user gestures.
    109    await test_driver.bless("Play audio element", () => {
    110        return Promise.all([audio.play(), detector.ensureStart()]);
    111    });
    112 }, "Setup Audio element and AudioContext")
    113 
    114 testPreservesPitch(true, 1.0, REFERENCE_PITCH,
    115    "The default playbackRate should not affect pitch")
    116 
    117 testPreservesPitch(false, 1.0, REFERENCE_PITCH,
    118    "The default playbackRate should not affect pitch, even with preservesPitch=false")
    119 
    120 testPreservesPitch(true, 2.0, REFERENCE_PITCH,
    121    "Speed-ups should not change the pitch when preservesPitch=true")
    122 
    123 testPreservesPitch(true, 0.5, REFERENCE_PITCH,
    124    "Slow-downs should not change the pitch when preservesPitch=true")
    125 
    126 testPreservesPitch(false, 2.0, REFERENCE_PITCH*2.0,
    127    "Speed-ups should change the pitch when preservesPitch=false")
    128 
    129 testPreservesPitch(false, 0.5, REFERENCE_PITCH*0.5,
    130    "Slow-downs should change the pitch when preservesPitch=false")
    131 
    132 </script>