@fluex/fluexgl-dsp 0.4.7 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/lib/dist/console-codes.d.ts +2 -1
- package/lib/dist/console-codes.d.ts.map +1 -1
- package/lib/dist/console-codes.js +1 -0
- package/lib/dist/core/classes/AudioClip.d.ts +26 -17
- package/lib/dist/core/classes/AudioClip.d.ts.map +1 -1
- package/lib/dist/core/classes/AudioClip.js +124 -51
- package/lib/dist/core/classes/AudioClipPlayer.d.ts +8 -8
- package/lib/dist/core/classes/AudioClipPlayer.d.ts.map +1 -1
- package/lib/dist/core/classes/AudioClipPlayer.js +22 -24
- package/lib/dist/core/classes/AudioDevice.d.ts +46 -5
- package/lib/dist/core/classes/AudioDevice.d.ts.map +1 -1
- package/lib/dist/core/classes/AudioDevice.js +47 -6
- package/lib/dist/core/classes/Channel.d.ts +20 -20
- package/lib/dist/core/classes/Channel.d.ts.map +1 -1
- package/lib/dist/core/classes/Channel.js +42 -42
- package/lib/dist/core/classes/DpsPipeline.d.ts +6 -6
- package/lib/dist/core/classes/DpsPipeline.d.ts.map +1 -1
- package/lib/dist/core/classes/DpsPipeline.js +18 -18
- package/lib/dist/core/classes/Effector.d.ts +5 -5
- package/lib/dist/core/classes/Effector.d.ts.map +1 -1
- package/lib/dist/core/classes/Effector.js +8 -8
- package/lib/dist/core/classes/Master.d.ts +6 -6
- package/lib/dist/core/classes/Master.d.ts.map +1 -1
- package/lib/dist/core/classes/Master.js +18 -18
- package/lib/dist/effects/classes/Analyser.d.ts +6 -6
- package/lib/dist/effects/classes/Analyser.d.ts.map +1 -1
- package/lib/dist/effects/classes/Analyser.js +7 -7
- package/lib/dist/effects/classes/Chorus.d.ts +7 -7
- package/lib/dist/effects/classes/Chorus.d.ts.map +1 -1
- package/lib/dist/effects/classes/Chorus.js +25 -25
- package/lib/dist/effects/classes/Distortion.d.ts +1 -1
- package/lib/dist/effects/classes/Distortion.d.ts.map +1 -1
- package/lib/dist/effects/classes/Distortion.js +1 -1
- package/lib/dist/effects/classes/Reverb.d.ts +32 -0
- package/lib/dist/effects/classes/Reverb.d.ts.map +1 -0
- package/lib/dist/effects/classes/Reverb.js +61 -0
- package/lib/dist/effects/classes/clips/HardClip.d.ts +5 -5
- package/lib/dist/effects/classes/clips/HardClip.d.ts.map +1 -1
- package/lib/dist/effects/classes/clips/HardClip.js +14 -14
- package/lib/dist/effects/classes/clips/SoftClip.d.ts +4 -4
- package/lib/dist/effects/classes/clips/SoftClip.d.ts.map +1 -1
- package/lib/dist/effects/classes/clips/SoftClip.js +13 -13
- package/lib/dist/effects/classes/filters/HighPassFilter.d.ts +5 -5
- package/lib/dist/effects/classes/filters/HighPassFilter.d.ts.map +1 -1
- package/lib/dist/effects/classes/filters/HighPassFilter.js +16 -16
- package/lib/dist/effects/classes/filters/LowPassFilter.d.ts +5 -5
- package/lib/dist/effects/classes/filters/LowPassFilter.d.ts.map +1 -1
- package/lib/dist/effects/classes/filters/LowPassFilter.js +17 -17
- package/lib/dist/effects/classes/filters/NotchFilter.d.ts +5 -5
- package/lib/dist/effects/classes/filters/NotchFilter.d.ts.map +1 -1
- package/lib/dist/effects/classes/filters/NotchFilter.js +16 -16
- package/lib/dist/effects/exports.d.ts +1 -5
- package/lib/dist/effects/exports.d.ts.map +1 -1
- package/lib/dist/effects/exports.js +1 -5
- package/lib/dist/index.d.ts +2 -2
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +2 -2
- package/lib/dist/typings.d.ts +11 -0
- package/lib/dist/typings.d.ts.map +1 -1
- package/lib/dist/utilities/debugger.d.ts +4 -4
- package/lib/dist/utilities/debugger.js +8 -8
- package/lib/dist/utilities/helpers.d.ts +13 -13
- package/lib/dist/utilities/helpers.d.ts.map +1 -1
- package/lib/dist/utilities/helpers.js +45 -59
- package/lib/dist/utilities/web-assembly.js +1 -1
- package/lib/src/console-codes.ts +2 -1
- package/lib/src/core/classes/AudioClip.ts +154 -60
- package/lib/src/core/classes/AudioClipPlayer.ts +22 -24
- package/lib/src/core/classes/AudioDevice.ts +49 -6
- package/lib/src/core/classes/Channel.ts +42 -42
- package/lib/src/core/classes/DpsPipeline.ts +19 -19
- package/lib/src/core/classes/Effector.ts +9 -9
- package/lib/src/core/classes/Master.ts +18 -18
- package/lib/src/effects/classes/Analyser.ts +7 -7
- package/lib/src/effects/classes/Chorus.ts +25 -25
- package/lib/src/effects/classes/Distortion.ts +1 -1
- package/lib/src/effects/classes/Reverb.ts +81 -0
- package/lib/src/effects/classes/clips/HardClip.ts +14 -14
- package/lib/src/effects/classes/clips/SoftClip.ts +13 -13
- package/lib/src/effects/classes/filters/HighPassFilter.ts +16 -16
- package/lib/src/effects/classes/filters/LowPassFilter.ts +17 -17
- package/lib/src/effects/classes/filters/NotchFilter.ts +16 -16
- package/lib/src/effects/exports.ts +1 -6
- package/lib/src/index.ts +11 -15
- package/lib/src/typings.ts +13 -0
- package/lib/src/utilities/debugger.ts +4 -4
- package/lib/src/utilities/helpers.ts +47 -60
- package/lib/src/utilities/web-assembly.ts +1 -1
- package/package.json +3 -2
- package/lib/src/effects/classes/reverbs/ChamberReverb.ts +0 -1
- package/lib/src/effects/classes/reverbs/ConvolverReverb.ts +0 -1
- package/lib/src/effects/classes/reverbs/GenericReverb.ts +0 -1
- package/lib/src/effects/classes/reverbs/HallReverb.ts +0 -1
- package/lib/src/effects/classes/reverbs/RoomReverb.ts +0 -1
|
@@ -24,10 +24,10 @@ export class Analyser extends Effector {
|
|
|
24
24
|
constructor(options?: Partial<AnalyserOptions>) {
|
|
25
25
|
super();
|
|
26
26
|
|
|
27
|
-
if (options) this.
|
|
27
|
+
if (options) this.setOptions(options);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
public async
|
|
30
|
+
public async initializeOnAttachment(context: AudioContext): Promise<void> {
|
|
31
31
|
|
|
32
32
|
this.context = context;
|
|
33
33
|
this.analyserNode = new AnalyserNode(context, this.options);
|
|
@@ -36,7 +36,7 @@ export class Analyser extends Effector {
|
|
|
36
36
|
this.allocateBuffers();
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
public
|
|
39
|
+
public setOptions(options: Partial<AnalyserOptions>): void {
|
|
40
40
|
|
|
41
41
|
(Object.keys(options) as AnalyserOptionKeys[]).forEach((key) => {
|
|
42
42
|
const value = options[key];
|
|
@@ -60,7 +60,7 @@ export class Analyser extends Effector {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
public
|
|
63
|
+
public getWaveformFloatData(): Float32Array | null {
|
|
64
64
|
|
|
65
65
|
if (!this.analyserNode) return null;
|
|
66
66
|
|
|
@@ -68,7 +68,7 @@ export class Analyser extends Effector {
|
|
|
68
68
|
return this.waveformFloat32ArrayBuffer;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
public
|
|
71
|
+
public getWaveformByteData(): Uint8Array | null {
|
|
72
72
|
|
|
73
73
|
if (!this.analyserNode) return null;
|
|
74
74
|
|
|
@@ -76,7 +76,7 @@ export class Analyser extends Effector {
|
|
|
76
76
|
return this.waveformUint8ArrayBuffer;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
public
|
|
79
|
+
public getFrequencyFloatData(): Float32Array | null {
|
|
80
80
|
|
|
81
81
|
if(!this.analyserNode) return null;
|
|
82
82
|
|
|
@@ -84,7 +84,7 @@ export class Analyser extends Effector {
|
|
|
84
84
|
return this.frequencyFloat32ArrayBuffer;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
public
|
|
87
|
+
public getFrequencyByteData(): Uint8Array | null {
|
|
88
88
|
|
|
89
89
|
if(!this.analyserNode) return null;
|
|
90
90
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { coerceFiniteNumber, sendMessageToWorklet, createAudioWorkletNode } from "../../utilities/helpers";
|
|
2
2
|
import { Effector } from "../../core/classes/Effector";
|
|
3
3
|
import { ChorusEffectOptions, ChorusMessageCommandId, AudioWorkletProcessorNames, StrictMode } from "../../typings";
|
|
4
4
|
|
|
@@ -17,22 +17,22 @@ export class Chorus extends Effector {
|
|
|
17
17
|
constructor({ baseDelayMs, depthMs, rateHz, mix, feedback, strictMode }: Partial<ChorusEffectOptions>) {
|
|
18
18
|
super();
|
|
19
19
|
|
|
20
|
-
this.baseDelayMs = Math.max(0,
|
|
21
|
-
this.depthMs = Math.max(0,
|
|
22
|
-
this.rateHz = Math.max(0,
|
|
23
|
-
this.mix = Math.max(0, Math.min(1,
|
|
24
|
-
this.feedback = Math.max(0, Math.min(1,
|
|
20
|
+
this.baseDelayMs = Math.max(0, coerceFiniteNumber(baseDelayMs, this.baseDelayMs));
|
|
21
|
+
this.depthMs = Math.max(0, coerceFiniteNumber(depthMs, this.depthMs));
|
|
22
|
+
this.rateHz = Math.max(0, coerceFiniteNumber(rateHz, this.rateHz));
|
|
23
|
+
this.mix = Math.max(0, Math.min(1, coerceFiniteNumber(mix, this.mix)));
|
|
24
|
+
this.feedback = Math.max(0, Math.min(1, coerceFiniteNumber(feedback, this.feedback)));
|
|
25
25
|
|
|
26
|
-
const mode =
|
|
26
|
+
const mode = coerceFiniteNumber(strictMode, this.strictMode);
|
|
27
27
|
this.strictMode = mode === StrictMode.Enabled ? StrictMode.Enabled : StrictMode.Disabled;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
public async
|
|
30
|
+
public async initializeOnAttachment(context: AudioContext): Promise<void> {
|
|
31
31
|
this.context = context;
|
|
32
|
-
this.audioWorkletNode =
|
|
32
|
+
this.audioWorkletNode = createAudioWorkletNode<ChorusEffectOptions>(context, AudioWorkletProcessorNames.Chorus, this.returnOptionsAsObject());
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
public
|
|
35
|
+
public returnOptionsAsObject(): ChorusEffectOptions {
|
|
36
36
|
return {
|
|
37
37
|
baseDelayMs: this.baseDelayMs,
|
|
38
38
|
depthMs: this.depthMs,
|
|
@@ -43,33 +43,33 @@ export class Chorus extends Effector {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
public
|
|
47
|
-
value = Math.max(0,
|
|
46
|
+
public setBaseDelayMs(value: number): boolean {
|
|
47
|
+
value = Math.max(0, coerceFiniteNumber(value, this.baseDelayMs));
|
|
48
48
|
this.baseDelayMs = value;
|
|
49
|
-
return
|
|
49
|
+
return sendMessageToWorklet<ChorusMessageCommandId, number>(this.audioWorkletNode, ChorusMessageCommandId.SetBaseDelayMs, value);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
public
|
|
53
|
-
value = Math.max(0,
|
|
52
|
+
public setDepthMs(value: number) {
|
|
53
|
+
value = Math.max(0, coerceFiniteNumber(value, this.depthMs));
|
|
54
54
|
this.depthMs = value;
|
|
55
|
-
return
|
|
55
|
+
return sendMessageToWorklet<ChorusMessageCommandId, number>(this.audioWorkletNode, ChorusMessageCommandId.SetDepthMs, value);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
public
|
|
59
|
-
value = Math.max(0,
|
|
58
|
+
public setRateHz(value: number) {
|
|
59
|
+
value = Math.max(0, coerceFiniteNumber(value, this.rateHz));
|
|
60
60
|
this.rateHz = value;
|
|
61
|
-
return
|
|
61
|
+
return sendMessageToWorklet<ChorusMessageCommandId, number>(this.audioWorkletNode, ChorusMessageCommandId.SetRateHz, value);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
public
|
|
65
|
-
value = Math.max(0, Math.min(1,
|
|
64
|
+
public setMix(value: number) {
|
|
65
|
+
value = Math.max(0, Math.min(1, coerceFiniteNumber(value, this.mix)));
|
|
66
66
|
this.mix = value;
|
|
67
|
-
return
|
|
67
|
+
return sendMessageToWorklet<ChorusMessageCommandId, number>(this.audioWorkletNode, ChorusMessageCommandId.SetMix, value);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
public
|
|
71
|
-
value = Math.max(0, Math.min(1,
|
|
70
|
+
public setFeedback(value: number) {
|
|
71
|
+
value = Math.max(0, Math.min(1, coerceFiniteNumber(value, this.feedback)));
|
|
72
72
|
this.feedback = value;
|
|
73
|
-
return
|
|
73
|
+
return sendMessageToWorklet<ChorusMessageCommandId, number>(this.audioWorkletNode, ChorusMessageCommandId.SetFeedback, value);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Effector } from "../../core/exports";
|
|
2
|
+
import { AudioWorkletProcessorNames, StrictMode } from "../../typings";
|
|
3
|
+
import { coerceFiniteNumber, createAudioWorkletNode, sendMessageToWorklet } from "../../utilities/helpers";
|
|
4
|
+
|
|
5
|
+
export interface ReverbOptions {
|
|
6
|
+
roomSize: number;
|
|
7
|
+
damping: number;
|
|
8
|
+
mix: number;
|
|
9
|
+
stereoSpreadMs: number;
|
|
10
|
+
strictMode: StrictMode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export enum ReverbMessageCommandId {
|
|
14
|
+
SetRoomSize,
|
|
15
|
+
SetDamping,
|
|
16
|
+
SetMix,
|
|
17
|
+
SetStereoSpreadMs
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class Reverb extends Effector {
|
|
21
|
+
|
|
22
|
+
public label: string | null = "Reverb";
|
|
23
|
+
public name: string = "Reverb";
|
|
24
|
+
|
|
25
|
+
public roomSize: number = 0.3;
|
|
26
|
+
public damping: number = 0.5;
|
|
27
|
+
public mix: number = 0.3;
|
|
28
|
+
public stereoSpreadMs: number = 0;
|
|
29
|
+
public strictMode: StrictMode = StrictMode.Disabled;
|
|
30
|
+
|
|
31
|
+
constructor(options?: Partial<ReverbOptions>) {
|
|
32
|
+
super();
|
|
33
|
+
|
|
34
|
+
this.roomSize = Math.max(0, coerceFiniteNumber(options?.roomSize ?? this.roomSize, this.roomSize));
|
|
35
|
+
this.damping = Math.max(0, coerceFiniteNumber(options?.damping ?? this.damping, this.damping));
|
|
36
|
+
this.mix = Math.max(0, coerceFiniteNumber(options?.mix ?? this.mix, this.mix));
|
|
37
|
+
this.stereoSpreadMs = Math.max(0, coerceFiniteNumber(options?.stereoSpreadMs ?? this.stereoSpreadMs, this.stereoSpreadMs));
|
|
38
|
+
|
|
39
|
+
const mode = coerceFiniteNumber(options?.strictMode ?? this.strictMode, this.strictMode);
|
|
40
|
+
this.strictMode = mode === StrictMode.Enabled ? StrictMode.Enabled : StrictMode.Disabled;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public async initializeOnAttachment(context: AudioContext): Promise<void> {
|
|
44
|
+
this.context = context;
|
|
45
|
+
this.audioWorkletNode = createAudioWorkletNode<ReverbOptions>(context, AudioWorkletProcessorNames.Reverb, this.returnOptionsAsObject());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public returnOptionsAsObject(): ReverbOptions {
|
|
49
|
+
return {
|
|
50
|
+
roomSize: this.roomSize,
|
|
51
|
+
damping: this.damping,
|
|
52
|
+
mix: this.mix,
|
|
53
|
+
stereoSpreadMs: this.stereoSpreadMs,
|
|
54
|
+
strictMode: this.strictMode
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public setRoomSize(roomSize: number): boolean {
|
|
59
|
+
roomSize = Math.max(0, coerceFiniteNumber(roomSize ?? this.roomSize, this.roomSize));
|
|
60
|
+
this.roomSize = roomSize;
|
|
61
|
+
return sendMessageToWorklet<ReverbMessageCommandId, number>(this.audioWorkletNode, ReverbMessageCommandId.SetRoomSize, roomSize);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public setDamping(damping: number): boolean {
|
|
65
|
+
damping = Math.max(0, coerceFiniteNumber(damping ?? this.damping, this.damping));
|
|
66
|
+
this.damping = damping;
|
|
67
|
+
return sendMessageToWorklet<ReverbMessageCommandId, number>(this.audioWorkletNode, ReverbMessageCommandId.SetDamping, damping);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public setMix(mix: number): boolean {
|
|
71
|
+
mix = Math.max(0, coerceFiniteNumber(mix ?? this.mix, this.mix));
|
|
72
|
+
this.mix = mix;
|
|
73
|
+
return sendMessageToWorklet<ReverbMessageCommandId, number>(this.audioWorkletNode, ReverbMessageCommandId.SetMix, mix);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public setStereoSpreadMs(stereoSpreadMs: number) {
|
|
77
|
+
stereoSpreadMs = Math.max(0, coerceFiniteNumber(stereoSpreadMs ?? this.stereoSpreadMs, this.stereoSpreadMs));
|
|
78
|
+
this.stereoSpreadMs = stereoSpreadMs;
|
|
79
|
+
return sendMessageToWorklet<ReverbMessageCommandId, number>(this.audioWorkletNode, ReverbMessageCommandId.SetStereoSpreadMs, stereoSpreadMs);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effector } from "../../../core/classes/Effector";
|
|
2
|
-
import {
|
|
2
|
+
import { coerceFiniteNumber, createAudioWorkletNode, sendMessageToWorklet } from "../../../utilities/helpers";
|
|
3
3
|
import { HardClipMessageCommandId, AudioWorkletProcessorNames, HardClipOptions, StrictMode } from "../../../typings";
|
|
4
4
|
|
|
5
5
|
export class HardClip extends Effector {
|
|
@@ -11,22 +11,22 @@ export class HardClip extends Effector {
|
|
|
11
11
|
public gain: number = 1;
|
|
12
12
|
public strictMode: StrictMode = StrictMode.Disabled;
|
|
13
13
|
|
|
14
|
-
constructor(
|
|
14
|
+
constructor(options?: HardClipOptions) {
|
|
15
15
|
super();
|
|
16
16
|
|
|
17
|
-
this.drive = Math.max(0,
|
|
18
|
-
this.gain = Math.max(0,
|
|
17
|
+
this.drive = Math.max(0, coerceFiniteNumber(options?.drive ?? this.drive, this.drive));
|
|
18
|
+
this.gain = Math.max(0, coerceFiniteNumber(options?.gain ?? this.gain, this.gain));
|
|
19
19
|
|
|
20
|
-
const mode =
|
|
20
|
+
const mode = coerceFiniteNumber(options?.strictMode ?? this.strictMode, this.strictMode);
|
|
21
21
|
this.strictMode = mode === StrictMode.Enabled ? StrictMode.Enabled : StrictMode.Disabled;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
public async
|
|
24
|
+
public async initializeOnAttachment(context: AudioContext): Promise<void> {
|
|
25
25
|
this.context = context;
|
|
26
|
-
this.audioWorkletNode =
|
|
26
|
+
this.audioWorkletNode = createAudioWorkletNode<HardClipOptions>(context, AudioWorkletProcessorNames.HardClip, this.returnOptionsAsObject());
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
public
|
|
29
|
+
public returnOptionsAsObject(): HardClipOptions {
|
|
30
30
|
return {
|
|
31
31
|
drive: this.drive,
|
|
32
32
|
gain: this.gain,
|
|
@@ -34,15 +34,15 @@ export class HardClip extends Effector {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
public
|
|
38
|
-
drive = Math.max(0,
|
|
37
|
+
public setDrive(drive: number): boolean {
|
|
38
|
+
drive = Math.max(0, coerceFiniteNumber(drive, this.drive));
|
|
39
39
|
this.drive = drive;
|
|
40
|
-
return
|
|
40
|
+
return sendMessageToWorklet<HardClipMessageCommandId, number>(this.audioWorkletNode, HardClipMessageCommandId.SetDrive, drive);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
public
|
|
44
|
-
gain = Math.max(0,
|
|
43
|
+
public setGain(gain: number): boolean{
|
|
44
|
+
gain = Math.max(0, coerceFiniteNumber(gain, this.gain));
|
|
45
45
|
this.gain = gain;
|
|
46
|
-
return
|
|
46
|
+
return sendMessageToWorklet<HardClipMessageCommandId, number>(this.audioWorkletNode, HardClipMessageCommandId.SetGain, gain);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { coerceFiniteNumber, createAudioWorkletNode, sendMessageToWorklet } from "../../../utilities/helpers";
|
|
2
2
|
import { Effector } from "../../../core/classes/Effector";
|
|
3
3
|
import { SoftClipOptions, AudioWorkletProcessorNames, SoftClipMessageCommandId, StrictMode } from "../../../typings";
|
|
4
4
|
|
|
@@ -14,23 +14,23 @@ export class SoftClip extends Effector {
|
|
|
14
14
|
constructor({ drive, gain, strictMode }: Partial<SoftClipOptions> = {}) {
|
|
15
15
|
super();
|
|
16
16
|
|
|
17
|
-
this.drive = Math.max(0,
|
|
18
|
-
this.gain = Math.max(0,
|
|
17
|
+
this.drive = Math.max(0, coerceFiniteNumber(drive, this.drive));
|
|
18
|
+
this.gain = Math.max(0, coerceFiniteNumber(gain, this.gain));
|
|
19
19
|
|
|
20
|
-
const mode =
|
|
20
|
+
const mode = coerceFiniteNumber(strictMode, this.strictMode);
|
|
21
21
|
this.strictMode = mode === StrictMode.Enabled ? StrictMode.Enabled : StrictMode.Disabled;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
public async
|
|
24
|
+
public async initializeOnAttachment(context: AudioContext): Promise<void> {
|
|
25
25
|
|
|
26
26
|
if(this.context === null)
|
|
27
27
|
this.context = context;
|
|
28
28
|
|
|
29
29
|
if(this.audioWorkletNode === null)
|
|
30
|
-
this.audioWorkletNode =
|
|
30
|
+
this.audioWorkletNode = createAudioWorkletNode<SoftClipOptions>(context, AudioWorkletProcessorNames.SoftClip, this.returnOptionsAsObject());
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
public
|
|
33
|
+
public returnOptionsAsObject(): SoftClipOptions {
|
|
34
34
|
return {
|
|
35
35
|
drive: this.drive,
|
|
36
36
|
gain: this.gain,
|
|
@@ -38,15 +38,15 @@ export class SoftClip extends Effector {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
public
|
|
42
|
-
drive = Math.max(0,
|
|
41
|
+
public setDrive(drive: number): boolean {
|
|
42
|
+
drive = Math.max(0, coerceFiniteNumber(drive, this.drive));
|
|
43
43
|
this.drive = drive;
|
|
44
|
-
return
|
|
44
|
+
return sendMessageToWorklet<SoftClipMessageCommandId, number>(this.audioWorkletNode, SoftClipMessageCommandId.SetDrive, drive);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
public
|
|
48
|
-
gain = Math.max(0,
|
|
47
|
+
public setGain(gain: number): boolean{
|
|
48
|
+
gain = Math.max(0, coerceFiniteNumber(gain, this.gain));
|
|
49
49
|
this.gain = gain;
|
|
50
|
-
return
|
|
50
|
+
return sendMessageToWorklet<SoftClipMessageCommandId, number>(this.audioWorkletNode, SoftClipMessageCommandId.SetGain, gain);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { coerceFiniteNumber, createAudioWorkletNode, sendMessageToWorklet } from "../../../utilities/helpers";
|
|
2
2
|
import { Effector } from "../../../core/classes/Effector";
|
|
3
3
|
import { AudioWorkletProcessorNames, HighPassFilterMessageCommandId, HighPassFilterOptions, StrictMode } from "../../../typings";
|
|
4
4
|
import { DEFAULT_SAMPLE_RATE } from "../../../utilities/constants";
|
|
@@ -18,22 +18,22 @@ export class HighPassFilter extends Effector {
|
|
|
18
18
|
constructor({ cutoff, q, strictMode }: Partial<HighPassFilterOptions> = {}) {
|
|
19
19
|
super();
|
|
20
20
|
|
|
21
|
-
this.cutoff =
|
|
22
|
-
this.q =
|
|
21
|
+
this.cutoff = coerceFiniteNumber(cutoff, this.cutoff);
|
|
22
|
+
this.q = coerceFiniteNumber(q, this.q);
|
|
23
23
|
|
|
24
|
-
const mode =
|
|
24
|
+
const mode = coerceFiniteNumber(strictMode, this.strictMode);
|
|
25
25
|
this.strictMode = mode === StrictMode.Enabled ? StrictMode.Enabled : StrictMode.Disabled;
|
|
26
26
|
this.audioWorkletNode && this.registerMessageEventListener(this.audioWorkletNode);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
public async
|
|
29
|
+
public async initializeOnAttachment(context: AudioContext): Promise<void> {
|
|
30
30
|
|
|
31
31
|
this.context = context;
|
|
32
32
|
this.contextSampleRate = context.sampleRate;
|
|
33
|
-
this.audioWorkletNode =
|
|
33
|
+
this.audioWorkletNode = createAudioWorkletNode(context, AudioWorkletProcessorNames.HighPassFilter, this.returnOptionsAsObject());
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
public
|
|
36
|
+
public returnOptionsAsObject(): HighPassFilterOptions {
|
|
37
37
|
return {
|
|
38
38
|
cutoff: this.cutoff,
|
|
39
39
|
q: this.q,
|
|
@@ -42,40 +42,40 @@ export class HighPassFilter extends Effector {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
public
|
|
45
|
+
public setCutoff(cutoff: number = 1000): boolean {
|
|
46
46
|
|
|
47
47
|
if (!this.context) return false;
|
|
48
48
|
|
|
49
|
-
cutoff =
|
|
49
|
+
cutoff = coerceFiniteNumber(cutoff, this.cutoff);
|
|
50
50
|
cutoff = Math.min(this.maxFrequency, cutoff);
|
|
51
51
|
|
|
52
52
|
if (cutoff >= this.context.sampleRate)
|
|
53
53
|
cutoff = this.context.sampleRate;
|
|
54
54
|
|
|
55
55
|
this.cutoff = cutoff;
|
|
56
|
-
return
|
|
56
|
+
return sendMessageToWorklet<HighPassFilterMessageCommandId, number>(this.audioWorkletNode, HighPassFilterMessageCommandId.SetCutoff, cutoff);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
public
|
|
59
|
+
public setMaxFrequency(maxFrequency: number = this.maxFrequency) {
|
|
60
60
|
|
|
61
|
-
maxFrequency =
|
|
61
|
+
maxFrequency = coerceFiniteNumber(maxFrequency, this.maxFrequency);
|
|
62
62
|
|
|
63
63
|
if(maxFrequency > (this.contextSampleRate * 0.5))
|
|
64
64
|
throw new Error("Could not set the max frequency, because the value is over the sample rate.");
|
|
65
65
|
|
|
66
66
|
this.maxFrequency = maxFrequency;
|
|
67
|
-
return
|
|
67
|
+
return sendMessageToWorklet<HighPassFilterMessageCommandId.SetMaxFrequency, number>(this.audioWorkletNode, HighPassFilterMessageCommandId.SetMaxFrequency, maxFrequency);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
public
|
|
70
|
+
public setQ(q: number = 0.7): boolean {
|
|
71
71
|
|
|
72
|
-
q =
|
|
72
|
+
q = coerceFiniteNumber(q, this.q);
|
|
73
73
|
q = Math.max(0.0001, q);
|
|
74
74
|
|
|
75
75
|
if (q > 4)
|
|
76
76
|
q = 4;
|
|
77
77
|
|
|
78
78
|
this.q = q;
|
|
79
|
-
return
|
|
79
|
+
return sendMessageToWorklet<HighPassFilterMessageCommandId, number>(this.audioWorkletNode, HighPassFilterMessageCommandId.SetQ, q);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effector } from "../../../core/classes/Effector";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { coerceFiniteNumber, sendMessageToWorklet, createAudioWorkletNode } from "../../../utilities/helpers";
|
|
4
4
|
|
|
5
5
|
import { LowPassFilterOptions, LowPassFilterMessageCommandId, AudioWorkletProcessorNames, StrictMode } from "../../../typings";
|
|
6
6
|
|
|
@@ -17,22 +17,22 @@ export class LowPassFilter extends Effector {
|
|
|
17
17
|
constructor({ cutoff, minFrequency, q, strictMode }: Partial<LowPassFilterOptions>) {
|
|
18
18
|
super();
|
|
19
19
|
|
|
20
|
-
this.cutoff =
|
|
21
|
-
this.minFrequency =
|
|
22
|
-
this.q =
|
|
20
|
+
this.cutoff = coerceFiniteNumber(cutoff, this.cutoff);
|
|
21
|
+
this.minFrequency = coerceFiniteNumber(minFrequency, this.minFrequency);
|
|
22
|
+
this.q = coerceFiniteNumber(q, this.q);
|
|
23
23
|
|
|
24
|
-
const mode =
|
|
24
|
+
const mode = coerceFiniteNumber(strictMode, this.strictMode);
|
|
25
25
|
this.strictMode = mode === StrictMode.Enabled ? StrictMode.Enabled : StrictMode.Disabled;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
public async
|
|
28
|
+
public async initializeOnAttachment(context: AudioContext): Promise<void> {
|
|
29
29
|
|
|
30
30
|
this.context = context;
|
|
31
|
-
this.audioWorkletNode =
|
|
31
|
+
this.audioWorkletNode = createAudioWorkletNode(context, AudioWorkletProcessorNames.LowPassFilter, this.returnOptionsAsObject());
|
|
32
32
|
this.audioWorkletNode && this.registerMessageEventListener(this.audioWorkletNode);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
public
|
|
35
|
+
public returnOptionsAsObject(): LowPassFilterOptions {
|
|
36
36
|
return {
|
|
37
37
|
cutoff: this.cutoff,
|
|
38
38
|
minFrequency: this.minFrequency,
|
|
@@ -41,40 +41,40 @@ export class LowPassFilter extends Effector {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
public
|
|
44
|
+
public setCutoff(cutoff: number = 1000): boolean {
|
|
45
45
|
|
|
46
46
|
if (!this.context) return false;
|
|
47
47
|
|
|
48
|
-
cutoff =
|
|
48
|
+
cutoff = coerceFiniteNumber(cutoff, this.cutoff);
|
|
49
49
|
cutoff = Math.max(this.minFrequency, cutoff);
|
|
50
50
|
|
|
51
51
|
if (cutoff >= this.context.sampleRate)
|
|
52
52
|
cutoff = this.context.sampleRate;
|
|
53
53
|
|
|
54
54
|
this.cutoff = cutoff;
|
|
55
|
-
return
|
|
55
|
+
return sendMessageToWorklet<LowPassFilterMessageCommandId, number>(this.audioWorkletNode, LowPassFilterMessageCommandId.SetCutoff, cutoff);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
public
|
|
58
|
+
public setMinFrequency(minFrequency: number = 10): boolean {
|
|
59
59
|
|
|
60
|
-
minFrequency =
|
|
60
|
+
minFrequency = coerceFiniteNumber(minFrequency, this.minFrequency);
|
|
61
61
|
|
|
62
62
|
if (minFrequency < 10)
|
|
63
63
|
minFrequency = 10;
|
|
64
64
|
|
|
65
65
|
this.minFrequency = minFrequency;
|
|
66
|
-
return
|
|
66
|
+
return sendMessageToWorklet<LowPassFilterMessageCommandId, number>(this.audioWorkletNode, LowPassFilterMessageCommandId.SetMinFrequency, minFrequency);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
public
|
|
69
|
+
public setQ(q: number = 0.7): boolean {
|
|
70
70
|
|
|
71
|
-
q =
|
|
71
|
+
q = coerceFiniteNumber(q, this.q);
|
|
72
72
|
q = Math.max(0.0001, q);
|
|
73
73
|
|
|
74
74
|
if(q > 4)
|
|
75
75
|
q = 4;
|
|
76
76
|
|
|
77
77
|
this.q = q;
|
|
78
|
-
return
|
|
78
|
+
return sendMessageToWorklet<LowPassFilterMessageCommandId, number>(this.audioWorkletNode, LowPassFilterMessageCommandId.SetQ, q);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AudioWorkletProcessorNames, NotchFilterMessageCommandId, NotchFilterOptions, StrictMode } from "../../../typings";
|
|
2
2
|
import { Effector } from "../../../core/classes/Effector";
|
|
3
3
|
import { DEFAULT_SAMPLE_RATE } from "../../../utilities/constants";
|
|
4
|
-
import {
|
|
4
|
+
import { coerceFiniteNumber, createAudioWorkletNode, sendMessageToWorklet } from "../../../utilities/helpers";
|
|
5
5
|
|
|
6
6
|
export default class NotchFilter extends Effector {
|
|
7
7
|
|
|
@@ -18,22 +18,22 @@ export default class NotchFilter extends Effector {
|
|
|
18
18
|
constructor({ cutoff, q, minFrequency, strictMode }: Partial<NotchFilterOptions> = {}) {
|
|
19
19
|
super();
|
|
20
20
|
|
|
21
|
-
this.cutoff =
|
|
22
|
-
this.q =
|
|
21
|
+
this.cutoff = coerceFiniteNumber(cutoff, this.cutoff);
|
|
22
|
+
this.q = coerceFiniteNumber(q, this.q);
|
|
23
23
|
|
|
24
|
-
const mode =
|
|
24
|
+
const mode = coerceFiniteNumber(strictMode, this.strictMode);
|
|
25
25
|
this.strictMode = mode === StrictMode.Enabled ? StrictMode.Enabled : StrictMode.Disabled;
|
|
26
26
|
this.audioWorkletNode && this.registerMessageEventListener(this.audioWorkletNode);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
public async
|
|
29
|
+
public async initializeOnAttachment(context: AudioContext): Promise<void> {
|
|
30
30
|
|
|
31
31
|
this.context = context;
|
|
32
32
|
this.contextSampleRate = context.sampleRate;
|
|
33
|
-
this.audioWorkletNode =
|
|
33
|
+
this.audioWorkletNode = createAudioWorkletNode(context, AudioWorkletProcessorNames.NotchFilter, this.returnOptionsAsObject());
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
public
|
|
36
|
+
public returnOptionsAsObject(): NotchFilterOptions {
|
|
37
37
|
return {
|
|
38
38
|
cutoff: this.cutoff,
|
|
39
39
|
q: this.q,
|
|
@@ -42,40 +42,40 @@ export default class NotchFilter extends Effector {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
public
|
|
45
|
+
public setCutoff(cutoff: number = 1000): boolean {
|
|
46
46
|
|
|
47
47
|
if (!this.context) return false;
|
|
48
48
|
|
|
49
|
-
cutoff =
|
|
49
|
+
cutoff = coerceFiniteNumber(cutoff, this.cutoff);
|
|
50
50
|
cutoff = Math.min(this.minFrequency, cutoff);
|
|
51
51
|
|
|
52
52
|
if (cutoff >= this.context.sampleRate)
|
|
53
53
|
cutoff = this.context.sampleRate;
|
|
54
54
|
|
|
55
55
|
this.cutoff = cutoff;
|
|
56
|
-
return
|
|
56
|
+
return sendMessageToWorklet<NotchFilterMessageCommandId, number>(this.audioWorkletNode, NotchFilterMessageCommandId.SetCutoff, cutoff);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
public
|
|
59
|
+
public setMinFrequency(minFrequency: number = this.minFrequency) {
|
|
60
60
|
|
|
61
|
-
minFrequency =
|
|
61
|
+
minFrequency = coerceFiniteNumber(minFrequency, this.minFrequency);
|
|
62
62
|
|
|
63
63
|
if(minFrequency < 10)
|
|
64
64
|
minFrequency = 10;
|
|
65
65
|
|
|
66
66
|
this.minFrequency = minFrequency;
|
|
67
|
-
return
|
|
67
|
+
return sendMessageToWorklet<NotchFilterMessageCommandId.SetMinFrequency, number>(this.audioWorkletNode, NotchFilterMessageCommandId.SetMinFrequency, minFrequency);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
public
|
|
70
|
+
public setQ(q: number = 0.7): boolean {
|
|
71
71
|
|
|
72
|
-
q =
|
|
72
|
+
q = coerceFiniteNumber(q, this.q);
|
|
73
73
|
q = Math.max(0.0001, q);
|
|
74
74
|
|
|
75
75
|
if (q > 4)
|
|
76
76
|
q = 4;
|
|
77
77
|
|
|
78
78
|
this.q = q;
|
|
79
|
-
return
|
|
79
|
+
return sendMessageToWorklet<NotchFilterMessageCommandId, number>(this.audioWorkletNode, NotchFilterMessageCommandId.SetQ, q);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -7,6 +7,7 @@ export { Saturation } from "./classes/Saturation";
|
|
|
7
7
|
export { StereoPanner } from "./classes/StereoPanner";
|
|
8
8
|
export { SoftClip } from "./classes/clips/SoftClip";
|
|
9
9
|
export { HardClip } from "./classes/clips/HardClip";
|
|
10
|
+
export { Reverb, type ReverbOptions } from "./classes/Reverb";
|
|
10
11
|
|
|
11
12
|
export { Compressor } from "./classes/compressors/Compressor";
|
|
12
13
|
export { MultibandCompressor } from "./classes/compressors/MultibandCompressor";
|
|
@@ -16,11 +17,5 @@ export { MonoDelay } from "./classes/delays/MonoDelay";
|
|
|
16
17
|
export { PingPongDelay } from "./classes/delays/PingPongDelay";
|
|
17
18
|
export { StereoDelay } from "./classes/delays/StereoDelay";
|
|
18
19
|
|
|
19
|
-
export { ChamberReverb } from "./classes/reverbs/ChamberReverb";
|
|
20
|
-
export { ConvolverReverb } from "./classes/reverbs/ConvolverReverb";
|
|
21
|
-
export { GenericReverb } from "./classes/reverbs/GenericReverb";
|
|
22
|
-
export { HallReverb } from "./classes/reverbs/HallReverb";
|
|
23
|
-
export { RoomReverb } from "./classes/reverbs/RoomReverb";
|
|
24
|
-
|
|
25
20
|
export { LowPassFilter } from "./classes/filters/LowPassFilter";
|
|
26
21
|
export { HighPassFilter } from "./classes/filters/HighPassFilter";
|