From 21d42e0415ba5f71c535dd99311bbce27a2a7c0e Mon Sep 17 00:00:00 2001 From: Andrew McOlash Date: Fri, 13 Sep 2024 16:35:41 -0700 Subject: [PATCH] add fps control, optional override for night mode when music playing, nicer text scroll, fps logger --- scripts/play.sh | 2 +- src/python/config.py | 9 ++++++--- src/python/display.py | 5 +++-- src/python/midi_input_handler.py | 2 +- src/python/midi_pi.py | 24 ++++++++++++++++++++++++ 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/scripts/play.sh b/scripts/play.sh index aa25679..85c9178 100755 --- a/scripts/play.sh +++ b/scripts/play.sh @@ -7,7 +7,7 @@ function playDir() { for f in `find "$1" -name '*.mid' -print | shuf` do echo $f - aplaymidi --port="$PORT" $f + aplaymidi --port="$PORT" "$f" done } diff --git a/src/python/config.py b/src/python/config.py index 0c33f94..3038002 100644 --- a/src/python/config.py +++ b/src/python/config.py @@ -22,6 +22,7 @@ 'DISPLAY_MENU_RESET', 'DISPLAY_OFF_TIMEOUT', 'MAX_AMBIENT_BRIGHTNESS', + 'MUSIC_PLAYING_OVERRIDE' ] # PLAYING_MODE Options @@ -79,6 +80,7 @@ def __init__(self): self.MIDI_DEVICE = "Digital Keyboard" # A partial match of the midi device name self.TIMEZONE = pytz.timezone("America/Los_Angeles") self.PORT = 8080 # server port + self.FPS = 100 # max updates per second. max updaes on pi2 currently peaks at 220. recommended to keep below to not fully use cpu # Key Configuration self.MIN_KEY = 28 @@ -86,7 +88,7 @@ def __init__(self): self.TOTAL_KEYS = self.MAX_KEY - self.MIN_KEY # Playing Configuration - self.FADE_SPEED = 5 + self.FADE_SPEED = 1 # Timeout before menu goes back to main one (in minutes) self.DISPLAY_MENU_RESET = 2 @@ -97,10 +99,10 @@ def __init__(self): # Scalar of how much to brighten colors self.MAX_AMBIENT_BRIGHTNESS = 20 - self.BRIGHTEN_AMOUNT = 10 + self.BRIGHTEN_AMOUNT = 5 # Number of keys to ripple from - self.RIPPLE_KEYS = 8 + self.RIPPLE_KEYS = 3 # Color Configuration self.CURRENT_PALETTE = Palette.Ocean @@ -116,6 +118,7 @@ def __init__(self): self.NIGHT_MODE_START_MINUTE = 30 # Starting minute when night mode begins (inclusive) self.NIGHT_MODE_END_HOUR = 23 # Ending hour when night mode stops (exclusive) self.NIGHT_MODE_END_MINUTE = 30 # Ending minute when night mode stops (exclusive) + self.MUSIC_PLAYING_OVERRIDE = True self.CYCLE_SPEED = 0.15 diff --git a/src/python/display.py b/src/python/display.py index c637c4b..9050d3a 100644 --- a/src/python/display.py +++ b/src/python/display.py @@ -19,7 +19,7 @@ UP_BUTTON = 12 TEXT_SCROLL_INITIAL_DELAY = 1.5 -TEXT_SCROLL_DELAY = 0.5 +TEXT_SCROLL_DELAY = 0.2 mainMenu = [ MenuItem('Music', items=Music.getMusic(), icon=Icons['music']), @@ -27,6 +27,7 @@ MenuItem('Settings', items=[ MenuItem('Color Palette', lambda value: Config.updatePalette(value), value=lambda: Config.CURRENT_PALETTE, options=list(Palette), icon=Icons['color']), MenuItem('Play Mode', lambda value: Config.updateValue('PLAY_MODE', value), value=lambda: Config.PLAY_MODE, options=list(PlayMode), icon=Icons['light']), + MenuItem('Music LED Override', lambda value: Config.updateValue('MUSIC_PLAYING_OVERRIDE', not value), value=lambda: Config.MUSIC_PLAYING_OVERRIDE), MenuItem('Ambient', items=[ MenuItem('Ambient Mode', lambda value: Config.updateValue('AMBIENT_MODE', value), value=lambda: Config.AMBIENT_MODE, options=list(AmbientMode)), MenuItem('Ambient Enabled', lambda value: Config.updateValue('AMBIENT_ENABLED', not value), value=lambda: Config.AMBIENT_ENABLED), @@ -212,7 +213,7 @@ def update(self): if items[scroll].value != None and items[scroll].showValue: selectedLabel = items[scroll].value() if not Config.CHORDS and len(selectedLabel) > 17 and self.displayOn and time.time() > self.textTimer: - self.textScroll += 2 + self.textScroll += 1 self.textTimer = time.time() + TEXT_SCROLL_DELAY self.dirty = True diff --git a/src/python/midi_input_handler.py b/src/python/midi_input_handler.py index fdfcd46..1b2db1c 100644 --- a/src/python/midi_input_handler.py +++ b/src/python/midi_input_handler.py @@ -134,7 +134,7 @@ def __call__(self, event, data=None): toUpdate.append(i) # Always show leds even in night mode when manually played. Only trigger leds from midi music when night mode off - if not self.midi_out_piano or not util.nightModeActive(): + if not self.midi_out_piano or Config.MUSIC_PLAYING_OVERRIDE or not util.nightModeActive(): Leds.lastPlayed = time.time() for i in toUpdate: diff --git a/src/python/midi_pi.py b/src/python/midi_pi.py index 8a38745..04c2cc5 100755 --- a/src/python/midi_pi.py +++ b/src/python/midi_pi.py @@ -3,6 +3,7 @@ import sys import time from threading import Thread +from math import floor from cal import Cal from config import Config @@ -28,9 +29,16 @@ def __init__(self): self.serverThread.daemon = True self.serverThread.start() + self.updates = 0 + self.sec = time.time() + self.frameTime = 1 / Config.FPS + print('Init Complete') def update(self): + # Track when the frame started + start = time.time() + MidiPorts.update() Config.update() Leds.updateLeds() @@ -39,6 +47,15 @@ def update(self): self.Display.update() updatePendingActions(self.Display) + # Limit number of updates to try and match fps + end = time.time() + diff = end - start + if diff < self.frameTime: + time.sleep(self.frameTime - diff) + + # Uncomment to enable fps logging (per second) + # self.fpsLogging() + def profile(self): # Just wait for keyboard interrupt, everything else is handled via the input callback. profile = cProfile.Profile() @@ -53,6 +70,13 @@ def profile(self): ps = pstats.Stats(profile) ps.print_stats() +def fpsLogging(self): + self.updates += 1 + if floor(time.time()) > floor(self.sec): + print("FPS: " + str(self.updates)) + self.updates = 0 + self.sec = time.time() + if __name__ == "__main__": try: print(niceTime() + ': Entering main loop. Press Control-C to exit.')