diff options
author | ghostop14 <ghostop14@gmail.com> | 2020-02-01 13:02:34 -0500 |
---|---|---|
committer | devnulling <devnulling@users.noreply.github.com> | 2020-02-04 09:08:55 -0800 |
commit | 90c8e30e87c935176224728d2a28709cb6a7adab (patch) | |
tree | 4a97b486b018e3de13962c08aba0e3f35a77fd15 /gr-dtv | |
parent | 5b38e99298d47da94e4436d810db550d9e7e4520 (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.grc | 258 | ||||
-rw-r--r-- | gr-dtv/examples/uhd_atsc_tx.grc | 109 | ||||
-rw-r--r-- | gr-dtv/examples/uhd_rx_atsc.grc | 385 | ||||
-rw-r--r-- | gr-dtv/lib/atsc/atsc_fpll_impl.cc | 33 |
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); } |