Guest User

keyboard_waveform

a guest
Jul 5th, 2023
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.26 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. import os
  4. import time
  5. import json
  6. import subprocess
  7.  
  8. from queue import Queue
  9. from pathlib import Path
  10.  
  11. import numpy as np
  12. import matplotlib.pyplot as plt
  13. from PIL import Image, ImageDraw
  14.  
  15. VID_SIZE = (150, 60)
  16.  
  17. def read_frames():
  18. command = [
  19. 'ffmpeg',
  20. '-f', 'pulse',
  21. '-i', 'alsa_output.pci-0000_0c_00.4.analog-stereo.monitor',
  22. '-filter_complex', '[0:a]showwaves=s=150x60:mode=cline:split_channels=1:scale=log:colors=00ffff|cd5c5c:rate=8,format=rgb24[v]',
  23. '-map', '[v]',
  24. '-pix_fmt', 'rgb24',
  25. '-f', 'rawvideo',
  26. 'pipe:1'
  27. ]
  28. process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  29.  
  30. while True:
  31. raw_frame = process.stdout.read(VID_SIZE[0] * VID_SIZE[1] * 3)
  32. if not raw_frame:
  33. break
  34. frame = np.frombuffer(raw_frame, dtype='uint8')
  35. frame = frame.reshape((VID_SIZE[1], VID_SIZE[0], 3))
  36. yield frame
  37.  
  38.  
  39. def scale_points(points, image_width, image_height, frame_width, frame_height):
  40. scaled_points = []
  41. for point in points:
  42. x = point[0] * (frame_width / image_width)
  43. y = point[1] * (frame_height / image_height)
  44. scaled_points.append([int(x), int(y)])
  45. return scaled_points
  46.  
  47.  
  48. def int_to_padded_hex(i):
  49. if not 0 <= i <= 255:
  50. raise ValueError("Input must be in the range 0-255")
  51.  
  52. return hex(i)[2:].zfill(2)
  53.  
  54.  
  55. def hex_to_rgb(hex_val):
  56. hex_val = hex_val.lstrip('#')
  57. return tuple(int(hex_val[i:i+2], 16) for i in (0, 2, 4))
  58.  
  59.  
  60. def main():
  61. # Parse JSON data from file
  62. json_file = str(Path.home()) + '/.local/share/keyboard_map/keyboard_labels.json'
  63.  
  64. with open(json_file) as f:
  65. kb_data = json.load(f)
  66.  
  67. # Extract shape labels and points
  68. shapes = kb_data['shapes']
  69. shape_points = {}
  70.  
  71. for shape in shapes:
  72. if shape['shape_type'] != 'rectangle':
  73. continue
  74.  
  75. shape_points[shape['label']] = shape['points']
  76.  
  77. scaled_key_coords = { k: scale_points(v, kb_data['imageWidth'], kb_data['imageHeight'], VID_SIZE[0], VID_SIZE[1]) for k, v in shape_points.items() }
  78.  
  79. # Iterate over frames and process
  80. for frame in read_frames():
  81. key_color_map = { k: frame[v[0][1]:v[1][1],v[0][0]:v[1][0],:].mean(axis=(0,1)).astype('uint8') for k, v in scaled_key_coords.items() }
  82.  
  83. key_color_assignments = [
  84. f"k { keyname } { ''.join([int_to_padded_hex(i) for i in color]) }" for keyname, color in key_color_map.items()
  85. ]
  86.  
  87. if os.getenv('DEBUG', '0') == '1':
  88. plt.imshow(frame)
  89. plt.show()
  90.  
  91. key_color_display = Image.new(mode='RGB', size=(150, 60), color='white')
  92. drawer = ImageDraw.Draw(key_color_display)
  93.  
  94. breakpoint()
  95.  
  96. for key_label, color in key_color_map.items():
  97. x1, y1 = scaled_key_coords[key_label][0]
  98. x2, y2 = scaled_key_coords[key_label][1]
  99. drawer.rectangle([x1, y1, x2, y2], fill=tuple(color))
  100.  
  101. key_color_display.show()
  102.  
  103. for i in range(0, len(key_color_assignments), 30):
  104. profile = '\n'.join(key_color_assignments[i:i+30]) + '\nc\n'
  105. process = subprocess.Popen(['g810-led', '-pp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  106. stdout, stderr = process.communicate(profile.encode())
  107. stdout, stderr = stdout.decode(), stderr.decode()
  108. if process.returncode != 0:
  109. raise Exception()
  110. time.sleep(.01)
  111.  
  112.  
  113. if __name__ == '__main__':
  114. main()
  115.  
  116.  
Advertisement
Add Comment
Please, Sign In to add comment