diff --git a/direct/src/interval/Interval.py b/direct/src/interval/Interval.py index d11b0283ef..e9f4df3b8e 100644 --- a/direct/src/interval/Interval.py +++ b/direct/src/interval/Interval.py @@ -56,6 +56,9 @@ class Interval(DirectObject): def getState(self): return self.state + def isPaused(self): + return self.getState() == CInterval.SPaused + def isStopped(self): # Returns true if the interval has not been started, has already # played to its completion, or has been explicitly stopped via diff --git a/direct/src/interval/SoundInterval.py b/direct/src/interval/SoundInterval.py index 4bef28ba74..73db73e0de 100644 --- a/direct/src/interval/SoundInterval.py +++ b/direct/src/interval/SoundInterval.py @@ -22,8 +22,14 @@ class SoundInterval(Interval.Interval): # seems to be some timing in the audio such that the stop doesn't # kill the looping sound until the next time around if duration # of the interval equals duration of the sound + # seamlessloop will let the audio system loop the sound rather + # than explicitly restarting the sound every time around. This + # prevents a skip in the sound at every repetition (the gap in + # the sound is caused by the delay between the end of the sound + # and the next taskMgr cycle) 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): """__init__(sound, loop, name) """ # Generate unique name @@ -39,6 +45,10 @@ class SoundInterval(Interval.Interval): self.volume = volume self.startTime = startTime self.node = node + self._seamlessLoop = seamlessLoop + if self._seamlessLoop: + self._fLoop = True + self._soundPlaying = False # If no duration given use sound's duration as interval's duration if float(duration) == 0.0 and self.sound != None: duration = max(self.soundDuration - self.startTime, 0) @@ -70,14 +80,15 @@ class SoundInterval(Interval.Interval): Interval.Interval.__init__(self, name, duration) def privInitialize(self, t): - # If its within a 10th of a second of the start, + # If it's within a 10th of a second of the start, # start at the beginning t1 = t + self.startTime if (t1 < 0.1): t1 = 0.0 - if t1 < self.soundDuration: + 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._soundPlaying = True self.state = CInterval.SStarted self.currT = t @@ -91,18 +102,31 @@ class SoundInterval(Interval.Interval): self.state = CInterval.SStarted self.currT = t + def finish(self, *args, **kArgs): + self._inFinish = True + Interval.Interval.finish(self, *args, **kArgs) + del self._inFinish + def privFinalize(self): - if self.sound != None: + # if we're just coming to the end of a seamlessloop, leave the sound alone, + # let the audio subsystem loop it + if (self._seamlessLoop and self._soundPlaying and self.getLoop() + and not hasattr(self, '_inFinish')): + return + elif self.sound != None: self.sound.stop() + self._soundPlaying = False self.currT = self.getDuration() self.state = CInterval.SFinal def privInterrupt(self): if self.sound != None: self.sound.stop() + self._soundPlaying = False self.state = CInterval.SPaused def loop(self, startT = 0.0, endT = -1.0, playRate = 1.0, stagger=False): + self.fLoop = 1 Interval.Interval.loop(self, startT, endT, playRate) if stagger: self.setT(random.random() * self.getDuration())