summaryrefslogtreecommitdiff
path: root/gr-dtv
diff options
context:
space:
mode:
authorghostop14 <ghostop14@gmail.com>2020-02-01 13:02:34 -0500
committerdevnulling <devnulling@users.noreply.github.com>2020-02-04 09:08:55 -0800
commit90c8e30e87c935176224728d2a28709cb6a7adab (patch)
tree4a97b486b018e3de13962c08aba0e3f35a77fd15 /gr-dtv
parent5b38e99298d47da94e4436d810db550d9e7e4520 (diff)
Fix ATSC Flowgraphs and Allow Realtime Viewing
The ATSC RX flowgraph has been fixed to allow for proper decoding. The original flowgraph had rate mismatches between the RX filter and the FPLL block that prevented proper decoding. This version also has a number of performance enhancements that ultimately allow the stream to be watched in real-time. These changes capitalize on new PRs for GR master branch. The ATSC RX filter was broken into its 2 respective parts (an RRC block and a resampler). The RRC block now uses the faster FFT RRC convenience wrapper, and the PFB arb resampler was crushing performance. So the sampling rate was adjusted to match the ATSC symbol rate*sps. This removed the need for a resampler altogether, significantly reducing CPU load. Processor core affinity based on a GRCon17 presentation was also applied to separate out blocks and prevent thread migration. Some cleanup was also done in the FPLL receiver block. Note that in using this in real-time, performance enhancements in PR 3076 that has not been merged into master yet are also important. The FPLL loop has some speedups due to the inlining of the NCO and sincos functions, and takes advantage of the already-merged cx_limited_range performance improvement in the FPLL loop too. An additional change to support fast CC multiply on systems that do not support the cx_limited_range compiler flag can be incorporated once 3076 is merged. This block also is better annotated for others to understand some of the design choices. Ultimately with the networking block in grnet, smplayer can be pointed at the flowgraph and TV watched in real-time. See the flowgraph for additional notes.
Diffstat (limited to 'gr-dtv')
-rw-r--r--gr-dtv/examples/uhd_atsc_capture.grc258
-rw-r--r--gr-dtv/examples/uhd_atsc_tx.grc109
-rw-r--r--gr-dtv/examples/uhd_rx_atsc.grc385
-rw-r--r--gr-dtv/lib/atsc/atsc_fpll_impl.cc33
4 files changed, 456 insertions, 329 deletions
diff --git a/gr-dtv/examples/uhd_atsc_capture.grc b/gr-dtv/examples/uhd_atsc_capture.grc
index 1d9f05920a..13bb4e253f 100644
--- a/gr-dtv/examples/uhd_atsc_capture.grc
+++ b/gr-dtv/examples/uhd_atsc_capture.grc
@@ -1,6 +1,7 @@
options:
parameters:
author: ''
+ catch_exceptions: 'True'
category: Custom
cmake_opt: ''
comment: ''
@@ -8,88 +9,87 @@ options:
description: ''
gen_cmake: 'On'
gen_linking: dynamic
- generate_options: no_gui
+ generate_options: qt_gui
hier_block_src_path: '.:'
id: uhd_atsc_capture
max_nouts: '0'
output_language: python
placement: (0,0)
qt_qss_theme: ''
- realtime_scheduling: ''
+ realtime_scheduling: '1'
run: 'True'
run_command: '{python} -u {filename}'
- run_options: run
+ run_options: prompt
sizing_mode: fixed
thread_safe_setters: ''
- title: Receive ATSC from UHD
- window_size: 4000, 4000
+ title: Capture ATSC Channel
states:
- coordinate: [11, 9]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [10, 10]
rotation: 0
state: enabled
blocks:
-- name: antenna
- id: variable
- parameters:
- comment: ''
- value: '"TX/RX"'
- states:
- coordinate: [32, 188.0]
- rotation: 0
- state: enabled
- name: atsc_sym_rate
id: variable
parameters:
comment: ''
value: 4.5e6/286*684
states:
- coordinate: [128, 124.0]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [192, 12.0]
rotation: 0
state: enabled
-- name: duration
- id: variable
+- name: center_freq
+ id: variable_qtgui_entry
parameters:
- comment: ''
- value: '30'
+ comment: Digital Ch 28 - 557MHz
+ gui_hint: 0,0,1,2
+ label: Center Frequency
+ type: real
+ value: 557e6
states:
- coordinate: [424, 188.0]
- rotation: 0
- state: enabled
-- name: freq
- id: variable
- parameters:
- comment: ''
- value: 605e6
- states:
- coordinate: [128, 188.0]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [792, 4.0]
rotation: 0
state: enabled
- name: gain
- id: variable
+ id: variable_qtgui_range
parameters:
comment: ''
- value: '18'
+ gui_hint: 1,0,1,2
+ label: Gain
+ min_len: '200'
+ orient: Qt.Horizontal
+ rangeType: float
+ start: '0'
+ step: '2'
+ stop: '60'
+ value: '46'
+ widget: counter_slider
states:
- coordinate: [232, 188.0]
- rotation: 0
- state: enabled
-- name: oversampled_rate
- id: variable
- parameters:
- comment: ''
- value: atsc_sym_rate*sps
- states:
- coordinate: [248, 124.0]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [656, 4.0]
rotation: 0
state: enabled
- name: sample_rate
id: variable
parameters:
comment: ''
- value: 6.25e6
+ value: atsc_sym_rate*sps
states:
- coordinate: [320, 188.0]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [312, 12.0]
rotation: 0
state: enabled
- name: sps
@@ -98,7 +98,10 @@ blocks:
comment: ''
value: '1.1'
states:
- coordinate: [32, 124.0]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [432, 12.0]
rotation: 0
state: enabled
- name: blocks_file_sink_0
@@ -108,35 +111,23 @@ blocks:
alias: ''
append: 'False'
comment: ''
- file: atsc_iq.sc16
- type: short
+ file: /tmp/atsc_11.8385MSPS.iq
+ type: complex
unbuffered: 'False'
- vlen: '2'
+ vlen: '1'
states:
- coordinate: [600, 324.0]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [336, 276.0]
rotation: 0
- state: enabled
-- name: blocks_head_0
- id: blocks_head
- parameters:
- affinity: ''
- alias: ''
- comment: ''
- maxoutbuf: '0'
- minoutbuf: '0'
- num_items: int(sample_rate*duration)
- type: short
- vlen: '2'
- states:
- coordinate: [352, 340.0]
- rotation: 0
- state: enabled
+ state: true
- name: u
id: uhd_usrp_source
parameters:
affinity: ''
alias: ''
- ant0: antenna
+ ant0: RX2
ant1: ''
ant10: ''
ant11: ''
@@ -200,7 +191,7 @@ blocks:
bw7: '0'
bw8: '0'
bw9: '0'
- center_freq0: freq
+ center_freq0: center_freq
center_freq1: '0'
center_freq10: '0'
center_freq11: '0'
@@ -241,7 +232,11 @@ blocks:
clock_source5: ''
clock_source6: ''
clock_source7: ''
- comment: ''
+ comment: 'Sample rate matches symbol rate to
+
+ avoid interpolation error and no longer
+
+ requires an arbitrary resampler for decoding.'
dc_offs_enb0: '""'
dc_offs_enb1: '""'
dc_offs_enb10: '""'
@@ -274,7 +269,7 @@ blocks:
dc_offs_enb7: '""'
dc_offs_enb8: '""'
dc_offs_enb9: '""'
- dev_addr: '""'
+ dev_addr: '"num_recv_frames=128"'
dev_args: '""'
gain0: gain
gain1: '0'
@@ -441,6 +436,38 @@ blocks:
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: sample_rate
sd_spec0: ''
sd_spec1: ''
@@ -453,7 +480,7 @@ blocks:
show_lo_controls: 'False'
stream_args: ''
stream_chans: '[]'
- sync: sync
+ sync: none
time_source0: ''
time_source1: ''
time_source2: ''
@@ -462,15 +489,98 @@ blocks:
time_source5: ''
time_source6: ''
time_source7: ''
- type: sc16
+ type: fc32
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [32, 116.0]
+ rotation: 0
+ state: enabled
+- name: usrp_freq_sink
+ id: qtgui_freq_sink_x
+ parameters:
+ affinity: ''
+ alias: ''
+ alpha1: '1.0'
+ alpha10: '1.0'
+ alpha2: '1.0'
+ alpha3: '1.0'
+ alpha4: '1.0'
+ alpha5: '1.0'
+ alpha6: '1.0'
+ alpha7: '1.0'
+ alpha8: '1.0'
+ alpha9: '1.0'
+ autoscale: 'False'
+ average: '0.2'
+ axislabels: 'True'
+ bw: sample_rate
+ color1: '"blue"'
+ color10: '"dark blue"'
+ color2: '"red"'
+ color3: '"green"'
+ color4: '"black"'
+ color5: '"cyan"'
+ color6: '"magenta"'
+ color7: '"yellow"'
+ color8: '"dark red"'
+ color9: '"dark green"'
+ comment: ''
+ ctrlpanel: 'False'
+ fc: center_freq
+ fftsize: '2048'
+ freqhalf: 'True'
+ grid: 'True'
+ gui_hint: 3,0,1,4
+ label: Relative Gain
+ label1: RX Signal
+ label10: ''
+ label2: ''
+ label3: ''
+ label4: ''
+ label5: ''
+ label6: ''
+ label7: ''
+ label8: ''
+ label9: ''
+ legend: 'True'
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ name: '"RX Spectrum"'
+ nconnections: '1'
+ showports: 'True'
+ tr_chan: '0'
+ tr_level: '0.0'
+ tr_mode: qtgui.TRIG_MODE_FREE
+ tr_tag: '""'
+ type: complex
+ units: dB
+ update_time: '0.10'
+ width1: '1'
+ width10: '1'
+ width2: '1'
+ width3: '1'
+ width4: '1'
+ width5: '1'
+ width6: '1'
+ width7: '1'
+ width8: '1'
+ width9: '1'
+ wintype: firdes.WIN_BLACKMAN_hARRIS
+ ymax: '-20'
+ ymin: '-100'
states:
- coordinate: [48, 308.0]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [304, 112.0]
rotation: 0
state: enabled
connections:
-- [blocks_head_0, '0', blocks_file_sink_0, '0']
-- [u, '0', blocks_head_0, '0']
+- [u, '0', blocks_file_sink_0, '0']
+- [u, '0', usrp_freq_sink, '0']
metadata:
file_format: 1
diff --git a/gr-dtv/examples/uhd_atsc_tx.grc b/gr-dtv/examples/uhd_atsc_tx.grc
index 359d705199..dd7201a4b6 100644
--- a/gr-dtv/examples/uhd_atsc_tx.grc
+++ b/gr-dtv/examples/uhd_atsc_tx.grc
@@ -1,6 +1,7 @@
options:
parameters:
author: ''
+ catch_exceptions: 'True'
category: Custom
cmake_opt: ''
comment: ''
@@ -22,9 +23,11 @@ options:
sizing_mode: fixed
thread_safe_setters: ''
title: ''
- window_size: 1280, 1024
states:
- coordinate: [368, 19]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [448, 20.0]
rotation: 0
state: enabled
@@ -35,7 +38,10 @@ blocks:
comment: ''
value: 429e6
states:
- coordinate: [808, 20]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [888, 20.0]
rotation: 0
state: enabled
- name: pilot_freq
@@ -44,7 +50,10 @@ blocks:
comment: ''
value: (6000000.0 - (symbol_rate / 2)) / 2
states:
- coordinate: [680, 20]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [760, 20.0]
rotation: 0
state: enabled
- name: symbol_rate
@@ -53,7 +62,10 @@ blocks:
comment: ''
value: 4500000.0 / 286 * 684
states:
- coordinate: [552, 19]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [632, 20.0]
rotation: 0
state: enabled
- name: tx_gain
@@ -71,7 +83,10 @@ blocks:
value: '50'
widget: counter_slider
states:
- coordinate: [808, 88]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [888, 84.0]
rotation: 0
state: enabled
- name: vga1_gain
@@ -89,7 +104,10 @@ blocks:
value: '-8'
widget: counter_slider
states:
- coordinate: [552, 88]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [632, 84.0]
rotation: 0
state: enabled
- name: vga2_gain
@@ -107,7 +125,10 @@ blocks:
value: '10'
widget: counter_slider
states:
- coordinate: [680, 88]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [760, 84.0]
rotation: 0
state: enabled
- name: blocks_file_source_0
@@ -126,6 +147,9 @@ blocks:
type: byte
vlen: '1'
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [64, 19]
rotation: 0
state: enabled
@@ -142,6 +166,9 @@ blocks:
offset: '4'
type: byte
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [88, 468.0]
rotation: 0
state: enabled
@@ -155,6 +182,9 @@ blocks:
minoutbuf: '0'
phase_inc: ((-3000000.0 + pilot_freq) / symbol_rate) * (math.pi * 2)
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [336, 332]
rotation: 0
state: enabled
@@ -170,6 +200,9 @@ blocks:
type: byte
vlen: '1'
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [88, 424.0]
rotation: 180
state: enabled
@@ -182,6 +215,9 @@ blocks:
maxoutbuf: '0'
minoutbuf: '0'
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [88, 376.0]
rotation: 0
state: enabled
@@ -194,6 +230,9 @@ blocks:
maxoutbuf: '0'
minoutbuf: '0'
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [88, 280.0]
rotation: 0
state: enabled
@@ -206,6 +245,9 @@ blocks:
maxoutbuf: '0'
minoutbuf: '0'
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [88, 136.0]
rotation: 180
state: enabled
@@ -218,6 +260,9 @@ blocks:
maxoutbuf: '0'
minoutbuf: '0'
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [88, 184.0]
rotation: 0
state: enabled
@@ -230,6 +275,9 @@ blocks:
maxoutbuf: '0'
minoutbuf: '0'
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [88, 232.0]
rotation: 180
state: enabled
@@ -242,6 +290,9 @@ blocks:
maxoutbuf: '0'
minoutbuf: '0'
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [88, 328.0]
rotation: 180
state: enabled
@@ -260,6 +311,9 @@ blocks:
rate2: C1_5_MEDIUM
rate3: C1_4
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [328, 476.0]
rotation: 0
state: enabled
@@ -277,6 +331,9 @@ blocks:
taps: firdes.root_raised_cosine(0.11, symbol_rate, symbol_rate/2, 0.1152, 200)
type: ccc
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [576, 316]
rotation: 0
state: enabled
@@ -287,9 +344,27 @@ blocks:
comment: ''
imports: import math
states:
- coordinate: [368, 91]
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [448, 92.0]
rotation: 0
state: enabled
+- name: note_0
+ id: note
+ parameters:
+ alias: ''
+ comment: 'This file is available at
+
+ http://www.w6rz.net/advatsc.ts'
+ note: ''
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [264, 20.0]
+ rotation: 0
+ state: true
- name: qtgui_freq_sink_x_0
id: qtgui_freq_sink_x
parameters:
@@ -364,6 +439,9 @@ blocks:
ymax: '10'
ymin: '-140'
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [944, 452.0]
rotation: 0
state: enabled
@@ -637,30 +715,35 @@ blocks:
time_source7: ''
type: fc32
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [944, 276.0]
rotation: 0
state: enabled
- name: virtual_sink_1
id: virtual_sink
parameters:
- affinity: ''
alias: ''
comment: ''
stream_id: mod-rot
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [592, 484.0]
rotation: 0
state: true
- name: virtual_source_1
id: virtual_source
parameters:
- affinity: ''
alias: ''
comment: ''
- maxoutbuf: ''
- minoutbuf: ''
stream_id: mod-rot
states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
coordinate: [336, 276.0]
rotation: 180
state: true
diff --git a/gr-dtv/examples/uhd_rx_atsc.grc b/gr-dtv/examples/uhd_rx_atsc.grc
index c7025bba7b..cb0aa31cc5 100644
--- a/gr-dtv/examples/uhd_rx_atsc.grc
+++ b/gr-dtv/examples/uhd_rx_atsc.grc
@@ -16,14 +16,13 @@ options:
output_language: python
placement: (0,0)
qt_qss_theme: ''
- realtime_scheduling: ''
+ realtime_scheduling: '1'
run: 'True'
run_command: '{python} -u {filename}'
run_options: prompt
sizing_mode: fixed
thread_safe_setters: ''
- title: Receive ATSC from UHD
- window_size: 4000, 4000
+ title: Receive ATSC from USRP
states:
bus_sink: false
bus_source: false
@@ -33,36 +32,6 @@ options:
state: enabled
blocks:
-- name: antenna
- id: variable_qtgui_chooser
- parameters:
- comment: ''
- gui_hint: 1,0,1,1
- label: Antenna
- label0: TX/RX
- label1: RX2
- label2: ''
- label3: ''
- label4: ''
- labels: '[]'
- num_opts: '2'
- option0: TX/RX
- option1: RX2
- option2: '2'
- option3: '3'
- option4: '4'
- options: '[0, 1, 2]'
- orient: Qt.QVBoxLayout
- type: string
- value: TX/RX
- widget: radio_buttons
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [344, 20.0]
- rotation: 0
- state: enabled
- name: atsc_sym_rate
id: variable
parameters:
@@ -72,43 +41,43 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [96, 108.0]
+ coordinate: [192, 12.0]
rotation: 0
state: enabled
-- name: freq
+- name: center_freq
id: variable_qtgui_entry
parameters:
- comment: ''
- gui_hint: 1,1,1,1
- label: Frequency
+ comment: Digital Ch 28 - 557 MHz
+ gui_hint: 0,0,1,2
+ label: Center Frequency
type: real
- value: 605e6
+ value: 557e6
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [520, 20.0]
+ coordinate: [792, 4.0]
rotation: 0
state: enabled
- name: gain
id: variable_qtgui_range
parameters:
comment: ''
- gui_hint: 1,3,1,1
+ gui_hint: 1,0,1,2
label: Gain
min_len: '200'
orient: Qt.Horizontal
rangeType: float
start: '0'
- step: '1'
- stop: '31'
- value: '18'
+ step: '2'
+ stop: '60'
+ value: '46'
widget: counter_slider
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [664, 20.0]
+ coordinate: [656, 4.0]
rotation: 0
state: enabled
- name: oversampled_rate
@@ -120,22 +89,19 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [216, 108.0]
+ coordinate: [432, 12.0]
rotation: 0
state: enabled
- name: sample_rate
- id: variable_qtgui_entry
+ id: variable
parameters:
comment: ''
- gui_hint: 1,2,1,1
- label: Sample Rate
- type: real
- value: 6.25e6
+ value: atsc_sym_rate*sps
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [520, 92.0]
+ coordinate: [312, 12.0]
rotation: 0
state: enabled
- name: sps
@@ -147,7 +113,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [16, 108.0]
+ coordinate: [568, 12.0]
rotation: 0
state: enabled
- name: agc
@@ -167,7 +133,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1144, 204.0]
+ coordinate: [1032, 244.0]
rotation: 0
state: enabled
- name: blocks_file_sink_0
@@ -177,7 +143,7 @@ blocks:
alias: ''
append: 'False'
comment: ''
- file: mpeg.ts
+ file: /tmp/mpeg.live.ts
type: byte
unbuffered: 'False'
vlen: '1'
@@ -185,13 +151,13 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1120, 476.0]
+ coordinate: [832, 668.0]
rotation: 0
state: enabled
- name: dc_blocker_xx_0
id: dc_blocker_xx
parameters:
- affinity: ''
+ affinity: '1'
alias: ''
comment: ''
length: '4096'
@@ -203,41 +169,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [912, 220.0]
- rotation: 0
- state: enabled
-- name: displays
- id: qtgui_tab_widget
- parameters:
- alias: ''
- comment: ''
- gui_hint: 0,0,1,4
- label0: RX Spectrum
- label1: Baseband
- label10: Tab 10
- label11: Tab 11
- label12: Tab 12
- label13: Tab 13
- label14: Tab 14
- label15: Tab 15
- label16: Tab 16
- label17: Tab 17
- label18: Tab 18
- label19: Tab 19
- label2: ''
- label3: Tab 3
- label4: Tab 4
- label5: Tab 5
- label6: Tab 6
- label7: Tab 7
- label8: Tab 8
- label9: Tab 9
- num_tabs: '1'
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [192, 28.0]
+ coordinate: [832, 260.0]
rotation: 0
state: enabled
- name: dtv_atsc_deinterleaver_0
@@ -252,7 +184,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [136, 496.0]
+ coordinate: [120, 608.0]
rotation: 0
state: enabled
- name: dtv_atsc_depad_0
@@ -267,7 +199,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [928, 496.0]
+ coordinate: [752, 608.0]
rotation: 0
state: enabled
- name: dtv_atsc_derandomizer_0
@@ -282,7 +214,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [680, 496.0]
+ coordinate: [568, 608.0]
rotation: 0
state: enabled
- name: dtv_atsc_equalizer_0
@@ -297,7 +229,23 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [848, 360.0]
+ coordinate: [664, 504.0]
+ rotation: 0
+ state: enabled
+- name: dtv_atsc_fpll_0
+ id: dtv_atsc_fpll
+ parameters:
+ affinity: '0'
+ alias: ''
+ comment: Set core affinity for performance
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ rate: oversampled_rate
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [608, 268.0]
rotation: 0
state: enabled
- name: dtv_atsc_fs_checker_0
@@ -312,7 +260,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [568, 360.0]
+ coordinate: [440, 504.0]
rotation: 0
state: enabled
- name: dtv_atsc_rs_decoder_0
@@ -327,7 +275,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [376, 496.0]
+ coordinate: [320, 608.0]
rotation: 0
state: enabled
- name: dtv_atsc_sync_0
@@ -343,94 +291,123 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [320, 356.0]
+ coordinate: [200, 500.0]
rotation: 0
state: enabled
- name: dtv_atsc_viterbi_decoder_0
id: dtv_atsc_viterbi_decoder
parameters:
- affinity: ''
+ affinity: '2'
alias: ''
- comment: ''
+ comment: Set core affinity for performance
maxoutbuf: '0'
minoutbuf: '0'
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1112, 360.0]
+ coordinate: [816, 504.0]
rotation: 0
state: enabled
-- name: fpll
- id: dtv_atsc_fpll
+- name: filter_fft_rrc_filter_0
+ id: filter_fft_rrc_filter
parameters:
affinity: ''
alias: ''
- comment: ''
+ alpha: '0.1152'
+ comment: 'FFT-based filter is less CPU intensive
+
+ for all but the smallest filter tap lengths.'
+ decim: '1'
+ gain: '1'
maxoutbuf: '0'
minoutbuf: '0'
- rate: oversampled_rate
+ ntaps: int((2*8 + 1)*sps)
+ nthreads: '1'
+ samp_rate: sample_rate
+ sym_rate: atsc_sym_rate/2.0
+ type: ccc
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [616, 228.0]
+ coordinate: [272, 228.0]
rotation: 0
- state: enabled
-- name: rx_filter
- id: dtv_atsc_rx_filter
+ state: true
+- name: note_0
+ id: note
parameters:
- affinity: ''
alias: ''
- comment: ''
- maxoutbuf: '0'
- minoutbuf: '0'
- rate: sample_rate
- sps: sps
+ comment: "Past examples with the RX filter use a pfb arb resampler\nthat crushes\
+ \ most CPUs. This approach is optimally tuned\nand only needs an FFT-based\
+ \ RRC and no resampler \nfor better performance."
+ note: ''
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [336, 220.0]
+ coordinate: [856, 380.0]
rotation: 0
- state: enabled
-- name: uhd_usrp_source_0
+ state: true
+- name: note_1
+ id: note
+ parameters:
+ alias: ''
+ comment: "This flowgraph can be adapted to watch the stream live by\ninstalling\
+ \ gr-grnet and using a tcp sink in \"server\" mode.\nYou can then use smplayer\
+ \ to play the stream (vlc doesn't\nwork as well as it doesn't seem to tolerate\
+ \ stream errors\nwell. In smplayer, under options these non-default settings\n\
+ seemed to help with stream viewing:\n- set performance preferences to allow\
+ \ \n frame drops and hard frame drops.\n- Set hardware decoding to auto.\n\
+ - On the cache performance tab Increase stream buffer to 8096.\n\nNOTE: Be patient\
+ \ with the players if there's errors in the signal.\nOn a real TV it may pixelate,\
+ \ but with streaming players they may\nget out of sync and look like they freeze\
+ \ with no video while \nthey're trying to resync with good data."
+ note: ''
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [1024, 516.0]
+ rotation: 0
+ state: true
+- name: u
id: uhd_usrp_source
parameters:
affinity: ''
alias: ''
- ant0: TX/RX
- 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
+ ant0: RX2
+ ant1: ''
+ ant10: ''
+ ant11: ''
+ ant12: ''
+ ant13: ''
+ ant14: ''
+ ant15: ''
+ ant16: ''
+ ant17: ''
+ ant18: ''
+ ant19: ''
+ ant2: ''
+ ant20: ''
+ ant21: ''
+ ant22: ''
+ ant23: ''
+ ant24: ''
+ ant25: ''
+ ant26: ''
+ ant27: ''
+ ant28: ''
+ ant29: ''
+ ant3: ''
+ ant30: ''
+ ant31: ''
+ ant4: ''
+ ant5: ''
+ ant6: ''
+ ant7: ''
+ ant8: ''
+ ant9: ''
bw0: '0'
bw1: '0'
bw10: '0'
@@ -463,7 +440,7 @@ blocks:
bw7: '0'
bw8: '0'
bw9: '0'
- center_freq0: freq
+ center_freq0: center_freq
center_freq1: '0'
center_freq10: '0'
center_freq11: '0'
@@ -495,7 +472,7 @@ blocks:
center_freq7: '0'
center_freq8: '0'
center_freq9: '0'
- clock_rate: 0e0
+ clock_rate: '0.0'
clock_source0: ''
clock_source1: ''
clock_source2: ''
@@ -504,7 +481,11 @@ blocks:
clock_source5: ''
clock_source6: ''
clock_source7: ''
- comment: ''
+ comment: 'Sample rate matches symbol rate to
+
+ avoid interpolation error and no longer
+
+ requires an arbitrary resampler.'
dc_offs_enb0: '""'
dc_offs_enb1: '""'
dc_offs_enb10: '""'
@@ -537,7 +518,7 @@ blocks:
dc_offs_enb7: '""'
dc_offs_enb8: '""'
dc_offs_enb9: '""'
- dev_addr: '"num_recv_frames=128,master_clock_rate=" + str(sample_rate*4)'
+ dev_addr: '"num_recv_frames=128"'
dev_args: '""'
gain0: gain
gain1: '0'
@@ -667,8 +648,8 @@ blocks:
lo_source7: internal
lo_source8: internal
lo_source9: internal
- maxoutbuf: ''
- minoutbuf: ''
+ maxoutbuf: '0'
+ minoutbuf: '0'
nchan: '1'
norm_gain0: 'False'
norm_gain1: 'False'
@@ -704,7 +685,7 @@ blocks:
norm_gain9: 'False'
num_mboards: '1'
otw: ''
- rx_agc0: Default
+ rx_agc0: Disabled
rx_agc1: Default
rx_agc10: Default
rx_agc11: Default
@@ -762,9 +743,9 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [40, 180.0]
+ coordinate: [32, 116.0]
rotation: 0
- state: true
+ state: enabled
- name: usrp_freq_sink
id: qtgui_freq_sink_x
parameters:
@@ -780,7 +761,7 @@ blocks:
alpha7: '1.0'
alpha8: '1.0'
alpha9: '1.0'
- autoscale: 'True'
+ autoscale: 'False'
average: '0.2'
axislabels: 'True'
bw: sample_rate
@@ -796,13 +777,13 @@ blocks:
color9: '"dark green"'
comment: ''
ctrlpanel: 'False'
- fc: freq
- fftsize: '4096'
+ fc: center_freq
+ fftsize: '2048'
freqhalf: 'True'
grid: 'True'
- gui_hint: displays@0
+ gui_hint: 3,0,1,4
label: Relative Gain
- label1: ''
+ label1: RX Signal
label10: ''
label2: ''
label3: ''
@@ -836,85 +817,31 @@ blocks:
width8: '1'
width9: '1'
wintype: firdes.WIN_BLACKMAN_hARRIS
- ymax: '10'
- ymin: '-140'
+ ymax: '-20'
+ ymin: '-100'
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [40, 332.0]
- rotation: 180
+ coordinate: [304, 112.0]
+ rotation: 0
state: enabled
-- name: virtual_sink_0
- id: virtual_sink
- parameters:
- alias: ''
- comment: ''
- stream_id: agc-sync
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [1136, 300.0]
- rotation: 180
- state: true
-- name: virtual_sink_1
- id: virtual_sink
- parameters:
- alias: ''
- comment: ''
- stream_id: viterbi-deint
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [1120, 404.0]
- rotation: 180
- state: true
-- name: virtual_source_0
- id: virtual_source
- parameters:
- alias: ''
- comment: ''
- stream_id: viterbi-deint
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [136, 444.0]
- rotation: 180
- state: true
-- name: virtual_source_2
- id: virtual_source
- parameters:
- alias: ''
- comment: ''
- stream_id: agc-sync
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [320, 300.0]
- rotation: 180
- state: true
connections:
-- [agc, '0', virtual_sink_0, '0']
+- [agc, '0', dtv_atsc_sync_0, '0']
- [dc_blocker_xx_0, '0', agc, '0']
- [dtv_atsc_deinterleaver_0, '0', dtv_atsc_rs_decoder_0, '0']
- [dtv_atsc_depad_0, '0', blocks_file_sink_0, '0']
- [dtv_atsc_derandomizer_0, '0', dtv_atsc_depad_0, '0']
- [dtv_atsc_equalizer_0, '0', dtv_atsc_viterbi_decoder_0, '0']
+- [dtv_atsc_fpll_0, '0', dc_blocker_xx_0, '0']
- [dtv_atsc_fs_checker_0, '0', dtv_atsc_equalizer_0, '0']
- [dtv_atsc_rs_decoder_0, '0', dtv_atsc_derandomizer_0, '0']
- [dtv_atsc_sync_0, '0', dtv_atsc_fs_checker_0, '0']
-- [dtv_atsc_viterbi_decoder_0, '0', virtual_sink_1, '0']
-- [fpll, '0', dc_blocker_xx_0, '0']
-- [rx_filter, '0', fpll, '0']
-- [uhd_usrp_source_0, '0', rx_filter, '0']
-- [uhd_usrp_source_0, '0', usrp_freq_sink, '0']
-- [virtual_source_0, '0', dtv_atsc_deinterleaver_0, '0']
-- [virtual_source_2, '0', dtv_atsc_sync_0, '0']
+- [dtv_atsc_viterbi_decoder_0, '0', dtv_atsc_deinterleaver_0, '0']
+- [filter_fft_rrc_filter_0, '0', dtv_atsc_fpll_0, '0']
+- [u, '0', filter_fft_rrc_filter_0, '0']
+- [u, '0', usrp_freq_sink, '0']
metadata:
file_format: 1
diff --git a/gr-dtv/lib/atsc/atsc_fpll_impl.cc b/gr-dtv/lib/atsc/atsc_fpll_impl.cc
index 71f24713ac..b85a38207d 100644
--- a/gr-dtv/lib/atsc/atsc_fpll_impl.cc
+++ b/gr-dtv/lib/atsc/atsc_fpll_impl.cc
@@ -41,32 +41,39 @@ int atsc_fpll_impl::work(int noutput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items)
{
+ constexpr float alpha = 0.01;
+ constexpr float beta = alpha * alpha / 4.0;
+
const gr_complex* in = (const gr_complex*)input_items[0];
float* out = (float*)output_items[0];
+ float a_cos, a_sin;
+ float x;
+ gr_complex result, filtered;
for (int k = 0; k < noutput_items; k++) {
- float a_cos, a_sin;
-
d_nco.step(); // increment phase
d_nco.sincos(&a_sin, &a_cos); // compute cos and sin
// Mix out carrier and output I-only signal
- gr_complex result = in[k] * gr_complex(a_sin, a_cos);
+
+ // PR Merge Note: Once the Costas Optimization PR #3076 merges, this
+ // line below helps with performance when cx_limited_range is not available
+ // such as on Macs and Windows. Once the merge happens I'll push an update.
+ // gr::fast_cc_multiply(result, in[k], gr_complex(a_sin, a_cos));
+ result = in[k] * gr_complex(a_sin, a_cos);
+
out[k] = result.real();
// Update phase/freq error
- gr_complex filtered = d_afc.filter(result);
- float x = gr::fast_atan2f(filtered.imag(), filtered.real());
+ filtered = d_afc.filter(result);
+ x = gr::fast_atan2f(filtered.imag(), filtered.real());
// avoid slamming filter with big transitions
- static const float limit = GR_M_PI / 2.0;
- if (x > limit)
- x = limit;
- else if (x < -limit)
- x = -limit;
-
- static const float alpha = 0.01;
- static const float beta = alpha * alpha / 4.0;
+ if (x > M_PI_2)
+ x = M_PI_2;
+ else if (x < -M_PI_2)
+ x = -M_PI_2;
+
d_nco.adjust_phase(alpha * x);
d_nco.adjust_freq(beta * x);
}