123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #!/usr/bin/python
- import copy
- from .midimessage import MidiType
- from .utils import *
- class MidiEventTrigger:
- NOTE=1
- CONTROL=2
- PROGRAM=4
- FILTER_ALL_KEY=-1
-
- def __init__(self, param):
- if param==None: self._initNone()
- elif isinstance(param, (tuple, list)): self._initTuple(param)
- elif isinstance(param, int): self._initTuple([param])
- elif isinstance(param, MidiEventTrigger): self._initCopy(param)
-
- def _initNone(self):
- self._init()
-
- """
- () -> déclenchement pour toutes les evenemnts parmis NOTE, CONTROL et PROGRAM
- (TYPE)
- (TYPE, CHANNEL, NOTE)
- (TYPE, CHANNEL, NOTE, FORWARD)
- (TYPE, CHANNEL, NOTE, FORWARD, CALLBACK [, DATA])
- TYPE: flags parmis NOTE, CONTROL, PROGRAM (qui sera une condition necessaire au déclenchement)
- CHANNEL: le canal pour le déclenchement
- none ou vide: declenchement pour toutes les valeurs
- int: declenchement pour une valeur
- array: declenchement pour toutes les valeurs de la liste
- tuple: declenchement pour l'interval (x,y) avec x ET y inclus
- NOTE: la clé de la Note du Program ou Control pour le déclenchement
- none ou vide: declenchement pour toutes les valeurs
- int: declenchement pour une valeur
- array: declenchement pour toutes les valeurs de la liste
- tuple: declenchement pour l'interval (x,y) avec x ET y inclus
- FORWARD: Uen fois l'élément traité doit il etre réinjecter en canal de sortie ?
- True ou vide: Oui
- None ou False: Non
- CALLBACK et DATA:
- callback appelé en cas de céclenchement de la forem fct(msg, data)
- """
- def _initTuple(self, t):
- self._init(*t)
-
-
-
- def _initCopy(self, t):
- _init(t.type, copy.copy(t.channel), copy.copy(t.key), t.forward)
-
-
- def _init(self, t=NOTE|CONTROL|PROGRAM, ch=None, k=None, f=True, cb=None, data=None ):
- self.channel=self.FILTER_ALL_KEY
- self.key=self.FILTER_ALL_KEY
- self.forward=True
-
- self.type=t
- if isinstance(ch, list):
- self.channel=ch
- elif isinstance(ch, tuple):
- self.channel=[]
- for i in range(ch[0], ch[1]+1):
- self.channel.append(i)
- if isinstance(k, list):
- self.key=k
- elif isinstance(k, tuple):
- self.key=[]
- for i in range(k[0], k[1]+1):
- self.key.append(i)
- self.forward=f
- self.callback=cb
- self.callbackData=data
-
- def trigger(self, msg):
- if self.callback:
- self.callback(msg, self.callbackData)
-
- def filter(self, _msg, out):
- msg=_msg[1]
- delta=_msg[0]
- t=msg.getType()
- if t!=MidiType.NOTE_ON and t!=MidiType.NOTE_OFF and \
- t!=MidiType.PROGRAM_CHANGE and t!=MidiType.CONTROL_CHANGE: return False
-
- #test du type
- lt=[]
- if self.type & self.NOTE: lt+=[MidiType.NOTE_ON, MidiType.NOTE_OFF]
- if self.type & self.CONTROL: lt+=[MidiType.CONTROL_CHANGE]
- if self.type & self.PROGRAM: lt+=[MidiType.PROGRAM_CHANGE]
- ok=False
- for tt in lt:
- if tt==t:
- ok=True
- break
- if not ok: return False
-
- if self.key!=None and self.key!=-1 and not (msg.key in self.key): return False
- if self.channel!=None and self.channel!=-1 and not (msg.key in self.channel): return False
- if out!=None and self.forward: out.send(msg)
- print(msg)
- self.trigger(msg)
- return True
-
-
- class MidiMultiTrigger:
-
- """
- param={
- id_1 : PARAM_TO_MIDI_EVENT_TRIGGER,
- id_2 : PARAM_TO_MIDI_EVENT_TRIGGER,
- ...
- id_n : PARAM_TO_MIDI_EVENT_TRIGGER,
- }
- """
- def __init__(self, param={}):
- if not isinstance(param, dict): raise Exception("MidiMultiTrigger expects an dict argument")
- self.data={}
- for i in param.keys():
- self.addTrigger(i, param[i])
-
-
- def addTrigger(self, name, param):
- self.data[name]=MidiEventTrigger(param)
-
- """
- names: None ou une liste des id a tester
- renvoie une liste des declenchements
- """
- def filter(self, msg, out, names=None):
- ret=[]
- toTest=self.data.keys()
- if names!=None: toTest=names
-
- for i in toTest:
- if self.data[i].filter(msg, out): ret.append(i)
- return ret
|