Load only a single AudioWorklet

This commit is contained in:
Christoph Guttandin 2022-03-21 16:34:23 +01:00
parent 1bedd96b84
commit 75a802cfb2
7 changed files with 42 additions and 17 deletions

View file

@ -1,5 +1,6 @@
import { expect } from "chai";
import { FeedbackCombFilter } from "./FeedbackCombFilter";
import { BitCrusher } from "Tone/effect/BitCrusher";
import { BasicTests } from "test/helper/Basic";
import { PassAudio } from "test/helper/PassAudio";
import { Offline } from "test/helper/Offline";
@ -76,5 +77,20 @@ describe("FeedbackCombFilter", () => {
});
});
});
it("should be usable with the BitCrusher", (done) => {
new FeedbackCombFilter();
new BitCrusher(4);
const handle = setTimeout(() => {
window.onunhandledrejection = null;
done();
}, 100);
window.onunhandledrejection = (event) => {
done(event.reason);
clearTimeout(handle);
};
});
});

View file

@ -105,8 +105,7 @@ export abstract class BaseContext
abstract get rawContext(): AnyAudioContext;
abstract addAudioWorkletModule(
_url: string,
_name: string
_url: string
): Promise<void>;
abstract lookAhead: number;

View file

@ -340,7 +340,7 @@ export class Context extends BaseContext {
/**
* Maps a module name to promise of the addModule method
*/
private _workletModules: Map<string, Promise<void>> = new Map();
private _workletPromise: null | Promise<void> = null;
/**
* Create an audio worklet node from a name and options. The module
@ -356,29 +356,23 @@ export class Context extends BaseContext {
/**
* Add an AudioWorkletProcessor module
* @param url The url of the module
* @param name The name of the module
*/
async addAudioWorkletModule(url: string, name: string): Promise<void> {
async addAudioWorkletModule(url: string): Promise<void> {
assert(
isDefined(this.rawContext.audioWorklet),
"AudioWorkletNode is only available in a secure context (https or localhost)"
);
if (!this._workletModules.has(name)) {
this._workletModules.set(
name,
this.rawContext.audioWorklet.addModule(url)
);
if (!this._workletPromise) {
this._workletPromise = this.rawContext.audioWorklet.addModule(url);
}
await this._workletModules.get(name);
await this._workletPromise;
}
/**
* Returns a promise which resolves when all of the worklets have been loaded on this context
*/
protected async workletsAreReady(): Promise<void> {
const promises: Promise<void>[] = [];
this._workletModules.forEach((promise) => promises.push(promise));
await Promise.all(promises);
await this._workletPromise ? this._workletPromise : Promise.resolve();
}
//---------------------------

View file

@ -25,7 +25,7 @@ describe("DummyContext", () => {
context.decodeAudioData(new Float32Array(100));
context.createAudioWorkletNode("test.js");
context.rawContext;
context.addAudioWorkletModule("test.js", "test");
context.addAudioWorkletModule("test.js");
context.resume();
context.setTimeout(() => {}, 1);
context.clearTimeout(1);

View file

@ -127,7 +127,7 @@ export class DummyContext extends BaseContext {
return {} as AnyAudioContext;
}
async addAudioWorkletModule(_url: string, _name: string): Promise<void> {
async addAudioWorkletModule(_url: string): Promise<void> {
return Promise.resolve();
}

View file

@ -53,7 +53,7 @@ export abstract class ToneAudioWorklet<Options extends ToneAudioWorkletOptions>
this._dummyParam = this._dummyGain.gain;
// Register the processor
this.context.addAudioWorkletModule(blobUrl, name).then(() => {
this.context.addAudioWorkletModule(blobUrl).then(() => {
// create the worklet when it's read
if (!this.disposed) {
this._worklet = this.context.createAudioWorkletNode(name, this.workletOptions);

View file

@ -1,4 +1,5 @@
import { BitCrusher } from "./BitCrusher";
import { FeedbackCombFilter } from "Tone/component/filter/FeedbackCombFilter";
import { Oscillator } from "Tone/source/oscillator/Oscillator";
import { BasicTests } from "test/helper/Basic";
import { EffectTests } from "test/helper/EffectTests";
@ -38,5 +39,20 @@ describe("BitCrusher", () => {
crusher.dispose();
});
});
it("should be usable with the FeedbackCombFilter", (done) => {
new BitCrusher(4);
new FeedbackCombFilter();
const handle = setTimeout(() => {
window.onunhandledrejection = null;
done();
}, 100);
window.onunhandledrejection = (event) => {
done(event.reason);
clearTimeout(handle);
};
});
});