@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.
Files changed (95) hide show
  1. package/README.md +7 -7
  2. package/lib/dist/console-codes.d.ts +2 -1
  3. package/lib/dist/console-codes.d.ts.map +1 -1
  4. package/lib/dist/console-codes.js +1 -0
  5. package/lib/dist/core/classes/AudioClip.d.ts +26 -17
  6. package/lib/dist/core/classes/AudioClip.d.ts.map +1 -1
  7. package/lib/dist/core/classes/AudioClip.js +124 -51
  8. package/lib/dist/core/classes/AudioClipPlayer.d.ts +8 -8
  9. package/lib/dist/core/classes/AudioClipPlayer.d.ts.map +1 -1
  10. package/lib/dist/core/classes/AudioClipPlayer.js +22 -24
  11. package/lib/dist/core/classes/AudioDevice.d.ts +46 -5
  12. package/lib/dist/core/classes/AudioDevice.d.ts.map +1 -1
  13. package/lib/dist/core/classes/AudioDevice.js +47 -6
  14. package/lib/dist/core/classes/Channel.d.ts +20 -20
  15. package/lib/dist/core/classes/Channel.d.ts.map +1 -1
  16. package/lib/dist/core/classes/Channel.js +42 -42
  17. package/lib/dist/core/classes/DpsPipeline.d.ts +6 -6
  18. package/lib/dist/core/classes/DpsPipeline.d.ts.map +1 -1
  19. package/lib/dist/core/classes/DpsPipeline.js +18 -18
  20. package/lib/dist/core/classes/Effector.d.ts +5 -5
  21. package/lib/dist/core/classes/Effector.d.ts.map +1 -1
  22. package/lib/dist/core/classes/Effector.js +8 -8
  23. package/lib/dist/core/classes/Master.d.ts +6 -6
  24. package/lib/dist/core/classes/Master.d.ts.map +1 -1
  25. package/lib/dist/core/classes/Master.js +18 -18
  26. package/lib/dist/effects/classes/Analyser.d.ts +6 -6
  27. package/lib/dist/effects/classes/Analyser.d.ts.map +1 -1
  28. package/lib/dist/effects/classes/Analyser.js +7 -7
  29. package/lib/dist/effects/classes/Chorus.d.ts +7 -7
  30. package/lib/dist/effects/classes/Chorus.d.ts.map +1 -1
  31. package/lib/dist/effects/classes/Chorus.js +25 -25
  32. package/lib/dist/effects/classes/Distortion.d.ts +1 -1
  33. package/lib/dist/effects/classes/Distortion.d.ts.map +1 -1
  34. package/lib/dist/effects/classes/Distortion.js +1 -1
  35. package/lib/dist/effects/classes/Reverb.d.ts +32 -0
  36. package/lib/dist/effects/classes/Reverb.d.ts.map +1 -0
  37. package/lib/dist/effects/classes/Reverb.js +61 -0
  38. package/lib/dist/effects/classes/clips/HardClip.d.ts +5 -5
  39. package/lib/dist/effects/classes/clips/HardClip.d.ts.map +1 -1
  40. package/lib/dist/effects/classes/clips/HardClip.js +14 -14
  41. package/lib/dist/effects/classes/clips/SoftClip.d.ts +4 -4
  42. package/lib/dist/effects/classes/clips/SoftClip.d.ts.map +1 -1
  43. package/lib/dist/effects/classes/clips/SoftClip.js +13 -13
  44. package/lib/dist/effects/classes/filters/HighPassFilter.d.ts +5 -5
  45. package/lib/dist/effects/classes/filters/HighPassFilter.d.ts.map +1 -1
  46. package/lib/dist/effects/classes/filters/HighPassFilter.js +16 -16
  47. package/lib/dist/effects/classes/filters/LowPassFilter.d.ts +5 -5
  48. package/lib/dist/effects/classes/filters/LowPassFilter.d.ts.map +1 -1
  49. package/lib/dist/effects/classes/filters/LowPassFilter.js +17 -17
  50. package/lib/dist/effects/classes/filters/NotchFilter.d.ts +5 -5
  51. package/lib/dist/effects/classes/filters/NotchFilter.d.ts.map +1 -1
  52. package/lib/dist/effects/classes/filters/NotchFilter.js +16 -16
  53. package/lib/dist/effects/exports.d.ts +1 -5
  54. package/lib/dist/effects/exports.d.ts.map +1 -1
  55. package/lib/dist/effects/exports.js +1 -5
  56. package/lib/dist/index.d.ts +2 -2
  57. package/lib/dist/index.d.ts.map +1 -1
  58. package/lib/dist/index.js +2 -2
  59. package/lib/dist/typings.d.ts +11 -0
  60. package/lib/dist/typings.d.ts.map +1 -1
  61. package/lib/dist/utilities/debugger.d.ts +4 -4
  62. package/lib/dist/utilities/debugger.js +8 -8
  63. package/lib/dist/utilities/helpers.d.ts +13 -13
  64. package/lib/dist/utilities/helpers.d.ts.map +1 -1
  65. package/lib/dist/utilities/helpers.js +45 -59
  66. package/lib/dist/utilities/web-assembly.js +1 -1
  67. package/lib/src/console-codes.ts +2 -1
  68. package/lib/src/core/classes/AudioClip.ts +154 -60
  69. package/lib/src/core/classes/AudioClipPlayer.ts +22 -24
  70. package/lib/src/core/classes/AudioDevice.ts +49 -6
  71. package/lib/src/core/classes/Channel.ts +42 -42
  72. package/lib/src/core/classes/DpsPipeline.ts +19 -19
  73. package/lib/src/core/classes/Effector.ts +9 -9
  74. package/lib/src/core/classes/Master.ts +18 -18
  75. package/lib/src/effects/classes/Analyser.ts +7 -7
  76. package/lib/src/effects/classes/Chorus.ts +25 -25
  77. package/lib/src/effects/classes/Distortion.ts +1 -1
  78. package/lib/src/effects/classes/Reverb.ts +81 -0
  79. package/lib/src/effects/classes/clips/HardClip.ts +14 -14
  80. package/lib/src/effects/classes/clips/SoftClip.ts +13 -13
  81. package/lib/src/effects/classes/filters/HighPassFilter.ts +16 -16
  82. package/lib/src/effects/classes/filters/LowPassFilter.ts +17 -17
  83. package/lib/src/effects/classes/filters/NotchFilter.ts +16 -16
  84. package/lib/src/effects/exports.ts +1 -6
  85. package/lib/src/index.ts +11 -15
  86. package/lib/src/typings.ts +13 -0
  87. package/lib/src/utilities/debugger.ts +4 -4
  88. package/lib/src/utilities/helpers.ts +47 -60
  89. package/lib/src/utilities/web-assembly.ts +1 -1
  90. package/package.json +3 -2
  91. package/lib/src/effects/classes/reverbs/ChamberReverb.ts +0 -1
  92. package/lib/src/effects/classes/reverbs/ConvolverReverb.ts +0 -1
  93. package/lib/src/effects/classes/reverbs/GenericReverb.ts +0 -1
  94. package/lib/src/effects/classes/reverbs/HallReverb.ts +0 -1
  95. package/lib/src/effects/classes/reverbs/RoomReverb.ts +0 -1
