+ # Note: Unlike other methods, this code pops bytes out of self.cmd
+ # to isolate the data.
+ msg, eox = self.cmd.pop(0), self.cmd.pop()
+ if len(self.cmd) < 1:
+ self.putx([0, ['SysEx: truncated manufacturer code (<1 bytes)']])
+ self.cmd, self.state = [], 'IDLE'
+ return
+ # Extract the manufacturer name (or SysEx realtime or non-realtime).
+ m1 = self.cmd.pop(0)
+ manu = (m1,)
+ if m1 == 0x00: # If byte == 0, then 2 more manufacturer bytes follow.
+ if len(self.cmd) < 2:
+ self.putx([0, ['SysEx: truncated manufacturer code (<3 bytes)']])
+ self.cmd, self.state = [], 'IDLE'
+ return
+ manu = (m1, self.cmd.pop(0), self.cmd.pop(0))
+ default_name = 'undefined'
+ manu_name = sysex_manufacturer_ids.get(manu, default_name)
+ if manu_name == default_name:
+ if len(manu) == 3:
+ manu_name = '%s (0x%02x 0x%02x 0x%02x)' % \
+ (default_name, manu[0], manu[1], manu[2])
+ else:
+ manu_name = '%s (0x%02x)' % (default_name, manu[0])
+ # Extract the payload.
+ # TODO: Write methods to decode SysEx realtime & non-realtime payloads.
+ payload = ''
+ while len(self.cmd) > 0:
+ payload += '0x%02x ' % (self.cmd.pop(0))
+ if payload == '':
+ payload = '<empty>'
+ self.putx([0, ['SysEx: for \'%s\' with payload %s' % \
+ (manu_name, payload)]])
+ self.cmd, self.state = [], 'IDLE'
+
+ def handle_syscommon_midi_time_code_quarter_frame_msg(self, newbyte):
+ # MIDI time code quarter frame: F1 nd
+ # n = message type
+ # d = values
+ c = self.cmd
+ if len(c) < 2:
+ return
+ msg = self.cmd[0]
+ nn, dd = (self.cmd[1] & 0x70) >> 4, self.cmd[1] & 0x0f
+ group = 'System Common'
+ self.es_block = self.es
+ if nn != 7: # If message type does not contain SMPTE type.
+ self.putx([0, ['%s: %s of %s, value 0x%01x' % \
+ (group, status_bytes[msg], quarter_frame_type[nn], dd)]])
+ self.cmd, self.state = [], 'IDLE'
+ return
+ tt = (dd & 0x6) >> 1
+ self.putx([0, ['%s: %s of %s, value 0x%01x for %s' % \
+ (group, status_bytes[msg], quarter_frame_type[nn], \
+ dd, smpte_type[tt])]])