Esempio n. 1
0
    def reload(self):
        """
        Causes this channel to be stopped in a way that looped audio will be
        reloaded and restarted.
        """

        with lock:
            renpysound.dequeue(self.number, True)
            renpysound.stop(self.number)
Esempio n. 2
0
    def fadeout(self, secs):
        """
        Causes the playing music to be faded out for the given number
        of seconds. Also clears any queued music.
        """

        self.keep_queue = 0
        self.dequeue()

        if not pcm_ok:
            return

        if secs == 0:
            renpysound.stop(self.number)
        else:
            renpysound.fadeout(self.number, int(secs * 1000))
Esempio n. 3
0
    def fadeout(self, secs):
        """
        Causes the playing music to be faded out for the given number
        of seconds. Also clears any queued music.
        """

        self.keep_queue = 0
        self.dequeue()

        if not pcm_ok:
            return

        if secs == 0:
            renpysound.stop(self.number)
        else:
            renpysound.fadeout(self.number, int(secs * 1000))
Esempio n. 4
0
    def periodic(self):
        """
        This is the periodic call that causes this channel to load new stuff
        into its queues, if necessary.
        """

        # Update the channel volume.
        vol = self.chan_volume * renpy.game.preferences.volumes.get(self.mixer, 1.0)

        if vol != self.actual_volume:
            renpysound.set_volume(self.number, vol)
            self.actual_volume = vol

        # This should be set from something that checks to see if our
        # mixer is muted.
        force_stop = self.context.force_stop or (renpy.game.preferences.mute.get(self.mixer, False) and self.stop_on_mute)

        if self.playing and force_stop:
            renpysound.stop(self.number)
            self.playing = False

        if force_stop:
            self.wait_stop = False

            if self.loop:
                self.queue = self.queue[-len(self.loop):]
            else:
                self.queue = [ ]
            return

        # Should we do the callback?
        do_callback = False

        topq = None

        # This has been modified so we only queue a single sound file
        # per call, to prevent memory leaks with really short sound
        # files. So this loop will only execute once, in practice.
        while True:

            depth = renpysound.queue_depth(self.number)

            if depth == 0:
                self.wait_stop = False
                self.playing = False

            # Need to check this, so we don't do pointless work.
            if not self.queue:
                break

            # If the pcm_queue is full, then we can't queue
            # anything, regardless of if it is midi or pcm.
            if depth >= 2:
                break

            # If we can't buffer things, and we're playing something
            # give up here.
            if not self.buffer_queue and depth >= 1:
                break

            # We can't queue anything if the depth is > 0 and we're
            # waiting for a synchro_start.
            if self.synchro_start and depth:
                break

            # If the queue is full, return.
            if renpysound.queue_depth(self.number) >= 2:
                break

            # Otherwise, we might be able to enqueue something.
            topq = self.queue.pop(0)

            # Blacklist of old file formats we used to support, but we now
            # ignore.
            lfn = topq.filename.lower() + self.file_suffix.lower()
            for i in (".mod", ".xm", ".mid", ".midi"):
                if lfn.endswith(i):
                    topq = None

            if not topq:
                continue

            try:
                filename, start, end = self.split_filename(topq.filename, topq.loop)

                if (end >= 0) and ((end - start) <= 0) and self.queue:
                    continue

                topf = load(self.file_prefix + filename + self.file_suffix)

                renpysound.set_video(self.number, self.movie)

                if depth == 0:
                    renpysound.play(self.number, topf, topq.filename, paused=self.synchro_start, fadein=topq.fadein, tight=topq.tight, start=start, end=end)
                else:
                    renpysound.queue(self.number, topf, topq.filename, fadein=topq.fadein, tight=topq.tight, start=start, end=end)

                self.playing = True

            except:

                # If playing failed, remove topq.filename from self.loop
                # so we don't keep trying.
                while topq.filename in self.loop:
                    self.loop.remove(topq.filename)

                if renpy.config.debug_sound and not renpy.game.after_rollback:
                    raise
                else:
                    return

            break

        if self.loop and not self.queue:
            for i in self.loop:
                if topq is not None:
                    newq = QueueEntry(i, 0, topq.tight, True)
                else:
                    newq = QueueEntry(i, 0, False, True)

                self.queue.append(newq)
        else:
            do_callback = True

        # Queue empty callback.
        if do_callback and self.callback:
            self.callback()  # E1102

        want_pause = self.context.pause or global_pause

        if self.paused != want_pause:

            if want_pause:
                self.pause()
            else:
                self.unpause()

            self.paused = want_pause
