#!/usr/bin/env python3 import sys import struct import xml.etree.ElementTree as ET import sys import binascii class SigmadDSPFirmwareGen(object): CHUNK_TYPE_DATA = 0 CHUNK_TYPE_CONTROL = 1 CHUNK_TYPE_SAMPLERATES = 2 CHUNK_HEADER_SIZE = 12 CHUNK_DATA_HEADER_SIZE = CHUNK_HEADER_SIZE + 2 CHUNK_CONTROL_HEADER_SIZE = CHUNK_HEADER_SIZE + 6 def __init__(self, in_files, out_file): self.crcsum = 0xffffffff self.size = 12 self.data_chunks = [] self.control_chunks = [] self.controls = {} samplerates = [] samplerate_mask = 1 for samplerate, in_file in in_files: samplerates.append(samplerate) self.parse_input_file(in_file, samplerate_mask, samplerate) samplerate_mask <<= 1 ok = True for chunk in self.control_chunks: ok = ok & self.validate_control_chunk(chunk) ok |= self.merge_control_chunks() if not ok: return self.out = open(out_file, "wb") self.out.write(b"ADISIGM") self.out.write(struct.pack(" 43: print("ERROR: Control name '%s' is to long. Maximum length is 43 characters" % full_name) ok = False key = (full_name, samplerate_mask) if key in self.controls: # SigmaStudio sometimes generates multiple controls that are 100% # identical, only generate an error if there are multiple controls # with the same name, but having different addresses or lengths if self.controls[key] != control_chunk: print("ERROR: Duplicated control name '%s'" % full_name) ok = False else: self.controls[key] = control_chunk return ok def merge_control_chunks(self): new_chunks = {} ok = True for chunk in self.control_chunks: name, pname, addr, length, samplerate_mask = chunk full_name = "%s %s" % (name, pname) if full_name in new_chunks.keys(): other_addr, other_length, other_samplerate_mask = new_chunks[full_name][2:5] if (other_addr != addr or other_length != length) and \ (samplerate_mask & other_samplerate_mask) == 0: print("ERROR: Controls with the same name for different samplerates need the same address and length. Mismatch for control {} ({}, {}) != ({}, {})".format( full_name, other_addr, other_length, addr, length)) ok = False new_chunks[full_name][4] |= samplerate_mask else: new_chunks[full_name] = [name, pname, addr, length, samplerate_mask] self.control_chunks = [tuple(x) for x in new_chunks.values()] return ok def write_control_chunk(self, control_chunk): name, pname, addr, length, samplerate_mask = control_chunk name_len = len("%s %s" % (name, pname)) size = self.CHUNK_CONTROL_HEADER_SIZE + name_len self.write_chunk_header(size, self.CHUNK_TYPE_CONTROL, samplerate_mask) self.write(struct.pack(" [ ] ".format(sys.argv[0])) sys.exit(1) in_files = {} for i in range(1, len(sys.argv) - 2, 2): rate = int(sys.argv[i+1]) if rate in in_files.keys(): print("ERROR: Duplicated samplerate {}".format(rate)) sys.exit(1) in_files[rate] = sys.argv[i] SigmadDSPFirmwareGen(in_files.items(), sys.argv[-1])