@fluex/fluexgl-dsp 0.3.1 → 0.3.3

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.
@@ -22,29 +22,31 @@ export class Channel {
22
22
  }
23
23
  rebuildEffectChain() {
24
24
  Debug.Log("Attempting to rebuild effect chain.");
25
- if (!this.audioClipsInputGainNode || !this.gainNode)
26
- return Debug.Error("Could not rebuild effect chain, because one or more gain nodes on this channel are undefined.", [
25
+ if (!this.audioClipsInputGainNode || !this.stereoPannerNode) {
26
+ return Debug.Error("Could not rebuild effect chain, because one or more nodes on this channel are undefined.", [
27
27
  `Channel id: ${this.id}.`,
28
28
  `Current amount of effects: ${this.effects.length}.`
29
29
  ]);
30
+ }
30
31
  this.audioClipsInputGainNode.disconnect();
31
32
  for (const effect of this.effects) {
32
33
  effect.audioWorkletNode?.disconnect();
33
34
  }
34
- const activeEffects = this.effects.filter(e => !!e.audioWorkletNode);
35
+ const activeEffects = this.effects.filter(function (e) {
36
+ return !!e.audioWorkletNode;
37
+ });
35
38
  if (activeEffects.length === 0) {
36
- this.audioClipsInputGainNode.connect(this.gainNode);
39
+ this.audioClipsInputGainNode.connect(this.stereoPannerNode);
37
40
  }
38
41
  else {
39
- const firstEffectGain = activeEffects[0].audioWorkletNode;
40
- this.audioClipsInputGainNode.connect(firstEffectGain);
42
+ this.audioClipsInputGainNode.connect(activeEffects[0].audioWorkletNode);
41
43
  for (let i = 0; i < activeEffects.length - 1; i++) {
42
44
  const current = activeEffects[i].audioWorkletNode;
43
45
  const next = activeEffects[i + 1].audioWorkletNode;
44
46
  current.connect(next);
45
47
  }
46
- const lastEffectGain = activeEffects[activeEffects.length - 1].audioWorkletNode;
47
- lastEffectGain.connect(this.gainNode);
48
+ const lastEffectNode = activeEffects[activeEffects.length - 1].audioWorkletNode;
49
+ lastEffectNode.connect(this.stereoPannerNode);
48
50
  }
49
51
  Debug.Success("Successfully rebuilt effect chain.", [
50
52
  `Channel id: ${this.id}.`,
@@ -1,9 +1,18 @@
1
+ import { EffectorEventMap } from "../../typings";
1
2
  export declare abstract class Effector {
2
3
  id: string;
3
4
  label: string | null;
4
5
  name: string;
5
6
  audioWorkletNode: AudioWorkletNode | null;
6
7
  parentialContext: AudioContext | null;
8
+ private hasRegisteredMessageEventListener;
9
+ private events;
10
+ private handleIncomingMessages;
11
+ protected registerMessageEventListener(node: AudioWorkletNode): void;
12
+ AddEventListener<K extends keyof EffectorEventMap>(event: K, cb: EffectorEventMap[K]): () => void;
13
+ Once<K extends keyof EffectorEventMap>(event: K, cb: EffectorEventMap[K]): () => void;
14
+ RemoveEventListener<K extends keyof EffectorEventMap>(event: K, cb: EffectorEventMap[K]): Effector;
15
+ ClearEventListeners(event?: keyof EffectorEventMap): Effector;
7
16
  abstract InitializeOnAttachment(parentialContext: AudioContext): Promise<void>;
8
17
  }
9
18
  //# sourceMappingURL=Effector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Effector.d.ts","sourceRoot":"","sources":["../../../src/core/classes/Effector.ts"],"names":[],"mappings":"AAEA,8BAAsB,QAAQ;IAEnB,EAAE,EAAE,MAAM,CAAQ;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5B,IAAI,EAAE,MAAM,CAAc;IAC1B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IACjD,gBAAgB,EAAE,YAAY,GAAG,IAAI,CAAQ;aAEpC,sBAAsB,CAAC,gBAAgB,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CACxF"}
1
+ {"version":3,"file":"Effector.d.ts","sourceRoot":"","sources":["../../../src/core/classes/Effector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEhH,8BAAsB,QAAQ;IAEnB,EAAE,EAAE,MAAM,CAAQ;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5B,IAAI,EAAE,MAAM,CAAc;IAC1B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IACjD,gBAAgB,EAAE,YAAY,GAAG,IAAI,CAAQ;IAEpD,OAAO,CAAC,iCAAiC,CAAkB;IAE3D,OAAO,CAAC,MAAM,CAMb;IAED,OAAO,CAAC,sBAAsB;IAgB9B,SAAS,CAAC,4BAA4B,CAAC,IAAI,EAAE,gBAAgB;IAKtD,gBAAgB,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAOjG,IAAI,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAarF,mBAAmB,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,QAAQ;IAalG,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,gBAAgB,GAAG,QAAQ;aAWpD,sBAAsB,CAAC,gBAAgB,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CACxF"}
@@ -5,4 +5,60 @@ export class Effector {
5
5
  name = "Effector";
6
6
  audioWorkletNode = null;
7
7
  parentialContext = null;
8
+ hasRegisteredMessageEventListener = false;
9
+ events = {
10
+ "incoming-processor-error": [],
11
+ "incoming-processor-message": [],
12
+ "incoming-processor-warning": [],
13
+ "processor-wasm-instantiated": [],
14
+ "initialized-on-channel-attachment": []
15
+ };
16
+ handleIncomingMessages(event) {
17
+ const messageData = event.data;
18
+ switch (messageData.type) {
19
+ case "message":
20
+ return this.events["incoming-processor-message"].forEach(ev => ev(messageData));
21
+ case "error":
22
+ return this.events["incoming-processor-error"].forEach(ev => ev(messageData));
23
+ case "warning":
24
+ return this.events["incoming-processor-message"].forEach(ev => ev(messageData));
25
+ case "wasm-instantiated":
26
+ return this.events["processor-wasm-instantiated"].forEach(ev => ev(messageData));
27
+ }
28
+ }
29
+ registerMessageEventListener(node) {
30
+ if (!this.hasRegisteredMessageEventListener)
31
+ node.port.onmessage = this.handleIncomingMessages.bind(this);
32
+ }
33
+ AddEventListener(event, cb) {
34
+ this.events[event].push(cb);
35
+ return () => this.RemoveEventListener(event, cb);
36
+ }
37
+ Once(event, cb) {
38
+ const wrapper = ((...args) => {
39
+ // @ts-ignore
40
+ cb(...args);
41
+ this.RemoveEventListener(event, wrapper);
42
+ });
43
+ return this.AddEventListener(event, wrapper);
44
+ }
45
+ RemoveEventListener(event, cb) {
46
+ const arr = this.events[event];
47
+ for (let i = 0; i < arr.length; i++) {
48
+ if (arr[i] === cb) {
49
+ arr.splice(i, 1);
50
+ break;
51
+ }
52
+ }
53
+ return this;
54
+ }
55
+ ClearEventListeners(event) {
56
+ if (event) {
57
+ this.events[event].length = 0;
58
+ }
59
+ else {
60
+ Object.keys(this.events).forEach((k) => (this.events[k].length = 0));
61
+ }
62
+ return this;
63
+ }
8
64
  }
@@ -4,11 +4,13 @@ export declare class LowPassFilter extends Effector {
4
4
  name: string;
5
5
  label: string | null;
6
6
  cutoff: number;
7
+ q: number;
7
8
  minFrequency: number;
8
- constructor({ cutoff, minFrequency }: Partial<LowPassFilterOptions>);
9
+ constructor({ cutoff, minFrequency, q }: Partial<LowPassFilterOptions>);
9
10
  InitializeOnAttachment(parentialContext: AudioContext): Promise<void>;
10
11
  ReturnOptionsAsObject(): LowPassFilterOptions;
11
12
  SetCutoff(cutoff?: number): boolean;
12
13
  SetMinFrequency(minFrequency?: number): boolean;
14
+ SetQ(q?: number): boolean;
13
15
  }
14
16
  //# sourceMappingURL=LowPassFilter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LowPassFilter.d.ts","sourceRoot":"","sources":["../../../../src/effects/classes/filters/LowPassFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAI1D,OAAO,EAAE,oBAAoB,EAA6D,MAAM,kBAAkB,CAAC;AAEnH,qBAAa,aAAc,SAAQ,QAAQ;IAEhC,IAAI,EAAE,MAAM,CAAmB;IAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAmB;IAEvC,MAAM,EAAE,MAAM,CAAQ;IACtB,YAAY,EAAE,MAAM,CAAM;gBAErB,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAOtD,sBAAsB,CAAC,gBAAgB,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3E,qBAAqB,IAAI,oBAAoB;IAO7C,SAAS,CAAC,MAAM,GAAE,MAAa,GAAG,OAAO;IAWzC,eAAe,CAAC,YAAY,GAAE,MAAW,GAAG,OAAO;CAS7D"}
1
+ {"version":3,"file":"LowPassFilter.d.ts","sourceRoot":"","sources":["../../../../src/effects/classes/filters/LowPassFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAI1D,OAAO,EAAE,oBAAoB,EAA6D,MAAM,kBAAkB,CAAC;AAEnH,qBAAa,aAAc,SAAQ,QAAQ;IAEhC,IAAI,EAAE,MAAM,CAAmB;IAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAmB;IAEvC,MAAM,EAAE,MAAM,CAAQ;IACtB,CAAC,EAAE,MAAM,CAAO;IAChB,YAAY,EAAE,MAAM,CAAM;gBAErB,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAQzD,sBAAsB,CAAC,gBAAgB,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3E,qBAAqB,IAAI,oBAAoB;IAQ7C,SAAS,CAAC,MAAM,GAAE,MAAa,GAAG,OAAO;IAWzC,eAAe,CAAC,YAAY,GAAE,MAAW,GAAG,OAAO;IASnD,IAAI,CAAC,CAAC,GAAE,MAAY,GAAG,OAAO;CAQxC"}
@@ -4,24 +4,28 @@ import { LowPassFilterMessageCommandId, AudioWorkletProcessorNames } from "../..
4
4
  export class LowPassFilter extends Effector {
5
5
  name = "LowPassFilter";
6
6
  label = "LowPassFilter";
7
- cutoff = 4000;
7
+ cutoff = 1000;
8
+ q = 0.7;
8
9
  minFrequency = 10;
9
- constructor({ cutoff, minFrequency }) {
10
+ constructor({ cutoff, minFrequency, q }) {
10
11
  super();
11
12
  this.cutoff = cutoff ?? this.cutoff;
12
13
  this.minFrequency = minFrequency ?? this.minFrequency;
14
+ this.q = q ?? this.q;
13
15
  }
14
16
  async InitializeOnAttachment(parentialContext) {
15
17
  this.parentialContext = parentialContext;
16
18
  this.audioWorkletNode = CreateAudioWorkletNode(parentialContext, AudioWorkletProcessorNames.LowPassFilter, this.ReturnOptionsAsObject());
19
+ this.registerMessageEventListener(this.audioWorkletNode);
17
20
  }
18
21
  ReturnOptionsAsObject() {
19
22
  return {
20
23
  cutoff: this.cutoff,
21
- minFrequency: this.minFrequency
24
+ minFrequency: this.minFrequency,
25
+ q: this.q
22
26
  };
23
27
  }
24
- SetCutoff(cutoff = 4000) {
28
+ SetCutoff(cutoff = 1000) {
25
29
  if (!this.parentialContext)
26
30
  return false;
27
31
  if (cutoff >= this.parentialContext.sampleRate)
@@ -35,4 +39,10 @@ export class LowPassFilter extends Effector {
35
39
  this.minFrequency = minFrequency;
36
40
  return SendMessageToWorklet(this.audioWorkletNode, LowPassFilterMessageCommandId.SetMinFrequency, minFrequency);
37
41
  }
42
+ SetQ(q = 0.7) {
43
+ if (q > 4)
44
+ q = 4;
45
+ this.q = q;
46
+ return SendMessageToWorklet(this.audioWorkletNode, LowPassFilterMessageCommandId.SetQ, q);
47
+ }
38
48
  }
@@ -9,5 +9,5 @@ export { AudioDevice, Channel, Effector, Master, AudioClip, DspPipeline } from "
9
9
  export { InitializeDspPipeline, ResolveAudioOutputDevices, ResolveAudioInputDevices, ResolveDefaultAudioInputDevice, ResolveDefaultAudioOutputDevice, LoadAudioSource, LoadAudioSourceFromBlob, LoadWorkletOnMasterChannel, SendMessageToWorklet } from "./utilities/helpers";
10
10
  export { SUPPORTED_FILE_TYPES } from "./utilities/constants";
11
11
  export { hasInitializedWasm, } from "./utilities/web-assembly";
12
- export type { FluexGLAudioDescriptor, FluexGLAudioDebuggerOptions, FluexGLAudioOptions, LoadAudioSourceOptions, AudioSourceData, ChannelOptions, ChannelSpatialization, AudioClipEventMap, AudioClipEvents, AudioClipOnProgressEvent, AudioClipAnalyserProperty, AudioClipAnalyserType, DspPipelineInitializationOptions, DspPipelineInitializationState, ChorusEffectOptions, LowPassFilterOptions, LowPassFilterMessageCommandId, ChorusMessageCommandId, AudioWorkletProcessorNames, SoftClipMessageCommandId, SoftClipOptions, HardClipMessageCommandId, HardClipOptions } from "./typings";
12
+ export type { FluexGLAudioDescriptor, FluexGLAudioDebuggerOptions, FluexGLAudioOptions, LoadAudioSourceOptions, AudioSourceData, ChannelOptions, ChannelSpatialization, AudioClipEventMap, AudioClipEvents, AudioClipOnProgressEvent, AudioClipAnalyserProperty, AudioClipAnalyserType, DspPipelineInitializationOptions, DspPipelineInitializationState, ChorusEffectOptions, LowPassFilterOptions, LowPassFilterMessageCommandId, ChorusMessageCommandId, AudioWorkletProcessorNames, SoftClipMessageCommandId, SoftClipOptions, HardClipMessageCommandId, HardClipOptions, EffectorEventMap, IncomingMessageType, IncomingProcessorMessage, ProcessorData, ProcessorIdentificationCodes, EffectorEvents } from "./typings";
13
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEnD,eAAO,MAAM,YAAY,EAAE,sBAkB1B,CAAA;AAED,OAAO,EACH,MAAM,EACN,UAAU,EACV,SAAS,EACT,OAAO,EACP,UAAU,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,aAAa,EACb,WAAW,EACX,aAAa,EACb,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EACV,QAAQ,EACR,aAAa,EACb,QAAQ,EACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACH,WAAW,EACX,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,WAAW,EACd,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACH,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,8BAA8B,EAC9B,+BAA+B,EAC/B,eAAe,EACf,uBAAuB,EACvB,0BAA0B,EAC1B,oBAAoB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,oBAAoB,EACvB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACH,kBAAkB,GACrB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACR,sBAAsB,EACtB,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,gCAAgC,EAChC,8BAA8B,EAC9B,mBAAmB,EACnB,oBAAoB,EACpB,6BAA6B,EAC7B,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,eAAe,EACf,wBAAwB,EACxB,eAAe,EAClB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAEnD,eAAO,MAAM,YAAY,EAAE,sBAkB1B,CAAA;AAED,OAAO,EACH,MAAM,EACN,UAAU,EACV,SAAS,EACT,OAAO,EACP,UAAU,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,aAAa,EACb,WAAW,EACX,aAAa,EACb,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EACV,QAAQ,EACR,aAAa,EACb,QAAQ,EACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACH,WAAW,EACX,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,WAAW,EACd,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACH,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,8BAA8B,EAC9B,+BAA+B,EAC/B,eAAe,EACf,uBAAuB,EACvB,0BAA0B,EAC1B,oBAAoB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,oBAAoB,EACvB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACH,kBAAkB,GACrB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACR,sBAAsB,EACtB,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EACzB,qBAAqB,EACrB,gCAAgC,EAChC,8BAA8B,EAC9B,mBAAmB,EACnB,oBAAoB,EACpB,6BAA6B,EAC7B,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,aAAa,EACb,4BAA4B,EAC5B,cAAc,EACjB,MAAM,WAAW,CAAC"}
@@ -1,12 +1,17 @@
1
1
  export type ChannelSpatialization = "mono" | "stereo" | "surround";
2
2
  export type AudioClipAnalyserType = "pre" | "post";
3
3
  export type AudioClipAnalyserProperty = "fftSize" | "minDecibels" | "maxDecibels" | "smoothingTimeConstant";
4
+ export type IncomingMessageType = "message" | "error" | "warning" | "wasm-instantiated";
4
5
  export type AudioClipEvents = {
5
6
  [K in keyof AudioClipEventMap]: AudioClipEventMap[K][];
6
7
  };
8
+ export type EffectorEvents = {
9
+ [K in keyof EffectorEventMap]: EffectorEventMap[K][];
10
+ };
7
11
  export declare enum LowPassFilterMessageCommandId {
8
12
  SetCutoff = 0,
9
- SetMinFrequency = 1
13
+ SetMinFrequency = 1,
14
+ SetQ = 2
10
15
  }
11
16
  export declare enum ChorusMessageCommandId {
12
17
  SetBaseDelayMs = 0,
@@ -41,6 +46,11 @@ export declare enum AudioWorkletProcessorNames {
41
46
  SoftClip = "SoftClipProcessor",
42
47
  HardClip = "HardClipProcessor"
43
48
  }
49
+ export declare enum ProcessorIdentificationCodes {
50
+ UnknownProcessorId = "UNKNOWN_PROCESSOR_ID",
51
+ UnknownProcessorName = "UNKNOWN_PROCESSOR_NAME",
52
+ UnknownProcessorCreationDate = "UNKNOWN_PROCESSOR_CREATION_DATE"
53
+ }
44
54
  export interface FluexGLAudioDebuggerOptions {
45
55
  breakOnError: boolean;
46
56
  showInfo: boolean;
@@ -104,6 +114,7 @@ export interface ChorusEffectOptions {
104
114
  export interface LowPassFilterOptions {
105
115
  cutoff: number;
106
116
  minFrequency: number;
117
+ q: number;
107
118
  }
108
119
  export interface SoftClipOptions {
109
120
  drive: number;
@@ -113,4 +124,24 @@ export interface HardClipOptions {
113
124
  drive: number;
114
125
  gain: number;
115
126
  }
127
+ export interface EffectorEventMap {
128
+ "incoming-processor-message": (message: IncomingProcessorMessage) => void;
129
+ "incoming-processor-warning": (message: IncomingProcessorMessage) => void;
130
+ "incoming-processor-error": (message: IncomingProcessorMessage) => void;
131
+ "initialized-on-channel-attachment": (message: IncomingProcessorMessage) => void;
132
+ "processor-wasm-instantiated": (message: IncomingProcessorMessage) => void;
133
+ }
134
+ export interface ProcessorData {
135
+ id: string | ProcessorIdentificationCodes.UnknownProcessorId;
136
+ name: string | ProcessorIdentificationCodes.UnknownProcessorName;
137
+ createdAt: number | ProcessorIdentificationCodes.UnknownProcessorCreationDate;
138
+ }
139
+ export interface IncomingProcessorMessage {
140
+ id: string;
141
+ timestamp: number;
142
+ message: string;
143
+ type: IncomingMessageType;
144
+ processor: ProcessorData;
145
+ additionalData?: any;
146
+ }
116
147
  //# sourceMappingURL=typings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"typings.d.ts","sourceRoot":"","sources":["../src/typings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"typings.d.ts","sourceRoot":"","sources":["../src/typings.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- // ======== Audio worklet command id's ========
2
1
  export var LowPassFilterMessageCommandId;
3
2
  (function (LowPassFilterMessageCommandId) {
4
3
  LowPassFilterMessageCommandId[LowPassFilterMessageCommandId["SetCutoff"] = 0] = "SetCutoff";
5
4
  LowPassFilterMessageCommandId[LowPassFilterMessageCommandId["SetMinFrequency"] = 1] = "SetMinFrequency";
5
+ LowPassFilterMessageCommandId[LowPassFilterMessageCommandId["SetQ"] = 2] = "SetQ";
6
6
  })(LowPassFilterMessageCommandId || (LowPassFilterMessageCommandId = {}));
7
7
  export var ChorusMessageCommandId;
8
8
  (function (ChorusMessageCommandId) {
@@ -41,3 +41,9 @@ export var AudioWorkletProcessorNames;
41
41
  AudioWorkletProcessorNames["SoftClip"] = "SoftClipProcessor";
42
42
  AudioWorkletProcessorNames["HardClip"] = "HardClipProcessor";
43
43
  })(AudioWorkletProcessorNames || (AudioWorkletProcessorNames = {}));
44
+ export var ProcessorIdentificationCodes;
45
+ (function (ProcessorIdentificationCodes) {
46
+ ProcessorIdentificationCodes["UnknownProcessorId"] = "UNKNOWN_PROCESSOR_ID";
47
+ ProcessorIdentificationCodes["UnknownProcessorName"] = "UNKNOWN_PROCESSOR_NAME";
48
+ ProcessorIdentificationCodes["UnknownProcessorCreationDate"] = "UNKNOWN_PROCESSOR_CREATION_DATE";
49
+ })(ProcessorIdentificationCodes || (ProcessorIdentificationCodes = {}));
@@ -37,38 +37,38 @@ export class Channel {
37
37
  private rebuildEffectChain() {
38
38
  Debug.Log("Attempting to rebuild effect chain.");
39
39
 
40
- if (!this.audioClipsInputGainNode || !this.gainNode) return Debug.Error("Could not rebuild effect chain, because one or more gain nodes on this channel are undefined.", [
41
- `Channel id: ${this.id}.`,
42
- `Current amount of effects: ${this.effects.length}.`
43
- ]);
44
-
40
+ if (!this.audioClipsInputGainNode || !this.stereoPannerNode) {
41
+ return Debug.Error(
42
+ "Could not rebuild effect chain, because one or more nodes on this channel are undefined.",
43
+ [
44
+ `Channel id: ${this.id}.`,
45
+ `Current amount of effects: ${this.effects.length}.`
46
+ ]
47
+ );
48
+ }
45
49
  this.audioClipsInputGainNode.disconnect();
46
50
 
47
51
  for (const effect of this.effects) {
48
52
  effect.audioWorkletNode?.disconnect();
49
53
  }
50
54
 
51
- const activeEffects = this.effects.filter(e => !!e.audioWorkletNode);
55
+ const activeEffects = this.effects.filter(function (e) {
56
+ return !!e.audioWorkletNode;
57
+ });
52
58
 
53
59
  if (activeEffects.length === 0) {
54
-
55
- this.audioClipsInputGainNode.connect(this.gainNode);
60
+ this.audioClipsInputGainNode.connect(this.stereoPannerNode);
56
61
  } else {
57
-
58
- const firstEffectGain = activeEffects[0].audioWorkletNode!;
59
- this.audioClipsInputGainNode.connect(firstEffectGain);
62
+ this.audioClipsInputGainNode.connect(activeEffects[0].audioWorkletNode!);
60
63
 
61
64
  for (let i = 0; i < activeEffects.length - 1; i++) {
62
-
63
65
  const current = activeEffects[i].audioWorkletNode!;
64
66
  const next = activeEffects[i + 1].audioWorkletNode!;
65
-
66
67
  current.connect(next);
67
68
  }
68
69
 
69
- const lastEffectGain = activeEffects[activeEffects.length - 1].audioWorkletNode!;
70
-
71
- lastEffectGain.connect(this.gainNode);
70
+ const lastEffectNode = activeEffects[activeEffects.length - 1].audioWorkletNode!;
71
+ lastEffectNode.connect(this.stereoPannerNode);
72
72
  }
73
73
 
74
74
  Debug.Success("Successfully rebuilt effect chain.", [
@@ -258,7 +258,7 @@ export class Channel {
258
258
 
259
259
  public SetAnalyserOptions(options: AnalyserOptions): Channel | null {
260
260
 
261
- this.analyserOptions = {...options};
261
+ this.analyserOptions = { ...options };
262
262
 
263
263
  if (!this.analyserNode) return null;
264
264
 
@@ -1,12 +1,89 @@
1
1
  import { v4 } from "uuid";
2
2
 
3
+ import { IncomingProcessorMessage, IncomingMessageType, EffectorEvents, EffectorEventMap } from "../../typings";
4
+
3
5
  export abstract class Effector {
4
-
6
+
5
7
  public id: string = v4();
6
8
  public label: string | null = null;
7
9
  public name: string = "Effector";
8
10
  public audioWorkletNode: AudioWorkletNode | null = null;
9
11
  public parentialContext: AudioContext | null = null;
10
12
 
13
+ private hasRegisteredMessageEventListener: boolean = false;
14
+
15
+ private events: EffectorEvents = {
16
+ "incoming-processor-error": [],
17
+ "incoming-processor-message": [],
18
+ "incoming-processor-warning": [],
19
+ "processor-wasm-instantiated": [],
20
+ "initialized-on-channel-attachment": []
21
+ }
22
+
23
+ private handleIncomingMessages(event: MessageEvent) {
24
+
25
+ const messageData = event.data as IncomingProcessorMessage;
26
+
27
+ switch (messageData.type) {
28
+ case "message":
29
+ return this.events["incoming-processor-message"].forEach(ev => ev(messageData));
30
+ case "error":
31
+ return this.events["incoming-processor-error"].forEach(ev => ev(messageData));
32
+ case "warning":
33
+ return this.events["incoming-processor-message"].forEach(ev => ev(messageData));
34
+ case "wasm-instantiated":
35
+ return this.events["processor-wasm-instantiated"].forEach(ev => ev(messageData));
36
+ }
37
+ }
38
+
39
+ protected registerMessageEventListener(node: AudioWorkletNode) {
40
+ if (!this.hasRegisteredMessageEventListener)
41
+ node.port.onmessage = this.handleIncomingMessages.bind(this);
42
+ }
43
+
44
+ public AddEventListener<K extends keyof EffectorEventMap>(event: K, cb: EffectorEventMap[K]): () => void {
45
+
46
+ this.events[event].push(cb);
47
+
48
+ return () => this.RemoveEventListener(event, cb);
49
+ }
50
+
51
+ public Once<K extends keyof EffectorEventMap>(event: K, cb: EffectorEventMap[K]): () => void {
52
+
53
+ const wrapper = ((...args: unknown[]) => {
54
+
55
+ // @ts-ignore
56
+ cb(...args);
57
+
58
+ this.RemoveEventListener(event, wrapper as unknown as EffectorEventMap[K]);
59
+ }) as unknown as EffectorEventMap[K];
60
+
61
+ return this.AddEventListener(event, wrapper);
62
+ }
63
+
64
+ public RemoveEventListener<K extends keyof EffectorEventMap>(event: K, cb: EffectorEventMap[K]): Effector {
65
+
66
+ const arr = this.events[event];
67
+
68
+ for (let i = 0; i < arr.length; i++) {
69
+ if (arr[i] === cb) {
70
+ arr.splice(i, 1);
71
+ break;
72
+ }
73
+ }
74
+ return this;
75
+ }
76
+
77
+ public ClearEventListeners(event?: keyof EffectorEventMap): Effector {
78
+
79
+ if (event) {
80
+ this.events[event].length = 0;
81
+ } else {
82
+ (Object.keys(this.events) as (keyof EffectorEventMap)[]).forEach((k) => (this.events[k].length = 0));
83
+ }
84
+
85
+ return this;
86
+ }
87
+
11
88
  public abstract InitializeOnAttachment(parentialContext: AudioContext): Promise<void>;
12
- }
89
+ }
@@ -9,30 +9,34 @@ export class LowPassFilter extends Effector {
9
9
  public name: string = "LowPassFilter";
10
10
  public label: string | null = "LowPassFilter";
11
11
 
12
- public cutoff: number = 4000;
12
+ public cutoff: number = 1000;
13
+ public q: number = 0.7;
13
14
  public minFrequency: number = 10;
14
15
 
15
- constructor({ cutoff, minFrequency }: Partial<LowPassFilterOptions>) {
16
+ constructor({ cutoff, minFrequency, q }: Partial<LowPassFilterOptions>) {
16
17
  super();
17
18
 
18
19
  this.cutoff = cutoff ?? this.cutoff;
19
20
  this.minFrequency = minFrequency ?? this.minFrequency;
21
+ this.q = q ?? this.q;
20
22
  }
21
23
 
22
24
  public async InitializeOnAttachment(parentialContext: AudioContext): Promise<void> {
23
25
 
24
26
  this.parentialContext = parentialContext;
25
27
  this.audioWorkletNode = CreateAudioWorkletNode(parentialContext, AudioWorkletProcessorNames.LowPassFilter, this.ReturnOptionsAsObject());
28
+ this.registerMessageEventListener(this.audioWorkletNode as AudioWorkletNode);
26
29
  }
27
30
 
28
31
  public ReturnOptionsAsObject(): LowPassFilterOptions {
29
32
  return {
30
33
  cutoff: this.cutoff,
31
- minFrequency: this.minFrequency
34
+ minFrequency: this.minFrequency,
35
+ q: this.q
32
36
  }
33
37
  }
34
38
 
35
- public SetCutoff(cutoff: number = 4000): boolean {
39
+ public SetCutoff(cutoff: number = 1000): boolean {
36
40
 
37
41
  if (!this.parentialContext) return false;
38
42
 
@@ -45,11 +49,19 @@ export class LowPassFilter extends Effector {
45
49
 
46
50
  public SetMinFrequency(minFrequency: number = 10): boolean {
47
51
 
48
-
49
52
  if (minFrequency < 10)
50
53
  minFrequency = 10;
51
54
 
52
55
  this.minFrequency = minFrequency;
53
56
  return SendMessageToWorklet<LowPassFilterMessageCommandId, number>(this.audioWorkletNode, LowPassFilterMessageCommandId.SetMinFrequency, minFrequency);
54
57
  }
58
+
59
+ public SetQ(q: number = 0.7): boolean {
60
+
61
+ if(q > 4)
62
+ q = 4;
63
+
64
+ this.q = q;
65
+ return SendMessageToWorklet<LowPassFilterMessageCommandId, number>(this.audioWorkletNode, LowPassFilterMessageCommandId.SetQ, q);
66
+ }
55
67
  }
package/lib/src/index.ts CHANGED
@@ -100,5 +100,11 @@ export type {
100
100
  SoftClipMessageCommandId,
101
101
  SoftClipOptions,
102
102
  HardClipMessageCommandId,
103
- HardClipOptions
103
+ HardClipOptions,
104
+ EffectorEventMap,
105
+ IncomingMessageType,
106
+ IncomingProcessorMessage,
107
+ ProcessorData,
108
+ ProcessorIdentificationCodes,
109
+ EffectorEvents
104
110
  } from "./typings";
@@ -1,17 +1,20 @@
1
1
  export type ChannelSpatialization = "mono" | "stereo" | "surround";
2
-
3
2
  export type AudioClipAnalyserType = "pre" | "post";
4
3
  export type AudioClipAnalyserProperty = "fftSize" | "minDecibels" | "maxDecibels" | "smoothingTimeConstant";
4
+ export type IncomingMessageType = "message" | "error" | "warning" | "wasm-instantiated";
5
5
 
6
- export type AudioClipEvents = {
6
+ export type AudioClipEvents = {
7
7
  [K in keyof AudioClipEventMap]: AudioClipEventMap[K][];
8
8
  }
9
9
 
10
- // ======== Audio worklet command id's ========
10
+ export type EffectorEvents = {
11
+ [K in keyof EffectorEventMap]: EffectorEventMap[K][];
12
+ }
11
13
 
12
14
  export enum LowPassFilterMessageCommandId {
13
15
  SetCutoff,
14
- SetMinFrequency
16
+ SetMinFrequency,
17
+ SetQ
15
18
  }
16
19
 
17
20
  export enum ChorusMessageCommandId {
@@ -51,6 +54,12 @@ export enum AudioWorkletProcessorNames {
51
54
  HardClip = "HardClipProcessor"
52
55
  }
53
56
 
57
+ export enum ProcessorIdentificationCodes {
58
+ UnknownProcessorId = "UNKNOWN_PROCESSOR_ID",
59
+ UnknownProcessorName = "UNKNOWN_PROCESSOR_NAME",
60
+ UnknownProcessorCreationDate = "UNKNOWN_PROCESSOR_CREATION_DATE"
61
+ }
62
+
54
63
  export interface FluexGLAudioDebuggerOptions {
55
64
  breakOnError: boolean;
56
65
  showInfo: boolean;
@@ -121,12 +130,13 @@ export interface ChorusEffectOptions {
121
130
  depthMs: number;
122
131
  rateHz: number;
123
132
  mix: number;
124
- feedback: number;
133
+ feedback: number;
125
134
  }
126
135
 
127
136
  export interface LowPassFilterOptions {
128
137
  cutoff: number;
129
138
  minFrequency: number;
139
+ q: number;
130
140
  }
131
141
 
132
142
  export interface SoftClipOptions {
@@ -137,4 +147,27 @@ export interface SoftClipOptions {
137
147
  export interface HardClipOptions {
138
148
  drive: number;
139
149
  gain: number;
150
+ }
151
+
152
+ export interface EffectorEventMap {
153
+ "incoming-processor-message": (message: IncomingProcessorMessage) => void;
154
+ "incoming-processor-warning": (message: IncomingProcessorMessage) => void;
155
+ "incoming-processor-error": (message: IncomingProcessorMessage) => void;
156
+ "initialized-on-channel-attachment": (message: IncomingProcessorMessage) => void;
157
+ "processor-wasm-instantiated": (message: IncomingProcessorMessage) => void;
158
+ }
159
+
160
+ export interface ProcessorData {
161
+ id: string | ProcessorIdentificationCodes.UnknownProcessorId;
162
+ name: string | ProcessorIdentificationCodes.UnknownProcessorName;
163
+ createdAt: number | ProcessorIdentificationCodes.UnknownProcessorCreationDate;
164
+ }
165
+
166
+ export interface IncomingProcessorMessage {
167
+ id: string;
168
+ timestamp: number;
169
+ message: string;
170
+ type: IncomingMessageType;
171
+ processor: ProcessorData;
172
+ additionalData?: any;
140
173
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluex/fluexgl-dsp",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "An open-source, web-based DSP library developed alongside FluexGL, designed for creating and manipulating sounds in various contexts.",
5
5
  "main": "lib/dist/index.js",
6
6
  "types": "lib/dist/index.d.ts",