Skip to content

Commit 5fcf1d5

Browse files
committed
improved audio graph
1 parent 7b542f4 commit 5fcf1d5

File tree

2 files changed

+70
-19
lines changed

2 files changed

+70
-19
lines changed

source/library/audio.ts

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,36 @@
33

44
import { PlayerError, IPlayerError } from './error';
55

6+
// Note to self: AudioGraph documentation
7+
// https://developer.mozilla.org/en-US/docs/Web/API/AudioNode
8+
69
export interface IAudioGraph {
10+
// https://developer.mozilla.org/en-US/docs/Web/API/GainNode
711
gainNode: GainNode;
12+
// https://developer.mozilla.org/en-US/docs/Web/API/PannerNode
813
pannerNode?: PannerNode;
14+
// https://developer.mozilla.org/en-US/docs/Web/API/StereoPannerNode
915
stereoPannerNode?: StereoPannerNode;
16+
// https://developer.mozilla.org/en-US/docs/Web/API/DelayNode
17+
delayNode?: DelayNode;
18+
// https://developer.mozilla.org/en-US/docs/Web/API/ScriptProcessorNode
19+
scriptProcessorNode?: ScriptProcessorNode;
20+
// https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode
21+
analyserNode?: AnalyserNode;
22+
// https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode
23+
biquadFilterNode?: BiquadFilterNode;
24+
// https://developer.mozilla.org/en-US/docs/Web/API/ChannelMergerNode
25+
channelMergeNode?: ChannelMergerNode;
26+
// https://developer.mozilla.org/en-US/docs/Web/API/ChannelSplitterNode
27+
channelSplitterNode?: ChannelSplitterNode;
28+
// https://developer.mozilla.org/en-US/docs/Web/API/ConvolverNode
29+
convolverNode?: ConvolverNode;
30+
// https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode
31+
dynamicCompressorNode?: DynamicsCompressorNode;
32+
// https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode
33+
oscillatorNode?: OscillatorNode;
34+
// https://developer.mozilla.org/en-US/docs/Web/API/WaveShaperNode
35+
waveShaperNode?: WaveShaperNode;
1036
}
1137

1238
export interface IAudioGraphOptions {
@@ -22,13 +48,16 @@ export class PlayerAudio {
2248

2349
protected _context: AudioContext;
2450
protected _contextState: string;
25-
protected _audioGraph: IAudioGraph | null;
51+
protected _audioGraph: IAudioGraph | null = null;
2652

27-
constructor() {
53+
constructor(customAudioGraph?: IAudioGraph) {
2854

2955
// initial context state is still "closed"
3056
this._contextState = 'closed';
31-
this._audioGraph = null;
57+
58+
if (customAudioGraph !== undefined) {
59+
this._audioGraph = customAudioGraph;
60+
}
3261

3362
// TODO: to speed up things would it be better to create a context in the constructor?
3463
// and suspend the context upon creating it until it gets used?
@@ -69,7 +98,7 @@ export class PlayerAudio {
6998

7099
this._context = audioContext;
71100

72-
this._createAudioGraph();
101+
this._connectAudioGraphGainToDestination();
73102

74103
resolve();
75104

@@ -135,27 +164,26 @@ export class PlayerAudio {
135164

136165
}
137166

138-
protected _createAudioGraph() {
167+
protected _connectAudioGraphGainToDestination() {
139168

140-
// https://developer.mozilla.org/en-US/docs/Web/API/GainNode
169+
if (this._audioGraph === null) {
141170

142-
let audioGraph = {
143-
gainNode: this._context.createGain()
144-
};
171+
this._audioGraph = {
172+
gainNode: this._context.createGain()
173+
}
145174

146-
// connect the gain node to the destination (speakers)
147-
audioGraph.gainNode.connect(this._context.destination);
175+
}
148176

149-
this._audioGraph = audioGraph;
177+
// connect the gain node to the destination (speakers)
178+
// https://developer.mozilla.org/en-US/docs/Web/API/AudioDestinationNode
179+
this._audioGraph.gainNode.connect(this._context.destination);
150180

151181
}
152182

153183
public setAudioGraph(audioGraph: IAudioGraph) {
154184

155185
if (this._audioGraph !== null) {
156-
157186
this._destroyAudioGraph();
158-
159187
}
160188

161189
this._audioGraph = audioGraph;
@@ -197,7 +225,7 @@ export class PlayerAudio {
197225

198226
}
199227

200-
public connectSourceNodeToGraph(sourceNode: AudioBufferSourceNode) {
228+
public connectSourceNodeToGraphGainNode(sourceNode: AudioBufferSourceNode) {
201229

202230
sourceNode.connect(this._audioGraph.gainNode);
203231

source/library/core.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
'use strict';
33

44
import { PlayerSound, ISound, ISoundAttributes, ISoundSource } from './sound';
5-
import { PlayerAudio } from './audio';
5+
import { PlayerAudio, IAudioGraph } from './audio';
66
import { PlayerRequest } from './request';
77
import { PlayerError, IPlayerError } from './error';
88

@@ -12,6 +12,7 @@ export interface ICoreOptions {
1212
soundsBaseUrl?: string;
1313
playingProgressIntervalTime?: number;
1414
playNextOnEnded?: boolean;
15+
audioGraph?: IAudioGraph;
1516
}
1617

1718
export class PlayerCore {
@@ -31,11 +32,13 @@ export class PlayerCore {
3132
// playing progress time interval
3233
protected _playingProgressIntervalTime: number;
3334
// playing progress timeoutID
34-
protected _playingTimeoutID: number | null;
35+
protected _playingTimeoutID: number | null = null;
3536
// when a song finishes, automatically play the next one
3637
protected _playNextOnEnded: boolean;
3738
// do we start over gain at the end of the queue
3839
protected _loopQueue: boolean;
40+
// a custon audioGraph created by the user
41+
protected _customAudioGraph: IAudioGraph | null = null;
3942

4043
// constants
4144
readonly WHERE_IN_QUEUE_AT_END: string = 'append';
@@ -67,6 +70,10 @@ export class PlayerCore {
6770
this._playNextOnEnded = options.playNextOnEnded;
6871
this._loopQueue = options.loopQueue;
6972

73+
if (typeof options.audioGraph !== 'undefined') {
74+
this._customAudioGraph = options.audioGraph;
75+
}
76+
7077
this._initialize();
7178

7279
}
@@ -90,7 +97,7 @@ export class PlayerCore {
9097
}
9198

9299
// player audio library instance
93-
this._playerAudio = new PlayerAudio();
100+
this._playerAudio = new PlayerAudio(this._customAudioGraph);
94101

95102
}
96103

@@ -423,7 +430,7 @@ export class PlayerCore {
423430
sound.startTime = sourceNode.context.currentTime;
424431

425432
// connect the source to the graph (destination)
426-
this._playerAudio.connectSourceNodeToGraph(sourceNode);
433+
this._playerAudio.connectSourceNodeToGraphGainNode(sourceNode);
427434

428435
// start playback
429436
// start(when, offset, duration)
@@ -778,4 +785,20 @@ export class PlayerCore {
778785

779786
};
780787

788+
public setAudioGraph(customAudioGraph: IAudioGraph) {
789+
790+
this._playerAudio.setAudioGraph(customAudioGraph);
791+
792+
this._customAudioGraph = customAudioGraph;
793+
794+
}
795+
796+
public getAudioGraph(): IAudioGraph {
797+
798+
this._customAudioGraph = this._playerAudio.getAudioGraph();
799+
800+
return this._customAudioGraph;
801+
802+
}
803+
781804
}

0 commit comments

Comments
 (0)