tor-browser

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

test_periodicWaveBandLimiting.html (3211B)


      1 <!DOCTYPE html>
      2 <title>Test effect of band limiting on PeriodicWave signals</title>
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <script>
      6 const sampleRate = 48000;
      7 const bufferSize = 12800;
      8 const epsilon = 0.01;
      9 
     10 // "All implementations must support arrays up to at least 8192", but the
     11 // linear interpolation of the current implementation distorts the higher
     12 // frequency components too much to pass this test.
     13 const frequencyIndexMax = 200;
     14 
     15 // A set of oscillators are created near the Nyquist frequency.
     16 // These are factors giving each oscillator frequency relative to the Nyquist.
     17 // The first is an octave below Nyquist and the last is just above.
     18 const OCTAVE_BELOW = 0;
     19 const HALF_BELOW = 1;
     20 const NEAR_BELOW = 2;
     21 const ABOVE = 3;
     22 const oscillatorFactors = [0.5, Math.sqrt(0.5), 0.99, 1.01];
     23 const oscillatorCount = oscillatorFactors.length;
     24 
     25 // Return magnitude relative to unit sine wave
     26 function magnitude(array) {
     27  var mag = 0
     28  for (var i = 0; i < array.length; ++i) {
     29    let sample = array[i];
     30    mag += sample * sample;
     31  }
     32  return Math.sqrt(2 * mag / array.length);
     33 }
     34 
     35 function test_frequency_index(frequencyIndex) {
     36 
     37  var context =
     38    new OfflineAudioContext(oscillatorCount, bufferSize, sampleRate);
     39 
     40  var merger = context.createChannelMerger(oscillatorCount);
     41  merger.connect(context.destination);
     42 
     43  var real = new Float32Array(frequencyIndex + 1);
     44  real[frequencyIndex] = 1;
     45  var image = new Float32Array(real.length);
     46  var wave = context.createPeriodicWave(real, image);
     47 
     48  for (var i = 0; i < oscillatorCount; ++i) {
     49    var oscillator = context.createOscillator();
     50    oscillator.frequency.value =
     51      oscillatorFactors[i] * sampleRate / (2 * frequencyIndex);
     52    oscillator.connect(merger, 0, i);
     53    oscillator.setPeriodicWave(wave);
     54    oscillator.start(0);
     55  }
     56 
     57  return context.startRendering().
     58    then((buffer) => {
     59      assert_equals(buffer.numberOfChannels, oscillatorCount);
     60      var magnitudes = [];
     61      for (var i = 0; i < oscillatorCount; ++i) {
     62        magnitudes[i] = magnitude(buffer.getChannelData(i));
     63      }
     64      // Unaffected by band-limiting one octave below Nyquist.
     65      assert_approx_equals(magnitudes[OCTAVE_BELOW], 1, epsilon,
     66                           "magnitude with frequency octave below Nyquist");
     67      // Still at least half the amplitude at half octave below Nyquist.
     68      assert_greater_than(magnitudes[HALF_BELOW], 0.5 * (1 - epsilon),
     69                          "magnitude with frequency half octave below Nyquist");
     70      // Approaching zero or zero near Nyquist.
     71      assert_less_than(magnitudes[NEAR_BELOW], 0.1,
     72                       "magnitude with frequency near Nyquist");
     73      assert_equals(magnitudes[ABOVE], 0,
     74                   "magnitude with frequency above Nyquist");
     75    });
     76 }
     77 
     78 // The 5/4 ratio with rounding up provides sampling across a range of
     79 // octaves and offsets within octaves.
     80 for (var frequencyIndex = 1;
     81     frequencyIndex < frequencyIndexMax;
     82     frequencyIndex = Math.floor((5 * frequencyIndex + 3) / 4)) {
     83  promise_test(test_frequency_index.bind(null, frequencyIndex),
     84               "Frequency " + frequencyIndex);
     85 }
     86 </script>