summaryrefslogtreecommitdiff
path: root/gr-analog/python
diff options
context:
space:
mode:
authorJosh Morman <jmorman@gnuradio.org>2021-11-24 12:01:00 -0500
committermormj <34754695+mormj@users.noreply.github.com>2021-11-24 14:41:53 -0500
commit2ede969ec5f3f6d361814403b7375db5f15ec14d (patch)
treed963e92732842ee3491da1282dfa09400342c96d /gr-analog/python
parentc6f291d57d913708a2517de3c6902425c2c575d3 (diff)
analog: pep8 formatting
Signed-off-by: Josh Morman <jmorman@gnuradio.org>
Diffstat (limited to 'gr-analog/python')
-rw-r--r--gr-analog/python/analog/am_demod.py13
-rw-r--r--gr-analog/python/analog/fm_demod.py8
-rw-r--r--gr-analog/python/analog/fm_emph.py124
-rw-r--r--gr-analog/python/analog/nbfm_rx.py14
-rw-r--r--gr-analog/python/analog/nbfm_tx.py25
-rw-r--r--gr-analog/python/analog/qa_agc.py2
-rw-r--r--gr-analog/python/analog/standard_squelch.py50
-rw-r--r--gr-analog/python/analog/wfm_rcv.py13
-rw-r--r--gr-analog/python/analog/wfm_rcv_fmdet.py110
-rw-r--r--gr-analog/python/analog/wfm_rcv_pll.py78
-rw-r--r--gr-analog/python/analog/wfm_tx.py17
11 files changed, 260 insertions, 194 deletions
diff --git a/gr-analog/python/analog/am_demod.py b/gr-analog/python/analog/am_demod.py
index a3c2a8e9de..34b7ddaf74 100644
--- a/gr-analog/python/analog/am_demod.py
+++ b/gr-analog/python/analog/am_demod.py
@@ -11,6 +11,7 @@ from gnuradio import gr
from gnuradio import blocks
from gnuradio import filter
+
class am_demod_cf(gr.hier_block2):
"""
Generalized AM demodulation block with audio filtering.
@@ -26,16 +27,18 @@ class am_demod_cf(gr.hier_block2):
audio_pass: audio low pass filter passband frequency (float)
audio_stop: audio low pass filter stop frequency (float)
"""
+
def __init__(self, channel_rate, audio_decim, audio_pass, audio_stop):
gr.hier_block2.__init__(self, "am_demod_cf",
- gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
gr.io_signature(1, 1, gr.sizeof_float)) # Input signature
MAG = blocks.complex_to_mag()
DCR = blocks.add_const_ff(-1.0)
audio_taps = filter.optfir.low_pass(0.5, # Filter gain
- channel_rate, # Sample rate
+ channel_rate, # Sample rate
audio_pass, # Audio passband
audio_stop, # Audio stopband
0.1, # Passband ripple
@@ -44,6 +47,7 @@ class am_demod_cf(gr.hier_block2):
self.connect(self, MAG, DCR, LPF, self)
+
class demod_10k0a3e_cf(am_demod_cf):
"""
AM demodulation block, 10 KHz channel.
@@ -55,7 +59,8 @@ class demod_10k0a3e_cf(am_demod_cf):
channel_rate: incoming sample rate of the AM baseband (integer)
audio_decim: input to output decimation rate (integer)
"""
+
def __init__(self, channel_rate, audio_decim):
am_demod_cf.__init__(self, channel_rate, audio_decim,
- 5000, # Audio passband
- 5500) # Audio stopband
+ 5000, # Audio passband
+ 5500) # Audio stopband
diff --git a/gr-analog/python/analog/fm_demod.py b/gr-analog/python/analog/fm_demod.py
index 96fed682ff..e829871df8 100644
--- a/gr-analog/python/analog/fm_demod.py
+++ b/gr-analog/python/analog/fm_demod.py
@@ -34,13 +34,15 @@ class fm_demod_cf(gr.hier_block2):
gain: gain applied to audio output (default = 1.0) (float)
tau: deemphasis time constant (default = 75e-6), specify tau=0.0 to prevent deemphasis (float)
"""
+
def __init__(self, channel_rate, audio_decim, deviation,
audio_pass, audio_stop, gain=1.0, tau=75e-6):
gr.hier_block2.__init__(self, "fm_demod_cf",
- gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
- k = channel_rate / (2*pi*deviation)
+ k = channel_rate / (2 * pi * deviation)
QUAD = analog.quadrature_demod_cf(k)
audio_taps = filter.optfir.low_pass(
@@ -72,6 +74,7 @@ class demod_20k0f3e_cf(fm_demod_cf):
sample_rate: incoming sample rate of the FM baseband (integer)
audio_decim: input to output decimation rate (integer)
"""
+
def __init__(self, channel_rate, audio_decim):
fm_demod_cf.__init__(self, channel_rate, audio_decim,
5000, # Deviation
@@ -91,6 +94,7 @@ class demod_200kf3e_cf(fm_demod_cf):
sample_rate: incoming sample rate of the FM baseband (integer)
audio_decim: input to output decimation rate (integer)
"""
+
def __init__(self, channel_rate, audio_decim):
fm_demod_cf.__init__(self, channel_rate, audio_decim,
75000, # Deviation
diff --git a/gr-analog/python/analog/fm_emph.py b/gr-analog/python/analog/fm_emph.py
index 9c1107bb14..a581bdf2ac 100644
--- a/gr-analog/python/analog/fm_emph.py
+++ b/gr-analog/python/analog/fm_emph.py
@@ -16,22 +16,22 @@ import cmath
class fm_deemph(gr.hier_block2):
r"""
FM Deemphasis IIR filter
-
+
Args:
fs: sampling frequency in Hz (float)
tau: Time constant in seconds (75us in US, 50us in EUR) (float)
-
+
An analog deemphasis filter:
-
+
R
o------/\/\/\/---+----o
|
= C
|
---
-
+
Has this transfer function:
-
+
1 1
---- ---
RC tau
@@ -39,39 +39,39 @@ class fm_deemph(gr.hier_block2):
1 1
s + ---- s + ---
RC tau
-
+
And has its -3 dB response, due to the pole, at
-
+
|H(j w_c)|^2 = 1/2 => s = j w_c = j (1/(RC))
-
+
Historically, this corner frequency of analog audio deemphasis filters
been specified by the RC time constant used, called tau.
So w_c = 1/tau.
-
+
FWIW, for standard tau values, some standard analog components would be:
tau = 75 us = (50K)(1.5 nF) = (50 ohms)(1.5 uF)
tau = 50 us = (50K)(1.0 nF) = (50 ohms)(1.0 uF)
-
+
In specifying tau for this digital deemphasis filter, tau specifies
the *digital* corner frequency, w_c, desired.
-
+
The digital deemphasis filter design below, uses the
"bilinear transformation" method of designing digital filters:
-
+
1. Convert digital specifications into the analog domain, by prewarping
digital frequency specifications into analog frequencies.
-
+
w_a = (2/T)tan(wT/2)
-
+
2. Use an analog filter design technique to design the filter.
-
+
3. Use the bilinear transformation to convert the analog filter design to a
digital filter design.
-
+
H(z) = H(s)|
s = (2/T)(1-z^-1)/(1+z^-1)
-
-
+
+
w_ca 1 1 - (-1) z^-1
H(z) = ---- * ----------- * -----------------------
2 fs -w_ca -w_ca
@@ -81,20 +81,21 @@ class fm_deemph(gr.hier_block2):
-w_ca
1 - -----
2 fs
-
+
We use this design technique, because it is an easy way to obtain a filter
design with the -6 dB/octave roll-off required of the deemphasis filter.
-
+
Jackson, Leland B., _Digital_Filters_and_Signal_Processing_Second_Edition_,
Kluwer Academic Publishers, 1989, pp 201-212
-
+
Orfanidis, Sophocles J., _Introduction_to_Signal_Processing_, Prentice Hall,
1996, pp 573-583
"""
def __init__(self, fs, tau=75e-6):
gr.hier_block2.__init__(self, "fm_deemph",
- gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float),
gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
# Digital corner frequency
@@ -111,8 +112,8 @@ class fm_deemph(gr.hier_block2):
p1 = (1.0 + k) / (1.0 - k)
b0 = -k / (1.0 - k)
- btaps = [ b0 * 1.0, b0 * -z1 ]
- ataps = [ 1.0, -p1 ]
+ btaps = [b0 * 1.0, b0 * -z1]
+ ataps = [1.0, -p1]
# Since H(s = 0) = 1.0, then H(z = 1) = 1.0 and has 0 dB gain at DC
@@ -120,18 +121,17 @@ class fm_deemph(gr.hier_block2):
self.connect(self, deemph, self)
-
class fm_preemph(gr.hier_block2):
r"""
FM Preemphasis IIR filter.
-
+
Args:
fs: sampling frequency in Hz (float)
tau: Time constant in seconds (75us in US, 50us in EUR) (float)
- fh: High frequency at which to flatten out (< 0 means default of 0.925*fs/2.0) (float)
-
+ fh: High frequency at which to flatten out (< 0 means default of 0.925*fs/2.0) (float)
+
An analog preemphasis filter, that flattens out again at the high end:
-
+
C
+-----||------+
| |
@@ -144,12 +144,12 @@ class fm_preemph(gr.hier_block2):
\
|
o--------------------------+--------o
-
+
(This fine ASCII rendition is based on Figure 5-15
in "Digital and Analog Communication Systems", Leon W. Couch II)
-
+
Has this transfer function:
-
+
1
s + ---
R1C
@@ -157,58 +157,58 @@ class fm_preemph(gr.hier_block2):
1 R1
s + --- (1 + --)
R1C R2
-
-
+
+
It has a corner due to the numerator, where the rise starts, at
-
+
|Hn(j w_cl)|^2 = 2*|Hn(0)|^2 => s = j w_cl = j (1/(R1C))
-
+
It has a corner due to the denominator, where it levels off again, at
-
+
|Hn(j w_ch)|^2 = 1/2*|Hd(0)|^2 => s = j w_ch = j (1/(R1C) * (1 + R1/R2))
-
+
Historically, the corner frequency of analog audio preemphasis filters
been specified by the R1C time constant used, called tau.
-
+
So
w_cl = 1/tau = 1/R1C; f_cl = 1/(2*pi*tau) = 1/(2*pi*R1*C)
w_ch = 1/tau2 = (1+R1/R2)/R1C; f_ch = 1/(2*pi*tau2) = (1+R1/R2)/(2*pi*R1*C)
-
+
and note f_ch = f_cl * (1 + R1/R2).
-
+
For broadcast FM audio, tau is 75us in the United States and 50us in Europe.
f_ch should be higher than our digital audio bandwidth.
-
+
The Bode plot looks like this:
-
-
+
+
/----------------
/
/ <-- slope = 20dB/decade
/
-------------/
f_cl f_ch
-
+
In specifying tau for this digital preemphasis filter, tau specifies
the *digital* corner frequency, w_cl, desired.
-
+
The digital preemphasis filter design below, uses the
"bilinear transformation" method of designing digital filters:
-
+
1. Convert digital specifications into the analog domain, by prewarping
digital frequency specifications into analog frequencies.
-
+
w_a = (2/T)tan(wT/2)
-
+
2. Use an analog filter design technique to design the filter.
-
+
3. Use the bilinear transformation to convert the analog filter design to a
digital filter design.
-
+
H(z) = H(s)|
s = (2/T)(1-z^-1)/(1+z^-1)
-
-
+
+
-w_cla
1 + ------
2 fs
@@ -224,19 +224,21 @@ class fm_preemph(gr.hier_block2):
-w_cha
1 - ------
2 fs
-
+
We use this design technique, because it is an easy way to obtain a filter
design with the 6 dB/octave rise required of the premphasis filter.
-
+
Jackson, Leland B., _Digital_Filters_and_Signal_Processing_Second_Edition_,
Kluwer Academic Publishers, 1989, pp 201-212
-
+
Orfanidis, Sophocles J., _Introduction_to_Signal_Processing_, Prentice Hall,
1996, pp 573-583
"""
+
def __init__(self, fs, tau=75e-6, fh=-1.0):
gr.hier_block2.__init__(self, "fm_preemph",
- gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float),
gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
# Set fh to something sensible, if needed.
@@ -244,7 +246,7 @@ class fm_preemph(gr.hier_block2):
# at z = -1.0 or z = 1.0 respectively. That makes the filter unstable
# and useless.
if fh <= 0.0 or fh >= fs / 2.0:
- fh = 0.925 * fs/2.0
+ fh = 0.925 * fs / 2.0
# Digital corner frequencies
w_cl = 1.0 / tau
@@ -268,11 +270,11 @@ class fm_preemph(gr.hier_block2):
# That isn't what users are going to expect, so adjust with a
# gain, g, so that H(z = 1) = 1.0 for 0 dB gain at DC.
w_0dB = 2.0 * math.pi * 0.0
- g = abs(1.0 - p1 * cmath.rect(1.0, -w_0dB)) \
+ g = abs(1.0 - p1 * cmath.rect(1.0, -w_0dB)) \
/ (b0 * abs(1.0 - z1 * cmath.rect(1.0, -w_0dB)))
- btaps = [ g * b0 * 1.0, g * b0 * -z1 ]
- ataps = [ 1.0, -p1 ]
+ btaps = [g * b0 * 1.0, g * b0 * -z1]
+ ataps = [1.0, -p1]
preemph = filter.iir_filter_ffd(btaps, ataps, False)
self.connect(self, preemph, self)
diff --git a/gr-analog/python/analog/nbfm_rx.py b/gr-analog/python/analog/nbfm_rx.py
index 72b2dcc936..232c8ab725 100644
--- a/gr-analog/python/analog/nbfm_rx.py
+++ b/gr-analog/python/analog/nbfm_rx.py
@@ -38,9 +38,11 @@ class nbfm_rx(gr.hier_block2):
deemph
audio_filter
"""
+
def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=5e3):
gr.hier_block2.__init__(self, "nbfm_rx",
- gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
# FIXME audio_rate and quad_rate ought to be exact rationals
@@ -48,13 +50,14 @@ class nbfm_rx(gr.hier_block2):
self._quad_rate = quad_rate = int(quad_rate)
if quad_rate % audio_rate != 0:
- raise ValueError("quad_rate is not an integer multiple of audio_rate")
+ raise ValueError(
+ "quad_rate is not an integer multiple of audio_rate")
squelch_threshold = 20 # dB
#self.squelch = analog.simple_squelch_cc(squelch_threshold, 0.001)
# FM Demodulator input: complex; output: float
- k = quad_rate / (2*math.pi*max_dev)
+ k = quad_rate / (2 * math.pi * max_dev)
self.quad_demod = analog.quadrature_demod_cf(k)
# FM Deemphasis IIR filter
@@ -74,8 +77,9 @@ class nbfm_rx(gr.hier_block2):
# input: float; output: float; taps: float
self.audio_filter = filter.fir_filter_fff(audio_decim, audio_taps)
- self.connect(self, self.quad_demod, self.deemph, self.audio_filter, self)
+ self.connect(self, self.quad_demod, self.deemph,
+ self.audio_filter, self)
def set_max_deviation(self, max_dev):
- k = self._quad_rate / (2*math.pi*max_dev)
+ k = self._quad_rate / (2 * math.pi * max_dev)
self.quad_demod.set_gain(k)
diff --git a/gr-analog/python/analog/nbfm_tx.py b/gr-analog/python/analog/nbfm_tx.py
index df7c6c6a58..653fb2c5dc 100644
--- a/gr-analog/python/analog/nbfm_tx.py
+++ b/gr-analog/python/analog/nbfm_tx.py
@@ -32,23 +32,26 @@ class nbfm_tx(gr.hier_block2):
quad_rate must be an integer multiple of audio_rate.
"""
+
def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=5e3, fh=-1.0):
gr.hier_block2.__init__(self, "nbfm_tx",
- gr.io_signature(1, 1, gr.sizeof_float), # Input signature
- gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
# FIXME audio_rate and quad_rate ought to be exact rationals
self._audio_rate = audio_rate = int(audio_rate)
self._quad_rate = quad_rate = int(quad_rate)
if quad_rate % audio_rate != 0:
- raise ValueError("quad_rate is not an integer multiple of audio_rate")
-
+ raise ValueError(
+ "quad_rate is not an integer multiple of audio_rate")
do_interp = audio_rate != quad_rate
if do_interp:
- interp_factor = int(quad_rate / audio_rate) # force integer
+ # force integer
+ interp_factor = int(quad_rate / audio_rate)
interp_taps = filter.optfir.low_pass(interp_factor, # gain
quad_rate, # Fs
4500, # passband cutoff
@@ -57,7 +60,8 @@ class nbfm_tx(gr.hier_block2):
40) # stopband atten dB
#print("len(interp_taps) =", len(interp_taps))
- self.interpolator = filter.interp_fir_filter_fff (interp_factor, interp_taps)
+ self.interpolator = filter.interp_fir_filter_fff(
+ interp_factor, interp_taps)
self.preemph = fm_preemph(quad_rate, tau=tau, fh=fh)
@@ -65,7 +69,8 @@ class nbfm_tx(gr.hier_block2):
self.modulator = analog.frequency_modulator_fc(k)
if do_interp:
- self.connect(self, self.interpolator, self.preemph, self.modulator, self)
+ self.connect(self, self.interpolator,
+ self.preemph, self.modulator, self)
else:
self.connect(self, self.preemph, self.modulator, self)
@@ -74,12 +79,12 @@ class nbfm_tx(gr.hier_block2):
self.modulator.set_sensitivity(k)
-
class ctcss_gen_f(gr.hier_block2):
def __init__(self, sample_rate, tone_freq):
gr.hier_block2.__init__(self, "ctcss_gen_f",
- gr.io_signature(0, 0, 0), # Input signature
- gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+ # Input signature
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
self.plgen = analog.sig_source_f(sample_rate, analog.GR_SIN_WAVE,
tone_freq, 0.1, 0.0)
diff --git a/gr-analog/python/analog/qa_agc.py b/gr-analog/python/analog/qa_agc.py
index 9368dd5d2a..b6d1f8957b 100644
--- a/gr-analog/python/analog/qa_agc.py
+++ b/gr-analog/python/analog/qa_agc.py
@@ -369,7 +369,7 @@ class test_agc(gr_unittest.TestCase):
tb = self.tb
expected_result = \
- ((100+0j),
+ ((100 + 0j),
(0.8090173602104187 + 0.5877856016159058j),
(0.3090175688266754 + 0.9510582685470581j),
(-0.309017539024353 + 0.9510582089424133j),
diff --git a/gr-analog/python/analog/standard_squelch.py b/gr-analog/python/analog/standard_squelch.py
index 49c4b589b7..e70efce700 100644
--- a/gr-analog/python/analog/standard_squelch.py
+++ b/gr-analog/python/analog/standard_squelch.py
@@ -12,26 +12,33 @@ from gnuradio import gr
from gnuradio import blocks
from gnuradio import filter
+
class standard_squelch(gr.hier_block2):
def __init__(self, audio_rate):
gr.hier_block2.__init__(self, "standard_squelch",
- gr.io_signature(1, 1, gr.sizeof_float), # Input signature
- gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
self.input_node = blocks.add_const_ff(0) # FIXME kludge
- self.low_iir = filter.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615))
+ self.low_iir = filter.iir_filter_ffd(
+ (0.0193, 0, -0.0193), (1, 1.9524, -0.9615))
self.low_square = blocks.multiply_ff()
- self.low_smooth = filter.single_pole_iir_filter_ff(1 / (0.01*audio_rate)) # 100ms time constant
+ self.low_smooth = filter.single_pole_iir_filter_ff(
+ 1 / (0.01 * audio_rate)) # 100ms time constant
- self.hi_iir = filter.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615))
+ self.hi_iir = filter.iir_filter_ffd(
+ (0.0193, 0, -0.0193), (1, 1.3597, -0.9615))
self.hi_square = blocks.multiply_ff()
- self.hi_smooth = filter.single_pole_iir_filter_ff(1 / (0.01*audio_rate))
+ self.hi_smooth = filter.single_pole_iir_filter_ff(
+ 1 / (0.01 * audio_rate))
- self.sub = blocks.sub_ff();
- self.add = blocks.add_ff();
- self.gate = blocks.threshold_ff(0.3,0.43,0)
- self.squelch_lpf = filter.single_pole_iir_filter_ff(1 / (0.01*audio_rate))
+ self.sub = blocks.sub_ff()
+ self.add = blocks.add_ff()
+ self.gate = blocks.threshold_ff(0.3, 0.43, 0)
+ self.squelch_lpf = filter.single_pole_iir_filter_ff(
+ 1 / (0.01 * audio_rate))
self.div = blocks.divide_ff()
self.squelch_mult = blocks.multiply_ff()
@@ -39,21 +46,22 @@ class standard_squelch(gr.hier_block2):
self.connect(self, self.input_node)
self.connect(self.input_node, (self.squelch_mult, 0))
- self.connect(self.input_node,self.low_iir)
- self.connect(self.low_iir,(self.low_square,0))
- self.connect(self.low_iir,(self.low_square,1))
- self.connect(self.low_square,self.low_smooth,(self.sub,0))
- self.connect(self.low_smooth, (self.add,0))
+ self.connect(self.input_node, self.low_iir)
+ self.connect(self.low_iir, (self.low_square, 0))
+ self.connect(self.low_iir, (self.low_square, 1))
+ self.connect(self.low_square, self.low_smooth, (self.sub, 0))
+ self.connect(self.low_smooth, (self.add, 0))
- self.connect(self.input_node,self.hi_iir)
- self.connect(self.hi_iir,(self.hi_square,0))
- self.connect(self.hi_iir,(self.hi_square,1))
- self.connect(self.hi_square,self.hi_smooth,(self.sub,1))
- self.connect(self.hi_smooth, (self.add,1))
+ self.connect(self.input_node, self.hi_iir)
+ self.connect(self.hi_iir, (self.hi_square, 0))
+ self.connect(self.hi_iir, (self.hi_square, 1))
+ self.connect(self.hi_square, self.hi_smooth, (self.sub, 1))
+ self.connect(self.hi_smooth, (self.add, 1))
self.connect(self.sub, (self.div, 0))
self.connect(self.add, (self.div, 1))
- self.connect(self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1))
+ self.connect(self.div, self.gate, self.squelch_lpf,
+ (self.squelch_mult, 1))
self.connect(self.squelch_mult, self)
def set_threshold(self, threshold):
diff --git a/gr-analog/python/analog/wfm_rcv.py b/gr-analog/python/analog/wfm_rcv.py
index 34ba9787db..d6e81ea7cd 100644
--- a/gr-analog/python/analog/wfm_rcv.py
+++ b/gr-analog/python/analog/wfm_rcv.py
@@ -17,7 +17,7 @@ from .fm_emph import fm_deemph
class wfm_rcv(gr.hier_block2):
- def __init__ (self, quad_rate, audio_decimation):
+ def __init__(self, quad_rate, audio_decimation):
"""
Hierarchical block for demodulating a broadcast FM signal.
@@ -29,7 +29,8 @@ class wfm_rcv(gr.hier_block2):
audio_decimation: how much to decimate quad_rate to get to audio. (integer)
"""
gr.hier_block2.__init__(self, "wfm_rcv",
- gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
if audio_decimation != int(audio_decimation):
raise ValueError("audio_decimation needs to be an integer")
@@ -38,10 +39,9 @@ class wfm_rcv(gr.hier_block2):
volume = 20.
max_dev = 75e3
- fm_demod_gain = quad_rate / (2*math.pi*max_dev)
+ fm_demod_gain = quad_rate / (2 * math.pi * max_dev)
audio_rate = quad_rate / audio_decimation
-
# We assign to self so that outsiders can grab the demodulator
# if they need to. E.g., to plot its output.
#
@@ -59,6 +59,7 @@ class wfm_rcv(gr.hier_block2):
width_of_transition_band,
fft.window.WIN_HAMMING)
# input: float; output: float
- self.audio_filter = filter.fir_filter_fff(audio_decimation, audio_coeffs)
+ self.audio_filter = filter.fir_filter_fff(
+ audio_decimation, audio_coeffs)
- self.connect (self, self.fm_demod, self.audio_filter, self.deemph, self)
+ self.connect(self, self.fm_demod, self.audio_filter, self.deemph, self)
diff --git a/gr-analog/python/analog/wfm_rcv_fmdet.py b/gr-analog/python/analog/wfm_rcv_fmdet.py
index 3b587cc44c..d9289aa333 100644
--- a/gr-analog/python/analog/wfm_rcv_fmdet.py
+++ b/gr-analog/python/analog/wfm_rcv_fmdet.py
@@ -19,7 +19,7 @@ from .fm_emph import fm_deemph
class wfm_rcv_fmdet(gr.hier_block2):
- def __init__ (self, demod_rate, audio_decimation):
+ def __init__(self, demod_rate, audio_decimation):
"""
Hierarchical block for demodulating a broadcast FM signal.
@@ -32,9 +32,10 @@ class wfm_rcv_fmdet(gr.hier_block2):
audio_decimation: how much to decimate demod_rate to get to audio. (integer)
"""
gr.hier_block2.__init__(self, "wfm_rcv_fmdet",
- gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
gr.io_signature(2, 2, gr.sizeof_float)) # Output signature
-
+
if audio_decimation != int(audio_decimation):
raise ValueError("audio_decimation needs to be an integer")
audio_decimation = int(audio_decimation)
@@ -51,26 +52,27 @@ class wfm_rcv_fmdet(gr.hier_block2):
self.fm_demod = analog.fmdet_cf(demod_rate, lowfreq, highfreq, 0.05)
# input: float; output: float
- self.deemph_Left = fm_deemph(audio_rate)
+ self.deemph_Left = fm_deemph(audio_rate)
self.deemph_Right = fm_deemph(audio_rate)
# compute FIR filter taps for audio filter
width_of_transition_band = audio_rate / 32
- audio_coeffs = filter.firdes.low_pass(1.0 , # gain
+ audio_coeffs = filter.firdes.low_pass(1.0, # gain
demod_rate, # sampling rate
- 15000 ,
+ 15000,
width_of_transition_band,
fft.window.WIN_HAMMING)
# input: float; output: float
- self.audio_filter = filter.fir_filter_fff(audio_decimation, audio_coeffs)
+ self.audio_filter = filter.fir_filter_fff(
+ audio_decimation, audio_coeffs)
if 1:
# Pick off the stereo carrier/2 with this filter. It
# attenuated 10 dB so apply 10 dB gain We pick off the
# negative frequency half because we want to base band by
# it!
- ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO
- ## DEEMPHASIS
+ # NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO
+ # DEEMPHASIS
stereo_carrier_filter_coeffs = \
filter.firdes.complex_band_pass(10.0,
@@ -80,9 +82,9 @@ class wfm_rcv_fmdet(gr.hier_block2):
width_of_transition_band,
fft.window.WIN_HAMMING)
- #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs)
- #print "stereo carrier filter ", stereo_carrier_filter_coeffs
- #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate
+ # print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs)
+ # print "stereo carrier filter ", stereo_carrier_filter_coeffs
+ # print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate
# Pick off the double side band suppressed carrier
# Left-Right audio. It is attenuated 10 dB so apply 10 dB
@@ -91,12 +93,12 @@ class wfm_rcv_fmdet(gr.hier_block2):
stereo_dsbsc_filter_coeffs = \
filter.firdes.complex_band_pass(20.0,
demod_rate,
- 38000-15000 / 2,
- 38000+15000 / 2,
+ 38000 - 15000 / 2,
+ 38000 + 15000 / 2,
width_of_transition_band,
fft.window.WIN_HAMMING)
- #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
- #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
+ # print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
+ # print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
# construct overlap add filter system from coefficients
# for stereo carrier
@@ -106,7 +108,7 @@ class wfm_rcv_fmdet(gr.hier_block2):
# carrier is twice the picked off carrier so arrange to do
# a complex multiply
- self.stereo_carrier_generator = blocks.multiply_cc();
+ self.stereo_carrier_generator = blocks.multiply_cc()
# Pick off the rds signal
stereo_rds_filter_coeffs = \
@@ -116,90 +118,96 @@ class wfm_rcv_fmdet(gr.hier_block2):
57000 + 1500,
width_of_transition_band,
fft.window.WIN_HAMMING)
- #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
- #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
+ # print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
+ # print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
# construct overlap add filter system from coefficients for stereo carrier
self.rds_signal_filter = \
filter.fir_filter_fcc(audio_decimation,
stereo_rds_filter_coeffs)
- self.rds_carrier_generator = blocks.multiply_cc();
- self.rds_signal_generator = blocks.multiply_cc();
- self_rds_signal_processor = blocks.null_sink(gr.sizeof_gr_complex);
+ self.rds_carrier_generator = blocks.multiply_cc()
+ self.rds_signal_generator = blocks.multiply_cc()
+ self_rds_signal_processor = blocks.null_sink(gr.sizeof_gr_complex)
- loop_bw = 2*math.pi/100.0
- max_freq = -2.0*math.pi*18990/audio_rate;
- min_freq = -2.0*math.pi*19010/audio_rate;
+ loop_bw = 2 * math.pi / 100.0
+ max_freq = -2.0 * math.pi * 18990 / audio_rate
+ min_freq = -2.0 * math.pi * 19010 / audio_rate
self.stereo_carrier_pll_recovery = analog.pll_refout_cc(loop_bw,
max_freq,
- min_freq);
+ min_freq)
- #self.stereo_carrier_pll_recovery.squelch_enable(False)
- ##pll_refout does not have squelch yet, so disabled for
- #now
+ # self.stereo_carrier_pll_recovery.squelch_enable(False)
+ # pll_refout does not have squelch yet, so disabled for
+ # now
# set up mixer (multiplier) to get the L-R signal at
# baseband
- self.stereo_basebander = blocks.multiply_cc();
+ self.stereo_basebander = blocks.multiply_cc()
# pick off the real component of the basebanded L-R
# signal. The imaginary SHOULD be zero
- self.LmR_real = blocks.complex_to_real();
- self.Make_Left = blocks.add_ff();
- self.Make_Right = blocks.sub_ff();
+ self.LmR_real = blocks.complex_to_real()
+ self.Make_Left = blocks.add_ff()
+ self.Make_Right = blocks.sub_ff()
self.stereo_dsbsc_filter = \
filter.fir_filter_fcc(audio_decimation,
stereo_dsbsc_filter_coeffs)
-
if 1:
# send the real signal to complex filter to pick off the
# carrier and then to one side of a multiplier
self.connect(self, self.fm_demod, self.stereo_carrier_filter,
self.stereo_carrier_pll_recovery,
- (self.stereo_carrier_generator,0))
+ (self.stereo_carrier_generator, 0))
# send the already filtered carrier to the otherside of the carrier
# the resulting signal from this multiplier is the carrier
# with correct phase but at -38000 Hz.
- self.connect(self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1))
+ self.connect(self.stereo_carrier_pll_recovery,
+ (self.stereo_carrier_generator, 1))
# send the new carrier to one side of the mixer (multiplier)
- self.connect(self.stereo_carrier_generator, (self.stereo_basebander,0))
+ self.connect(self.stereo_carrier_generator,
+ (self.stereo_basebander, 0))
# send the demphasized audio to the DSBSC pick off filter, the complex
# DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier
# the result is BASEBANDED DSBSC with phase zero!
- self.connect(self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1))
+ self.connect(self.fm_demod, self.stereo_dsbsc_filter,
+ (self.stereo_basebander, 1))
# Pick off the real part since the imaginary is
# theoretically zero and then to one side of a summer
- self.connect(self.stereo_basebander, self.LmR_real, (self.Make_Left,0))
+ self.connect(self.stereo_basebander,
+ self.LmR_real, (self.Make_Left, 0))
- #take the same real part of the DSBSC baseband signal and
- #send it to negative side of a subtracter
- self.connect(self.LmR_real,(self.Make_Right,1))
+ # take the same real part of the DSBSC baseband signal and
+ # send it to negative side of a subtracter
+ self.connect(self.LmR_real, (self.Make_Right, 1))
# Make rds carrier by taking the squared pilot tone and
# multiplying by pilot tone
- self.connect(self.stereo_basebander,(self.rds_carrier_generator,0))
- self.connect(self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1))
+ self.connect(self.stereo_basebander,
+ (self.rds_carrier_generator, 0))
+ self.connect(self.stereo_carrier_pll_recovery,
+ (self.rds_carrier_generator, 1))
# take signal, filter off rds, send into mixer 0 channel
- self.connect(self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0))
+ self.connect(self.fm_demod, self.rds_signal_filter,
+ (self.rds_signal_generator, 0))
# take rds_carrier_generator output and send into mixer 1
# channel
- self.connect(self.rds_carrier_generator,(self.rds_signal_generator,1))
+ self.connect(self.rds_carrier_generator,
+ (self.rds_signal_generator, 1))
# send basebanded rds signal and send into "processor"
# which for now is a null sink
- self.connect(self.rds_signal_generator,self_rds_signal_processor)
-
+ self.connect(self.rds_signal_generator, self_rds_signal_processor)
if 1:
# pick off the audio, L+R that is what we used to have and
@@ -208,14 +216,14 @@ class wfm_rcv_fmdet(gr.hier_block2):
# take the picked off L+R audio and send it to the PLUS
# side of the subtractor
- self.connect(self.audio_filter,(self.Make_Right, 0))
+ self.connect(self.audio_filter, (self.Make_Right, 0))
# The result of Make_Left gets (L+R) + (L-R) and results in 2*L
# The result of Make_Right gets (L+R) - (L-R) and results in 2*R
- self.connect(self.Make_Left , self.deemph_Left, (self, 0))
+ self.connect(self.Make_Left, self.deemph_Left, (self, 0))
self.connect(self.Make_Right, self.deemph_Right, (self, 1))
# NOTE: mono support will require variable number of outputs in hier_block2s
# See ticket:174 in Trac database
- #else:
+ # else:
# self.connect (self.fm_demod, self.audio_filter, self)
diff --git a/gr-analog/python/analog/wfm_rcv_pll.py b/gr-analog/python/analog/wfm_rcv_pll.py
index 04ea9b1430..ce0e357d7d 100644
--- a/gr-analog/python/analog/wfm_rcv_pll.py
+++ b/gr-analog/python/analog/wfm_rcv_pll.py
@@ -16,6 +16,7 @@ from gnuradio import filter, fft
from gnuradio.filter import firdes
from gnuradio import analog
+
class wfm_rcv_pll(gr.hier_block2):
def __init__(self, demod_rate, audio_decimation, deemph_tau):
"""
@@ -30,7 +31,8 @@ class wfm_rcv_pll(gr.hier_block2):
deemph_tau: deemphasis ime constant in seconds (75us in US, 50us in EUR). (float)
"""
gr.hier_block2.__init__(self, "wfm_rcv_pll",
- gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
gr.io_signature(2, 2, gr.sizeof_float)) # Output signature
if audio_decimation != int(audio_decimation):
@@ -42,56 +44,80 @@ class wfm_rcv_pll(gr.hier_block2):
##################################################
self.demod_rate = demod_rate
self.deemph_tau = deemph_tau
- self.stereo_carrier_filter_coeffs = stereo_carrier_filter_coeffs = firdes.band_pass(-2.0, demod_rate, 37600, 38400, 400, fft.window.WIN_HAMMING, 6.76)
- self.pilot_carrier_filter_coeffs = pilot_carrier_filter_coeffs = firdes.complex_band_pass(1.0, demod_rate, 18980, 19020, 1500, fft.window.WIN_HAMMING, 6.76)
+ self.stereo_carrier_filter_coeffs = stereo_carrier_filter_coeffs = firdes.band_pass(
+ -2.0, demod_rate, 37600, 38400, 400, fft.window.WIN_HAMMING, 6.76)
+ self.pilot_carrier_filter_coeffs = pilot_carrier_filter_coeffs = firdes.complex_band_pass(
+ 1.0, demod_rate, 18980, 19020, 1500, fft.window.WIN_HAMMING, 6.76)
self.deviation = deviation = 75000
- self.audio_filter_coeffs = audio_filter_coeffs = firdes.low_pass(1, demod_rate, 15000,1500, fft.window.WIN_HAMMING, 6.76)
+ self.audio_filter_coeffs = audio_filter_coeffs = firdes.low_pass(
+ 1, demod_rate, 15000, 1500, fft.window.WIN_HAMMING, 6.76)
self.audio_decim = audio_decim = audio_decimation
self.audio_rate = audio_rate = demod_rate / audio_decim
- self.samp_delay = samp_delay = (len(pilot_carrier_filter_coeffs) - 1) // 2 + (len(stereo_carrier_filter_coeffs) - 1) // 2
+ self.samp_delay = samp_delay = (len(
+ pilot_carrier_filter_coeffs) - 1) // 2 + (len(stereo_carrier_filter_coeffs) - 1) // 2
##################################################
# Blocks
##################################################
- self.pilot_carrier_bpf = filter.fir_filter_fcc(1, pilot_carrier_filter_coeffs)
+ self.pilot_carrier_bpf = filter.fir_filter_fcc(
+ 1, pilot_carrier_filter_coeffs)
self.pilot_carrier_bpf.declare_sample_delay(0)
- self.stereo_carrier_bpf = filter.fft_filter_fff(1, stereo_carrier_filter_coeffs, 1)
+ self.stereo_carrier_bpf = filter.fft_filter_fff(
+ 1, stereo_carrier_filter_coeffs, 1)
self.stereo_carrier_bpf.declare_sample_delay(0)
- self.stereo_audio_lpf = filter.fft_filter_fff(audio_decim, audio_filter_coeffs, 1)
+ self.stereo_audio_lpf = filter.fft_filter_fff(
+ audio_decim, audio_filter_coeffs, 1)
self.stereo_audio_lpf.declare_sample_delay(0)
- self.mono_audio_lpf = filter.fft_filter_fff(audio_decim, audio_filter_coeffs, 1)
+ self.mono_audio_lpf = filter.fft_filter_fff(
+ audio_decim, audio_filter_coeffs, 1)
self.mono_audio_lpf.declare_sample_delay(0)
self.blocks_stereo_multiply = blocks.multiply_ff(1)
self.blocks_pilot_multiply = blocks.multiply_cc(1)
self.blocks_complex_to_imag = blocks.complex_to_imag(1)
self.blocks_right_sub = blocks.sub_ff(1)
self.blocks_left_add = blocks.add_ff(1)
- self.analog_quadrature_demod_cf = analog.quadrature_demod_cf(demod_rate/(2*math.pi*deviation))
- self.analog_pll_refout_cc = analog.pll_refout_cc(0.001, 2*math.pi * 19200 / demod_rate, 2*math.pi * 18800 / demod_rate)
- self.analog_right_fm_deemph = analog.fm_deemph(fs=audio_rate, tau=deemph_tau)
- self.analog_left_fm_deemph = analog.fm_deemph(fs=audio_rate, tau=deemph_tau)
- self.blocks_delay_0 = blocks.delay(gr.sizeof_float*1, samp_delay)
+ self.analog_quadrature_demod_cf = analog.quadrature_demod_cf(
+ demod_rate / (2 * math.pi * deviation))
+ self.analog_pll_refout_cc = analog.pll_refout_cc(
+ 0.001, 2 * math.pi * 19200 / demod_rate, 2 * math.pi * 18800 / demod_rate)
+ self.analog_right_fm_deemph = analog.fm_deemph(
+ fs=audio_rate, tau=deemph_tau)
+ self.analog_left_fm_deemph = analog.fm_deemph(
+ fs=audio_rate, tau=deemph_tau)
+ self.blocks_delay_0 = blocks.delay(gr.sizeof_float * 1, samp_delay)
##################################################
# Connections
##################################################
self.connect((self.analog_left_fm_deemph, 0), (self, 0))
self.connect((self.analog_right_fm_deemph, 0), (self, 1))
- self.connect((self.analog_pll_refout_cc, 0), (self.blocks_pilot_multiply, 1))
- self.connect((self.analog_pll_refout_cc, 0), (self.blocks_pilot_multiply, 0))
- self.connect((self.analog_quadrature_demod_cf, 0), (self.blocks_delay_0, 0))
- self.connect((self.blocks_delay_0, 0), (self.blocks_stereo_multiply, 0))
+ self.connect((self.analog_pll_refout_cc, 0),
+ (self.blocks_pilot_multiply, 1))
+ self.connect((self.analog_pll_refout_cc, 0),
+ (self.blocks_pilot_multiply, 0))
+ self.connect((self.analog_quadrature_demod_cf, 0),
+ (self.blocks_delay_0, 0))
+ self.connect((self.blocks_delay_0, 0),
+ (self.blocks_stereo_multiply, 0))
self.connect((self.blocks_delay_0, 0), (self.mono_audio_lpf, 0))
- self.connect((self.analog_quadrature_demod_cf, 0), (self.pilot_carrier_bpf, 0))
- self.connect((self.blocks_left_add, 0), (self.analog_left_fm_deemph, 0))
- self.connect((self.blocks_right_sub, 0), (self.analog_right_fm_deemph, 0))
- self.connect((self.blocks_complex_to_imag, 0), (self.stereo_carrier_bpf, 0))
- self.connect((self.blocks_pilot_multiply, 0), (self.blocks_complex_to_imag, 0))
- self.connect((self.blocks_stereo_multiply, 0), (self.stereo_audio_lpf, 0)) # L - R path
+ self.connect((self.analog_quadrature_demod_cf, 0),
+ (self.pilot_carrier_bpf, 0))
+ self.connect((self.blocks_left_add, 0),
+ (self.analog_left_fm_deemph, 0))
+ self.connect((self.blocks_right_sub, 0),
+ (self.analog_right_fm_deemph, 0))
+ self.connect((self.blocks_complex_to_imag, 0),
+ (self.stereo_carrier_bpf, 0))
+ self.connect((self.blocks_pilot_multiply, 0),
+ (self.blocks_complex_to_imag, 0))
+ self.connect((self.blocks_stereo_multiply, 0),
+ (self.stereo_audio_lpf, 0)) # L - R path
self.connect((self.mono_audio_lpf, 0), (self.blocks_left_add, 1))
self.connect((self.mono_audio_lpf, 0), (self.blocks_right_sub, 0))
self.connect((self.stereo_audio_lpf, 0), (self.blocks_left_add, 0))
self.connect((self.stereo_audio_lpf, 0), (self.blocks_right_sub, 1))
- self.connect((self.stereo_carrier_bpf, 0), (self.blocks_stereo_multiply, 1))
- self.connect((self.pilot_carrier_bpf, 0), (self.analog_pll_refout_cc, 0))
+ self.connect((self.stereo_carrier_bpf, 0),
+ (self.blocks_stereo_multiply, 1))
+ self.connect((self.pilot_carrier_bpf, 0),
+ (self.analog_pll_refout_cc, 0))
self.connect((self, 0), (self.analog_quadrature_demod_cf, 0))
diff --git a/gr-analog/python/analog/wfm_tx.py b/gr-analog/python/analog/wfm_tx.py
index 11f90ae545..70e91f8261 100644
--- a/gr-analog/python/analog/wfm_tx.py
+++ b/gr-analog/python/analog/wfm_tx.py
@@ -35,16 +35,17 @@ class wfm_tx(gr.hier_block2):
quad_rate must be an integer multiple of audio_rate.
"""
gr.hier_block2.__init__(self, "wfm_tx",
- gr.io_signature(1, 1, gr.sizeof_float), # Input signature
- gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+ # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
# FIXME audio_rate and quad_rate ought to be exact rationals
audio_rate = int(audio_rate)
quad_rate = int(quad_rate)
if quad_rate % audio_rate != 0:
- raise ValueError("quad_rate is not an integer multiple of audio_rate")
-
+ raise ValueError(
+ "quad_rate is not an integer multiple of audio_rate")
do_interp = audio_rate != quad_rate
@@ -58,14 +59,16 @@ class wfm_tx(gr.hier_block2):
40) # stopband atten dB
print("len(interp_taps) =", len(interp_taps))
- self.interpolator = filter.interp_fir_filter_fff (interp_factor, interp_taps)
+ self.interpolator = filter.interp_fir_filter_fff(
+ interp_factor, interp_taps)
self.preemph = fm_preemph(quad_rate, tau=tau, fh=fh)
k = 2 * math.pi * max_dev / quad_rate
- self.modulator = analog.frequency_modulator_fc (k)
+ self.modulator = analog.frequency_modulator_fc(k)
if do_interp:
- self.connect(self, self.interpolator, self.preemph, self.modulator, self)
+ self.connect(self, self.interpolator,
+ self.preemph, self.modulator, self)
else:
self.connect(self, self.preemph, self.modulator, self)