#! /usr/bin/python # -*- coding: utf-8 -*- """ SPDX-License-Identifier: GPL-2.0-only (c) 2012 micha@librelight.de """ # file descriptor on linux /dev/midi1 import sys import os #import fcntl import _thread as thread import time import copy def list_device(filter="APC_MINI"): dpath = "/dev/snd/" filter = "APC_MINI" out = [] for i in os.listdir(dpath): if i.startswith("controlC"): #print(i) cmd = "udevadm info {}/{}".format(dpath,i) #print("midi device_info",cmd) r=os.popen(cmd) lines = r.readlines() ok = 0 for j in lines: if filter in j: ok = 1 if ok: out.append(i) for j in lines: j=j.strip() print("-",j) return out class simplemidi(object): def __init__(self,device="/dev/midi1"): self.__lock = thread.allocate_lock() self.__mode = "" #self.__lock.acquire() #self.__lock.release() self.__data = "" self.__name = device self.__open() def __close(self): os.close( self.__midi ) def __open(self): try: option = os.O_RDWR | os.O_NONBLOCK # os.O_RDONLY | os.O_NONBLOCK self.__midi = os.open( self.__name, option) self.__mode = "a" self.is_open = 1 except OSError as e: print("__open File", self.__name, "ERR: {0} ".format(e.args) ) print(" sleep 1sec...") time.sleep(1) self.is_open = 0 print("DEVICE MODE:",self.__mode) def init(self): #placeholder pygame pass def get_device_info(self,nr): if nr == 1: return "simplemidi", self.__device return None def write_delayed(self,data): #import thread thread.start_new_thread(self._write_delayed,([data,0.01],)) #midi writeloop thread.start_new_thread(self._write_delayed,([data,0.1],)) #midi writeloop thread.start_new_thread(self._write_delayed,([data,1],)) #midi writeloop def _write_delayed(self,data): time.sleep(data[1]) self.write(data[0]) def write(self,data): try: self.__lock.acquire() # change midi file to write mode if self.__mode == "rw": os.close(self.__midi) option = os.O_WRONLY | os.O_NONBLOCK self.__midi = os.open( self.__name, option) if len(data) == 3: msg = "" try: msg = chr(int(data[0])) + chr(int(data[1])) + chr(int(data[2]) ) os.write(self.__midi, bytes(msg,"utf-8") ) except Exception as e:# SyntaxError:print("midi err",[msg,data ]) print("midi-single-write:", e, data) time.sleep(1) self.__open() elif len(data) > 3: #print("multi sending---------------------------") for i in data: if len(i) == 3: msg = "" try: msg = chr(int(i[0])) + chr(int(i[1])) + chr(int(i[2])) print([msg]) os.write(self.__midi, msg ) except Exception as e: pass print("midi-multi-write:", e, data) # change midi file to read mode if self.__mode == "rw": os.close(self.__midi) option = os.O_RDONLY | os.O_NONBLOCK self.__midi = os.open( self.__name, option) finally: self.__lock.release() def read(self,count=3): self.__lock.acquire() data = copy.deepcopy(self.__data) self.__lock.release() return data def poll(self,sysex=0): self.__lock.acquire() ok = 0 try: if sysex: self.__data = os.read(self.__midi, 1) #read abort if no data to read else: inp = os.read(self.__midi, 3) #read abort if no data to read try: #self.__data = [ ord( inp[0] ) ,ord( inp[1] ), ord( inp[2] ) ] self.__data = [ inp[0] , inp[1] , inp[2] ] except KeyError as e: print("File", self.__name, "ERR: {0} ".format(e.args) ,[inp]) except IndexError as e: print("File", self.__name, "ERR: {0} ".format(e.args) ,[inp]) ok = 1 except KeyboardInterrupt as e: raise e except: # OSError: time.sleep(0.01) # CPU STRESSLESS finally: self.__lock.release() return ok