summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js')
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js155
1 files changed, 155 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js
new file mode 100644
index 0000000000..43279f91d6
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioparam-interface/automation-rate-testing.js
@@ -0,0 +1,155 @@
+// Test k-rate vs a-rate AudioParams.
+//
+// |options| describes how the testing of the AudioParam should be done:
+//
+// sourceNodeName: name of source node to use for testing; defaults to
+// 'OscillatorNode'. If set to 'none', then no source node
+// is created for testing and it is assumed that the AudioNode
+// under test are sources and need to be started.
+// verifyPieceWiseConstant: if true, verify that the k-rate output is
+// piecewise constant for each render quantum.
+// nodeName: name of the AudioNode to be tested
+// nodeOptions: options to be used in the AudioNode constructor
+//
+// prefix: Prefix for all output messages (to make them unique for
+// testharness)
+//
+// rateSettings: A vector of dictionaries specifying how to set the automation
+// rate(s):
+// name: Name of the AudioParam
+// value: The automation rate for the AudioParam given by |name|.
+//
+// automations: A vector of dictionaries specifying how to automate each
+// AudioParam:
+// name: Name of the AudioParam
+//
+// methods: A vector of dictionaries specifying the automation methods to
+// be used for testing:
+// name: Automation method to call
+// options: Arguments for the automation method
+//
+// Testing is somewhat rudimentary. We create two nodes of the same type. One
+// node uses the default automation rates for each AudioParam (expecting them to
+// be a-rate). The second node sets the automation rate of AudioParams to
+// "k-rate". The set is speciified by |options.rateSettings|.
+//
+// For both of these nodes, the same set of automation methods (given by
+// |options.automations|) is applied. A simple oscillator is connected to each
+// node which in turn are connected to different channels of an offline context.
+// Channel 0 is the k-rate node output; channel 1, the a-rate output; and
+// channel 3, the difference between the outputs.
+//
+// Success is declared if the difference signal is not exactly zero. This means
+// the the automations did different things, as expected.
+//
+// The promise from |startRendering| is returned.
+function doTest(context, should, options) {
+ let merger = new ChannelMergerNode(
+ context, {numberOfInputs: context.destination.channelCount});
+ merger.connect(context.destination);
+
+ let src = null;
+
+ // Skip creating a source to drive the graph if |sourceNodeName| is 'none'.
+ // If |sourceNodeName| is given, use that, else default to OscillatorNode.
+ if (options.sourceNodeName !== 'none') {
+ src = new window[options.sourceNodeName || 'OscillatorNode'](context);
+ }
+
+ let kRateNode = new window[options.nodeName](context, options.nodeOptions);
+ let aRateNode = new window[options.nodeName](context, options.nodeOptions);
+ let inverter = new GainNode(context, {gain: -1});
+
+ // Set kRateNode filter to use k-rate params.
+ options.rateSettings.forEach(setting => {
+ kRateNode[setting.name].automationRate = setting.value;
+ // Mostly for documentation in the output. These should always
+ // pass.
+ should(
+ kRateNode[setting.name].automationRate,
+ `${options.prefix}: Setting ${
+ setting.name
+ }.automationRate to "${setting.value}"`)
+ .beEqualTo(setting.value);
+ });
+
+ // Run through all automations for each node separately. (Mostly to keep
+ // output of automations together.)
+ options.automations.forEach(param => {
+ param.methods.forEach(method => {
+ // Most for documentation in the output. These should never throw.
+ let message = `${param.name}.${method.name}(${method.options})`
+ should(() => {
+ kRateNode[param.name][method.name](...method.options);
+ }, options.prefix + ': k-rate node: ' + message).notThrow();
+ });
+ });
+ options.automations.forEach(param => {
+ param.methods.forEach(method => {
+ // Most for documentation in the output. These should never throw.
+ let message = `${param.name}.${method.name}(${method.options})`
+ should(() => {
+ aRateNode[param.name][method.name](...method.options);
+ }, options.prefix + ': a-rate node:' + message).notThrow();
+ });
+ });
+
+ // Connect the source, if specified.
+ if (src) {
+ src.connect(kRateNode);
+ src.connect(aRateNode);
+ }
+
+ // The k-rate result is channel 0, and the a-rate result is channel 1.
+ kRateNode.connect(merger, 0, 0);
+ aRateNode.connect(merger, 0, 1);
+
+ // Compute the difference between the a-rate and k-rate results and send
+ // that to channel 2.
+ kRateNode.connect(merger, 0, 2);
+ aRateNode.connect(inverter).connect(merger, 0, 2);
+
+ if (src) {
+ src.start();
+ } else {
+ // If there's no source, then assume the test nodes are sources and start
+ // them.
+ kRateNode.start();
+ aRateNode.start();
+ }
+
+ return context.startRendering().then(renderedBuffer => {
+ let kRateOutput = renderedBuffer.getChannelData(0);
+ let aRateOutput = renderedBuffer.getChannelData(1);
+ let diff = renderedBuffer.getChannelData(2);
+
+ // Some informative messages to print out values of the k-rate and
+ // a-rate outputs. These should always pass.
+ should(
+ kRateOutput, `${options.prefix}: Output of k-rate ${options.nodeName}`)
+ .beEqualToArray(kRateOutput);
+ should(
+ aRateOutput, `${options.prefix}: Output of a-rate ${options.nodeName}`)
+ .beEqualToArray(aRateOutput);
+
+ // The real test. If k-rate AudioParam is working correctly, the
+ // k-rate result MUST differ from the a-rate result.
+ should(
+ diff,
+ `${
+ options.prefix
+ }: Difference between a-rate and k-rate ${options.nodeName}`)
+ .notBeConstantValueOf(0);
+
+ if (options.verifyPieceWiseConstant) {
+ // Verify that the output from the k-rate parameter is step-wise
+ // constant.
+ for (let k = 0; k < kRateOutput.length; k += 128) {
+ should(
+ kRateOutput.slice(k, k + 128),
+ `${options.prefix} k-rate output [${k}: ${k + 127}]`)
+ .beConstantValueOf(kRateOutput[k]);
+ }
+ }
+ });
+}