Fadeouts and gain
This commit is contained in:
60
events.py
60
events.py
@@ -16,7 +16,10 @@ class Event:
|
||||
self._at.set_timings(timings)
|
||||
|
||||
def set_audiencecontent(self, audiencecontent):
|
||||
self.audiencecontent = audiencecontent
|
||||
self._audiencecontent = audiencecontent
|
||||
|
||||
def set_eventrunner(self, eventrunner):
|
||||
self._eventrunner = eventrunner
|
||||
|
||||
@property
|
||||
def scheduled(self):
|
||||
@@ -39,6 +42,9 @@ class Event:
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def notify(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
class Display(Event):
|
||||
def __init__(self, media, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -46,7 +52,7 @@ class Display(Event):
|
||||
|
||||
|
||||
class Playback(Event):
|
||||
def __init__(self, media, device=None, channels=[1,2], tempo=None, beats=None, leadin=0, loop=False, *args, **kwargs):
|
||||
def __init__(self, media, device=None, channels=[1,2], tempo=None, beats=None, leadin=0, loop=False, gain=0, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._media = media
|
||||
self._device = device
|
||||
@@ -57,6 +63,9 @@ class Playback(Event):
|
||||
self._beats = beats
|
||||
self._leadin = leadin
|
||||
self._loop = loop
|
||||
self._gain = 10**(gain/10) # Convert from dB to linear gain
|
||||
self._fadecurve = None
|
||||
self._fadeframe = None
|
||||
|
||||
def prepare(self):
|
||||
self._at._timings.register_tempo(self._tempo, self._beats, self._at)
|
||||
@@ -68,11 +77,13 @@ class Playback(Event):
|
||||
|
||||
def start(self):
|
||||
print("Start playback")
|
||||
self._data, fs = soundfile.read(self._media)
|
||||
self._data, self._fs = soundfile.read(self._media)
|
||||
self._current_frame = 0
|
||||
self._fadecurve = None
|
||||
self._fadeframe = None
|
||||
|
||||
self._stream = sounddevice.OutputStream(
|
||||
samplerate=fs, device=self._device, channels=self._channels,
|
||||
samplerate=self._fs, device=self._device, channels=self._channels,
|
||||
callback=self.callback, finished_callback=self.finished_callback)
|
||||
self._stream.start()
|
||||
|
||||
@@ -80,7 +91,12 @@ class Playback(Event):
|
||||
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 self._fadecurve is not None:
|
||||
chunksize = min(chunksize, len(self._fadecurve) - self._fadeframe)
|
||||
outdata[:chunksize, self._mapping] = self._data[self._current_frame:self._current_frame + chunksize] * self._gain
|
||||
if self._fadecurve is not None:
|
||||
outdata[:chunksize, self._mapping] *= self._fadecurve[self._fadeframe:self._fadeframe + chunksize, np.newaxis]
|
||||
self._fadeframe += chunksize
|
||||
if chunksize < frames:
|
||||
outdata[chunksize:, self._mapping] = 0
|
||||
raise sounddevice.CallbackStop()
|
||||
@@ -88,7 +104,10 @@ class Playback(Event):
|
||||
|
||||
def finished_callback(self):
|
||||
self._data = None
|
||||
self._fadecurve = None
|
||||
self._fadeframe = None
|
||||
print("Playback finished")
|
||||
self._eventrunner.finished(self)
|
||||
|
||||
def stop(self):
|
||||
print("Stop playback")
|
||||
@@ -96,6 +115,22 @@ class Playback(Event):
|
||||
self._stream.close(True)
|
||||
self._stream = None
|
||||
|
||||
def notify(self, message, fadetime=10, db=30, *args, **kwargs):
|
||||
if message == 'fadeout':
|
||||
self._fadecurve = np.logspace(0, -db/10, fadetime * self._fs)
|
||||
self._fadeframe = 0
|
||||
|
||||
class FadeOut(Event):
|
||||
def __init__(self, duration=10, db=30, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._duration = duration
|
||||
self._db = db
|
||||
|
||||
def start(self):
|
||||
print("Fading out")
|
||||
self._eventrunner.notify('fadeout', fadetime=self._duration, db=self._db)
|
||||
self._eventrunner.finished(self)
|
||||
|
||||
class SetTempo(Event):
|
||||
def __init__(self, tempo=None, beats=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -106,7 +141,7 @@ class SetTempo(Event):
|
||||
self._at._timings.register_tempo(self._tempo, self._beats, self._at)
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
self._eventrunner.finished(self)
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
@@ -120,7 +155,7 @@ class SetMark(Event):
|
||||
self._at._timings.register_mark(self._name, self._at)
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
self._eventrunner.finished(self)
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
@@ -134,7 +169,7 @@ class ButtonMark(Event):
|
||||
self._at._timings.register_mark(self._name, None)
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
self._eventrunner.finished(self)
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
@@ -146,10 +181,15 @@ class Lyrics(Event):
|
||||
self._duration = duration
|
||||
|
||||
def start(self):
|
||||
self.audiencecontent.new_content(display.DisplayLyrics(self._text))
|
||||
self._audiencecontent.new_content(display.DisplayLyrics(self._text))
|
||||
print("Started displaying lyrics")
|
||||
print(self._text)
|
||||
|
||||
def stop(self):
|
||||
self.audiencecontent.new_content(display.DisplayContent())
|
||||
self._audiencecontent.new_content(display.DisplayContent())
|
||||
print("Stopped displaying lyrics")
|
||||
|
||||
def notify(self, message, *args, **kwargs):
|
||||
if message == 'newdisplay':
|
||||
self._eventrunner.finished(self)
|
||||
|
||||
|
||||
14
gig.py
14
gig.py
@@ -24,6 +24,8 @@ class EventRunner:
|
||||
self._playing = None
|
||||
self._active = []
|
||||
self._currentitem = None
|
||||
for item in self._gigconfig['items']:
|
||||
self._gigconfig['items'][item].set_eventrunner(self)
|
||||
|
||||
def set_audiencecontent(self, audiencecontent):
|
||||
for item in self._gigconfig['items']:
|
||||
@@ -75,6 +77,7 @@ class EventRunner:
|
||||
self._playing = None
|
||||
self._selected = None
|
||||
for event in self._active:
|
||||
if event is not None:
|
||||
event.stop()
|
||||
self._active = []
|
||||
if self._currentitem is not None:
|
||||
@@ -84,6 +87,17 @@ class EventRunner:
|
||||
event.start()
|
||||
self._active.append(event)
|
||||
|
||||
def notify(self, *args, **kwargs):
|
||||
for event in self._active:
|
||||
if event is not None:
|
||||
event.notify(*args, **kwargs)
|
||||
|
||||
def finished(self, event):
|
||||
# We might get called back here from within a notify or other such construct
|
||||
for i, e in enumerate(self._active):
|
||||
if e is event:
|
||||
self._active[i] = None
|
||||
|
||||
def pause(self):
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user