package/README.md CHANGED
@@ -30,14 +30,14 @@ import { DspPipeline, Channel, LoadAudioSource, AudioClip } from "@fluex/fluexgl
30
30
  pathToWorklet: "/data/fluexgl-dsp-processor.worklet"
31
31
  });
32
32
 
33
- await pipeline.InitializeDpsPipeline();
33
+ await pipeline.initializeDpsPipeline();
34
34
 
35
- const audioDevice = await pipeline.ResolveDefaultAudioOutputDevice();
35
+ const audioDevice = await pipeline.resolveDefaultAudioOutputDevice();
36
36
 
37
37
  if(!audioDevice) return;
38
38
 
39
- const master = audioDevice.GetMasterChannel();
40
- const context = audioDevice.GetContext();
39
+ const master = audioDevice.getMasterChannel();
40
+ const context = audioDevice.getContext();
41
41
 
42
42
  const audioSource = await LoadAudioSource("/music.mp3");
43
43
 
@@ -46,11 +46,11 @@ import { DspPipeline, Channel, LoadAudioSource, AudioClip } from "@fluex/fluexgl
46
46
  const audioClip = new AudioClip(audioSource);
47
47
  const channel = new Channel(context);
48
48
 
49
- channel.Send(master);
50
- audioClip.Send(channel);
49
+ channel.send(master);
50
+ audioClip.send(channel);
51
51
 
52
52
  button.addEventListener("click", function() {
53
- audioClip.Play();
53
+ audioClip.play();
54
54
  });
55
55
  })();
