You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
45 lines
1.2 KiB
45 lines
1.2 KiB
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
|
|
|