simplemidi_wraper.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #! /usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. This file is part of LibreLight.
  5. LibreLight is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 2 of the License, or
  8. (at your option) any later version.
  9. LibreLight is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with LibreLight. If not, see <http://www.gnu.org/licenses/>.
  15. (c) 2012 micha.rathfelder@gmail.com
  16. """
  17. # file descriptor on linux /dev/midi1
  18. import sys
  19. import os
  20. #import fcntl
  21. import _thread as thread
  22. import time
  23. import copy
  24. class simplemidi(object):
  25. def __init__(self,device="/dev/midi1"):
  26. self.__lock = thread.allocate_lock()
  27. self.__mode = ""
  28. #self.__lock.acquire()
  29. #self.__lock.release()
  30. self.__data = ""
  31. self.__name = device
  32. self.__open()
  33. def __close(self):
  34. os.close( self.__midi )
  35. def __open(self):
  36. try:
  37. option = os.O_RDWR | os.O_NONBLOCK # os.O_RDONLY | os.O_NONBLOCK
  38. self.__midi = os.open( self.__name, option)
  39. self.__mode = "a"
  40. except OSError as e:
  41. print("File", self.__name, "ERR: {0} ".format(e.args) )
  42. try:
  43. self.__mode = "rw"
  44. option = os.O_RDONLY | os.O_NONBLOCK
  45. self.__midi = os.open( self.__name, option)
  46. print("DEVICE MODE:",self.__mode)
  47. except OSError as e:
  48. print("File", self.__name, "ERR: {0} ".format(e.args) )
  49. input()
  50. sys.exit()
  51. print("DEVICE MODE:",self.__mode)
  52. def init(self):
  53. #placeholder pygame
  54. pass
  55. def get_device_info(self,nr):
  56. if nr == 1:
  57. return "simplemidi", self.__device
  58. else:
  59. return None
  60. def write_delayed(self,data):
  61. #import thread
  62. thread.start_new_thread(self._write_delayed,([data,0.01],)) #midi writeloop
  63. thread.start_new_thread(self._write_delayed,([data,0.1],)) #midi writeloop
  64. thread.start_new_thread(self._write_delayed,([data,1],)) #midi writeloop
  65. def _write_delayed(self,data):
  66. time.sleep(data[1])
  67. self.write(data[0])
  68. def write(self,data):
  69. self.__lock.acquire()
  70. # change midi file to write mode
  71. if self.__mode == "rw":
  72. os.close(self.__midi)
  73. option = os.O_WRONLY | os.O_NONBLOCK
  74. self.__midi = os.open( self.__name, option)
  75. if len(data) == 3:
  76. msg = ""
  77. try:
  78. msg = chr(int(data[0])) + chr(int(data[1])) + chr(int(data[2]) )
  79. #if data[0] != 191:
  80. # print(data#[msg])
  81. os.write(self.__midi, bytes(msg,"utf-8") )
  82. except Exception as e:# SyntaxError:print("midi err",[msg,data ])
  83. print("midi-single-write:", e, data)
  84. #self.__close() #STOPPING MIDI ...
  85. #self.__open()
  86. elif len(data) > 3:
  87. #print("multi sending---------------------------")
  88. for i in data:
  89. if len(i) == 3:
  90. msg = ""
  91. try:
  92. msg = chr(int(i[0])) + chr(int(i[1])) + chr(int(i[2]))
  93. print([msg])
  94. os.write(self.__midi, msg )
  95. except Exception as e:
  96. pass
  97. print("midi-multi-write:", e, data)
  98. # change midi file to read mode
  99. if self.__mode == "rw":
  100. os.close(self.__midi)
  101. option = os.O_RDONLY | os.O_NONBLOCK
  102. self.__midi = os.open( self.__name, option)
  103. self.__lock.release()
  104. def read(self,count=3):
  105. self.__lock.acquire()
  106. data = copy.deepcopy(self.__data)
  107. self.__lock.release()
  108. return data
  109. def poll(self,sysex=0):
  110. self.__lock.acquire()
  111. try:
  112. if sysex:
  113. self.__data = os.read(self.__midi, 1) #read abort if no data to read
  114. else:
  115. inp = os.read(self.__midi, 3) #read abort if no data to read
  116. try:
  117. #self.__data = [ ord( inp[0] ) ,ord( inp[1] ), ord( inp[2] ) ]
  118. self.__data = [ inp[0] , inp[1] , inp[2] ]
  119. except KeyError as e:
  120. print("File", self.__name, "ERR: {0} ".format(e.args) ,[inp])
  121. except IndexError as e:
  122. print("File", self.__name, "ERR: {0} ".format(e.args) ,[inp])
  123. self.__lock.release()
  124. return 1
  125. except OSError:
  126. time.sleep(0.01) # CPU STRESSLESS
  127. self.__lock.release()
  128. return 0