Skip to content

Commit

Permalink
Merge pull request phaserjs#5274 from pi-kei/sound-panning
Browse files Browse the repository at this point in the history
Add ability to pan sounds
  • Loading branch information
photonstorm authored Dec 14, 2020
2 parents 1d58620 + 7f2874c commit dde5b25
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 5 deletions.
7 changes: 5 additions & 2 deletions src/sound/BaseSound.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ var BaseSound = new Class({
detune: 0,
seek: 0,
loop: false,
delay: 0
delay: 0,
pan: 0

};

Expand Down Expand Up @@ -217,7 +218,8 @@ var BaseSound = new Class({
detune: 0,
seek: 0,
loop: false,
delay: 0
delay: 0,
pan: 0
}
}, marker);

Expand Down Expand Up @@ -418,6 +420,7 @@ var BaseSound = new Class({
this.rate = this.currentConfig.rate;
this.detune = this.currentConfig.detune;
this.loop = this.currentConfig.loop;
this.pan = this.currentConfig.pan;
},

/**
Expand Down
27 changes: 27 additions & 0 deletions src/sound/events/PAN_EVENT.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @author pi-kei
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/

/**
* The Sound Pan Event.
*
* This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes.
*
* Listen to it from a Sound instance using `Sound.on('pan', listener)`, i.e.:
*
* ```javascript
* var sound = this.sound.add('key');
* sound.on('pan', listener);
* sound.play();
* sound.setPan(0.5);
* ```
*
* @event Phaser.Sound.Events#PAN
* @since 3.0.0
*
* @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event.
* @param {number} pan - The new pan of the Sound.
*/
module.exports = 'pan';
1 change: 1 addition & 0 deletions src/sound/events/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module.exports = {
LOOP: require('./LOOP_EVENT'),
LOOPED: require('./LOOPED_EVENT'),
MUTE: require('./MUTE_EVENT'),
PAN: require('./PAN_EVENT'),
PAUSE_ALL: require('./PAUSE_ALL_EVENT'),
PAUSE: require('./PAUSE_EVENT'),
PLAY: require('./PLAY_EVENT'),
Expand Down
43 changes: 43 additions & 0 deletions src/sound/html5/HTML5AudioSound.js
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,49 @@ var HTML5AudioSound = new Class({
{
this.loop = value;

return this;
},

/**
* Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan).
* Has no effect on HTML5 Audio Sound.
*
* @name Phaser.Sound.HTML5AudioSound#pan
* @type {number}
* @default 0
* @fires Phaser.Sound.Events#PAN
* @since 3.0.0
*/
pan: {

get: function ()
{
return this.currentConfig.pan;
},

set: function (value)
{
this.currentConfig.pan = value;

this.emit(Events.PAN, this, value);
}
},

/**
* Sets the pan of this Sound. Has no effect on HTML5 Audio Sound.
*
* @method Phaser.Sound.HTML5AudioSound#setPan
* @fires Phaser.Sound.Events#PAN
* @since 3.4.0
*
* @param {number} value - The pan of the sound.
*
* @return {Phaser.Sound.HTML5AudioSound} This Sound instance.
*/
setPan: function (value)
{
this.pan = value;

return this;
}

Expand Down
8 changes: 6 additions & 2 deletions src/sound/noaudio/NoAudioSound.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ var NoAudioSound = new Class({
detune: 0,
seek: 0,
loop: false,
delay: 0
delay: 0,
pan: 0
}, config);

this.currentConfig = this.config;
Expand All @@ -80,6 +81,7 @@ var NoAudioSound = new Class({
this.detune = 0;
this.seek = 0;
this.loop = false;
this.pan = 0;
this.markers = {};
this.currentMarker = null;
this.pendingRemove = false;
Expand Down Expand Up @@ -178,7 +180,9 @@ var NoAudioSound = new Class({

setSeek: returnThis,

setLoop: returnThis
setLoop: returnThis,

setPan: returnThis

});

Expand Down
1 change: 1 addition & 0 deletions src/sound/typedefs/SoundConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
* @property {number} [seek=0] - Position of playback for this sound, in seconds.
* @property {boolean} [loop=false] - Whether or not the sound or current sound marker should loop.
* @property {number} [delay=0] - Time, in seconds, that should elapse before the sound actually starts its playback.
* @property {number} [pan=0] - A value between -1 (full left pan) and 1 (full right pan). 0 means no pan.
*/
58 changes: 57 additions & 1 deletion src/sound/webaudio/WebAudioSound.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ var WebAudioSound = new Class({
*/
this.volumeNode = manager.context.createGain();

/**
* Panner node responsible for controlling this sound's pan.
*
* @name Phaser.Sound.WebAudioSound#pannerNode
* @type {StereoPannerNode}
* @private
*/
this.pannerNode = manager.context.createStereoPanner();

/**
* The time at which the sound should have started playback from the beginning.
* Based on BaseAudioContext.currentTime value.
Expand Down Expand Up @@ -165,7 +174,9 @@ var WebAudioSound = new Class({

this.muteNode.connect(this.volumeNode);

this.volumeNode.connect(manager.destination);
this.volumeNode.connect(this.pannerNode);

this.pannerNode.connect(manager.destination);

this.duration = this.audioBuffer.duration;

Expand Down Expand Up @@ -493,6 +504,8 @@ var WebAudioSound = new Class({
this.muteNode = null;
this.volumeNode.disconnect();
this.volumeNode = null;
this.pannerNode.disconnect();
this.pannerNode = null;
this.rateUpdates.length = 0;
this.rateUpdates = null;
},
Expand Down Expand Up @@ -892,6 +905,49 @@ var WebAudioSound = new Class({
{
this.loop = value;

return this;
},

/**
* Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan).
*
* @name Phaser.Sound.WebAudioSound#pan
* @type {number}
* @default 0
* @fires Phaser.Sound.Events#PAN
* @since 3.0.0
*/
pan: {

get: function ()
{
return this.pannerNode.pan.value;
},

set: function (value)
{
this.currentConfig.pan = value;
this.pannerNode.pan.setValueAtTime(value, this.manager.context.currentTime);

this.emit(Events.PAN, this, value);
}
},

/**
* Sets the pan of this Sound.
*
* @method Phaser.Sound.WebAudioSound#setPan
* @fires Phaser.Sound.Events#PAN
* @since 3.4.0
*
* @param {number} value - The pan of the sound.
*
* @return {Phaser.Sound.WebAudioSound} This Sound instance.
*/
setPan: function (value)
{
this.pan = value;

return this;
}

Expand Down
42 changes: 42 additions & 0 deletions types/phaser.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65371,6 +65371,10 @@ declare namespace Phaser {
* Time, in seconds, that should elapse before the sound actually starts its playback.
*/
delay?: number;
/**
* A value between -1 (full left pan) and 1 (full right pan). 0 means no pan.
*/
pan?: number;
};

/**
Expand Down Expand Up @@ -85691,6 +85695,22 @@ declare namespace Phaser {
*/
const MUTE: any;

/**
* The Sound Pan Event.
*
* This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes.
*
* Listen to it from a Sound instance using `Sound.on('pan', listener)`, i.e.:
*
* ```javascript
* var sound = this.sound.add('key');
* sound.on('pan', listener);
* sound.play();
* sound.setPan(0.5);
* ```
*/
const PAN: any;

/**
* The Pause All Sounds Event.
*
Expand Down Expand Up @@ -85980,6 +86000,18 @@ declare namespace Phaser {
*/
setLoop(value: boolean): Phaser.Sound.HTML5AudioSound;

/**
* Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan).
* Has no effect on HTML5 Audio Sound.
*/
pan: number;

/**
* Sets the pan of this Sound. Has no effect on HTML5 Audio Sound.
* @param value The pan of the sound.
*/
setPan(value: number): Phaser.Sound.HTML5AudioSound;

}

/**
Expand Down Expand Up @@ -86302,6 +86334,16 @@ declare namespace Phaser {
*/
setLoop(value: boolean): Phaser.Sound.WebAudioSound;

/**
* Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan).
*/
pan: number;

/**
* Sets the pan of this Sound.
* @param value The pan of the sound.
*/
setPan(value: number): Phaser.Sound.WebAudioSound;
}

/**
Expand Down

0 comments on commit dde5b25

Please sign in to comment.