# events.py import soundfile import sounddevice import timings import display import numpy as np class Event: def __init__(self, at='start'): self._at = timings.Timing(at) def set_timings(self, timings): self._at.set_timings(timings) def set_audiencecontent(self, audiencecontent): self.audiencecontent = audiencecontent @property def scheduled(self): return self._at.scheduled @scheduled.setter def scheduled(self, value): self._at.scheduled = value @property def at(self): return self._at.at def prepare(self): pass def start(self): pass def stop(self): pass class Display(Event): def __init__(self, media, *args, **kwargs): super().__init__(*args, **kwargs) self._media = media class Playback(Event): def __init__(self, media, device=None, channels=[1,2], tempo=None, beats=None, leadin=0, loop=False, *args, **kwargs): super().__init__(*args, **kwargs) self._media = media self._device = device self._mapping = np.atleast_1d(np.array(channels, copy=True)) self._channels = self._mapping.max() self._mapping -= 1 self._tempo = tempo self._beats = beats self._leadin = leadin self._loop = loop def prepare(self): self._at._timings.register_tempo(self._tempo, self._beats, self._at) # def start(self): # print("Start playback") # data, fs = soundfile.read(self._media) # sounddevice.play(data, fs, device=self._device, mapping=self._mapping) def start(self): print("Start playback") self._data, fs = soundfile.read(self._media) self._current_frame = 0 self._stream = sounddevice.OutputStream( samplerate=fs, device=self._device, channels=self._channels, callback=self.callback, finished_callback=self.finished_callback) self._stream.start() def callback(self, outdata, frames, time, status): if status: print(status) chunksize = min(len(self._data) - self._current_frame, frames) outdata[:chunksize, self._mapping] = self._data[self._current_frame:self._current_frame + chunksize] if chunksize < frames: outdata[chunksize:, self._mapping] = 0 raise sounddevice.CallbackStop() self._current_frame += chunksize def finished_callback(self): self._data = None print("Playback finished") def stop(self): print("Stop playback") self._stream.stop(True) self._stream.close(True) self._stream = None class SetTempo(Event): def __init__(self, tempo=None, beats=None, *args, **kwargs): super().__init__(*args, **kwargs) self._tempo = tempo self._beats = beats def prepare(self): self._at._timings.register_tempo(self._tempo, self._beats, self._at) def start(self): pass def stop(self): pass class SetMark(Event): def __init__(self, name, *args, **kwargs): super().__init__(*args, **kwargs) self._name = name def prepare(self): self._at._timings.register_mark(self._name, self._at) def start(self): pass def stop(self): pass class ButtonMark(Event): def __init__(self, name, *args, **kwargs): super().__init__(*args, **kwargs) self._name = name def prepare(self): self._at._timings.register_mark(self._name, None) def start(self): pass def stop(self): pass class Lyrics(Event): def __init__(self, text, duration=None, *args, **kwargs): super().__init__(*args, **kwargs) self._text = text self._duration = duration def start(self): self.audiencecontent.new_content(display.DisplayLyrics(self._text)) print("Started displaying lyrics") print(self._text) def stop(self): self.audiencecontent.new_content(display.DisplayContent()) print("Stopped displaying lyrics")