Revision 831ca406
| b/gr-utils/src/python/gr_filter_design.py | ||
|---|---|---|
| 1 | 1 |
#!/usr/bin/env python |
| 2 | 2 |
|
| 3 |
import sys, os, csv |
|
| 3 |
import sys, os, re, csv
|
|
| 4 | 4 |
from optparse import OptionParser |
| 5 | 5 |
from gnuradio import gr, blks2, eng_notation |
| 6 | 6 |
|
| ... | ... | |
| 190 | 190 |
"Rectangular Window" : gr.firdes.WIN_RECTANGULAR, |
| 191 | 191 |
"Kaiser Window" : gr.firdes.WIN_KAISER, |
| 192 | 192 |
"Blackman-harris Window" : gr.firdes.WIN_BLACKMAN_hARRIS} |
| 193 |
self.filterWindowsMap = ["Hamming Window", |
|
| 194 |
"Hann Window", |
|
| 195 |
"Blackman Window", |
|
| 196 |
"Rectangular Window", |
|
| 197 |
"Kaiser Window", |
|
| 198 |
"Blackman-harris Window"] |
|
| 193 | 199 |
|
| 194 | 200 |
self.show() |
| 195 | 201 |
|
| ... | ... | |
| 336 | 342 |
taps = gr.firdes.low_pass_2(gain, fs, pb, tb, |
| 337 | 343 |
atten, wintype) |
| 338 | 344 |
params = {"fs": fs, "gain": gain, "wintype": wintype,
|
| 339 |
"filttype": "lpf", "passband": pb, "stopband": sb,
|
|
| 340 |
"atten": atten} |
|
| 345 |
"filttype": "lpf", "pbend": pb, "sbstart": sb,
|
|
| 346 |
"atten": atten, "ntaps": len(taps)}
|
|
| 341 | 347 |
return (taps, params, ret) |
| 342 | 348 |
else: |
| 343 | 349 |
return ([], [], ret) |
| ... | ... | |
| 356 | 362 |
if(r): |
| 357 | 363 |
taps = gr.firdes.band_pass_2(gain, fs, pb1, pb2, tb, |
| 358 | 364 |
atten, wintype) |
| 359 |
return (taps,r) |
|
| 365 |
params = {"fs": fs, "gain": gain, "wintype": wintype,
|
|
| 366 |
"filttype": "bpf", "pbstart": pb1, "pbend": pb2, |
|
| 367 |
"tb": tb, "atten": atten, "ntaps": len(taps)} |
|
| 368 |
return (taps,params,r) |
|
| 360 | 369 |
else: |
| 361 |
return ([],r) |
|
| 370 |
return ([],[],r)
|
|
| 362 | 371 |
|
| 363 | 372 |
def design_win_cbpf(self, fs, gain, wintype): |
| 364 | 373 |
ret = True |
| ... | ... | |
| 374 | 383 |
if(r): |
| 375 | 384 |
taps = gr.firdes.complex_band_pass_2(gain, fs, pb1, pb2, tb, |
| 376 | 385 |
atten, wintype) |
| 377 |
return (taps,r) |
|
| 386 |
params = {"fs": fs, "gain": gain, "wintype": wintype,
|
|
| 387 |
"filttype": "cbpf", "pbstart": pb1, "pbend": pb2, |
|
| 388 |
"tb": tb, "atten": atten, "ntaps": len(taps)} |
|
| 389 |
return (taps,params,r) |
|
| 378 | 390 |
else: |
| 379 |
return ([],r) |
|
| 391 |
return ([],[],r)
|
|
| 380 | 392 |
|
| 381 | 393 |
def design_win_bnf(self, fs, gain, wintype): |
| 382 | 394 |
ret = True |
| ... | ... | |
| 392 | 404 |
if(r): |
| 393 | 405 |
taps = gr.firdes.band_reject_2(gain, fs, pb1, pb2, tb, |
| 394 | 406 |
atten, wintype) |
| 395 |
return (taps,r) |
|
| 407 |
params = {"fs": fs, "gain": gain, "wintype": wintype,
|
|
| 408 |
"filttype": "bnf", "sbstart": pb1, "sbend": pb2, |
|
| 409 |
"tb": tb, "atten": atten, "ntaps": len(taps)} |
|
| 410 |
return (taps,params,r) |
|
| 396 | 411 |
else: |
| 397 |
return ([],r) |
|
| 412 |
return ([],[],r)
|
|
| 398 | 413 |
|
| 399 | 414 |
def design_win_hpf(self, fs, gain, wintype): |
| 400 | 415 |
ret = True |
| ... | ... | |
| 409 | 424 |
tb = pb - sb |
| 410 | 425 |
taps = gr.firdes.high_pass_2(gain, fs, pb, tb, |
| 411 | 426 |
atten, wintype) |
| 412 |
return (taps,r) |
|
| 427 |
params = {"fs": fs, "gain": gain, "wintype": wintype,
|
|
| 428 |
"filttype": "hpf", "sbend": sb, "pbstart": pb, |
|
| 429 |
"atten": atten, "ntaps": len(taps)} |
|
| 430 |
return (taps,params,r) |
|
| 413 | 431 |
else: |
| 414 |
return ([],r) |
|
| 432 |
return ([],[],r)
|
|
| 415 | 433 |
|
| 416 | 434 |
def design_win_rrc(self, fs, gain, wintype): |
| 417 | 435 |
ret = True |
| ... | ... | |
| 425 | 443 |
if(r): |
| 426 | 444 |
taps = gr.firdes.root_raised_cosine(gain, fs, sr, |
| 427 | 445 |
alpha, ntaps) |
| 428 |
return (taps,r) |
|
| 446 |
params = {"fs": fs, "gain": gain, "wintype": wintype,
|
|
| 447 |
"filttype": "rrc", "srate": sr, "alpha": alpha, |
|
| 448 |
"ntaps": ntaps} |
|
| 449 |
return (taps,params,r) |
|
| 429 | 450 |
else: |
| 430 |
return ([],r) |
|
| 451 |
return ([],[],r)
|
|
| 431 | 452 |
|
| 432 | 453 |
def design_win_gaus(self, fs, gain, wintype): |
| 433 | 454 |
ret = True |
| ... | ... | |
| 441 | 462 |
if(r): |
| 442 | 463 |
spb = fs / sr |
| 443 | 464 |
taps = gr.firdes.gaussian(gain, spb, bt, ntaps) |
| 444 |
return (taps,r) |
|
| 465 |
params = {"fs": fs, "gain": gain, "wintype": wintype,
|
|
| 466 |
"filttype": "gaus", "srate": sr, "bt": bt, |
|
| 467 |
"ntaps": ntaps} |
|
| 468 |
return (taps,params,r) |
|
| 445 | 469 |
else: |
| 446 |
return ([],r) |
|
| 470 |
return ([],[],r)
|
|
| 447 | 471 |
|
| 448 | 472 |
# Design Functions for Equiripple Filters |
| 449 | 473 |
def design_opt_lpf(self, fs, gain): |
| ... | ... | |
| 672 | 696 |
params = {}
|
| 673 | 697 |
for row in csvhandle: |
| 674 | 698 |
if(row[0] != "taps"): |
| 675 |
try: # if it's not a float, its a string |
|
| 676 |
params[row[0]] = float(row[1]) |
|
| 677 |
except ValueError: |
|
| 678 |
params[row[0]] = row[1] |
|
| 699 |
testcpx = re.findall("[+-]?\d+\.*\d*[Ee]?[-+]?\d+j", row[1])
|
|
| 700 |
if(len(testcpx) > 0): # it's a complex |
|
| 701 |
params[row[0]] = complex(row[1]) |
|
| 702 |
else: # assume it's a float |
|
| 703 |
try: # if it's not a float, its a string |
|
| 704 |
params[row[0]] = float(row[1]) |
|
| 705 |
except ValueError: |
|
| 706 |
params[row[0]] = row[1] |
|
| 679 | 707 |
else: |
| 680 |
taps = [float(r) for r in row[1:]] |
|
| 708 |
testcpx = re.findall("[+-]?\d+\.*\d*[Ee]?[-+]?\d+j", row[1])
|
|
| 709 |
if(len(testcpx) > 0): # it's a complex |
|
| 710 |
taps = [complex(r) for r in row[1:]] |
|
| 711 |
else: |
|
| 712 |
taps = [float(r) for r in row[1:]] |
|
| 681 | 713 |
handle.close() |
| 682 | 714 |
self.draw_plots(taps, params) |
| 683 | 715 |
|
| 684 | 716 |
self.gui.sampleRateEdit.setText(Qt.QString("%1").arg(params["fs"]))
|
| 685 | 717 |
self.gui.filterGainEdit.setText(Qt.QString("%1").arg(params["gain"]))
|
| 686 | 718 |
|
| 687 |
#FIXME: work on setting filter type and window type dropdown boxes |
|
| 688 |
#FIXME: enable this and design for all other filt types |
|
| 719 |
# Set up GUI parameters for each filter type |
|
| 689 | 720 |
if(params["filttype"] == "lpf"): |
| 690 |
self.gui.endofLpfPassBandEdit.setText(Qt.QString("%1").arg(params["passband"]))
|
|
| 691 |
self.gui.startofLpfStopBandEdit.setText(Qt.QString("%1").arg(params["stopband"]))
|
|
| 721 |
self.gui.filterTypeComboBox.setCurrentIndex(0) |
|
| 722 |
self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) |
|
| 723 |
|
|
| 724 |
self.gui.endofLpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbend"]))
|
|
| 725 |
self.gui.startofLpfStopBandEdit.setText(Qt.QString("%1").arg(params["sbstart"]))
|
|
| 692 | 726 |
self.gui.lpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"]))
|
| 693 | 727 |
elif(params["filttype"] == "bpf"): |
| 694 |
self.gui.startofBpfPassBandEdit |
|
| 695 |
self.gui.endofBpfPassBandEdit |
|
| 696 |
self.gui.bpfTransitionEdit |
|
| 697 |
self.gui.bpfStopBandAttenEdit |
|
| 728 |
self.gui.filterTypeComboBox.setCurrentIndex(1) |
|
| 729 |
self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) |
|
| 730 |
|
|
| 731 |
self.gui.startofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbstart"]))
|
|
| 732 |
self.gui.endofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbend"]))
|
|
| 733 |
self.gui.bpfTransitionEdit.setText(Qt.QString("%1").arg(params["tb"]))
|
|
| 734 |
self.gui.bpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"]))
|
|
| 698 | 735 |
elif(params["filttype"] == "cbpf"): |
| 699 |
self.gui.startofBpfPassBandEdit |
|
| 700 |
self.gui.endofBpfPassBandEdit |
|
| 701 |
self.gui.bpfTransitionEdit |
|
| 702 |
self.gui.bpfStopBandAttenEdit |
|
| 736 |
self.gui.filterTypeComboBox.setCurrentIndex(2) |
|
| 737 |
self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) |
|
| 738 |
|
|
| 739 |
self.gui.startofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbstart"]))
|
|
| 740 |
self.gui.endofBpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbend"]))
|
|
| 741 |
self.gui.bpfTransitionEdit.setText(Qt.QString("%1").arg(params["tb"]))
|
|
| 742 |
self.gui.bpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"]))
|
|
| 703 | 743 |
elif(params["filttype"] == "bnf"): |
| 704 |
self.gui.startofBnfStopBandEdit |
|
| 705 |
self.gui.endofBnfStopBandEdit |
|
| 706 |
self.gui.bnfTransitionEdit |
|
| 707 |
self.gui.bnfStopBandAttenEdit |
|
| 744 |
self.gui.filterTypeComboBox.setCurrentIndex(3) |
|
| 745 |
self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) |
|
| 746 |
|
|
| 747 |
self.gui.startofBnfStopBandEdit.setText(Qt.QString("%1").arg(params["sbstart"]))
|
|
| 748 |
self.gui.endofBnfStopBandEdit.setText(Qt.QString("%1").arg(params["sbend"]))
|
|
| 749 |
self.gui.bnfTransitionEdit.setText(Qt.QString("%1").arg(params["tb"]))
|
|
| 750 |
self.gui.bnfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"]))
|
|
| 708 | 751 |
elif(params["filttype"] == "hpf"): |
| 709 |
self.gui.endofHpfStopBandEdit |
|
| 710 |
self.gui.startofHpfPassBandEdit |
|
| 711 |
self.gui.hpfStopBandAttenEdit |
|
| 752 |
self.gui.filterTypeComboBox.setCurrentIndex(4) |
|
| 753 |
self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) |
|
| 754 |
|
|
| 755 |
self.gui.endofHpfStopBandEdit.setText(Qt.QString("%1").arg(params["sbend"]))
|
|
| 756 |
self.gui.startofHpfPassBandEdit.setText(Qt.QString("%1").arg(params["pbstart"]))
|
|
| 757 |
self.gui.hpfStopBandAttenEdit.setText(Qt.QString("%1").arg(params["atten"]))
|
|
| 712 | 758 |
elif(params["filttype"] == "rrc"): |
| 713 |
self.gui.rrcSymbolRateEdit |
|
| 714 |
self.gui.rrcAlphaEdit |
|
| 715 |
self.gui.rrcNumTapsEdit |
|
| 716 |
elif(params["filttype"] == "gauss"): |
|
| 717 |
self.gui.gausSymbolRateEdit |
|
| 718 |
self.gui.gausBTEdit |
|
| 719 |
self.gui.gausNumTapsEdit |
|
| 759 |
self.gui.filterTypeComboBox.setCurrentIndex(5) |
|
| 760 |
self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) |
|
| 761 |
|
|
| 762 |
self.gui.rrcSymbolRateEdit.setText(Qt.QString("%1").arg(params["srate"]))
|
|
| 763 |
self.gui.rrcAlphaEdit.setText(Qt.QString("%1").arg(params["alpha"]))
|
|
| 764 |
self.gui.rrcNumTapsEdit.setText(Qt.QString("%1").arg(params["ntaps"]))
|
|
| 765 |
elif(params["filttype"] == "gaus"): |
|
| 766 |
self.gui.filterTypeComboBox.setCurrentIndex(6) |
|
| 767 |
self.gui.filterDesignTypeComboBox.setCurrentIndex(int(params["wintype"])) |
|
| 768 |
|
|
| 769 |
self.gui.gausSymbolRateEdit.setText(Qt.QString("%1").arg(params["srate"]))
|
|
| 770 |
self.gui.gausBTEdit.setText(Qt.QString("%1").arg(params["bt"]))
|
|
| 771 |
self.gui.gausNumTapsEdit.setText(Qt.QString("%1").arg(params["ntaps"]))
|
|
| 720 | 772 |
|
| 721 | 773 |
|
| 722 | 774 |
def draw_plots(self, taps, params): |
Also available in: Unified diff