From 2ee8cb1a5287b25105d62c984b4f3f39a57866c7 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Fri, 27 Sep 2019 17:55:09 -0400 Subject: [PATCH] feat: Wrapper around the AudioWorkletNode --- Tone/core/context/ToneAudioWorklet.ts | 63 +++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Tone/core/context/ToneAudioWorklet.ts diff --git a/Tone/core/context/ToneAudioWorklet.ts b/Tone/core/context/ToneAudioWorklet.ts new file mode 100644 index 000000000..fb67689ca --- /dev/null +++ b/Tone/core/context/ToneAudioWorklet.ts @@ -0,0 +1,63 @@ +import { ToneAudioNode, ToneAudioNodeOptions } from "./ToneAudioNode"; + +export type ToneAudioWorkletOptions = ToneAudioNodeOptions; + +export abstract class ToneAudioWorklet extends ToneAudioNode { + + readonly name: string = "ToneAudioWorklet"; + + /** + * The processing node + */ + protected _worklet!: AudioWorkletNode; + + /** + * The constructor options for the node + */ + protected workletOptions: Partial = {}; + + /** + * The code which is run in the worklet + */ + protected abstract _audioWorklet(): string; + + /** + * Get the name of the audio worklet + */ + protected abstract _audioWorkletName(): string; + + /** + * Invoked when the module is loaded and the node is created + */ + protected abstract onReady(node: AudioWorkletNode): void; + + constructor(options: Options) { + super(options); + + const blobUrl = URL.createObjectURL(new Blob([this._audioWorklet()], { type: "text/javascript" })); + const name = this._audioWorkletName(); + + // Register the processor + this.context.addAudioWorkletModule(blobUrl, name).then(() => { + // create the worklet when it's read + if (!this.disposed) { + this._worklet = this.context.createAudioWorkletNode(name, this.workletOptions); + this._worklet.onprocessorerror = e => { + console.log(e); + // @ts-ignore + throw e.error; + }; + this.onReady(this._worklet); + } + }); + } + + dispose(): this { + super.dispose(); + if (this._worklet) { + this._worklet.disconnect(); + } + return this; + } + +}