summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rondeau <tom@trondeau.com>2014-04-11 11:50:03 -0400
committerTom Rondeau <tom@trondeau.com>2014-04-11 11:50:03 -0400
commitb0dce1e14c76479c995b48ad5d4002a1fe96d9d9 (patch)
tree9ed4e4a4cacda017d41202e7428a802657b77074
parentd087c4186e64bdea8c10a2ab3fad9f2474e9c818 (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.py106
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),)