Пример #1
0
class Player:
    async_queue_size = 3  # larger is less chance of getting skips, but latency increases
    update_rate = 40  # larger is less cpu usage but more chance of getting skips
    levelmeter_lowest = -40  # dB

    def __init__(self, app):
        self.app = app
        self.app.after(self.update_rate, self.tick)
        self.app.firstTrackFrame.play()
        self.stopping = False
        self.mixer = StreamMixer([], endless=True)
        self.output = Output(self.mixer.samplerate,
                             self.mixer.samplewidth,
                             self.mixer.nchannels,
                             queuesize=self.async_queue_size)
        self.mixed_samples = iter(self.mixer)
        self.levelmeter = LevelMeter(rms_mode=False,
                                     lowest=self.levelmeter_lowest)

    def stop(self):
        self.stopping = True
        self.app.firstTrackFrame.close_stream()
        self.app.secondTrackFrame.close_stream()
        self.mixer.close()
        self.output.close()

    def switch_player(self):
        """
        The actual switching of the main track player. Note that it can be playing
        already because of the fade-in mixing.
        """
        first_is_playing = self.app.firstTrackFrame.playing
        self.app.firstTrackFrame.play(not first_is_playing)
        self.app.secondTrackFrame.play(first_is_playing)

    def tick(self):
        if self.output.queue_size() <= self.async_queue_size / 2:
            self.app.firstTrackFrame.tick(self.mixer)
            self.app.secondTrackFrame.tick(self.mixer)
            _, sample = next(self.mixed_samples)
            if sample and sample.duration > 0:
                self.output.play_sample(sample, async=True)
                left, _, right, _ = self.levelmeter.update(sample)
                self.app.update_levels(left, right)
            else:
                self.levelmeter.reset()
                self.app.update_levels(self.levelmeter.level_left,
                                       self.levelmeter.level_right)
        if not self.stopping:
            self.app.after(self.update_rate, self.tick)

    def play_sample(self, sample):
        if sample and sample.duration > 0:
            self.mixer.add_sample(sample)

    def start_play_other(self):
        # @todo fix the track switching and fadein/fadeout, it's a bit of a mess
        if self.app.firstTrackFrame.playing:
            other_track = self.app.secondTrackFrame
        else:
            other_track = self.app.firstTrackFrame
        other_track.start_fadein()