class Filter: def __init__(self, B, A): """Create an IIR filter, given the B and A coefficient vectors""" self.B = B self.A = A if len(A) > 2: self.prev_outputs = Ringbuffer(len(A) - 1) else: self.prev_outputs = Ringbuffer(3) self.prev_inputs = Ringbuffer(len(B)) def filter(self, x): #take one sample, and filter it. Return the output y = 0 self.prev_inputs.new_sample(x) k = 0 for b in self.B: y = y + b * self.prev_inputs.reverse_index(k) k = k + 1 k = 0 for a in self.A[1:]: y = y - a * self.prev_outputs.reverse_index(k) k = k + 1 y = y / self.A[0] self.prev_outputs.new_sample(y) return y def new_sample(self, x): return self.filter(x)
class Filter: def __init__(self, B, A): """Create an IIR filter, given the B and A coefficient vectors""" self.B = B self.A = A if len(A)>2: self.prev_outputs = Ringbuffer(len(A)-1) else: self.prev_outputs = Ringbuffer(3) self.prev_inputs = Ringbuffer(len(B)) def filter(self, x): #take one sample, and filter it. Return the output y = 0 self.prev_inputs.new_sample(x) k =0 for b in self.B: y = y + b * self.prev_inputs.reverse_index(k) k = k + 1 k = 0 for a in self.A[1:]: y = y - a * self.prev_outputs.reverse_index(k) k = k + 1 y = y / self.A[0] self.prev_outputs.new_sample(y) return y def new_sample(self,x): return self.filter(x)
class WindowedAverage: def __init__(self, window): if have_numpy: self.window = numpy.array(window) else: self.window = list(window) self.buffer = Ringbuffer(len(window)) def new_sample(self, x): self.buffer.new_sample(x) if have_numpy: avg = numpy.mean(self.buffer.get_samples() * self.window) else: i = 0 sum = 0 for s in self.buffer.get_samples(): sum += self.window[i]*s i = i + 1 avg = sum/len(self.window) return avg
class Erosion: def __init__(self, window): self.window = window self.buffer = Ringbuffer(window) def new_sample(self, x): self.buffer.new_sample(x) return min(self.buffer.get_samples())
class MovingAverage: def __init__(self, window_len): self.window_len = window_len self.buffer = Ringbuffer(window_len) def new_sample(self, x): self.buffer.new_sample(x) return self.buffer.get_sum() / float(self.window_len)
class EnergyBuffer: def __init__(self, len): self.buffer = Ringbuffer(len) self.differentiator = Differentiator() def new_sample(self, x): d = self.differentiator.new_sample(x) self.buffer.new_sample(x*x) return math.sqrt(self.buffer.get_mean())
class MovingAverage: def __init__(self, window_len): self.window_len = window_len self.buffer = Ringbuffer(window_len) def new_sample(self, x): self.buffer.new_sample(x) return self.buffer.get_sum()/float(self.window_len)
class RandomDelay: def __init__(self, window): self.window = window self.buffer = Ringbuffer(window) def new_sample(self, x): self.buffer.new_sample(x) s = self.buffer.get_samples return random.choice(s)
class EnergyBuffer: def __init__(self, len): self.buffer = Ringbuffer(len) self.differentiator = Differentiator() def new_sample(self, x): d = self.differentiator.new_sample(x) self.buffer.new_sample(x * x) return math.sqrt(self.buffer.get_mean())
class PLL: #phase locked loop def __init__(self, bp_filter, lp_filter, centre_freq, sr, loop_gain=1.0, in_gain=1.0): self.sr = sr self.base_rate = (centre_freq*2*math.pi) / sr self.int = 0 self.bp_filter = bp_filter self.lp_filter = lp_filter self.phase_buffer = Ringbuffer(int(sr/centre_freq)) self.loop_gain = loop_gain self.in_gain = in_gain def set_gain(self, gain): self.gain = gain def set_base_freq(self, freq): self.base_rate = (freq*2*math.pi) / self.sr def get_sync(self): return abs(self.phase_buffer.get_sum()) def new_sample(self, x): (osc,int,y) = self.run(x) return int def run(self, x): #band pass the input y = self.bp_filter.new_sample(x*self.in_gain) # drive the oscillator at natural frequency self.int = self.int + self.base_rate osc = math.sin(self.int) #compute phase difference phase_com = osc * y #store phase comparison self.phase_buffer.new_sample(phase_com) # filter the phase comparator ph_adj = self.lp_filter.new_sample(phase_com) # shift the integrator self.int = self.int + ph_adj * self.loop_gain #return value of oscillator, the phase value (unwrapped), and the bp filtered input signal return (osc, self.int, y)
class PLL: #phase locked loop def __init__(self, bp_filter, lp_filter, centre_freq, sr, loop_gain=1.0, in_gain=1.0): self.sr = sr self.base_rate = (centre_freq * 2 * math.pi) / sr self.int = 0 self.bp_filter = bp_filter self.lp_filter = lp_filter self.phase_buffer = Ringbuffer(int(sr / centre_freq)) self.loop_gain = loop_gain self.in_gain = in_gain def set_gain(self, gain): self.gain = gain def set_base_freq(self, freq): self.base_rate = (freq * 2 * math.pi) / self.sr def get_sync(self): return abs(self.phase_buffer.get_sum()) def new_sample(self, x): (osc, int, y) = self.run(x) return int def run(self, x): #band pass the input y = self.bp_filter.new_sample(x * self.in_gain) # drive the oscillator at natural frequency self.int = self.int + self.base_rate osc = math.sin(self.int) #compute phase difference phase_com = osc * y #store phase comparison self.phase_buffer.new_sample(phase_com) # filter the phase comparator ph_adj = self.lp_filter.new_sample(phase_com) # shift the integrator self.int = self.int + ph_adj * self.loop_gain #return value of oscillator, the phase value (unwrapped), and the bp filtered input signal return (osc, self.int, y)
class WindowedReduceFilter: def __init__(self, binop, window): self.state = None self.window = window self.buffer = Ringbuffer(window) self.binop = binop def new_sample(self, x): self.buffer.new_sample(x) samples = self.buffer.get_samples() state = reduce(self.binop, samples) return state
class Delay: def __init__(self, delay): self.delay = delay self.buffer = Ringbuffer(delay) def new_sample(self, x): return self.buffer.new_sample(x)
class Median: def __init__(self, window): self.window = window self.buffer = Ringbuffer(window) def new_sample(self, x): self.buffer.new_sample(x) b = list(self.buffer.get_samples()) b.sort() lb = len(b) # even case if lb % 2 == 0: return b[len(b) / 2] + b[len(b) / 2 + 1] else: # odd case return b[len(b + 1) / 2]
class Median: def __init__(self, window): self.window = window self.buffer = Ringbuffer(window) def new_sample(self, x): self.buffer.new_sample(x) b = list(self.buffer.get_samples()) b.sort() lb = len(b) # even case if lb%2==0: return b[len(b)/2]+b[len(b)/2+1] else: # odd case return b[len(b+1)/2]
class WindowedAverage: def __init__(self, window): if have_numpy: self.window = numpy.array(window) else: self.window = list(window) self.buffer = Ringbuffer(len(window)) def new_sample(self, x): self.buffer.new_sample(x) if have_numpy: avg = numpy.mean(self.buffer.get_samples() * self.window) else: i = 0 sum = 0 for s in self.buffer.get_samples(): sum += self.window[i] * s i = i + 1 avg = sum / len(self.window) return avg