summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors')
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/active-processing.js54
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/add-offset.js34
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/array-check-processor.js94
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/channel-count-processor.js19
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-new-after-new.js16
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-new-after-super.js15
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-singleton.js16
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-super-after-new.js16
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/denormal-test-processor.js12
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor-globalthis.js12
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor.js18
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dynamic-register-processor.js22
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/error-processor.js40
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/gain-processor.js38
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/input-count-processor.js22
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/input-length-processor.js27
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js47
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/one-pole-processor.js49
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/option-test-processor.js19
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/param-size-processor.js30
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/port-processor.js34
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-getter-test-instance-processor.js44
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-getter-test-prototype-processor.js55
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-parameter-test-processor.js18
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/promise-processor.js40
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/register-processor-typeerrors.js39
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/sharedarraybuffer-processor.js35
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/timing-info-processor.js25
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-output-processor.js42
-rw-r--r--testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-outputs-check-processor.js78
30 files changed, 1010 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/active-processing.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/active-processing.js
new file mode 100644
index 0000000000..ef497733ca
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/active-processing.js
@@ -0,0 +1,54 @@
+/**
+ * @class ActiveProcessingTester
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class sends a message to its AudioWorkletNodew whenever the
+ * number of channels on the input changes. The message includes the actual
+ * number of channels, the context time at which this occurred, and whether
+ * we're done processing or not.
+ */
+class ActiveProcessingTester extends AudioWorkletProcessor {
+ constructor(options) {
+ super(options);
+ this._lastChannelCount = 0;
+
+ // See if user specified a value for test duration.
+ if (options.hasOwnProperty('processorOptions') &&
+ options.processorOptions.hasOwnProperty('testDuration')) {
+ this._testDuration = options.processorOptions.testDuration;
+ } else {
+ this._testDuration = 5;
+ }
+
+ // Time at which we'll signal we're done, based on the requested
+ // |testDuration|
+ this._endTime = currentTime + this._testDuration;
+ }
+
+ process(inputs, outputs) {
+ const input = inputs[0];
+ const output = outputs[0];
+ const inputChannelCount = input.length;
+ const isFinished = currentTime > this._endTime;
+
+ // Send a message if we're done or the count changed.
+ if (isFinished || (inputChannelCount != this._lastChannelCount)) {
+ this.port.postMessage({
+ channelCount: inputChannelCount,
+ finished: isFinished,
+ time: currentTime
+ });
+ this._lastChannelCount = inputChannelCount;
+ }
+
+ // Just copy the input to the output for no particular reason.
+ for (let channel = 0; channel < input.length; ++channel) {
+ output[channel].set(input[channel]);
+ }
+
+ // When we're finished, this method no longer needs to be called.
+ return !isFinished;
+ }
+}
+
+registerProcessor('active-processing-tester', ActiveProcessingTester);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/add-offset.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/add-offset.js
new file mode 100644
index 0000000000..d05056bd84
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/add-offset.js
@@ -0,0 +1,34 @@
+/*
+ * @class AddOffsetProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * Just adds a fixed value to the input
+ */
+class AddOffsetProcessor extends AudioWorkletProcessor {
+ constructor(options) {
+ super();
+
+ this._offset = options.processorOptions.offset;
+ }
+
+ process(inputs, outputs) {
+ // This processor assumes the node has at least 1 input and 1 output.
+ let input = inputs[0];
+ let output = outputs[0];
+ let outputChannel = output[0];
+
+ if (input.length > 0) {
+ let inputChannel = input[0];
+ for (let k = 0; k < outputChannel.length; ++k)
+ outputChannel[k] = inputChannel[k] + this._offset;
+ } else {
+ // No input connected, so pretend it's silence and just fill the
+ // output with the offset value.
+ outputChannel.fill(this._offset);
+ }
+
+ return true;
+ }
+}
+
+registerProcessor('add-offset-processor', AddOffsetProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/array-check-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/array-check-processor.js
new file mode 100644
index 0000000000..d6eeff3d15
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/array-check-processor.js
@@ -0,0 +1,94 @@
+/**
+ * @class ArrayFrozenProcessor
+ * @extends AudioWorkletProcessor
+ */
+class ArrayFrozenProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this._messageSent = false;
+ }
+
+ process(inputs, outputs, parameters) {
+ const input = inputs[0];
+ const output = outputs[0];
+
+ if (!this._messageSent) {
+ this.port.postMessage({
+ inputLength: input.length,
+ isInputFrozen: Object.isFrozen(inputs) && Object.isFrozen(input),
+ outputLength: output.length,
+ isOutputFrozen: Object.isFrozen(outputs) && Object.isFrozen(output)
+ });
+ this._messageSent = true;
+ }
+
+ return false;
+ }
+}
+
+/**
+ * @class ArrayTransferProcessor
+ * @extends AudioWorkletProcessor
+ */
+class ArrayTransferProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this._messageSent = false;
+ }
+
+ process(inputs, outputs, parameters) {
+ const input = inputs[0];
+ const output = outputs[0];
+
+ if (!this._messageSent) {
+ try {
+ // Transferring Array objects should NOT work.
+ this.port.postMessage({
+ inputs, input, inputChannel: input[0],
+ outputs, output, outputChannel: output[0]
+ }, [inputs, input, inputs[0], outputs, output, output[0]]);
+ // Hence, the following must NOT be reached.
+ this.port.postMessage({
+ type: 'assertion',
+ success: false,
+ message: 'Transferring inputs/outputs, an individual input/output ' +
+ 'array, or a channel Float32Array MUST fail, but succeeded.'
+ });
+ } catch (error) {
+ this.port.postMessage({
+ type: 'assertion',
+ success: true,
+ message: 'Transferring inputs/outputs, an individual input/output ' +
+ 'array, or a channel Float32Array is not allowed as expected.'
+ });
+ }
+
+ try {
+ // Transferring ArrayBuffers should work.
+ this.port.postMessage(
+ {inputChannel: input[0], outputChannel: output[0]},
+ [input[0].buffer, output[0].buffer]);
+ this.port.postMessage({
+ type: 'assertion',
+ success: true,
+ message: 'Transferring ArrayBuffers was successful as expected.'
+ });
+ } catch (error) {
+ // This must NOT be reached.
+ this.port.postMessage({
+ type: 'assertion',
+ success: false,
+ message: 'Transferring ArrayBuffers unexpectedly failed.'
+ });
+ }
+
+ this.port.postMessage({done: true});
+ this._messageSent = true;
+ }
+
+ return false;
+ }
+}
+
+registerProcessor('array-frozen-processor', ArrayFrozenProcessor);
+registerProcessor('array-transfer-processor', ArrayTransferProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/channel-count-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/channel-count-processor.js
new file mode 100644
index 0000000000..556459f46b
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/channel-count-processor.js
@@ -0,0 +1,19 @@
+/**
+ * @class ChannelCountProcessor
+ * @extends AudioWorkletProcessor
+ */
+class ChannelCountProcessor extends AudioWorkletProcessor {
+ constructor(options) {
+ super(options);
+ }
+
+ process(inputs, outputs) {
+ this.port.postMessage({
+ inputChannel: inputs[0].length,
+ outputChannel: outputs[0].length
+ });
+ return false;
+ }
+}
+
+registerProcessor('channel-count', ChannelCountProcessor); \ No newline at end of file
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-new-after-new.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-new-after-new.js
new file mode 100644
index 0000000000..d4c63f7775
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-new-after-new.js
@@ -0,0 +1,16 @@
+class NewAfterNew extends AudioWorkletProcessor {
+ constructor() {
+ const processor = new AudioWorkletProcessor()
+ let message = {threw: false};
+ try {
+ new AudioWorkletProcessor();
+ } catch (e) {
+ message.threw = true;
+ message.errorName = e.name;
+ message.isTypeError = e instanceof TypeError;
+ }
+ processor.port.postMessage(message);
+ return processor;
+ }
+}
+registerProcessor("new-after-new", NewAfterNew);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-new-after-super.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-new-after-super.js
new file mode 100644
index 0000000000..a6d4f0e2e8
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-new-after-super.js
@@ -0,0 +1,15 @@
+class NewAfterSuper extends AudioWorkletProcessor {
+ constructor() {
+ super()
+ let message = {threw: false};
+ try {
+ new AudioWorkletProcessor()
+ } catch (e) {
+ message.threw = true;
+ message.errorName = e.name;
+ message.isTypeError = e instanceof TypeError;
+ }
+ this.port.postMessage(message);
+ }
+}
+registerProcessor("new-after-super", NewAfterSuper);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-singleton.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-singleton.js
new file mode 100644
index 0000000000..c40b5a7179
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-singleton.js
@@ -0,0 +1,16 @@
+let singleton;
+class Singleton extends AudioWorkletProcessor {
+ constructor() {
+ if (!singleton) {
+ singleton = new AudioWorkletProcessor();
+ singleton.process = function() {
+ this.port.postMessage({message: "process called"});
+ // This function will be called at most once for each AudioWorkletNode
+ // if the node has no input connections.
+ return false;
+ }
+ }
+ return singleton;
+ }
+}
+registerProcessor("singleton", Singleton);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-super-after-new.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-super-after-new.js
new file mode 100644
index 0000000000..e447830c5f
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/construction-port-super-after-new.js
@@ -0,0 +1,16 @@
+class SuperAfterNew extends AudioWorkletProcessor {
+ constructor() {
+ const processor = new AudioWorkletProcessor()
+ let message = {threw: false};
+ try {
+ super();
+ } catch (e) {
+ message.threw = true;
+ message.errorName = e.name;
+ message.isTypeError = e instanceof TypeError;
+ }
+ processor.port.postMessage(message);
+ return processor;
+ }
+}
+registerProcessor("super-after-new", SuperAfterNew);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/denormal-test-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/denormal-test-processor.js
new file mode 100644
index 0000000000..2b7929437d
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/denormal-test-processor.js
@@ -0,0 +1,12 @@
+class DenormalTestProcessor extends AudioWorkletProcessor {
+ process() {
+ // The denormals should be non-zeros. Otherwise, it's a violation of
+ // ECMA specification: https://tc39.es/ecma262/#sec-number.min_value
+ this.port.postMessage({
+ result: Number.MIN_VALUE !== 0.0
+ });
+ return false;
+ }
+}
+
+registerProcessor('denormal-test', DenormalTestProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor-globalthis.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor-globalthis.js
new file mode 100644
index 0000000000..d1b16cc9aa
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor-globalthis.js
@@ -0,0 +1,12 @@
+class DummyProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process(inputs, outputs, parameters) {
+ // Doesn't do anything here.
+ return true;
+ }
+}
+
+globalThis.registerProcessor('dummy-globalthis', DummyProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor.js
new file mode 100644
index 0000000000..11155d508c
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dummy-processor.js
@@ -0,0 +1,18 @@
+/**
+ * @class DummyProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class demonstrates the bare-bone structure of the processor.
+ */
+class DummyProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process(inputs, outputs, parameters) {
+ // Doesn't do anything here.
+ return true;
+ }
+}
+
+registerProcessor('dummy', DummyProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dynamic-register-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dynamic-register-processor.js
new file mode 100644
index 0000000000..5e825aebb4
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/dynamic-register-processor.js
@@ -0,0 +1,22 @@
+class ProcessorA extends AudioWorkletProcessor {
+ process() {
+ return true;
+ }
+}
+
+// ProcessorB registers ProcessorA upon the construction.
+class ProcessorB extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this.port.onmessage = () => {
+ registerProcessor('ProcessorA', ProcessorA);
+ this.port.postMessage({});
+ };
+ }
+
+ process() {
+ return true;
+ }
+}
+
+registerProcessor('ProcessorB', ProcessorB);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/error-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/error-processor.js
new file mode 100644
index 0000000000..66ff5e2e25
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/error-processor.js
@@ -0,0 +1,40 @@
+/**
+ * @class ConstructorErrorProcessor
+ * @extends AudioWorkletProcessor
+ */
+class ConstructorErrorProcessor extends AudioWorkletProcessor {
+ constructor() {
+ throw 'ConstructorErrorProcessor: an error thrown from constructor.';
+ }
+
+ process() {
+ return true;
+ }
+}
+
+
+/**
+ * @class ProcessErrorProcessor
+ * @extends AudioWorkletProcessor
+ */
+class ProcessErrorProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process() {
+ throw 'ProcessErrorProcessor: an error throw from process method.';
+ return true;
+ }
+}
+
+
+/**
+ * @class EmptyErrorProcessor
+ * @extends AudioWorkletProcessor
+ */
+class EmptyErrorProcessor extends AudioWorkletProcessor { process() {} }
+
+registerProcessor('constructor-error', ConstructorErrorProcessor);
+registerProcessor('process-error', ProcessErrorProcessor);
+registerProcessor('empty-error', EmptyErrorProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/gain-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/gain-processor.js
new file mode 100644
index 0000000000..e9e130e374
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/gain-processor.js
@@ -0,0 +1,38 @@
+/**
+ * @class GainProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class demonstrates the bare-bone structure of the processor.
+ */
+class GainProcessor extends AudioWorkletProcessor {
+ static get parameterDescriptors() {
+ return [
+ {name: 'gain', defaultValue: 0.707}
+ ];
+ }
+
+ constructor() {
+ super();
+ }
+
+ process(inputs, outputs, parameters) {
+ let input = inputs[0];
+ let output = outputs[0];
+ let gain = parameters.gain;
+ for (let channel = 0; channel < input.length; ++channel) {
+ let inputChannel = input[channel];
+ let outputChannel = output[channel];
+ if (gain.length === 1) {
+ for (let i = 0; i < inputChannel.length; ++i)
+ outputChannel[i] = inputChannel[i] * gain[0];
+ } else {
+ for (let i = 0; i < inputChannel.length; ++i)
+ outputChannel[i] = inputChannel[i] * gain[i];
+ }
+ }
+
+ return true;
+ }
+}
+
+registerProcessor('gain', GainProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/input-count-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/input-count-processor.js
new file mode 100644
index 0000000000..6d53ba84c7
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/input-count-processor.js
@@ -0,0 +1,22 @@
+/**
+ * @class CountProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class just looks at the number of input channels on the first
+ * input and fills the first output channel with that value.
+ */
+class CountProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process(inputs, outputs, parameters) {
+ let input = inputs[0];
+ let output = outputs[0];
+ output[0].fill(input.length);
+
+ return true;
+ }
+}
+
+registerProcessor('counter', CountProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/input-length-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/input-length-processor.js
new file mode 100644
index 0000000000..be485f03e8
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/input-length-processor.js
@@ -0,0 +1,27 @@
+/**
+ * @class InputLengthProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class just sets the output to the length of the
+ * input array for verifying that the input length changes when the
+ * input is disconnected.
+ */
+class InputLengthProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ }
+
+ process(inputs, outputs, parameters) {
+ let input = inputs[0];
+ let output = outputs[0];
+
+ // Set output channel to the length of the input channel array.
+ // If the input is unconnected, set the value to zero.
+ const fillValue = input.length > 0 ? input[0].length : 0;
+ output[0].fill(fillValue);
+
+ return true;
+ }
+}
+
+registerProcessor('input-length-processor', InputLengthProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js
new file mode 100644
index 0000000000..e4a5dc39ba
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/invalid-param-array-processor.js
@@ -0,0 +1,47 @@
+/**
+ * @class InvalidParamArrayProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor intentionally returns an array with an invalid size when the
+ * processor's getter is queried.
+ */
+let singleton = undefined;
+let secondFetch = false;
+let useDescriptor = false;
+let processCounter = 0;
+
+class InvalidParamArrayProcessor extends AudioWorkletProcessor {
+ static get parameterDescriptors() {
+ if (useDescriptor)
+ return [{name: 'invalidParam'}];
+ useDescriptor = true;
+ return [];
+ }
+
+ constructor() {
+ super();
+ if (singleton === undefined)
+ singleton = this;
+ return singleton;
+ }
+
+ process(inputs, outputs, parameters) {
+ const output = outputs[0];
+ for (let channel = 0; channel < output.length; ++channel)
+ output[channel].fill(1);
+ return false;
+ }
+}
+
+// This overridden getter is invoked under the hood before process() gets
+// called. After this gets called, process() method above will be invalidated,
+// and mark the worklet node non-functional. (i.e. in an error state)
+Object.defineProperty(Object.prototype, 'invalidParam', {'get': () => {
+ if (secondFetch)
+ return new Float32Array(256);
+ secondFetch = true;
+ return new Float32Array(128);
+}});
+
+registerProcessor('invalid-param-array-1', InvalidParamArrayProcessor);
+registerProcessor('invalid-param-array-2', InvalidParamArrayProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/one-pole-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/one-pole-processor.js
new file mode 100644
index 0000000000..0bcc43f6f0
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/one-pole-processor.js
@@ -0,0 +1,49 @@
+/**
+ * @class OnePoleFilter
+ * @extends AudioWorkletProcessor
+ *
+ * A simple One-pole filter.
+ */
+
+class OnePoleFilter extends AudioWorkletProcessor {
+
+ // This gets evaluated as soon as the global scope is created.
+ static get parameterDescriptors() {
+ return [{
+ name: 'frequency',
+ defaultValue: 250,
+ minValue: 0,
+ maxValue: 0.5 * sampleRate
+ }];
+ }
+
+ constructor() {
+ super();
+ this.updateCoefficientsWithFrequency_(250);
+ }
+
+ updateCoefficientsWithFrequency_(frequency) {
+ this.b1_ = Math.exp(-2 * Math.PI * frequency / sampleRate);
+ this.a0_ = 1.0 - this.b1_;
+ this.z1_ = 0;
+ }
+
+ process(inputs, outputs, parameters) {
+ let input = inputs[0];
+ let output = outputs[0];
+ let frequency = parameters.frequency;
+ for (let channel = 0; channel < output.length; ++channel) {
+ let inputChannel = input[channel];
+ let outputChannel = output[channel];
+ for (let i = 0; i < outputChannel.length; ++i) {
+ this.updateCoefficientsWithFrequency_(frequency[i]);
+ this.z1_ = inputChannel[i] * this.a0_ + this.z1_ * this.b1_;
+ outputChannel[i] = this.z1_;
+ }
+ }
+
+ return true;
+ }
+}
+
+registerProcessor('one-pole-filter', OnePoleFilter);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/option-test-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/option-test-processor.js
new file mode 100644
index 0000000000..27e1da6325
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/option-test-processor.js
@@ -0,0 +1,19 @@
+/**
+ * @class OptionTestProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class demonstrates the option passing feature by echoing the
+ * received |nodeOptions| back to the node.
+ */
+class OptionTestProcessor extends AudioWorkletProcessor {
+ constructor(nodeOptions) {
+ super();
+ this.port.postMessage(nodeOptions);
+ }
+
+ process() {
+ return true;
+ }
+}
+
+registerProcessor('option-test-processor', OptionTestProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/param-size-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/param-size-processor.js
new file mode 100644
index 0000000000..d7ce836500
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/param-size-processor.js
@@ -0,0 +1,30 @@
+/**
+ * @class ParamSizeProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor is a source node which basically outputs the size of the
+ * AudioParam array for each render quantum.
+ */
+
+class ParamSizeProcessor extends AudioWorkletProcessor {
+ static get parameterDescriptors() {
+ return [{name: 'param'}];
+ }
+
+ constructor() {
+ super();
+ }
+
+ process(inputs, outputs, parameters) {
+ let output = outputs[0];
+ let param = parameters.param;
+
+ for (let channel = 0; channel < output.length; ++channel) {
+ output[channel].fill(param.length);
+ }
+
+ return true;
+ }
+}
+
+registerProcessor('param-size', ParamSizeProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/port-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/port-processor.js
new file mode 100644
index 0000000000..8def5a61d7
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/port-processor.js
@@ -0,0 +1,34 @@
+/**
+ * @class PortProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class demonstrates the message port functionality.
+ */
+class PortProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this.port.onmessage = this.handleMessage.bind(this);
+ this.port.postMessage({
+ state: 'created',
+ timeStamp: currentTime,
+ currentFrame: currentFrame
+ });
+ this.processCallCount = 0;
+ }
+
+ handleMessage(event) {
+ this.port.postMessage({
+ message: event.data,
+ timeStamp: currentTime,
+ currentFrame: currentFrame,
+ processCallCount: this.processCallCount
+ });
+ }
+
+ process() {
+ ++this.processCallCount;
+ return true;
+ }
+}
+
+registerProcessor('port-processor', PortProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-getter-test-instance-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-getter-test-instance-processor.js
new file mode 100644
index 0000000000..b1434f54ba
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-getter-test-instance-processor.js
@@ -0,0 +1,44 @@
+/**
+ * @class ProcessGetterTestInstanceProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class tests that a 'process' getter on an
+ * AudioWorkletProcessorConstructor instance is called at the right times.
+ */
+
+class ProcessGetterTestInstanceProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this.getterCallCount = 0;
+ this.totalProcessCallCount = 0;
+ Object.defineProperty(this, 'process', { get: function() {
+ if (!(this instanceof ProcessGetterTestInstanceProcessor)) {
+ throw new Error('`process` getter called with bad `this`.');
+ }
+ ++this.getterCallCount;
+ let functionCallCount = 0;
+ return () => {
+ if (++functionCallCount > 1) {
+ const message = 'Closure of function returned from `process` getter' +
+ ' should be used for only one call.'
+ this.port.postMessage({message: message});
+ throw new Error(message);
+ }
+ if (++this.totalProcessCallCount < 2) {
+ return true; // Expect another getter call.
+ }
+ if (this.totalProcessCallCount != this.getterCallCount) {
+ const message =
+ 'Getter should be called only once for each process() call.'
+ this.port.postMessage({message: message});
+ throw new Error(message);
+ }
+ this.port.postMessage({message: 'done'});
+ return false; // No more calls required.
+ };
+ }});
+ }
+}
+
+registerProcessor('process-getter-test-instance',
+ ProcessGetterTestInstanceProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-getter-test-prototype-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-getter-test-prototype-processor.js
new file mode 100644
index 0000000000..cef5fa8b52
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-getter-test-prototype-processor.js
@@ -0,0 +1,55 @@
+/**
+ * @class ProcessGetterTestPrototypeProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class tests that a 'process' getter on
+ * AudioWorkletProcessorConstructor is called at the right times.
+ */
+
+// Reporting errors during registerProcess() is awkward.
+// The occurrance of an error is flagged, so that a trial registration can be
+// performed and registration against the expected AudioWorkletNode name is
+// performed only if no errors are flagged during the trial registration.
+let error_flag = false;
+
+class ProcessGetterTestPrototypeProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this.getterCallCount = 0;
+ this.totalProcessCallCount = 0;
+ }
+ get process() {
+ if (!(this instanceof ProcessGetterTestPrototypeProcessor)) {
+ error_flag = true;
+ throw new Error('`process` getter called with bad `this`.');
+ }
+ ++this.getterCallCount;
+ let functionCallCount = 0;
+ return () => {
+ if (++functionCallCount > 1) {
+ const message = 'Closure of function returned from `process` getter' +
+ ' should be used for only one call.'
+ this.port.postMessage({message: message});
+ throw new Error(message);
+ }
+ if (++this.totalProcessCallCount < 2) {
+ return true; // Expect another getter call.
+ }
+ if (this.totalProcessCallCount != this.getterCallCount) {
+ const message =
+ 'Getter should be called only once for each process() call.'
+ this.port.postMessage({message: message});
+ throw new Error(message);
+ }
+ this.port.postMessage({message: 'done'});
+ return false; // No more calls required.
+ };
+ }
+}
+
+registerProcessor('trial-process-getter-test-prototype',
+ ProcessGetterTestPrototypeProcessor);
+if (!error_flag) {
+ registerProcessor('process-getter-test-prototype',
+ ProcessGetterTestPrototypeProcessor);
+}
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-parameter-test-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-parameter-test-processor.js
new file mode 100644
index 0000000000..a300d3cdec
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/process-parameter-test-processor.js
@@ -0,0 +1,18 @@
+/**
+ * @class ProcessParameterTestProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class forwards input and output parameters to its
+ * AudioWorkletNode.
+ */
+class ProcessParameterTestProcessor extends AudioWorkletProcessor {
+ process(inputs, outputs) {
+ this.port.postMessage({
+ inputs: inputs,
+ outputs: outputs
+ });
+ return false;
+ }
+}
+
+registerProcessor('process-parameter-test', ProcessParameterTestProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/promise-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/promise-processor.js
new file mode 100644
index 0000000000..6a8144b3cc
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/promise-processor.js
@@ -0,0 +1,40 @@
+/**
+ * @class PromiseProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor creates and resolves a promise in its `process` method. When
+ * the handler passed to `then()` is called, a counter that is global in the
+ * global scope is incremented. There are two copies of this
+ * AudioWorkletNode/Processor, so the counter should always be even in the
+ * process method of the AudioWorklet processing, since the Promise completion
+ * handler are resolved in between render quanta.
+ *
+ * After a few iterations of the test, one of the worklet posts back the string
+ * "ok" to the main thread, and the test is considered a success.
+ */
+var idx = 0;
+
+class PromiseProcessor extends AudioWorkletProcessor {
+ constructor(options) {
+ super(options);
+ }
+
+ process(inputs, outputs) {
+ if (idx % 2 != 0) {
+ this.port.postMessage("ko");
+ // Don't bother continuing calling process in this case, the test has
+ // already failed.
+ return false;
+ }
+ Promise.resolve().then(() => {
+ idx++;
+ if (idx == 100) {
+ this.port.postMessage("ok");
+ }
+ });
+ // Ensure process is called again.
+ return true;
+ }
+}
+
+registerProcessor('promise-processor', PromiseProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/register-processor-typeerrors.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/register-processor-typeerrors.js
new file mode 100644
index 0000000000..93894842fc
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/register-processor-typeerrors.js
@@ -0,0 +1,39 @@
+// For cross-thread messaging.
+class MessengerProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this.port.onmessage = this.startTest.bind(this);
+ }
+
+ process() {}
+
+ startTest(message) {
+ runRegisterProcessorTest(this.port);
+ }
+}
+
+function runRegisterProcessorTest(messagePort) {
+ try {
+ // TypeError when a given parameter is not a Function.
+ const DummyObject = {};
+ registerProcessor('type-error-on-object', DummyObject);
+ } catch (exception) {
+ messagePort.postMessage({
+ name: exception.name,
+ message: exception.message
+ });
+ }
+
+ try {
+ // TypeError When a given parameter is a Function, but not a constructor.
+ const DummyFunction = () => {};
+ registerProcessor('type-error-on-function', DummyFunction);
+ } catch (exception) {
+ messagePort.postMessage({
+ name: exception.name,
+ message: exception.message
+ });
+ }
+}
+
+registerProcessor('messenger-processor', MessengerProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/sharedarraybuffer-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/sharedarraybuffer-processor.js
new file mode 100644
index 0000000000..2ccacccd4b
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/sharedarraybuffer-processor.js
@@ -0,0 +1,35 @@
+/**
+ * @class SharedArrayBufferProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class demonstrates passing SharedArrayBuffers to and from
+ * workers.
+ */
+class SharedArrayBufferProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this.port.onmessage = this.handleMessage.bind(this);
+ this.port.onmessageerror = this.handleMessageError.bind(this);
+ let sab = new SharedArrayBuffer(8);
+ this.port.postMessage({state: 'created', sab});
+ }
+
+ handleMessage(event) {
+ this.port.postMessage({
+ state: 'received message',
+ isSab: event.data instanceof SharedArrayBuffer
+ });
+ }
+
+ handleMessageError(event) {
+ this.port.postMessage({
+ state: 'received messageerror'
+ });
+ }
+
+ process() {
+ return true;
+ }
+}
+
+registerProcessor('sharedarraybuffer-processor', SharedArrayBufferProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/timing-info-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/timing-info-processor.js
new file mode 100644
index 0000000000..714e32dbb5
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/timing-info-processor.js
@@ -0,0 +1,25 @@
+/**
+ * @class TimingInfoProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor class is to test the timing information in AWGS.
+ */
+class TimingInfoProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this.port.onmessage = this.echoMessage.bind(this);
+ }
+
+ echoMessage(event) {
+ this.port.postMessage({
+ currentTime: currentTime,
+ currentFrame: currentFrame
+ });
+ }
+
+ process() {
+ return true;
+ }
+}
+
+registerProcessor('timing-info-processor', TimingInfoProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-output-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-output-processor.js
new file mode 100644
index 0000000000..2d7399ca3b
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-output-processor.js
@@ -0,0 +1,42 @@
+/**
+ * @class ZeroOutputProcessor
+ * @extends AudioWorkletProcessor
+ *
+ * This processor accumulates the incoming buffer and send the buffered data
+ * to the main thread when it reaches the specified frame length. The processor
+ * only supports the single input.
+ */
+
+const kRenderQuantumFrames = 128;
+
+class ZeroOutputProcessor extends AudioWorkletProcessor {
+ constructor(options) {
+ super();
+
+ this._framesRequested = options.processorOptions.bufferLength;
+ this._framesCaptured = 0;
+ this._buffer = [];
+ for (let i = 0; i < options.processorOptions.channeCount; ++i) {
+ this._buffer[i] = new Float32Array(this._framesRequested);
+ }
+ }
+
+ process(inputs) {
+ let input = inputs[0];
+ let startIndex = this._framesCaptured;
+ let endIndex = startIndex + kRenderQuantumFrames;
+ for (let i = 0; i < this._buffer.length; ++i) {
+ this._buffer[i].subarray(startIndex, endIndex).set(input[i]);
+ }
+ this._framesCaptured = endIndex;
+
+ if (this._framesCaptured >= this._framesRequested) {
+ this.port.postMessage({ capturedBuffer: this._buffer });
+ return false;
+ } else {
+ return true;
+ }
+ }
+}
+
+registerProcessor('zero-output-processor', ZeroOutputProcessor);
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-outputs-check-processor.js b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-outputs-check-processor.js
new file mode 100644
index 0000000000..f816e918a2
--- /dev/null
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audioworklet-interface/processors/zero-outputs-check-processor.js
@@ -0,0 +1,78 @@
+/**
+ * Returns true if a given AudioPort is completely filled with zero samples.
+ * "AudioPort" is a short-hand for FrozenArray<FrozenArray<Float32Array>>.
+ *
+ * @param {FrozenArray<FrozenArray<Float32Array>>} audioPort
+ * @returns bool
+ */
+function IsAllZero(audioPort) {
+ for (let busIndex = 0; busIndex < audioPort.length; ++busIndex) {
+ const audioBus = audioPort[busIndex];
+ for (let channelIndex = 0; channelIndex < audioBus.length; ++channelIndex) {
+ const audioChannel = audioBus[channelIndex];
+ for (let sample = 0; sample < audioChannel.length; ++sample) {
+ if (audioChannel[sample] != 0)
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+const kRenderQuantumFrames = 128;
+const kTestLengthInSec = 1.0;
+const kPulseDuration = 100;
+
+/**
+ * Checks the |outputs| argument of AudioWorkletProcessor.process() and
+ * send a message to an associated AudioWorkletNode. It needs to be all zero
+ * at all times.
+ *
+ * @class ZeroOutputsCheckProcessor
+ * @extends {AudioWorkletProcessor}
+ */
+class ZeroOutputsCheckProcessor extends AudioWorkletProcessor {
+ constructor() {
+ super();
+ this.startTime = currentTime;
+ this.counter = 0;
+ }
+
+ process(inputs, outputs) {
+ if (!IsAllZero(outputs)) {
+ this.port.postMessage({
+ type: 'assertion',
+ success: false,
+ message: 'Unexpected Non-zero sample found in |outputs|.'
+ });
+ return false;
+ }
+
+ if (currentTime - this.startTime >= kTestLengthInSec) {
+ this.port.postMessage({
+ type: 'assertion',
+ success: true,
+ message: `|outputs| has been all zeros for ${kTestLengthInSec} ` +
+ 'seconds as expected.'
+ });
+ return false;
+ }
+
+ // Every ~0.25 second (100 render quanta), switch between outputting white
+ // noise and just exiting without doing anything. (from crbug.com/1099756)
+ this.counter++;
+ if (Math.floor(this.counter / kPulseDuration) % 2 == 0)
+ return true;
+
+ let output = outputs[0];
+ for (let channel = 0; channel < output.length; ++channel) {
+ for (let sample = 0; sample < 128; sample++) {
+ output[channel][sample] = 0.1 * (Math.random() - 0.5);
+ }
+ }
+
+ return true;
+ }
+}
+
+registerProcessor('zero-outputs-check-processor', ZeroOutputsCheckProcessor);