diff --git a/sound.js b/sound.js index ea2364e9..932336da 100644 --- a/sound.js +++ b/sound.js @@ -13,6 +13,29 @@ function isRelativePath(path) { return !/^(\/|http(s?)|asset)/.test(path); } +function calculateRelativeVolume(volume, pan) { + // calculates a lower volume relative to the pan value + const relativeVolume = (volume * (1 - Math.abs(pan))); + return Number(relativeVolume.toFixed(1)); +} + +function setAndroidVolumes(sound) { + // calculates the volumes for left and right channels + if (sound._pan) { + const relativeVolume = calculateRelativeVolume(sound._volume, sound._pan); + if (sound._pan < 0) { + // left is louder + RNSound.setVolume(sound._key, sound._volume, relativeVolume); + } else { + // right is louder + RNSound.setVolume(sound._key, relativeVolume, sound._volume); + } + } else { + // no panning, same volume on both channels + RNSound.setVolume(sound._key, sound._volume, sound._volume); + } +} + function Sound(filename, basePath, onError, options) { var asset = resolveAssetSource(filename); if (asset) { @@ -155,8 +178,8 @@ Sound.prototype.getPitch = function() { Sound.prototype.setVolume = function(value) { this._volume = value; if (this._loaded) { - if (IsAndroid || IsWindows) { - RNSound.setVolume(this._key, value, value); + if (IsAndroid) { + setAndroidVolumes(this) } else { RNSound.setVolume(this._key, value); } @@ -164,6 +187,20 @@ Sound.prototype.setVolume = function(value) { return this; }; +Sound.prototype.setPan = function(value) { + this._pan = value; + if (this._loaded) { + if (IsWindows) { + throw new Error('#setPan not supported on windows'); + } else if (IsAndroid) { + setAndroidVolumes(this) + } else { + RNSound.setPan(this._key, value); + } + } + return this; +}; + Sound.prototype.getSystemVolume = function(callback) { if(!IsWindows) { RNSound.getSystemVolume(callback); @@ -182,13 +219,6 @@ Sound.prototype.getPan = function() { return this._pan; }; -Sound.prototype.setPan = function(value) { - if (this._loaded) { - RNSound.setPan(this._key, this._pan = value); - } - return this; -}; - Sound.prototype.getNumberOfLoops = function() { return this._numberOfLoops; };