def set_processing_mixer_state_all(cls, fcp, subunit_id, attr, fb_id, in_fb, data): attrs = ('current', 'minimum', 'maximum', 'resolution', 'default') if subunit_id > 0x07: raise ValueError('Invalid argument for subunit ID') if attr not in attrs: raise ValueError('Invalid argument for attribute') if fb_id > 255: raise ValueError('Invalid argument for function block ID') if in_fb > 255: raise ValueError('Invalid argument for input function block ID') for datum in data: if len(data) != 2: raise ValueError('Invalid argument for array of data array') args = bytearray() args.append(0x00) args.append(0x08 | (subunit_id & 0x07)) args.append(0xb8) args.append(0x82) # Processing function block args.append(fb_id) args.append(cls.ATTRIBUTE_VALUES[attr]) args.append(0x04) # Selector length is 4 args.append(in_fb) args.append(0xff) args.append(0xff) args.append(0x03) # Mixer control args.append(len(data)) # The length of control data for datum in data: args.extend(datum) AvcGeneral.command_control(fcp, args)
def set_processing_mixer_state(cls, fcp, subunit_id, attr, fb_id, in_fb, in_ch, out_ch, data): attrs = ('current', 'minimum', 'maximum', 'resolution', 'default') if subunit_id > 0x07: raise ValueError('Invalid argument for subunit ID') if attr not in attrs: raise ValueError('Invalid argument for attribute') if fb_id > 255: raise ValueError('Invalid argument for function block ID') if in_fb > 255: raise ValueError('Invalid argument for input function block ID') if in_ch > 255: raise ValueError('Invalid argument for input channel number') if out_ch > 255: raise ValueError('Invalid argument for output channel number') if len(data) != 2: raise ValueError('Invalid argument for data array') args = bytearray() args.append(0x00) args.append(0x08 | (subunit_id & 0x07)) args.append(0xb8) args.append(0x82) # Processing function block args.append(fb_id) args.append(cls.ATTRIBUTE_VALUES[attr]) args.append(0x04) # Selector length is 4 args.append(in_fb) args.append(in_ch) args.append(out_ch) args.append(0x03) # Mixer control args.append(0x02) # Control data is 2 args.extend(data) # Higher and lower parts of setting AvcGeneral.command_control(fcp, args)
def set_feature_mute_state(cls, fcp, subunit_id, attr, fb_id, ch, mute): if subunit_id > 0x07: raise ValueError('Invalid argument for subunit ID') if attr is not 'current': raise ValueError('Invalid argument for attribute') if fb_id > 255: raise ValueError('Invalid argument for function block ID') if ch > 255: raise ValueError('Invalid argument for channel number') if mute: val = 0x70 else: val = 0x60 args = bytearray() args.append(0x00) args.append(0x08 | (subunit_id & 0x07)) args.append(0xb8) args.append(0x81) # Feature function block args.append(fb_id) args.append(cls.ATTRIBUTE_VALUES[attr]) args.append(0x02) # Selector length is 2 args.append(ch) args.append(0x01) # Mute control args.append(0x01) # Control data length is 1 args.append(val) AvcGeneral.command_control(fcp, args)
def set_digital_channel_status(cls, fcp, spec, name, values): if spec == 'con': attrs = cls.SUPPORTED_CON_STATUS subcmds = cls.__CON_SUBCMDS elif spec == 'pro': attrs = cls.SUPPORTED_PRO_STATUS subcmds = cls.__PRO_SUBCMDS else: raise ValueError('Invalid argument for specification name') if name not in attrs: raise ValueError('Invalid argument for attribute name') if attrs[name] != 1: if type(values) != 'list' or len(values) != attrs[name]: raise ValueError('Invalid argument for attribute value length') args = bytearray(0xff for i in range(10)) args[0] = 0x00 args[1] = 0xff args[2] = 0x00 args[3] = cls.SUPPORTED_SPEC.index(spec) args[4] = subcmds[name] args[5] = attrs[name] if attrs[name] == 1: args[6] = values else: for i in range(len(values)): args[6 + i] = values[i] AvcGeneral.command_control(fcp, args)
def ask_signal_source(cls, fcp, src, dst): args = bytearray() args.append(0x02) args.append(0xff) args.append(0x1a) args.append(0xff) args.append(src[0]) args.append(src[1]) args.append(dst[0]) args.append(dst[1]) AvcGeneral.command_inquire(fcp, args)
def command_set_param(self, cmd, param): deps = bytearray() deps.append(0x46) deps.append(0x49) deps.append(0x31) deps.append(cmd) deps.append(param) try: AvcGeneral.set_vendor_dependent(self.fcp, self.company_ids, deps) except Exception as e: if str(e) != 'Unknown status': raise e
def set_format(cls, fcp, direction, plug, fmt): args = bytearray() args.append(0x00) # Control args.append(0xff) # Addressing to unit args.append(0xbf) # Extended stream format information command args.append(0xc0) # SINGLE subfunction args.append(cls.plug_direction.index(direction)) args.append(0x00) args.append(0x00) args.append(plug) args.append(0xff) args.append(0xff) args.extend(cls._build_format(fmt)) AvcGeneral.command_control(fcp, args)
def __command_set(cls, fcp, cmd, key, name): if key not in cls.__PARAMS[cmd]: raise ValueError('Invalid argument for {0}.'.format(name)) data = bytearray() data.extend(cls.__PREFIX) data.append(cmd.value) data.append(cls.__PARAMS[cmd][key]) try: AvcGeneral.set_vendor_dependent(fcp, cls.__OUI, data) # The response frame includes wrong __OUI and __PREFIX. except Exception as e: # The response code is 0x0c, against control requect (0x00). if str(e) != 'Unknown status': raise e
def get_subunit_fb_info(cls, fcp, subunit_type, subunit_id, page, fb_type): if subunit_type not in AvcGeneral.SUBUNIT_TYPES: raise ValueError('Invalid argument for subunit type') if subunit_id > 7: raise ValueError('Invalid argument for subunit id') args = bytearray(0xff for i in range(30)) args[0] = 0x01 args[1] = ( AvcGeneral.SUBUNIT_TYPES.index(subunit_type) << 3) | subunit_id args[2] = 0x31 args[3] = page args[4] = 0xff try: params = AvcGeneral.command_status(fcp, args) except Exception as e: if str(e) == 'Not implemented': return [] raise entries = [] for i in range(5): if params[5 + 5 * i] == 0xff: continue entry = {} entry['type'] = params[5 + 5 * i] entry['id'] = params[6 + 5 * i] entry['purpose'] = cls.FB_PURPOSE[params[7 + 5 * i]] entry['inputs'] = params[8 + 5 * i] entry['outputs'] = params[9 + 5 * i] entries.append(entry) return entries
def get_plug_clusters(cls, fcp, addr): args = bytearray() args.append(0x01) args.append(addr[5]) args.append(0x02) # Plug info command args.append(0xc0) # Bco plug info subcommand args.append(addr[0]) args.append(addr[1]) args.append(addr[2]) args.append(addr[3]) args.append(addr[4]) args.append(0x03) # Info type is 'channel position data' args.append(0xff) args.append(0xff) params = AvcGeneral.command_status(fcp, args) data = params[10:] pos = 0 clusters = [[] for i in range(data[pos])] pos += 1 for cls in range(len(clusters)): num = data[pos] pos += 1 if num == 0: break clusters[cls] = [[0, 0] for j in range(num)] for e in range(len(clusters[cls])): clusters[cls][e][0] = data[pos] clusters[cls][e][1] = data[pos + 1] pos += 2 return clusters
def __parse_subunit_plugs(self): subunit_plugs = {} for page in range(AvcGeneral.MAXIMUM_SUBUNIT_PAGE + 1): try: subunits = AvcGeneral.get_subunit_info(self.fcp, page) except: break for entry in subunits: type = entry['type'] maximum_id = entry['maximum-id'] if type not in subunit_plugs: subunit_plugs[type] = {} for id in range(maximum_id + 1): if id not in subunit_plugs[type]: subunit_plugs[type][id] = {} subunit_plugs[type][id]['output'] = {} subunit_plugs[type][id]['input'] = {} info = AvcConnection.get_subunit_plug_info(self.fcp, type, 0) for dir, num in info.items(): for i in range(num): plug = self.__parse_subunit_plug(dir, type, 0, i) subunit_plugs[type][id][dir][i] = plug return subunit_plugs
def get_subunit_plug_info(cls, fcp): subunits = {} for page in range(AvcGeneral.MAXIMUM_SUBUNIT_PAGE + 1): try: info = AvcGeneral.get_subunit_info(fcp, page) except Exception: break for entry in info: subunit_type = entry['type'] maximum_id = entry['maximum-id'] for subunit_id in range(maximum_id + 1): try: data = AvcConnection.get_subunit_plug_info( fcp, subunit_type, subunit_id) except Exception: continue id = (subunit_type, subunit_id) if id not in subunits: subunits[id] = {} for direction, count in data.items(): subunits[id][direction] = count return subunits
def get_formats(cls, fcp, direction, plug): if direction not in cls.plug_direction: raise ValueError('Invalid argument for plug direction') if plug > 255: raise ValueError('Invalid argument for plug number') fmts = [] args = bytearray() args.append(0x01) args.append(0xff) args.append(0xbf) args.append(0xc1) args.append(cls.plug_direction.index(direction)) args.append(0x00) args.append(0x00) args.append(plug) args.append(0xff) args.append(0xff) args.append(0x00) args.append(0xff) for i in range(255): args[10] = i try: params = AvcGeneral.command_status(fcp, args) fmt = cls._parse_format(params[11:]) fmts.append(fmt) except Exception as e: break return fmts
def get_entry_list(cls, fcp, addr): fmts = [] for i in range(0xff): # DM1500 tends to cause timeout. time.sleep(0.1) try: args = bytearray() args.append(0x01) args.append(addr[5]) args.append(0x2f) # Bco stream format support args.append(0xc1) # List request args.append(addr[0]) args.append(addr[1]) args.append(addr[2]) args.append(addr[3]) args.append(addr[4]) args.append(0xff) args.append(i) args.append(0xff) params = AvcGeneral.command_status(fcp, args) fmts.append(cls._parse_format(params[11:])) except OSError as e: if str(e) != 'Rejected': raise else: break return fmts
def get_processing_mixer_state(cls, fcp, subunit_id, attr, fb_id, in_fb, in_ch, out_ch): attrs = ('current', 'minimum', 'maximum', 'resolution', 'default') if subunit_id > 0x07: raise ValueError('Invalid argument for subunit ID') if attr not in attrs: raise ValueError('Invalid argument for attribute') if fb_id > 255: raise ValueError('Invalid argument for function block ID') if in_fb > 255: raise ValueError('Invalid argument for input function block ID') if in_ch > 255: raise ValueError('Invalid argument for input channel number') if out_ch > 255: raise ValueError('Invalid argument for output channel number') args = bytearray() args.append(0x01) args.append(0x08 | (subunit_id & 0x07)) args.append(0xb8) args.append(0x82) # Processing function block args.append(fb_id) args.append(cls.attribute_values[attr]) args.append(0x04) # Selector length is 4 args.append(in_fb) args.append(in_ch) args.append(out_ch) args.append(0x03) # Mixer control args.append(0x02) # Control data is 2 args.append(0xff) # Higher part of setting args.append(0xff) # Lower part of setting params = AvcGeneral.command_status(fcp, args) data = params[12:14] return data
def get_feature_lr_state(cls, fcp, subunit_id, attr, fb_id, ch): if subunit_id > 0x07: raise ValueError('Invalid argument for subunit ID') if attr not in cls.ATTRIBUTES: raise ValueError('Invalid argument for attribute') if fb_id > 255: raise ValueError('Invalid argument for function block ID') if ch > 255: raise ValueError('Invalid argument for channel number') args = bytearray() args.append(0x01) args.append(0x08 | (subunit_id & 0x07)) args.append(0xb8) args.append(0x81) # Feature function block args.append(fb_id) args.append(cls.ATTRIBUTE_VALUES[attr]) args.append(0x02) # Selector length is 2 args.append(ch) args.append(0x03) # LR control args.append(0x02) # Control data length is 2 args.append(0xff) # Higher part of balance args.append(0xff) # Lower part of balance params = AvcGeneral.command_status(fcp, args) data = params[10:12] return data
def get_feature_mute_state(cls, fcp, subunit_id, attr, fb_id, ch): if subunit_id > 0x07: raise ValueError('Invalid argument for subunit ID') if attr is not 'current': raise ValueError('Invalid argument for attribute') if fb_id > 255: raise ValueError('Invalid argument for function block ID') if ch > 255: raise ValueError('Invalid argument for channel number') args = bytearray() args.append(0x01) args.append(0x08 | (subunit_id & 0x07)) args.append(0xb8) args.append(0x81) # Feature function block args.append(fb_id) args.append(cls.ATTRIBUTE_VALUES[attr]) args.append(0x02) # Selector length is 2 args.append(ch) args.append(0x01) # Mute control args.append(0x01) # Control data length is 1 args.append(0xff) # Status params = AvcGeneral.command_status(fcp, args) val = params[10] if val == 0x70: return True elif val == 0x60: return False else: raise OSError('Unexpected value in response')
def get_processing_mixer_state_all(cls, fcp, subunit_id, attr, fb_id, in_fb): attrs = ('current', 'minimum', 'maximum', 'resolution', 'default') if subunit_id > 0x07: raise ValueError('Invalid argument for subunit ID') if attr not in attrs: raise ValueError('Invalid argument for attribute') if fb_id > 255: raise ValueError('Invalid argument for function block ID') if in_fb > 255: raise ValueError('Invalid argument for input function block ID') args = bytearray() args.append(0x01) args.append(0x08 | (subunit_id & 0x07)) args.append(0xb8) args.append(0x82) # Processing function block args.append(fb_id) args.append(cls.ATTRIBUTE_VALUES[attr]) args.append(0x04) # Selector length is 4 args.append(in_fb) args.append(0xff) args.append(0xff) args.append(0x03) # Mixer control args.append(0xff) # The length of control data in response params = AvcGeneral.command_status(fcp, args) count = params[11] // 2 data = [] params = params[12:] for i in range(0, count, 2): data.append(params[i * 2:i * 2 + 1]) return data
def get_firmware_version(cls, fcp: Hinawa.FwFcp): data = bytearray() data.extend(cls.__PREFIX) data.append(VendorCmd.FIRMWARE_VER.value) data.append(0xff) resp = AvcGeneral.get_vendor_dependent(fcp, cls.__OUI, data) # The response frame includes wrong __OUI and __PREFIX. return resp[4]
def __init__(self, path): super().__init__(path) if self.vendor_name != 'TASCAM' or self.model_name != 'FireOne': raise ValueError('Unsupported model: {0}, {1}'.format( self.vendor_name, self.model_name)) unit_info = AvcGeneral.get_unit_info(self.fcp) self.company_ids = unit_info['company-id']
def command_get_param(self, cmd): deps = bytearray() deps.append(0x46) deps.append(0x49) deps.append(0x31) deps.append(cmd) deps.append(0xff) params = AvcGeneral.get_vendor_dependent(self.fcp, self.company_ids, deps) return params[4]
def set_signal_source(cls, fcp, src, dst): args = bytearray() args.append(0x00) args.append(0xff) args.append(0x1a) args.append(0x0f) args.append(src[0]) args.append(src[1]) args.append(dst[0]) args.append(dst[1]) return AvcGeneral.command_control(fcp, args)
def set_selector_state(cls, fcp, subunit_id, attr, fb_id, value): if subunit_id > 0x07: raise ValueError('Invalid argument for subunit ID') if attr not in ('current', 'minimum', 'maximum', 'default'): raise ValueError('Invalid argument for attribute') if fb_id > 255: raise ValueError('Invalid argument for function block ID') if value > 255: raise ValueError('Invalid argument for selector value') args = bytearray() args.append(0x00) args.append(0x08 | (subunit_id & 0x07)) args.append(0xb8) args.append(0x80) # Selector function block args.append(fb_id) args.append(cls.ATTRIBUTE_VALUES[attr]) args.append(0x02) # Selector length is 2 args.append(value) args.append(0x01) # Selector control AvcGeneral.command_control(fcp, args)
def __command_get(cls, fcp, cmd, name): data = bytearray() data.extend(cls.__PREFIX) data.append(cmd.value) data.append(0xff) resp = AvcGeneral.get_vendor_dependent(fcp, cls.__OUI, data) # The response frame includes wrong __OUI and __PREFIX. for key, val in cls.__PARAMS[cmd].items(): if val == resp[4]: return key raise OSError('Invalid argument for {0}.'.format(name))
def get_signal_source(cls, fcp, dst): args = bytearray() args.append(0x01) args.append(0xff) args.append(0x1a) args.append(0xff) args.append(0xff) args.append(0xfe) args.append(dst[0]) args.append(dst[1]) params = AvcGeneral.command_status(fcp, args) src = params[4:6] return cls.parse_signal_addr(src)
def set_feature_lr_state(cls, fcp, subunit_id, attr, fb_id, ch, data): if subunit_id > 0x07: raise ValueError('Invalid argument for subunit ID') if attr not in cls.ATTRIBUTES: raise ValueError('Invalid argument for attribute') if fb_id > 255: raise ValueError('Invalid argument for function block ID') if ch > 255: raise ValueError('Invalid argument for channel number') if len(data) != 2: raise ValueError('Invalid argument for data array') args = bytearray() args.append(0x00) args.append(0x08 | (subunit_id & 0x07)) args.append(0xb8) args.append(0x81) # Feature function block args.append(fb_id) args.append(cls.ATTRIBUTE_VALUES[attr]) args.append(0x02) # Selector length is 2 args.append(ch) args.append(0x03) # LR control args.append(0x02) # Control data length is 2 args.extend(data) # Higher and lower parts of volume AvcGeneral.command_control(fcp, args)
def get_plug_channels(cls, fcp, addr): args = bytearray() args.append(0x01) args.append(addr[5]) args.append(0x02) # Plug info command args.append(0xc0) # Bco plug info subcommand args.append(addr[0]) args.append(addr[1]) args.append(addr[2]) args.append(addr[3]) args.append(addr[4]) args.append(0x02) # Info type is 'the number of channels' args.append(0xff) args.append(0xff) params = AvcGeneral.command_status(fcp, args) return params[10]
def get_plug_input(cls, fcp, addr): args = bytearray() args.append(0x01) args.append(addr[5]) args.append(0x02) # Plug info command args.append(0xc0) # Bco plug info subcommand args.append(addr[0]) args.append(addr[1]) args.append(addr[2]) args.append(addr[3]) args.append(addr[4]) args.append(0x05) # Info type is 'input data' args.append(0xff) args.append(0xff) params = AvcGeneral.command_status(fcp, args) return cls.parse_plug_addr(params[10:])
def get_stream_detection(cls, fcp, company_ids, dir, ext_plug): if dir not in cls.ADDR_DIR: raise ValueError('Invalid argument for address direction') if ext_plug >= 255: raise ValueError('Invalid argument for external plug number') args = bytearray() args.append(0x00) args.append(cls.ADDR_DIR.index(dir)) args.append(ext_plug) args.append(0xff) params = AvcGeneral.get_vendor_dependent(fcp, company_ids, args) if params[0] != args[0] or params[1] != args[1] or params[2] != args[2]: raise OSError('Unexpected value in response') if params[3] == 0x00: return False return True
def get_plug_cluster_info(cls, fcp, addr, cluster): args = bytearray() args.append(0x01) args.append(addr[5]) args.append(0x02) # Plug info command args.append(0xc0) # Bco plug info subcommand args.append(addr[0]) args.append(addr[1]) args.append(addr[2]) args.append(addr[3]) args.append(addr[4]) args.append(0x07) # Info type is 'cluster info' args.append(cluster) args.append(0xff) params = AvcGeneral.command_status(fcp, args) length = params[12] return params[13:13 + length].decode()