diff options
author | Tom Rondeau <tom@trondeau.com> | 2014-04-11 11:50:03 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2014-04-11 11:50:03 -0400 |
commit | b0dce1e14c76479c995b48ad5d4002a1fe96d9d9 (patch) | |
tree | 9ed4e4a4cacda017d41202e7428a802657b77074 | |
parent | d087c4186e64bdea8c10a2ab3fad9f2474e9c818 (diff) |
filter: Python pfb.arb_resampler calculating better taps when rate < 1.0.
We have to change the concept of the channel bandwidth out of the resampler when the rate is < 1.0. Previously, we were getting aliasing by using the wrong bandwidth concept.
-rw-r--r-- | gr-filter/python/filter/pfb.py | 106 |
1 files changed, 72 insertions, 34 deletions
diff --git a/gr-filter/python/filter/pfb.py b/gr-filter/python/filter/pfb.py index 732812ef2a..7ba19ec299 100644 --- a/gr-filter/python/filter/pfb.py +++ b/gr-filter/python/filter/pfb.py @@ -204,24 +204,43 @@ class arb_resampler_ccf(gr.hier_block2): if (taps is not None) and (len(taps) > 0): self._taps = taps else: - # Create a filter that covers the full bandwidth of the input signal - bw = 0.4 - tb = 0.2 - ripple = 0.1 - #self._taps = filter.firdes.low_pass_2(self._size, self._size, bw, tb, atten) - made = False - while not made: - try: - self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten) - made = True - except RuntimeError: - ripple += 0.01 - made = False - print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) - - # Build in an exit strategy; if we've come this far, it ain't working. - if(ripple >= 1.0): - raise RuntimeError("optfir could not generate an appropriate filter.") + # Create a filter that covers the full bandwidth of the output signal + + # If rate >= 1, we need to prevent images in the output, + # so we have to filter it to less than half the channel + # width of 0.5. If rate < 1, we need to filter to less + # than half the output signal's bw to avoid aliasing, so + # the half-band here is 0.5*rate. + percent = 0.80 + if(self._rate < 1): + halfband = 0.5*self._rate + bw = percent*halfband + tb = (percent/2.0)*halfband + ripple = 0.1 + + # As we drop the bw factor, the optfir filter has a harder time converging; + # using the firdes method here for better results. + self._taps = filter.firdes.low_pass_2(self._size, self._size, bw, tb, atten, + filter.firdes.WIN_BLACKMAN_HARRIS) + else: + halfband = 0.5 + bw = percent*halfband + tb = (percent/2.0)*halfband + ripple = 0.1 + + made = False + while not made: + try: + self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") self.pfb = filter.pfb_arb_resampler_ccf(self._rate, self._taps, self._size) #print "PFB has %d taps\n" % (len(self._taps),) @@ -258,23 +277,42 @@ class arb_resampler_fff(gr.hier_block2): self._taps = taps else: # Create a filter that covers the full bandwidth of the input signal - bw = 0.4 - tb = 0.2 - ripple = 0.1 - #self._taps = filter.firdes.low_pass_2(self._size, self._size, bw, tb, atten) - made = False - while not made: - try: - self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten) - made = True - except RuntimeError: - ripple += 0.01 - made = False - print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) - # Build in an exit strategy; if we've come this far, it ain't working. - if(ripple >= 1.0): - raise RuntimeError("optfir could not generate an appropriate filter.") + # If rate >= 1, we need to prevent images in the output, + # so we have to filter it to less than half the channel + # width of 0.5. If rate < 1, we need to filter to less + # than half the output signal's bw to avoid aliasing, so + # the half-band here is 0.5*rate. + percent = 0.80 + if(self._rate < 1): + halfband = 0.5*self._rate + bw = percent*halfband + tb = (percent/2.0)*halfband + ripple = 0.1 + + # As we drop the bw factor, the optfir filter has a harder time converging; + # using the firdes method here for better results. + self._taps = filter.firdes.low_pass_2(self._size, self._size, bw, tb, atten, + filter.firdes.WIN_BLACKMAN_HARRIS) + else: + halfband = 0.5 + bw = percent*halfband + tb = (percent/2.0)*halfband + ripple = 0.1 + + made = False + while not made: + try: + self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") self.pfb = filter.pfb_arb_resampler_fff(self._rate, self._taps, self._size) #print "PFB has %d taps\n" % (len(self._taps),) |