def chuck(samplerate, sig, shift_hz=1000): rc_imag = [ allpass(samplerate, rc) for rc in [5.49e-06, 4.75e-05, 2.37e-04, 1.27e-03] ] rc_real = [ allpass(samplerate, rc) for rc in [2.00e-05, 1.07e-04, 5.36e-04, 4.64e-03] ] sos_imag = [ signal.tf2sos( polynomial.polymul(rc1[0], rc2[0]), polynomial.polymul(rc1[1], rc2[1]), )[0] for rc1, rc2 in zip(rc_imag[::2], rc_imag[1::2]) ] sos_real = [ signal.tf2sos( polynomial.polymul(rc1[0], rc2[0]), polynomial.polymul(rc1[1], rc2[1]), )[0] for rc1, rc2 in zip(rc_real[::2], rc_real[1::2]) ] # plot_response(sys._getframe().f_code.co_name, sos_real, sos_imag) real = signal.sosfilt(sos_real, sig) imag = signal.sosfilt(sos_imag, sig) analytic = 0.5 * (real - 1j * imag) return pitch_shift(samplerate, analytic, shift_hz)
def group_delays(b, a, w, plot=None): """ Compute group delay of analog filter. Parameters ---------- b : array_like Numerator of a linear filter. a : array_like Denominator of a linear filter. w : array_like Angular frequencies in rad/s. plot : callable, optional A callable that takes two arguments. If given, the return parameters `w` and `gd` are passed to plot. Returns ------- w : ndarray The angular frequencies at which `gd` was computed. gd : ndarray The group delay in seconds. """ b, a = map(np.atleast_1d, (b, a)) sos = tf2sos(b, a) gd = sos_group_delays(sos, w)[1] if plot is not None: plot(w, gd) return w, gd
def low_pass_filter(signal, fs, end_freq): """ Description - Low Pass Filter Input :param signal:list, 입력 신호 :param fs: Float, 샘플링 주파수 (sampling frequency) :param end_freq: Float, 끝 주파수 (passband) Output :return list, 필터링된 신호 Example: >>> signal = [0, 1, 2, 3, 2, 1, 0, -1, -2, -3, -2, -1] >>> fs = 0.1 >>> end_freq = 0.02 >>> low_pass_filter(signal, fs, end_freq) array([-7.04764275e-05, 1.06577490e+00, 2.14355722e+00, 2.64998306e+00, 2.14375040e+00, 1.06552842e+00, -1.00019323e-03, -1.06409485e+00, -2.13795954e+00, -2.66057414e+00, -2.17495858e+00, -9.99904965e-01]) """ n, wn = buttord(2 * end_freq / fs, 4 * end_freq / fs, 1, 10) # 'Butterworth Filter'의 차수(order) 구하기 b, a = butter(n, wn, btype='low') # 'Butterworth Filter'의 a와 b 파라메터 생성 sos = tf2sos(b, a) # 2차수(order) 필터 계수의 배열 구하기 signal = np.array(signal).reshape(-1) # 1차원 리스트가 아닌 경우를 위해 1차원으로 변환 filtered_signal = sosfiltfilt(sos, signal) # A forward-backward digital filter using cascaded second-order sections. return filtered_signal
def design_filter(self): """ This filter is used to design Biquad Filters This creates the A and B coefficients for Biquad IIR filters as used in CSPL """ f0 = self.fc.value() Q = self.Q.value() gain = self.linear_gain.value() biquadType = self.filter_type.value() design_function = BIQUAD_DESIGN_LIBRARY[biquadType] b_coefficients, a_coefficients = design_function( gain, f0, Q, SAMPLERATE) # if the filter design results in a numerator and denominator that are equal, then just implement the passthrough filter if np.array_equal(b_coefficients, a_coefficients): b_coefficients = np.array([1., 0., 0.]) a_coefficients = np.array([1., 0., 0.]) self.a = np.array(a_coefficients) / a_coefficients[0] self.b = np.array(b_coefficients) / a_coefficients[0] assert len(self.a) == 3 assert len(self.b) == 3 self.sos = signal.tf2sos(self.b, self.a) self.coefficients_changed.emit()
def low_shelving_2nd_cascade(w0, Gb, num_biquad, biquad_per_octave, Q=1 / np.sqrt(2)): """Low shelving filter design using cascaded biquad filters. Parameters ---------- w0 : float Cut-off frequency in radian per second. Gb : float Gain of each biquad filter in decibel. num_biquad : int Number of biquad filters. Q : float, optional Quality factor of each biquad filter. Returns ------- sos : array_like Array of second-order filter coefficients, must have shape ``(n_sections, 6)``. Each row corresponds to a second-order section, with the first three columns providing the numerator coefficients and the last three providing the denominator coefficients. """ sos = np.zeros((num_biquad, 6)) for m in range(num_biquad): wm = w0 * 2**(-(m + 0.5) / biquad_per_octave) b, a = low_shelving_2nd_coeff(omega=wm, G=Gb, Q=Q) sos[m] = tf2sos(b, a) return sos
def group_delayz(b, a, w, plot=None, fs=2*np.pi): """ Compute the group delay of digital filter. Parameters ---------- b : array_like Numerator of a linear filter. a : array_like Denominator of a linear filter. w : array_like Frequencies in the same units as `fs`. plot : callable A callable that takes two arguments. If given, the return parameters `w` and `gd` are passed to plot. fs : float, optional The angular sampling frequency of the digital system. Returns ------- w : ndarray The frequencies at which `gd` was computed, in the same units as `fs`. gd : ndarray The group delay in seconds. """ b, a = map(np.atleast_1d, (b, a)) if len(a) == 1: # scipy.signal.group_delay returns gd in samples thus scaled by 1/fs gd = sig.group_delay((b, a), w=w, fs=fs)[1] else: sos = sig.tf2sos(b, a) gd = sos_group_delayz(sos, w, plot, fs)[1] if plot is not None: plot(w, gd) return w, gd
def __init__(self, output_count, dtype, color): """ Parameters ---------- output_count : int number of channels to generate dtype : str or numpy.dtype or type data type to generate color : str coloration of noise to generate """ super().__init__(output_count=output_count, dtype=dtype) color = color.upper() # initialize constants self._GAIN_FACTOR = 20 # fmt: off self._B_PINK = np.array([0.049922035, -0.095993537, 0.050612699, -0.004408786], dtype=dtype) self._A_PINK = np.array([1, -2.494956002, 2.017265875, -0.522189400], dtype=dtype) # "Consider designing filters in ZPK format and converting directly to SOS." # https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.tf2sos.html self._SOS_EM = np.array( [[0.0248484318401191, -0.0430465879719351, 0.0185894592446002, 1, -1.83308400613427, 0.833084457582538], [1.09742855358091, -2, 0.902572344822294, 1, -1.84861597668780, 0.849007279800584], [1.32049919002049, -2, 1.27062183754708, 1, -1.51266987481441, 0.958710654962438], [2, -1.23789744854974, 0.693137522016399, 1, -0.555672516031578, 0.356572277622976], [2, -0.127412449936323, 0.451198075878658, 1, -0.0464446484127454, 0.0651312831643292], [0.295094951044653, 0.0954033015853709, 0, 1, 0, 0]], dtype=dtype ) # fmt: on # pick utilized coefficients if color == "PINK": a = self._A_PINK self._sos = tf2sos(b=self._B_PINK, a=self._A_PINK).astype(dtype) # "It is generally discouraged to convert from TF to SOS format, since doing so # usually will not improve numerical precision errors." # https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.tf2sos.html elif color in ["EM", "EIGENMIKE"]: [_, a] = sos2tf(sos=self._SOS_EM) self._sos = self._SOS_EM else: raise NotImplementedError( f'chosen noise generator color "{color}" not implemented yet.' ) # initialize IIR filter delay conditions self._last_delays = sosfilt_zi(sos=self._sos).astype(dtype) # adjust in middle axis according to output count self._last_delays = np.repeat( self._last_delays[:, np.newaxis, :], repeats=output_count, axis=1 ) # approximate decay time to skip transient response part of IIR filter, according to [1] t60_samples = int(np.log(1000.0) / (1.0 - np.abs(np.roots(a)).max())) + 1 # generate and discard long enough sequence to skip IIR transient response (decay time) _ = self.generate_block(block_length=t60_samples)
def reconstruction(self, v): out = np.zeros(v.shape[0]) for index, filter in enumerate(self.H): print("For filter %i, with coefficents\n%s\n" % (index, filter)) sos = signal.tf2sos(filter.num, filter.den) noise = signal.sosfilt(sos, v[:, index]) out = out + (-1.)**(index) * noise return out
def __init__(self, name, input_signal, b=[1., 1.], a=[1., 1., 1.], **kwargs): super().__init__(name, **kwargs) self._input = input_signal self._sos = sp.tf2sos(b, a)
def applyThiran(sig, order=12, oversample=8): out = [] for fraction in np.linspace(0, 1, oversample, endpoint=False)[1:]: b, a = thiranAllpass(order, fraction) sos = signal.tf2sos(b, a) out.append(signal.sosfilt(sos, sig)) delay = order // 2 index = np.linspace(-delay, len(sig) - delay, len(out), endpoint=False) return out, index
def design_filter(self): R = self.R.value() Rleak = self.Rleak.value() L = self.L.value() Zs = signal.lti([(R + Rleak) * L, R * Rleak], [L, Rleak]) Zd = Zs.to_discrete(1 / SAMPLERATE) self.b = Zd.num self.a = Zd.den self.sos = signal.tf2sos(self.b, self.a) self.coefficients_changed.emit()
def mcnulty(samplerate, sig, shift_hz=1000): rc_real = [ allpass(samplerate, rc) for rc in [ 9.31e-06, 4.2723e-05, 0.0001836, 0.00078146, 0.003333, 0.026055, ] ] rc_imag = [ allpass(samplerate, rc) for rc in [ 2.6676e-06, 2.08e-05, 8.87e-05, 0.00038064, 0.0016049999999999999, 0.007412, ] ] sos_real = [ signal.tf2sos( polynomial.polymul(rc1[0], rc2[0]), polynomial.polymul(rc1[1], rc2[1]), )[0] for rc1, rc2 in zip(rc_real[::2], rc_real[1::2]) ] sos_imag = [ signal.tf2sos( polynomial.polymul(rc1[0], rc2[0]), polynomial.polymul(rc1[1], rc2[1]), )[0] for rc1, rc2 in zip(rc_imag[::2], rc_imag[1::2]) ] # plot_response(sys._getframe().f_code.co_name, sos_real, sos_imag) real = signal.sosfilt(sos_real, sig) imag = signal.sosfilt(sos_imag, sig) analytic = 0.5 * (real - 1j * imag) return pitch_shift(samplerate, analytic, shift_hz)
def receive_stages(self, b, a): self.sos = np.array(ss.tf2sos(b, a, pairing='keep_odd')) for it in range(0, len(self.sos)): self.stages_list.append(False) tempObject = stageControl(self, self.stages_list, it) tempItem = QtWidgets.QListWidgetItem() tempItem.setSizeHint(tempObject.sizeHint()) self.ui.FilterList.addItem(tempItem) self.ui.FilterList.setItemWidget(tempItem, tempObject) self.manage_plot() #Ploteamos las etapas
def make_digital_filter(N, rp, rs, Wn, btype='low'): finish = False WnAdd = Wn rpAdd = rp rsAdd = rs fullArray = [] try: while (finish == False): if (WnAdd < 0.5): WnAdd = WnAdd + 0.001 elif (abs(rpAdd - rp) / rp < 0.05): rpAdd = rpAdd + 0.01 elif (abs(rsAdd - rs) / rs < 0.05): rsAdd = rsAdd + 0.01 else: raise Exception( "There is no filters with these characteristics.") b, a = signal.ellip(N, rpAdd, rsAdd, WnAdd, btype, analog=False) sos = signal.tf2sos(b, a) #print sos w, h = signal.sosfreqz(sos, worN=1000000) #plot_2nd_order_from_sos(sos) makeCallibration(sos) #plot_2nd_order_from_sos(sos) #print "sos" print sos w, h = signal.sosfreqz(sos, worN=1000000) #plot_sosfreqz(w,h) #fullArray = getCoefficientsForElliptic(sos, True) fullArray = getCoefficients(sos) #print fullArray try: new_sos = getSosFromCoefficients(fullArray) #new_sos = getSosFromCoefficientsForElliptic(fullArray) finish = True except ValueError as e: pass except Exception as e: print e print "There is no filters with these characteristics." return w, h = signal.sosfreqz(sos, worN=1000000) #plot_sosfreqz(w,h) print "new_sos" print new_sos print "general_coefficients" fullArrayRounded = getRoundCoefficients(fullArray) getKeysFromKoefArray(fullArrayRounded) w, h = signal.sosfreqz(new_sos, worN=1000000) plot_sosfreqz(w, h)
def high_shelving_1st_cascade(w0, Gb, num_biquad, biquad_per_octave): """High shelving filter design using cascaded biquad filters. - see low_shelving_2nd_cascade() - under construction for code improvement """ sos = np.zeros((num_biquad, 6)) for m in range(num_biquad): wm = w0 * 2**(-(m + 0.5) / biquad_per_octave) b, a = high_shelving_1st_coeff(omega=wm, G=Gb) sos[m] = tf2sos(b, a) return sos
def _normalized_sos(coeff): # Subfunction to re-normalize the coefficients of the incoming LPC (FIR) coefficients to unity based on the noise # gain np.sqrt(np.sum(coeff**2)) impulse = np.zeros(129) impulse[64] = 1 sos = signal.tf2sos(1, coeff) filtsig1 = signal.sosfilt(sos, impulse) lpc_noise_gain = np.sqrt(np.sum(filtsig1**2)) gainmatrix = np.ones([sos.shape[0], sos.shape[1]]) gainmatrix[0, 0] = 1 / lpc_noise_gain soscoeff = sos * gainmatrix return soscoeff
def convert2SOS(myFilter): SOSarray = tf2sos(myFilter.num, myFilter.den) SOSnumber,_ = SOSarray.shape SOSoutput = np.empty(shape=(SOSnumber,3)) for index in range(SOSnumber): SOSoutput[index][:] = SOSarray[index][3::] if SOSoutput[index][2]==0: SOSoutput[index] = np.roll(SOSoutput[index],1) return SOSoutput
def testApply(): samplerate = 44100 duration = 1 # seconds frequency = 100 time = np.linspace(0, duration, duration * samplerate) phase = (frequency * time) saw = signal.sawtooth(phase, 1.0) coef = thiran(16, 16.5) print(coef) sos = signal.tf2sos(*coef) sig = signal.sosfilt(sos, saw) print(f"Converge?: {np.all(np.isfinite(sig))}") soundfile.write("out.wav", sig, samplerate, subtype="FLOAT")
def lowShelf(w0, Q, A): #Low Shelf #H(s) = A * ((s^2 + sqrt(A)*s/Q + A) / (A*(s^2) + sqrt(A)*s/Q + 1) COSW0 = math.cos(w0) alpha = math.sin(w0) / (2 * Q) b0 = A * ((A + 1) - (A - 1) * COSW0 + (2 * math.sqrt(A) * alpha)) b1 = 2 * A * ((A - 1) - ((A + 1) * COSW0)) b2 = A * ((A + 1) - (A - 1) * COSW0 - (2 * math.sqrt(A) * alpha)) a0 = (A + 1) + ((A - 1) * COSW0) + (2 * math.sqrt(A) * alpha) a1 = -2 * ((A - 1) + ((A + 1) * COSW0)) a2 = (A + 1) + ((A - 1) * COSW0) - (2 * math.sqrt(A) * alpha) num = [b0, b1, b2] den = [a0, a1, a2] sos = signal.tf2sos(num, den) return sos
def bandpass(w0, Q): #BPF using peak gain Q #H(s) = s / (s^2 + s/q + 1) COSW0 = math.cos(w0) alpha = math.sin(w0) / (2 * Q) b0 = Q * alpha #= SINW0/2 b1 = 0 b2 = -b0 a0 = a + alpha a1 = -2 * COSW0 a2 = 1 - alpha num = [b0, b1, b2] den = [a0, a1, a2] sos = signal.tf2sos(num, den) return sos
def peaking(w0, Q, A): #Peaking EQ, modeled from: #H(s) = (s^2 + s*A/Q + 1) / ( s^2 + s/(A*Q) + 1) COSW0 = math.cos(w0) alpha = math.sin(w0) / (2 * Q) b0 = 1 + (alpha * A) b1 = -2 * COSW0 b2 = 1 - (alpha * A) a0 = 1 + (alpha / A) a1 = -2 * COSW0 a2 = 1 - (alpha / A) num = [b0, b1, b2] den = [a0, a1, a2] sos = signal.tf2sos(num, den) return sos
def highpass(w0, Q): #HPF, modeled from: #H(s) = (s^2) / ((s^2) + (s/Q) + 1) COSW0 = math.cos(w0) alpha = math.sin(w0) / (2 * Q) b0 = (1 + COSW0) / 2 b1 = -(1 + COSW0) b2 = b0 a0 = 1 + alpha a1 = -2 * COSW0 a2 = 1 - alpha num = [b0, b1, b2] den = [a0, a1, a2] sos = signal.tf2sos(num, den) return sos
def get_session_encoding_models(session_info, models=None): """ Loops and computes traditional scores open-field scores for each unit, these include: -> speed score: correlation between firing rate and speed -> head angle score: correlation between firing rate and head angle -> head directation score: correlation between firing rate and head direction -> border score: -> spatial information: -> grid score: :param SubjectSessionInfo session_info: instance of class SubjectInfo for a particular subject :return: dict: with all the scores """ # get data fr = session_info.get_fr() # smooth data to match behavior time smoothness sos_coefs = signal.tf2sos(session_info.task_params['filter_coef_'], 1) fr2 = signal.sosfiltfilt(sos_coefs, fr, axis=1) spikes = session_info.get_binned_spikes() of_dat = SimpleNamespace(**session_info.get_track_data()) task_params = session_info.task_params sem = spatial_funcs.AllSpatialEncodingModels(x=of_dat.x, y=of_dat.y, speed=of_dat.sp, ha=of_dat.ha, hd=of_dat.hd, neural_data=fr2, n_jobs=10, **task_params) if models is None: sem.get_models() else: if isinstance(models, str): models = [models] for model in models: model_method = f"get_{model}_model" if hasattr(sem, model_method): getattr(sem, model_method)() else: print(f"Encoding model for {model} does not exists.") sem.get_scores() return sem
def printSos(order=12, oversample=5): for fraction in np.linspace(0, 1, oversample, endpoint=False)[1:]: print(fraction) b, a = thiran(order, order + fraction) sos = signal.tf2sos(b, a) print("{") for section in sos: text = " {" for idx, value in enumerate(section): if idx == 3: continue if idx != len(section) - 1: text += f"Sample({value}), " else: text += f"Sample({value})" print(text + "},") print("}")
def lowShelf(w0, Q, A): #WROTE AND TESTED THIS FUNCTION, LEFT IT UNUSED IN FINAL IMPLEMENTATION #Low Shelf, modeled from: #H(s) = A * ((s^2 + sqrt(A)*s/Q + A) / (A*(s^2) + sqrt(A)*s/Q + 1) COSW0 = math.cos(w0) alpha = math.sin(w0) / (2 * Q) b0 = A * ((A + 1) - (A - 1) * COSW0 + (2 * math.sqrt(A) * alpha)) b1 = 2 * A * ((A - 1) - ((A + 1) * COSW0)) b2 = A * ((A + 1) - (A - 1) * COSW0 - (2 * math.sqrt(A) * alpha)) a0 = (A + 1) + ((A - 1) * COSW0) + (2 * math.sqrt(A) * alpha) a1 = -2 * ((A - 1) + ((A + 1) * COSW0)) a2 = (A + 1) + ((A - 1) * COSW0) - (2 * math.sqrt(A) * alpha) num = [b0, b1, b2] den = [a0, a1, a2] sos = signal.tf2sos(num, den) return sos
def bandpass(w0, Q): #WROTE THIS FUNCTION, LEFT IT UNUSED IN FINAL IMPLEMENTATION #BPF, modeled from: #H(s) = s / (s^2 + s/q + 1) COSW0 = math.cos(w0) alpha = math.sin(w0) / (2 * Q) b0 = Q * alpha #= SINW0/2 b1 = 0 b2 = -b0 a0 = a + alpha a1 = -2 * COSW0 a2 = 1 - alpha num = [b0, b1, b2] den = [a0, a1, a2] sos = signal.tf2sos(num, den) return sos
def lowpass(w0, Q): #LPF, modeled from: #H(s) = 1/(s^2 + s/Q + 1) COSW0 = math.cos(w0) alpha = math.sin(w0) / (2 * Q) b0 = (1 - COSW0) / 2 b1 = 1 - COSW0 b2 = b0 a0 = 1 + alpha a1 = -2 * COSW0 a2 = 1 - alpha num = [b0, b1, b2] den = [a0, a1, a2] sos = signal.tf2sos(num, den) return sos
def signal(self): """ Deliver the signal. Returns ------- Array of floats The resulting signal as an array of length :attr:`~SignalGenerator.numsamples`. """ rnd_gen = RandomState(self.seed) ma = self.handle_empty_coefficients(self.ma) ar = self.handle_empty_coefficients(self.ar) sos = tf2sos(ma, ar) ntaps = ma.shape[0] sdelay = round(0.5 * (ntaps - 1)) wnoise = self.rms * rnd_gen.standard_normal( self.numsamples + sdelay) # create longer signal to compensate delay return sosfilt(sos, x=wnoise)[sdelay:]
def lowpass(w0, Q): #RETURNS SOS that can be used in SOSFILT #LPF #H(s) = 1/(s^2 + s/Q + 1) COSW0 = math.cos(w0) alpha = math.sin(w0) / (2 * Q) b0 = (1 - COSW0) / 2 b1 = 1 - COSW0 b2 = b0 a0 = 1 + alpha a1 = -2 * COSW0 a2 = 1 - alpha num = [b0, b1, b2] den = [a0, a1, a2] sos = signal.tf2sos(num, den) return sos
def band_pass_filter(signal, fs, start_freq, end_freq, margin_rate): """ Description - High Pass Filter Input :param signal:list, 입력 신호 :param fs: Float, 샘플링 주파수 (sampling frequency) :param start_freq: Float, 시작 주파수 (passband) :param end_freq: Float, 끝 주파수 (passband) :param margin_rate: Float, 마진율 Output :return list, 필터링된 신호 Example > signal = [0, 1, 2, 3, 2, 1, 0, -1, -2, -3, -2, -1] > fs = 0.1 > start_freq = 0.001 > end_freq = 0.003 > band_pass_filter(signal, fs, start_freq, end_freq, 0.08) [0.63095463 0.95862525 1.23888854 1.41245392 1.44684504 1.36618891 1.22107957 1.05946482 0.92849059 0.87631723 0.92292086 1.02981141] """ # fn = fs / 2 wp = np.divide([start_freq, end_freq], fn) ws = np.divide([start_freq * margin_rate, end_freq / margin_rate], fn) n, wn = buttord(wp, ws, 1, 10) # 'Butterworth Filter'의 차수(order) 구하기 b, a = butter(n, wn, btype='band') # 'Butterworth Filter'의 a와 b 파라메터 생성 sos = tf2sos(b, a) signal = np.array(signal).reshape(-1) filtered_signal = sosfiltfilt(sos, signal) return filtered_signal
def output_filter(B, A, name, show_response = False, emit_test_ir = False, impulse_resp_length = 64): sos = signal.tf2sos(B, A) if show_response: B, A = signal.sos2tf(sos) w, h = signal.freqz(B, A, worN=2**12) plt.title('Digital filter frequency response') plt.semilogx(w*fs/(2.0*np.pi), 20 * np.log10(abs(h)), label = 'A_orig') plt.ylim(-50, 20) plt.ylabel('Amplitude [dB]', color='b') plt.xlabel('Frequency [rad/sample]') plt.grid() plt.show() filter_q = 31 max_q_adjust = 0 for bq in range(len(sos)): sos[bq] /= sos[bq][3] abs_sum = sum(abs(sos[bq])) - 1.0 m = int(np.ceil(np.log2(abs_sum))) #TODO check this works for -ve abs_sums max_q_adjust = max(max_q_adjust, m) max_q_adjust -= 1 #to take advantage of 64 bit maccs filter_q -= max_q_adjust #TODO check for -ve max_q_adjust sos_quantised = np.zeros(np.shape(sos)) int_max = np.int64(int32_max) / 2**max_q_adjust print 'const int32_t filter_coeffs_' + name + '[] = {' for bq in range(len(sos)): print '\t', for i in range(3): v = np.int32(np.float64(int_max) * sos[bq][i]) print str(v) + ', ' , sos_quantised[bq][i] = np.float64(v) / np.float64(int_max) for i in range(4, 6): v = int(np.float64(int_max) * -sos[bq][i]) sos_quantised[bq][i] = np.float64(-v) / np.float64(int_max) print str(v) + ', ' , print sos_quantised[bq][3] = 1.0 print '};' print 'const uint32_t num_sections_' + name + ' = ' + str(len(sos)) + ';' print 'const uint32_t q_format_' + name + ' = ' + str(filter_q) + ';' print 'int32_t filter_state_'+ name +'[' +str(len(sos)) + '*DSP_NUM_STATES_PER_BIQUAD] = {0};' d = np.zeros(impulse_resp_length) d[0] = 1 B_q, A_q = signal.sos2tf(sos_quantised) filter_impulse_response = signal.lfilter(B_q, A_q, d) if emit_test_ir: print 'const unsigned impulse_resp_length_' + name + ' = ' + str(impulse_resp_length)+';' print 'const int32_t expected_ir_' + name + '[' + str(impulse_resp_length) + '] = {' for i in range(impulse_resp_length): s = str(int(int32_max * filter_impulse_response[i])) + ', ' if i%8 == 7: print s else: print s, print '};' return