Guest User

Untitled

a guest
Feb 8th, 2025
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 49.41 KB | None | 0 0
  1. import serial
  2. import numpy as np
  3. import time
  4. import threading
  5. import random
  6. import socket
  7. import re
  8. import math
  9. from pynput import mouse
  10. from pynput import keyboard
  11. import matplotlib.pyplot as plt
  12. import configparser
  13.  
  14. config = configparser.ConfigParser()
  15.  
  16. # Serial settings
  17. serial_port = "COM4" # Replace with the correct COM port
  18. baud_rate = 576000
  19.  
  20. # Monitor settings
  21. monitor = {
  22. "left": 1400,
  23. "top": 1130,
  24. "width": 1060, # Adjust to your screen resolution
  25. "height": 10, # Thin strip for screen capture
  26. }
  27.  
  28. # customizable
  29. beat_color = (200, 200, 200) #RGB format
  30. scratch_color = (255,127,80) #why the fuck is this blue
  31. red_tap = (255, 0, 255) #RGB
  32. blue_tap = (0, 255, 130) #RGB
  33. left_spin_color = (0, 255, 0) #RGB format
  34. right_spin_color = (253, 0, 228) #RGB format
  35. beat_background = False #Legacy
  36. beat_boost = 20 #for beat_background only. tells how much to increase brightness on beat by. Also ignores maxbrightness
  37. saturation_boost = 2 #does this work?
  38. strip_length = 600 #how many LEDs are on the strip
  39. spin_animation_speed = 1 #how many pixels each frame jumps
  40. max_brightness = 200 #max brightness for everything on the strip
  41. dampening_factor = 0.9 #mm damp. this might not work
  42. tap_size = 200 #size of tap in pixels
  43.  
  44.  
  45. #non-customizable
  46. overlay_lock = threading.Lock()
  47. brightfactor = max_brightness / 255 #
  48. left_spin_color = (left_spin_color[0]*brightfactor, left_spin_color[1]*brightfactor, left_spin_color[2]*brightfactor) #equally dampens rgb of spin effect to ensure it is under the maxbrightness
  49. right_spin_color = (right_spin_color[0]*brightfactor, right_spin_color[1]*brightfactor, right_spin_color[2]*brightfactor)
  50. tap_size = int(tap_size / 2) # halfing because logic will double tap size
  51.  
  52. #initializing values
  53. previous_colors = [(0, 0, 0)] * strip_length
  54. overlay_colors = [(0, 0, 0)] * strip_length
  55. livetime = time.time
  56. start_time = 1
  57. active_effects = []
  58. current_time = 1
  59. sync_frame = bytearray([255, 0, 0, 255]) # for syncing with ESP32
  60. spinning_l = False
  61. spinning_r = False
  62. colors = [[0,0,0] for _ in range(strip_length)]
  63. # Track the last time we updated the smoothed colors
  64. last_update_time = time.time()
  65. last_smooth_colors = [] # Stores the last smoothed colors
  66. m = 0
  67. t = 0
  68. osc_damp = 1 #dampen rate for parabola
  69. osc_freq = 20 #oscillation frequency for parabola
  70. data = ""
  71. data_prev = "a"
  72. notes = []
  73. temp_spin_color = [[0,0,0] for _ in range(strip_length)]
  74. temp_hold_blue_color = [[0,0,0] for _ in range(strip_length)]
  75. temp_hold_red_color = [[0,0,0] for _ in range(strip_length)]
  76. match_index = (strip_length / 9)
  77. s_down = True #for scratches. makes effect bounce
  78. s = 1
  79. v = time.time()
  80. n = 0#for counting time AFTER blue hold has ended (fade out effect)
  81. u = 0#for counting time AFTER red hold has ended (fade out effect)
  82. spinright = time.time()
  83. spinleft = time.time()
  84. red_match_timer = 100000
  85. blue_match_timer = 100000
  86. strip_length
  87. spinstart = time.time()
  88. beathold = False
  89. frequency = 1
  90. holdstart = False
  91. tempb = 0.2 #for holds to store decreasing value on fade out effect
  92. tempr = 0.2
  93.  
  94.  
  95. #calcing random scratch colors
  96. scratch_min = (min(255, int((scratch_color[0] / 10) * 6)),
  97. min(255, int((scratch_color[1] / 10) * 6)),
  98. min(255, int((scratch_color[2] / 10) * 6)))
  99.  
  100. scratch_max = (min(255, int((scratch_color[0] / 10) * 12)),
  101. min(255, int((scratch_color[1] / 10) * 12)),
  102. min(255, int((scratch_color[2] / 10) * 12)))
  103.  
  104. def update_colors():
  105. global red_tap, blue_tap, left_spin_color, right_spin_color, scratch_color, beat_color, beat_boost, spin_animation_speed, max_brightness, tap_size
  106. config.read('config.ini')
  107. red_tap = (int(config.get('Red Tap', 'B', fallback=100)), int(config.get('Red Tap', 'G', fallback=100)), int(config.get('Red Tap', 'R', fallback=100)))
  108. blue_tap = (int(config.get('Blue Tap', 'B', fallback=100)), int(config.get('Blue Tap', 'G', fallback=100)), int(config.get('Blue Tap', 'R', fallback=100)))
  109. left_spin_color = (int(config.get('Left Spin', 'B', fallback=100)), int(config.get('Left Spin', 'G', fallback=100)), int(config.get('Left Spin', 'R', fallback=100)))
  110. right_spin_color = (int(config.get('Right Spin', 'B', fallback=100)), int(config.get('Right Spin', 'G', fallback=100)), int(config.get('Right Spin', 'R', fallback=100)))
  111. scratch_color = (int(config.get('Scratch', 'B', fallback=100)), int(config.get('Scratch', 'G', fallback=100)), int(config.get('Scratch', 'R', fallback=100)))
  112. beat_color = (int(config.get('Beat', 'B', fallback=100)), int(config.get('Beat', 'G', fallback=100)), int(config.get('Beat', 'R', fallback=100)))
  113. beat_boost = int(config.get('Other Effects', 'Beat Boost', fallback = 20))
  114. spin_animation_speed = int(config.get('Other Effects', 'Spin Animation Speed', fallback = 20)) / 20
  115. max_brightness = int(config.get('Other Effects', 'Max Brightness' , fallback = 200))
  116. tap_size = int(config.get('Other Effects', 'Tap Size' , fallback = 200))
  117.  
  118.  
  119. def on_press(key):
  120. global blue_match_timer, red_match_timer, spinning_l, spinning_r, scratch, start_spintime, current_value, loop, start_time, livetime
  121. try:
  122. if key.char == '1': # Check if '1' is pressed
  123. var = 1
  124. for effect in active_effects:
  125. if effect["start_index"] == 300 and effect["effect_id"] == 5 or effect["start_index"] == 300 and effect["effect_id"] == 6:
  126. var = effect["effect_var"] + 1
  127. print(var)
  128. active_effects.remove(effect)
  129. active_effects.append({
  130. "start_index": 300,
  131. "start_time": time.time(),
  132. "effect_id": 5,
  133. "effect_var": var
  134. })
  135. blue_match_timer = time.time()
  136. print("match hit")
  137. if key.char == '2': # Check if '1' is pressed
  138. var = 1
  139. for effect in active_effects:
  140. if effect["start_index"] == 300 and effect["effect_id"] == 5 or effect["start_index"] == 300 and effect["effect_id"] == 6:
  141. var = effect["effect_var"] + 1
  142. active_effects.remove(effect)
  143. active_effects.append({
  144. "start_index": 300,
  145. "start_time": time.time(),
  146. "effect_id": 6,
  147. "effect_var": var
  148. })
  149. red_match_timer = time.time()
  150. print("match hit")
  151. if key.char == '3': # Check if '1' is pressed
  152. active_effects.append({
  153. "start_index": 300,
  154. "start_time": time.time(),
  155. "effect_id": 3,
  156. "effect_var": 20 #osc_freq
  157. })
  158. print("tap hit")
  159. if key.char == '4': # Check if '1' is pressed
  160. active_effects.append({
  161. "start_index": 300,
  162. "start_time": time.time(),
  163. "effect_id": 4,
  164. "effect_var": 20 #osc_freq
  165. })
  166. print("tap hit")
  167. if key.char == '5': # Check if '1' is pressed
  168. active_effects.append({
  169. "start_index": strip_length,
  170. "start_time": time.time(),
  171. "effect_id": 1,
  172. "effect_var": ease_out(0, strip_length, t)
  173. })
  174. print("spin hit")
  175. #print("Starting left spin")
  176. remove_note("SpinLeftStart")
  177. scratch = False
  178. loop = False #for ease out
  179. if key.char == '6': # Check if '1' is pressed
  180. active_effects.append({
  181. "start_index": strip_length,
  182. "start_time": time.time(),
  183. "effect_id": 2,
  184. "effect_var": ease_out(0, strip_length, t)
  185. })
  186. print("spin hit")
  187. #print("Starting right spin")
  188. remove_note("SpinRightStart")
  189. scratch = False
  190. loop = False #for ease out
  191. if key.char == '7': # Check if '1' is pressed
  192. active_effects.append({
  193. "start_index": 300,
  194. "start_time": time.time(),
  195. "effect_id": 8,
  196. "effect_var": tap_size
  197. })
  198. print("hold hit")
  199. #print("Starting right spin")
  200. remove_note("SpinRightStart")
  201. scratch = False
  202. loop = False #for ease out
  203. if key.char == '8':
  204. start_time = livetime() + 0.5
  205. int(start_time)
  206.  
  207. except AttributeError:
  208. print(f"Special key {key} pressed")
  209.  
  210.  
  211.  
  212. listener = keyboard.Listener(
  213. on_press=on_press)
  214. listener.start()
  215.  
  216.  
  217.  
  218. def port_connect():
  219. global data
  220. host = '127.0.0.1' # Same as C# server
  221. port = 8008 # Same port as C# server
  222.  
  223. # Create a socket and connect to the server
  224. #print("attempgin connection")
  225. client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  226. #print("attempgin connection 2")
  227. client_socket.connect((host, port))
  228.  
  229. #print("Connected to C# server.")
  230. #try:
  231. while True:
  232. # Receive data
  233. data = client_socket.recv(1024).decode('utf-8')
  234. print(f"Received: {data}")
  235. str(data)
  236. add_note(data)
  237. data = ""
  238. #except KeyboardInterrupt:
  239. #print("Disconnected.")
  240.  
  241. def add_note(note):
  242. global notes
  243. notes.append(note)
  244.  
  245. def remove_note(name):
  246. global notes
  247. notes = [note for note in notes if not note.startswith(name)]
  248.  
  249.  
  250. def apply_overlay(main):
  251. """Combine the main colors with the overlay buffer."""
  252. with overlay_lock:
  253. # Merge overlay effects with main colors
  254. combined_colors = [
  255. overlay if overlay != (0, 0, 0) else smoothed_colors
  256. for overlay, smoothed_colors in zip(overlay_colors, main)
  257. ]
  258. return combined_colors
  259.  
  260. def on_beat():
  261. global start_time, beathold
  262. """Handle key press events."""
  263. if any("DrumStart" in note for note in notes):
  264. for note in notes:
  265. if "DrumStart" and "Beatholdtrue" in note:
  266. beathold = True
  267. print("bveathold!")
  268. start_time = livetime() + 0.5
  269. int(start_time)
  270. ##print("Beat! Brightening all LEDs.")
  271. #print("beat triggered")
  272. remove_note("DrumStart")
  273.  
  274. def beat_end():
  275. global start_time, beathold
  276. if any("DrumEnd" in note for note in notes):
  277. start_time = livetime() + 0.5
  278. int(start_time)
  279. beathold = False
  280. print("beat ended!")
  281. remove_note("DrumEnd")
  282.  
  283. def on_hold():
  284. global holdstart
  285. if any("Blue HoldStart" in note for note in notes):
  286. for note in notes:
  287. if "Blue HoldStart" and "Holdtrue" in note:
  288. holdstart = True
  289. match = re.search(r"Blue HoldStart \((-?\d+)\)", note)
  290. try:
  291. index = int((int(match.group(1)) + 4) * match_index)
  292. except:
  293. index = 0
  294.  
  295. active_effects.append({
  296. "start_index": index,
  297. "start_time": time.time(),
  298. "effect_id": 8,
  299. "effect_var": 0,
  300. "xvalue": 0,
  301. "yvalue": 0,
  302. "end" : False
  303. })
  304. remove_note("Blue HoldStart")
  305.  
  306. elif "Blue HoldStart" in note:
  307. match = re.search(r"Blue HoldStart \((-?\d+)\)", note)
  308. try:
  309. index = int((int(match.group(1)) + 4) * match_index)
  310. except:
  311. index = 0
  312.  
  313. active_effects.append({
  314. "start_index": index,
  315. "start_time": time.time(),
  316. "effect_id": 8,
  317. "effect_var": 0,
  318. "xvalue": 0,
  319. "yvalue": 0,
  320. "end" : False
  321. })
  322. remove_note("Blue HoldStart")
  323.  
  324. if any("Red HoldStart" in note for note in notes):
  325. for note in notes:
  326. if "Red HoldStart" and "Holdtrue" in note:
  327. holdstart = True
  328. match = re.search(r"Red HoldStart \((-?\d+)\)", note)
  329. try:
  330. index = int((int(match.group(1)) + 4) * match_index)
  331. except:
  332. index = 0
  333.  
  334. active_effects.append({
  335. "start_index": index,
  336. "start_time": time.time(),
  337. "effect_id": 9,
  338. "effect_var": 0,
  339. "xvalue": 0,
  340. "yvalue": 0,
  341. "end" : False
  342. })
  343. remove_note("Red HoldStart")
  344.  
  345. elif "Red HoldStart" in note:
  346. match = re.search(r"Red HoldStart \((-?\d+)\)", note)
  347. try:
  348. index = int((int(match.group(1)) + 4) * match_index)
  349. except:
  350. index = 0
  351.  
  352. active_effects.append({
  353. "start_index": index,
  354. "start_time": time.time(),
  355. "effect_id": 9,
  356. "effect_var": 0,
  357. "xvalue": 0,
  358. "yvalue": 0,
  359. "end" : False
  360. })
  361. remove_note("Red HoldStart")
  362.  
  363. def on_sectioncontinuationorend():
  364. global holdstart
  365. if any("SectionContinuationOrEnd" in note for note in notes):
  366. for note in notes:
  367. if "SectionContinuationOrEnd" and "Holdtrue" in note:
  368. return
  369. else:
  370. print("ending hold")
  371. holdstart = False
  372.  
  373.  
  374.  
  375. def on_release():
  376. global start_time
  377. if "IsDrum" in notes:
  378. start_time = time.time()
  379. #print("Beat release")
  380.  
  381. def on_scratch():
  382. global scratch
  383. if any("ScratchStart" in note for note in notes):
  384. #print("scratch triggered")
  385. active_effects.append({
  386. "start_index": 0,
  387. "start_time": 0,
  388. "effect_id": 7
  389. })
  390. scratch = True
  391. remove_note("ScratchStart")
  392.  
  393. def on_continue():
  394. if any("SectionContinuationOrEnd" in note for note in notes):
  395. for note in notes:
  396. if "SectionContinuationOrEnd" in note:
  397. remove_note("SectionContinuationOrEnd")
  398. if any("Blue HoldStart" in note for note in notes):
  399. for note in notes:
  400. if "Blue HoldStart" in note:
  401. remove_note("Blue HoldStart")
  402. if any("Red HoldStart" in note for note in notes):
  403. for note in notes:
  404. if "Red HoldStart" in note:
  405. remove_note("Red HoldStart")
  406. if any("Red Match" in note for note in notes):
  407. for note in notes:
  408. if "Red Match" in note:
  409. remove_note("Red Match")
  410. if any("Blue Match" in note for note in notes):
  411. for note in notes:
  412. if "Blue Match" in note:
  413. remove_note("Blue Match")
  414.  
  415. def on_match():
  416. global scratch, blue_match_timer, red_match_timer, active_effects
  417. if any("Blue Match" in note for note in notes):
  418. var = 1
  419. for note in notes:
  420. if "Blue Match" in note:
  421. match = re.search(r"Blue Match \((-?\d+)\)", note)
  422. #print("blue match triggered")
  423. try:
  424. index = (int(match.group(1)) + 4) * match_index
  425. for effect in active_effects:
  426. if effect["start_index"] == index and effect["effect_id"] == 5 or effect["start_index"] == index and effect["effect_id"] == 6:
  427. var = effect["effect_var"] + 1
  428. active_effects.remove(effect)
  429. except:
  430. index = 0
  431.  
  432. active_effects.append({
  433. "start_index": index,
  434. "start_time": time.time(),
  435. "effect_id": 5,
  436. "effect_var": var
  437. })
  438. remove_note("Blue Match")
  439. scratch = False
  440. blue_match_timer = time.time()
  441. #print(f"blue match activated{note}")
  442. if any("Red Match" in note for note in notes):
  443. for note in notes:
  444. if "Red Match" in note:
  445. var = 1
  446. match = re.search(r"Red Match \((-?\d+)\)", note)
  447. #print("red match triggered")
  448. try:
  449. index = (int(match.group(1)) + 4) * match_index
  450. for effect in active_effects:
  451. if effect["start_index"] == index and effect["effect_id"] == 5 or effect["start_index"] == index and effect["effect_id"] == 6:
  452. var = effect["effect_var"] + 1
  453. active_effects.remove(effect)
  454. except:
  455. index = 0
  456.  
  457. active_effects.append({
  458. "start_index": index,
  459. "start_time": time.time(),
  460. "effect_id": 6,
  461. "effect_var": var
  462. })
  463. remove_note("Red Match")
  464. scratch = False
  465. red_match_timer = time.time()
  466. #print(f"blue match activated{note}")
  467.  
  468.  
  469.  
  470. def spin_start():
  471. global spinning_l, spinning_r, effects_to_remove, scratch, current_value, start_spintime, loop, active_effects
  472. if any("SpinLeftStart" in note for note in notes):
  473. active_effects.append({
  474. "start_index": strip_length,
  475. "start_time": time.time(),
  476. "effect_id": 1,
  477. "effect_var": ease_out(spinstart, strip_length, t)
  478. })
  479. spinning_l = True
  480. spinning_r = False
  481. #print("Starting left spin")
  482. remove_note("SpinLeftStart")
  483. current_value = ease_out(spinstart, strip_length, t)
  484. start_spintime = time.time() #for ease out
  485. scratch = False
  486. loop = False #for ease out
  487.  
  488. #setting matches to 0
  489. for effect in active_effects:
  490. if effect["effect_id"] == 3 or effect["effect_id"] == 4:
  491. effects_to_remove.append(effect)
  492. #print(effect)
  493.  
  494. if any("SpinRightStart" in note for note in notes):
  495. active_effects.append({
  496. "start_index": strip_length,
  497. "start_time": time.time(),
  498. "effect_id": 2,
  499. "effect_var": ease_out(spinstart, strip_length, t)
  500. })
  501. #print("Starting right spin")
  502. remove_note("SpinRightStart")
  503. current_value = ease_out(spinstart, strip_length, t)
  504. start_spintime = time.time() #for ease out
  505. scratch = False
  506. loop = True #for ease out
  507.  
  508. #setting matches to 0
  509. for effect in active_effects:
  510. if effect["effect_id"] == 3 or effect["effect_id"] == 4:
  511. effects_to_remove.append(effect)
  512. #print(effect)
  513.  
  514. return # Exit the function as we've already triggered the action
  515.  
  516. def tap_start():
  517. global active_effects, strip_length, scratch, osc_freq
  518. if any("Blue Tap" in note for note in notes):
  519. for note in notes:
  520. if "Blue Tap" in note:
  521. # Add the new effect with its start index and start time
  522. match = re.search(r"Blue Tap \((-?\d+)\)", note)
  523. remove_note("Blue Tap")
  524. try:
  525. index = int((int(match.group(1)) + 4) * match_index)
  526. index = int(index)
  527. except:
  528. index = 0
  529. index = random.randint(index - 20, index + 20)
  530. active_effects.append({
  531. "start_index": index,
  532. "start_time": time.time(),
  533. "effect_id": 3,
  534. "effect_var": 20 #osc_freq
  535. })
  536. #print(note)
  537. scratch = False
  538. ##print(active_effects)
  539. if any("Red Tap" in note for note in notes):
  540. for note in notes:
  541. if "Red Tap" in note:
  542. # Calculate a unique start index for this effect
  543. # Add the new effect with its start index and start time
  544. match = re.search(r"Red Tap \((-?\d+)\)", note)
  545. remove_note("Red Tap")
  546. try:
  547. index = int((int(match.group(1)) + 4) * match_index)
  548. index = int(index)
  549. except:
  550. index = 0
  551. index = random.randint(index - 20, index + 20)
  552. active_effects.append({
  553. "start_index": index,
  554. "start_time": time.time(),
  555. "effect_id": 4,
  556. "effect_var": 20 #osc_freq
  557. })
  558. #print(note)
  559. scratch = False
  560.  
  561.  
  562. def sine_wave(x, amplitude, frequency, phase=0):
  563. return amplitude * np.sin(2 * np.pi * frequency * x + phase)
  564.  
  565.  
  566. def oscillating_parabola(x, osc_damp, osc_freq):
  567. normalized_x = x / tap_size # Normalize x to the range [-50, 50]. this determines the range of the tap
  568. unscaled = (1 - normalized_x**2) * np.exp(-osc_damp * np.abs(normalized_x)) * np.cos(osc_freq * normalized_x)
  569. return 127 * unscaled # Scale to make max value 255
  570.  
  571. def get_y_coords_for_index(i):
  572. # Ensure i is within the valid range
  573. if 0 <= i < len(coordinates):
  574. #print(i)
  575. x, y = coordinates[i] # Get the (x, y) pair at index i
  576. #print(x)
  577. return y
  578. else:
  579. raise ValueError(f"i is out of range{i}")
  580.  
  581.  
  582.  
  583.  
  584. def beats():
  585. global colors, start_time
  586. live = livetime()
  587. int(live)
  588. time_diff = max(start_time - live, 0)
  589. if beat_background == True:
  590. for i in range(strip_length):
  591. index = i
  592. r, g, b = colors[i][2], colors[i][1], colors[i][0]
  593. r = min(max(int(r, (time_diff*beat_boost), 0)))
  594. g = min(max(int(g, (time_diff*beat_boost), 0)))
  595. b = min(max(int(b, (time_diff*beat_boost), 0)))
  596. r = min(max(int(r), 0), 255)
  597. g = min(max(int(g), 0), 255)
  598. b = min(max(int(b), 0), 255)
  599. colors[index] = (r, g, b)
  600. elif beathold == True:
  601.  
  602. for i in range(strip_length):
  603.  
  604. index = i
  605. r, g, b = colors[i][2], colors[i][1], colors[i][0]
  606.  
  607. increase_r = beat_boost - r
  608. increase_g = beat_boost - g
  609. increase_b = beat_boost - b
  610.  
  611. max_increase = max(increase_r, increase_g, increase_b)
  612.  
  613. # Apply the same increase to all color components
  614. r = min(max(int(r + max_increase), 0), 255)
  615. g = min(max(int(g + max_increase), 0), 255)
  616. b = min(max(int(b + max_increase), 0), 255)
  617.  
  618. colors[index] = (r, g, b)
  619. else:
  620. for i in range(strip_length):
  621. index = i
  622. r, g, b = colors[i][2], colors[i][1], colors[i][0]
  623.  
  624. # Calculate the increase for each color component
  625. increase_r = time_diff * beat_boost - r
  626. increase_g = time_diff * beat_boost - g
  627. increase_b = time_diff * beat_boost - b
  628.  
  629. # Determine the maximum increase
  630. max_increase = max(increase_r, increase_g, increase_b)
  631. max_increase = max(max_increase, 0)
  632.  
  633. # Apply the same increase to all color components
  634. r = min(max(int(r + max_increase), 0), 255)
  635. g = min(max(int(g + max_increase), 0), 255)
  636. b = min(max(int(b + max_increase), 0), 255)
  637.  
  638. colors[index] = (r, g, b)
  639.  
  640. return colors
  641.  
  642. def ease_out(spinstart, strip_length, t):
  643. return strip_length - (strip_length - spinstart) * math.exp(-spin_animation_speed * t) #first value controls speed, 2nd controls difference in speed of start of animation compared to the end
  644.  
  645. def send_colors(colors, ser):
  646. #try:
  647. with overlay_lock: # Ensure exclusive access to the serial port
  648. # Send the sync frame first
  649. ser.write(sync_frame)
  650. max_color = max(colors, key=lambda c: sum(c)) # Find the brightest color based on sum of RGB
  651. print("Brightest color:", max_color)
  652.  
  653. # Send the LED data
  654. data = bytearray(np.clip(np.array(colors), 0, 255).astype(np.uint8).flatten())
  655. ser.write(data)
  656.  
  657. ##print(f"Sync frame sent: {len(sync_frame)} bytes, LED data sent: {len(data)} bytes")
  658. #except Exception as e:
  659. #print(f"Error sending data: {e}")
  660.  
  661. def update_effects():
  662. global active_effects, effects_to_remove, overlay_colors, overlay_lock, tempb, tempr, strip_length,temp_hold_blue_color,temp_hold_red_color, blue_match, red_match, spinning_l, spinning_r, loop, m , q, u, n, t, s, d, e, f, v, osc_freq, effects_to_remove, colors, spinright, spinleft, previous_colors, s_down, scratch, blue_match_timer, red_match_timer, current_value, x_values, y_values, coordinates, holdstart
  663. active_effects.sort(key=lambda effect: effect["effect_id"])
  664. current_time = time.time()
  665. blue_match = False
  666. red_match = False
  667. with overlay_lock:
  668. # Reset overlay colors
  669. overlay_colors = [(0, 0, 0)] * strip_length
  670. for effect in active_effects:
  671. elapsed_time = current_time - effect["start_time"]
  672. start_index = int(effect["start_index"])
  673.  
  674.  
  675. if effect["effect_id"] == 1: # LEFT SPIN
  676. current_spintime = time.time()
  677. elapsed_spintime = current_spintime - effect["start_time"]
  678.  
  679. t = elapsed_spintime
  680. effect["effect_var"] = math.ceil(ease_out(0, strip_length * 2, t))
  681. if effect["effect_var"] < strip_length:
  682. for i in range(0 , int(effect["effect_var"])):
  683. ##print(current_value)
  684. index = i
  685. #print(i)
  686. mod = effect["effect_var"] - i
  687. mod = (mod / effect["effect_var"])
  688. #mod = (i / strip_length)
  689. mod = max(0, (255 * mod) - i)
  690. r, g, b = left_spin_color
  691. r = max(0, r - mod)
  692. g = max(0, g - mod)
  693. b = max(0, b - mod)
  694. #print(r,g,b)
  695. #time.sleep(0.1)
  696. temp_spin_color[index] = (r,g,b)
  697. #compare old colors and keep highest value
  698. colors[index] = (r, g, b)
  699. elif effect["effect_var"] >= strip_length:
  700. #print(effect["effect_var"])
  701.  
  702. effect["start_index"] = effect["start_index"] + spin_animation_speed * 5
  703. #print(effect["start_index"])
  704.  
  705. for i in range(0 , strip_length):
  706. ##print(current_value)
  707.  
  708. #r, g, b = temp_spin_color[index][0], temp_spin_color[index][1], temp_spin_color[index][2]
  709.  
  710. index = int(effect["start_index"] - strip_length + i)
  711. if 0 <= index < strip_length:
  712. r, g, b = temp_spin_color[i][0], temp_spin_color[i][1], temp_spin_color[i][2]
  713. colors[index] = (r, g, b)
  714. #print(index)
  715. #temp_spin_color[index] = (r,g,b)
  716. if index >= strip_length: # Only clear LEDs that move off the strip666666666666667
  717. colors[min(strip_length - 1, index - strip_length)] = (0, 0, 0)
  718.  
  719. #previous_colors[i] = (r,g,b)
  720. #colors[i] = (0, 0, 0)
  721.  
  722.  
  723.  
  724. if effect["start_index"] > strip_length * 2:
  725. print("true")
  726. effects_to_remove.append(effect)
  727. #print("spin ended")
  728. break
  729.  
  730.  
  731. if effect["effect_id"] == 2: #RIGHT SPIN
  732. current_spintime = time.time()
  733. elapsed_spintime = current_spintime - effect["start_time"]
  734.  
  735. t = elapsed_spintime
  736. effect["effect_var"] = math.ceil(ease_out(0, strip_length * 2, t))
  737.  
  738. if effect["effect_var"] < strip_length:
  739. for i in range(0 , int(effect["effect_var"])):
  740. ##print(current_value)
  741. index = i
  742. #print(i)
  743. mod = effect["effect_var"] - i
  744. mod = (mod / effect["effect_var"])
  745. #mod = (i / strip_length)
  746. mod = max(0, (255 * mod) - i)
  747. r, g, b = right_spin_color
  748. r = max(0, r - mod)
  749. g = max(0, g - mod)
  750. b = max(0, b - mod)
  751. #print(r,g,b)
  752. #time.sleep(0.1)
  753. temp_spin_color[index] = (r,g,b)
  754. #compare old colors and keep highest value
  755. colors[index] = (r, g, b)
  756. elif effect["effect_var"] >= strip_length:
  757. #print(effect["effect_var"])
  758.  
  759. effect["start_index"] = effect["start_index"] + spin_animation_speed * 5
  760. #print(effect["start_index"])
  761.  
  762. for i in range(0 , strip_length):
  763. ##print(current_value)
  764.  
  765. #r, g, b = temp_spin_color[index][0], temp_spin_color[index][1], temp_spin_color[index][2]
  766.  
  767. index = int(effect["start_index"] - strip_length + i)
  768. if 0 <= index < strip_length:
  769. r, g, b = temp_spin_color[i][0], temp_spin_color[i][1], temp_spin_color[i][2]
  770. colors[index] = (r, g, b)
  771. #print(index)
  772. #temp_spin_color[index] = (r,g,b)
  773. if index >= strip_length: # Only clear LEDs that move off the strip666666666666667
  774. colors[min(strip_length - 1, index - strip_length)] = (0, 0, 0)
  775.  
  776. #previous_colors[i] = (r,g,b)
  777. #colors[i] = (0, 0, 0)
  778.  
  779.  
  780.  
  781. if effect["start_index"] > strip_length * 2:
  782. print("true")
  783. effects_to_remove.append(effect)
  784. #print("spin ended")
  785. break
  786.  
  787. if effect["effect_id"] == 5 and (blue_match_timer + 1) <= current_time: #blue match
  788. effects_to_remove.append(effect)
  789. if effect["effect_id"] == 5 and blue_match == False:
  790. for i in range(max(0, start_index - effect["effect_var"] * 5), min(strip_length, start_index + effect["effect_var"] * 5)):
  791.  
  792. r, g, b = colors[i][0], colors[i][1], colors[i][0]
  793.  
  794. r = abs(r - 255)
  795. g = abs(g - 255)
  796. b = abs(b - 255)
  797.  
  798.  
  799. colors[i] = (r, g, b)
  800. blue_match = True
  801.  
  802.  
  803. if effect["effect_id"] == 6 and (red_match_timer + 1) <= current_time: #red match
  804. effects_to_remove.append(effect)
  805. if effect["effect_id"] == 6:
  806. for i in range(max(0, start_index - effect["effect_var"] * 5), min(strip_length, start_index + effect["effect_var"] * 5)):
  807.  
  808. r, g, b = colors[i][0], colors[i][1], colors[i][0]
  809.  
  810. r = abs(r - 255)
  811. g = abs(g - 255)
  812. b = abs(b - 255)
  813.  
  814. colors[i] = (r, g, b)
  815. red_match = True
  816.  
  817.  
  818. if effect["effect_id"] == 3: # BLUE TAP
  819. inverse = 1 - elapsed_time # timer
  820.  
  821. #logic for sine wave
  822. osc_freq = effect["effect_var"]
  823. effect["effect_var"] = effect["effect_var"] / 1.5
  824. x_values = np.arange(-tap_size, tap_size, 1) #size of tap
  825. y_values = [oscillating_parabola(x, osc_damp, osc_freq) for x in x_values]
  826. coordinates = [(int(x), int(oscillating_parabola(x, osc_damp, osc_freq))+ 127) for x in x_values]
  827.  
  828. for i in range(max(0, start_index - tap_size), min(strip_length, start_index + tap_size)):
  829.  
  830. #getting old colors
  831. x, y, z = colors[i][0], colors[i][1], colors [i][2]
  832.  
  833. #logic for the main tap brightness
  834. iterate = i - start_index + tap_size
  835. brightness = get_y_coords_for_index(iterate)
  836. r, g, b = blue_tap
  837. r = (r / 255) * brightness
  838. g = (g / 255) * brightness
  839. b = (b / 255) * brightness
  840.  
  841. #logic for fadeout effect
  842. r, g, b = [int(c * brightness / 255) for c in blue_tap]
  843. r = max(0, r - abs((i - start_index) * 2)) * inverse #the number controls the size of the tap. lower == bigger
  844. g = max(0, g - abs((i - start_index) * 2)) * inverse
  845. b = max(0, b - abs((i - start_index) * 2)) * inverse
  846.  
  847.  
  848. #compare old colors against new colors
  849. if x >= r:
  850. r = x
  851. if y >= g:
  852. g = y
  853. if z >= b:
  854. b = z
  855. #send colors to array
  856.  
  857. colors[i] = (r, g, b)
  858.  
  859.  
  860. osc_freq = 20 # resets freq for next tap
  861.  
  862. if current_time - effect["start_time"] > 1:
  863. effects_to_remove.append(effect)
  864.  
  865. if effect["effect_id"] == 4: # Red TAP
  866. inverse = 1 - elapsed_time # timer
  867.  
  868. #logic for sine wave
  869. osc_freq = effect["effect_var"]
  870. effect["effect_var"] = effect["effect_var"] / 1.5
  871. x_values = np.arange(-tap_size, tap_size, 1) #size of tap
  872. y_values = [oscillating_parabola(x, osc_damp, osc_freq) for x in x_values]
  873. coordinates = [(int(x), int(oscillating_parabola(x, osc_damp, osc_freq))+ 127) for x in x_values]
  874.  
  875. for i in range(max(0, start_index - tap_size), min(strip_length, start_index + tap_size)):
  876.  
  877. #getting old colors
  878. x, y, z = colors[i][0], colors[i][1], colors [i][2]
  879.  
  880. #logic for the main tap brightness
  881. iterate = i - start_index + tap_size
  882. brightness = get_y_coords_for_index(iterate)
  883. r, g, b = red_tap
  884. r = (r / 255) * brightness
  885. g = (g / 255) * brightness
  886. b = (b / 255) * brightness
  887.  
  888. #logic for fadeout effect
  889. r, g, b = [int(c * brightness / 255) for c in red_tap]
  890. r = max(0, r - abs((i - start_index) * 2)) * inverse #the number controls the size of the tap. lower == bigger
  891. g = max(0, g - abs((i - start_index) * 2)) * inverse
  892. b = max(0, b - abs((i - start_index) * 2)) * inverse
  893.  
  894. #compare old colors against new colors
  895. if x >= r:
  896. r = x
  897. if y >= g:
  898. g = y
  899. if z >= b:
  900. b = z
  901. #send colors to array
  902.  
  903. colors[i] = (r, g, b)
  904.  
  905. osc_freq = 20 # resets freq for next tap
  906.  
  907. if current_time - effect["start_time"] > 1:
  908. effects_to_remove.append(effect)
  909.  
  910. if effect["effect_id"] == 8: # Blue Hold
  911.  
  912. inverse = 1 - (n - current_time)
  913. frequency = 10
  914. x_values = np.arange(effect["effect_var"], (effect["effect_var"] + tap_size), 1)
  915. #print(x_values)
  916. effect["xvalue"] = np.concatenate([x_values, x_values[::-1]])
  917. effect["effect_var"] = effect["effect_var"] + 5
  918. amplitude = 127 # Example amplitude
  919. frequency = 0.04 # Example frequency
  920. effect["yvalue"] = sine_wave(effect["xvalue"], amplitude, frequency)
  921. iterate = 0
  922.  
  923. if holdstart == True and effect["end"] == False:
  924. tempb = min(tempb * 2, 1)
  925. for i in range(max(0, start_index - tap_size), min(strip_length, start_index + tap_size)):
  926.  
  927. #capture old colors
  928. x, y, z = colors[i][0], colors[i][1], colors [i][2]
  929.  
  930. #logic for the main tap brightness
  931. brightness = effect["yvalue"][iterate]
  932. brightness = (brightness + 127) * tempb
  933. iterate = iterate + 1
  934. print(brightness)
  935.  
  936. r, g, b = blue_tap
  937. r = (r / 255) * brightness
  938. g = (g / 255) * brightness
  939. b = (b / 255) * brightness
  940.  
  941. r, g, b = [int(c * brightness / 255) for c in blue_tap]
  942. r = max(0, r - abs((i - start_index) * 3)) #the number controls the size of the tap. lower == bigger
  943. g = max(0, g - abs((i - start_index) * 3))
  944. b = max(0, b - abs((i - start_index) * 3))
  945.  
  946. #send colors to array
  947.  
  948. #compare old colors against new colors
  949. if x >= r:
  950. r = x
  951. if y >= g:
  952. g = y
  953. if z >= b:
  954. b = z
  955. temp_hold_blue_color[i] = (r, g, b)
  956. colors[i] = (r, g, b)
  957.  
  958. effect["start_time"] = time.time() #for counting time AFTER note has ended (fade out effect)
  959. if holdstart == False or effect["end"] == True:
  960. tempb = tempb * 1.5
  961. for i in range(max(0, start_index - tap_size), min(strip_length, start_index + tap_size)):
  962. r, g, b = temp_hold_blue_color[i][0], temp_hold_blue_color[i][1], temp_hold_blue_color[i][2]
  963. index = i
  964. x, y, z = colors[i][0], colors[i][1], colors [i][2]
  965.  
  966. #logic for the main tap brightness
  967. brightness = effect["yvalue"][iterate]
  968. brightness = (brightness + 127)
  969. iterate = iterate + 1
  970.  
  971. r, g, b = blue_tap
  972. r = (r / 255) * brightness
  973. g = (g / 255) * brightness
  974. b = (b / 255) * brightness
  975.  
  976. r, g, b = [int(c * brightness / 255) for c in blue_tap]
  977. r = max(0, r - abs((i - start_index) * 3)) #the number controls the size of the tap. lower == bigger
  978. g = max(0, g - abs((i - start_index) * 3))
  979. b = max(0, b - abs((i - start_index) * 3))
  980.  
  981. #send colors to array
  982. r = r / tempb
  983. g = g / tempb
  984. b = b / tempb
  985.  
  986. #compare old colors against new colors
  987. if x >= r:
  988. r = x
  989. if y >= g:
  990. g = y
  991. if z >= b:
  992. b = z
  993.  
  994. temp_hold_blue_color[i] = (r, g, b)
  995.  
  996. colors[i] = (r, g, b)
  997. effect["end"] = True
  998.  
  999. if current_time - effect["start_time"] >= 1:
  1000. tempb = 0.2
  1001. effects_to_remove.append(effect)
  1002. temp_hold_blue_color = [[0,0,0] for _ in range(strip_length)]
  1003.  
  1004.  
  1005. if effect["effect_id"] == 9: # Red Hold
  1006. inverse = 1 - (n - current_time)
  1007. frequency = 10
  1008. x_values = np.arange(effect["effect_var"], (effect["effect_var"] + tap_size), 1)
  1009. #print(x_values)
  1010. effect["xvalue"] = np.concatenate([x_values, x_values[::-1]])
  1011. effect["effect_var"] = effect["effect_var"] + 5
  1012. amplitude = 127 # Example amplitude
  1013. frequency = 0.04 # Example frequency
  1014. effect["yvalue"] = sine_wave(effect["xvalue"], amplitude, frequency)
  1015. iterate = 0
  1016.  
  1017. if holdstart == True and effect["end"] == False:
  1018. tempr = min(tempr * 2, 1)
  1019. for i in range(max(0, start_index - tap_size), min(strip_length, start_index + tap_size)):
  1020.  
  1021. #capture old colors
  1022. x, y, z = colors[i][0], colors[i][1], colors [i][2]
  1023.  
  1024. #logic for the main tap brightness
  1025. brightness = effect["yvalue"][iterate]
  1026.  
  1027. brightness = (brightness + 127) * tempr
  1028. iterate = iterate + 1
  1029.  
  1030. r, g, b = red_tap
  1031. r = (r / 255) * brightness
  1032. g = (g / 255) * brightness
  1033. b = (b / 255) * brightness
  1034.  
  1035. r, g, b = [int(c * brightness / 255) for c in red_tap]
  1036. r = max(0, r - abs((i - start_index) * 3)) #the number controls the size of the tap. lower == bigger
  1037. g = max(0, g - abs((i - start_index) * 3))
  1038. b = max(0, b - abs((i - start_index) * 3))
  1039.  
  1040. #send colors to array
  1041.  
  1042. #compare old colors against new colors
  1043. if x >= r:
  1044. r = x
  1045. if y >= g:
  1046. g = y
  1047. if z >= b:
  1048. b = z
  1049. temp_hold_red_color[i] = (r, g, b)
  1050. colors[i] = (r, g, b)
  1051.  
  1052. effect["start_time"] = time.time() #for counting time AFTER note has ended (fade out effect)
  1053. if holdstart == False or effect["end"] == True:
  1054. tempr = tempr * 1.5
  1055. for i in range(max(0, start_index - tap_size), min(strip_length, start_index + tap_size)):
  1056. r, g, b = temp_hold_red_color[i][0], temp_hold_red_color[i][1], temp_hold_red_color[i][2]
  1057. index = i
  1058. x, y, z = colors[i][0], colors[i][1], colors [i][2]
  1059.  
  1060. #logic for the main tap brightness
  1061. brightness = effect["yvalue"][iterate]
  1062. brightness = (brightness + 127)
  1063. iterate = iterate + 1
  1064.  
  1065. r, g, b = blue_tap
  1066. r = (r / 255) * brightness
  1067. g = (g / 255) * brightness
  1068. b = (b / 255) * brightness
  1069.  
  1070. r, g, b = [int(c * brightness / 255) for c in red_tap]
  1071. r = max(0, r - abs((i - start_index) * 3)) #the number controls the size of the tap. lower == bigger
  1072. g = max(0, g - abs((i - start_index) * 3))
  1073. b = max(0, b - abs((i - start_index) * 3))
  1074.  
  1075. #send colors to array
  1076. r = r / tempr
  1077. g = g / tempr
  1078. b = b / tempr
  1079.  
  1080. #compare old colors against new colors
  1081. if x >= r:
  1082. r = x
  1083. if y >= g:
  1084. g = y
  1085. if z >= b:
  1086. b = z
  1087.  
  1088. temp_hold_red_color[i] = (r, g, b)
  1089.  
  1090. colors[i] = (r, g, b)
  1091. effect["end"] = True
  1092.  
  1093.  
  1094. if current_time - effect["start_time"] >= 1:
  1095. effects_to_remove.append(effect)
  1096. temp_hold_red_color = [[0,0,0] for _ in range(strip_length)]
  1097. tempr = 0.2
  1098.  
  1099. if any(any(string in note for string in ["Blue Tap", "Red Tap", "Blue Match", "Red Match", "SectionContinuationOrEnd", "SpinLeftStart", "SpinRightStart"]) for note in notes):
  1100. for effect in active_effects:
  1101. if effect["effect_id"] == 7:
  1102. effects_to_remove.append(effect)
  1103. #print("removing effect 7")
  1104. break
  1105.  
  1106.  
  1107. if effect["effect_id"] == 7 and scratch == True: #SCRATCH
  1108. for i in range(start_index, strip_length):
  1109. r, g, b = colors[i][0], colors[i][1], colors[i][2]
  1110. d, e, f = scratch_min[0], scratch_min[1], scratch_min[2]
  1111. j, k, l = scratch_max[0], scratch_max[1], scratch_max[2]
  1112. x, y, z = (random.randint(d, j), random.randint(e, k), random.randint(f, l))
  1113. r = r + x
  1114. g = g + y
  1115. b = b + z
  1116. colors[i] = r, g, b
  1117. colors = colors[-s:] + colors[:-s]
  1118. if s_down == True:
  1119. s = s - 6
  1120. if s <= -24:
  1121. s_down = False
  1122. break
  1123. else:
  1124. s = s + 6
  1125. if s >= 24:
  1126. s_down = True
  1127. break
  1128. if effect["effect_id"] == 7 and scratch == False:
  1129. effects_to_remove.append(effect)
  1130. for effect in effects_to_remove:
  1131. try:
  1132. ##print(f"effect being removed{effect}")
  1133. active_effects.remove(effect)
  1134. except:
  1135. print("effect not found")
  1136. return colors
  1137.  
  1138.  
  1139. def mouse_light_effect(start_index, effect_id):
  1140. """Start a light effect at a given LED index with a unique effect ID."""
  1141. global active_effects
  1142. effect_id = 1
  1143. # Add a new effect with its start time, index, and ID
  1144. active_effects.append({
  1145. "start_time": livetime(),
  1146. "start_index": start_index,
  1147. "effect_id": effect_id
  1148. })
  1149.  
  1150.  
  1151.  
  1152. # Open the serial connection
  1153. with serial.Serial(serial_port, baud_rate, timeout=1) as ser:
  1154. last_sent_time = time.time()
  1155. t1 = threading.Thread(None, port_connect)
  1156. t1.start()
  1157. while True:
  1158. colors = [[0,0,0] for _ in range(strip_length)]
  1159. # Measure start time
  1160. #start_time = time.time()
  1161. #if data != data_prev:
  1162.  
  1163. #for tap effect
  1164. x_values = np.arange(-tap_size, tap_size, 1) #size of tap
  1165. y_values = [oscillating_parabola(x, osc_damp, osc_freq) for x in x_values]
  1166. coordinates = [(int(x), int(oscillating_parabola(x, osc_damp, osc_freq))+ 127) for x in x_values]
  1167.  
  1168. effects_to_remove = [] # reset effects to remove
  1169.  
  1170. #on_match()
  1171. spin_start()
  1172. tap_start()
  1173. on_scratch()
  1174. on_beat()
  1175. on_hold()
  1176. beat_end()
  1177. on_release()
  1178. on_sectioncontinuationorend()
  1179. on_continue()
  1180. previous_colors = colors
  1181. update_effects()
  1182. beats()
  1183. send_colors(colors, ser)
  1184. update_colors()
  1185. # print(f"notes{notes}")
  1186. # print(f"active effects{active_effects}")
  1187. # print(f"removed effects{effects_to_remove}")
  1188. # time.sleep(1)
  1189.  
  1190. ##print(smoothed_colors[:2])
  1191.  
  1192. # Measure execution time
  1193. # execution_time = time.time() - start_time
  1194. # #print(f"Loop executed in {execution_time:.6f} seconds")
  1195. # execution_time = timeit.timeit("get_screen_colors()", globals=globals(), number=100)
  1196. # #print(f"on_spin executed in {execution_time / 100:.6f} seconds per run (average)")
Add Comment
Please, Sign In to add comment