diff options
author | Josh Morman <jmorman@gnuradio.org> | 2021-11-24 12:01:00 -0500 |
---|---|---|
committer | mormj <34754695+mormj@users.noreply.github.com> | 2021-11-24 14:41:53 -0500 |
commit | 2ede969ec5f3f6d361814403b7375db5f15ec14d (patch) | |
tree | d963e92732842ee3491da1282dfa09400342c96d /gr-analog | |
parent | c6f291d57d913708a2517de3c6902425c2c575d3 (diff) |
analog: pep8 formatting
Signed-off-by: Josh Morman <jmorman@gnuradio.org>
Diffstat (limited to 'gr-analog')
-rw-r--r-- | gr-analog/examples/fm_demod.py | 17 | ||||
-rw-r--r-- | gr-analog/examples/fmtest.py | 69 | ||||
-rw-r--r-- | gr-analog/examples/tags/uhd_burst_detector.py | 34 | ||||
-rw-r--r-- | gr-analog/python/analog/am_demod.py | 13 | ||||
-rw-r--r-- | gr-analog/python/analog/fm_demod.py | 8 | ||||
-rw-r--r-- | gr-analog/python/analog/fm_emph.py | 124 | ||||
-rw-r--r-- | gr-analog/python/analog/nbfm_rx.py | 14 | ||||
-rw-r--r-- | gr-analog/python/analog/nbfm_tx.py | 25 | ||||
-rw-r--r-- | gr-analog/python/analog/qa_agc.py | 2 | ||||
-rw-r--r-- | gr-analog/python/analog/standard_squelch.py | 50 | ||||
-rw-r--r-- | gr-analog/python/analog/wfm_rcv.py | 13 | ||||
-rw-r--r-- | gr-analog/python/analog/wfm_rcv_fmdet.py | 110 | ||||
-rw-r--r-- | gr-analog/python/analog/wfm_rcv_pll.py | 78 | ||||
-rw-r--r-- | gr-analog/python/analog/wfm_tx.py | 17 |
14 files changed, 325 insertions, 249 deletions
diff --git a/gr-analog/examples/fm_demod.py b/gr-analog/examples/fm_demod.py index 961f06ff4d..190febb001 100644 --- a/gr-analog/examples/fm_demod.py +++ b/gr-analog/examples/fm_demod.py @@ -15,9 +15,12 @@ from gnuradio import analog from gnuradio import audio from gnuradio.filter import firdes from gnuradio.fft import window -import sys, math +import sys +import math # Create a top_block + + class build_graph(gr.top_block): def __init__(self): gr.top_block.__init__(self) @@ -35,7 +38,7 @@ class build_graph(gr.top_block): # Set the demodulator using the same deviation as the receiver. max_dev = 75e3 - fm_demod_gain = input_rate / (2*math.pi*max_dev/8.0) + fm_demod_gain = input_rate / (2 * math.pi * max_dev / 8.0) fm_demod = analog.quadrature_demod_cf(fm_demod_gain) # Create a filter for the resampler and filter the audio @@ -45,8 +48,8 @@ class build_graph(gr.top_block): # building the filter. volume = 0.20 nfilts = 32 - resamp_taps = firdes.low_pass_2(volume*nfilts, # gain - nfilts*input_rate, # sampling rate + resamp_taps = firdes.low_pass_2(volume * nfilts, # gain + nfilts * input_rate, # sampling rate 15e3, # low pass cutoff freq 1e3, # width of trans. band 60, # stop band attenuaton @@ -64,7 +67,8 @@ class build_graph(gr.top_block): # now wire it all together self.connect(src, fm_demod) self.connect(fm_demod, resamp_filter) - self.connect(resamp_filter, (audio_sink,0)) + self.connect(resamp_filter, (audio_sink, 0)) + def main(args): tb = build_graph() @@ -72,7 +76,6 @@ def main(args): input('Press Enter to quit: ') tb.stop() + if __name__ == '__main__': main(sys.argv[1:]) - - diff --git a/gr-analog/examples/fmtest.py b/gr-analog/examples/fmtest.py index 0664238b6b..a93b3ff250 100644 --- a/gr-analog/examples/fmtest.py +++ b/gr-analog/examples/fmtest.py @@ -14,7 +14,9 @@ from gnuradio import filter from gnuradio.fft import window from gnuradio import analog from gnuradio import channels -import sys, math, time +import sys +import math +import time import numpy try: @@ -32,11 +34,11 @@ class fmtx(gr.hier_block2): gr.io_signature(1, 1, gr.sizeof_gr_complex)) fmtx = analog.nbfm_tx(audio_rate, if_rate, max_dev=5e3, - tau=75e-6, fh=0.925*if_rate/2.0) + tau=75e-6, fh=0.925 * if_rate / 2.0) # Local oscillator lo = analog.sig_source_c(if_rate, # sample rate - analog.GR_SIN_WAVE, # waveform type + analog.GR_SIN_WAVE, # waveform type lo_freq, # frequency 1.0, # amplitude 0) # DC Offset @@ -46,6 +48,7 @@ class fmtx(gr.hier_block2): self.connect(lo, (mixer, 1)) self.connect(mixer, self) + class fmtest(gr.top_block): def __init__(self): gr.top_block.__init__(self) @@ -57,14 +60,16 @@ class fmtest(gr.top_block): self._N = 5 chspacing = 16000 freq = [10, 20, 30, 40, 50] - f_lo = [0, 1*chspacing, -1*chspacing, 2*chspacing, -2*chspacing] + f_lo = [0, 1 * chspacing, -1 * chspacing, + 2 * chspacing, -2 * chspacing] - self._if_rate = 4*self._N*self._audio_rate + self._if_rate = 4 * self._N * self._audio_rate # Create a signal source and frequency modulate it self.sum = blocks.add_cc() for n in range(self._N): - sig = analog.sig_source_f(self._audio_rate, analog.GR_SIN_WAVE, freq[n], 0.5) + sig = analog.sig_source_f( + self._audio_rate, analog.GR_SIN_WAVE, freq[n], 0.5) fm = fmtx(f_lo[n], self._audio_rate, self._if_rate) self.connect(sig, fm) self.connect(fm, (self.sum, n)) @@ -75,7 +80,6 @@ class fmtest(gr.top_block): self.connect(self.sum, self.head, self.channel, self.snk_tx) - # Design the channlizer self._M = 10 bw = chspacing / 2.0 @@ -99,10 +103,12 @@ class fmtest(gr.top_block): self.squelch = list() self.snks = list() for i in range(self._M): - self.fmdet.append(analog.nbfm_rx(self._audio_rate, self._chan_rate)) - self.squelch.append(analog.standard_squelch(self._audio_rate*10)) + self.fmdet.append(analog.nbfm_rx( + self._audio_rate, self._chan_rate)) + self.squelch.append(analog.standard_squelch(self._audio_rate * 10)) self.snks.append(blocks.vector_sink_f()) - self.connect((self.pfb, i), self.fmdet[i], self.squelch[i], self.snks[i]) + self.connect( + (self.pfb, i), self.fmdet[i], self.squelch[i], self.snks[i]) def num_tx_channels(self): return self._N @@ -110,6 +116,7 @@ class fmtest(gr.top_block): def num_rx_channels(self): return self._M + def main(): fm = fmtest() @@ -119,9 +126,9 @@ def main(): tend = time.time() if 1: - fig1 = pylab.figure(1, figsize=(12,10), facecolor="w") - fig2 = pylab.figure(2, figsize=(12,10), facecolor="w") - fig3 = pylab.figure(3, figsize=(12,10), facecolor="w") + fig1 = pylab.figure(1, figsize=(12, 10), facecolor="w") + fig2 = pylab.figure(2, figsize=(12, 10), facecolor="w") + fig3 = pylab.figure(3, figsize=(12, 10), facecolor="w") Ns = 10000 Ne = 100000 @@ -132,16 +139,16 @@ def main(): # Plot transmitted signal fs = fm._if_rate - d = fm.snk_tx.data()[Ns:Ns+Ne] + d = fm.snk_tx.data()[Ns:Ns + Ne] sp1_f = fig1.add_subplot(2, 1, 1) - X,freq = sp1_f.psd(d, NFFT=fftlen, noverlap=fftlen / 4, Fs=fs, - window = lambda d: d*winfunc(fftlen), - visible=False) - X_in = 10.0*numpy.log10(abs(numpy.fft.fftshift(X))) + X, freq = sp1_f.psd(d, NFFT=fftlen, noverlap=fftlen / 4, Fs=fs, + window=lambda d: d * winfunc(fftlen), + visible=False) + X_in = 10.0 * numpy.log10(abs(numpy.fft.fftshift(X))) f_in = numpy.arange(-fs / 2.0, fs / 2.0, fs / float(X_in.size)) p1_f = sp1_f.plot(f_in, X_in, "b") - sp1_f.set_xlim([min(f_in), max(f_in)+1]) + sp1_f.set_xlim([min(f_in), max(f_in) + 1]) sp1_f.set_ylim([-120.0, 20.0]) sp1_f.set_title("Input Signal", weight="bold") @@ -149,7 +156,7 @@ def main(): sp1_f.set_ylabel("Power (dBW)") Ts = 1.0 / fs - Tmax = len(d)*Ts + Tmax = len(d) * Ts t_in = numpy.arange(0, Tmax, Ts) x_in = numpy.array(d) @@ -173,16 +180,16 @@ def main(): # this is a bug, probably due to the corner cases d = fm.snks[i].data()[Ns:Ne] - sp2_f = fig2.add_subplot(Nrows, Ncols, 1+i) - X,freq = sp2_f.psd(d, NFFT=fftlen, noverlap=fftlen / 4, Fs=fs_o, - window = lambda d: d*winfunc(fftlen), - visible=False) + sp2_f = fig2.add_subplot(Nrows, Ncols, 1 + i) + X, freq = sp2_f.psd(d, NFFT=fftlen, noverlap=fftlen / 4, Fs=fs_o, + window=lambda d: d * winfunc(fftlen), + visible=False) #X_o = 10.0*numpy.log10(abs(numpy.fft.fftshift(X))) - X_o = 10.0*numpy.log10(abs(X)) + X_o = 10.0 * numpy.log10(abs(X)) #f_o = numpy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size)) - f_o = numpy.arange(0, fs_o / 2.0, fs_o/2.0/float(X_o.size)) + f_o = numpy.arange(0, fs_o / 2.0, fs_o / 2.0 / float(X_o.size)) p2_f = sp2_f.plot(f_o, X_o, "b") - sp2_f.set_xlim([min(f_o), max(f_o)+0.1]) + sp2_f.set_xlim([min(f_o), max(f_o) + 0.1]) sp2_f.set_ylim([-120.0, 20.0]) sp2_f.grid(True) @@ -190,22 +197,20 @@ def main(): sp2_f.set_xlabel("Frequency (kHz)") sp2_f.set_ylabel("Power (dBW)") - Ts = 1.0 / fs_o - Tmax = len(d)*Ts + Tmax = len(d) * Ts t_o = numpy.arange(0, Tmax, Ts) x_t = numpy.array(d) - sp2_t = fig3.add_subplot(Nrows, Ncols, 1+i) + sp2_t = fig3.add_subplot(Nrows, Ncols, 1 + i) p2_t = sp2_t.plot(t_o, x_t.real, "b") p2_t = sp2_t.plot(t_o, x_t.imag, "r") - sp2_t.set_xlim([min(t_o), max(t_o)+1]) + sp2_t.set_xlim([min(t_o), max(t_o) + 1]) sp2_t.set_ylim([-1, 1]) sp2_t.set_xlabel("Time (s)") sp2_t.set_ylabel("Amplitude") - pylab.show() diff --git a/gr-analog/examples/tags/uhd_burst_detector.py b/gr-analog/examples/tags/uhd_burst_detector.py index 0e017e47a2..0c4a68de8f 100644 --- a/gr-analog/examples/tags/uhd_burst_detector.py +++ b/gr-analog/examples/tags/uhd_burst_detector.py @@ -17,6 +17,7 @@ from gnuradio.eng_arg import eng_float from gnuradio.filter import firdes from argparse import ArgumentParser + class uhd_burst_detector(gr.top_block): def __init__(self, uhd_address, options): @@ -42,24 +43,24 @@ class uhd_burst_detector(gr.top_block): self.tagger = blocks.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods - data = 1000*[0,] + 1000*[1,] + data = 1000 * [0, ] + 1000 * [1, ] self.signal = blocks.vector_source_s(data, True) # Energy detector to get signal burst - ## use squelch to detect energy - self.det = analog.simple_squelch_cc(self.threshold, 0.01) - ## convert to mag squared (float) + # use squelch to detect energy + self.det = analog.simple_squelch_cc(self.threshold, 0.01) + # convert to mag squared (float) self.c2m = blocks.complex_to_mag_squared() - ## average to debounce + # average to debounce self.avg = filter.single_pole_iir_filter_ff(0.01) - ## rescale signal for conversion to short + # rescale signal for conversion to short self.scale = blocks.multiply_const_ff(2**16) - ## signal input uses shorts + # signal input uses shorts self.f2s = blocks.float_to_short() # Use file sink burst tagger to capture bursts - self.fsnk = blocks.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) - + self.fsnk = blocks.tagged_file_sink( + gr.sizeof_gr_complex, self.samp_rate) ################################################## # Connections @@ -81,22 +82,23 @@ class uhd_burst_detector(gr.top_block): self.samp_rate = samp_rate self.uhd_src_0.set_samp_rate(self.samp_rate) + if __name__ == '__main__': parser = ArgumentParser() parser.add_argument("-a", "--address", default="addr=192.168.10.2", - help="select address of the device [default=%(default)r]") - #parser.add_argument("-A", "--antenna", default=None, + help="select address of the device [default=%(default)r]") + # parser.add_argument("-A", "--antenna", default=None, # help="select Rx Antenna (only on RFX-series boards)") parser.add_argument("-f", "--freq", type=eng_float, default=450e6, - help="set frequency to FREQ", metavar="FREQ") + help="set frequency to FREQ", metavar="FREQ") parser.add_argument("-g", "--gain", type=eng_float, default=0, - help="set gain in dB [default=%(default)r]") + help="set gain in dB [default=%(default)r]") parser.add_argument("-R", "--samp-rate", type=eng_float, default=200000, - help="set USRP sample rate [default=%(default)r]") + help="set USRP sample rate [default=%(default)r]") parser.add_argument("-t", "--threshold", type=float, default=-60, - help="Set the detection power threshold (dBm) [default=%(default)r") + help="Set the detection power threshold (dBm) [default=%(default)r") parser.add_argument("-T", "--trigger", action="store_true", default=False, - help="Use internal trigger instead of detector [default=%(default)r]") + help="Use internal trigger instead of detector [default=%(default)r]") args = parser.parse_args() uhd_addr = args.address 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) |