Esempio n. 5
0
    def periodic(self):
        """
        This is the periodic call that causes this channel to load new stuff
        into its queues, if necessary.
        """

        # Update the channel volume.

        mixer_volume = renpy.game.preferences.volumes.get(self.mixer, 1.0)

        if renpy.game.preferences.self_voicing:
            if self.mixer not in renpy.config.voice_mixers:
                mixer_volume = mixer_volume * renpy.game.preferences.self_voicing_volume_drop

        vol = self.chan_volume * mixer_volume

        if vol != self.actual_volume:
            renpysound.set_volume(self.number, vol)
            self.actual_volume = vol

        # This should be set from something that checks to see if our
        # mixer is muted.
        force_stop = self.context.force_stop or (
            renpy.game.preferences.mute.get(self.mixer, False)
            and self.stop_on_mute)

        if self.playing and force_stop:
            renpysound.stop(self.number)
            self.playing = False

        if force_stop:
            self.wait_stop = False

            if self.loop:
                self.queue = self.queue[-len(self.loop):]
            else:
                self.queue = []
            return

        topq = None

        # This has been modified so we only queue a single sound file
        # per call, to prevent memory leaks with really short sound
        # files. So this loop will only execute once, in practice.
        while True:

            depth = renpysound.queue_depth(self.number)

            if depth == 0:
                self.wait_stop = False
                self.playing = False

            # Need to check this, so we don't do pointless work.
            if not self.queue:
                break

            # If the pcm_queue is full, then we can't queue
            # anything, regardless of if it is midi or pcm.
            if depth >= 2:
                break

            # If we can't buffer things, and we're playing something
            # give up here.
            if not self.buffer_queue and depth >= 1:
                break

            # We can't queue anything if the depth is > 0 and we're
            # waiting for a synchro_start.
            if self.synchro_start and depth:
                break

            # If the queue is full, return.
            if renpysound.queue_depth(self.number) >= 2:
                break

            # Otherwise, we might be able to enqueue something.
            topq = self.queue.pop(0)

            # Blacklist of old file formats we used to support, but we now
            # ignore.
            lfn = topq.filename.lower() + self.file_suffix.lower()
            for i in (".mod", ".xm", ".mid", ".midi"):
                if lfn.endswith(i):
                    topq = None

            if not topq:
                continue

            try:
                filename, start, end = self.split_filename(
                    topq.filename, topq.loop)

                self.set_tertiary_volume(topq.relative_volume)

                if (end >= 0) and ((end - start) <= 0) and self.queue:
                    continue

                if isinstance(topq.filename, AudioData):
                    topf = io.BytesIO(topq.filename.data)
                else:
                    topf = load(self.file_prefix + filename + self.file_suffix)

                renpysound.set_video(self.number, self.movie)

                if depth == 0:
                    renpysound.play(self.number,
                                    topf,
                                    topq.filename,
                                    paused=self.synchro_start,
                                    fadein=topq.fadein,
                                    tight=topq.tight,
                                    start=start,
                                    end=end)
                else:
                    renpysound.queue(self.number,
                                     topf,
                                     topq.filename,
                                     fadein=topq.fadein,
                                     tight=topq.tight,
                                     start=start,
                                     end=end)

                self.playing = True

            except:

                # If playing failed, remove topq.filename from self.loop
                # so we don't keep trying.
                while topq.filename in self.loop:
                    self.loop.remove(topq.filename)

                if renpy.config.debug_sound and not renpy.game.after_rollback:
                    raise
                else:
                    return

            break

        # Empty queue?
        if not self.queue:
            # Re-loop:
            if self.loop:
                for i in self.loop:
                    if topq is not None:
                        newq = QueueEntry(i, 0, topq.tight, True,
                                          topq.relative_volume)
                    else:
                        newq = QueueEntry(i, 0, False, True,
                                          topq.relative_volume)

                    self.queue.append(newq)
            # Try callback:
            elif self.callback:
                self.callback()  # E1102

        want_pause = self.context.pause or global_pause

        if self.paused != want_pause:

            if want_pause:
                self.pause()
            else:
                self.unpause()

            self.paused = want_pause