From 8c60d6a03d317953bf37df634536a0d3273991b6 Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Sat, 3 Jan 2026 21:37:50 +0000 Subject: [PATCH] Jitter monitor phase 0 --- app/jittermonitor.py | 27 +++++++++++++++++++++++++++ app/musicmuster.py | 4 ++++ 2 files changed, 31 insertions(+) create mode 100644 app/jittermonitor.py diff --git a/app/jittermonitor.py b/app/jittermonitor.py new file mode 100644 index 0000000..4b1bf6c --- /dev/null +++ b/app/jittermonitor.py @@ -0,0 +1,27 @@ +from PyQt6.QtCore import QObject, QTimer, QElapsedTimer, pyqtSignal + +class EventLoopJitterMonitor(QObject): + long_pause_detected = pyqtSignal(float) # pause length in ms + + def __init__(self, parent=None, interval_ms: int = 20, threshold_ms: int = 80): + super().__init__(parent) + self._interval = interval_ms + self._threshold = threshold_ms + self._timer = QTimer(self) + self._timer.setInterval(self._interval) + self._timer.timeout.connect(self._on_timeout) + self._elapsed = QElapsedTimer() + self._elapsed.start() + self._last = self._elapsed.elapsed() + + def start(self) -> None: + self._timer.start() + + def _on_timeout(self) -> None: + now = self._elapsed.elapsed() + delta = now - self._last # ms since last timeout + self._last = now + if delta > self._interval + self._threshold: + # log somewhere with timestamp + current track + position + print(f"[JITTER] {delta} ms gap in event loop") + self.long_pause_detected.emit(delta) diff --git a/app/musicmuster.py b/app/musicmuster.py index 1059ddd..da3c025 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -90,6 +90,7 @@ from ui.main_window_footer_ui import Ui_FooterSection # type: ignore from utilities import check_db, update_bitrates import helpers +from jittermonitor import EventLoopJitterMonitor class Current: base_model: PlaylistModel @@ -1206,6 +1207,9 @@ class Window(QMainWindow): self.action_quicklog = QShortcut(QKeySequence("Ctrl+L"), self) self.action_quicklog.activated.connect(self.quicklog) + self.jitter_monitor = EventLoopJitterMonitor(self) + self.jitter_monitor.start() + self.load_last_playlists() self.stop_autoplay = False