|
|
|
|
@ -357,6 +357,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|
|
|
|
mixer.init()
|
|
|
|
|
self.widgetFadeVolume.hideAxis('bottom')
|
|
|
|
|
self.widgetFadeVolume.hideAxis('left')
|
|
|
|
|
self.widgetFadeVolume.setDefaultPadding(0)
|
|
|
|
|
self.widgetFadeVolume.setBackground(Config.FADE_CURVE_BACKGROUND)
|
|
|
|
|
FadeCurve.GraphWidget = self.widgetFadeVolume
|
|
|
|
|
|
|
|
|
|
@ -915,6 +916,24 @@ class Window(QMainWindow, Ui_MainWindow):
|
|
|
|
|
else:
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def get_playtime(self) -> int:
|
|
|
|
|
"""
|
|
|
|
|
Return number of milliseconds current track has been playing or
|
|
|
|
|
zero if not playing. The vlc function get_time() only updates 3-4
|
|
|
|
|
times a second; this function has much better resolution.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
self.current_track.track_id is None or
|
|
|
|
|
self.current_track.start_time is None
|
|
|
|
|
):
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
now = datetime.now()
|
|
|
|
|
track_start = self.current_track.start_time
|
|
|
|
|
elapsed_seconds = (now - track_start).total_seconds()
|
|
|
|
|
return int(elapsed_seconds * 1000)
|
|
|
|
|
|
|
|
|
|
def hide_played(self):
|
|
|
|
|
"""Toggle hide played tracks"""
|
|
|
|
|
|
|
|
|
|
@ -1671,29 +1690,25 @@ class Window(QMainWindow, Ui_MainWindow):
|
|
|
|
|
|
|
|
|
|
def tick(self) -> None:
|
|
|
|
|
"""
|
|
|
|
|
Carry out clock tick actions.
|
|
|
|
|
Called every Config.TIMER_MS milliseconds. Call periodic functions
|
|
|
|
|
as required.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
self.clock_counter is incrememted at each tick (100ms), and this
|
|
|
|
|
value is used to determine the actions to take.
|
|
|
|
|
# Get current number of milliseconds
|
|
|
|
|
self.clock_counter += Config.TIMER_MS
|
|
|
|
|
self.clock_counter %= 1000
|
|
|
|
|
|
|
|
|
|
The Fade Volume graph is updated every 10ms.
|
|
|
|
|
# Call periodic functions
|
|
|
|
|
if self.clock_counter % 10 == 0:
|
|
|
|
|
self.tick_10ms()
|
|
|
|
|
if self.clock_counter % 500 == 0:
|
|
|
|
|
self.tick_500ms()
|
|
|
|
|
if self.clock_counter == 0:
|
|
|
|
|
self.tick_1000ms()
|
|
|
|
|
|
|
|
|
|
The Time of Day clock and any cart progress bars are updated
|
|
|
|
|
every 500ms.
|
|
|
|
|
|
|
|
|
|
All other timers are updated every second. As the timer displays
|
|
|
|
|
have a one-second resolution, updating every 500ms can result in
|
|
|
|
|
some timers updating and then, 500ms later, other timers
|
|
|
|
|
updating. That looks odd.
|
|
|
|
|
|
|
|
|
|
Actions required:
|
|
|
|
|
- Update Fade Volume graph
|
|
|
|
|
- Update TOD clock
|
|
|
|
|
- Call cart_tick
|
|
|
|
|
- If track is playing:
|
|
|
|
|
update track clocks time and colours
|
|
|
|
|
- Else:
|
|
|
|
|
run stop_track
|
|
|
|
|
def tick_10ms(self) -> None:
|
|
|
|
|
"""
|
|
|
|
|
Called every 10ms
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# Update volume fade curve
|
|
|
|
|
@ -1707,74 +1722,84 @@ class Window(QMainWindow, Ui_MainWindow):
|
|
|
|
|
).total_seconds() * 1000
|
|
|
|
|
self.current_track.fade_graph.tick(play_time)
|
|
|
|
|
|
|
|
|
|
if self.clock_counter % 20 == 0:
|
|
|
|
|
# Update TOD clock
|
|
|
|
|
self.lblTOD.setText(datetime.now().strftime(
|
|
|
|
|
Config.TOD_TIME_FORMAT))
|
|
|
|
|
# Update carts
|
|
|
|
|
self.cart_tick()
|
|
|
|
|
def tick_500ms(self) -> None:
|
|
|
|
|
"""
|
|
|
|
|
Called every 500ms
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
if self.clock_counter % 50 == 0:
|
|
|
|
|
if not self.playing:
|
|
|
|
|
return
|
|
|
|
|
self.lblTOD.setText(datetime.now().strftime(
|
|
|
|
|
Config.TOD_TIME_FORMAT))
|
|
|
|
|
# Update carts
|
|
|
|
|
self.cart_tick()
|
|
|
|
|
|
|
|
|
|
# If track is playing, update track clocks time and colours
|
|
|
|
|
# There is a discrete time between starting playing a track and
|
|
|
|
|
# player.is_playing() returning True, so assume playing if less
|
|
|
|
|
# than Config.PLAY_SETTLE microseconds have passed since
|
|
|
|
|
# starting play.
|
|
|
|
|
if self.music.player and self.current_track.start_time and (
|
|
|
|
|
self.music.player.is_playing() or
|
|
|
|
|
(datetime.now() - self.current_track.start_time)
|
|
|
|
|
< timedelta(microseconds=Config.PLAY_SETTLE)):
|
|
|
|
|
playtime = self.music.get_playtime()
|
|
|
|
|
time_to_fade = (self.current_track.fade_at - playtime)
|
|
|
|
|
time_to_silence = (
|
|
|
|
|
self.current_track.silence_at - playtime)
|
|
|
|
|
time_to_end = (self.current_track.duration - playtime)
|
|
|
|
|
def tick_1000ms(self) -> None:
|
|
|
|
|
"""
|
|
|
|
|
Called every 1000ms
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# Elapsed time
|
|
|
|
|
self.label_elapsed_timer.setText(helpers.ms_to_mmss(playtime))
|
|
|
|
|
# Only update play clocks once a second so that their updates
|
|
|
|
|
# are synchronised (otherwise it looks odd)
|
|
|
|
|
|
|
|
|
|
# Time to fade
|
|
|
|
|
self.label_fade_timer.setText(helpers.ms_to_mmss(time_to_fade))
|
|
|
|
|
if not self.playing:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# If silent in the next 5 seconds, put warning colour on
|
|
|
|
|
# time to silence box and enable play controls
|
|
|
|
|
if time_to_silence <= 5500:
|
|
|
|
|
self.frame_silent.setStyleSheet(
|
|
|
|
|
f"background: {Config.COLOUR_ENDING_TIMER}"
|
|
|
|
|
)
|
|
|
|
|
self.enable_play_next_controls()
|
|
|
|
|
# Set warning colour on time to silence box when fade starts
|
|
|
|
|
elif time_to_fade <= 500:
|
|
|
|
|
self.frame_silent.setStyleSheet(
|
|
|
|
|
f"background: {Config.COLOUR_WARNING_TIMER}"
|
|
|
|
|
)
|
|
|
|
|
# Five seconds before fade starts, set warning colour on
|
|
|
|
|
# time to silence box and enable play controls
|
|
|
|
|
elif time_to_fade <= 5500:
|
|
|
|
|
self.frame_fade.setStyleSheet(
|
|
|
|
|
f"background: {Config.COLOUR_WARNING_TIMER}"
|
|
|
|
|
)
|
|
|
|
|
self.enable_play_next_controls()
|
|
|
|
|
else:
|
|
|
|
|
self.frame_silent.setStyleSheet("")
|
|
|
|
|
self.frame_fade.setStyleSheet("")
|
|
|
|
|
# If track is playing, update track clocks time and colours
|
|
|
|
|
# There is a discrete time between starting playing a track and
|
|
|
|
|
# player.is_playing() returning True, so assume playing if less
|
|
|
|
|
# than Config.PLAY_SETTLE microseconds have passed since
|
|
|
|
|
# starting play.
|
|
|
|
|
if self.music.player and self.current_track.start_time and (
|
|
|
|
|
self.music.player.is_playing() or
|
|
|
|
|
(datetime.now() - self.current_track.start_time)
|
|
|
|
|
< timedelta(microseconds=Config.PLAY_SETTLE)):
|
|
|
|
|
playtime = self.get_playtime()
|
|
|
|
|
time_to_fade = (self.current_track.fade_at - playtime)
|
|
|
|
|
time_to_silence = (
|
|
|
|
|
self.current_track.silence_at - playtime)
|
|
|
|
|
time_to_end = (self.current_track.duration - playtime)
|
|
|
|
|
|
|
|
|
|
self.label_silent_timer.setText(
|
|
|
|
|
helpers.ms_to_mmss(time_to_silence)
|
|
|
|
|
# Elapsed time
|
|
|
|
|
self.label_elapsed_timer.setText(helpers.ms_to_mmss(playtime))
|
|
|
|
|
|
|
|
|
|
# Time to fade
|
|
|
|
|
self.label_fade_timer.setText(helpers.ms_to_mmss(time_to_fade))
|
|
|
|
|
|
|
|
|
|
# If silent in the next 5 seconds, put warning colour on
|
|
|
|
|
# time to silence box and enable play controls
|
|
|
|
|
if time_to_silence <= 5500:
|
|
|
|
|
self.frame_silent.setStyleSheet(
|
|
|
|
|
f"background: {Config.COLOUR_ENDING_TIMER}"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Time to end
|
|
|
|
|
self.label_end_timer.setText(helpers.ms_to_mmss(time_to_end))
|
|
|
|
|
|
|
|
|
|
# Autoplay next track
|
|
|
|
|
# if time_to_silence <= 1500:
|
|
|
|
|
# self.play_next()
|
|
|
|
|
self.enable_play_next_controls()
|
|
|
|
|
# Set warning colour on time to silence box when fade starts
|
|
|
|
|
elif time_to_fade <= 500:
|
|
|
|
|
self.frame_silent.setStyleSheet(
|
|
|
|
|
f"background: {Config.COLOUR_WARNING_TIMER}"
|
|
|
|
|
)
|
|
|
|
|
# Five seconds before fade starts, set warning colour on
|
|
|
|
|
# time to silence box and enable play controls
|
|
|
|
|
elif time_to_fade <= 5500:
|
|
|
|
|
self.frame_fade.setStyleSheet(
|
|
|
|
|
f"background: {Config.COLOUR_WARNING_TIMER}"
|
|
|
|
|
)
|
|
|
|
|
self.enable_play_next_controls()
|
|
|
|
|
else:
|
|
|
|
|
if self.playing:
|
|
|
|
|
self.stop_playing()
|
|
|
|
|
self.frame_silent.setStyleSheet("")
|
|
|
|
|
self.frame_fade.setStyleSheet("")
|
|
|
|
|
|
|
|
|
|
self.label_silent_timer.setText(
|
|
|
|
|
helpers.ms_to_mmss(time_to_silence)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Time to end
|
|
|
|
|
self.label_end_timer.setText(helpers.ms_to_mmss(time_to_end))
|
|
|
|
|
|
|
|
|
|
# Autoplay next track
|
|
|
|
|
# if time_to_silence <= 1500:
|
|
|
|
|
# self.play_next()
|
|
|
|
|
else:
|
|
|
|
|
if self.playing:
|
|
|
|
|
self.stop_playing()
|
|
|
|
|
|
|
|
|
|
def update_headers(self) -> None:
|
|
|
|
|
"""
|
|
|
|
|
|