"""
this is a program for designing IIR/FIR digital filters
"""
from PythonCard import clipboard,dialog,graphic,model
from PythonCard.components import radiogroup,bitmapcanvas,slider
import wx
import os
import random
import sys,time
from math import *
from pyspuc.fir_coeff import *
from pyspuc.butterworth_fir import *
from pyspuc.iir_allpass1 import iir_allpass1_double
from pyspuc.iir_allpass1_cascade import iir_allpass1_cascade_double
from pyspuc.gaussian_fir import *
from pyspuc.template_functions import *
from pyspuc.freq_functions import *
from pyspuc.create_remez_lpfir import *
from pyspuc.complex import complex_double
from pyspuc.notch_allpass import *
from pyspuc.cutboost import *
from pyspuc.iir_coeff import iir_coeff
from pyspuc.butterworth_iir import butterworth_iir
from pyspuc.chebyshev_iir import chebyshev_iir
from pyspuc.elliptic_iir import elliptic_iir
pts = 500
pi = 3.1416
w = []
for i in xrange(pts):
w.append(pi*i/float(pts))
class Filtplot(model.Background):
def on_initialize(self, event):
self.filename = None
comp = self.components
self.sliderLabels = {
'stcWeight':comp.stcWeight.text,
'stcPassband':comp.stcPassband.text,
'stctrans':comp.stctrans.text,
'stcOrder':comp.stcOrder.text,
'stcTaps':comp.stcTaps.text,
'stcBits':comp.stcBits.text,
'stcAlpha':comp.stcAlpha.text,
}
self.setSliderLabels()
self.components.bufOff.backgroundColor = 'white'
self.components.bufOff.clear()
self.doFiltplot()
t = time.localtime();
s = "Digital Filter Design Demo, built using Boost Python library\n"
s += "Copyright: Tony Kirke 2006\n"
s += "Copyright: DSP Templates Corporation 2006\n"
s += "Revision 665\n"
r = dialog.messageDialog(self,s, 'Notice')
if (r.accepted == False): sys.exit()
def doFiltplot(self):
comp = self.components
canvas = comp.bufOff
width, height = canvas.size
xOffset = width / 2
yOffset = height / 2
pass_edge = comp.sldPassband.value/2000.0
trans = pass_edge*comp.sldtrans.value/2000.0
hb_trans = comp.sldtrans.value/2000.0
delta = comp.sldtrans.value/2000.0
notch_trans = 1.0-comp.sldtrans.value/1000.0
stop_edge = pass_edge + trans
if (stop_edge > 0.42):
stop_edge = 0.42
stop_dBs = -comp.sldWeight.value/10
stop_weight = 10**(-stop_dBs/20.0)
taps = comp.sldTaps.value
self.bits = comp.sldBits.value
order = comp.sldOrder.value
ripple = stop_weight
if(ripple>1):
ripple = 1
alpha = comp.sldAlpha.value/1000.0
CF = iir_coeff(order)
MF = fir_coeff_double(taps);
use_fir = 0
use_iir = 0
comp.Coefficients.clear()
if (comp.filtType.stringSelection == 'Maxflat FIR'):
butterworth_fir(MF, pass_edge)
use_fir = 1
elif (comp.filtType.stringSelection == 'Remez FIR'):
create_remez_lpfir(MF,pass_edge,stop_edge,stop_weight)
use_fir = 1
elif (comp.filtType.stringSelection == 'Gaussian FIR'):
gaussian_fir(MF, pass_edge, 8)
use_fir = 1
elif (comp.filtType.stringSelection == 'Raised Cosine FIR'):
raised_cosine(MF, alpha, 2)
use_fir = 1
elif (comp.filtType.stringSelection == 'Root Raised Cosine FIR'):
root_raised_cosine(MF, alpha, 2)
use_fir = 1
elif (comp.filtType.stringSelection == 'Elliptic'):
elliptic_iir(CF,pass_edge,stop_edge,stop_dBs,ripple);
use_iir = 1
elif (comp.filtType.stringSelection == 'Chebyshev'):
chebyshev_iir(CF,pass_edge,ripple);
use_iir = 1
elif (comp.filtType.stringSelection == 'Notch IIR'):
NF = notch_allpass_double(pass_edge,notch_trans)
z = self.other_freq(NF)
elif (comp.filtType.stringSelection == 'Cut Boost'):
BF = cutboost_double(pass_edge,notch_trans,stop_weight)
z = self.other_freq(BF)
elif (comp.filtType.stringSelection == 'Halfband IIR'):
AF = iir_allpass1_cascade_double(pass_edge,order,self.bits)
z = self.other_freq(AF)
s0 = "A0 = "
s1 = "A1 = "
for i in xrange(order):
if (AF.get_a0(i) > 0.0001):
s0 += str(AF.get_a0(i)) + " "
if (AF.get_a1(i) > 0.0001):
s1 += str(AF.get_a1(i)) + " "
comp.Coefficients.setInsertionPoint(0)
comp.Coefficients.appendText(s0)
comp.Coefficients.appendText("\n"+s1)
else:
butterworth_iir(CF,pass_edge,3.0);
use_iir = 1
if use_fir:
z = self.filt_freq(MF)
s0 = "Coefficients = "
for i in xrange(taps):
if (i==taps-1):
s0 += str(MF.gettap(i))
else:
s0 += str(MF.gettap(i)) + ", "
comp.Coefficients.clear()
comp.Coefficients.appendText(s0)
if use_iir:
z = self.filt_freq(CF)
s0 = "Coefficients in second order sections\n"
s0 += "B = "
for i in xrange(order/2):
s0 += "1.0,"
s0 += str(CF.get_coeff_b(2*i)) + ","
s0 += str(CF.get_coeff_b(2*i+1)) + "/"
s0 += "\n"
s0 += "A = "
for i in xrange(order/2):
s0 += "1.0,"
s0 += str(CF.get_coeff_a(2*i)) + ","
s0 += str(CF.get_coeff_a(2*i+1)) + "/"
comp.Coefficients.clear()
comp.Coefficients.appendText(s0)
color = 'red'
canvas.foregroundColor = color
canvas.autoRefresh = 0
canvas.clear()
lastX = 0
lastY = yOffset
self.keepDrawing = 1
points = []
grid = []
for i in xrange(10):
y_grid = i*height/10
grid.append((0, y_grid, width, y_grid))
grid.append((0, height-1, width, height-1))
for i in xrange(10):
x_grid = i*width/10
grid.append((x_grid, 0, x_grid, height))
grid.append((width-1, 0, width-1, height))
canvas.drawLineList(grid)
canvas.foregroundColor = 'blue'
for i in xrange(pts):
x = i
y = 0.2*yOffset - 0.01*height*z[i]
points.append((lastX, lastY, x, y))
lastX = x
lastY = y
canvas.drawLineList(points)
canvas.autoRefresh = 1
canvas.refresh()
def on_select(self, event):
name = event.target.name
if name.startswith('sld'):
labelName = 'stc' + name[3:]
self.components[labelName].text = self.sliderLabels[labelName] + \
' ' + str(event.target.value)
self.doFiltplot()
def setSliderLabels(self):
comp = self.components
for key in self.sliderLabels:
sliderName = 'sld' + key[3:]
comp[key].text = self.sliderLabels[key] + ' ' + str(comp[sliderName].value)
def on_editClear_command(self, event):
self.components.bufOff.clear()
def to_complex(self,cp):
return(complex(cp.re,cp.im))
def filt_freq(self,FIR):
z = []
FIR.quantize(self.bits)
h0 = FIR.freqz_mag(0)
if (h0 < 0.01): h0 = 1.0
for i in xrange(pts):
h = FIR.freqz_mag(w[i])
t = h/h0
if (t == 0): t = 0.00001
tl = 20*log10(t)
z.append(tl)
return z
def other_freq(self,AP):
imp = 1
dsum = 0
d = []
h = []
for i in xrange(pts):
d.append(AP.clock(imp))
dsum = dsum+d[i]
imp = 0
dsum = 1.0/dsum
for k in xrange(pts):
sum = 0
z = complex(1.0,0.0)
z_inc = complex(cos(w[k]),sin(w[k]))
for i in xrange(pts):
sum = sum + z*d[i]*dsum
z = z*z_inc
h.append(20*log10(abs(sum)))
return h
if __name__ == '__main__':
app = model.Application(Filtplot)
app.MainLoop()