def __init__(self, engine): AudioStream.idx += 1 self.name = '%s-audiostream-%s' % (engine.name, self.idx) self.engine = engine self.logger = logging.getLogger('%s [%s-a%s]' % (__name__, engine.name, self.idx)) # track being played by this stream self.current_track = None self.buffered_track = None # This exists because if there is a sink error, it doesn't # really make sense to recreate the sink -- it'll just fail # again. Instead, wait for the user to try to play a track, # and maybe the issue has resolved itself (plugged device in?) self.needs_sink = True self.last_position = 0 self.audio_filters = gst_utils.ProviderBin('gst_audio_filter', '%s-filters' % self.name) self.playbin = Gst.ElementFactory.make("playbin", "%s-playbin" % self.name) if self.playbin is None: raise TypeError("gstreamer 1.x base plugins not installed!") gst_utils.disable_video_text(self.playbin) self.playbin.connect("about-to-finish", self.on_about_to_finish) video = Gst.ElementFactory.make("fakesink", '%s-fakevideo' % self.name) video.set_property('sync', True) self.playbin.set_property('video-sink', video) self.audio_sink = DynamicAudioSink('%s-sink' % self.name) self.playbin.set_property('audio-sink', self.audio_sink) # Setup the bus bus = self.playbin.get_bus() bus.add_signal_watch() bus.connect('message', self.on_message) # priority boost hack if needed priority_boost(self.playbin) # Pulsesink changes volume behind our back, track it self.playbin.connect('notify::volume', self.on_volume_change) self.fader = TrackFader(self, self.on_fade_out_begin, '%s-fade-%s' % (engine.name, self.idx))
def test_calculate_fades(): fader = TrackFader(None, None, None) # fin, fout, start_off, stop_off, tracklen; # start, start+fade, end-fade, end calcs = [ # fmt: off # one is zero/none (0, 4, 0, 0, 10, 0, 0, 6, 10), (None, 4, 0, 0, 10, 0, 0, 6, 10), # other is zero/none (4, 0, 0, 0, 10, 0, 4, 10, 10), (4, None, 0, 0, 10, 0, 4, 10, 10), # both are equal (4, 4, 0, 0, 10, 0, 4, 6, 10), # both are none (0, 0, 0, 0, 10, 0, 0, 10, 10), (None, None, 0, 0, 10, 0, 0, 10, 10), # Bigger than playlen: all three cases (0, 4, 0, 0, 2, 0, 0, 0, 2), (4, 0, 0, 0, 2, 0, 2, 2, 2), (4, 4, 0, 0, 2, 0, 1, 1, 2), # With start offset (4, 4, 1, 0, 10, 1, 5, 6, 10), # With stop offset (4, 4, 0, 9, 10, 0, 4, 5, 9), # With both (2, 2, 1, 9, 10, 1, 3, 7, 9), # With both, constrained (4, 4, 4, 8, 10, 4, 6, 6, 8), (2, 4, 4, 7, 10, 4, 5, 5, 7), (4, 2, 4, 7, 10, 4, 6, 6, 7), # fmt: on ] i = 0 for fin, fout, start, stop, tlen, t0, t1, t2, t3 in calcs: print('%2d: Fade In: %s; Fade Out: %s; start: %s; stop: %s; Len: %s' % (i, fin, fout, start, stop, tlen)) track = FakeTrack(start, stop, tlen) assert fader.calculate_fades(track, fin, fout) == (t0, t1, t2, t3) i += 1
def check_fader(test): stream = FakeStream() fader = TrackFader(stream, stream.on_fade_out, 'test') for data in test: print(data) now = data[0] stream.position = int(now * TrackFader.SECOND) print(stream.position) volume = data[1] state = data[2] timer_id = data[3] if len(data) > 4: action = data[4] args = data[5:] if len(data) > 5 else () if action == 'start': action = '_on_fade_start' elif action == 'execute': action = '_execute_fade' args = timeout_args[0] fader.now = now - 0.010 # Call the function getattr(fader, action)(*args) # Check to see if timer id exists if timer_id is None: assert fader.timer_id is None elif timer_id == TmSt: assert fader.timer_id == fader._on_fade_start elif timer_id == TmEx: assert fader.timer_id == fader._execute_fade else: assert False assert fader.state == state assert stream.volume == volume