summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xgr-analog/examples/USRP_FM_stereo.grc651
-rw-r--r--gr-analog/python/analog/wfm_rcv_pll.py223
2 files changed, 718 insertions, 156 deletions
diff --git a/gr-analog/examples/USRP_FM_stereo.grc b/gr-analog/examples/USRP_FM_stereo.grc
new file mode 100755
index 0000000000..f4d3c5d923
--- /dev/null
+++ b/gr-analog/examples/USRP_FM_stereo.grc
@@ -0,0 +1,651 @@
+options:
+ parameters:
+ author: Barry Duggan
+ catch_exceptions: 'True'
+ category: '[GRC Hier Blocks]'
+ cmake_opt: ''
+ comment: ''
+ copyright: ''
+ description: ''
+ gen_cmake: 'On'
+ gen_linking: dynamic
+ generate_options: qt_gui
+ hier_block_src_path: '.:'
+ id: USRP_FM_stereo
+ max_nouts: '0'
+ output_language: python
+ placement: (0,0)
+ qt_qss_theme: ''
+ realtime_scheduling: ''
+ run: 'True'
+ run_command: '{python} -u {filename}'
+ run_options: prompt
+ sizing_mode: fixed
+ thread_safe_setters: ''
+ title: Broadcast FM stereo
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [16, 12.0]
+ rotation: 0
+ state: enabled
+
+blocks:
+- name: audio_decim
+ id: variable
+ parameters:
+ comment: ''
+ value: (int)(demod_rate/48000)
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [448, 12.0]
+ rotation: 0
+ state: true
+- name: center_freq
+ id: variable_qtgui_range
+ parameters:
+ comment: ''
+ gui_hint: ''
+ label: Frequency
+ min_len: '200'
+ orient: QtCore.Qt.Horizontal
+ rangeType: float
+ start: '88000000'
+ step: '200000'
+ stop: '108000000'
+ value: '102100000'
+ widget: counter_slider
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [672, 12.0]
+ rotation: 0
+ state: true
+- name: demod_rate
+ id: variable
+ parameters:
+ comment: ''
+ value: (int)(samp_rate/rf_decim)
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [272, 12.0]
+ rotation: 0
+ state: enabled
+- name: rf_decim
+ id: variable
+ parameters:
+ comment: ''
+ value: '2'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [368, 12.0]
+ rotation: 0
+ state: true
+- name: rf_gain
+ id: variable_qtgui_range
+ parameters:
+ comment: ''
+ gui_hint: ''
+ label: RF Gain
+ min_len: '200'
+ orient: QtCore.Qt.Horizontal
+ rangeType: float
+ start: '0'
+ step: '1'
+ stop: '70'
+ value: '50'
+ widget: slider
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [552, 12.0]
+ rotation: 0
+ state: true
+- name: samp_rate
+ id: variable
+ parameters:
+ comment: ''
+ value: '768000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [184, 12.0]
+ rotation: 0
+ state: enabled
+- name: volume
+ id: variable_qtgui_range
+ parameters:
+ comment: ''
+ gui_hint: ''
+ label: Volume
+ min_len: '200'
+ orient: QtCore.Qt.Horizontal
+ rangeType: float
+ start: '0'
+ step: '0.05'
+ stop: '1.0'
+ value: '0.2'
+ widget: slider
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [808, 12.0]
+ rotation: 0
+ state: enabled
+- name: analog_wfm_rcv_pll_0
+ id: analog_wfm_rcv_pll
+ parameters:
+ affinity: ''
+ alias: ''
+ audio_decimation: audio_decim
+ comment: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ quad_rate: (int)(samp_rate/rf_decim)
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [488, 200.0]
+ rotation: 0
+ state: true
+- name: audio_sink_0
+ id: audio_sink
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ device_name: ''
+ num_inputs: '2'
+ ok_to_block: 'True'
+ samp_rate: '48000'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [888, 200.0]
+ rotation: 0
+ state: true
+- name: blocks_multiply_const_vxx_0_0
+ id: blocks_multiply_const_vxx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ const: volume
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ type: float
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [704, 196.0]
+ rotation: 0
+ state: enabled
+- name: blocks_multiply_const_vxx_0_0_0
+ id: blocks_multiply_const_vxx
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: Volume
+ const: volume
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ type: float
+ vlen: '1'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [704, 252.0]
+ rotation: 0
+ state: enabled
+- name: filter_fft_low_pass_filter_0
+ id: filter_fft_low_pass_filter
+ parameters:
+ affinity: ''
+ alias: ''
+ beta: '6.76'
+ comment: ''
+ cutoff_freq: '180000'
+ decim: rf_decim
+ gain: '1'
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ nthreads: '1'
+ samp_rate: samp_rate
+ type: ccc
+ width: '20000'
+ win: firdes.WIN_HAMMING
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [296, 156.0]
+ rotation: 0
+ state: true
+- name: qtgui_sink_x_0
+ id: qtgui_sink_x
+ parameters:
+ affinity: ''
+ alias: ''
+ bw: samp_rate
+ comment: ''
+ fc: center_freq
+ fftsize: '1024'
+ gui_hint: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ name: '""'
+ plotconst: 'True'
+ plotfreq: 'True'
+ plottime: 'True'
+ plotwaterfall: 'True'
+ rate: '10'
+ showports: 'False'
+ showrf: 'True'
+ type: complex
+ wintype: firdes.WIN_BLACKMAN_hARRIS
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [496, 324.0]
+ rotation: 0
+ state: true
+- name: uhd_usrp_source_0
+ id: uhd_usrp_source
+ parameters:
+ affinity: ''
+ alias: ''
+ ant0: '"RX2"'
+ ant1: RX2
+ ant10: RX2
+ ant11: RX2
+ ant12: RX2
+ ant13: RX2
+ ant14: RX2
+ ant15: RX2
+ ant16: RX2
+ ant17: RX2
+ ant18: RX2
+ ant19: RX2
+ ant2: RX2
+ ant20: RX2
+ ant21: RX2
+ ant22: RX2
+ ant23: RX2
+ ant24: RX2
+ ant25: RX2
+ ant26: RX2
+ ant27: RX2
+ ant28: RX2
+ ant29: RX2
+ ant3: RX2
+ ant30: RX2
+ ant31: RX2
+ ant4: RX2
+ ant5: RX2
+ ant6: RX2
+ ant7: RX2
+ ant8: RX2
+ ant9: RX2
+ bw0: '0'
+ bw1: '0'
+ bw10: '0'
+ bw11: '0'
+ bw12: '0'
+ bw13: '0'
+ bw14: '0'
+ bw15: '0'
+ bw16: '0'
+ bw17: '0'
+ bw18: '0'
+ bw19: '0'
+ bw2: '0'
+ bw20: '0'
+ bw21: '0'
+ bw22: '0'
+ bw23: '0'
+ bw24: '0'
+ bw25: '0'
+ bw26: '0'
+ bw27: '0'
+ bw28: '0'
+ bw29: '0'
+ bw3: '0'
+ bw30: '0'
+ bw31: '0'
+ bw4: '0'
+ bw5: '0'
+ bw6: '0'
+ bw7: '0'
+ bw8: '0'
+ bw9: '0'
+ center_freq0: uhd.tune_request(center_freq, 180000)
+ center_freq1: '0'
+ center_freq10: '0'
+ center_freq11: '0'
+ center_freq12: '0'
+ center_freq13: '0'
+ center_freq14: '0'
+ center_freq15: '0'
+ center_freq16: '0'
+ center_freq17: '0'
+ center_freq18: '0'
+ center_freq19: '0'
+ center_freq2: '0'
+ center_freq20: '0'
+ center_freq21: '0'
+ center_freq22: '0'
+ center_freq23: '0'
+ center_freq24: '0'
+ center_freq25: '0'
+ center_freq26: '0'
+ center_freq27: '0'
+ center_freq28: '0'
+ center_freq29: '0'
+ center_freq3: '0'
+ center_freq30: '0'
+ center_freq31: '0'
+ center_freq4: '0'
+ center_freq5: '0'
+ center_freq6: '0'
+ center_freq7: '0'
+ center_freq8: '0'
+ center_freq9: '0'
+ clock_rate: 0e0
+ clock_source0: ''
+ clock_source1: ''
+ clock_source2: ''
+ clock_source3: ''
+ clock_source4: ''
+ clock_source5: ''
+ clock_source6: ''
+ clock_source7: ''
+ comment: ''
+ dc_offs_enb0: '""'
+ dc_offs_enb1: '""'
+ dc_offs_enb10: '""'
+ dc_offs_enb11: '""'
+ dc_offs_enb12: '""'
+ dc_offs_enb13: '""'
+ dc_offs_enb14: '""'
+ dc_offs_enb15: '""'
+ dc_offs_enb16: '""'
+ dc_offs_enb17: '""'
+ dc_offs_enb18: '""'
+ dc_offs_enb19: '""'
+ dc_offs_enb2: '""'
+ dc_offs_enb20: '""'
+ dc_offs_enb21: '""'
+ dc_offs_enb22: '""'
+ dc_offs_enb23: '""'
+ dc_offs_enb24: '""'
+ dc_offs_enb25: '""'
+ dc_offs_enb26: '""'
+ dc_offs_enb27: '""'
+ dc_offs_enb28: '""'
+ dc_offs_enb29: '""'
+ dc_offs_enb3: '""'
+ dc_offs_enb30: '""'
+ dc_offs_enb31: '""'
+ dc_offs_enb4: '""'
+ dc_offs_enb5: '""'
+ dc_offs_enb6: '""'
+ dc_offs_enb7: '""'
+ dc_offs_enb8: '""'
+ dc_offs_enb9: '""'
+ dev_addr: ''
+ dev_args: '""'
+ gain0: rf_gain
+ gain1: '0'
+ gain10: '0'
+ gain11: '0'
+ gain12: '0'
+ gain13: '0'
+ gain14: '0'
+ gain15: '0'
+ gain16: '0'
+ gain17: '0'
+ gain18: '0'
+ gain19: '0'
+ gain2: '0'
+ gain20: '0'
+ gain21: '0'
+ gain22: '0'
+ gain23: '0'
+ gain24: '0'
+ gain25: '0'
+ gain26: '0'
+ gain27: '0'
+ gain28: '0'
+ gain29: '0'
+ gain3: '0'
+ gain30: '0'
+ gain31: '0'
+ gain4: '0'
+ gain5: '0'
+ gain6: '0'
+ gain7: '0'
+ gain8: '0'
+ gain9: '0'
+ iq_imbal_enb0: '""'
+ iq_imbal_enb1: '""'
+ iq_imbal_enb10: '""'
+ iq_imbal_enb11: '""'
+ iq_imbal_enb12: '""'
+ iq_imbal_enb13: '""'
+ iq_imbal_enb14: '""'
+ iq_imbal_enb15: '""'
+ iq_imbal_enb16: '""'
+ iq_imbal_enb17: '""'
+ iq_imbal_enb18: '""'
+ iq_imbal_enb19: '""'
+ iq_imbal_enb2: '""'
+ iq_imbal_enb20: '""'
+ iq_imbal_enb21: '""'
+ iq_imbal_enb22: '""'
+ iq_imbal_enb23: '""'
+ iq_imbal_enb24: '""'
+ iq_imbal_enb25: '""'
+ iq_imbal_enb26: '""'
+ iq_imbal_enb27: '""'
+ iq_imbal_enb28: '""'
+ iq_imbal_enb29: '""'
+ iq_imbal_enb3: '""'
+ iq_imbal_enb30: '""'
+ iq_imbal_enb31: '""'
+ iq_imbal_enb4: '""'
+ iq_imbal_enb5: '""'
+ iq_imbal_enb6: '""'
+ iq_imbal_enb7: '""'
+ iq_imbal_enb8: '""'
+ iq_imbal_enb9: '""'
+ lo_export0: 'False'
+ lo_export1: 'False'
+ lo_export10: 'False'
+ lo_export11: 'False'
+ lo_export12: 'False'
+ lo_export13: 'False'
+ lo_export14: 'False'
+ lo_export15: 'False'
+ lo_export16: 'False'
+ lo_export17: 'False'
+ lo_export18: 'False'
+ lo_export19: 'False'
+ lo_export2: 'False'
+ lo_export20: 'False'
+ lo_export21: 'False'
+ lo_export22: 'False'
+ lo_export23: 'False'
+ lo_export24: 'False'
+ lo_export25: 'False'
+ lo_export26: 'False'
+ lo_export27: 'False'
+ lo_export28: 'False'
+ lo_export29: 'False'
+ lo_export3: 'False'
+ lo_export30: 'False'
+ lo_export31: 'False'
+ lo_export4: 'False'
+ lo_export5: 'False'
+ lo_export6: 'False'
+ lo_export7: 'False'
+ lo_export8: 'False'
+ lo_export9: 'False'
+ lo_source0: internal
+ lo_source1: internal
+ lo_source10: internal
+ lo_source11: internal
+ lo_source12: internal
+ lo_source13: internal
+ lo_source14: internal
+ lo_source15: internal
+ lo_source16: internal
+ lo_source17: internal
+ lo_source18: internal
+ lo_source19: internal
+ lo_source2: internal
+ lo_source20: internal
+ lo_source21: internal
+ lo_source22: internal
+ lo_source23: internal
+ lo_source24: internal
+ lo_source25: internal
+ lo_source26: internal
+ lo_source27: internal
+ lo_source28: internal
+ lo_source29: internal
+ lo_source3: internal
+ lo_source30: internal
+ lo_source31: internal
+ lo_source4: internal
+ lo_source5: internal
+ lo_source6: internal
+ lo_source7: internal
+ lo_source8: internal
+ lo_source9: internal
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ nchan: '1'
+ norm_gain0: 'False'
+ norm_gain1: 'False'
+ norm_gain10: 'False'
+ norm_gain11: 'False'
+ norm_gain12: 'False'
+ norm_gain13: 'False'
+ norm_gain14: 'False'
+ norm_gain15: 'False'
+ norm_gain16: 'False'
+ norm_gain17: 'False'
+ norm_gain18: 'False'
+ norm_gain19: 'False'
+ norm_gain2: 'False'
+ norm_gain20: 'False'
+ norm_gain21: 'False'
+ norm_gain22: 'False'
+ norm_gain23: 'False'
+ norm_gain24: 'False'
+ norm_gain25: 'False'
+ norm_gain26: 'False'
+ norm_gain27: 'False'
+ norm_gain28: 'False'
+ norm_gain29: 'False'
+ norm_gain3: 'False'
+ norm_gain30: 'False'
+ norm_gain31: 'False'
+ norm_gain4: 'False'
+ norm_gain5: 'False'
+ norm_gain6: 'False'
+ norm_gain7: 'False'
+ norm_gain8: 'False'
+ norm_gain9: 'False'
+ num_mboards: '1'
+ otw: ''
+ rx_agc0: Disabled
+ rx_agc1: Default
+ rx_agc10: Default
+ rx_agc11: Default
+ rx_agc12: Default
+ rx_agc13: Default
+ rx_agc14: Default
+ rx_agc15: Default
+ rx_agc16: Default
+ rx_agc17: Default
+ rx_agc18: Default
+ rx_agc19: Default
+ rx_agc2: Default
+ rx_agc20: Default
+ rx_agc21: Default
+ rx_agc22: Default
+ rx_agc23: Default
+ rx_agc24: Default
+ rx_agc25: Default
+ rx_agc26: Default
+ rx_agc27: Default
+ rx_agc28: Default
+ rx_agc29: Default
+ rx_agc3: Default
+ rx_agc30: Default
+ rx_agc31: Default
+ rx_agc4: Default
+ rx_agc5: Default
+ rx_agc6: Default
+ rx_agc7: Default
+ rx_agc8: Default
+ rx_agc9: Default
+ samp_rate: samp_rate
+ sd_spec0: ''
+ sd_spec1: ''
+ sd_spec2: ''
+ sd_spec3: ''
+ sd_spec4: ''
+ sd_spec5: ''
+ sd_spec6: ''
+ sd_spec7: ''
+ show_lo_controls: 'False'
+ stream_args: ''
+ stream_chans: '[]'
+ sync: none
+ time_source0: ''
+ time_source1: ''
+ time_source2: ''
+ time_source3: ''
+ time_source4: ''
+ time_source5: ''
+ time_source6: ''
+ time_source7: ''
+ type: fc32
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [72, 164.0]
+ rotation: 0
+ state: true
+
+connections:
+- [analog_wfm_rcv_pll_0, '0', blocks_multiply_const_vxx_0_0, '0']
+- [analog_wfm_rcv_pll_0, '1', blocks_multiply_const_vxx_0_0_0, '0']
+- [blocks_multiply_const_vxx_0_0, '0', audio_sink_0, '0']
+- [blocks_multiply_const_vxx_0_0_0, '0', audio_sink_0, '1']
+- [filter_fft_low_pass_filter_0, '0', analog_wfm_rcv_pll_0, '0']
+- [filter_fft_low_pass_filter_0, '0', qtgui_sink_x_0, '0']
+- [uhd_usrp_source_0, '0', filter_fft_low_pass_filter_0, '0']
+
+metadata:
+ file_format: 1
diff --git a/gr-analog/python/analog/wfm_rcv_pll.py b/gr-analog/python/analog/wfm_rcv_pll.py
index bc5e7c27c7..a0fd36fa4f 100644
--- a/gr-analog/python/analog/wfm_rcv_pll.py
+++ b/gr-analog/python/analog/wfm_rcv_pll.py
@@ -1,11 +1,11 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
#
-# Copyright 2005,2006,2012-2013 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
+# SPDX-License-Identifier: GPL-3.0
#
+# GNU Radio Python Flow Graph
+# Title: FM stereo demod block
from __future__ import absolute_import
from __future__ import division
@@ -16,10 +16,8 @@ import math
from gnuradio import gr
from gnuradio import blocks
from gnuradio import filter
-
-from . import analog_python as analog
-from .fm_emph import fm_deemph
-
+from gnuradio.filter import firdes
+from gnuradio import analog
class wfm_rcv_pll(gr.hier_block2):
def __init__(self, demod_rate, audio_decimation):
@@ -36,151 +34,64 @@ class wfm_rcv_pll(gr.hier_block2):
gr.hier_block2.__init__(self, "wfm_rcv_pll",
gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
gr.io_signature(2, 2, gr.sizeof_float)) # Output signature
- bandwidth = 250e3
- audio_rate = demod_rate / audio_decimation
-
-
- # We assign to self so that outsiders can grab the demodulator
- # if they need to. E.g., to plot its output.
- #
- # input: complex; output: float
- loop_bw = 2*math.pi/100.0
- max_freq = 2.0*math.pi*90e3/demod_rate
- self.fm_demod = analog.pll_freqdet_cf(loop_bw, max_freq,-max_freq)
-
- # input: float; output: float
- 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
- demod_rate, # sampling rate
- 15000 ,
- width_of_transition_band,
- filter.firdes.WIN_HAMMING)
- # input: float; output: float
- 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
-
- stereo_carrier_filter_coeffs = \
- filter.firdes.complex_band_pass(10.0,
- demod_rate,
- -19020,
- -18980,
- width_of_transition_band,
- filter.firdes.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
-
- # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain
-
- stereo_dsbsc_filter_coeffs = \
- filter.firdes.complex_band_pass(20.0,
- demod_rate,
- 38000-15000 / 2,
- 38000+15000 / 2,
- width_of_transition_band,
- filter.firdes.WIN_HAMMING)
- #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.stereo_carrier_filter = \
- filter.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs)
-
- # carrier is twice the picked off carrier so arrange to do a complex multiply
-
- self.stereo_carrier_generator = blocks.multiply_cc();
-
- # Pick off the rds signal
-
- stereo_rds_filter_coeffs = \
- filter.firdes.complex_band_pass(30.0,
- demod_rate,
- 57000 - 1500,
- 57000 + 1500,
- width_of_transition_band,
- filter.firdes.WIN_HAMMING)
- #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);
-
- 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);
- #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();
-
- # 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.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))
- # send the already filtered carrier to the otherside of the carrier
- self.connect(self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1))
- # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz.
-
- # send the new carrier to one side of the mixer (multiplier)
- 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
- self.connect(self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1))
- # the result is BASEBANDED DSBSC with phase zero!
-
- # 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))
- #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))
- # take signal, filter off rds, send into mixer 0 channel
- 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))
- # 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)
+ ##################################################
+ # Variables
+ ##################################################
+ self.samp_rate = samp_rate = 3840000
+ self.rf_decim = rf_decim = 10
+ self.demod_rate = demod_rate = (int)(samp_rate/rf_decim)
+ self.stereo_carrier_filter_coeffs_0 = stereo_carrier_filter_coeffs_0 = firdes.band_pass(1.0, demod_rate, 37600, 38400, 400, firdes.WIN_HAMMING, 6.76)
+ self.stereo_carrier_filter_coeffs = stereo_carrier_filter_coeffs = firdes.complex_band_pass(1.0, demod_rate, 18980, 19020, 1500, firdes.WIN_HAMMING, 6.76)
+ self.deviation = deviation = 75000
+ self.audio_filter = audio_filter = firdes.low_pass(1, demod_rate, 15000,1500, firdes.WIN_HAMMING, 6.76)
+ self.audio_decim = audio_decim = (int)(demod_rate/48000)
+
+ ##################################################
+ # Blocks
+ ##################################################
+ self.fir_filter_xxx_1 = filter.fir_filter_fcc(1, stereo_carrier_filter_coeffs)
+ self.fir_filter_xxx_1.declare_sample_delay(0)
+ self.fft_filter_xxx_3 = filter.fft_filter_fff(1, stereo_carrier_filter_coeffs_0, 1)
+ self.fft_filter_xxx_3.declare_sample_delay(0)
+ self.fft_filter_xxx_2 = filter.fft_filter_fff(audio_decim, audio_filter, 1)
+ self.fft_filter_xxx_2.declare_sample_delay(0)
+ self.fft_filter_xxx_1 = filter.fft_filter_fff(audio_decim, audio_filter, 1)
+ self.fft_filter_xxx_1.declare_sample_delay(0)
+ self.blocks_multiply_xx_2 = blocks.multiply_vff(1)
+ self.blocks_multiply_xx_0 = blocks.multiply_vcc(1)
+ self.blocks_multiply_const_vxx_0_1 = blocks.multiply_const_ff(5.5)
+ self.blocks_multiply_const_vxx_0 = blocks.multiply_const_ff(-5.5)
+ self.blocks_complex_to_imag_0 = blocks.complex_to_imag(1)
+ self.blocks_add_xx_0_0 = blocks.add_vff(1)
+ self.blocks_add_xx_0 = blocks.add_vff(1)
+ self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(demod_rate/(2*math.pi*deviation))
+ self.analog_pll_refout_cc_0 = analog.pll_refout_cc(0.001, 2*math.pi * 19200 / demod_rate, 2*math.pi * 18800 / demod_rate)
+ self.analog_fm_deemph_0_0 = analog.fm_deemph(fs=48000, tau=75e-6)
+ self.analog_fm_deemph_0 = analog.fm_deemph(fs=48000, tau=75e-6)
+
+ ##################################################
+ # Connections
+ ##################################################
+ self.connect((self.analog_fm_deemph_0, 0), (self, 1))
+ self.connect((self.analog_fm_deemph_0_0, 0), (self, 0))
+ self.connect((self.analog_pll_refout_cc_0, 0), (self.blocks_multiply_xx_0, 1))
+ self.connect((self.analog_pll_refout_cc_0, 0), (self.blocks_multiply_xx_0, 0))
+ self.connect((self.analog_quadrature_demod_cf_0, 0), (self.blocks_multiply_xx_2, 0))
+ self.connect((self.analog_quadrature_demod_cf_0, 0), (self.fft_filter_xxx_1, 0))
+ self.connect((self.analog_quadrature_demod_cf_0, 0), (self.fir_filter_xxx_1, 0))
+ self.connect((self.blocks_add_xx_0, 0), (self.analog_fm_deemph_0, 0))
+ self.connect((self.blocks_add_xx_0_0, 0), (self.analog_fm_deemph_0_0, 0))
+ self.connect((self.blocks_complex_to_imag_0, 0), (self.fft_filter_xxx_3, 0))
+ self.connect((self.blocks_multiply_const_vxx_0, 0), (self.blocks_add_xx_0, 0))
+ self.connect((self.blocks_multiply_const_vxx_0_1, 0), (self.blocks_add_xx_0_0, 0))
+ self.connect((self.blocks_multiply_xx_0, 0), (self.blocks_complex_to_imag_0, 0))
+ self.connect((self.blocks_multiply_xx_2, 0), (self.fft_filter_xxx_2, 0))
+ self.connect((self.fft_filter_xxx_1, 0), (self.blocks_add_xx_0, 1))
+ self.connect((self.fft_filter_xxx_1, 0), (self.blocks_add_xx_0_0, 1))
+ self.connect((self.fft_filter_xxx_2, 0), (self.blocks_multiply_const_vxx_0, 0))
+ self.connect((self.fft_filter_xxx_2, 0), (self.blocks_multiply_const_vxx_0_1, 0))
+ self.connect((self.fft_filter_xxx_3, 0), (self.blocks_multiply_xx_2, 1))
+ self.connect((self.fir_filter_xxx_1, 0), (self.analog_pll_refout_cc_0, 0))
+ self.connect((self, 0), (self.analog_quadrature_demod_cf_0, 0))
- if 1:
- # pick off the audio, L+R that is what we used to have and send it to the summer
- self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1))
- # 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))
- # 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_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:
- # self.connect (self.fm_demod, self.audio_filter, self)