tor-browser

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

audioworklet-audioparam-iterable.https.html (6639B)


      1 <!DOCTYPE html>
      2 <html>
      3  <head>
      4    <meta charset="utf-8" />
      5    <title>
      6      Test get parameterDescriptor as various iterables
      7    </title>
      8    <script src="/resources/testharness.js"></script>
      9    <script src="/resources/testharnessreport.js"></script>
     10    <script src="/webaudio/js/helpers.js"></script>
     11  </head>
     12 
     13  <body>
     14    <script id="params">
     15      // A series of AudioParamDescriptors, copied one by one into various iterable
     16      // data structures. This is used by both the processor side and the main
     17      // thread side, so is in a different script tag.
     18      const PARAMS = [
     19        {
     20          name: "a control-rate parameter",
     21          defaultValue: 0.5,
     22          minValue: 0,
     23          maxValue: 1,
     24          automationRate: "a-rate",
     25        },
     26        {
     27          name: "你好",
     28          defaultValue: 2.5,
     29          minValue: 0,
     30          maxValue: 7,
     31          automationRate: "a-rate",
     32        },
     33        {
     34          name: "🎶",
     35          defaultValue: 8.5,
     36          minValue: 0,
     37          maxValue: 11115,
     38          automationRate: "k-rate",
     39        },
     40      ];
     41    </script>
     42    <script id="processors" type="worklet">
     43      registerProcessor("set",
     44      class SetParamProcessor extends AudioWorkletProcessor {
     45        static get parameterDescriptors() {
     46          var s = new Set();
     47          s.add(PARAMS[0]);
     48          s.add(PARAMS[1]);
     49          s.add(PARAMS[2]);
     50          return s;
     51        }
     52        constructor() { super(); }
     53        process() {
     54        }
     55      });
     56 
     57      registerProcessor("array",
     58      class ArrayParamProcessor extends AudioWorkletProcessor {
     59        static get parameterDescriptors() {
     60          return PARAMS;
     61        }
     62        constructor() { super(); }
     63        process() { }
     64      });
     65 
     66      function* gen() {
     67        yield PARAMS[0];
     68        yield PARAMS[1];
     69        yield PARAMS[2];
     70      }
     71      registerProcessor("generator",
     72      class GeneratorParamProcessor extends AudioWorkletProcessor {
     73        static get parameterDescriptors() {
     74          return gen();
     75        }
     76        constructor() { super(); }
     77        process() { }
     78      });
     79      // Test a processor that has a get parameterDescriptors, but it returns
     80      // something that is not iterable.
     81      try {
     82        registerProcessor("invalid",
     83        class InvalidParamProcessor extends AudioWorkletProcessor {
     84          static get parameterDescriptors() {
     85            return 4;
     86          }
     87          constructor() { super(); }
     88          process() { }
     89        });
     90        throw "This should not have been reached.";
     91      } catch (e) {
     92        // unclear how to signal success here, but we can signal failure in the
     93        // developer console
     94        if (e.name != "TypeError") {
     95          throw "This should be TypeError";
     96        }
     97      }
     98      // Test a processor that has a get parameterDescriptors, with a duplicate
     99      // param name something that is not iterable.
    100      try {
    101        registerProcessor("duplicate-param-name",
    102        class DuplicateParamProcessor extends AudioWorkletProcessor {
    103          static get parameterDescriptors() {
    104            var p = {
    105                name: "a",
    106                defaultValue: 1,
    107                minValue: 0,
    108                maxValue: 1,
    109                automationRate: "k-rate",
    110            };
    111            return [p,p];
    112          }
    113          constructor() { super(); }
    114          process() { }
    115        });
    116        throw "This should not have been reached.";
    117      } catch (e) {
    118        // unclear how to signal success here, but we can signal failure in the
    119        // developer console
    120        if (e.name != "NotSupportedError") {
    121          throw "This should be NotSupportedError";
    122        }
    123      }
    124      // Test a processor that has a no get parameterDescriptors.
    125      try {
    126        registerProcessor("no-params",
    127        class NoParamProcessor extends AudioWorkletProcessor {
    128          constructor() { super(); }
    129          process() { }
    130        });
    131      } catch (e) {
    132        throw "Construction should have worked.";
    133      }
    134    </script>
    135    <script>
    136      setup({ explicit_done: true });
    137      // Mangle the PARAMS object into a map that has the same shape as what an
    138      // AudioWorkletNode.parameter property would
    139      var PARAMS_MAP = new Map();
    140      for (var param of PARAMS) {
    141        var o = param;
    142        var name = o.name;
    143        delete o.name;
    144        PARAMS_MAP.set(name, o);
    145      }
    146 
    147      // This compares `lhs` and `rhs`, that are two maplike with the same shape
    148      // as PARAMS_MAP.
    149      function compare(testname, lhs, rhs) {
    150        equals(lhs.size, rhs.size, "Map match in size for " + testname);
    151        var i = 0;
    152        for (var [k, v] of lhs) {
    153          is_true(rhs.has(k), testname + ": " + k + " exists in both maps");
    154          var vrhs = rhs.get(k);
    155          ["defaultValue", "minValue", "maxValue", "automationRate"].forEach(
    156            paramKey => {
    157              equals(
    158                v[paramKey],
    159                vrhs[paramKey],
    160                `Values for ${k}.${paramKey} match for ${testname}`
    161              );
    162            }
    163          );
    164        }
    165      }
    166      var ac = new AudioContext();
    167      var url = URLFromScriptsElements(["params", "processors"]);
    168      ac.audioWorklet
    169        .addModule(url)
    170        .then(() => {
    171              ["set", "array", "generator"].forEach(iterable => {
    172                test(() => {
    173                  var node = new AudioWorkletNode(ac, iterable);
    174                  compare(iterable, node.parameters, PARAMS_MAP);
    175                }, `Creating an AudioWorkletNode with a ${iterable} for
    176                    parameter descriptor worked`);
    177          });
    178        })
    179        .then(function() {
    180          test(function() {
    181            assert_throws_dom("InvalidStateError", function() {
    182              new AudioWorkletNode(ac, "invalid");
    183            });
    184          }, `Attempting to create an AudioWorkletNode with an non
    185              iterable for parameter descriptor should not work`);
    186        })
    187      .then(function() {
    188        test(() => {
    189          new AudioWorkletNode(ac, "no-params");
    190        }, `Attempting to create an AudioWorkletNode from a processor
    191            that does not have a parameterDescriptors getter should work`);
    192      })
    193      .then(function() {
    194        test(function() {
    195          assert_throws_dom("InvalidStateError", function() {
    196            new AudioWorkletNode(ac, "duplicate-param-name");
    197          });
    198        }, `Attempting to create an AudioWorkletNode with two parameter
    199            descriptor with the same name should not work`);
    200      }).then(function() {
    201        done();
    202      });
    203    </script>
    204  </body>
    205 </html>