Add functionality to set a marker when playback is replaced.

This commit is contained in:
2026-09-17 18:04:37 +01:00
parent 14a05e8694
commit 985c46772b

View File

@@ -110,6 +110,7 @@ class Playback(Event):
self._nextdata = None
self._nextfs = None
self._delay = False
self._setmark = None
self._stream = sounddevice.OutputStream(
samplerate=self._fs, device=self._device, channels=self._channels,
@@ -136,6 +137,9 @@ class Playback(Event):
raise sounddevice.CallbackStop()
self._current_frame += frames
frames = 0
if self._setmark is not None:
self._eventrunner.activate(self._setmark)
self._setmark = None
def callback_fillchunk(self, outdata, offset, frames):
chunksize = min(len(self._data) - self._current_frame, frames)
@@ -171,19 +175,20 @@ class Playback(Event):
self._stream.close(True)
self._stream = None
def replace(self, media, delay=False, loop=False):
def replace(self, media, delay=False, loop=False, setmark=None):
self._nextdata, self._nextfs = soundfile.read(media)
self._delay = delay
self._nextloop = loop
self._setmark = setmark
# We really should check that the media is the sampe shape as the
# existing playback. But for now, let's trust the user. *cough*
def notify(self, message, fadetime=10, db=30, media=None, delay=False, *args, **kwargs):
def notify(self, message, fadetime=10, db=30, media=None, delay=False, setmark=None, *args, **kwargs):
if message == 'fadeout':
self._fadecurve = np.logspace(0, -db/10, fadetime * self._fs)
self._fadeframe = 0
elif message == 'replaceplayback':
self.replace(media, delay)
self.replace(media, delay, setmark=setmark)
elif message == 'endloop':
self._loop = False
@@ -215,18 +220,23 @@ class EndLoop(Event):
class PlaybackNext(Event):
def __init__(self, media, delay=False, loop=False, *args, **kwargs):
def __init__(self, media, delay=False, loop=False, setmark=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self._media = media
self._delay = delay
self._loop = loop
self._setmark = setmark
def __repr__(self):
return '{}(at={}, media={}, delay={}, loop={})'.format(type(self).__name__, self._at, self._media, self._delay, self._loop)
return '{}(at={}, media={}, delay={}, loop={}, setmark={})'.format(type(self).__name__, self._at, self._media, self._delay, self._loop, self._setmark)
def prepare(self):
if self._setmark is not None:
self._at._timings.register_mark(self._setmark, None)
def start(self):
print("Replacing playback")
self._eventrunner.notify('replaceplayback', media=self._media, delay=self._delay, loop=self._loop)
self._eventrunner.notify('replaceplayback', media=self._media, delay=self._delay, loop=self._loop, setmark=self._setmark)
self._eventrunner.finished(self)
class SetTempo(Event):