Формулы преобразования аналоговых фильтров в цифровые, Easyelectronics: Цифровые рекурсивные фильтры. Часть 1
import numpy as np
class ConvolutionDef_P2:
def __init__(self):
self.B = [1.0, 0.0, 0.0]
self.A = [0.0, 0.0]
def HPF2_CalcScales(freqHz, sampleHz):
if (freqHz > 0) and (sampleHz > 0):
try:
betta = np.tan(freqHz / sampleHz * np.pi)
betta2 = betta * betta
A0 = 1 + np.sqrt(2) * betta + betta2
A1 = 2 - 2 * betta2
A2 = 1 - np.sqrt(2) * betta + betta2
B0 = betta2
B1 = -2 * betta2
B2 = betta2
convol = ConvolutionDef_P2()
convol.B[0] = B0 / A0
convol.B[1] = B1 / A0
convol.B[2] = B2 / A0
convol.A[0] = -A1 / A0
convol.A[1] = -A2 / A0
except Exception as e:
convol = Convolution()
print("ERROR FilterCalc: {}".format(str(e)))
print(vars(convol))
return convol
def LPF2_CalcScales(freqHz, sampleHz):
scales = HPF2_CalcScales(freqHz, sampleHz)
scales.A[0] = -scales.A[0]
scales.B[1] = -scales.B[1]
return scales
def FilterApplyToSample(scales, sample):
resp = []
resp = np.zeros(len(sample))
X = []
X = np.zeros(2)
Y = []
Y = np.zeros(2)
i = 0
for x in sample:
y = x * scales.B[0] + X[0] * scales.B[1] + X[1] * scales.B[2] + \
Y[0] * scales.A[0] + Y[1] * scales.A[1]
X[1] = X[0]
X[0] = x
Y[1] = Y[0]
Y[0] = y
resp[i] = y
i += 1
return resp
Например, из суммы синусов с некоторым шагом, для подачи на вход фильтра:
def FillSampleByArr(sett, freqsArr):
end_time = sett.samplePoints / sett.sampleRateHz
time = np.arange(0, end_time, 1 / sett.sampleRateHz)
sinewaves = np.zeros(len(time))
n = 0
for freq in freqsArr:
sine_i = sett.sampleAmp * np.sin((2 * np.pi) * freq * time)
sinewave += sine_i
n += 1
sinewaves = sinewaves / n
sinewaves = sinewaves.astype(int)
return sinewaves, time
def FillSampleByEvenFreq(sett, freqHzFrom, freqHzTo, freqHzStep):
freqsArr = np.arange(freqHzFrom, freqHzTo, freqHzStep)
return FillSampleByArr(sett, freqsArr)
import matplotlib.pyplot as plt
sett = SampleSettings(
samplePoints = 2000,
sampleRateHz = 50000,
sampleAmp = 0x01FF
)
fltCutFreqHz = 5000
sample, time = FillSampleByEvenFreq(sett, freqFromHz = 400, freqToHz = sett.sampleRateHz / 4, freqStepHz = 200)
# Filter Select:
filterScales = HPF2_CalcScales(freqHz = fltCutFreqHz, sampleHz = sett.sampleRateHz)
#filterScales = LPF2_CalcScales(freqHz = fltCutFreqHz, sampleHz = sett.sampleRateHz)
response = FilterApplyToSample(filterScales, sample)
# FFT
samplePoints = len(sample)
freqPoints = int(samplePoints/(2 * freqAxisDiv))
# Frequency domain representation
fftSample = np.fft.fft(sample) / samplePoints # Normalize amplitude
fftSample = fftSample[range(freqPoints)] # Exclude sampling frequency
fftSample = abs(fftSample)
fftResponse = np.fft.fft(response) / samplePoints
fftResponse = fftResponse_dbg[range(freqPoints)]
fftResponse = abs(fftResponse)
# Show:
plt.figure()
plt.subplot(221)
plt.plot(time, sample)
plt.subplot(222)
plt.plot(time, response)
values = np.arange(freqPoints)
timePeriod = samplePoints / sett.sampleRateHz
axFreqs = values / timePeriod
plt.subplot(223)
plt.plot(axFreqs, fftSample)
plt.subplot(224)
plt.plot(axFreqs, fftResponse)
plt.show()