56
56
  ```
@@ -19,7 +19,8 @@ export declare enum ErrorCodes {
19
19
  AUDIO_CLIP_ALREADY_ATTACHED = "ERROR:FLUEXGL-DSP@0018",
20
20
  AUDIO_CLIP_NOT_FOUND = "ERROR:FLUEXGL-DSP@0019",
21
21
  AUDIO_CLIP_PLAYER_NO_CONTEXT = "ERROR:FLUEXGL-DSP@0020",
22
- PANNING_OUT_OF_RANGE = "ERROR:FLUEXGL-DSP@0021"
22
+ PANNING_OUT_OF_RANGE = "ERROR:FLUEXGL-DSP@0021",
23
+ PITCH_OUT_OF_RANGE = "ERROR:FLUEXGL-DSP@0022"
23
24
  }
24
25
  export declare enum WarningCodes {
25
26
  NO_DEFAULT_AUDIO_DEVICE_FOUND = "WARNING:FLUEXGL-DSP@0001"
@@ -1 +1 @@
1
- {"version":3,"file":"console-codes.d.ts","sourceRoot":"","sources":["../src/console-codes.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IAClB,qBAAqB,2BAA2B;IAChD,kBAAkB,2BAA2B;IAC7C,sBAAsB,2BAA2B;IACjD,mBAAmB,2BAA2B;IAC9C,iCAAiC,2BAA2B;IAC5D,2BAA2B,2BAA2B;IACtD,sBAAsB,2BAA2B;IACjD,mCAAmC,2BAA2B;IAC9D,uBAAuB,2BAA2B;IAClD,gBAAgB,2BAA2B;IAC3C,wBAAwB,2BAA2B;IACnD,iBAAiB,2BAA2B;IAC5C,6BAA6B,2BAA2B;IACxD,uBAAuB,2BAA2B;IAClD,8BAA8B,2BAA2B;IACzD,sBAAsB,2BAA2B;IACjD,8BAA8B,2BAA2B;IACzD,2BAA2B,2BAA2B;IACtD,oBAAoB,2BAA2B;IAC/C,4BAA4B,2BAA2B;IACvD,oBAAoB,2BAA2B;CAClD;AAED,oBAAY,YAAY;IACpB,6BAA6B,6BAA6B;CAC7D;AAED,oBAAY,YAAY;CAEvB"}
1
+ {"version":3,"file":"console-codes.d.ts","sourceRoot":"","sources":["../src/console-codes.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IAClB,qBAAqB,2BAA2B;IAChD,kBAAkB,2BAA2B;IAC7C,sBAAsB,2BAA2B;IACjD,mBAAmB,2BAA2B;IAC9C,iCAAiC,2BAA2B;IAC5D,2BAA2B,2BAA2B;IACtD,sBAAsB,2BAA2B;IACjD,mCAAmC,2BAA2B;IAC9D,uBAAuB,2BAA2B;IAClD,gBAAgB,2BAA2B;IAC3C,wBAAwB,2BAA2B;IACnD,iBAAiB,2BAA2B;IAC5C,6BAA6B,2BAA2B;IACxD,uBAAuB,2BAA2B;IAClD,8BAA8B,2BAA2B;IACzD,sBAAsB,2BAA2B;IACjD,8BAA8B,2BAA2B;IACzD,2BAA2B,2BAA2B;IACtD,oBAAoB,2BAA2B;IAC/C,4BAA4B,2BAA2B;IACvD,oBAAoB,2BAA2B;IAC/C,kBAAkB,2BAA2B;CAChD;AAED,oBAAY,YAAY;IACpB,6BAA6B,6BAA6B;CAC7D;AAED,oBAAY,YAAY;CAEvB"}
@@ -21,6 +21,7 @@ export var ErrorCodes;
21
21
  ErrorCodes["AUDIO_CLIP_NOT_FOUND"] = "ERROR:FLUEXGL-DSP@0019";
22
22
  ErrorCodes["AUDIO_CLIP_PLAYER_NO_CONTEXT"] = "ERROR:FLUEXGL-DSP@0020";
23
23
  ErrorCodes["PANNING_OUT_OF_RANGE"] = "ERROR:FLUEXGL-DSP@0021";
24
+ ErrorCodes["PITCH_OUT_OF_RANGE"] = "ERROR:FLUEXGL-DSP@0022";
24
25
  })(ErrorCodes || (ErrorCodes = {}));
25
26
  export var WarningCodes;
26
27
  (function (WarningCodes) {
@@ -11,6 +11,9 @@ export declare class AudioClip {
11
11
  startTime: number;
12
12
  offsetAtStart: number;
13
13
  playbackRate: number;
14
+ pitch: number;
15
+ minPitchSemitones: number;
16
+ maxPitchSemitones: number;
14
17
  progressUpdateSpeed: number;
15
18
  gainNode: GainNode | null;
16
19
  stereoPannerNode: StereoPannerNode | null;
@@ -18,30 +21,36 @@ export declare class AudioClip {
18
21
  audioClipPlayer: AudioClipPlayer | null;
19
22
  private audioBufferSourceNodes;
20
23
  private maxAudioBufferSourceNodes;
24
+ private audioClipPlayers;
21
25
  private progressInterval;
22
26
  private events;
23
27
  constructor(data: AudioSourceData);
24
28
  private createBufferSource;
25
29
  private connectSourcesTo;
26
30
  private safeDisconnect;
31
+ private getOutputNodes;
27
32
  private rebuildNodeChain;
28
- Initialize(audioClipPlayer: AudioClipPlayer): void;
29
- Play(timestamp?: number, offset?: number): void | this | null;
30
- Seek(seconds: number): void | this;
31
- Stop(): AudioClip | null;
32
- SetVolume(volume: number): AudioClip;
33
- SetPanLevel(panLevel: number): AudioClip;
34
- Loop(loop?: boolean): AudioClip;
35
- SetMaxAudioBufferSourceNodes(value: number): AudioClip;
36
- DisconnectAllAudioBufferSourceNodes(): boolean;
37
- AddEventListener<K extends keyof AudioClipEventMap>(event: K, cb: AudioClipEventMap[K]): () => void;
38
- Once<K extends keyof AudioClipEventMap>(event: K, cb: AudioClipEventMap[K]): () => void;
39
- RemoveEventListener<K extends keyof AudioClipEventMap>(event: K, cb: AudioClipEventMap[K]): AudioClip;
40
- ClearEventListeners(event?: keyof AudioClipEventMap): AudioClip;
41
- GetChannelData(channel?: number): Float32Array;
42
- Send(channel: Channel | Master): void;
43
- Unsend(channel: Channel | Master): void;
44
- SetPlaybackRateInSemitones(semitones: number): AudioClip;
33
+ initialize(audioClipPlayer: AudioClipPlayer): void;
34
+ play(timestamp?: number, offset?: number): void | this | null;
35
+ seek(seconds: number): void | this;
36
+ stop(): AudioClip | null;
37
+ setVolume(volume: number): AudioClip;
38
+ setPanLevel(panLevel: number): AudioClip;
39
+ setLoop(loop?: boolean): AudioClip;
40
+ setMaxAudioBufferSourceNodes(value: number): AudioClip;
41
+ disconnectAllAudioBufferSourceNodes(): boolean;
42
+ addEventListener<K extends keyof AudioClipEventMap>(event: K, cb: AudioClipEventMap[K]): () => void;
43
+ once<K extends keyof AudioClipEventMap>(event: K, cb: AudioClipEventMap[K]): () => void;
44
+ removeEventListener<K extends keyof AudioClipEventMap>(event: K, cb: AudioClipEventMap[K]): AudioClip;
45
+ clearEventListeners(event?: keyof AudioClipEventMap): AudioClip;
46
+ getChannelData(channel?: number): Float32Array;
47
+ send(channel: Channel | Master): void;
48
+ unsend(channel: Channel | Master): void;
49
+ detachFromAudioClipPlayer(audioClipPlayer: AudioClipPlayer): void;
50
+ setPitch(semitones: number): AudioClip;
51
+ resetPitch(): AudioClip;
52
+ /** @deprecated Use {@link setPitch} instead. */
53
+ setPlaybackRateInSemitones(semitones: number): AudioClip;
45
54
  get currentPlaybackTime(): number;
46
55
  get duration(): number;
47
56
  get volume(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"AudioClip.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClip.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAmB,eAAe,EAAE,MAAM,eAAe,CAAC;AAEpF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMlC,qBAAa,SAAS;IA4BC,IAAI,EAAE,eAAe;IA1BjC,EAAE,EAAE,MAAM,CAAQ;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE5B,IAAI,EAAE,OAAO,CAAS;IACtB,SAAS,EAAE,OAAO,CAAS;IAC3B,SAAS,EAAE,MAAM,CAAK;IACtB,aAAa,EAAE,MAAM,CAAK;IAC1B,YAAY,EAAE,MAAM,CAAK;IAEzB,mBAAmB,EAAE,MAAM,CAAM;IAEjC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAQ;IACjC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAEjD,OAAO,EAAE,YAAY,GAAG,IAAI,CAAQ;IACpC,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAEtD,OAAO,CAAC,sBAAsB,CAA+B;IAC7D,OAAO,CAAC,yBAAyB,CAAa;IAE9C,OAAO,CAAC,gBAAgB,CAAoB;IAE5C,OAAO,CAAC,MAAM,CAEb;gBAEkB,IAAI,EAAE,eAAe;IAExC,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;IAmBjB,UAAU,CAAC,eAAe,EAAE,eAAe;IAc3C,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAqExC,IAAI,CAAC,OAAO,EAAE,MAAM;IAsBpB,IAAI,IAAI,SAAS,GAAG,IAAI;IAkBxB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAUpC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS;IAexC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS;IAU/B,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS;IAatD,mCAAmC,IAAI,OAAO;IAc9C,gBAAgB,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAMnG,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAYvF,mBAAmB,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,SAAS;IAarG,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS;IAW/D,cAAc,CAAC,OAAO,GAAE,MAAU,GAAG,YAAY;IAIjD,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAW9B,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAWhC,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;IAe/D,IAAW,mBAAmB,IAAI,MAAM,CAIvC;IAED,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,aAAa,IAAI,MAAM,CAEjC;IAED,IAAW,iBAAiB,IAAI,MAAM,CAKrC;IAED,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED,IAAW,gBAAgB,IAAI,MAAM,CAEpC;IAED,IAAW,UAAU,IAAI,MAAM,CAE9B;CACJ"}
1
+ {"version":3,"file":"AudioClip.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClip.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,9 @@ export class AudioClip {
12
12
  startTime = 0;
13
13
  offsetAtStart = 0;
14
14
  playbackRate = 1;
15
+ pitch = 0;
16
+ minPitchSemitones = -24;
17
+ maxPitchSemitones = 24;
15
18
  progressUpdateSpeed = 20;
16
19
  gainNode = null;
17
20
  stereoPannerNode = null;
@@ -19,9 +22,12 @@ export class AudioClip {
19
22
  audioClipPlayer = null;
20
23
  audioBufferSourceNodes = [];
21
24
  maxAudioBufferSourceNodes = 1;
25
+ audioClipPlayers = [];
22
26
  progressInterval = 0;
23
27
  events = {
24
- "progress": []
28
+ "progress": [],
29
+ "initialize": [],
30
+ "play": []
25
31
  };
26
32
  constructor(data) {
27
33
  this.data = data;
@@ -45,42 +51,74 @@ export class AudioClip {
45
51
  safeDisconnect(node) {
46
52
  node?.disconnect();
47
53
  }
54
+ getOutputNodes() {
55
+ const nodes = [];
56
+ for (const player of this.audioClipPlayers) {
57
+ if (player.outputGainNode && !nodes.includes(player.outputGainNode))
58
+ nodes.push(player.outputGainNode);
59
+ }
60
+ return nodes;
61
+ }
48
62
  rebuildNodeChain() {
49
- if (!this.context || !this.gainNode || !this.stereoPannerNode || !this.audioClipPlayer || !this.audioClipPlayer.outputGainNode) {
50
- Debug.Error("Failed to rebuild node chain, because some of the core AudioNodes are missing.");
63
+ if (!this.context || !this.gainNode || !this.stereoPannerNode) {
64
+ Debug.error("Failed to rebuild node chain, because some of the core AudioNodes are missing.");
65
+ return false;
66
+ }
67
+ const destinations = this.getOutputNodes();
68
+ if (destinations.length === 0) {
69
+ Debug.error("Failed to rebuild node chain, because no output destinations are available.");
51
70
  return false;
52
71
  }
53
- const destination = this.audioClipPlayer.outputGainNode;
54
72
  this.safeDisconnect(this.gainNode);
55
73
  this.safeDisconnect(this.stereoPannerNode);
56
74
  this.gainNode.connect(this.stereoPannerNode);
57
- this.stereoPannerNode.connect(destination);
75
+ for (const destination of destinations) {
76
+ this.stereoPannerNode.connect(destination);
77
+ }
58
78
  this.connectSourcesTo(this.gainNode);
59
79
  return true;
60
80
  }
61
- Initialize(audioClipPlayer) {
81
+ initialize(audioClipPlayer) {
82
+ const startTimestamp = Date.now(), self = this;
62
83
  if (!audioClipPlayer.context)
63
- return Debug.Error("Could not initialize AudioClip, because the AudioClipPlayer somehow has no audio context.", [
84
+ return Debug.error("Could not initialize AudioClip, because the AudioClipPlayer somehow has no audio context.", [
64
85
  `AudioClipPlayer id: ${audioClipPlayer.id}`,
65
86
  `AudioClip id: ${this.id}`
66
87
  ], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
88
+ if (this.context && this.context !== audioClipPlayer.context) {
89
+ return Debug.error("Could not initialize AudioClip, because the AudioClipPlayer does not share the same AudioContext.", [
90
+ `AudioClipPlayer id: ${audioClipPlayer.id}`,
91
+ `AudioClip id: ${this.id}`
92
+ ], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
93
+ }
67
94
  this.audioClipPlayer = audioClipPlayer;
68
95
  this.context = audioClipPlayer.context;
69
- this.gainNode = new GainNode(this.context);
70
- this.stereoPannerNode = new StereoPannerNode(this.context);
96
+ if (!this.gainNode)
97
+ this.gainNode = new GainNode(this.context);
98
+ if (!this.stereoPannerNode)
99
+ this.stereoPannerNode = new StereoPannerNode(this.context);
100
+ if (!this.audioClipPlayers.includes(audioClipPlayer))
101
+ this.audioClipPlayers.push(audioClipPlayer);
102
+ const endTimestamp = Date.now(), difference = endTimestamp - startTimestamp;
103
+ this.events.initialize.forEach(function (cb) {
104
+ cb({
105
+ durationOfInitialization: difference,
106
+ context: self.context
107
+ });
108
+ });
109
+ this.rebuildNodeChain();
71
110
  }
72
- Play(timestamp, offset) {
111
+ play(timestamp, offset) {
73
112
  if (!this.context)
74
- return Debug.Error("Could not play audio clip, because context (AudioContext) is undefined.", [
75
- "Make sure to attach this AudioClip to an AudioClipPlayer instance, before calling .Play on this AudioClip."
113
+ return Debug.error("Could not play audio clip, because context (AudioContext) is undefined.", [
114
+ "Make sure to attach this AudioClip to an AudioClipPlayer instance, before calling .play on this AudioClip."
76
115
  ]);
77
- const context = this.context;
78
- const self = this;
116
+ const context = this.context, self = this;
79
117
  if (this.audioBufferSourceNodes.length > this.maxAudioBufferSourceNodes - 1)
80
118
  return null;
81
119
  const bufferSource = this.createBufferSource();
82
120
  if (!bufferSource) {
83
- Debug.Error("Something went wrong.");
121
+ Debug.error("Something went wrong.");
84
122
  return null;
85
123
  }
86
124
  const actualOffset = offset ?? this.offsetAtStart ?? 0;
@@ -118,12 +156,19 @@ export class AudioClip {
118
156
  this.audioBufferSourceNodes.push(bufferSource);
119
157
  this.rebuildNodeChain();
120
158
  bufferSource.start(timestamp ?? this.startTime, actualOffset);
159
+ this.events.play.forEach(function (cb) {
160
+ cb({
161
+ timestamp: Date.now(),
162
+ audioBufferSourceNodes: self.audioBufferSourceNodes,
163
+ context: context,
164
+ });
165
+ });
121
166
  return this;
122
167
  }
123
- Seek(seconds) {
168
+ seek(seconds) {
124
169
  if (!this.context)
125
- return Debug.Error("Could not seek because the context (AudioContext) of this AudioClip is undefined.", [
126
- `Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .Seek on this AudioClip.`,
170
+ return Debug.error("Could not seek because the context (AudioContext) of this AudioClip is undefined.", [
171
+ `Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .seek on this AudioClip.`,
127
172
  `AudioClip id: ${this.id}`
128
173
  ]);
129
174
  const clamped = Math.max(0, Math.min(seconds, this.duration));
@@ -131,11 +176,11 @@ export class AudioClip {
131
176
  this.offsetAtStart = clamped;
132
177
  return this;
133
178
  }
134
- this.Stop();
135
- this.Play(undefined, clamped);
179
+ this.stop();
180
+ this.play(undefined, clamped);
136
181
  return this;
137
182
  }
138
- Stop() {
183
+ stop() {
139
184
  this.audioBufferSourceNodes.forEach(function (node) {
140
185
  node.stop();
141
186
  node.disconnect();
@@ -148,37 +193,37 @@ export class AudioClip {
148
193
  }
149
194
  return this;
150
195
  }
151
- SetVolume(volume) {
196
+ setVolume(volume) {
152
197
  if (!this.context)
153
- Debug.Error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
154
- "Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetVolume() on this AudioClip.",
198
+ Debug.error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
199
+ "Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .setVolume() on this AudioClip.",
155
200
  ], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
156
201
  this.gainNode?.gain.setValueAtTime(volume, this.context?.currentTime ?? 0);
157
202
  return this;
158
203
  }
159
- SetPanLevel(panLevel) {
204
+ setPanLevel(panLevel) {
160
205
  if (!this.context)
161
- Debug.Error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
162
- "Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .SetPanLevel() on this AudioClip.",
206
+ Debug.error("Could not set volume because the context (AudioContext) of this AudioClip is undefined.", [
207
+ "Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .setPanLevel() on this AudioClip.",
163
208
  ], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
164
209
  if (panLevel < -1 || panLevel > 1)
165
- Debug.Error("Could not set the pan level because it is not between -1 and 1.", [
210
+ Debug.error("Could not set the pan level because it is not between -1 and 1.", [
166
211
  `Given value: ${panLevel}.`,
167
212
  `Accepts a value between -1 and 1. Can be a floating number.`
168
213
  ], ErrorCodes.PANNING_OUT_OF_RANGE);
169
214
  this.stereoPannerNode?.pan.setValueAtTime(panLevel, this.context?.currentTime ?? 0);
170
215
  return this;
171
216
  }
172
- Loop(loop) {
217
+ setLoop(loop) {
173
218
  this.audioBufferSourceNodes.forEach(function (node) {
174
219
  node.loop = loop ?? true;
175
220
  });
176
221
  this.loop = loop ?? true;
177
222
  return this;
178
223
  }
179
- SetMaxAudioBufferSourceNodes(value) {
224
+ setMaxAudioBufferSourceNodes(value) {
180
225
  if (!DSP.overrideMaxAudioBufferNodes) {
181
- Debug.Warn("Cannot set maxAudioBufferSourceNodes because the option to override the current maximum value is disabled.", [
226
+ Debug.warn("Cannot set maxAudioBufferSourceNodes because the option to override the current maximum value is disabled.", [
182
227
  "Set overrideMaxAudioBufferNodes on DSP to true, in order to override the maximum audio buffer source nodes."
183
228
  ]);
184
229
  return this;
@@ -186,7 +231,7 @@ export class AudioClip {
186
231
  this.maxAudioBufferSourceNodes = value;
187
232
  return this;
188
233
  }
189
- DisconnectAllAudioBufferSourceNodes() {
234
+ disconnectAllAudioBufferSourceNodes() {
190
235
  if (!this.context)
191
236
  return false;
192
237
  const contextCurrentTime = this.context?.currentTime;
@@ -196,19 +241,19 @@ export class AudioClip {
196
241
  });
197
242
  return true;
198
243
  }
199
- AddEventListener(event, cb) {
244
+ addEventListener(event, cb) {
200
245
  this.events[event].push(cb);
201
- return () => this.RemoveEventListener(event, cb);
246
+ return () => this.removeEventListener(event, cb);
202
247
  }
203
- Once(event, cb) {
248
+ once(event, cb) {
204
249
  const wrapper = ((...args) => {
205
250
  // @ts-ignore
206
251
  cb(...args);
207
- this.RemoveEventListener(event, wrapper);
252
+ this.removeEventListener(event, wrapper);
208
253
  });
209
- return this.AddEventListener(event, wrapper);
254
+ return this.addEventListener(event, wrapper);
210
255
  }
211
- RemoveEventListener(event, cb) {
256
+ removeEventListener(event, cb) {
212
257
  const arr = this.events[event];
213
258
  for (let i = 0; i < arr.length; i++) {
214
259
  if (arr[i] === cb) {
@@ -218,7 +263,7 @@ export class AudioClip {
218
263
  }
219
264
  return this;
220
265
  }
221
- ClearEventListeners(event) {
266
+ clearEventListeners(event) {
222
267
  if (event) {
223
268
  this.events[event].length = 0;
224
269
  }
@@ -227,37 +272,65 @@ export class AudioClip {
227
272
  }
228
273
  return this;
229
274
  }
230
- GetChannelData(channel = 0) {
275
+ getChannelData(channel = 0) {
231
276
  return this.data.audioBuffer.getChannelData(channel);
232
277
  }
233
- Send(channel) {
278
+ send(channel) {
234
279
  if (!channel.audioClipPlayer)
235
- return Debug.Error("Could not send AudioClip signal to channel, because the channel's AudioClipPlayer is undefined.", [
280
+ return Debug.error("Could not send AudioClip signal to channel, because the channel's AudioClipPlayer is undefined.", [
236
281
  "Make sure to initialize the Channel.",
237
282
  `Channel id: ${channel.id}.`,
238
283
  `AudioClip id: ${this.id}.`
239
284
  ]);
240
- channel.audioClipPlayer.AttachAudioClip(this);
285
+ channel.audioClipPlayer.attachAudioClip(this);
241
286
  }
242
- Unsend(channel) {
287
+ unsend(channel) {
243
288
  if (!channel.audioClipPlayer)
244
- return Debug.Error("Could not unsend AudioClip signal to channel, because the channel's AudioClipPlayer is undefined.", [
289
+ return Debug.error("Could not unsend AudioClip signal to channel, because the channel's AudioClipPlayer is undefined.", [
245
290
  "Make sure to initialize the Channel.",
246
291
  `Channel id: ${channel.id}.`,
247
292
  `AudioClip id: ${this.id}.`
248
293
  ]);
249
- channel.audioClipPlayer.DetachAudioClip(this);
294
+ channel.audioClipPlayer.detachAudioClip(this);
295
+ }
296
+ detachFromAudioClipPlayer(audioClipPlayer) {
297
+ const idx = this.audioClipPlayers.indexOf(audioClipPlayer);
298
+ if (idx === -1)
299
+ return;
300
+ this.audioClipPlayers.splice(idx, 1);
301
+ if (this.audioClipPlayer === audioClipPlayer) {
302
+ this.audioClipPlayer = this.audioClipPlayers[0] ?? null;
303
+ }
304
+ if (this.audioClipPlayers.length === 0) {
305
+ this.stop();
306
+ return;
307
+ }
308
+ this.rebuildNodeChain();
250
309
  }
251
- SetPlaybackRateInSemitones(semitones) {
310
+ setPitch(semitones) {
252
311
  if (!this.context)
253
- throw new Error("Could not set playback rate because the AudioContext is not defined.");
312
+ Debug.error("Could not set pitch because the context (AudioContext) of this AudioClip is undefined.", [
313
+ "Make sure to attach this AudioClip to an AudioClipPlayer instance before calling .setPitch() on this AudioClip.",
314
+ ], ErrorCodes.AUDIO_CLIP_PLAYER_NO_CONTEXT);
315
+ if (semitones < this.minPitchSemitones || semitones > this.maxPitchSemitones)
316
+ Debug.error("Could not set the pitch because it is not within the allowed semitone range.", [
317
+ `Given value: ${semitones}.`,
318
+ `Accepts a value between ${this.minPitchSemitones} and ${this.maxPitchSemitones} semitones.`
319
+ ], ErrorCodes.PITCH_OUT_OF_RANGE);
254
320
  const calculatedPlaybackRate = Math.pow(2, semitones / 12);
255
- for (const buffer of this.audioBufferSourceNodes) {
256
- buffer.playbackRate.setValueAtTime(calculatedPlaybackRate, this.context?.currentTime);
257
- }
321
+ for (const buffer of this.audioBufferSourceNodes)
322
+ buffer.playbackRate.setValueAtTime(calculatedPlaybackRate, this.context?.currentTime ?? 0);
323
+ this.pitch = semitones;
258
324
  this.playbackRate = calculatedPlaybackRate;
259
325
  return this;
260
326
  }
327
+ resetPitch() {
328
+ return this.setPitch(0);
329
+ }
330
+ /** @deprecated Use {@link setPitch} instead. */
331
+ setPlaybackRateInSemitones(semitones) {
332
+ return this.setPitch(semitones);
333
+ }
261
334
  get currentPlaybackTime() {
262
335
  return (!this.isPlaying || !this.context)
263
336
  ? 0
@@ -9,14 +9,14 @@ export declare class AudioClipPlayer {
9
9
  context: AudioContext | null;
10
10
  channel: Channel | Master | null;
11
11
  constructor(context: AudioContext);
12
- AttachAudioClip(audioClip: AudioClip): void;
13
- DetachAudioClip(clip: AudioClip): void;
14
- Send(channel: Channel | Master): void;
15
- Unsend(): void;
16
- SetVolume(value: number): void;
17
- StopAll(): void;
18
- Dispose(): void;
19
- SetLabel(label: string): void;
12
+ attachAudioClip(audioClip: AudioClip): void;
13
+ detachAudioClip(clip: AudioClip): void;
14
+ send(channel: Channel | Master): void;
15
+ unsend(): void;
16
+ setVolume(value: number): void;
17
+ stopAll(): void;
18
+ dispose(): void;
19
+ setLabel(label: string): void;
20
20
  get length(): number;
21
21
  get volume(): number;
22
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AudioClipPlayer.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClipPlayer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,qBAAa,eAAe;IAEjB,KAAK,EAAE,MAAM,CAAqB;IAClC,EAAE,EAAE,MAAM,CAAQ;IAElB,UAAU,EAAE,SAAS,EAAE,CAAM;IAC7B,cAAc,EAAE,QAAQ,GAAG,IAAI,CAAQ;IAEvC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAQ;IACpC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAQ;gBAEnC,OAAO,EAAE,YAAY;IAK1B,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAU3C,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAgBtC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAUrC,MAAM,IAAI,IAAI;IAad,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAU9B,OAAO,IAAI,IAAI;IAOf,OAAO,IAAI,IAAI;IAYf,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIpC,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;CACJ"}
1
+ {"version":3,"file":"AudioClipPlayer.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioClipPlayer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,qBAAa,eAAe;IAEjB,KAAK,EAAE,MAAM,CAAqB;IAClC,EAAE,EAAE,MAAM,CAAQ;IAElB,UAAU,EAAE,SAAS,EAAE,CAAM;IAC7B,cAAc,EAAE,QAAQ,GAAG,IAAI,CAAQ;IAEvC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAQ;IACpC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAQ;IAE/C,YAAY,OAAO,EAAE,YAAY,EAGhC;IAEM,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAQjD;IAEM,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAY5C;IAEM,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ3C;IAEM,MAAM,IAAI,IAAI,CAWpB;IAEM,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAQpC;IAEM,OAAO,IAAI,IAAI,CAKrB;IAEM,OAAO,IAAI,IAAI,CAUrB;IAEM,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEnC;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;CACJ"}
@@ -12,34 +12,32 @@ export class AudioClipPlayer {
12
12
  this.context = context;
13
13
  this.outputGainNode = new GainNode(context);
14
14
  }
15
- AttachAudioClip(audioClip) {
15
+ attachAudioClip(audioClip) {
16
16
  if (this.audioClips.includes(audioClip))
17
- return Debug.Error("Could not attach audio clip because it is already part of this channel", [
18
- "Call .DetachAudioClip([clip AudioClip]) before attaching audio clip."
17
+ return Debug.error("Could not attach audio clip because it is already part of this channel", [
18
+ "Call .detachAudioClip([clip AudioClip]) before attaching audio clip."
19
19
  ], ErrorCodes.AUDIO_CLIP_ALREADY_ATTACHED);
20
- audioClip.Initialize(this);
20
+ audioClip.initialize(this);
21
21
  this.audioClips.push(audioClip);
22
22
  }
23
- DetachAudioClip(clip) {
23
+ detachAudioClip(clip) {
24
24
  if (!this.audioClips.includes(clip))
25
- return Debug.Error("Could not detach audio clip because it is not part of this channel", [
26
- "Call .AttachAudioClip([clip AudioClip]) before detaching audio clip."
25
+ return Debug.error("Could not detach audio clip because it is not part of this channel", [
26
+ "Call .attachAudioClip([clip AudioClip]) before detaching audio clip."
27
27
  ], ErrorCodes.AUDIO_CLIP_NOT_FOUND);
28
- clip.Stop();
29
- const self = this;
30
- this.audioClips.forEach(function (_clip, index) {
31
- if (clip.id === _clip.id)
32
- return self.audioClips.splice(index, 1);
33
- });
28
+ const idx = this.audioClips.indexOf(clip);
29
+ if (idx >= 0)
30
+ this.audioClips.splice(idx, 1);
31
+ clip.detachFromAudioClipPlayer(this);
34
32
  }
35
- Send(channel) {
33
+ send(channel) {
36
34
  if (!this.outputGainNode || !channel.input)
37
- return Debug.Error("Could not send AudioClipPlayer signal to a channel/master.");
38
- this.Unsend();
35
+ return Debug.error("Could not send AudioClipPlayer signal to a channel/master.");
36
+ this.unsend();
39
37
  this.channel = channel;
40
38
  this.outputGainNode.connect(channel.input);
41
39
  }
42
- Unsend() {
40
+ unsend() {
43
41
  if (!this.outputGainNode)
44
42
  return;
45
43
  if (this.channel && this.channel.input) {
@@ -50,7 +48,7 @@ export class AudioClipPlayer {
50
48
  }
51
49
  this.channel = null;
52
50
  }
53
- SetVolume(value) {
51
+ setVolume(value) {
54
52
  if (!this.outputGainNode)
55
53
  return;
56
54
  if (value < 0)
@@ -59,21 +57,21 @@ export class AudioClipPlayer {
59
57
  value = 1;
60
58
  this.outputGainNode.gain.value = value;
61
59
  }
62
- StopAll() {
60
+ stopAll() {
63
61
  this.audioClips.forEach(function (clip) {
64
- clip.Stop();
62
+ clip.stop();
65
63
  });
66
64
  }
67
- Dispose() {
68
- this.StopAll();
69
- this.Unsend();
65
+ dispose() {
66
+ this.stopAll();
67
+ this.unsend();
70
68
  this.outputGainNode?.disconnect();
71
69
  this.audioClips = [];
72
70
  this.outputGainNode = null;
73
71
  this.channel = null;
74
72
  this.context = null;
75
73
  }
76
- SetLabel(label) {
74
+ setLabel(label) {
77
75
  this.label = label;
78
76
  }
79
77
  get length() {
@@ -7,11 +7,52 @@ export declare class AudioDevice {
7
7
  context: AudioContext;
8
8
  masterChannel: Master;
9
9
  masterChannels: Master[];
10
+ readonly sampleRate: number;
11
+ readonly baseLatency: number;
12
+ readonly outputLatency: number;
13
+ readonly state: AudioContextState;
14
+ readonly currentTime: number;
15
+ readonly maximumFrequency: number;
10
16
  constructor(deviceInfo: MediaDeviceInfo);
11
- GetMasterChannel(): Master;
12
- SetMasterChannel(channel: Master): void;
13
- CreateMasterChannel(): Master;
14
- GetContext(): AudioContext;
15
- CreateChannel(label?: string): Channel;
17
+ /**
18
+ * Returns the master channel associated with this audio device.
19
+ * The master channel is the main output channel for this audio device, and is used to control the overall volume and other properties of the audio output.
20
+ * @returns
21
+ */
22
+ getMasterChannel(): Master;
23
+ /**
24
+ * Sets the master channel for this audio device.
25
+ * The master channel is normally automatically created when the audio device is initialized, but this method allows for the master channel to be changed if needed.
26
+ * @param channel
27
+ * @returns
28
+ */
29
+ setMasterChannel(channel: Master): void;
30
+ /**
31
+ * Creates a new master channel based on the this audio device's audio context, and adds it to the master channels array.
32
+ * Normally, an audio device should only have one master channel, but this method allows for multiple master channels to be created and used if needed.
33
+ * @returns
34
+ */
35
+ createMasterChannel(): Master;
36
+ /**
37
+ * Returns the audio context associated with this audio device.
38
+ * This method is provided for ease of use, and is a wrapper for the context property.
39
+ *
40
+ * The audio context can vary between audio devices, and is used to create channels and master channels that are associated with this audio device.
41
+ */
42
+ getContext(): AudioContext;
43
+ /**
44
+ * Creates a new channel based on the this audio device's audio context.
45
+ * This method is a wrapper for the Channel constructor, and is provided for ease of use.
46
+ * In case you want to create a channel with a different audio context, you can use the Channel constructor directly.
47
+ *
48
+ * @example
49
+ * ```
50
+ * const myChannel: Channel = audioDevice.createChannel("My Channel");
51
+ * ```
52
+ *
53
+ * @param label
54
+ * @returns
55
+ */
56
+ createChannel(label?: string): Channel;
16
57
  }
17
58
  //# sourceMappingURL=AudioDevice.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AudioDevice.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioDevice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,qBAAa,WAAW;IAUD,UAAU,EAAE,eAAe;IARvC,EAAE,EAAE,MAAM,CAAQ;IAClB,SAAS,EAAE,MAAM,CAAc;IAE/B,OAAO,EAAE,YAAY,CAAsB;IAE3C,aAAa,EAAE,MAAM,CAA4B;IACjD,cAAc,EAAE,MAAM,EAAE,CAAM;gBAElB,UAAU,EAAE,eAAe;IAEvC,gBAAgB,IAAI,MAAM;IAI1B,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAUvC,mBAAmB,IAAI,MAAM;IAQ7B,UAAU,IAAI,YAAY;IAI1B,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;CAGhD"}
1
+ {"version":3,"file":"AudioDevice.d.ts","sourceRoot":"","sources":["../../../src/core/classes/AudioDevice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,qBAAa,WAAW;IAkBD,UAAU,EAAE,eAAe;IAhBvC,EAAE,EAAE,MAAM,CAAQ;IAClB,SAAS,EAAE,MAAM,CAAc;IAE/B,OAAO,EAAE,YAAY,CAAsB;IAE3C,aAAa,EAAE,MAAM,CAA4B;IACjD,cAAc,EAAE,MAAM,EAAE,CAAM;IAErC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAA2B;IACtD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAA4B;IACxD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAA8B;IAC5D,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAsB;IACvD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAA4B;IAExD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAA+B;IAEhE,YAAmB,UAAU,EAAE,eAAe,EAAI;IAElD;;;;OAIG;IACI,gBAAgB,IAAI,MAAM,CAEhC;IAED;;;;;OAKG;IACI,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAQ7C;IAED;;;;OAIG;IACI,mBAAmB,IAAI,MAAM,CAMnC;IAED;;;;;OAKG;IACI,UAAU,IAAI,YAAY,CAEhC;IAED;;;;;;;;;;;;OAYG;IACI,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAE5C;CACJ"}