2
0
Redmond Urbino 19 жил өмнө
parent
commit
9e1f6e25c5

+ 13 - 3
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
     # 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
     # and the next taskMgr cycle). There still seems to be a skip
     # in Miles when looping MP3s. =(
     # 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,
     def __init__(self, sound, loop = 0, duration = 0.0, name = None,
                  volume = 1.0, startTime = 0.0, node=None,
                  volume = 1.0, startTime = 0.0, node=None,
-                 seamlessLoop=True):
+                 seamlessLoop=True, listenerNode = None):
         """__init__(sound, loop, name)
         """__init__(sound, loop, name)
         """
         """
         # Generate unique name
         # Generate unique name
@@ -46,6 +48,7 @@ class SoundInterval(Interval.Interval):
         self.volume = volume
         self.volume = volume
         self.startTime = startTime
         self.startTime = startTime
         self.node = node
         self.node = node
+        self.listenerNode = listenerNode
         self._seamlessLoop = seamlessLoop
         self._seamlessLoop = seamlessLoop
         if self._seamlessLoop:
         if self._seamlessLoop:
             self._fLoop = True
             self._fLoop = True
@@ -88,7 +91,8 @@ class SoundInterval(Interval.Interval):
             t1 = 0.0
             t1 = 0.0
         if (t1 < self.soundDuration) and not (self._seamlessLoop and self._soundPlaying):
         if (t1 < self.soundDuration) and not (self._seamlessLoop and self._soundPlaying):
             base.sfxPlayer.playSfx(
             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._soundPlaying = True
         self.state = CInterval.SStarted
         self.state = CInterval.SStarted
         self.currT = t
         self.currT = t
@@ -99,7 +103,13 @@ class SoundInterval(Interval.Interval):
             t1 = t + self.startTime
             t1 = t + self.startTime
             if t1 < self.soundDuration:
             if t1 < self.soundDuration:
                 base.sfxPlayer.playSfx(
                 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.state = CInterval.SStarted
         self.currT = t
         self.currT = t
 
 

+ 31 - 17
direct/src/showbase/SfxPlayer.py

@@ -35,16 +35,24 @@ class SfxPlayer:
         # this is a scale factor to convert distances so that a sound
         # this is a scale factor to convert distances so that a sound
         # located at self.cutoffDistance will have a volume
         # located at self.cutoffDistance will have a volume
         # of self.cutoffVolume
         # 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
         Get the volume that a sound should be played at if it is
         localized at this node. We compute this wrt the camera
         localized at this node. We compute this wrt the camera
+        or to listenerNode.
         """
         """
         d = None
         d = None
         if not node.isEmpty():
         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:
         if d == None or d > self.cutoffDistance:
             volume = 0
             volume = 0
         else:
         else:
@@ -59,25 +67,31 @@ class SfxPlayer:
 
 
     def playSfx(
     def playSfx(
             self, sfx, looping = 0, interrupt = 1, volume = None,
             self, sfx, looping = 0, interrupt = 1, volume = None,
-            time = 0.0, node=None):
+            time = 0.0, node=None, listenerNode = None):
         if sfx:
         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
             # dont start over if it's already playing, unless
             # "interrupt" was specified
             # "interrupt" was specified
             if interrupt or (sfx.status() != AudioSound.PLAYING):
             if interrupt or (sfx.status() != AudioSound.PLAYING):
                 sfx.setTime(time)
                 sfx.setTime(time)
                 sfx.setLoop(looping)
                 sfx.setLoop(looping)
                 sfx.play()
                 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)
+        
+