import time from typing import Optional class Tempo(object): _last_beat: float _override_beat: Optional[float] = None def __init__(self, bpm: float = 60): self._bpm: float = bpm self.update_last_beat() def set_bpm(self, bpm: float) -> None: self._bpm = bpm def get_bpm(self) -> float: return self._bpm def update_last_beat(self) -> None: self._last_beat = time.time() def get_beat_time(self) -> float: return 1000 / (self._bpm / 60) def get_beat_delay(self) -> Optional[float]: tick = self._override_beat if tick is None: return None self._override_beat = None return tick - self._last_beat def sync_beat(self): self._override_beat = time.time() def wait(self, beat_divider: int = 1): now = time.time() next_beat = self._last_beat + (self.get_beat_time() / beat_divider / 1000) wait_time = next_beat - now beat_delay = self.get_beat_delay() if beat_delay is not None: wait_time += beat_delay if wait_time > 0: time.sleep(wait_time) self.update_last_beat() return True