simplemidi.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import json
  2. import os
  3. import socket
  4. import time
  5. import subprocess
  6. from ctypes import Union
  7. from gi.overrides import Gtk
  8. import config
  9. PORT=8081
  10. class SPResponse:
  11. def __init__(self, code, msg, log):
  12. self.code=code
  13. self.message=msg
  14. self.log=log
  15. def __bool__(self):
  16. return self.code!=0
  17. class Socket(socket.socket):
  18. def __init__(self):
  19. super().__init__(socket.AF_INET, socket.SOCK_STREAM)
  20. def readc(self, blocking=True):
  21. c=b''
  22. while not len(c):
  23. c=self.recv(1)
  24. return c
  25. def readline(self):
  26. buffer = bytes()
  27. ok=False
  28. while not ok:
  29. c = self.readc()
  30. if c[0]==10: #new line
  31. ok=True
  32. else:
  33. buffer+=bytes(c)
  34. self.readc()
  35. self.readc()
  36. return buffer.decode("utf-8")
  37. def response(self):
  38. x=self.readline()
  39. _status = x.split(" ")
  40. code = int(_status[0])
  41. msg = " ".join(_status[1:])
  42. log = ""
  43. ok=False
  44. delim=">".encode()
  45. while not ok:
  46. c=self.readc()
  47. if c!=delim:
  48. log+=self.readline()+"\n"
  49. else:
  50. self.readc()
  51. break
  52. return SPResponse(code, msg, log)
  53. def write(self, string):
  54. if not "\n" in string: string += "\r\n"
  55. b = string.encode()
  56. l = len(b)
  57. i = 0
  58. while i < l:
  59. i += self.send(b[i:])
  60. def connect(self, address) -> None:
  61. x=super().connect(address)
  62. self.readc()
  63. self.readc()
  64. self.readc()
  65. def set_pad(self, pad):
  66. if isinstance(pad, str):
  67. self.write('pad select "%s"\n'%pad)
  68. else:
  69. self.write('pad select %d\n'%pad)
  70. return self.response()
  71. def set_configuration(self, path):
  72. self.write('pad load "%s"\n' % path)
  73. return self.response()
  74. def clear(self):
  75. self.write('pad clear\n')
  76. return self.response()
  77. class Response:
  78. def __init__(self, sock):
  79. self.code=0
  80. self.message=""
  81. self.log=""
  82. class DisconnectException(Exception):
  83. def __init__(self, string=""):
  84. super().__init__(string)
  85. class SimpleMidi:
  86. TEMP_FILE=".simple_midi_exchange"
  87. NB_TRIES=200
  88. def __init__(self, connect=None):
  89. self.connect=connect
  90. self.pid=-1
  91. self.socket=None
  92. self.process=None
  93. def run(self):
  94. if not self.connect and not self.is_alive():
  95. padsdir = os.path.normpath(os.path.join(os.getcwd(), "../pads"))
  96. args=(os.path.join(os.getcwd(), config.PAD_ROUTER_BIN), "--command", "inet", "8081", "-k", "--pads-dir", padsdir)
  97. self.process=subprocess.Popen(args)
  98. """if (self.pid>0):
  99. os.kill(self.pid, 9)
  100. os.wait()
  101. "ui/" + config.PAD_ROUTER_BIN, ".", "--command", "inet", "8081", "-k", "--pads-dir", padsdir)
  102. self.pid = os.fork()
  103. if not self.pid:
  104. Gtk.main_quit()
  105. print("Start: ", config.PAD_ROUTER_BIN + " --pads-dir " + SimpleMidi.TEMP_FILE)
  106. os.chdir("..")
  107. padsdir = os.path.normpath(os.path.join(os.getcwd(), "pads"))
  108. args=("ui/" + config.PAD_ROUTER_BIN, ".", "--command", "inet", "8081", "-k", "--pads-dir", padsdir)
  109. print(" ".join(args))
  110. os.execl(*args)"""
  111. self.socket = Socket()
  112. for i in range(SimpleMidi.NB_TRIES):
  113. try:
  114. self.socket.connect(self.connect if self.connect else("127.0.0.1", PORT) )
  115. return
  116. except:
  117. print("Impossible de se connecter, essai %d/%d"%(i+1, SimpleMidi.NB_TRIES))
  118. time.sleep(0.5)
  119. if not self.is_alive():
  120. raise DisconnectException()
  121. raise DisconnectException()
  122. def clear(self):
  123. if not self.is_alive():
  124. raise DisconnectException()
  125. self.socket.clear()
  126. def set_pad(self, pad):
  127. if isinstance(pad, dict):
  128. if "pad" in pad:
  129. pad=pad["pad"]
  130. elif "name" in pad:
  131. pad=pad["name"]
  132. if not self.is_alive():
  133. raise DisconnectException()
  134. self.socket.set_pad(pad)
  135. def set_configuration_data(self, padconf):
  136. if not self.is_alive():
  137. self.run()
  138. with open(SimpleMidi.TEMP_FILE, "w") as f:
  139. f.write(json.dumps(padconf.json()))
  140. self.socket.set_configuration("ui/"+SimpleMidi.TEMP_FILE)
  141. def set_configuration_file(self, padconf):
  142. if not self.is_alive():
  143. self.run()
  144. self.socket.set_configuration(padconf)
  145. def is_alive(self):
  146. return self.process and self.process.poll()==None
  147. if __name__ == "__main__":
  148. sm = SimpleMidi()
  149. sm.run()
  150. sm.set_pad(0)
  151. sm.clear()
  152. while True:
  153. time.sleep(5)
  154. sm.set_configuration_file("ui/conf2.conf")
  155. time.sleep(5)
  156. sm.set_configuration_file("ui/conf3.conf")