summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/python
diff options
context:
space:
mode:
authorTom2010-02-01 19:21:54 -0500
committerTom2010-02-01 19:21:54 -0500
commit4640708a2cb9740c41f0e27a6ce865a85473a4a0 (patch)
treef95c41a7c24ef25c5be1b23893f06de5cb14818b /gnuradio-core/src/python
parent824aa242f143a088f04031840bc36ed54de74005 (diff)
parent3bac2fa547168ca52352892e5f9db3335724682e (diff)
downloadgnuradio-4640708a2cb9740c41f0e27a6ce865a85473a4a0.tar.gz
gnuradio-4640708a2cb9740c41f0e27a6ce865a85473a4a0.tar.bz2
gnuradio-4640708a2cb9740c41f0e27a6ce865a85473a4a0.zip
Merge branch 'fll'
Diffstat (limited to 'gnuradio-core/src/python')
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py64
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py56
2 files changed, 77 insertions, 43 deletions
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py
index cd9a207c8..e9fb3df89 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py
@@ -26,7 +26,7 @@ differential BPSK modulation and demodulation.
"""
from gnuradio import gr, gru, modulation_utils
-from math import pi, sqrt
+from math import pi, sqrt, ceil
import psk
import cmath
from pprint import pprint
@@ -38,6 +38,7 @@ _def_gray_code = True
_def_verbose = False
_def_log = False
+_def_freq_alpha = 4e-3
_def_costas_alpha = 0.1
_def_timing_alpha = 0.100
_def_timing_beta = 0.010
@@ -85,8 +86,6 @@ class dbpsk2_mod(gr.hier_block2):
if not isinstance(self._samples_per_symbol, int) or self._samples_per_symbol < 2:
raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol)
- ntaps = 11 * self._samples_per_symbol
-
arity = pow(2,self.bits_per_symbol())
# turn bytes into k-bit vectors
@@ -103,15 +102,15 @@ class dbpsk2_mod(gr.hier_block2):
self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[arity])
# pulse shaping filter
- self.rrc_taps = gr.firdes.root_raised_cosine(
- self._samples_per_symbol, # gain (samples_per_symbol since we're
- # interpolating by samples_per_symbol)
- self._samples_per_symbol, # sampling rate
- 1.0, # symbol rate
- self._excess_bw, # excess bandwidth (roll-off factor)
+ nfilts = 32
+ ntaps = nfilts * 11 * self._samples_per_symbol # make nfilts filters of ntaps each
+ self.rrc_taps = gr.firdes.root_raised_cosine(
+ nfilts, # gain
+ nfilts, # sampling rate based on 32 filters in resampler
+ 1.0, # symbol rate
+ self._excess_bw, # excess bandwidth (roll-off factor)
ntaps)
- self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol,
- self.rrc_taps)
+ self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps)
# Connect
self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc,
@@ -182,6 +181,7 @@ class dbpsk2_demod(gr.hier_block2):
def __init__(self,
samples_per_symbol=_def_samples_per_symbol,
excess_bw=_def_excess_bw,
+ freq_alpha=_def_freq_alpha,
costas_alpha=_def_costas_alpha,
timing_alpha=_def_timing_alpha,
timing_max_dev=_def_timing_max_dev,
@@ -199,9 +199,11 @@ class dbpsk2_demod(gr.hier_block2):
@type samples_per_symbol: float
@param excess_bw: Root-raised cosine filter excess bandwidth
@type excess_bw: float
- @param costas_alpha: loop filter gain
+ @param freq_alpha: loop filter gain for frequency recovery
+ @type freq_alpha: float
+ @param costas_alpha: loop filter gain for phase/fine frequency recovery
@type costas_alpha: float
- @param timing_alpha: timing loop alpha gain
+ @param timing_alpha: loop alpha gain for timing recovery
@type timing_alpha: float
@param timing_max: timing loop maximum rate deviations
@type timing_max: float
@@ -223,6 +225,8 @@ class dbpsk2_demod(gr.hier_block2):
self._samples_per_symbol = samples_per_symbol
self._excess_bw = excess_bw
+ self._freq_alpha = freq_alpha
+ self._freq_beta = 0.25*self._freq_alpha**2
self._costas_alpha = costas_alpha
self._timing_alpha = timing_alpha
self._timing_beta = _def_timing_beta
@@ -238,24 +242,32 @@ class dbpsk2_demod(gr.hier_block2):
self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
#self.agc = gr.feedforward_agc_cc(16, 1.0)
+ # Frequency correction
+ self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw,
+ 11*int(self._samples_per_symbol),
+ self._freq_alpha, self._freq_beta)
+
+ # symbol timing recovery with RRC data filter
+ nfilts = 32
+ ntaps = 11 * int(self._samples_per_symbol*nfilts)
+ taps = gr.firdes.root_raised_cosine(nfilts, nfilts,
+ 1.0/float(self._samples_per_symbol),
+ self._excess_bw, ntaps)
+ self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol,
+ self._timing_alpha,
+ taps, nfilts, nfilts/2, self._timing_max_dev)
+ self.time_recov.set_beta(self._timing_beta)
+
+ # Perform phase / fine frequency correction
self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha
# Allow a frequency swing of +/- half of the sample rate
fmin = -0.5
fmax = 0.5
- self.clock_recov = gr.costas_loop_cc(self._costas_alpha,
+ self.phase_recov = gr.costas_loop_cc(self._costas_alpha,
self._costas_beta,
fmax, fmin, arity)
- # symbol timing recovery with RRC data filter
- nfilts = 32
- ntaps = 11 * samples_per_symbol*nfilts
- taps = gr.firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(self._samples_per_symbol), self._excess_bw, ntaps)
- self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol,
- self._timing_alpha,
- taps, nfilts, nfilts/2, self._timing_max_dev)
- self.time_recov.set_beta(self._timing_beta)
-
# Do differential decoding based on phase change of symbols
self.diffdec = gr.diff_phasor_cc()
@@ -280,8 +292,7 @@ class dbpsk2_demod(gr.hier_block2):
# Connect
self.connect(self, self.agc,
- self.clock_recov,
- self.time_recov,
+ self.freq_recov, self.time_recov, self.phase_recov,
self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self)
if sync_out: self.connect(self.time_recov, (self, 1))
@@ -297,6 +308,7 @@ class dbpsk2_demod(gr.hier_block2):
print "bits per symbol: %d" % self.bits_per_symbol()
print "Gray code: %s" % self._gray_code
print "RRC roll-off factor: %.2f" % self._excess_bw
+ print "FLL gain: %.2f" % self._freq_alpha
print "Costas Loop alpha: %.2f" % self._costas_alpha
print "Costas Loop beta: %.2f" % self._costas_beta
print "Timing alpha gain: %.2f" % self._timing_alpha
@@ -333,6 +345,8 @@ class dbpsk2_demod(gr.hier_block2):
parser.add_option("", "--no-gray-code", dest="gray_code",
action="store_false", default=_def_gray_code,
help="disable gray coding on modulated bits (PSK)")
+ parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha,
+ help="set frequency lock loop alpha gain value [default=%default] (PSK)")
parser.add_option("", "--costas-alpha", type="float", default=None,
help="set Costas loop alpha value [default=%default] (PSK)")
parser.add_option("", "--gain-alpha", type="float", default=_def_timing_alpha,
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py
index fd1e9f0ef..9fae6acca 100644
--- a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py
@@ -38,6 +38,7 @@ _def_gray_code = True
_def_verbose = False
_def_log = False
+_def_freq_alpha = 4e-3
_def_costas_alpha = 0.01
_def_timing_alpha = 0.100
_def_timing_beta = 0.010
@@ -105,14 +106,15 @@ class dqpsk2_mod(gr.hier_block2):
self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const)
# pulse shaping filter
- self.rrc_taps = gr.firdes.root_raised_cosine(
- self._samples_per_symbol, # gain (sps since we're interpolating by sps)
- self._samples_per_symbol, # sampling rate
- 1.0, # symbol rate
- self._excess_bw, # excess bandwidth (roll-off factor)
+ nfilts = 32
+ ntaps = nfilts * 11 * self._samples_per_symbol # make nfilts filters of ntaps each
+ self.rrc_taps = gr.firdes.root_raised_cosine(
+ nfilts, # gain
+ nfilts, # sampling rate based on 32 filters in resampler
+ 1.0, # symbol rate
+ self._excess_bw, # excess bandwidth (roll-off factor)
ntaps)
-
- self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps)
+ self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps)
if verbose:
self._print_verbage()
@@ -182,6 +184,7 @@ class dqpsk2_demod(gr.hier_block2):
def __init__(self,
samples_per_symbol=_def_samples_per_symbol,
excess_bw=_def_excess_bw,
+ freq_alpha=_def_freq_alpha,
costas_alpha=_def_costas_alpha,
timing_alpha=_def_timing_alpha,
timing_max_dev=_def_timing_max_dev,
@@ -199,6 +202,8 @@ class dqpsk2_demod(gr.hier_block2):
@type samples_per_symbol: float
@param excess_bw: Root-raised cosine filter excess bandwidth
@type excess_bw: float
+ @param freq_alpha: loop filter gain for frequency recovery
+ @type freq_alpha: float
@param costas_alpha: loop filter gain
@type costas_alphas: float
@param timing_alpha: timing loop alpha gain
@@ -223,6 +228,8 @@ class dqpsk2_demod(gr.hier_block2):
self._samples_per_symbol = samples_per_symbol
self._excess_bw = excess_bw
+ self._freq_alpha = freq_alpha
+ self._freq_beta = 0.25*self._freq_alpha**2
self._costas_alpha = costas_alpha
self._timing_alpha = timing_alpha
self._timing_beta = _def_timing_beta
@@ -238,24 +245,35 @@ class dqpsk2_demod(gr.hier_block2):
self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
#self.agc = gr.feedforward_agc_cc(16, 2.0)
- self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha
- # Allow a frequency swing of +/- half of the sample rate
- fmin = -0.5
- fmax = 0.5
+ # Frequency correction
+ self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw,
+ 11*int(self._samples_per_symbol),
+ self._freq_alpha, self._freq_beta)
- self.clock_recov = gr.costas_loop_cc(self._costas_alpha,
- self._costas_beta,
- fmax, fmin, arity)
# symbol timing recovery with RRC data filter
nfilts = 32
- ntaps = 11 * samples_per_symbol*nfilts
- taps = gr.firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(self._samples_per_symbol), self._excess_bw, ntaps)
+ ntaps = 11 * int(samples_per_symbol*nfilts)
+ taps = gr.firdes.root_raised_cosine(nfilts, nfilts,
+ 1.0/float(self._samples_per_symbol),
+ self._excess_bw, ntaps)
self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol,
self._timing_alpha,
taps, nfilts, nfilts/2, self._timing_max_dev)
self.time_recov.set_beta(self._timing_beta)
+
+ # Perform phase / fine frequency correction
+ self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha
+ # Allow a frequency swing of +/- half of the sample rate
+ fmin = -0.5
+ fmax = 0.5
+
+ self.phase_recov = gr.costas_loop_cc(self._costas_alpha,
+ self._costas_beta,
+ fmax, fmin, arity)
+
+
# Perform Differential decoding on the constellation
self.diffdec = gr.diff_phasor_cc()
@@ -280,8 +298,7 @@ class dqpsk2_demod(gr.hier_block2):
# Connect
self.connect(self, self.agc,
- self.clock_recov,
- self.time_recov,
+ self.freq_recov, self.time_recov, self.phase_recov,
self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self)
if sync_out: self.connect(self.time_recov, (self, 1))
@@ -297,6 +314,7 @@ class dqpsk2_demod(gr.hier_block2):
print "bits per symbol: %d" % self.bits_per_symbol()
print "Gray code: %s" % self._gray_code
print "RRC roll-off factor: %.2f" % self._excess_bw
+ print "FLL gain: %.2f" % self._freq_alpha
print "Costas Loop alpha: %.2e" % self._costas_alpha
print "Costas Loop beta: %.2e" % self._costas_beta
print "Timing alpha gain: %.2f" % self._timing_alpha
@@ -333,6 +351,8 @@ class dqpsk2_demod(gr.hier_block2):
parser.add_option("", "--no-gray-code", dest="gray_code",
action="store_false", default=_def_gray_code,
help="disable gray coding on modulated bits (PSK)")
+ parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha,
+ help="set frequency lock loop alpha gain value [default=%default] (PSK)")
parser.add_option("", "--costas-alpha", type="float", default=_def_costas_alpha,
help="set Costas loop alpha value [default=%default] (PSK)")
parser.add_option("", "--gain-alpha", type="float", default=_def_timing_alpha,