apcmini.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #! /usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. SPDX-License-Identifier: GPL-2.0-only
  5. (c) micha@librelight.de
  6. """
  7. import sys
  8. sys.stdout.write("\x1b]2;APCmini\x07")
  9. import os
  10. #sys.path.append(os.getcwd() + '/..')
  11. sys.path.insert(0,"/opt/LibreLight/Xdesk/")
  12. import time
  13. import socket, struct
  14. import random
  15. import lib.chat as chat
  16. if 0:
  17. # z.b. Windows
  18. # 10 MB RAM
  19. from interfaces.midi.lib.pygamemidi_wraper import pygamemidi
  20. midi = pygamemidi(out=2,inp=3)
  21. else:
  22. # 4 MB RAM , only tested on linux
  23. import lib.simplemidi_wraper as smidi
  24. device = smidi.list_device(filter="APC_MINI")
  25. _id = device[-1][-1]
  26. midi = smidi.simplemidi("/dev/snd/midiC{}D0".format(_id) ) #,inp="/dev/midi1")
  27. cli = None
  28. class dummyChat():
  29. def __init__(self):
  30. pass
  31. def send(self,*arg,**args):
  32. print("dummyChat",self,arg,args)
  33. #c = chat.tcp_sender()
  34. c = dummyChat()
  35. def send(msg):
  36. print("send",msg)
  37. c.send(msg)
  38. BLACK = 0
  39. YELLOW = 5
  40. YELLOW_BLINK = 6
  41. GREEN = 1
  42. GREEN_BLINK = 2
  43. RED = 3
  44. RED_BLINK = 4
  45. class MAIN():
  46. def __init__(self):
  47. self.buf = []
  48. self.dbg = 0
  49. self.blink = -1
  50. self.is_open = -1
  51. self.midi = midi
  52. def loop(self):
  53. release = 0
  54. if 0:
  55. r = 225
  56. for i in range(4):
  57. for i in range(r):
  58. if self.dbg:print(i)
  59. midi.write([144,40+i,GREEN])
  60. time.sleep(0.2)
  61. for i in range(r):
  62. print(i)
  63. midi.write([144,40+i,BLACK])
  64. time.sleep(0.2)
  65. for i in range(r):
  66. print(i)
  67. midi.write([144,40+i,RED])
  68. time.sleep(1.52)
  69. for i in range(r):
  70. print(i)
  71. midi.write([144,60+i,BLACK])
  72. time.sleep(0.5)
  73. last_t = time.time()
  74. blink = 0
  75. while True:
  76. if release:
  77. release = 0
  78. for i in range(4):
  79. midi.write([144,60+i,YELLOW])
  80. midi.write([144,52+i,YELLOW])
  81. midi.write([144,44+i,YELLOW])
  82. midi.write([144,36+i,YELLOW])
  83. midi.write([144,24+i,RED])
  84. midi.write([144,24+i+4,RED])
  85. midi.write([144,56+i,GREEN])
  86. midi.write([144,8+i,GREEN])
  87. midi.write([144,12+i,GREEN])
  88. #midi.write([144,82,YELLOW])
  89. #time.sleep(.5)
  90. #midi.write([144,82,BLACK])
  91. rows = [56,48,40,32,24,16,8,0,64,48]
  92. midi_function = {
  93. "Off": (128,144),
  94. "On ":(144,160),
  95. "PLY":(160,176),
  96. "CC ":(176,192),
  97. "PC ":(192,208),
  98. "CA ":(208,223),
  99. "QtrFrame":(241,242),
  100. "tclock":(248,249),
  101. }
  102. # cut byte
  103. # x=174;((x)^(x>>4<<4))
  104. # int(bin(151)[-4:],2)+1
  105. #nibl = x=174;((x)^(x>>4<<4))
  106. #nibl = int(bin(151)[-4:],2)+1
  107. ch = -123
  108. if midi.poll():
  109. midi_date = midi.read(1)
  110. #print("MIDI",midi_date)
  111. if 1:# midi_date[0] >= 128 midi_date[0] <= 143:
  112. ch = int(bin(midi_date[0])[-4:],2)+1
  113. for fn,v in midi_function.items():
  114. if midi_date[0] >= v[0] and midi_date[0] < v[1]:
  115. FN = fn
  116. break
  117. r_old = 0
  118. row = 0
  119. for r in rows:
  120. #print(r_old,r)
  121. if r_old and midi_date[1] >= r_old and midi_date[1] < r:
  122. row = midi_data[1] - r+1
  123. print("jo")
  124. r_old=r
  125. nibl = int(bin(midi_date[1])[2:][-4:],2)+1
  126. _bin2 = bin(midi_date[1])
  127. _bin2 = _bin2[2:]
  128. _bin2 = _bin2.rjust(8,"0")
  129. _bin2 = int(_bin2[1:5],2)
  130. _bin = bin(midi_date[1])
  131. _bin = _bin[2:]
  132. _bin = _bin.rjust(8,"0")
  133. _bin = _bin[-3:] # 3 bit
  134. value = ""
  135. btn = int(midi_date[1]) #btn_row*btn_col
  136. if FN == "CC ":
  137. _bin2 =str(int(_bin2)+1000)
  138. value = midi_date[-1]
  139. btn += 1000
  140. if FN == "On ":
  141. value = 1
  142. midi.write([144,midi_date[1],YELLOW])
  143. if FN == "Off":
  144. value = 0
  145. release = 1
  146. midi.write([144,midi_date[1],BLACK])
  147. btn_row = int(_bin2)+1
  148. btn_col =int(_bin,2)+1
  149. #print(row,"in:",FN,"ch",ch,"raw",midi_date,_bin,btn_row,btn_col,[value])
  150. #print([btn_row,btn_col,btn,value])
  151. if self.dbg:print([btn,value])
  152. self.buf.append([btn,value])
  153. if time.time()>last_t+0.5:
  154. last_t = time.time()
  155. #print("blink",blink)
  156. if blink:
  157. blink = 0
  158. midi.write([144,82,YELLOW])
  159. else:
  160. blink = 1
  161. midi.write([144,82,BLACK])
  162. self.is_open = midi.is_open
  163. self.blink = blink
  164. if __name__ == "__main__":
  165. import _thread as thread
  166. main = MAIN()
  167. thread.start_new_thread(main.loop,())
  168. time.sleep(1)
  169. while 1:
  170. if main.buf:
  171. buf = main.buf[:]
  172. main.buf = []
  173. for m in buf:
  174. print("-> midi:",m)
  175. time.sleep(0.1)