Compare commits

...

2 Commits

Author SHA1 Message Date
Keith Edmunds
d3834928fd Remove padding around volume graph 2023-06-22 00:24:32 +01:00
Keith Edmunds
09f0e11aa7 Improve clock management
- tick() implemented independently of Config.TIMER_MS
 - have tick() call periodic functions
 - don't rely on vlc get_time() (too coarse)
2023-06-19 09:40:32 +01:00
3 changed files with 105 additions and 89 deletions

View File

@ -69,7 +69,6 @@ class Config(object):
MAX_MISSING_FILES_TO_REPORT = 10
MILLISECOND_SIGFIGS = 0
MINIMUM_ROW_HEIGHT = 30
MYSQL_CONNECT = os.environ.get('MYSQL_CONNECT') or "mysql+mysqldb://musicmuster:musicmuster@localhost/musicmuster_v2" # noqa E501
NOTE_TIME_FORMAT = "%H:%M:%S"
OBS_HOST = "localhost"
OBS_PASSWORD = "auster"

View File

@ -91,14 +91,6 @@ class Music:
fader = FadeTrack(p)
pool.start(fader)
def get_playtime(self) -> Optional[int]:
"""Return elapsed play time"""
if not self.player:
return None
return self.player.get_time()
def get_position(self) -> Optional[float]:
"""Return current position"""

View File

@ -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,14 +1722,24 @@ 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
def tick_500ms(self) -> None:
"""
Called every 500ms
"""
self.lblTOD.setText(datetime.now().strftime(
Config.TOD_TIME_FORMAT))
# Update carts
self.cart_tick()
if self.clock_counter % 50 == 0:
def tick_1000ms(self) -> None:
"""
Called every 1000ms
"""
# Only update play clocks once a second so that their updates
# are synchronised (otherwise it looks odd)
if not self.playing:
return
@ -1727,7 +1752,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.music.player.is_playing() or
(datetime.now() - self.current_track.start_time)
< timedelta(microseconds=Config.PLAY_SETTLE)):
playtime = self.music.get_playtime()
playtime = self.get_playtime()
time_to_fade = (self.current_track.fade_at - playtime)
time_to_silence = (
self.current_track.silence_at - playtime)