46 lines
1.2 KiB
Python
46 lines
1.2 KiB
Python
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
|