def param_to_bytes(self, value, max_length=1, ignore_limit=False, word_length=None): biquad = False if word_length is None: word_length = self.dsp.WORD_LENGTH if isinstance(value, float): value = self.dsp.decimal_repr(value) res = int_data(value, word_length) elif isinstance(value, int): res = int_data(value, word_length) elif isinstance(value, Biquad): res = [] bqn = value.normalized() vals = [] vals.append(bqn.b2) vals.append(bqn.b1) vals.append(bqn.b0) vals.append(-bqn.a2) vals.append(-bqn.a1) for v in vals: dec = self.dsp.decimal_repr(v) res = res + list(int_data(dec, word_length)) elif isinstance(value, Iterable): res = [] for part in value: if isinstance(part, Biquad): biquad = True res = res + self.param_to_bytes(part, 0, ignore_limit=True) else: raise RuntimeError("parameter type not implemented: %s", type(value).__name__) while len(res) < max_length * word_length: if biquad: # Fill biquad filter banks with pass filters passfilter = Biquad.pass_filter() res = res + \ self.param_to_bytes(passfilter, 0, ignore_limit=True) else: # Fill with zeros res.append(0) if not (ignore_limit) and len(res) > (max_length * word_length): logging.error( "parameter set too long (%s bytes), won't fit into %s words", len(res), max_length * self.dsp.WORD_LENGTH) res = None return res
def parse_biquad(self, value): filters = value.split(",") result = [] for f in filters: try: biquad = Biquad.create_filter(f, self.fs) except Exception: biquad = None if biquad == None: logging.error("can't parse filter definition %s", f) else: result.append(biquad) return result
def readfilters(filename, fs=48000): filters = [] with open(filename) as file: for line in file.readlines(): line = line.strip() if len(line) == 0: continue if line.startswith("#"): continue try: bq = Biquad.create_filter(line, fs) filters.append(bq) except Exception as e: print(e) logging.warning("can't parse line %s", line) return filters
def readfilters(filename, fs=48000): filters = [] with open(filename) as file: for line in file.readlines(): if line.startswith("Filter"): parts = line.split() if len(parts) >= 12 and parts[2] == "ON" and \ parts[4] == "Fc" and parts[6] == "Hz" and \ parts[7] == "Gain" and parts[9] == "dB" and \ parts[10] == "Q": fc = float(parts[5]) gain = float(parts[8]) q = float(parts[11]) logging.info("Filter fc=%s, q=%s, gaion=%s, fs=%s", fc, q, gain, fs) filters.append(Biquad.peaking_eq(fc, q, gain, fs)) return filters
def cmd_tonecontrol(self): if len(self.args.parameters) > 2: filtertype = self.args.parameters[0].lower() frequency = parse_frequency(self.args.parameters[1]) dbgain = parse_decibel(self.args.parameters[2]) else: print( "parameter missing, need type frequency db, e.g. ls 200Hz 3db") sys.exit(1) if frequency <= 0: print("frequency {} invalid".format(frequency)) sys.exit(1) if filtertype not in ["ls", "hs"]: print("filter type {} unsupported".format(type)) sys.exit(1) filterdef = "{}:{}:{}".format(filtertype, frequency, dbgain) tonefilter = Biquad.create_filter(filterdef, self.dsptk.get_samplerate()) if tonefilter is None: print("can't handle filter {}".format(filterdef)) sys.exit(1) if filtertype[0] == "l": low = tonefilter high = None else: low = None high = tonefilter try: self.dsptk.set_tonecontrol_filters(low, high) except Exception as e: print(e) sys.exit(1)
def readfilters(filename, fs=48000): filters = [] with open(filename) as file: for line in file.readlines(): if line.startswith("Filter"): parts = line.split() if len(parts) >= 12 and parts[2] == "ON" and \ parts[3] == "PK" and \ parts[4] == "Fc" and parts[6] == "Hz" and \ parts[7] == "Gain" and parts[9] == "dB" and \ parts[10] == "Q": fc = float(parts[5]) gain = float(parts[8]) q = float(parts[11]) logging.info("Filter EQ fc=%s, q=%s, gaion=%s, fs=%s", fc, q, gain, fs) filters.append(Biquad.peaking_eq(fc, q, gain, fs)) elif len(parts) >= 6 and parts[2] == "ON" and \ parts[3] == "LP" and \ parts[4] == "Fc" and parts[6] == "Hz": fc = float(parts[5]) logging.info("Filter LP fc=%s", fc) filters.append(Biquad.low_pass(fc, 0.707, fs)) elif len(parts) >= 9 and parts[2] == "ON" and \ parts[3] == "LPQ" and \ parts[4] == "Fc" and parts[6] == "Hz" and \ parts[7] == "Q": fc = float(parts[5]) q = float(parts[8]) logging.info("Filter LPQ fc=%s, q=%s", fc, q) filters.append(Biquad.low_pass(fc, q, fs)) elif len(parts) >= 10 and parts[2] == "ON" and \ parts[3] == "LS" and \ parts[4] == "Fc" and parts[6] == "Hz" and \ parts[7] == "Gain" and parts[9] == "dB": fc = float(parts[5]) db = float(parts[8]) q = 0.707 logging.info("Filter LS fc=%s, db=%s", fc, db) filters.append(Biquad.low_shelf(fc, q, db, fs)) elif len(parts) >= 6 and parts[2] == "ON" and \ parts[3] == "HP" and \ parts[4] == "Fc" and parts[6] == "Hz": fc = float(parts[5]) logging.info("Filter HP fc=%s", fc) filters.append(Biquad.high_pass(fc, 0.707, fs)) elif len(parts) >= 9 and parts[2] == "ON" and \ parts[3] == "HPQ" and \ parts[4] == "Fc" and parts[6] == "Hz" and \ parts[7] == "Q": fc = float(parts[5]) q = float(parts[8]) logging.info("Filter HPQ fc=%s, q=%s", fc, q) filters.append(Biquad.high_pass(fc, q, fs)) elif len(parts) >= 10 and parts[2] == "ON" and \ parts[3] == "HS" and \ parts[4] == "Fc" and parts[6] == "Hz" and \ parts[7] == "Gain" and parts[9] == "dB": fc = float(parts[5]) db = float(parts[8]) q = 0.707 logging.info("Filter HS fc=%s, db=%s", fc, db) filters.append(Biquad.high_shelf(fc, q, db, fs)) elif len(parts) >= 7 and parts[2] == "ON" and \ parts[3] == "NO" and \ parts[4] == "Fc" and parts[6] == "Hz": fc = float(parts[5]) q = 0.707 logging.info("Filter NO fc=%s", fc, db) filters.append(Biquad.notch(fc, q, fs)) else: if len(parts) >= 4 and parts[3] != "None": print("Filter type " + parts[3] + " not yet supported") return filters
def clear_iir_filters(self, mode=MODE_BOTH): # Simply fill filter arrays with dummy filters self.set_filters([Biquad.plain()] * 256, mode=mode, cutoff_long=True)