From 715e58a59205f114088658691651f79d05969dc1 Mon Sep 17 00:00:00 2001 From: Peter van der Noord Date: Tue, 6 Sep 2022 22:06:05 +0200 Subject: [PATCH] Add stereo panner to VolumeNodes, plus get/set methods (#9) --- packages/channels/src/Channel.ts | 2 ++ packages/channels/src/Channels.ts | 2 ++ packages/channels/src/PlayingSound.ts | 2 ++ packages/channels/src/VolumeNodes.ts | 10 +++++++++- packages/channels/src/types.ts | 8 +++++--- packages/channels/src/util/createVolumeNodesGraph.ts | 3 +++ 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/channels/src/Channel.ts b/packages/channels/src/Channel.ts index c05f48b..ce1f0b0 100644 --- a/packages/channels/src/Channel.ts +++ b/packages/channels/src/Channel.ts @@ -82,4 +82,6 @@ export class Channel implements CanConnectMediaElement { public setVolume = (value: number) => this.volumeNodes.setVolume(value); public connectMediaElement = (element: HTMLMediaElement) => this.volumeNodes.connectMediaElement(element); + public getPan = () => this.volumeNodes.getPan(); + public setPan = (value: number) => this.volumeNodes.setPan(value); } diff --git a/packages/channels/src/Channels.ts b/packages/channels/src/Channels.ts index 2db4521..d11425c 100644 --- a/packages/channels/src/Channels.ts +++ b/packages/channels/src/Channels.ts @@ -243,4 +243,6 @@ export class Channels extends EventDispatcher implements HasVolume { public setVolume = (value: number) => this.volumeNodes.setVolume(value); public connectMediaElement = (element: HTMLMediaElement) => this.volumeNodes.connectMediaElement(element); + public getPan = () => this.volumeNodes.getPan(); + public setPan = (value: number) => this.volumeNodes.setPan(value); } diff --git a/packages/channels/src/PlayingSound.ts b/packages/channels/src/PlayingSound.ts index f632fe4..2aa9622 100644 --- a/packages/channels/src/PlayingSound.ts +++ b/packages/channels/src/PlayingSound.ts @@ -111,4 +111,6 @@ export class PlayingSound implements HasVolume { public getFadeVolume = () => this.volumeNodes.getFadeVolume(); public getVolume = () => this.volumeNodes.getVolume(); public setVolume = (value: number) => this.volumeNodes.setVolume(value); + public getPan = () => this.volumeNodes.getPan(); + public setPan = (value: number) => this.volumeNodes.setPan(value); } diff --git a/packages/channels/src/VolumeNodes.ts b/packages/channels/src/VolumeNodes.ts index 8852130..c50aba7 100644 --- a/packages/channels/src/VolumeNodes.ts +++ b/packages/channels/src/VolumeNodes.ts @@ -17,6 +17,7 @@ type VolumeNodeOptions = { export class VolumeNodes implements CanConnectMediaElement { private readonly volumeGainNode: GainNode; private readonly fadeGainNode: GainNode; + private readonly stereoPannerNode: StereoPannerNode; public readonly input: AudioNode; public readonly output: AudioNode; @@ -28,7 +29,7 @@ export class VolumeNodes implements CanConnectMediaElement { private readonly volumeTarget: HasVolume, { volume = 1, fadeVolume = 1, effects }: VolumeNodeOptions ) { - const { fadeGainNode, volumeGainNode, input, output } = + const { fadeGainNode, volumeGainNode, input, output, stereoPannerNode } = createVolumeNodesGraph({ audioContext, effects, @@ -36,6 +37,7 @@ export class VolumeNodes implements CanConnectMediaElement { this.volumeGainNode = volumeGainNode; this.fadeGainNode = fadeGainNode; + this.stereoPannerNode = stereoPannerNode; this.input = input; this.output = output; @@ -118,4 +120,10 @@ export class VolumeNodes implements CanConnectMediaElement { this.audioContext.createMediaElementSource(element); mediaElementSource.connect(this.input); }; + + public setPan = (value: number) => { + this.stereoPannerNode.pan.value = value; + }; + + public getPan = () => this.stereoPannerNode.pan.value; } diff --git a/packages/channels/src/types.ts b/packages/channels/src/types.ts index 23e5aa0..e298304 100644 --- a/packages/channels/src/types.ts +++ b/packages/channels/src/types.ts @@ -4,13 +4,15 @@ export type Sound = ISample; export type CreateSound = ICreateSample; export interface HasVolume { - getFadeVolume(): number; - getVolume(): number; - setVolume(value: number): void; + getFadeVolume: () => number; + getVolume: () => number; + setVolume: (value: number) => void; mute: () => void; unmute: () => void; fadeOut: (duration: number, onComplete?: () => void) => void; fadeIn: (duration: number, onComplete?: () => void) => void; + setPan: (value: number) => void; + getPan: () => number; } export interface CanConnectMediaElement extends HasVolume { diff --git a/packages/channels/src/util/createVolumeNodesGraph.ts b/packages/channels/src/util/createVolumeNodesGraph.ts index 5ce2660..85e08fd 100644 --- a/packages/channels/src/util/createVolumeNodesGraph.ts +++ b/packages/channels/src/util/createVolumeNodesGraph.ts @@ -13,9 +13,11 @@ export const createVolumeNodesGraph = ({ audioContext, effects }: Props) => { const volumeGainNode = audioContext.createGain(); const fadeGainNode = audioContext.createGain(); + const stereoPannerNode = audioContext.createStereoPanner(); const nodesChain: Array = [ effects?.preVolume?.output, + stereoPannerNode, volumeGainNode, fadeGainNode, effects?.postVolume?.input, @@ -36,5 +38,6 @@ export const createVolumeNodesGraph = ({ audioContext, effects }: Props) => { volumeGainNode, input, output, + stereoPannerNode, }; };