diff --git a/direct/src/interval/SoundInterval.py b/direct/src/interval/SoundInterval.py index cbda5ab929..4aecedcb45 100644 --- a/direct/src/interval/SoundInterval.py +++ b/direct/src/interval/SoundInterval.py @@ -28,9 +28,11 @@ class SoundInterval(Interval.Interval): # the sound is caused by the delay between the end of the sound # and the next taskMgr cycle). There still seems to be a skip # in Miles when looping MP3s. =( + # RAU 03/01/07 add listenerNode in case we dont want to + # use base.camera as the listener, node must not be None def __init__(self, sound, loop = 0, duration = 0.0, name = None, volume = 1.0, startTime = 0.0, node=None, - seamlessLoop=True): + seamlessLoop=True, listenerNode = None): """__init__(sound, loop, name) """ # Generate unique name @@ -46,6 +48,7 @@ class SoundInterval(Interval.Interval): self.volume = volume self.startTime = startTime self.node = node + self.listenerNode = listenerNode self._seamlessLoop = seamlessLoop if self._seamlessLoop: self._fLoop = True @@ -88,7 +91,8 @@ class SoundInterval(Interval.Interval): t1 = 0.0 if (t1 < self.soundDuration) and not (self._seamlessLoop and self._soundPlaying): base.sfxPlayer.playSfx( - self.sound, self.fLoop, 1, self.volume, t1, self.node) + self.sound, self.fLoop, 1, self.volume, t1, self.node, + listenerNode = self.listenerNode) self._soundPlaying = True self.state = CInterval.SStarted self.currT = t @@ -99,7 +103,13 @@ class SoundInterval(Interval.Interval): t1 = t + self.startTime if t1 < self.soundDuration: base.sfxPlayer.playSfx( - self.sound, self.fLoop, 1, self.volume, t1, self.node) + self.sound, self.fLoop, 1, self.volume, t1, self.node, + listenerNode = self.listenerNode) + if self.listenerNode and not self.listenerNode.isEmpty() and \ + self.node and not self.node.isEmpty(): + base.sfxPlayer.setFinalVolume(self.sound, self.node, self.volume, + self.listenerNode) + self.state = CInterval.SStarted self.currT = t diff --git a/direct/src/showbase/SfxPlayer.py b/direct/src/showbase/SfxPlayer.py index b129e13194..3bab71a011 100644 --- a/direct/src/showbase/SfxPlayer.py +++ b/direct/src/showbase/SfxPlayer.py @@ -35,16 +35,24 @@ class SfxPlayer: # this is a scale factor to convert distances so that a sound # located at self.cutoffDistance will have a volume # of self.cutoffVolume - self.distanceScale = rawCutoffDistance / self.cutoffDistance + self.distanceScale = rawCutoffDistance / self.cutoffDistance - def getLocalizedVolume(self, node): + def getCutoffDistance(self): + """Return the curent cutoff distance.""" + return self.cutoffDistance + + def getLocalizedVolume(self, node, listenerNode = None): """ Get the volume that a sound should be played at if it is localized at this node. We compute this wrt the camera + or to listenerNode. """ d = None if not node.isEmpty(): - d = node.getDistance(base.cam) + if listenerNode and not listenerNode.isEmpty(): + d = node.getDistance(listenerNode) + else: + d = node.getDistance(base.cam) if d == None or d > self.cutoffDistance: volume = 0 else: @@ -59,25 +67,31 @@ class SfxPlayer: def playSfx( self, sfx, looping = 0, interrupt = 1, volume = None, - time = 0.0, node=None): + time = 0.0, node=None, listenerNode = None): if sfx: - # If we have either a node or a volume, we need to adjust the sfx - # The volume passed in multiplies the distance base volume - if node or (volume is not None): - if node: - finalVolume = self.getLocalizedVolume(node) - else: - finalVolume = 1 - if volume is not None: - finalVolume *= volume - if node is not None: - finalVolume *= node.getNetAudioVolume() - sfx.setVolume(finalVolume) - + self.setFinalVolume(sfx, node, volume, listenerNode) + # dont start over if it's already playing, unless # "interrupt" was specified if interrupt or (sfx.status() != AudioSound.PLAYING): sfx.setTime(time) sfx.setLoop(looping) sfx.play() + + def setFinalVolume(self, sfx, node, volume, listenerNode): + """Calculate the final volume based on all contributed factors.""" + # If we have either a node or a volume, we need to adjust the sfx + # The volume passed in multiplies the distance base volume + if node or (volume is not None): + if node: + finalVolume = self.getLocalizedVolume(node, listenerNode) + else: + finalVolume = 1 + if volume is not None: + finalVolume *= volume + if node is not None: + finalVolume *= node.getNetAudioVolume() + sfx.setVolume(finalVolume) + +