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; } }