class BLTriangle(GeneratorInterface): """ Implements a triangle signal generator based on BLIT algorithm """ def __init__(self, sampling_rate, with_postfilter=True, ppiv=2700): super(BLTriangle, self).__init__(sampling_rate) self._table = GenerateBLSawtoothIntegrate(sampling_rate=sampling_rate, length=4, ppiv=ppiv) self._halfM = len(self._table) self._sawtooth_gen = PhaseAccumulator(sampling_rate) self._alpha = 0.0 self._frequency = 0.0 self._phi = 0.0 self._update = True if with_postfilter: self._post_filter = BLPostFilter() def SetPhase(self, phase): self._sawtooth_gen.SetPhase(phase) self._phi = phase if hasattr(self, '_post_filter'): self._post_filter.set_last(0.0) def SetFrequency(self, frequency): self._sawtooth_gen.SetFrequency(frequency) self._frequency = frequency def _read_table(self, value): abs_value = numpy.abs(value) if abs_value < self._alpha: relative_index = int( numpy.round(self._halfM * abs_value / self._alpha)) index = numpy.minimum(self._halfM - relative_index, self._halfM - 1) if index > self._halfM / 2: read = self._table[self._halfM - index] else: read = self._table[index] # print(str(self) + str(value) + " " + str(relative_index) + " " + str(index) + "->" + str(read)) return read else: return 0.0 def ProcessSample(self): self._ProcessParameters() tmp = self._sawtooth_gen.ProcessSample() A = IncrementAndWrap(tmp, self._phi) B = IncrementAndWrap(A, 1.0) C = 2 * numpy.abs(A) - 1.0 D = self._read_table(A) E = self._read_table(B) normalised_freq = 2 * self._frequency / self._sampling_rate F = C - D * normalised_freq + E * normalised_freq # out = numpy.clip(F, -1.0, 1.0) out = F if hasattr(self, '_post_filter'): return self._post_filter.process_sample(out) else: return out def _ProcessParameters(self): if self._update: self._alpha = self._sampling_rate * 4 / self._frequency self._update = False
class BLSawtooth(GeneratorInterface): """ Implements a sawtooth signal generator based on BLIT algorithm """ def __init__(self, sampling_rate, with_postfilter=True): super(BLSawtooth, self).__init__(sampling_rate) self._table = GenerateBLSawtoothSegment(sampling_rate=sampling_rate, length=4) self._halfM = len(self._table) self._sawtooth_gen = PhaseAccumulator(sampling_rate) self._frequency = 0.0 self._update = False self._alpha = 1.0 self._phi = 0.0 self.debug_A = 0.0 self.debug_B = 0.0 self.debug_C = 0.0 if with_postfilter: self._post_filter = BLPostFilter() print(self._halfM) def SetPhase(self, phase): self._phi = phase if hasattr(self, '_post_filter'): self._post_filter.set_last(0.0) def SetFrequency(self, frequency): self._frequency = frequency self._sawtooth_gen.SetFrequency(frequency) self._update = True def _read_table(self, value): abs_value = numpy.abs(value) sign_value = numpy.sign(value) if abs_value < self._alpha: relative_index = int(self._halfM * abs_value / self._alpha) # index = numpy.minimum(self._halfM - relative_index, self._halfM - 1) index = self._halfM - relative_index - 1 # print(index) read = sign_value * self._table[index] return read else: return 0.0 def ProcessSample(self): self._ProcessParameters() current = self._sawtooth_gen.ProcessSample() A = IncrementAndWrap(current, self._phi) C = self._read_table(A) B = IncrementAndWrap(A, 1.0) out = B + C self.debug_A = A self.debug_B = B self.debug_C = C if hasattr(self, '_post_filter'): return self._post_filter.process_sample(out) else: return out def _ProcessParameters(self): if self._update: self._alpha = self._frequency * 4.0 / self._sampling_rate print(self._alpha) self._update = False
class BLSawtooth(GeneratorInterface): """ Implements a sawtooth signal generator based on BLIT algorithm """ def __init__(self, sampling_rate, with_postfilter=True): super(BLSawtooth, self).__init__(sampling_rate) self._table = GenerateBLSawtoothSegment(sampling_rate=sampling_rate, length = 4) self._halfM = len(self._table) self._sawtooth_gen = PhaseAccumulator(sampling_rate) self._frequency = 0.0 self._update = False self._alpha = 1.0 self._phi = 0.0 self.debug_A = 0.0 self.debug_B = 0.0 self.debug_C = 0.0 if with_postfilter: self._post_filter = BLPostFilter() print(self._halfM) def SetPhase(self, phase): self._phi = phase if hasattr(self, '_post_filter'): self._post_filter.set_last(0.0) def SetFrequency(self, frequency): self._frequency = frequency self._sawtooth_gen.SetFrequency(frequency) self._update = True def _read_table(self, value): abs_value = numpy.abs(value) sign_value = numpy.sign(value) if abs_value < self._alpha: relative_index = int(self._halfM * abs_value / self._alpha) # index = numpy.minimum(self._halfM - relative_index, self._halfM - 1) index = self._halfM - relative_index - 1 # print(index) read = sign_value * self._table[index] return read else: return 0.0 def ProcessSample(self): self._ProcessParameters() current = self._sawtooth_gen.ProcessSample() A = IncrementAndWrap(current, self._phi) C = self._read_table(A) B = IncrementAndWrap(A, 1.0) out = B + C self.debug_A = A self.debug_B = B self.debug_C = C if hasattr(self, '_post_filter'): return self._post_filter.process_sample(out) else: return out def _ProcessParameters(self): if self._update: self._alpha = self._frequency * 4.0 / self._sampling_rate print(self._alpha) self._update = False
class BLTriangle(GeneratorInterface): """ Implements a triangle signal generator based on BLIT algorithm """ def __init__(self, sampling_rate, with_postfilter=True, ppiv=2700): super(BLTriangle, self).__init__(sampling_rate) self._table = GenerateBLSawtoothIntegrate(sampling_rate=sampling_rate, length = 4, ppiv=ppiv) self._halfM = len(self._table) self._sawtooth_gen = PhaseAccumulator(sampling_rate) self._alpha = 0.0 self._frequency = 0.0 self._phi = 0.0 self._update = True if with_postfilter: self._post_filter = BLPostFilter() def SetPhase(self, phase): self._sawtooth_gen.SetPhase(phase) self._phi = phase if hasattr(self, '_post_filter'): self._post_filter.set_last(0.0) def SetFrequency(self, frequency): self._sawtooth_gen.SetFrequency(frequency) self._frequency = frequency def _read_table(self, value): abs_value = numpy.abs(value) if abs_value < self._alpha: relative_index = int(numpy.round(self._halfM * abs_value / self._alpha)) index = numpy.minimum(self._halfM - relative_index, self._halfM - 1) if index > self._halfM / 2: read = self._table[self._halfM - index] else: read = self._table[index] # print(str(self) + str(value) + " " + str(relative_index) + " " + str(index) + "->" + str(read)) return read else: return 0.0 def ProcessSample(self): self._ProcessParameters() tmp = self._sawtooth_gen.ProcessSample() A = IncrementAndWrap(tmp, self._phi) B = IncrementAndWrap(A, 1.0) C = 2 * numpy.abs(A) - 1.0 D = self._read_table(A) E = self._read_table(B) normalised_freq = 2 * self._frequency / self._sampling_rate F = C - D * normalised_freq + E * normalised_freq # out = numpy.clip(F, -1.0, 1.0) out = F if hasattr(self, '_post_filter'): return self._post_filter.process_sample(out) else: return out def _ProcessParameters(self): if self._update: self._alpha = self._sampling_rate * 4 / self._frequency self._update = False