diff --git a/SelectedTrackControl.py b/SelectedTrackControl.py index 3ce8217..56a7706 100755 --- a/SelectedTrackControl.py +++ b/SelectedTrackControl.py @@ -39,6 +39,7 @@ def __init__(self, c_instance): self._device_control, QuantizationControl(c_instance, self), ) + self.prevMsg = None def mapping_parse_recursive(self, mapping): tuple_type = type((1,2)); @@ -75,32 +76,62 @@ def update_display(self): def connect_script_instances(self, instanciated_scripts): pass - + + + def recursive_forward_midi(self,script_handle,midi_map_handle, data): + # need to check if tuple, or not: + if type(data)==tuple: + # Live.Base.log("tuple detected") + for i in data: + self.recursive_forward_midi(script_handle, midi_map_handle,i) + elif isinstance(data,MIDI.Note) or isinstance(data,MIDI.NoteOff): + # Live.Base.log("recusrive_forward_midi logging Note: channel %d, key %d" % (data.channel, data.key)) + Live.MidiMap.forward_midi_note(script_handle, midi_map_handle, data.channel, data.key) + elif isinstance(data,MIDI.CC): + # Live.Base.log("recusrive_forward_midi logging CC: channel %d, key %d" % (data.channel, data.key)) + Live.MidiMap.forward_midi_cc(script_handle, midi_map_handle, data.channel, data.key) + else: + # Live.Base.log("Type didn't work...") + # Live.Base.log(type(data).__name__) + pass + + # called from Live to build the MIDI bindings def build_midi_map(self, midi_map_handle): #log("SelectedTrackControl::build_midi_map") script_handle = self.c_instance.handle() - - for channel in range(16): - callbacks = self.midi_callbacks.get(channel, {}) - - for note in callbacks.get(MIDI.NOTEON_STATUS,{}).keys(): - Live.MidiMap.forward_midi_note(script_handle, midi_map_handle, channel, note) - - for cc in callbacks.get(MIDI.CC_STATUS,{}).keys(): - Live.MidiMap.forward_midi_cc(script_handle, midi_map_handle, channel, cc) - - + """ + EN: this needs to only capture the notes and cc's from the settings.py list + """ + + Live.Base.log("STC_EN: Starting mapping") + for item in settings.midi_mapping: + # item -> key + #MIDI.midi_mapping[item] -> values + # Live.Base.log("STC_EN: mapping Item: %s" % (item)) + self.recursive_forward_midi(script_handle,midi_map_handle, settings.midi_mapping[item]) + # called from Live when MIDI messages are received def receive_midi(self, midi_bytes): + """ + There seems to be a doubling up of messages, may need to filter if two messages are too close together; + but this may affect other functinality. + :param midi_bytes: + :return: + """ + # Dirty filter: + if self.prevMsg is not None and midi_bytes==self.prevMsg: + return + self.prevMsg = midi_bytes + channel = (midi_bytes[0] & MIDI.CHAN_MASK) status = (midi_bytes[0] & MIDI.STATUS_MASK) key = midi_bytes[1] value = midi_bytes[2] - #log("receive_midi on channel %d, status %d, key %d, value %d" % (channel, status, key, value)) + # Live.Base.log("receive_midi on channel %d, status %d, key %d, value %d" % (channel, status, key, value)) # execute callbacks that are registered for this event callbacks = self.midi_callbacks.get(channel,{}).get(status,{}).get(key,[]) @@ -151,4 +182,11 @@ def register_midi_callback(self, callback, key, mode, status, channel): self.midi_callbacks[channel][status][key].append(callback) else: self.midi_callbacks[channel][status][key] = [callback, ] + + def send_midi(self, midi_event_bytes): + u"""Script -> Live + Use this function to send MIDI events through Live to the _real_ MIDI devices + that this script is assigned to. + """ + self.c_instance.send_midi(midi_event_bytes) \ No newline at end of file