small performance improvement

added milliseconds limit for frame rendering speed
removed redundant if blocks
This commit is contained in:
Elektrospy 2019-01-17 22:54:57 +01:00
parent fc4cd6353b
commit 39b848e433

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import websocket import websocket
try: try:
import thread import thread
@ -29,7 +30,9 @@ except:
# get input parameter # get input parameter
beatsaber_host = '127.0.0.1' beatsaber_host = '127.0.0.1'
try: try:
beatsaber_host = int(sys.argv[3]) new_host = str(sys.argv[3])
if new_host != "":
beatsaber_host = new_host
except: except:
pass pass
@ -54,10 +57,7 @@ class Layer:
self.png_image_data_flatten = self.flatten_rgb_array_from_png(self.png_image_data) self.png_image_data_flatten = self.flatten_rgb_array_from_png(self.png_image_data)
# internal event states # internal event states
self.layer_current_event_value = 0 self.layer_current_event_value = 0
self.layer_event_triggered = False
self.animation_finished = True self.animation_finished = True
self.animation_update_limit_ms = 1
self.animation_last_update_ms = self.millis()
self.animation_current_brightness = self.max_brightness self.animation_current_brightness = self.max_brightness
# just debug stuff # just debug stuff
# print("created layer for " + self.path) # print("created layer for " + self.path)
@ -71,18 +71,10 @@ class Layer:
self.layer_buffer_current_color[2] self.layer_buffer_current_color[2]
) )
def millis(self):
dt = datetime.now()
millis = dt.microsecond / 1000
return int(round((time_.time() * 1000) + int(millis)))
def run_next_fade_color(self): def run_next_fade_color(self):
if not self.animation_finished and self.animation_current_brightness > 0: if not self.animation_finished and self.animation_current_brightness > 0:
current_millis = self.millis()
if current_millis - self.animation_last_update_ms >= self.animation_update_limit_ms:
# fade rgb values # fade rgb values
self.animation_current_brightness -= 10 self.animation_current_brightness -= 25
self.animation_last_update_ms = self.millis()
# set current layer color brightness to animation brightness # set current layer color brightness to animation brightness
for i in range(0, 2): for i in range(0, 2):
@ -90,14 +82,9 @@ class Layer:
self.layer_buffer_current_color[i], self.layer_buffer_current_color[i],
self.animation_current_brightness self.animation_current_brightness
) )
elif self.animation_finished:
# if animation is finished, reset current fade brightness
self.animation_current_brightness = self.max_brightness
# print("animation finished!")
def trigger_event(self, event_value): def trigger_event(self, event_value):
# print("new event " + self.path + " value: " + str(event_value)) # print("new event " + self.path + " value: " + str(event_value))
self.layer_event_triggered = True
# get new rgb color for frame, based on event # get new rgb color for frame, based on event
self.layer_buffer_current_color = self.get_current_frame_rgb_color(event_value) self.layer_buffer_current_color = self.get_current_frame_rgb_color(event_value)
@ -108,9 +95,6 @@ class Layer:
# create black rgb color array # create black rgb color array
output_rgb_array = np.zeros(self.color_values, np.uint8) output_rgb_array = np.zeros(self.color_values, np.uint8)
if self.layer_event_triggered:
# if event_value == 0:
# print("Layer off!")
if event_value == 1 or event_value == 2: if event_value == 1 or event_value == 2:
# static blue light # static blue light
output_rgb_array[2] = self.max_brightness output_rgb_array[2] = self.max_brightness
@ -121,7 +105,7 @@ class Layer:
# reset current brightness of color for new animation # reset current brightness of color for new animation
self.animation_current_brightness = self.max_brightness self.animation_current_brightness = self.max_brightness
self.animation_finished = False self.animation_finished = False
# output_rgb_array[2] = self.max_brightness output_rgb_array[2] = self.max_brightness
elif event_value == 5 or event_value == 6: elif event_value == 5 or event_value == 6:
# static red light # static red light
output_rgb_array[0] = self.max_brightness output_rgb_array[0] = self.max_brightness
@ -132,21 +116,10 @@ class Layer:
# reset current brightness of color for new animation # reset current brightness of color for new animation
self.animation_current_brightness = self.max_brightness self.animation_current_brightness = self.max_brightness
self.animation_finished = False self.animation_finished = False
# output_rgb_array[0] = self.max_brightness output_rgb_array[0] = self.max_brightness
# elif event_value != 0 and event_value > 7:
# print("unknown event effect value")
return output_rgb_array return output_rgb_array
# only used for debbuging
def print_png_values(self):
output_string = ""
# get color values
for x in self.png_image_data_flatten:
output_string += str(x)
output_string += ","
# print(output_string)
def render_rgb_layer(self, r=0, g=0, b=0): def render_rgb_layer(self, r=0, g=0, b=0):
# reset layer buffer, step by number of color values (default 3, rgb) # reset layer buffer, step by number of color values (default 3, rgb)
for i in range(0, self.rgb_buffer_length): for i in range(0, self.rgb_buffer_length):
@ -157,10 +130,10 @@ class Layer:
# if true to mapping, else ignore and keep it at zero (black) # if true to mapping, else ignore and keep it at zero (black)
if self.png_image_data_flatten[i] != 0: if self.png_image_data_flatten[i] != 0:
self.layer_buffer_array[i] = self.get_new_color_value(r, self.png_image_data_flatten[i]) self.layer_buffer_array[i] = self.get_new_color_value(r, self.png_image_data_flatten[i])
if self.png_image_data_flatten[i+1] != 0: if self.png_image_data_flatten[i + 1] != 0:
self.layer_buffer_array[i+1] = self.get_new_color_value(g, self.png_image_data_flatten[i+1]) self.layer_buffer_array[i + 1] = self.get_new_color_value(g, self.png_image_data_flatten[i + 1])
if self.png_image_data_flatten[i+2] != 0: if self.png_image_data_flatten[i + 2] != 0:
self.layer_buffer_array[i+2] = self.get_new_color_value(b, self.png_image_data_flatten[i+2]) self.layer_buffer_array[i + 2] = self.get_new_color_value(b, self.png_image_data_flatten[i + 2])
# helper method to calculate new color value # helper method to calculate new color value
# based on current value and target mapping value # based on current value and target mapping value
@ -184,14 +157,6 @@ class Layer:
return output_array return output_array
# create layer objects for the lights
layer_small = Layer('maps/small.png')
layer_middle = Layer('maps/middle.png')
layer_big = Layer('maps/big.png')
layer_left = Layer('maps/left.png')
layer_right = Layer('maps/right.png')
# ------------------------------------ # ------------------------------------
# Websocket event part start # Websocket event part start
# ------------------------------------ # ------------------------------------
@ -251,7 +216,7 @@ def event_beat_map(event_object):
def event_beat_map_parse(beatmap_event_object): def event_beat_map_parse(beatmap_event_object):
event_type = beatmap_event_object["type"] event_type = beatmap_event_object["type"]
event_value = beatmap_event_object["value"] event_value = beatmap_event_object["value"]
if event_type >= 0 and event_type < 5: if 0 <= event_type < 5:
if event_type == 0: if event_type == 0:
trigger_light_small(event_value) trigger_light_small(event_value)
elif event_type == 1: elif event_type == 1:
@ -304,13 +269,10 @@ def on_close(ws):
def on_open(ws): def on_open(ws):
def run(*args):
while True:
time_.sleep(1)
# print("websocket connected") # print("websocket connected")
thread.start_new_thread(run, ()) thread.start_new_thread(run, ())
# ------------------------------------ # ------------------------------------
# Websocket event part end # Websocket event part end
# ------------------------------------ # ------------------------------------
@ -323,9 +285,6 @@ def get_higher_color_value(value1, value2):
return new_value return new_value
buffer_length = Nx * Ny * 3
def merge_layer_arrays(layer_first, layer_second): def merge_layer_arrays(layer_first, layer_second):
output_array = np.zeros(buffer_length, np.uint8) output_array = np.zeros(buffer_length, np.uint8)
for idx in range(0, buffer_length): for idx in range(0, buffer_length):
@ -343,23 +302,49 @@ def get_merged_layers_array():
return output_array return output_array
# Start websocket logic thread def millis():
ws = websocket.WebSocketApp('ws://' + beatsaber_host + ':6557/socket', dt = datetime.now()
cur_millis = dt.microsecond / 1000
return int(round((time_.time() * 1000) + int(cur_millis)))
if __name__ == "__main__":
buffer_length = Nx * Ny * 3
# create layer objects for the lights
layer_small = Layer('maps/small.png')
layer_middle = Layer('maps/middle.png')
layer_big = Layer('maps/big.png')
layer_left = Layer('maps/left.png')
layer_right = Layer('maps/right.png')
# Start websocket logic thread
ws = websocket.WebSocketApp('ws://' + beatsaber_host + ':6557/socket',
on_message=on_message, on_message=on_message,
on_error=on_error, on_error=on_error,
on_close=on_close) on_close=on_close,
ws.on_open = on_open on_open=on_open)
wst = threading.Thread(target=ws.run_forever) wst = threading.Thread(target=ws.run_forever)
wst.daemon = True wst.daemon = True
wst.start() wst.start()
# Start layer logic loop # frame refresh time limit, default ~16ms for about ~60fps
while True: frame_update_limit_ms = 16
frame_last_update_ms = millis()
frame_current_millis = millis()
# Start layer logic loop
while True:
frame_current_millis = millis()
if frame_current_millis - frame_last_update_ms >= frame_update_limit_ms:
# run layer render logic
layer_small.run() layer_small.run()
layer_middle.run() layer_middle.run()
layer_big.run() layer_big.run()
layer_left.run() layer_left.run()
layer_right.run() layer_right.run()
# merge layers together
output_buffer = get_merged_layers_array() output_buffer = get_merged_layers_array()
output_bytes = output_buffer.tobytes() # convert frame buffer to byte string and write to stdout
os.write(1, output_bytes) os.write(1, output_buffer.tobytes())
# refresh last frame update time
frame_last_update_ms = millis()