summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt9
-rw-r--r--cmake/Modules/GrBuildTypes.cmake158
-rw-r--r--gnuradio-runtime/python/gnuradio/__init__.py1
-rw-r--r--gr-dtv/CMakeLists.txt108
-rw-r--r--gr-dtv/apps/CMakeLists.txt29
-rw-r--r--gr-dtv/doc/CMakeLists.txt23
-rw-r--r--gr-dtv/doc/README.dtv13
-rw-r--r--gr-dtv/examples/CMakeLists.txt26
-rw-r--r--gr-dtv/examples/file_atsc_rx.grc485
-rw-r--r--gr-dtv/examples/uhd_atsc_capture.grc1076
-rw-r--r--gr-dtv/examples/uhd_rx_atsc.grc1976
-rw-r--r--gr-dtv/gnuradio-dtv.pc.in11
-rw-r--r--gr-dtv/grc/CMakeLists.txt35
-rw-r--r--gr-dtv/grc/dtv_atsc_deinterleaver.xml25
-rw-r--r--gr-dtv/grc/dtv_atsc_depad.xml24
-rw-r--r--gr-dtv/grc/dtv_atsc_derandomizer.xml25
-rw-r--r--gr-dtv/grc/dtv_atsc_equalizer.xml25
-rw-r--r--gr-dtv/grc/dtv_atsc_fpll.xml29
-rw-r--r--gr-dtv/grc/dtv_atsc_fs_checker.xml25
-rw-r--r--gr-dtv/grc/dtv_atsc_rs_decoder.xml25
-rw-r--r--gr-dtv/grc/dtv_atsc_rx.xml35
-rw-r--r--gr-dtv/grc/dtv_atsc_rx_filter.xml35
-rw-r--r--gr-dtv/grc/dtv_atsc_sync.xml30
-rw-r--r--gr-dtv/grc/dtv_atsc_viterbi_decoder.xml25
-rw-r--r--gr-dtv/grc/dtv_block_tree.xml48
-rw-r--r--gr-dtv/include/gnuradio/dtv/CMakeLists.txt37
-rw-r--r--gr-dtv/include/gnuradio/dtv/api.h33
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_consts.h47
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_deinterleaver.h54
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_depad.h54
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_derandomizer.h54
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_equalizer.h53
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_fpll.h70
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_fs_checker.h53
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_rs_decoder.h53
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_sync.h55
-rw-r--r--gr-dtv/include/gnuradio/dtv/atsc_viterbi_decoder.h53
-rw-r--r--gr-dtv/lib/CMakeLists.txt104
-rw-r--r--gr-dtv/lib/atsc/atsc_deinterleaver_impl.cc97
-rw-r--r--gr-dtv/lib/atsc/atsc_deinterleaver_impl.h75
-rw-r--r--gr-dtv/lib/atsc/atsc_depad_impl.cc66
-rw-r--r--gr-dtv/lib/atsc/atsc_depad_impl.h45
-rw-r--r--gr-dtv/lib/atsc/atsc_derandomizer_impl.cc79
-rw-r--r--gr-dtv/lib/atsc/atsc_derandomizer_impl.h48
-rw-r--r--gr-dtv/lib/atsc/atsc_equalizer_impl.cc183
-rw-r--r--gr-dtv/lib/atsc/atsc_equalizer_impl.h71
-rw-r--r--gr-dtv/lib/atsc/atsc_fake_single_viterbi.cc72
-rw-r--r--gr-dtv/lib/atsc/atsc_fake_single_viterbi.h52
-rw-r--r--gr-dtv/lib/atsc/atsc_fpll_impl.cc95
-rw-r--r--gr-dtv/lib/atsc/atsc_fpll_impl.h53
-rw-r--r--gr-dtv/lib/atsc/atsc_fs_checker_impl.cc128
-rw-r--r--gr-dtv/lib/atsc/atsc_fs_checker_impl.h67
-rw-r--r--gr-dtv/lib/atsc/atsc_interleaver_fifo.h86
-rw-r--r--gr-dtv/lib/atsc/atsc_pnXXX_impl.h59
-rw-r--r--gr-dtv/lib/atsc/atsc_randomize.cc117
-rw-r--r--gr-dtv/lib/atsc/atsc_randomize.h92
-rw-r--r--gr-dtv/lib/atsc/atsc_rs_decoder_impl.cc131
-rw-r--r--gr-dtv/lib/atsc/atsc_rs_decoder_impl.h62
-rw-r--r--gr-dtv/lib/atsc/atsc_single_viterbi.cc123
-rw-r--r--gr-dtv/lib/atsc/atsc_single_viterbi.h60
-rw-r--r--gr-dtv/lib/atsc/atsc_syminfo_impl.h62
-rw-r--r--gr-dtv/lib/atsc/atsc_sync_impl.cc196
-rw-r--r--gr-dtv/lib/atsc/atsc_sync_impl.h83
-rw-r--r--gr-dtv/lib/atsc/atsc_types.h269
-rw-r--r--gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc139
-rw-r--r--gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.h76
-rw-r--r--gr-dtv/lib/atsc/atsc_viterbi_gen.cc267
-rw-r--r--gr-dtv/lib/atsc/interleaver_fifo.h84
-rw-r--r--gr-dtv/lib/gnuradio-dtv.rc.in55
-rw-r--r--gr-dtv/python/dtv/CMakeLists.txt50
-rw-r--r--gr-dtv/python/dtv/__init__.py37
-rw-r--r--gr-dtv/python/dtv/atsc_rx.py70
-rw-r--r--gr-dtv/python/dtv/atsc_rx_filter.py55
-rwxr-xr-xgr-dtv/python/dtv/qa_dtv.py37
-rw-r--r--gr-dtv/swig/CMakeLists.txt56
-rw-r--r--gr-dtv/swig/dtv_swig.i60
76 files changed, 8476 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 145fb9a3bd..7accbdc7ae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,14 +29,18 @@ cmake_minimum_required(VERSION 2.6)
project(gnuradio CXX C)
enable_testing()
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
+
+include(GrBuildTypes)
+
#select the release build type by default to get optimization flags
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
message(STATUS "Build type not specified: defaulting to release.")
endif(NOT CMAKE_BUILD_TYPE)
+GR_CHECK_BUILD_TYPE(${CMAKE_BUILD_TYPE})
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
-
-list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
+message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
# Set the version information here
set(VERSION_INFO_MAJOR_VERSION 3)
@@ -320,6 +324,7 @@ add_subdirectory(gr-fft)
add_subdirectory(gr-filter)
add_subdirectory(gr-analog)
add_subdirectory(gr-digital)
+add_subdirectory(gr-dtv)
add_subdirectory(gr-atsc)
add_subdirectory(gr-audio)
add_subdirectory(gr-comedi)
diff --git a/cmake/Modules/GrBuildTypes.cmake b/cmake/Modules/GrBuildTypes.cmake
new file mode 100644
index 0000000000..aa59d0089f
--- /dev/null
+++ b/cmake/Modules/GrBuildTypes.cmake
@@ -0,0 +1,158 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+if(DEFINED __INCLUDED_GR_BUILD_TYPES_CMAKE)
+ return()
+endif()
+set(__INCLUDED_GR_BUILD_TYPES_CMAKE TRUE)
+
+# Standard CMake Build Types and their basic CFLAGS:
+# - None: nothing set
+# - Debug: -O2 -g
+# - Release: -O3
+# - RelWithDebInfo: -O3 -g
+# - MinSizeRel: -OS
+
+# Addtional Build Types, defined below:
+# - NoOptWithASM: -O0 -g -save-temps
+# - O2WithASM: -O2 -g -save-temps
+# - O3WithASM: -O3 -g -save-temps
+
+# Defines the list of acceptable cmake build types. When adding a new
+# build type below, make sure to add it to this list.
+list(APPEND AVAIL_BUILDTYPES
+ None Debug Release RelWithDebInfo MinSizeRel
+ NoOptWithASM O2WithASM O3WithASM
+)
+
+########################################################################
+# GR_CHECK_BUILD_TYPE(build type)
+#
+# Use this to check that the build type set in CMAKE_BUILD_TYPE on the
+# commandline is one of the valid build types used by this project. It
+# checks the value set in the cmake interface against the list of
+# known build types in AVAIL_BUILDTYPES. If the build type is found,
+# the function exits immediately. If nothing is found by the end of
+# checking all available build types, we exit with an error and list
+# the avialable build types.
+########################################################################
+function(GR_CHECK_BUILD_TYPE settype)
+ foreach(btype ${AVAIL_BUILDTYPES})
+ if(${settype} STREQUAL ${btype})
+ return() # found it; exit cleanly
+ endif(${settype} STREQUAL ${btype})
+ endforeach(btype)
+ # Build type not found; error out
+ message(FATAL_ERROR "Build type '${settype}' not valid, must be one of: ${AVAIL_BUILDTYPES}")
+endfunction(GR_CHECK_BUILD_TYPE)
+
+########################################################################
+# For GCC and Clang, we can set a build type:
+#
+# -DCMAKE_BUILD_TYPE=NoOptWithASM
+#
+# This type uses no optimization (-O0), outputs debug symbols (-g) and
+# outputs all intermediary files the build system produces, including
+# all assembly (.s) files. Look in the build directory for these
+# files.
+# NOTE: This is not defined on Windows systems.
+########################################################################
+if(NOT WIN32)
+ SET(CMAKE_CXX_FLAGS_NOOPTWITHASM "-Wall -save-temps -g -O0" CACHE STRING
+ "Flags used by the C++ compiler during NoOptWithASM builds." FORCE)
+ SET(CMAKE_C_FLAGS_NOOPTWITHASM "-Wall -save-temps -g -O0" CACHE STRING
+ "Flags used by the C compiler during NoOptWithASM builds." FORCE)
+ SET(CMAKE_EXE_LINKER_FLAGS_NOOPTWITHASM
+ "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+ "Flags used for linking binaries during NoOptWithASM builds." FORCE)
+ SET(CMAKE_SHARED_LINKER_FLAGS_NOOPTWITHASM
+ "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+ "Flags used by the shared lib linker during NoOptWithASM builds." FORCE)
+
+ MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_NOOPTWITHASM
+ CMAKE_C_FLAGS_NOOPTWITHASM
+ CMAKE_EXE_LINKER_FLAGS_NOOPTWITHASM
+ CMAKE_SHARED_LINKER_FLAGS_NOOPTWITHASM)
+endif(NOT WIN32)
+
+
+
+########################################################################
+# For GCC and Clang, we can set a build type:
+#
+# -DCMAKE_BUILD_TYPE=O2WithASM
+#
+# This type uses level 2 optimization (-O2), outputs debug symbols
+# (-g) and outputs all intermediary files the build system produces,
+# including all assembly (.s) files. Look in the build directory for
+# these files.
+# NOTE: This is not defined on Windows systems.
+########################################################################
+
+if(NOT WIN32)
+ SET(CMAKE_CXX_FLAGS_O2WITHASM "-Wall -save-temps -g -O2" CACHE STRING
+ "Flags used by the C++ compiler during O2WithASM builds." FORCE)
+ SET(CMAKE_C_FLAGS_O2WITHASM "-Wall -save-temps -g -O2" CACHE STRING
+ "Flags used by the C compiler during O2WithASM builds." FORCE)
+ SET(CMAKE_EXE_LINKER_FLAGS_O2WITHASM
+ "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+ "Flags used for linking binaries during O2WithASM builds." FORCE)
+ SET(CMAKE_SHARED_LINKER_FLAGS_O2WITHASM
+ "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+ "Flags used by the shared lib linker during O2WithASM builds." FORCE)
+
+ MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_O2WITHASM
+ CMAKE_C_FLAGS_O2WITHASM
+ CMAKE_EXE_LINKER_FLAGS_O2WITHASM
+ CMAKE_SHARED_LINKER_FLAGS_O2WITHASM)
+endif(NOT WIN32)
+
+
+########################################################################
+# For GCC and Clang, we can set a build type:
+#
+# -DCMAKE_BUILD_TYPE=O3WithASM
+#
+# This type uses level 3 optimization (-O3), outputs debug symbols
+# (-g) and outputs all intermediary files the build system produces,
+# including all assembly (.s) files. Look in the build directory for
+# these files.
+# NOTE: This is not defined on Windows systems.
+########################################################################
+
+if(NOT WIN32)
+ SET(CMAKE_CXX_FLAGS_O3WITHASM "-Wall -save-temps -g -O3" CACHE STRING
+ "Flags used by the C++ compiler during O3WithASM builds." FORCE)
+ SET(CMAKE_C_FLAGS_O3WITHASM "-Wall -save-temps -g -O3" CACHE STRING
+ "Flags used by the C compiler during O3WithASM builds." FORCE)
+ SET(CMAKE_EXE_LINKER_FLAGS_O3WITHASM
+ "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+ "Flags used for linking binaries during O3WithASM builds." FORCE)
+ SET(CMAKE_SHARED_LINKER_FLAGS_O3WITHASM
+ "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+ "Flags used by the shared lib linker during O3WithASM builds." FORCE)
+
+ MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_O3WITHASM
+ CMAKE_C_FLAGS_O3WITHASM
+ CMAKE_EXE_LINKER_FLAGS_O3WITHASM
+ CMAKE_SHARED_LINKER_FLAGS_O3WITHASM)
+endif(NOT WIN32)
diff --git a/gnuradio-runtime/python/gnuradio/__init__.py b/gnuradio-runtime/python/gnuradio/__init__.py
index 39886272de..dd7b89650b 100644
--- a/gnuradio-runtime/python/gnuradio/__init__.py
+++ b/gnuradio-runtime/python/gnuradio/__init__.py
@@ -32,6 +32,7 @@ if path.endswith(path_ending):
__path__.append(os.path.join(build_path, 'gr-filter', 'python'))
__path__.append(os.path.join(build_path, 'gr-fft', 'python'))
__path__.append(os.path.join(build_path, 'gr-analog', 'python'))
+ __path__.append(os.path.join(build_path, 'gr-dtv', 'python'))
__path__.append(os.path.join(build_path, 'gr-trellis', 'python'))
__path__.append(os.path.join(build_path, 'gr-wavelet', 'python'))
__path__.append(os.path.join(build_path, 'gr-audio', 'python'))
diff --git a/gr-dtv/CMakeLists.txt b/gr-dtv/CMakeLists.txt
new file mode 100644
index 0000000000..bccfff7886
--- /dev/null
+++ b/gr-dtv/CMakeLists.txt
@@ -0,0 +1,108 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# Setup dependencies
+########################################################################
+include(GrBoost)
+
+########################################################################
+# Register component
+########################################################################
+include(GrComponent)
+
+GR_REGISTER_COMPONENT("gr-dtv" ENABLE_GR_DTV
+ Boost_FOUND
+ ENABLE_GNURADIO_RUNTIME
+)
+
+GR_SET_GLOBAL(GR_DTV_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_BINARY_DIR}/lib
+)
+
+########################################################################
+# Begin conditional configuration
+########################################################################
+if(ENABLE_GR_DTV)
+
+########################################################################
+# Setup CPack components
+########################################################################
+include(GrPackage)
+CPACK_SET(CPACK_COMPONENT_GROUP_DTV_DESCRIPTION "GNU Radio DTV Blocks")
+
+CPACK_COMPONENT("dtv_runtime"
+ GROUP "DTV"
+ DISPLAY_NAME "Runtime"
+ DESCRIPTION "Runtime"
+ DEPENDS "runtime_runtime"
+)
+
+CPACK_COMPONENT("dtv_devel"
+ GROUP "DTV"
+ DISPLAY_NAME "Development"
+ DESCRIPTION "C++ headers, package config, import libraries"
+ DEPENDS "runtime_devel"
+)
+
+CPACK_COMPONENT("dtv_python"
+ GROUP "DTV"
+ DISPLAY_NAME "Python"
+ DESCRIPTION "Python modules for runtime; GRC xml files"
+ DEPENDS "runtime_python;dtv_runtime"
+)
+
+CPACK_COMPONENT("dtv_swig"
+ GROUP "DTV"
+ DISPLAY_NAME "SWIG"
+ DESCRIPTION "SWIG development .i files"
+ DEPENDS "runtime_swig;dtv_python;dtv_devel"
+)
+
+########################################################################
+# Add subdirectories
+########################################################################
+add_subdirectory(include/gnuradio/dtv)
+add_subdirectory(lib)
+if(ENABLE_PYTHON)
+ add_subdirectory(swig)
+ add_subdirectory(python/dtv)
+ add_subdirectory(grc)
+ add_subdirectory(examples)
+ add_subdirectory(apps)
+endif(ENABLE_PYTHON)
+add_subdirectory(doc)
+
+########################################################################
+# Create Pkg Config File
+########################################################################
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-dtv.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-dtv.pc
+@ONLY)
+
+install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-dtv.pc
+ DESTINATION ${GR_LIBRARY_DIR}/pkgconfig
+ COMPONENT "dtv_devel"
+)
+
+endif(ENABLE_GR_DTV)
diff --git a/gr-dtv/apps/CMakeLists.txt b/gr-dtv/apps/CMakeLists.txt
new file mode 100644
index 0000000000..f328234e3d
--- /dev/null
+++ b/gr-dtv/apps/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+########################################################################
+# Install some dtv apps
+########################################################################
+GR_PYTHON_INSTALL(
+ PROGRAMS
+ DESTINATION ${GR_RUNTIME_DIR}
+ COMPONENT "dtv_python"
+)
diff --git a/gr-dtv/doc/CMakeLists.txt b/gr-dtv/doc/CMakeLists.txt
new file mode 100644
index 0000000000..b21afa8abf
--- /dev/null
+++ b/gr-dtv/doc/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+install(
+ FILES README.dtv
+ DESTINATION ${GR_PKG_DOC_DIR}
+)
diff --git a/gr-dtv/doc/README.dtv b/gr-dtv/doc/README.dtv
new file mode 100644
index 0000000000..23639f0269
--- /dev/null
+++ b/gr-dtv/doc/README.dtv
@@ -0,0 +1,13 @@
+This is the GNU Radio DTV package. It contains the blocks that
+implement various digital television standards.
+
+To use the DTV blocks, the Python namespaces is in gnuradio.dtv, which
+would be normally imported as:
+
+ from gnuradio import dtv
+
+See the Doxygen documentation for details about the blocks available
+in this package. A quick listing of the details can be found in Python
+after importing by using:
+
+ help(dtv)
diff --git a/gr-dtv/examples/CMakeLists.txt b/gr-dtv/examples/CMakeLists.txt
new file mode 100644
index 0000000000..82b663d924
--- /dev/null
+++ b/gr-dtv/examples/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+GR_PYTHON_INSTALL(
+ PROGRAMS
+ DESTINATION ${GR_PKG_DTV_EXAMPLES_DIR}
+ COMPONENT "dtv_python"
+)
diff --git a/gr-dtv/examples/file_atsc_rx.grc b/gr-dtv/examples/file_atsc_rx.grc
new file mode 100644
index 0000000000..c75f45d3fc
--- /dev/null
+++ b/gr-dtv/examples/file_atsc_rx.grc
@@ -0,0 +1,485 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Tue Jul 22 14:34:09 2014</timestamp>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>atsc_sym_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>4.5e6/286*684</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(94, 115)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>sample_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>6.25e6</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(278, 200)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>duration</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(381, 198)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>gain</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>18</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(205, 200)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>freq</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>605e6</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(117, 201)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>antenna</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>"TX/RX"</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(27, 201)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>sps</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>1.1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(20, 115)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>oversampled_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>atsc_sym_rate*sps</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(207, 115)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>file_atsc_rx</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Receive ATSC from UHD</value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>4000, 4000</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>no_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>run</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(11, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_interleaved_short_to_complex</key>
+ <param>
+ <key>id</key>
+ <value>blocks_interleaved_short_to_complex_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vector_input</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>swap</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(206, 337)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_rx</key>
+ <param>
+ <key>id</key>
+ <value>dtv_atsc_rx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>rate</key>
+ <value>sample_rate</value>
+ </param>
+ <param>
+ <key>sps</key>
+ <value>1.5</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(398, 329)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_file_sink</key>
+ <param>
+ <key>id</key>
+ <value>blocks_file_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>file</key>
+ <value>mpeg.ts</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>unbuffered</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>append</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(605, 321)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_file_source</key>
+ <param>
+ <key>id</key>
+ <value>blocks_file_source_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>file</key>
+ <value>atsc_iq.sc16</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>short</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(33, 329)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>blocks_file_source_0</source_block_id>
+ <sink_block_id>blocks_interleaved_short_to_complex_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_interleaved_short_to_complex_0</source_block_id>
+ <sink_block_id>dtv_atsc_rx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_atsc_rx_0</source_block_id>
+ <sink_block_id>blocks_file_sink_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-dtv/examples/uhd_atsc_capture.grc b/gr-dtv/examples/uhd_atsc_capture.grc
new file mode 100644
index 0000000000..eb341bfe52
--- /dev/null
+++ b/gr-dtv/examples/uhd_atsc_capture.grc
@@ -0,0 +1,1076 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Tue Jul 22 14:30:13 2014</timestamp>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>atsc_sym_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>4.5e6/286*684</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(94, 115)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>sample_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>6.25e6</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(278, 200)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>duration</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(381, 198)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>gain</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>18</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(205, 200)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>freq</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>605e6</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(117, 201)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>antenna</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>"TX/RX"</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(27, 201)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>sps</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>1.1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(20, 115)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>oversampled_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>atsc_sym_rate*sps</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(207, 115)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>uhd_usrp_source</key>
+ <param>
+ <key>id</key>
+ <value>u</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>sc16</value>
+ </param>
+ <param>
+ <key>otw</key>
+ <value></value>
+ </param>
+ <param>
+ <key>stream_args</key>
+ <value></value>
+ </param>
+ <param>
+ <key>stream_chans</key>
+ <value>[]</value>
+ </param>
+ <param>
+ <key>dev_addr</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>dev_args</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>sync</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_rate</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>num_mboards</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>clock_source0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>nchan</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>sample_rate</value>
+ </param>
+ <param>
+ <key>center_freq0</key>
+ <value>freq</value>
+ </param>
+ <param>
+ <key>gain0</key>
+ <value>gain</value>
+ </param>
+ <param>
+ <key>ant0</key>
+ <value>antenna</value>
+ </param>
+ <param>
+ <key>bw0</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant11</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant12</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant13</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant14</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant15</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant16</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant17</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant18</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant19</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant20</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant21</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant22</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant23</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant24</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant25</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant26</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant27</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant28</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant29</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant30</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant31</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(43, 319)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_head</key>
+ <param>
+ <key>id</key>
+ <value>blocks_head_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>short</value>
+ </param>
+ <param>
+ <key>num_items</key>
+ <value>int(sample_rate*duration)</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(294, 335)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_file_sink</key>
+ <param>
+ <key>id</key>
+ <value>blocks_file_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>file</key>
+ <value>atsc_iq.sc16</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>short</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>unbuffered</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>append</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(464, 319)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>uhd_atsc_capture</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Receive ATSC from UHD</value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>4000, 4000</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>no_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>run</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(11, 9)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>u</source_block_id>
+ <sink_block_id>blocks_head_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_head_0</source_block_id>
+ <sink_block_id>blocks_file_sink_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-dtv/examples/uhd_rx_atsc.grc b/gr-dtv/examples/uhd_rx_atsc.grc
new file mode 100644
index 0000000000..4ff6c90716
--- /dev/null
+++ b/gr-dtv/examples/uhd_rx_atsc.grc
@@ -0,0 +1,1976 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Tue Jul 22 12:06:50 2014</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>uhd_rx_atsc</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Receive ATSC from UHD</value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>4000, 4000</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>qt_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>oversampled_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>atsc_sym_rate*sps</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(207, 115)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>atsc_sym_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>4.5e6/286*684</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(94, 115)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>sps</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>1.1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(20, 115)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_tab_widget</key>
+ <param>
+ <key>id</key>
+ <value>displays</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>num_tabs</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>label0</key>
+ <value>RX Spectrum</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value>Baseband</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value>Tab 3</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value>Tab 4</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value>0,0,1,4</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(191, 28)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_chooser</key>
+ <param>
+ <key>id</key>
+ <value>antenna</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Antenna</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>string</value>
+ </param>
+ <param>
+ <key>num_opts</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>TX/RX</value>
+ </param>
+ <param>
+ <key>options</key>
+ <value>[0, 1, 2]</value>
+ </param>
+ <param>
+ <key>labels</key>
+ <value>[]</value>
+ </param>
+ <param>
+ <key>option0</key>
+ <value>TX/RX</value>
+ </param>
+ <param>
+ <key>label0</key>
+ <value>TX/RX</value>
+ </param>
+ <param>
+ <key>option1</key>
+ <value>RX2</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value>RX2</value>
+ </param>
+ <param>
+ <key>option2</key>
+ <value>2</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>option3</key>
+ <value>3</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>option4</key>
+ <value>4</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>widget</key>
+ <value>radio_buttons</value>
+ </param>
+ <param>
+ <key>orient</key>
+ <value>Qt.QVBoxLayout</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value>1,0,1,1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(342, 20)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_entry</key>
+ <param>
+ <key>id</key>
+ <value>sample_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Sample Rate</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>real</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>6.25e6</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value>1,2,1,1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(486, 104)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_range</key>
+ <param>
+ <key>id</key>
+ <value>gain</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Gain</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>18</value>
+ </param>
+ <param>
+ <key>start</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>stop</key>
+ <value>31</value>
+ </param>
+ <param>
+ <key>step</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>widget</key>
+ <value>counter_slider</value>
+ </param>
+ <param>
+ <key>orient</key>
+ <value>Qt.Horizontal</value>
+ </param>
+ <param>
+ <key>min_len</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value>1,3,1,1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(621, 20)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_file_sink</key>
+ <param>
+ <key>id</key>
+ <value>blocks_file_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>file</key>
+ <value>mpeg.ts</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>unbuffered</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>append</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1055, 497)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_qtgui_entry</key>
+ <param>
+ <key>id</key>
+ <value>freq</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Frequency</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>real</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>605e6</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value>1,1,1,1</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(487, 18)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>analog_agc_xx</key>
+ <param>
+ <key>id</key>
+ <value>agc</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>rate</key>
+ <value>1e-5</value>
+ </param>
+ <param>
+ <key>reference</key>
+ <value>4.0</value>
+ </param>
+ <param>
+ <key>gain</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>max_gain</key>
+ <value>65536</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(860, 318)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_fpll</key>
+ <param>
+ <key>id</key>
+ <value>fpll</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>rate</key>
+ <value>oversampled_rate</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(500, 342)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dc_blocker_xx</key>
+ <param>
+ <key>id</key>
+ <value>dc_blocker_xx_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>ff</value>
+ </param>
+ <param>
+ <key>length</key>
+ <value>4096</value>
+ </param>
+ <param>
+ <key>long_form</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(703, 334)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_equalizer</key>
+ <param>
+ <key>id</key>
+ <value>dtv_atsc_equalizer_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(684, 433)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_fs_checker</key>
+ <param>
+ <key>id</key>
+ <value>dtv_atsc_fs_checker_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(465, 433)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_sync</key>
+ <param>
+ <key>id</key>
+ <value>dtv_atsc_sync_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>rate</key>
+ <value>oversampled_rate</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(272, 429)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_viterbi_decoder</key>
+ <param>
+ <key>id</key>
+ <value>dtv_atsc_viterbi_decoder_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(859, 433)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_depad</key>
+ <param>
+ <key>id</key>
+ <value>dtv_atsc_depad_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(876, 517)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_derandomizer</key>
+ <param>
+ <key>id</key>
+ <value>dtv_atsc_derandomizer_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(694, 517)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_rs_decoder</key>
+ <param>
+ <key>id</key>
+ <value>dtv_atsc_rs_decoder_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(456, 517)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_deinterleaver</key>
+ <param>
+ <key>id</key>
+ <value>dtv_atsc_deinterleaver_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(276, 517)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>dtv_atsc_rx_filter</key>
+ <param>
+ <key>id</key>
+ <value>rx_filter</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>rate</key>
+ <value>sample_rate</value>
+ </param>
+ <param>
+ <key>sps</key>
+ <value>sps</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(286, 334)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>qtgui_freq_sink_x</key>
+ <param>
+ <key>id</key>
+ <value>usrp_freq_sink</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>name</key>
+ <value>"RX Spectrum"</value>
+ </param>
+ <param>
+ <key>fftsize</key>
+ <value>4096</value>
+ </param>
+ <param>
+ <key>wintype</key>
+ <value>firdes.WIN_BLACKMAN_hARRIS</value>
+ </param>
+ <param>
+ <key>fc</key>
+ <value>freq</value>
+ </param>
+ <param>
+ <key>bw</key>
+ <value>sample_rate</value>
+ </param>
+ <param>
+ <key>grid</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>autoscale</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>0.2</value>
+ </param>
+ <param>
+ <key>ymin</key>
+ <value>-140</value>
+ </param>
+ <param>
+ <key>ymax</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>nconnections</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>update_time</key>
+ <value>0.10</value>
+ </param>
+ <param>
+ <key>gui_hint</key>
+ <value>displays@0</value>
+ </param>
+ <param>
+ <key>showports</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width1</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color1</key>
+ <value>"blue"</value>
+ </param>
+ <param>
+ <key>alpha1</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width2</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color2</key>
+ <value>"red"</value>
+ </param>
+ <param>
+ <key>alpha2</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width3</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color3</key>
+ <value>"green"</value>
+ </param>
+ <param>
+ <key>alpha3</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width4</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color4</key>
+ <value>"black"</value>
+ </param>
+ <param>
+ <key>alpha4</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width5</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color5</key>
+ <value>"cyan"</value>
+ </param>
+ <param>
+ <key>alpha5</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width6</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color6</key>
+ <value>"magenta"</value>
+ </param>
+ <param>
+ <key>alpha6</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width7</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color7</key>
+ <value>"yellow"</value>
+ </param>
+ <param>
+ <key>alpha7</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width8</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color8</key>
+ <value>"dark red"</value>
+ </param>
+ <param>
+ <key>alpha8</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width9</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color9</key>
+ <value>"dark green"</value>
+ </param>
+ <param>
+ <key>alpha9</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>label10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>width10</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>color10</key>
+ <value>"dark blue"</value>
+ </param>
+ <param>
+ <key>alpha10</key>
+ <value>1.0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(35, 216)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>uhd_usrp_source</key>
+ <param>
+ <key>id</key>
+ <value>u</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>fc32</value>
+ </param>
+ <param>
+ <key>otw</key>
+ <value></value>
+ </param>
+ <param>
+ <key>stream_args</key>
+ <value></value>
+ </param>
+ <param>
+ <key>stream_chans</key>
+ <value>[]</value>
+ </param>
+ <param>
+ <key>dev_addr</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>dev_args</key>
+ <value>""</value>
+ </param>
+ <param>
+ <key>sync</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_rate</key>
+ <value>0.0</value>
+ </param>
+ <param>
+ <key>num_mboards</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>clock_source0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec0</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>clock_source7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>time_source7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>sd_spec7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>nchan</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>sample_rate</value>
+ </param>
+ <param>
+ <key>center_freq0</key>
+ <value>freq</value>
+ </param>
+ <param>
+ <key>gain0</key>
+ <value>gain</value>
+ </param>
+ <param>
+ <key>ant0</key>
+ <value>antenna</value>
+ </param>
+ <param>
+ <key>bw0</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant1</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw1</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant2</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw2</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant3</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw3</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant4</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw4</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant5</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw5</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant6</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw6</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant7</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw7</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant8</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw8</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant9</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw9</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant10</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw10</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant11</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw11</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant12</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw12</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant13</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw13</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant14</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw14</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant15</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw15</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant16</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw16</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant17</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw17</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant18</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw18</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant19</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw19</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant20</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw20</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant21</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw21</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant22</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw22</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant23</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw23</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant24</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw24</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant25</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw25</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant26</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw26</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant27</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw27</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant28</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw28</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant29</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw29</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant30</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw30</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>center_freq31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>gain31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ant31</key>
+ <value></value>
+ </param>
+ <param>
+ <key>bw31</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>alias</key>
+ <value></value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(42, 318)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>dtv_atsc_viterbi_decoder_0</source_block_id>
+ <sink_block_id>dtv_atsc_deinterleaver_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>u</source_block_id>
+ <sink_block_id>rx_filter</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>rx_filter</source_block_id>
+ <sink_block_id>fpll</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>fpll</source_block_id>
+ <sink_block_id>dc_blocker_xx_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dc_blocker_xx_0</source_block_id>
+ <sink_block_id>agc</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_atsc_equalizer_0</source_block_id>
+ <sink_block_id>dtv_atsc_viterbi_decoder_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_atsc_fs_checker_0</source_block_id>
+ <sink_block_id>dtv_atsc_equalizer_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_atsc_sync_0</source_block_id>
+ <sink_block_id>dtv_atsc_fs_checker_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>agc</source_block_id>
+ <sink_block_id>dtv_atsc_sync_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_atsc_depad_0</source_block_id>
+ <sink_block_id>blocks_file_sink_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_atsc_derandomizer_0</source_block_id>
+ <sink_block_id>dtv_atsc_depad_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_atsc_rs_decoder_0</source_block_id>
+ <sink_block_id>dtv_atsc_derandomizer_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>dtv_atsc_deinterleaver_0</source_block_id>
+ <sink_block_id>dtv_atsc_rs_decoder_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>u</source_block_id>
+ <sink_block_id>usrp_freq_sink</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-dtv/gnuradio-dtv.pc.in b/gr-dtv/gnuradio-dtv.pc.in
new file mode 100644
index 0000000000..bac3b06745
--- /dev/null
+++ b/gr-dtv/gnuradio-dtv.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-dtv
+Description: GNU Radio's digital TV signal processing blocks
+Requires: gnuradio-runtime gnuradio-filter gnuradio-analog
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-dtv
+Cflags: -I${includedir}
diff --git a/gr-dtv/grc/CMakeLists.txt b/gr-dtv/grc/CMakeLists.txt
new file mode 100644
index 0000000000..bd8d67a4ce
--- /dev/null
+++ b/gr-dtv/grc/CMakeLists.txt
@@ -0,0 +1,35 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+install(FILES
+ dtv_atsc_deinterleaver.xml
+ dtv_atsc_depad.xml
+ dtv_atsc_derandomizer.xml
+ dtv_atsc_equalizer.xml
+ dtv_atsc_fpll.xml
+ dtv_atsc_fs_checker.xml
+ dtv_atsc_rs_decoder.xml
+ dtv_atsc_rx.xml
+ dtv_atsc_rx_filter.xml
+ dtv_atsc_sync.xml
+ dtv_atsc_viterbi_decoder.xml
+ dtv_block_tree.xml
+ DESTINATION ${GRC_BLOCKS_DIR}
+ COMPONENT "dtv_python"
+)
diff --git a/gr-dtv/grc/dtv_atsc_deinterleaver.xml b/gr-dtv/grc/dtv_atsc_deinterleaver.xml
new file mode 100644
index 0000000000..051ea77554
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_deinterleaver.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Deinterleaver
+###################################################
+ -->
+<block>
+ <name>ATSC Deinterleaver</name>
+ <key>dtv_atsc_deinterleaver</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_deinterleaver()</make>
+
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>256</vlen>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>256</vlen>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_depad.xml b/gr-dtv/grc/dtv_atsc_depad.xml
new file mode 100644
index 0000000000..95a1380914
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_depad.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Depad
+###################################################
+ -->
+<block>
+ <name>ATSC Depad</name>
+ <key>dtv_atsc_depad</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_depad()</make>
+
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>256</vlen>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_derandomizer.xml b/gr-dtv/grc/dtv_atsc_derandomizer.xml
new file mode 100644
index 0000000000..5473f47e8c
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_derandomizer.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Derandomizer
+###################################################
+ -->
+<block>
+ <name>ATSC Derandomizer</name>
+ <key>dtv_atsc_derandomizer</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_derandomizer()</make>
+
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>256</vlen>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>256</vlen>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_equalizer.xml b/gr-dtv/grc/dtv_atsc_equalizer.xml
new file mode 100644
index 0000000000..7faf65fd22
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_equalizer.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Equalizer
+###################################################
+ -->
+<block>
+ <name>ATSC Equalizer</name>
+ <key>dtv_atsc_equalizer</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_equalizer()</make>
+
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>4096</vlen>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>4096</vlen>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_fpll.xml b/gr-dtv/grc/dtv_atsc_fpll.xml
new file mode 100644
index 0000000000..00d28ce8b6
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_fpll.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Receiver PLL
+###################################################
+ -->
+<block>
+ <name>ATSC Receiver FPLL</name>
+ <key>dtv_atsc_fpll</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_fpll($rate)</make>
+
+ <param>
+ <name>Sample Rate</name>
+ <key>rate</key>
+ <type>float</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>float</type>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_fs_checker.xml b/gr-dtv/grc/dtv_atsc_fs_checker.xml
new file mode 100644
index 0000000000..4c733d53b9
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_fs_checker.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Field Sync Checker
+###################################################
+ -->
+<block>
+ <name>ATSC Field Sync Checker</name>
+ <key>dtv_atsc_fs_checker</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_fs_checker()</make>
+
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>4096</vlen>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>4096</vlen>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_rs_decoder.xml b/gr-dtv/grc/dtv_atsc_rs_decoder.xml
new file mode 100644
index 0000000000..18a3053f00
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_rs_decoder.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Reed–Solomon Decoder
+###################################################
+ -->
+<block>
+ <name>ATSC Reed–Solomon Decoder</name>
+ <key>dtv_atsc_rs_decoder</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_rs_decoder()</make>
+
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>256</vlen>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>256</vlen>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_rx.xml b/gr-dtv/grc/dtv_atsc_rx.xml
new file mode 100644
index 0000000000..900769609f
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_rx.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Receive Pipeline
+###################################################
+ -->
+<block>
+ <name>ATSC Receive Pipeline</name>
+ <key>dtv_atsc_rx</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_rx($rate,$sps)</make>
+
+ <param>
+ <name>Input Rate</name>
+ <key>rate</key>
+ <type>float</type>
+ </param>
+
+ <param>
+ <name>Oversampling Ratio</name>
+ <key>sps</key>
+ <type>float</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_rx_filter.xml b/gr-dtv/grc/dtv_atsc_rx_filter.xml
new file mode 100644
index 0000000000..bc8bf0914a
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_rx_filter.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC RX Filter
+###################################################
+ -->
+<block>
+ <name>ATSC RX Filter</name>
+ <key>dtv_atsc_rx_filter</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_rx_filter($rate,$sps)</make>
+
+ <param>
+ <name>Input Rate</name>
+ <key>rate</key>
+ <type>float</type>
+ </param>
+
+ <param>
+ <name>Oversampling Ratio</name>
+ <key>sps</key>
+ <type>float</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_sync.xml b/gr-dtv/grc/dtv_atsc_sync.xml
new file mode 100644
index 0000000000..a9528f84a0
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_sync.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Receiver Sync
+###################################################
+ -->
+<block>
+ <name>ATSC Receiver SYNC</name>
+ <key>dtv_atsc_sync</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_sync($rate)</make>
+
+ <param>
+ <name>Sample Rate</name>
+ <key>rate</key>
+ <type>float</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>float</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>4096</vlen>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_atsc_viterbi_decoder.xml b/gr-dtv/grc/dtv_atsc_viterbi_decoder.xml
new file mode 100644
index 0000000000..23d58d08af
--- /dev/null
+++ b/gr-dtv/grc/dtv_atsc_viterbi_decoder.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## ATSC Equalizer
+###################################################
+ -->
+<block>
+ <name>ATSC Viterbi Decoder</name>
+ <key>dtv_atsc_viterbi_decoder</key>
+ <import>from gnuradio import dtv</import>
+ <make>dtv.atsc_viterbi_decoder()</make>
+
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ <vlen>4096</vlen>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ <vlen>256</vlen>
+ </source>
+
+</block>
diff --git a/gr-dtv/grc/dtv_block_tree.xml b/gr-dtv/grc/dtv_block_tree.xml
new file mode 100644
index 0000000000..8b84c361b4
--- /dev/null
+++ b/gr-dtv/grc/dtv_block_tree.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright 2014 Free Software Foundation, Inc.
+
+ This file is part of GNU Radio
+
+ GNU Radio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Radio is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Radio; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street,
+ Boston, MA 02110-1301, USA.
+-->
+
+<!--
+###################################################
+##Block Tree for GR DTV blocks.
+###################################################
+ -->
+<cat>
+ <name></name> <!-- Blank for Root Name -->
+ <cat>
+ <name>Digital Television</name>
+ <cat>
+ <name>ATSC</name>
+ <block>dtv_atsc_deinterleaver</block>
+ <block>dtv_atsc_depad</block>
+ <block>dtv_atsc_derandomizer</block>
+ <block>dtv_atsc_equalizer</block>
+ <block>dtv_atsc_fpll</block>
+ <block>dtv_atsc_fs_checker</block>
+ <block>dtv_atsc_rs_decoder</block>
+ <block>dtv_atsc_rx</block>
+ <block>dtv_atsc_rx_filter</block>
+ <block>dtv_atsc_sync</block>
+ <block>dtv_atsc_viterbi_decoder</block>
+ </cat>
+ </cat>
+</cat>
diff --git a/gr-dtv/include/gnuradio/dtv/CMakeLists.txt b/gr-dtv/include/gnuradio/dtv/CMakeLists.txt
new file mode 100644
index 0000000000..d9a01421a3
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# Install header files
+########################################################################
+install(FILES
+ api.h
+ atsc_consts.h
+ atsc_deinterleaver.h
+ atsc_depad.h
+ atsc_derandomizer.h
+ atsc_equalizer.h
+ atsc_fpll.h
+ atsc_fs_checker.h
+ atsc_rs_decoder.h
+ atsc_sync.h
+ atsc_viterbi_decoder.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/dtv
+ COMPONENT "dtv_devel"
+)
diff --git a/gr-dtv/include/gnuradio/dtv/api.h b/gr-dtv/include/gnuradio/dtv/api.h
new file mode 100644
index 0000000000..14fd46981a
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/api.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_API_H
+#define INCLUDED_DTV_API_H
+
+#include <gnuradio/attributes.h>
+
+#ifdef gnuradio_dtv_EXPORTS
+# define DTV_API __GR_ATTR_EXPORT
+#else
+# define DTV_API __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_DTV_API_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_consts.h b/gr-dtv/include/gnuradio/dtv/atsc_consts.h
new file mode 100644
index 0000000000..12b594788d
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_consts.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_CONSTS_H
+#define INCLUDED_DTV_ATSC_CONSTS_H
+
+#include <gnuradio/dtv/api.h>
+
+namespace gr {
+ namespace dtv {
+
+ // These will go into an mpeg_consts.h once other mod/demods are done
+ static const int ATSC_MPEG_DATA_LENGTH = 187;
+ static const int ATSC_MPEG_PKT_LENGTH = 188; // sync + data
+ static const int ATSC_MPEG_RS_ENCODED_LENGTH = 207;
+ static const int MPEG_SYNC_BYTE = 0x47;
+ static const int MPEG_TRANSPORT_ERROR_BIT = 0x80; // top bit of byte after SYNC
+
+ // ATSC specific constants
+ static const double ATSC_SYMBOL_RATE = 4.5e6/286*684; // ~10.76 MHz
+ static const double ATSC_DATA_SEGMENT_RATE = ATSC_SYMBOL_RATE/832; // ~12.935 kHz
+ static const int ATSC_DATA_SEGMENT_LENGTH = 832; // includes 4 sync symbols at beginning
+ static const int ATSC_DSEGS_PER_FIELD = 312; // regular data segs / field
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_CONSTS_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_deinterleaver.h b/gr-dtv/include/gnuradio/dtv/atsc_deinterleaver.h
new file mode 100644
index 0000000000..658aa47a96
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_deinterleaver.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_DEINTERLEAVER_H
+#define INCLUDED_DTV_ATSC_DEINTERLEAVER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief ATSC deinterleave RS encoded ATSC data ( atsc_mpeg_packet_rs_encoded --> atsc_mpeg_packet_rs_encoded)
+ * \ingroup dtv_atsc
+ *
+ * input: atsc_mpeg_packet_rs_encoded; output: atsc_mpeg_packet_rs_encoded
+ */
+ class DTV_API atsc_deinterleaver : virtual public gr::sync_block
+ {
+ public:
+
+ // gr::dtv::atsc_deinterleaver::sptr
+ typedef boost::shared_ptr<atsc_deinterleaver> sptr;
+
+ /*!
+ * \brief Make a new instance of gr::dtv::atsc_deinterleaver.
+ */
+ static sptr make();
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_DEINTERLEAVER_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_depad.h b/gr-dtv/include/gnuradio/dtv/atsc_depad.h
new file mode 100644
index 0000000000..4dfe21a6f9
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_depad.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_DEPAD_H
+#define INCLUDED_DTV_ATSC_DEPAD_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/sync_interpolator.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief ATSC depad mpeg ts packets from 256 byte atsc_mpeg_packet to 188 byte char
+ * \ingroup dtv_atsc
+ *
+ * input: atsc_mpeg_packet; output: unsigned char
+ */
+ class DTV_API atsc_depad : virtual public gr::sync_interpolator
+ {
+ public:
+
+ // gr::dtv::atsc_depad::sptr
+ typedef boost::shared_ptr<atsc_depad> sptr;
+
+ /*!
+ * \brief Make a new instance of gr::dtv::atsc_depad.
+ */
+ static sptr make();
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_DEPAD_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_derandomizer.h b/gr-dtv/include/gnuradio/dtv/atsc_derandomizer.h
new file mode 100644
index 0000000000..d941cae004
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_derandomizer.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_DERANDOMIZER_H
+#define INCLUDED_DTV_ATSC_DERANDOMIZER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief ATSC "dewhiten" incoming mpeg transport stream packets
+ * \ingroup dtv_atsc
+ *
+ * input: atsc_mpeg_packet_no_sync; output: atsc_mpeg_packet;
+ */
+ class DTV_API atsc_derandomizer : virtual public gr::sync_block
+ {
+ public:
+
+ // gr::dtv::atsc_derandomizer::sptr
+ typedef boost::shared_ptr<atsc_derandomizer> sptr;
+
+ /*!
+ * \brief Make a new instance of gr::dtv::atsc_derandomizer.
+ */
+ static sptr make();
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_DERANDOMIZER_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_equalizer.h b/gr-dtv/include/gnuradio/dtv/atsc_equalizer.h
new file mode 100644
index 0000000000..3fe101ac25
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_equalizer.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_EQUALIZER_H
+#define INCLUDED_DTV_ATSC_EQUALIZER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief ATSC Receiver Equalizer
+ *
+ * \ingroup dtv_atsc
+ */
+ class DTV_API atsc_equalizer : virtual public gr::block
+ {
+ public:
+
+ // gr::dtv::atsc_equalizer::sptr
+ typedef boost::shared_ptr<atsc_equalizer> sptr;
+
+ /*!
+ * \brief Make a new instance of gr::dtv::atsc_equalizer.
+ */
+ static sptr make();
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_EQUALIZER_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_fpll.h b/gr-dtv/include/gnuradio/dtv/atsc_fpll.h
new file mode 100644
index 0000000000..6dc30413da
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_fpll.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_FPLL_H
+#define INCLUDED_DTV_ATSC_FPLL_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief ATSC Receiver FPLL
+ *
+ * This block is takes in a complex I/Q baseband stream from the
+ * receive filter and outputs the 8-level symbol stream.
+ *
+ * It does this by first locally generating a pilot tone and
+ * complex mixing with the input signal. This results in the
+ * pilot tone shifting to DC and places the signal in the upper
+ * sideband.
+ *
+ * As no information is encoded in the phase of the waveform, the
+ * Q channel is then discarded, producing a real signal with the
+ * lower sideband restored.
+ *
+ * The 8-level symbol stream still has a DC offset, and still
+ * requires symbol timing recovery.
+ *
+ * \ingroup dtv_atsc
+ */
+ class DTV_API atsc_fpll : virtual public gr::sync_block
+ {
+ public:
+
+ // gr::dtv::atsc_fpll::sptr
+ typedef boost::shared_ptr<atsc_fpll> sptr;
+
+ /*!
+ * \brief Make a new instance of gr::dtv::atsc_fpll.
+ *
+ * param rate Sample rate of incoming stream
+ */
+ static sptr make(float rate);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_FPLL_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_fs_checker.h b/gr-dtv/include/gnuradio/dtv/atsc_fs_checker.h
new file mode 100644
index 0000000000..d5a4a7d083
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_fs_checker.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_FS_CHECKER_H
+#define INCLUDED_DTV_ATSC_FS_CHECKER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief ATSC Receiver FS_CHECKER
+ *
+ * \ingroup dtv_atsc
+ */
+ class DTV_API atsc_fs_checker : virtual public gr::block
+ {
+ public:
+
+ // gr::dtv::atsc_fs_checker::sptr
+ typedef boost::shared_ptr<atsc_fs_checker> sptr;
+
+ /*!
+ * \brief Make a new instance of gr::dtv::atsc_fs_checker.
+ */
+ static sptr make();
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_FS_CHECKER_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_rs_decoder.h b/gr-dtv/include/gnuradio/dtv/atsc_rs_decoder.h
new file mode 100644
index 0000000000..92eb263e5d
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_rs_decoder.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_RS_DECODER_H
+#define INCLUDED_DTV_ATSC_RS_DECODER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief ATSC Receiver Reed-Solomon Decoder
+ *
+ * \ingroup dtv_atsc
+ */
+ class DTV_API atsc_rs_decoder : virtual public gr::sync_block
+ {
+ public:
+
+ // gr::dtv::atsc_rs_decoder::sptr
+ typedef boost::shared_ptr<atsc_rs_decoder> sptr;
+
+ /*!
+ * \brief Make a new instance of gr::dtv::atsc_rs_decoder.
+ */
+ static sptr make();
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_RS_DECODER_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_sync.h b/gr-dtv/include/gnuradio/dtv/atsc_sync.h
new file mode 100644
index 0000000000..8a2aded60d
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_sync.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_SYNC_H
+#define INCLUDED_DTV_ATSC_SYNC_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief ATSC Receiver SYNC
+ *
+ * \ingroup dtv_atsc
+ */
+ class DTV_API atsc_sync : virtual public gr::block
+ {
+ public:
+
+ // gr::dtv::atsc_sync::sptr
+ typedef boost::shared_ptr<atsc_sync> sptr;
+
+ /*!
+ * \brief Make a new instance of gr::dtv::atsc_sync.
+ *
+ * param rate Sample rate of incoming stream
+ */
+ static sptr make(float rate);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_SYNC_H */
diff --git a/gr-dtv/include/gnuradio/dtv/atsc_viterbi_decoder.h b/gr-dtv/include/gnuradio/dtv/atsc_viterbi_decoder.h
new file mode 100644
index 0000000000..a4c18c39da
--- /dev/null
+++ b/gr-dtv/include/gnuradio/dtv/atsc_viterbi_decoder.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_VITERBI_DECODER_H
+#define INCLUDED_DTV_ATSC_VITERBI_DECODER_H
+
+#include <gnuradio/dtv/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief ATSC Viterbi Decoder
+ *
+ * \ingroup dtv_atsc
+ */
+ class DTV_API atsc_viterbi_decoder : virtual public gr::sync_block
+ {
+ public:
+
+ // gr::dtv::atsc_viterbi_decoder::sptr
+ typedef boost::shared_ptr<atsc_viterbi_decoder> sptr;
+
+ /*!
+ * \brief Make a new instance of gr::dtv::atsc_viterbi_decoder.
+ */
+ static sptr make();
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_VITERBI_DECODER_H */
diff --git a/gr-dtv/lib/CMakeLists.txt b/gr-dtv/lib/CMakeLists.txt
new file mode 100644
index 0000000000..9227f24c96
--- /dev/null
+++ b/gr-dtv/lib/CMakeLists.txt
@@ -0,0 +1,104 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# Setup the include and linker paths
+########################################################################
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${GR_DTV_INCLUDE_DIRS}
+ ${GR_FILTER_INCLUDE_DIRS}
+ ${GR_ANALOG_INCLUDE_DIRS}
+ ${GR_FEC_INCLUDE_DIRS}
+ ${GNURADIO_RUNTIME_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+)
+
+link_directories(${Boost_LIBRARY_DIRS})
+
+if(ENABLE_GR_CTRLPORT)
+ ADD_DEFINITIONS(-DGR_CTRLPORT)
+ include_directories(${ICE_INCLUDE_DIR})
+endif(ENABLE_GR_CTRLPORT)
+
+########################################################################
+# Generate viterbi mux source
+# http://www.vtk.org/Wiki/CMake_Cross_Compiling#Using_executables_in_the_build_created_during_the_build
+########################################################################
+if(NOT CMAKE_CROSSCOMPILING)
+ add_executable(atsc_viterbi_gen atsc/atsc_viterbi_gen.cc)
+ export(TARGETS atsc_viterbi_gen APPEND FILE ${EXPORT_FILE})
+endif()
+
+set(atsc_viterbi_mux_cc ${CMAKE_CURRENT_BINARY_DIR}/atsc_viterbi_mux.cc)
+
+add_custom_command(
+ OUTPUT ${atsc_viterbi_mux_cc}
+ DEPENDS atsc_viterbi_gen
+ COMMAND atsc_viterbi_gen -o ${atsc_viterbi_mux_cc}
+)
+
+########################################################################
+# Setup library
+########################################################################
+list(APPEND dtv_sources
+ ${atsc_viterbi_mux_cc}
+ atsc/atsc_deinterleaver_impl.cc
+ atsc/atsc_depad_impl.cc
+ atsc/atsc_derandomizer_impl.cc
+ atsc/atsc_equalizer_impl.cc
+ atsc/atsc_fpll_impl.cc
+ atsc/atsc_fs_checker_impl.cc
+ atsc/atsc_randomize.cc
+ atsc/atsc_rs_decoder_impl.cc
+ atsc/atsc_sync_impl.cc
+ atsc/atsc_fake_single_viterbi.cc
+ atsc/atsc_single_viterbi.cc
+ atsc/atsc_viterbi_decoder_impl.cc
+)
+
+if(ENABLE_GR_CTRLPORT)
+list(APPEND dtv_sources
+)
+endif(ENABLE_GR_CTRLPORT)
+
+list(APPEND dtv_libs
+ gnuradio-runtime
+ gnuradio-analog
+ gnuradio-filter
+ gnuradio-fec
+)
+
+#Add Windows DLL resource file if using MSVC
+if(MSVC)
+ include(${CMAKE_SOURCE_DIR}/cmake/Modules/GrVersion.cmake)
+
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-dtv.rc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-dtv.rc
+ @ONLY)
+
+ list(APPEND dtv_sources
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-dtv.rc
+ )
+endif(MSVC)
+
+add_library(gnuradio-dtv SHARED ${dtv_sources})
+target_link_libraries(gnuradio-dtv ${dtv_libs})
+GR_LIBRARY_FOO(gnuradio-dtv RUNTIME_COMPONENT "dtv_runtime" DEVEL_COMPONENT "dtv_devel")
diff --git a/gr-dtv/lib/atsc/atsc_deinterleaver_impl.cc b/gr-dtv/lib/atsc/atsc_deinterleaver_impl.cc
new file mode 100644
index 0000000000..7b2001aacb
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_deinterleaver_impl.cc
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atsc_deinterleaver_impl.h"
+#include "gnuradio/dtv/atsc_consts.h"
+#include <gnuradio/io_signature.h>
+
+namespace gr {
+ namespace dtv {
+
+ atsc_deinterleaver::sptr
+ atsc_deinterleaver::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new atsc_deinterleaver_impl());
+ }
+
+ atsc_deinterleaver_impl::atsc_deinterleaver_impl()
+ : gr::sync_block("atsc_deinterleaver",
+ io_signature::make(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)),
+ io_signature::make(1, 1, sizeof(atsc_mpeg_packet_rs_encoded))),
+ alignment_fifo (156)
+ {
+ m_fifo.resize(52);
+
+ for (int i = 0; i < 52; i++)
+ m_fifo[52 - 1 - i] = new interleaver_fifo<unsigned char>(i * 4);
+
+ sync();
+ }
+
+ atsc_deinterleaver_impl::~atsc_deinterleaver_impl()
+ {
+ for (int i = 0; i < 52; i++)
+ delete m_fifo[i];
+ }
+
+ void atsc_deinterleaver_impl::reset()
+ {
+ sync();
+ for (int i = 0; i < 52; i++)
+ m_fifo[i]->reset();
+ }
+
+ int
+ atsc_deinterleaver_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *)input_items[0];
+ atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *)output_items[0];
+
+ for (int i = 0; i < noutput_items; i++) {
+ assert (in[i].pli.regular_seg_p());
+ plinfo::sanity_check(in[i].pli);
+
+ // reset commutator if required using INPUT pipeline info
+ if (in[i].pli.first_regular_seg_p())
+ sync();
+
+ // remap OUTPUT pipeline info to reflect 52 data segment end-to-end delay
+ plinfo::delay (out[i].pli, in[i].pli, 52);
+
+ // now do the actual deinterleaving
+ for (unsigned int j = 0; j < sizeof(in[i].data); j++) {
+ out[i].data[j] = alignment_fifo.stuff(transform (in[i].data[j]));
+ }
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_deinterleaver_impl.h b/gr-dtv/lib/atsc/atsc_deinterleaver_impl.h
new file mode 100644
index 0000000000..75eb7e877d
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_deinterleaver_impl.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_DEINTERLEAVER_IMPL_H
+#define INCLUDED_DTV_ATSC_DEINTERLEAVER_IMPL_H
+
+#include <gnuradio/dtv/atsc_deinterleaver.h>
+#include "atsc_types.h"
+#include "interleaver_fifo.h"
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_deinterleaver_impl : public atsc_deinterleaver
+ {
+ private:
+ //! transform a single symbol
+ unsigned char transform(unsigned char input) {
+ unsigned char retval = m_fifo[m_commutator]->stuff(input);
+ m_commutator++;
+ if (m_commutator >= 52)
+ m_commutator = 0;
+ return retval;
+ }
+
+ /*!
+ * Note: The use of the alignment_fifo keeps the encoder and decoder
+ * aligned if both are synced to a field boundary. There may be other
+ * ways to implement this function. This is a best guess as to how
+ * this should behave, as we have no test vectors for either the
+ * interleaver or deinterleaver.
+ */
+ interleaver_fifo<unsigned char> alignment_fifo;
+
+ int m_commutator;
+ std::vector<interleaver_fifo<unsigned char> *> m_fifo;
+
+ public:
+ atsc_deinterleaver_impl();
+ ~atsc_deinterleaver_impl();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ //! reset interleaver (flushes contents and resets commutator)
+ void reset();
+
+ //! sync interleaver (resets commutator, but doesn't flush fifos)
+ void sync() { m_commutator = 0; }
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_DEINTERLEAVER_IMPL_H */
diff --git a/gr-dtv/lib/atsc/atsc_depad_impl.cc b/gr-dtv/lib/atsc/atsc_depad_impl.cc
new file mode 100644
index 0000000000..e1172e630c
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_depad_impl.cc
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atsc_depad_impl.h"
+#include "gnuradio/dtv/atsc_consts.h"
+#include <gnuradio/io_signature.h>
+
+namespace gr {
+ namespace dtv {
+
+ atsc_depad::sptr
+ atsc_depad::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new atsc_depad_impl());
+ }
+
+ atsc_depad_impl::atsc_depad_impl()
+ : gr::sync_interpolator("atsc_depad",
+ io_signature::make(1, 1, sizeof(atsc_mpeg_packet)),
+ io_signature::make(1, 1, sizeof(unsigned char)),
+ ATSC_MPEG_PKT_LENGTH)
+ {
+ }
+
+ int
+ atsc_depad_impl::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const atsc_mpeg_packet *in = (const atsc_mpeg_packet *)input_items[0];
+ unsigned char *out = (unsigned char *)output_items[0];
+
+ int i;
+
+ for (i = 0; i < noutput_items/ATSC_MPEG_PKT_LENGTH; i++)
+ memcpy(&out[i * ATSC_MPEG_PKT_LENGTH], in[i].data, ATSC_MPEG_PKT_LENGTH);
+
+ return i * ATSC_MPEG_PKT_LENGTH;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_depad_impl.h b/gr-dtv/lib/atsc/atsc_depad_impl.h
new file mode 100644
index 0000000000..d29b1cfe9e
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_depad_impl.h
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_DEPAD_IMPL_H
+#define INCLUDED_DTV_ATSC_DEPAD_IMPL_H
+
+#include <gnuradio/dtv/atsc_depad.h>
+#include "atsc_types.h"
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_depad_impl : public atsc_depad
+ {
+ public:
+ atsc_depad_impl();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_DEPAD_IMPL_H */
diff --git a/gr-dtv/lib/atsc/atsc_derandomizer_impl.cc b/gr-dtv/lib/atsc/atsc_derandomizer_impl.cc
new file mode 100644
index 0000000000..364713f7b5
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_derandomizer_impl.cc
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atsc_derandomizer_impl.h"
+#include "gnuradio/dtv/atsc_consts.h"
+#include <gnuradio/io_signature.h>
+
+namespace gr {
+ namespace dtv {
+
+ atsc_derandomizer::sptr
+ atsc_derandomizer::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new atsc_derandomizer_impl());
+ }
+
+ atsc_derandomizer_impl::atsc_derandomizer_impl()
+ : gr::sync_block("dtv_atsc_derandomizer",
+ io_signature::make(1, 1, sizeof(atsc_mpeg_packet_no_sync)),
+ io_signature::make(1, 1, sizeof(atsc_mpeg_packet)))
+ {
+ d_rand.reset();
+ }
+
+ int
+ atsc_derandomizer_impl::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const atsc_mpeg_packet_no_sync *in = (const atsc_mpeg_packet_no_sync *) input_items[0];
+ atsc_mpeg_packet *out = (atsc_mpeg_packet *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+
+ assert(in[i].pli.regular_seg_p());
+
+ if (in[i].pli.first_regular_seg_p())
+ d_rand.reset();
+
+ d_rand.derandomize(out[i], in[i]);
+
+ // Check the pipeline info for error status and and set the
+ // corresponding bit in transport packet header.
+
+ if (in[i].pli.transport_error_p())
+ out[i].data[1] |= MPEG_TRANSPORT_ERROR_BIT;
+ else
+ out[i].data[1] &= ~MPEG_TRANSPORT_ERROR_BIT;
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_derandomizer_impl.h b/gr-dtv/lib/atsc/atsc_derandomizer_impl.h
new file mode 100644
index 0000000000..a307a51d86
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_derandomizer_impl.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_DERANDOMIZER_IMPL_H
+#define INCLUDED_DTV_ATSC_DERANDOMIZER_IMPL_H
+
+#include <gnuradio/dtv/atsc_derandomizer.h>
+#include "atsc_randomize.h"
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_derandomizer_impl : public atsc_derandomizer
+ {
+ private:
+ atsc_randomize d_rand;
+
+ public:
+ atsc_derandomizer_impl();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_DERANDOMIZER_IMPL_H */
diff --git a/gr-dtv/lib/atsc/atsc_equalizer_impl.cc b/gr-dtv/lib/atsc/atsc_equalizer_impl.cc
new file mode 100644
index 0000000000..c804be6dc7
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_equalizer_impl.cc
@@ -0,0 +1,183 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atsc_equalizer_impl.h"
+#include "atsc_types.h"
+#include "atsc_pnXXX_impl.h"
+#include <gnuradio/io_signature.h>
+
+namespace gr {
+ namespace dtv {
+
+ atsc_equalizer::sptr
+ atsc_equalizer::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new atsc_equalizer_impl());
+ }
+
+ static float
+ bin_map (int bit)
+ {
+ return bit ? +5 : -5;
+ }
+
+ static void
+ init_field_sync_common (float *p, int mask)
+ {
+ int i = 0;
+
+ p[i++] = bin_map (1); // data segment sync pulse
+ p[i++] = bin_map (0);
+ p[i++] = bin_map (0);
+ p[i++] = bin_map (1);
+
+ for (int j = 0; j < 511; j++) // PN511
+ p[i++] = bin_map (atsc_pn511[j]);
+
+ for (int j = 0; j < 63; j++) // PN63
+ p[i++] = bin_map (atsc_pn63[j]);
+
+ for (int j = 0; j < 63; j++) // PN63, toggled on field 2
+ p[i++] = bin_map (atsc_pn63[j] ^ mask);
+
+ for (int j = 0; j < 63; j++) // PN63
+ p[i++] = bin_map (atsc_pn63[j]);
+ }
+
+ atsc_equalizer_impl::atsc_equalizer_impl()
+ : gr::block("dtv_atsc_equalizer",
+ io_signature::make(1, 1, sizeof(atsc_soft_data_segment)),
+ io_signature::make(1, 1, sizeof(atsc_soft_data_segment)))
+ {
+ init_field_sync_common(training_sequence1, 0);
+ init_field_sync_common(training_sequence2, 1);
+
+ for (int i = 0; i < NTAPS; i++)
+ d_taps[i] = 0.0;
+
+ d_buff_not_filled = true;
+ }
+
+ atsc_equalizer_impl::~atsc_equalizer_impl()
+ {
+ }
+
+ void
+ atsc_equalizer_impl::filterN(const float *input_samples, float *output_samples, int nsamples)
+ {
+ for (int j = 0; j < nsamples; j++) {
+ output_samples[j] = 0;
+ for(int i = 0; i < NTAPS; i++)
+ output_samples[j] += d_taps[i] * input_samples[j + i];
+ }
+ }
+
+ void
+ atsc_equalizer_impl::adaptN(const float *input_samples,
+ const float *training_pattern,
+ float *output_samples,
+ int nsamples)
+ {
+ static const double BETA = 0.00005; // FIXME figure out what this ought to be
+ // FIXME add gear-shifting
+
+ for(int j = 0; j < nsamples; j++) {
+ output_samples[j] = 0;
+ for( int i = 0; i < NTAPS; i++ )
+ output_samples[j] += d_taps[i] * input_samples[j + i];
+
+ double e = output_samples[j] - training_pattern[j];
+
+ // update taps...
+ for( int i = 0; i < NTAPS; i++ )
+ d_taps[i] -= BETA * e * (double)(input_samples[j + i]);
+ }
+ }
+
+ int
+ atsc_equalizer_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const atsc_soft_data_segment *in = (const atsc_soft_data_segment *) input_items[0];
+ atsc_soft_data_segment *out = (atsc_soft_data_segment *) output_items[0];
+
+ int output_produced = 0;
+ int i = 0;
+
+ if(d_buff_not_filled) {
+ for(int j = 0; j < ATSC_DATA_SEGMENT_LENGTH; j++)
+ data_mem[NPRETAPS + j] = in[i].data[j];
+ d_flags = in[i].pli._flags;
+ d_segno = in[i].pli._segno;
+ d_buff_not_filled = false;
+ i++;
+ }
+
+ for (; i < noutput_items; i++) {
+
+ for(int j = 0; j < NTAPS - NPRETAPS; j++)
+ data_mem[ATSC_DATA_SEGMENT_LENGTH + NPRETAPS + j] = in[i].data[j];
+
+ if(d_segno == -1) {
+ if(d_flags & 0x0010) {
+ adaptN(data_mem, training_sequence2, data_mem2, KNOWN_FIELD_SYNC_LENGTH);
+ //filterN(&data_mem[KNOWN_FIELD_SYNC_LENGTH], data_mem2, ATSC_DATA_SEGMENT_LENGTH - KNOWN_FIELD_SYNC_LENGTH);
+ }
+ else if( !(d_flags & 0x0010) ) {
+ adaptN( data_mem, training_sequence1, data_mem2, KNOWN_FIELD_SYNC_LENGTH );
+ //filterN(&data_mem[KNOWN_FIELD_SYNC_LENGTH], data_mem2, ATSC_DATA_SEGMENT_LENGTH - KNOWN_FIELD_SYNC_LENGTH);
+ }
+ }
+ else {
+ filterN(data_mem, data_mem2, ATSC_DATA_SEGMENT_LENGTH);
+
+ for(int j = 0; j < ATSC_DATA_SEGMENT_LENGTH; j++)
+ out[output_produced].data[j] = data_mem2[j];
+
+ out[output_produced].pli._flags = d_flags;
+ out[output_produced].pli._segno = d_segno;
+ output_produced++;
+ }
+
+ for( int j = 0; j < NPRETAPS; j++ )
+ data_mem[j] = data_mem[ATSC_DATA_SEGMENT_LENGTH + j];
+
+ for(int j = 0; j < ATSC_DATA_SEGMENT_LENGTH; j++)
+ data_mem[NPRETAPS + j] = in[i].data[j];
+
+ d_flags = in[i].pli._flags;
+ d_segno = in[i].pli._segno;
+ }
+
+ consume_each(noutput_items);
+ return output_produced;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_equalizer_impl.h b/gr-dtv/lib/atsc/atsc_equalizer_impl.h
new file mode 100644
index 0000000000..6ff89ca646
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_equalizer_impl.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_EQUALIZER_IMPL_H
+#define INCLUDED_DTV_ATSC_EQUALIZER_IMPL_H
+
+#include <gnuradio/dtv/atsc_equalizer.h>
+#include <gnuradio/dtv/atsc_consts.h>
+#include "atsc_syminfo_impl.h"
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_equalizer_impl : public atsc_equalizer
+ {
+ private:
+ static const int NTAPS = 64;
+ static const int NPRETAPS = (int) (NTAPS * 0.8); // probably should be either .2 or .8
+
+ // the length of the field sync pattern that we know unequivocally
+ static const int KNOWN_FIELD_SYNC_LENGTH = 4 + 511 + 3 * 63;
+
+ float training_sequence1[KNOWN_FIELD_SYNC_LENGTH];
+ float training_sequence2[KNOWN_FIELD_SYNC_LENGTH];
+
+ void filterN(const float *input_samples, float *output_samples, int nsamples);
+ void adaptN(const float *input_samples, const float *training_pattern,
+ float *output_samples, int nsamples);
+
+ float d_taps[NTAPS];
+
+ float data_mem[ATSC_DATA_SEGMENT_LENGTH + NTAPS]; // Buffer for previous data packet
+ float data_mem2[ATSC_DATA_SEGMENT_LENGTH];
+ unsigned short d_flags;
+ short d_segno;
+
+ int d_buff_not_filled;
+
+ public:
+ atsc_equalizer_impl();
+ ~atsc_equalizer_impl();
+
+ virtual int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_EQUALIZER_IMPL_H */
diff --git a/gr-dtv/lib/atsc/atsc_fake_single_viterbi.cc b/gr-dtv/lib/atsc/atsc_fake_single_viterbi.cc
new file mode 100644
index 0000000000..ffe410292e
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_fake_single_viterbi.cc
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "atsc_fake_single_viterbi.h"
+
+namespace gr {
+ namespace dtv {
+
+ void
+ atsc_fake_single_viterbi::reset()
+ {
+ post_coder_state = 0;
+ }
+
+ atsc_fake_single_viterbi::atsc_fake_single_viterbi()
+ {
+ reset();
+ }
+
+ /*
+ * implement simple slicer and post coder
+ */
+ char
+ atsc_fake_single_viterbi::decode(float input)
+ {
+ int y2, y1;
+
+ if (input < -4){
+ y2 = 0;
+ y1 = 0;
+ }
+ else if (input < 0){
+ y2 = 0;
+ y1 = 1;
+ }
+ else if (input < 4){
+ y2 = 1;
+ y1 = 0;
+ }
+ else {
+ y2 = 1;
+ y1 = 1;
+ }
+
+ int x1 = y1;
+ int x2 = y2 ^ post_coder_state;
+ post_coder_state = y2;
+
+ return (x2 << 1) | x1;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_fake_single_viterbi.h b/gr-dtv/lib/atsc/atsc_fake_single_viterbi.h
new file mode 100644
index 0000000000..9ca546a6ab
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_fake_single_viterbi.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_ATSC_FAKE_SINGLE_VITERBI_H
+#define INCLUDED_ATSC_FAKE_SINGLE_VITERBI_H
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_fake_single_viterbi
+ {
+ public:
+ atsc_fake_single_viterbi();
+
+ /*!
+ * \p INPUT ideally takes on the values +/- 1,3,5,7
+ * return is decoded dibit in the range [0, 3]
+ */
+ char decode (float input);
+
+ void reset();
+
+ //! internal delay of decoder
+ int delay() { return 0; }
+
+ protected:
+ int post_coder_state;
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_ATSC_FAKE_SINGLE_VITERBI_H */
diff --git a/gr-dtv/lib/atsc/atsc_fpll_impl.cc b/gr-dtv/lib/atsc/atsc_fpll_impl.cc
new file mode 100644
index 0000000000..2015e350ef
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_fpll_impl.cc
@@ -0,0 +1,95 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atsc_fpll_impl.h"
+#include <gnuradio/io_signature.h>
+#include <gnuradio/math.h>
+#include <gnuradio/sincos.h>
+
+namespace gr {
+ namespace dtv {
+
+ atsc_fpll::sptr
+ atsc_fpll::make(float rate)
+ {
+ return gnuradio::get_initial_sptr
+ (new atsc_fpll_impl(rate));
+ }
+
+ atsc_fpll_impl::atsc_fpll_impl(float rate)
+ : sync_block("dtv_atsc_fpll",
+ io_signature::make(1, 1, sizeof(gr_complex)),
+ io_signature::make(1, 1, sizeof(float)))
+ {
+ d_afc.set_taps(1.0-exp(-1.0/rate/5e-6));
+ d_nco.set_freq((-3e6 + 0.309e6)/rate*2*M_PI);
+ d_nco.set_phase(0.0);
+ }
+
+ atsc_fpll_impl::~atsc_fpll_impl()
+ {
+ }
+
+ int
+ atsc_fpll_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const gr_complex *in = (const gr_complex *)input_items[0];
+ float *out = (float *)output_items[0];
+
+ 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);
+ out[k] = result.real();
+
+ // Update phase/freq error
+ gr_complex filtered = d_afc.filter(result);
+ float x = gr::fast_atan2f(filtered.imag(), filtered.real());
+
+ // avoid slamming filter with big transitions
+ static const float limit = 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;
+ d_nco.adjust_phase(alpha*x);
+ d_nco.adjust_freq(beta*x);
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_fpll_impl.h b/gr-dtv/lib/atsc/atsc_fpll_impl.h
new file mode 100644
index 0000000000..e06fc09cc5
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_fpll_impl.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_FPLL_IMPL_H
+#define INCLUDED_DTV_ATSC_FPLL_IMPL_H
+
+#include <gnuradio/dtv/atsc_fpll.h>
+#include <gnuradio/nco.h>
+#include <gnuradio/filter/single_pole_iir.h>
+#include <gnuradio/analog/agc.h>
+#include <stdio.h>
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_fpll_impl : public atsc_fpll
+ {
+ private:
+ gr::nco<float,float> d_nco;
+ gr::filter::single_pole_iir<gr_complex,gr_complex,float> d_afc;
+
+ public:
+ atsc_fpll_impl(float rate);
+ ~atsc_fpll_impl();
+
+ virtual int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_FPLL_IMPL_H */
diff --git a/gr-dtv/lib/atsc/atsc_fs_checker_impl.cc b/gr-dtv/lib/atsc/atsc_fs_checker_impl.cc
new file mode 100644
index 0000000000..3a39bc794b
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_fs_checker_impl.cc
@@ -0,0 +1,128 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atsc_fs_checker_impl.h"
+#include "atsc_types.h"
+#include "atsc_syminfo_impl.h"
+#include "atsc_pnXXX_impl.h"
+#include "gnuradio/dtv/atsc_consts.h"
+#include <gnuradio/io_signature.h>
+
+static const int PN511_ERROR_LIMIT = 20; // max number of bits wrong
+static const int PN63_ERROR_LIMIT = 5;
+
+namespace gr {
+ namespace dtv {
+
+ atsc_fs_checker::sptr
+ atsc_fs_checker::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new atsc_fs_checker_impl());
+ }
+
+ atsc_fs_checker_impl::atsc_fs_checker_impl()
+ : gr::block("dtv_atsc_fs_checker",
+ io_signature::make(1, 1, sizeof(atsc_soft_data_segment)),
+ io_signature::make(1, 1, sizeof(atsc_soft_data_segment)))
+ {
+ reset();
+ }
+
+ void
+ atsc_fs_checker_impl::reset()
+ {
+ d_index = 0;
+ memset (d_sample_sr, 0, sizeof (d_sample_sr));
+ memset (d_tag_sr, 0, sizeof (d_tag_sr));
+ memset (d_bit_sr, 0, sizeof (d_bit_sr));
+ d_field_num = 0;
+ d_segment_num = 0;
+ }
+
+ atsc_fs_checker_impl::~atsc_fs_checker_impl()
+ {
+ }
+
+ int
+ atsc_fs_checker_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const atsc_soft_data_segment *in = (const atsc_soft_data_segment *) input_items[0];
+ atsc_soft_data_segment *out = (atsc_soft_data_segment *) output_items[0];
+
+ int output_produced = 0;
+
+ for (int i = 0; i < noutput_items; i++) {
+ // check for a hit on the PN 511 pattern
+ int errors = 0;
+
+ for (int j = 0; j < LENGTH_511 && errors < PN511_ERROR_LIMIT; j++)
+ errors += (in[i].data[j + OFFSET_511] >= 0) ^ atsc_pn511[j];
+
+ //std::cout << errors << std::endl;
+
+ if (errors < PN511_ERROR_LIMIT) { // 511 pattern is good.
+ // determine if this is field 1 or field 2
+ errors = 0;
+ for (int j = 0; j < LENGTH_2ND_63; j++)
+ errors += (in[i].data[j + OFFSET_2ND_63] >= 0) ^ atsc_pn63[j];
+
+ // we should have either field 1 (== PN63) or field 2 (== ~PN63)
+ if (errors <= PN63_ERROR_LIMIT) {
+ //std::cout << "Found FIELD_SYNC_1" << std::endl;
+ d_field_num = 1; // We are in field number 1 now
+ d_segment_num = -1; // This is the first segment
+ }
+ else if (errors >= (LENGTH_2ND_63 - PN63_ERROR_LIMIT)) {
+ //std::cout << "Found FIELD_SYNC_2" << std::endl;
+ d_field_num = 2; // We are in field number 2 now
+ d_segment_num = -1; // This is the first segment
+ }
+ else {
+ // should be extremely rare.
+ std::cerr << "!!! atsc_fs_checker: PN63 error count = " << errors << std::endl;
+ }
+ }
+
+ if( d_field_num == 1 || d_field_num == 2 ) { // If we have sync
+ // So we copy out current packet data to an output packet and fill its plinfo
+ for( int j = 0; j < ATSC_DATA_SEGMENT_LENGTH; j++ )
+ out[output_produced].data[j] = in[i].data[j];
+ out[output_produced].pli.set_regular_seg((d_field_num == 2), d_segment_num);
+ d_segment_num++;
+ output_produced++;
+ }
+ }
+
+ consume_each(noutput_items);
+ return output_produced;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_fs_checker_impl.h b/gr-dtv/lib/atsc/atsc_fs_checker_impl.h
new file mode 100644
index 0000000000..1210ae5830
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_fs_checker_impl.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_FS_CHECKER_IMPL_H
+#define INCLUDED_DTV_ATSC_FS_CHECKER_IMPL_H
+
+#include <gnuradio/dtv/atsc_fs_checker.h>
+#include "atsc_syminfo_impl.h"
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_fs_checker_impl : public atsc_fs_checker
+ {
+ private:
+ static const int SRSIZE = 1024; // must be power of two
+ int d_index; // points at oldest sample
+ float d_sample_sr[SRSIZE]; // sample shift register
+ atsc::syminfo d_tag_sr[SRSIZE]; // tag shift register
+ unsigned char d_bit_sr[SRSIZE]; // binary decision shift register
+ int d_field_num;
+ int d_segment_num;
+
+ static const int OFFSET_511 = 4; // offset to second PN 63 pattern
+ static const int LENGTH_511 = 511; // length of PN 63 pattern
+ static const int OFFSET_2ND_63 = 578; // offset to second PN 63 pattern
+ static const int LENGTH_2ND_63 = 63; // length of PN 63 pattern
+
+ inline static int wrap (int index){ return index & (SRSIZE - 1); }
+ inline static int incr (int index){ return wrap (index + 1); }
+ inline static int decr (int index){ return wrap (index - 1); }
+
+ public:
+ atsc_fs_checker_impl();
+ ~atsc_fs_checker_impl();
+
+ void reset();
+
+ virtual int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_FS_CHECKER_IMPL_H */
diff --git a/gr-dtv/lib/atsc/atsc_interleaver_fifo.h b/gr-dtv/lib/atsc/atsc_interleaver_fifo.h
new file mode 100644
index 0000000000..0d40389c74
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_interleaver_fifo.h
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_INTERLEAVER_FIFO_H
+#define INCLUDED_DTV_ATSC_INTERLEAVER_FIFO_H
+
+#include <string.h>
+
+namespace gr {
+ namespace dtv {
+
+ template<class symbol_type>
+ class interleaver_fifo {
+ public:
+
+ interleaver_fifo(unsigned int size);
+ ~interleaver_fifo();
+
+ //! reset interleaver (flushes contents and resets commutator)
+ void reset ();
+
+ //! stuff a symbol into the fifo and return the oldest
+ symbol_type stuff(symbol_type input) {
+ if (m_size == 0)
+ return input;
+
+ symbol_type retval = m_fifo[m_position];
+ m_fifo[m_position] = input;
+ m_position++;
+ if (m_position >= m_size)
+ m_position = 0;
+
+ return retval;
+ }
+
+ protected:
+ unsigned int m_size;
+ unsigned int m_position;
+ symbol_type *m_fifo;
+ };
+
+ template<class symbol_type>
+ interleaver_fifo<symbol_type>::interleaver_fifo(unsigned int size)
+ {
+ m_size = size;
+ m_position = 0;
+ m_fifo = new symbol_type[size];
+ memset (m_fifo, 0, m_size * sizeof(symbol_type));
+ }
+
+ template<class symbol_type>
+ interleaver_fifo<symbol_type>::~interleaver_fifo()
+ {
+ delete [] m_fifo;
+ }
+
+ template<class symbol_type> void
+ interleaver_fifo<symbol_type>::reset()
+ {
+ m_position = 0;
+ memset (m_fifo, 0, m_size * sizeof (symbol_type));
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_INTERLEAVER_FIFO_H */
diff --git a/gr-dtv/lib/atsc/atsc_pnXXX_impl.h b/gr-dtv/lib/atsc/atsc_pnXXX_impl.h
new file mode 100644
index 0000000000..d4b86dcdbb
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_pnXXX_impl.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_PNXXX_H
+#define INCLUDED_DTV_ATSC_PNXXX_H
+
+#include <gnuradio/dtv/api.h>
+
+const unsigned char atsc_pn511[511] = {
+ 0,0,0,0, 0,0,0,1, 0,1,1,1, 1,1,1,1, 1,1,0,0, 1,0,1,0, 1,0,1,0, 1,1,1,0,
+ 0,1,1,0, 0,1,1,0, 1,0,0,0, 1,0,0,0, 1,0,0,1, 1,1,1,0, 0,0,0,1, 1,1,0,1,
+
+ 0,1,1,1, 1,1,0,1, 0,0,1,1, 0,1,0,1, 0,0,1,1, 1,0,1,1, 0,0,1,1, 1,0,1,0,
+ 0,1,0,0, 0,1,0,1, 1,0,0,0, 1,1,1,1, 0,0,1,0, 0,0,0,1, 0,1,0,0, 0,1,1,1,
+
+ 1,1,0,0, 1,1,1,1, 0,1,0,1, 0,0,0,1, 0,1,0,0, 1,1,0,0, 0,0,1,1, 0,0,0,1,
+ 0,0,0,0, 0,1,0,0, 0,0,1,1, 1,1,1,1, 0,0,0,0, 0,1,0,1, 0,1,0,0, 0,0,0,0,
+
+ 1,1,0,0, 1,1,1,1, 1,1,1,0, 1,1,1,0, 1,0,1,0, 1,0,0,1, 0,1,1,0, 0,1,1,0,
+ 0,0,1,1, 0,1,1,1, 0,1,1,1, 1,0,1,1, 0,1,0,0, 1,0,1,0, 0,1,0,0, 1,1,1,0,
+
+ 0,1,1,1, 0,0,0,1, 0,1,1,1, 0,1,0,0, 0,0,1,1, 0,1,0,0, 1,1,1,1, 1,0,1,1,
+ 0,0,0,1, 0,1,0,1, 1,0,1,1, 1,1,0,0, 1,1,0,1, 1,0,1,0, 1,1,1,0, 1,1,0,1,
+
+ 1,0,0,1, 0,1,1,0, 1,1,0,1, 1,1,0,0, 1,0,0,1, 0,0,1,0, 1,1,1,0, 0,0,1,1,
+ 1,0,0,1, 0,1,1,1, 1,0,1,0, 0,0,1,1, 0,1,0,1, 1,0,0,0, 0,1,0,0, 1,1,0,1,
+
+ 1,1,1,1, 0,0,0,1, 0,0,1,0, 1,0,1,1, 1,1,0,0, 0,1,1,0, 0,1,0,1, 0,0,0,0,
+ 1,0,0,0, 1,1,0,0, 0,0,0,1, 1,1,1,0, 1,1,1,1, 1,1,0,1, 0,1,1,0, 1,0,1,0,
+
+ 1,1,0,0, 1,0,0,1, 1,0,0,1, 0,0,0,1, 1,1,0,1, 1,1,0,0, 0,0,1,0, 1,1,0,1,
+ 0,0,0,0, 0,1,1,0, 1,1,0,0, 0,0,0,0, 1,0,0,1, 0,0,0,0, 0,0,0,1, 1,1,0
+};
+
+const unsigned char atsc_pn63[63] = {
+ 1,1,1,0, 0,1,0,0, 1,0,1,1, 0,1,1,1, 0,1,1,0, 0,1,1,0, 1,0,1,0, 1,1,1,1,
+ 1,1,0,0, 0,0,0,1, 0,0,0,0, 1,1,0,0, 0,1,0,1, 0,0,1,1, 1,1,0,1, 0,0,0
+};
+
+#endif /* INCLUDED_DTV_ATSC_PNXXX_H */
diff --git a/gr-dtv/lib/atsc/atsc_randomize.cc b/gr-dtv/lib/atsc/atsc_randomize.cc
new file mode 100644
index 0000000000..769b08587a
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_randomize.cc
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "atsc_randomize.h"
+
+namespace gr {
+ namespace dtv {
+
+ unsigned char atsc_randomize::s_output_map[1 << 14];
+ bool atsc_randomize::s_output_map_initialized_p = false;
+
+ atsc_randomize::atsc_randomize ()
+ {
+ d_state = PRELOAD_VALUE;
+
+ if (!s_output_map_initialized_p)
+ initialize_output_map ();
+ }
+
+ /*!
+ * \brief Generate the table used in the fast_output_map function.
+ *
+ * The table has 16K byte entries, but because of how is is used, only
+ * 256 entries end up being resident in the cache. This seems
+ * like a good use of memory. We can get away with a 16K table
+ * because the low two bits of the state do not affect the output
+ * function. By shifting right those two bits we shrink the table,
+ * and also get better cache line utilization.
+ */
+ void
+ atsc_randomize::initialize_output_map ()
+ {
+ s_output_map_initialized_p = true;
+
+ for (int i = 0; i < (1 << 14); i++)
+ s_output_map[i] = slow_output_map (i << 2);
+ }
+
+
+ void
+ atsc_randomize::reset ()
+ {
+ d_state = PRELOAD_VALUE;
+ }
+
+ void
+ atsc_randomize::randomize (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet &in)
+ {
+ assert (in.data[0] == MPEG_SYNC_BYTE); // confirm it's there, then drop
+
+ for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++)
+ out.data[i] = in.data[i + 1] ^ output_and_clk ();
+ }
+
+ void
+ atsc_randomize::derandomize (atsc_mpeg_packet &out, const atsc_mpeg_packet_no_sync &in)
+ {
+ out.data[0] = MPEG_SYNC_BYTE; // add sync byte to beginning of packet
+
+ for (int i = 0; i < ATSC_MPEG_DATA_LENGTH; i++)
+ out.data[i + 1] = in.data[i] ^ output_and_clk ();
+ }
+
+
+ unsigned char
+ atsc_randomize::slow_output_map (int st)
+ {
+ int output = 0;
+
+ if (st & 0x8000)
+ output |= 0x01;
+
+ if (st & 0x2000)
+ output |= 0x02;
+
+ if (st & 0x1000)
+ output |= 0x04;
+
+ if (st & 0x0200)
+ output |= 0x08;
+
+ if (st & 0x0020)
+ output |= 0x10;
+
+ if (st & 0x0010)
+ output |= 0x20;
+
+ if (st & 0x0008)
+ output |= 0x40;
+
+ if (st & 0x0004)
+ output |= 0x80;
+
+ return output;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_randomize.h b/gr-dtv/lib/atsc/atsc_randomize.h
new file mode 100644
index 0000000000..0903240f48
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_randomize.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_ATSC_RANDOMIZE_H
+#define INCLUDED_ATSC_RANDOMIZE_H
+
+#include "atsc_types.h"
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_randomize
+ {
+ public:
+ atsc_randomize();
+
+ /*! \brief reset randomizer LFSR
+ *
+ * must be called during the Data Segment Sync interval prior to the
+ * first data segment. I.e., the LFSR is reset prior to the first
+ * field of each VSB data frame.
+ */
+ void reset ();
+
+ //! randomize (whiten) mpeg packet and remove leading MPEG-2 sync byte
+ void randomize (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet &in);
+
+ //! derandomize (de-whiten) mpeg packet and add leading MPEG-2 sync byte
+ void derandomize (atsc_mpeg_packet &out, const atsc_mpeg_packet_no_sync &in);
+
+ unsigned int state() const { return d_state; }
+ private:
+ static void initialize_output_map ();
+ static unsigned char slow_output_map (int st);
+
+ static unsigned char fast_output_map (int st){
+ return s_output_map[(st & 0xb23c) >> 2]; // Magic const with 8 bits set improves cache
+ // utilization. The bits correspond to the taps
+ // used in output calculation. Others may be
+ // safely ignored.
+ }
+
+ //! return current output value
+ unsigned char output (){
+ return fast_output_map (d_state);
+ }
+
+ //! clock LFSR; advance to next state.
+ void clk (){
+ if (d_state & 0x1)
+ d_state = ((d_state ^ MASK) >> 1) | 0x8000;
+ else
+ d_state = d_state >> 1;
+ }
+
+ //! return current output value and advance to next state
+ unsigned char output_and_clk (){
+ unsigned char r = output ();
+ clk ();
+ return r;
+ }
+
+ unsigned int d_state;
+
+ static const unsigned int PRELOAD_VALUE = 0x018f; /* 0xf180 bit reversed */
+ static const unsigned int MASK = 0xa638;
+ static unsigned char s_output_map[1 << 14];
+ static bool s_output_map_initialized_p;
+ };
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_ATSC_RANDOMIZE_H */
diff --git a/gr-dtv/lib/atsc/atsc_rs_decoder_impl.cc b/gr-dtv/lib/atsc/atsc_rs_decoder_impl.cc
new file mode 100644
index 0000000000..7a950e716e
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_rs_decoder_impl.cc
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atsc_rs_decoder_impl.h"
+#include "gnuradio/dtv/atsc_consts.h"
+#include <gnuradio/io_signature.h>
+
+namespace gr {
+ namespace dtv {
+
+ static const int rs_init_symsize = 8;
+ static const int rs_init_gfpoly = 0x11d;
+ static const int rs_init_fcr = 0; // first consecutive root
+ static const int rs_init_prim = 1; // primitive is 1 (alpha)
+ static const int rs_init_nroots = 20;
+
+ static const int N = (1 << rs_init_symsize) - 1; // 255
+ static const int K = N - rs_init_nroots; // 235
+
+ static const int amount_of_pad = N - ATSC_MPEG_RS_ENCODED_LENGTH; // 48
+
+ atsc_rs_decoder::sptr
+ atsc_rs_decoder::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new atsc_rs_decoder_impl());
+ }
+
+ atsc_rs_decoder_impl::atsc_rs_decoder_impl()
+ : gr::sync_block("dtv_atsc_rs_decoder",
+ io_signature::make(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)),
+ io_signature::make(1, 1, sizeof(atsc_mpeg_packet_no_sync)))
+ {
+ d_rs = init_rs_char(rs_init_symsize, rs_init_gfpoly, rs_init_fcr, rs_init_prim, rs_init_nroots);
+ assert (d_rs != 0);
+ nerrors_corrrected_count = 0;
+ bad_packet_count = 0;
+ total_packets = 0;
+ }
+
+ int atsc_rs_decoder_impl::decode (atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet_rs_encoded &in)
+ {
+ unsigned char tmp[N];
+ int ncorrections;
+
+ assert((int)(amount_of_pad + sizeof(in.data)) == N);
+
+ // add missing prefix zero padding to message
+ memset(tmp, 0, amount_of_pad);
+ memcpy(&tmp[amount_of_pad], in.data, sizeof(in.data));
+
+ // correct message...
+ ncorrections = decode_rs_char(d_rs, tmp, 0, 0);
+
+ // copy corrected message to output, skipping prefix zero padding
+ memcpy (out.data, &tmp[amount_of_pad], sizeof (out.data));
+
+ return ncorrections;
+ }
+
+ atsc_rs_decoder_impl::~atsc_rs_decoder_impl()
+ {
+ if (d_rs)
+ free_rs_char (d_rs);
+ d_rs = 0;
+ }
+
+ int
+ atsc_rs_decoder_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const atsc_mpeg_packet_rs_encoded *in = (const atsc_mpeg_packet_rs_encoded *)input_items[0];
+ atsc_mpeg_packet_no_sync *out = (atsc_mpeg_packet_no_sync *)output_items[0];
+
+ for (int i = 0; i < noutput_items; i++) {
+ assert(in[i].pli.regular_seg_p());
+ out[i].pli = in[i].pli; // copy pipeline info...
+
+ int nerrors_corrrected = decode(out[i], in[i]);
+ out[i].pli.set_transport_error(nerrors_corrrected == -1);
+ if (nerrors_corrrected == -1)
+ bad_packet_count++;
+ else
+ nerrors_corrrected_count += nerrors_corrrected;
+
+ total_packets++;
+ #if 0
+ if (total_packets > 1000) {
+ // FIXME: convert to logger
+ std::cout << "Error rate: "
+ << (float)nerrors_corrrected_count/total_packets
+ << "\tPacket error rate: "
+ << (float)bad_packet_count/total_packets
+ << std::endl;
+
+ nerrors_corrrected_count = 0;
+ bad_packet_count = 0;
+ total_packets = 0;
+ }
+ #endif
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_rs_decoder_impl.h b/gr-dtv/lib/atsc/atsc_rs_decoder_impl.h
new file mode 100644
index 0000000000..57460128dc
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_rs_decoder_impl.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_RS_DECODER_IMPL_H
+#define INCLUDED_DTV_ATSC_RS_DECODER_IMPL_H
+
+#include <gnuradio/dtv/atsc_rs_decoder.h>
+#include "atsc_types.h"
+
+extern "C" {
+#include <gnuradio/fec/rs.h>
+}
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_rs_decoder_impl : public atsc_rs_decoder
+ {
+ private:
+ int nerrors_corrrected_count;
+ int bad_packet_count;
+ int total_packets;
+ void *d_rs;
+
+ public:
+ atsc_rs_decoder_impl();
+ ~atsc_rs_decoder_impl();
+
+ /*!
+ * Decode RS encoded packet.
+ * \returns a count of corrected symbols, or -1 if the block was uncorrectible.
+ */
+ int decode(atsc_mpeg_packet_no_sync &out, const atsc_mpeg_packet_rs_encoded &in);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_RS_DECODER_IMPL_H */
diff --git a/gr-dtv/lib/atsc/atsc_single_viterbi.cc b/gr-dtv/lib/atsc/atsc_single_viterbi.cc
new file mode 100644
index 0000000000..385940e453
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_single_viterbi.cc
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002, 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "atsc_single_viterbi.h"
+#include <math.h>
+
+namespace gr {
+ namespace dtv {
+
+ /* was_sent is a table of what symbol we get given what bit pair
+ was sent and what state we where in [state][pair] */
+ const int atsc_single_viterbi::was_sent[4][4] = {
+ {0,2,4,6},
+ {0,2,4,6},
+ {1,3,5,7},
+ {1,3,5,7},
+ };
+
+ /* transition_table is a table of what state we were in
+ given current state and bit pair sent [state][pair] */
+ const int atsc_single_viterbi::transition_table[4][4] = {
+ {0,2,0,2},
+ {2,0,2,0},
+ {1,3,1,3},
+ {3,1,3,1},
+ };
+
+ void
+ atsc_single_viterbi::reset()
+ {
+ for (unsigned int i = 0; i<2; i++)
+ for (unsigned int j = 0; j<4; j++) {
+ path_metrics[i][j] = 0;
+ traceback[i][j] = 0;
+ }
+ post_coder_state = 0;
+ phase = 0;
+ }
+
+ atsc_single_viterbi::atsc_single_viterbi()
+ {
+ reset();
+ }
+
+ char
+ atsc_single_viterbi::decode(float input)
+ {
+ unsigned int best_state = 0;
+ float best_state_metric = 100000;
+
+ /* Precompute distances from input to each possible symbol */
+ float distances[8] = { (float)fabs( input + 7 ), (float)fabs( input + 5 ),
+ (float)fabs( input + 3 ), (float)fabs( input + 1 ),
+ (float)fabs( input - 1 ), (float)fabs( input - 3 ),
+ (float)fabs( input - 5 ), (float)fabs( input - 7 ) };
+
+ /* We start by iterating over all possible states */
+ for (unsigned int state = 0; state < 4; state++) {
+ /* Next we find the most probable path from the previous
+ states to the state we are testing, we only need to look at
+ the 4 paths that can be taken given the 2-bit input */
+ int min_metric_symb = 0;
+ float min_metric = distances[was_sent[state][0]] + path_metrics[phase][transition_table[state][0]];
+ for (unsigned int symbol_sent = 1; symbol_sent < 4; symbol_sent++)
+ if( (distances[was_sent[state][symbol_sent]] + path_metrics[phase][transition_table[state][symbol_sent]]) < min_metric) {
+ min_metric = distances[was_sent[state][symbol_sent]] + path_metrics[phase][transition_table[state][symbol_sent]];
+ min_metric_symb = symbol_sent;
+ }
+
+ path_metrics[phase^1][state] = min_metric;
+ traceback[phase^1][state] = (((unsigned long long)min_metric_symb) << 62) | (traceback[phase][transition_table[state][min_metric_symb]] >> 2);
+
+ /* If this is the most probable state so far remember it, this
+ only needs to be checked when we are about to output a path
+ so this test can be saved till later if needed, if perfomed
+ later it could also be optimized with SIMD instructions.
+ Even better this check could be eliminated as we are
+ outputing the tail of our traceback not the head, for any
+ head state path will tend towards the optimal path with a
+ probability approaching 1 in just 8 or so transitions
+ */
+ if(min_metric <= best_state_metric) {
+ best_state_metric = min_metric;
+ best_state = state;
+ }
+ }
+
+ if(best_state_metric > 10000) {
+ for(unsigned int state = 0; state < 4; state++)
+ path_metrics[phase^1][state] -= best_state_metric;
+ }
+ phase ^= 1;
+
+ int y2 = (0x2 & traceback[phase][best_state]) >> 1;
+ int x2 = y2 ^ post_coder_state;
+ post_coder_state = y2;
+
+ return ( x2 << 1 ) | (0x1 & traceback[phase][best_state]);
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+
diff --git a/gr-dtv/lib/atsc/atsc_single_viterbi.h b/gr-dtv/lib/atsc/atsc_single_viterbi.h
new file mode 100644
index 0000000000..3c756c7690
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_single_viterbi.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002, 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_SINGLE_VITERBI_H
+#define INCLUDED_DTV_ATSC_SINGLE_VITERBI_H
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_single_viterbi
+ {
+ public:
+ atsc_single_viterbi();
+
+ static const unsigned int TB_LEN = 32;
+
+ /*!
+ * \p INPUT ideally takes on the values +/- 1,3,5,7
+ * return is decoded dibit in the range [0, 3]
+ */
+ char decode(float input);
+
+ void reset ();
+
+ //! internal delay of decoder
+ static int delay () { return TB_LEN - 1; }
+
+ protected:
+ static const int transition_table[4][4];
+ static const int was_sent[4][4];
+
+ float path_metrics [2][4];
+ unsigned long long traceback [2][4];
+ unsigned char phase;
+ int post_coder_state;
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_SINGLE_VITERBI_H */
diff --git a/gr-dtv/lib/atsc/atsc_syminfo_impl.h b/gr-dtv/lib/atsc/atsc_syminfo_impl.h
new file mode 100644
index 0000000000..4a5008e5f8
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_syminfo_impl.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_DTV_ATSC_SYMINFO_H
+#define INCLUDED_GR_DTV_ATSC_SYMINFO_H
+
+namespace gr {
+ namespace dtv {
+ namespace atsc {
+
+ static const unsigned int SI_SEGMENT_NUM_MASK = 0x1ff;
+ static const unsigned int SI_FIELD_SYNC_SEGMENT_NUM = SI_SEGMENT_NUM_MASK; // conceptually -1
+
+ struct syminfo {
+ unsigned int symbol_num : 10; // 0..831
+ unsigned int segment_num : 9; // 0..311 and SI_FIELD_SYNC_SEGMENT_NUM
+ unsigned int field_num : 1; // 0..1
+ unsigned int valid : 1; // contents are valid
+ };
+
+
+ static inline bool
+ tag_is_start_field_sync (syminfo tag)
+ {
+ return tag.symbol_num == 0 && tag.segment_num == SI_FIELD_SYNC_SEGMENT_NUM && tag.valid;
+ }
+
+ static inline bool
+ tag_is_start_field_sync_1 (syminfo tag)
+ {
+ return tag_is_start_field_sync (tag) && tag.field_num == 0;
+ }
+
+ static inline bool
+ tag_is_start_field_sync_2 (syminfo tag)
+ {
+ return tag_is_start_field_sync (tag) && tag.field_num == 1;
+ }
+
+ } /* namespace atsc */
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_DTV_ATSC_SYMINFO_H */
diff --git a/gr-dtv/lib/atsc/atsc_sync_impl.cc b/gr-dtv/lib/atsc/atsc_sync_impl.cc
new file mode 100644
index 0000000000..ec46d6b8d1
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_sync_impl.cc
@@ -0,0 +1,196 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "atsc_sync_impl.h"
+#include "atsc_types.h"
+#include <gnuradio/io_signature.h>
+
+namespace gr {
+ namespace dtv {
+
+ atsc_sync::sptr
+ atsc_sync::make(float rate)
+ {
+ return gnuradio::get_initial_sptr
+ (new atsc_sync_impl(rate));
+ }
+
+ atsc_sync_impl::atsc_sync_impl(float rate)
+ : gr::block("dtv_atsc_sync",
+ io_signature::make(1, 1, sizeof(float)),
+ io_signature::make(1, 1, sizeof(atsc_soft_data_segment))),
+ d_next_input(0), d_rx_clock_to_symbol_freq(rate/ATSC_SYMBOL_RATE),
+ d_si(0)
+ {
+ d_loop.set_taps(LOOP_FILTER_TAP);
+ reset();
+ }
+
+ void
+ atsc_sync_impl::reset()
+ {
+ d_w = d_rx_clock_to_symbol_freq;
+ d_mu = 0.5;
+
+ for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++)
+ sample_mem[i] = 0;
+
+ d_timing_adjust = 0;
+ d_counter = 0;
+ d_symbol_index = 0;
+ d_seg_locked = false;
+
+ d_sr = 0;
+
+ for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++)
+ d_integrator[i] = SSI_MIN;
+ }
+
+ atsc_sync_impl::~atsc_sync_impl()
+ {
+ }
+
+ void
+ atsc_sync_impl::forecast(int noutput_items,
+ gr_vector_int &ninput_items_required)
+ {
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = static_cast<int>(noutput_items * d_rx_clock_to_symbol_freq * ATSC_DATA_SEGMENT_LENGTH) + 1500 - 1;
+ }
+
+ int
+ atsc_sync_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const float *in = (const float *) input_items[0];
+ atsc_soft_data_segment *soft_data_segment_out = (atsc_soft_data_segment *) output_items[0];
+
+ float interp_sample;
+
+ // amount actually consumed
+ d_si = 0;
+
+ for (output_produced = 0; output_produced < noutput_items && (d_si + (int)d_interp.ntaps()) < ninput_items[0];) {
+ // First we interpolate a sample from input to work with
+ interp_sample = d_interp.interpolate(&in[d_si], d_mu);
+
+ // Apply our timing adjustment slowly over several samples
+ d_mu += ADJUSTMENT_GAIN * 1e3 * d_timing_adjust;
+
+ double s = d_mu + d_w;
+ double float_incr = floor(s);
+ d_mu = s - float_incr;
+ d_incr = (int)float_incr;
+
+ assert (d_incr >= 1 && d_incr <= 3);
+ d_si += d_incr;
+
+ // Remember the sample at this count position
+ sample_mem[d_counter] = interp_sample;
+
+ // Is the sample positive or negative?
+ int bit = (interp_sample < 0 ? 0 : 1);
+
+ // Put the sign bit into our shift register
+ d_sr = ((bit & 1) << 3) | (d_sr >> 1);
+
+ // When +,-,-,+ (0x9, 1001) samples show up we have likely found a segment
+ // sync, it is more likely the segment sync will show up at about the same
+ // spot every ATSC_DATA_SEGMENT_LENGTH samples so we add some weight
+ // to this spot every pass to prevent random +,-,-,+ symbols from
+ // confusing our synchronizer
+ d_integrator[d_counter] += ((d_sr == 0x9) ? +2 : -1);
+ if(d_integrator[d_counter] < SSI_MIN) d_integrator[d_counter] = SSI_MIN;
+ if(d_integrator[d_counter] > SSI_MAX) d_integrator[d_counter] = SSI_MAX;
+
+ d_symbol_index++;
+ if( d_symbol_index >= ATSC_DATA_SEGMENT_LENGTH )
+ d_symbol_index = 0;
+
+ d_counter++;
+ if( d_counter >= ATSC_DATA_SEGMENT_LENGTH ) { // counter just wrapped...
+ int best_correlation_value = d_integrator[0];
+ int best_correlation_index = 0;
+
+ for(int i = 1; i < ATSC_DATA_SEGMENT_LENGTH; i++)
+ if (d_integrator[i] > best_correlation_value) {
+ best_correlation_value = d_integrator[i];
+ best_correlation_index = i;
+ }
+
+ d_seg_locked = best_correlation_value >= MIN_SEG_LOCK_CORRELATION_VALUE;
+
+ // the coefficients are -1,-1,+1,+1
+ //d_timing_adjust = sample_mem[best_correlation_index - 3] +
+ // sample_mem[best_correlation_index - 2] -
+ // sample_mem[best_correlation_index - 1] -
+ // sample_mem[best_correlation_index];
+
+ //printf( "d_timing_adjust = %f\n", d_timing_adjust );
+
+ int corr_count = best_correlation_index;
+
+ d_timing_adjust = -sample_mem[corr_count--];
+ if( corr_count < 0 ) corr_count = ATSC_DATA_SEGMENT_LENGTH - 1;
+ d_timing_adjust -= sample_mem[corr_count--];
+ if( corr_count < 0 ) corr_count = ATSC_DATA_SEGMENT_LENGTH - 1;
+ d_timing_adjust += sample_mem[corr_count--];
+ if( corr_count < 0 ) corr_count = ATSC_DATA_SEGMENT_LENGTH - 1;
+ d_timing_adjust += sample_mem[corr_count--];
+
+ d_symbol_index = SYMBOL_INDEX_OFFSET - 1 - best_correlation_index;
+ if (d_symbol_index < 0)
+ d_symbol_index += ATSC_DATA_SEGMENT_LENGTH;
+
+ d_counter = 0;
+ }
+
+ // If we are locked we can start filling and producing data packets
+ // Due to the way we lock the first data packet will almost always be
+ // half full, this is OK becouse the fs_checker will not let packets though
+ // untill a non-corrupted field packet is found
+ if( d_seg_locked ) {
+ data_mem[d_symbol_index] = interp_sample;
+
+ if( d_symbol_index >= (ATSC_DATA_SEGMENT_LENGTH - 1) )
+ {
+ for( int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++ )
+ soft_data_segment_out[output_produced].data[i] = data_mem[i];
+ output_produced++;
+ }
+ }
+ }
+
+ consume_each(d_si);
+ return output_produced;
+
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_sync_impl.h b/gr-dtv/lib/atsc/atsc_sync_impl.h
new file mode 100644
index 0000000000..eb0ad17286
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_sync_impl.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_SYNC_IMPL_H
+#define INCLUDED_DTV_ATSC_SYNC_IMPL_H
+
+#include <gnuradio/dtv/atsc_consts.h>
+#include <gnuradio/dtv/atsc_sync.h>
+#include <gnuradio/filter/single_pole_iir.h>
+#include <gnuradio/filter/mmse_fir_interpolator_ff.h>
+
+namespace gr {
+ namespace dtv {
+
+ class atsc_sync_impl : public atsc_sync
+ {
+ private:
+ static const double LOOP_FILTER_TAP = 0.0005; // 0.0005 works
+ static const double ADJUSTMENT_GAIN = 1.0e-5 / (10 * ATSC_DATA_SEGMENT_LENGTH);
+ static const int SYMBOL_INDEX_OFFSET = 3;
+ static const int MIN_SEG_LOCK_CORRELATION_VALUE = 5;
+ static const int SSI_MIN = -16;
+ static const int SSI_MAX = 15;
+
+ gr::filter::single_pole_iir<float,float,float> d_loop; // ``VCO'' loop filter
+ gr::filter::mmse_fir_interpolator_ff d_interp;
+
+ unsigned long long d_next_input;
+ double d_rx_clock_to_symbol_freq;
+ int d_si;
+ double d_w; // ratio of PERIOD of Tx to Rx clocks
+ double d_mu; // fractional delay [0,1]
+ int d_incr;
+
+ float sample_mem[ATSC_DATA_SEGMENT_LENGTH];
+ float data_mem[ATSC_DATA_SEGMENT_LENGTH];
+
+ double d_timing_adjust;
+ int d_counter; // free running mod 832 counter
+ int d_symbol_index;
+ bool d_seg_locked;
+ int d_sr; // 4 bit shift register
+ signed char d_integrator[ATSC_DATA_SEGMENT_LENGTH];
+ int output_produced;
+
+ public:
+ atsc_sync_impl(float rate);
+ ~atsc_sync_impl();
+
+ void reset();
+
+ void forecast(int noutput_items,
+ gr_vector_int &ninput_items_required);
+
+ virtual int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_SYNC_IMPL_H */
diff --git a/gr-dtv/lib/atsc/atsc_types.h b/gr-dtv/lib/atsc/atsc_types.h
new file mode 100644
index 0000000000..e9f82bae8c
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_types.h
@@ -0,0 +1,269 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2006,2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DTV_INCLUDED_ATSC_TYPES_H
+#define DTV_INCLUDED_ATSC_TYPES_H
+
+#include <gnuradio/dtv/atsc_consts.h>
+#include <cstring>
+#include <cassert>
+
+namespace gr {
+ namespace dtv {
+
+ /*!
+ * \brief pipeline info that flows with data
+ *
+ * Not all modules need all the info
+ */
+ class plinfo {
+ public:
+ plinfo () : _flags (0), _segno (0) { }
+
+ // accessors
+
+ bool field_sync1_p () const { return (_flags & fl_field_sync1) != 0; }
+ bool field_sync2_p () const { return (_flags & fl_field_sync2) != 0; }
+ bool field_sync_p () const { return field_sync1_p () || field_sync2_p (); }
+
+ bool regular_seg_p () const { return (_flags & fl_regular_seg) != 0; }
+
+ bool in_field1_p () const { return (_flags & fl_field2) == 0; }
+ bool in_field2_p () const { return (_flags & fl_field2) != 0; }
+
+ bool first_regular_seg_p () const { return (_flags & fl_first_regular_seg) != 0; }
+
+ bool transport_error_p () const { return (_flags & fl_transport_error) != 0; }
+
+ unsigned int segno () const { return _segno; }
+ unsigned int flags () const { return _flags; }
+
+ // setters
+
+ void set_field_sync1 ()
+ {
+ _segno = 0;
+ _flags = fl_field_sync1;
+ }
+
+ void set_field_sync2 ()
+ {
+ _segno = 0;
+ _flags = fl_field_sync2 | fl_field2;
+ }
+
+ void set_regular_seg (bool field2, int segno)
+ {
+ //assert (0 <= segno && segno < ATSC_DSEGS_PER_FIELD);
+ _segno = segno;
+ _flags = fl_regular_seg;
+ if (segno == 0)
+ _flags |= fl_first_regular_seg;
+ if (segno >= ATSC_DSEGS_PER_FIELD)
+ _flags |= fl_transport_error;
+ if (field2)
+ _flags |= fl_field2;
+ }
+
+ void set_transport_error (bool error){
+ if (error)
+ _flags |= fl_transport_error;
+ else
+ _flags &= ~fl_transport_error;
+ }
+
+ // overload equality operator
+ bool operator== (const plinfo &other) const {
+ return (_flags == other._flags && _segno == other._segno);
+ }
+
+ bool operator!= (const plinfo &other) const {
+ return !(_flags == other._flags && _segno == other._segno);
+ }
+
+ /*!
+ * Set \p OUT such that it reflects a \p NSEGS_OF_DELAY
+ * pipeline delay from \p IN.
+ */
+ static void delay (plinfo &out, const plinfo &in, int nsegs_of_delay)
+ {
+ assert (in.regular_seg_p ());
+ assert (nsegs_of_delay >= 0);
+
+ int s = in.segno ();
+ if (in.in_field2_p ())
+ s += ATSC_DSEGS_PER_FIELD;
+
+ s -= nsegs_of_delay;
+ if (s < 0)
+ s += 2 * ATSC_DSEGS_PER_FIELD;
+
+ //assert (0 <= s && s < 2 * ATSC_DSEGS_PER_FIELD);
+
+ if (s < ATSC_DSEGS_PER_FIELD)
+ out.set_regular_seg (false, s); // field 1
+ else
+ out.set_regular_seg (true, s - ATSC_DSEGS_PER_FIELD); // field 2
+ }
+
+ /*!
+ * confirm that \p X is plausible
+ */
+ static void sanity_check (const plinfo &in)
+ {
+ // basic sanity checks...
+ //assert (x.segno () >= 0);
+ //assert (x.segno () < (unsigned) ATSC_DSEGS_PER_FIELD);
+ //assert ((x.flags () & ~0x3f) == 0);
+
+ //assert (x.regular_seg_p () ^ x.field_sync_p ());
+ //assert ((x.segno () != 0) ^ x.first_regular_seg_p ());
+ }
+
+ unsigned short _flags; // bitmask
+ short _segno; // segment number [-1,311] -1 is the field sync segment
+
+ protected:
+ // these three are mutually exclusive
+ // This is a regular data segment.
+ static const int fl_regular_seg = 0x0001;
+ // This is a field sync segment, for 1st half of a field.
+ static const int fl_field_sync1 = 0x0002;
+ // This is a field sync segment, for 2nd half of a field.
+ static const int fl_field_sync2 = 0x0004;
+
+ // This bit is on ONLY when fl_regular_seg is set AND when this is
+ // the first regular data segment AFTER a field sync segment. This
+ // segment causes various processing modules to reset.
+ static const int fl_first_regular_seg = 0x0008;
+
+ // which field are we in?
+ static const int fl_field2 = 0x0010; // else field 1
+
+ // This bit is set when Reed-Solomon decoding detects an error that it
+ // can't correct. Note that other error detection (e.g. Viterbi) do not
+ // set it, since Reed-Solomon will correct many of those. This bit is
+ // then copied into the final Transport Stream packet so that MPEG
+ // software can see that the 188-byte data segment has been corrupted.
+ static const int fl_transport_error = 0x0020;
+ };
+
+
+
+
+ class atsc_mpeg_packet {
+ public:
+ static const int NPAD = 68;
+ unsigned char data[ATSC_MPEG_DATA_LENGTH + 1]; // first byte is sync
+ unsigned char _pad_[NPAD]; // pad to power of 2 (256)
+
+ // overload equality operator
+ bool operator== (const atsc_mpeg_packet &other) const {
+ return std::memcmp (data, other.data, sizeof (data)) == 0;
+ };
+
+ bool operator!= (const atsc_mpeg_packet &other) const {
+ return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+ };
+ };
+
+ class atsc_mpeg_packet_no_sync {
+ public:
+ static const int NPAD = 65;
+ plinfo pli;
+ unsigned char data[ATSC_MPEG_DATA_LENGTH];
+ unsigned char _pad_[NPAD]; // pad to power of 2 (256)
+
+ // overload equality operator
+ bool operator== (const atsc_mpeg_packet_no_sync &other) const {
+ return std::memcmp (data, other.data, sizeof (data)) == 0;
+ }
+
+ bool operator!= (const atsc_mpeg_packet_no_sync &other) const {
+ return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+ }
+ };
+
+ class atsc_mpeg_packet_rs_encoded {
+ public:
+ static const int NPAD = 45;
+ plinfo pli;
+ unsigned char data[ATSC_MPEG_RS_ENCODED_LENGTH];
+ unsigned char _pad_[NPAD]; // pad to power of 2 (256)
+
+ // overload equality operator
+ bool operator== (const atsc_mpeg_packet_rs_encoded &other) const {
+ return std::memcmp (data, other.data, sizeof (data)) == 0;
+ }
+
+ bool operator!= (const atsc_mpeg_packet_rs_encoded &other) const {
+ return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+ }
+ };
+
+
+ //! contains 832 3 bit symbols. The low 3 bits in the byte hold the symbol.
+
+ class atsc_data_segment {
+ public:
+ static const int NPAD = 188;
+ plinfo pli;
+ unsigned char data[ATSC_DATA_SEGMENT_LENGTH];
+ unsigned char _pad_[NPAD]; // pad to power of 2 (1024)
+
+ // overload equality operator
+ bool operator== (const atsc_data_segment &other) const {
+ return std::memcmp (data, other.data, sizeof (data)) == 0;
+ }
+
+ bool operator!= (const atsc_data_segment &other) const {
+ return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+ }
+ };
+
+ /*!
+ * Contains 832 bipolar floating point symbols.
+ * Nominal values are +/- {1, 3, 5, 7}.
+ * This data type represents the input to the viterbi decoder.
+ */
+
+ class atsc_soft_data_segment {
+ public:
+ static const int NPAD = 764;
+ plinfo pli;
+ float data[ATSC_DATA_SEGMENT_LENGTH];
+ unsigned char _pad_[NPAD]; // pad to power of 2 (4096)
+
+ // overload equality operator
+ bool operator== (const atsc_data_segment &other) const {
+ return std::memcmp (data, other.data, sizeof (data)) == 0;
+ }
+
+ bool operator!= (const atsc_data_segment &other) const {
+ return !(std::memcmp (data, other.data, sizeof (data)) == 0);
+ }
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* _ATSC_TYPES_H_ */
diff --git a/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc b/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc
new file mode 100644
index 0000000000..430eb55a17
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.cc
@@ -0,0 +1,139 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include "atsc_viterbi_decoder_impl.h"
+#include "atsc_types.h"
+#include <atsc_viterbi_mux.cc> // machine generated
+
+namespace gr {
+ namespace dtv {
+
+ atsc_viterbi_decoder::sptr
+ atsc_viterbi_decoder::make()
+ {
+ return gnuradio::get_initial_sptr
+ (new atsc_viterbi_decoder_impl());
+ }
+
+ atsc_viterbi_decoder_impl::atsc_viterbi_decoder_impl()
+ : sync_block("dtv_atsc_viterbi_decoder",
+ io_signature::make(1, 1, sizeof(atsc_soft_data_segment)),
+ io_signature::make(1, 1, sizeof(atsc_mpeg_packet_rs_encoded)))
+ {
+ set_output_multiple(NCODERS);
+
+ /*
+ * These fifo's handle the alignment problem caused by the
+ * inherent decoding delay of the individual viterbi decoders.
+ * The net result is that this entire block has a pipeline latency
+ * of 12 complete segments.
+ *
+ * If anybody cares, it is possible to do it with less delay, but
+ * this approach is at least somewhat understandable...
+ */
+
+ // the -4 is for the 4 sync symbols
+ int fifo_size = ATSC_DATA_SEGMENT_LENGTH - 4 - viterbi[0].delay();
+ for (int i = 0; i < NCODERS; i++)
+ fifo[i] = new fifo_t(fifo_size);
+
+ reset();
+ }
+
+ atsc_viterbi_decoder_impl::~atsc_viterbi_decoder_impl()
+ {
+ for (int i = 0; i < NCODERS; i++)
+ delete fifo[i];
+ }
+
+ void
+ atsc_viterbi_decoder_impl::reset()
+ {
+ for (int i = 0; i < NCODERS; i++)
+ fifo[i]->reset();
+ }
+
+ int
+ atsc_viterbi_decoder_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const atsc_soft_data_segment *in = (const atsc_soft_data_segment *) input_items[0];
+ atsc_mpeg_packet_rs_encoded *out = (atsc_mpeg_packet_rs_encoded *) output_items[0];
+
+ // The way the fs_checker works ensures we start getting packets
+ // starting with a field sync, and out input multiple is set to
+ // 12, so we should always get a mod 12 numbered first packet
+ assert(noutput_items % NCODERS == 0);
+
+ int dbwhere;
+ int dbindex;
+ int shift;
+ float symbols[NCODERS][enco_which_max];
+ unsigned char dibits[NCODERS][enco_which_max];
+
+ unsigned char out_copy[OUTPUT_SIZE];
+
+ for (int i = 0; i < noutput_items; i += NCODERS) {
+ /* Build a continuous symbol buffer for each encoder */
+ for (unsigned int encoder = 0; encoder < NCODERS; encoder++)
+ for (unsigned int k = 0; k < enco_which_max; k++)
+ symbols[encoder][k] = in[i + (enco_which_syms[encoder][k]/832)].data[enco_which_syms[encoder][k] % 832];
+
+ /* Now run each of the 12 Viterbi decoders over their subset of
+ the input symbols */
+ for (unsigned int encoder = 0; encoder < NCODERS; encoder++)
+ for (unsigned int k = 0; k < enco_which_max; k++)
+ dibits[encoder][k] = viterbi[encoder].decode(symbols[encoder][k]);
+
+ /* Move dibits into their location in the output buffer */
+ for (unsigned int encoder = 0; encoder < NCODERS; encoder++) {
+ for (unsigned int k = 0; k < enco_which_max; k++) {
+ /* Store the dibit into the output data segment */
+ dbwhere = enco_which_dibits[encoder][k];
+ dbindex = dbwhere >> 3;
+ shift = dbwhere & 0x7;
+ out_copy[dbindex] = (out_copy[dbindex] & ~(0x03 << shift)) | (fifo[encoder]->stuff(dibits[encoder][k]) << shift);
+ } /* Symbols fed into one encoder */
+ } /* Encoders */
+
+ // copy output from contiguous temp buffer into final output
+ for (int j = 0; j < NCODERS; j++) {
+ memcpy (&out[i + j].data[0],
+ &out_copy[j * OUTPUT_SIZE/NCODERS],
+ ATSC_MPEG_RS_ENCODED_LENGTH * sizeof(out_copy[0]));
+
+ // adjust pipeline info to reflect 12 segment delay
+ plinfo::delay(out[i + j].pli, in[i + j].pli, NCODERS);
+ }
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace dtv */
+} /* namespace gr */
diff --git a/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.h b/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.h
new file mode 100644
index 0000000000..b4fbbd1033
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_viterbi_decoder_impl.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DTV_ATSC_VITERBI_DECODER_IMPL_H
+#define INCLUDED_DTV_ATSC_VITERBI_DECODER_IMPL_H
+
+#include <gnuradio/dtv/atsc_viterbi_decoder.h>
+#include <gnuradio/dtv/atsc_consts.h>
+#include "atsc_syminfo_impl.h"
+#include "atsc_interleaver_fifo.h"
+
+#define USE_SIMPLE_SLICER 0
+#define NCODERS 12
+
+#if USE_SIMPLE_SLICER
+#include "atsc_fake_single_viterbi.h"
+#else
+#include "atsc_single_viterbi.h"
+#endif
+
+namespace gr {
+ namespace dtv {
+
+#if USE_SIMPLE_SLICER
+ typedef atsc_fake_single_viterbi single_viterbi_t;
+#else
+ typedef atsc_single_viterbi single_viterbi_t;
+#endif
+
+ class atsc_viterbi_decoder_impl : public atsc_viterbi_decoder
+ {
+ private:
+ int last_start;
+ typedef interleaver_fifo<unsigned char> fifo_t;
+
+ static const int SEGMENT_SIZE = ATSC_MPEG_RS_ENCODED_LENGTH; // 207
+ static const int OUTPUT_SIZE = (SEGMENT_SIZE * 12);
+ static const int INPUT_SIZE = (ATSC_DATA_SEGMENT_LENGTH * 12);
+
+ single_viterbi_t viterbi[NCODERS];
+ fifo_t *fifo[NCODERS];
+
+ public:
+ atsc_viterbi_decoder_impl();
+ ~atsc_viterbi_decoder_impl();
+
+ void reset();
+
+ virtual int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace dtv */
+} /* namespace gr */
+
+#endif /* INCLUDED_DTV_ATSC_VITERBI_DECODER_IMPL_H */
diff --git a/gr-dtv/lib/atsc/atsc_viterbi_gen.cc b/gr-dtv/lib/atsc/atsc_viterbi_gen.cc
new file mode 100644
index 0000000000..bff3c47736
--- /dev/null
+++ b/gr-dtv/lib/atsc/atsc_viterbi_gen.cc
@@ -0,0 +1,267 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <iostream>
+#include <stdio.h>
+
+using std::cerr;
+
+/*
+ * Trellis-encode a whole pile of 12 data segments for ATSC.
+ * This also includes scrambling the data among twelve Trellis encoders.
+ *
+ * Input is twelve 207-byte blocks of raw data (Reed-Solomon output that's
+ * been scrambled up by interleaving with other blocks).
+ *
+ * Output is 12 x 208 x 4 bytes, each byte containing a 3-bit symbol.
+ * The first 4 bytes are the segment sync symbol.
+ *
+ Got the first version of Trellis encoder coded. Compiles, but I
+ didn't realize that each data segment contains an odd number of BITS!
+ The second data segment in a field starts by pulling bits out of the
+ middles of the bytes it's encoding. You actually have to read all the
+ entries in that table on page 59 AND 60 to get it.
+
+ There's a 4-segment asymmetric pattern of bit accesses.
+ There's a 3-segment asymmetric pattern of muxing encoders.
+
+ The result is there's a 12-segment pattern that repeats throughout
+ the encoding of a field. So this routine now encodes 12 segments at once.
+
+ This encoding system was either designed by a complete idiot or by
+ a complete genius. It's highly complex when it could have been very
+ simple. Now the question is whether
+ this incredible complexity buys us anything subtle and important.
+ */
+
+#define SEGMENT_SIZE 207
+#define INPUT_SIZE (SEGMENT_SIZE * 12)
+#define DIBITS_PER_BYTE 4
+#define EXTRAS (4 * 12) /* FIXME, sync symbols and such */
+#define SYMBOLS_OUT ((INPUT_SIZE * DIBITS_PER_BYTE) + EXTRAS)
+#define SEGOF(x) ( (x) / ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE))
+#define SYMOF(x) (((x) % ((SEGMENT_SIZE+1) * DIBITS_PER_BYTE))-4)
+#define ENCODERS 12
+#define ENCODER_SEG_BUMP 4
+
+
+/* Shift counts to bit numbers (high order, low order); 9x entries unused */
+static const int bit1[8] = {1, 99, 3, 98, 5, 97, 7, 96};
+static const int bit2[8] = {0, 99, 2, 98, 4, 97, 6, 96};
+
+/* Detailed Debugging */
+int debug_dec = 0;
+
+/*
+ * Build indirect data structures to say which symbols go into which
+ * encoder, and then where the resulting dibits from the encoders go.
+ */
+int
+build_decode_structures (char *fileout)
+{
+ int retval = 0;
+ int i;
+ int encoder;
+ int trellis_wheredata[ENCODERS];
+ unsigned char *symp, *next_sym_seg;
+ unsigned char symbols[SYMBOLS_OUT];
+ int chunk;
+ int shift;
+ int skip_encoder_bump;
+ int *enco_syms[ENCODERS];
+ int *enco_dibits[ENCODERS];
+ int j;
+ /* The data structures we'll build and then spit out... */
+ int sync_symbol_indices[1000];
+ int sync_symbol_indices_max;
+ int enco_which_syms[ENCODERS][INPUT_SIZE];
+ int enco_which_dibits[ENCODERS][INPUT_SIZE];
+ int enco_which_max;
+ #define BIT_PTR(int,shif) (((int) << 3) | ((shif) & 0x7))
+ /* Running indices into them as we build 'em... */
+ int *syncsyms = sync_symbol_indices;
+
+ /* Start our running pointers at the start of our per-encoder subarrays */
+ for (i = 0; i < ENCODERS; i++) {
+ enco_dibits[i] = enco_which_dibits[i];
+ enco_syms[i] = enco_which_syms[i];
+ }
+
+ encoder = ENCODERS - ENCODER_SEG_BUMP;
+ skip_encoder_bump = 0;
+ symp = symbols;
+ next_sym_seg = symp;
+
+ for (chunk = 0;
+ chunk < INPUT_SIZE;
+ chunk += ENCODERS) {
+ /* Associate data bytes with the Trellis encoders.
+ They get loaded or stored in an order that depends on where we are in the
+ segment sync progress (sigh).
+ GRR! When the chunk reload happens at the same time as the
+ segment boundary, we should bump the encoder NOW for the reload,
+ rather than LATER during the bitshift transition!!! */
+ if (symp >= next_sym_seg) {
+ encoder = (encoder + ENCODER_SEG_BUMP) % ENCODERS;
+ skip_encoder_bump = 1;
+ }
+
+ /* Remember where the data bytes are going to go, once we've
+ accumulated them from the 12 interleaved decoders */
+ for (i = 0; i < ENCODERS; i++) {
+ trellis_wheredata[encoder] = chunk+i;
+ encoder++;
+ if (encoder >= ENCODERS) encoder = 0;
+ }
+
+ for (shift = 6; shift >= 0; shift -= 2) {
+
+ /* Segment boundaries happen to occur on some bitshift transitions. */
+ if (symp >= next_sym_seg) {
+ /* Segment transition. Output a data segment sync symbol, and
+ mess with the trellis encoder mux. */
+ *syncsyms++ = symp - symbols;
+ symp += 4;
+ next_sym_seg = symp + (SEGMENT_SIZE * DIBITS_PER_BYTE);
+
+ if (!skip_encoder_bump)
+ encoder = (encoder + ENCODER_SEG_BUMP) % ENCODERS;
+ skip_encoder_bump = 0;
+ }
+
+ /* Now run each of the 12 Trellis encoders to spit out 12 symbols.
+ Each encoder takes input from the same byte of the chunk, but the
+ outputs of the encoders come out in various orders.
+ NOPE -- this is false. The encoders take input from various
+ bytes of the chunk (which changes at segment sync time), AND
+ they also come out in various orders. You really do have to
+ keep separate track of: the datasegs bytes, the encoders, and
+ the symbol bytes -- because they're all moving with respect to
+ each other!!! */
+ for (i = 0; i < ENCODERS; i++) {
+ if (debug_dec)
+ printf ("Seg %ld Symb %3ld Trell %2d Byte %6d Bits %d-%d = ",
+ (long) SEGOF(symp-symbols), (long) SYMOF(symp-symbols),
+ encoder, trellis_wheredata[encoder],
+ bit1[shift], bit2[shift]);
+
+ /* Decoding: Grab symbol, run through decoder, slice dibit into
+ buffer. */
+ /* This symbol goes into this encoder next */
+ *(enco_syms[encoder]++) = symp - symbols;
+ symp++;
+ /* The next output from this encoder goes into these dibits */
+ *(enco_dibits[encoder]++) = BIT_PTR(trellis_wheredata[encoder], shift);
+
+ encoder++; if (encoder >= ENCODERS) encoder = 0;
+ } /* Encoders */
+ } /* Bit shifts */
+
+#if 0
+ /* Now dump out the chunk of 12 data bytes that the twelve decoders have
+ accumulated. */
+ unsigned char trellis_buffer[ENCODERS];
+ unsigned char dibit;
+ unsigned char symbol;
+ int save_state;
+ for (i = 0; i < ENCODERS; i++) {
+ datasegs [trellis_wheredata[encoder]] = trellis_buffer[encoder];
+ encoder++;
+ if (encoder >= ENCODERS) encoder = 0;
+ } /* Dumping encoder bytes */
+#endif
+ } /* Chunks */
+
+ /* Now print the resulting data structures in C++ */
+
+ if (!freopen(fileout, "w", stdout))
+ return 2;
+
+ printf ("/*\n\
+ * atsc_viterbi_mux.cc\n\
+ *\n\
+ * Data structures for knowing which symbols are fed to which\n\
+ * Viterbi decoders, and then where to put the resulting output dibits.\n\
+ *\n\
+ * Generated by 'atsc_viterbi_gen.cc'.\n\
+ */\n\n");
+ sync_symbol_indices_max = syncsyms - sync_symbol_indices;
+ printf ("const unsigned int sync_symbol_indices_max = %d;\n",
+ sync_symbol_indices_max);
+ printf ("const unsigned int sync_symbol_indices[%d] = {\n ",
+ sync_symbol_indices_max);
+ for (i = 0; i < sync_symbol_indices_max; i++) {
+ printf ("%d,%s", sync_symbol_indices[i], (7 == i%8)? "\n ": " ");
+ }
+ printf ("};\n\n");
+
+ enco_which_max = enco_dibits[0] - enco_which_dibits[0];
+ for (i = 0; i < ENCODERS; i++)
+ if (enco_which_max != enco_dibits[i] - enco_which_dibits[i]) {
+ cerr << "Encoder " << i << " has different max_dibits " <<
+ enco_dibits[i] - enco_which_dibits[i] << " than " << enco_which_max;
+ retval = 3;
+ }
+
+ printf ("const unsigned int enco_which_max = %d;\n" , enco_which_max);
+
+ printf ("const unsigned int enco_which_syms[%d][%d] = {\n",
+ ENCODERS, enco_which_max);
+ for (i = 0; i < ENCODERS; i++) {
+ printf (" /* %d */\n {", i);
+ for (j = 0; j < enco_which_max; j++)
+ printf ("%d,%s", enco_which_syms[i][j], (7 == j%8)? "\n ": " ");
+ printf ("},\n");
+ }
+ printf ("};\n\n");
+
+ printf ("const unsigned int enco_which_dibits[%d][%d] = {\n",
+ ENCODERS, enco_which_max);
+ for (i = 0; i < ENCODERS; i++) {
+ printf (" /* %d */\n {", i);
+ for (j = 0; j < enco_which_max; j++)
+ printf ("%d,%s", enco_which_dibits[i][j], (7 == j%8)? "\n ": " ");
+ printf ("},\n");
+ }
+ printf ("};\n\n");
+ return retval;
+}
+
+int
+usage()
+{
+ cerr << "atsc_viterbi_gen: Usage:\n";
+ cerr << " ./atsc_viterbi_gen -o atsc_viterbi_mux.cc\n";
+ cerr << "That's all, folks!\n";
+ return 1;
+}
+
+
+int
+main(int argc, char **argv)
+{
+ if (argc != 3) return usage();
+ if (argv[1][0] != '-'
+ || argv[1][1] != 'o'
+ || argv[1][2] != 0 ) return usage();
+ return build_decode_structures(argv[2]);
+}
diff --git a/gr-dtv/lib/atsc/interleaver_fifo.h b/gr-dtv/lib/atsc/interleaver_fifo.h
new file mode 100644
index 0000000000..bc23b2d5d0
--- /dev/null
+++ b/gr-dtv/lib/atsc/interleaver_fifo.h
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _INTERLEAVER_FIFO_H_
+#define _INTERLEAVER_FIFO_H_
+
+#include <string.h>
+
+/*!
+ * \brief template class for interleaver fifo
+ */
+
+template<class symbol_type>
+class interleaver_fifo {
+ public:
+
+ interleaver_fifo (unsigned int size);
+ ~interleaver_fifo ();
+
+ //! reset interleaver (flushes contents and resets commutator)
+ void reset ();
+
+ //! stuff a symbol into the fifo and return the oldest
+ symbol_type stuff (symbol_type input){
+ if (m_size == 0)
+ return input;
+
+ symbol_type retval = m_fifo[m_position];
+ m_fifo[m_position] = input;
+ m_position++;
+ if (m_position >= m_size)
+ m_position = 0;
+
+ return retval;
+ }
+
+protected:
+ unsigned int m_size;
+ unsigned int m_position;
+ symbol_type *m_fifo;
+};
+
+template<class symbol_type>
+interleaver_fifo<symbol_type>::interleaver_fifo (unsigned int size)
+{
+ m_size = size;
+ m_position = 0;
+ m_fifo = new symbol_type[size];
+ memset (m_fifo, 0, m_size * sizeof (symbol_type));
+}
+
+template<class symbol_type>
+interleaver_fifo<symbol_type>::~interleaver_fifo ()
+{
+ delete [] m_fifo;
+}
+
+template<class symbol_type> void
+interleaver_fifo<symbol_type>::reset ()
+{
+ m_position = 0;
+ memset (m_fifo, 0, m_size * sizeof (symbol_type));
+}
+
+#endif /* _INTERLEAVER_FIFO_H_ */
diff --git a/gr-dtv/lib/gnuradio-dtv.rc.in b/gr-dtv/lib/gnuradio-dtv.rc.in
new file mode 100644
index 0000000000..0909e4fc8b
--- /dev/null
+++ b/gr-dtv/lib/gnuradio-dtv.rc.in
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <afxres.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@
+ PRODUCTVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@
+ FILEFLAGSMASK 0x3fL
+#ifndef NDEBUG
+ FILEFLAGS 0x0L
+#else
+ FILEFLAGS 0x1L
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_DRV_INSTALLABLE
+ BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "gnuradio-dtv"
+ VALUE "FileVersion", "@VERSION@"
+ VALUE "InternalName", "gnuradio-dtv.dll"
+ VALUE "LegalCopyright", "Licensed under GPLv3 or any later version"
+ VALUE "OriginalFilename", "gnuradio-dtv.dll"
+ VALUE "ProductName", "gnuradio-dtv"
+ VALUE "ProductVersion", "@VERSION@"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+ END
diff --git a/gr-dtv/python/dtv/CMakeLists.txt b/gr-dtv/python/dtv/CMakeLists.txt
new file mode 100644
index 0000000000..543c2c14cf
--- /dev/null
+++ b/gr-dtv/python/dtv/CMakeLists.txt
@@ -0,0 +1,50 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# Install python examples
+########################################################################
+include(GrPython)
+
+GR_PYTHON_INSTALL(
+ FILES
+ __init__.py
+ atsc_rx.py
+ atsc_rx_filter.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/dtv
+ COMPONENT "dtv_python"
+)
+
+########################################################################
+# Handle the unit tests
+########################################################################
+if(ENABLE_TESTING)
+ set(GR_TEST_TARGET_DEPS "")
+ set(GR_TEST_LIBRARY_DIRS "")
+ set(GR_TEST_PYTHON_DIRS
+ ${CMAKE_BINARY_DIR}/gnuradio-runtime/python
+ )
+
+ include(GrTest)
+ file(GLOB py_qa_test_files "qa_*.py")
+ foreach(py_qa_test_file ${py_qa_test_files})
+ get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
+ GR_ADD_TEST(${py_qa_test_name} ${QA_PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file})
+ endforeach(py_qa_test_file)
+endif(ENABLE_TESTING)
diff --git a/gr-dtv/python/dtv/__init__.py b/gr-dtv/python/dtv/__init__.py
new file mode 100644
index 0000000000..8d2b8bfbcf
--- /dev/null
+++ b/gr-dtv/python/dtv/__init__.py
@@ -0,0 +1,37 @@
+#
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+# The presence of this file turns this directory into a Python package
+
+'''
+Blocks and utilities for digital TV module.
+'''
+import os
+
+try:
+ from dtv_swig import *
+except ImportError:
+ dirname, filename = os.path.split(os.path.abspath(__file__))
+ __path__.append(os.path.join(dirname, "..", "..", "swig"))
+ from dtv_swig import *
+
+# Import pure python code here
+from atsc_rx import *
diff --git a/gr-dtv/python/dtv/atsc_rx.py b/gr-dtv/python/dtv/atsc_rx.py
new file mode 100644
index 0000000000..590e5f041c
--- /dev/null
+++ b/gr-dtv/python/dtv/atsc_rx.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env /usr/bin/python
+#
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+from gnuradio import gr, filter, analog
+from atsc_rx_filter import *
+
+class atsc_rx(gr.hier_block2):
+ def __init__(self, input_rate, sps):
+ gr.hier_block2.__init__(self, "atsc_rx",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_char)) # Output signature
+
+ # ATSC receiver filter/interpolator
+ rx_filt = atsc_rx_filter(input_rate, sps)
+
+ # Lock on to pilot tone, shift to DC, then discard Q channel
+ output_rate = ATSC_SYMBOL_RATE*sps
+ pll = dtv.atsc_fpll(output_rate)
+
+ # Remove pilot tone now at DC
+ dcr = filter.dc_blocker_ff(4096)
+
+ # Normalize signal to proper constellation amplitude
+ agc = analog.agc_ff(1e-5, 4.0)
+
+ # Synchronize bit and segement timing
+ btl = dtv.atsc_sync(output_rate)
+
+ # Check for correct field sync
+ fsc = dtv.atsc_fs_checker()
+
+ # Equalize channel using training sequences
+ equ = dtv.atsc_equalizer()
+
+ # Remove convolutional trellis coding
+ vit = dtv.atsc_viterbi_decoder()
+
+ # Remove convolutional interleaving
+ dei = dtv.atsc_deinterleaver()
+
+ # Reed-Solomon decode
+ rsd = dtv.atsc_rs_decoder()
+
+ # Derandomize MPEG2-TS packet
+ der = dtv.atsc_derandomizer()
+
+ # Remove padding from packet
+ dep = dtv.atsc_depad()
+
+ # Connect pipeline
+ self.connect(self, rx_filt, pll, dcr, agc, btl, fsc, equ)
+ self.connect(equ, vit, dei, rsd, der, dep, self)
diff --git a/gr-dtv/python/dtv/atsc_rx_filter.py b/gr-dtv/python/dtv/atsc_rx_filter.py
new file mode 100644
index 0000000000..e860fa265a
--- /dev/null
+++ b/gr-dtv/python/dtv/atsc_rx_filter.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env /usr/bin/python
+#
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+from gnuradio import gr, filter
+import dtv_swig as dtv
+
+# FIXME move these into separate constants module
+ATSC_CHANNEL_BW = 6.0e6
+ATSC_SYMBOL_RATE = 4.5e6/286*684 # ~10.76 Mbaud
+ATSC_RRC_SYMS = 8 # filter kernel extends over 2N+1 symbols
+
+class atsc_rx_filter(gr.hier_block2):
+ def __init__(self, input_rate, sps):
+ gr.hier_block2.__init__(self, "atsc_rx_filter",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+ # Create matched RX filter with RRC response for fractional
+ # interpolator.
+ nfilts = 16
+ output_rate = ATSC_SYMBOL_RATE*sps # Desired oversampled sample rate
+ filter_rate = input_rate*nfilts
+ symbol_rate = ATSC_SYMBOL_RATE/2.0 # One-sided bandwidth of sideband
+ excess_bw = 0.1152 #1.0-(0.5*ATSC_SYMBOL_RATE/ATSC_CHANNEL_BW) # ~10.3%
+ ntaps = int((2*ATSC_RRC_SYMS+1)*sps*nfilts)
+ interp = output_rate/input_rate
+ gain = nfilts*symbol_rate/filter_rate
+ rrc_taps = filter.firdes.root_raised_cosine(gain, # Filter gain
+ filter_rate, # PFB filter prototype rate
+ symbol_rate, # ATSC symbol rate
+ excess_bw, # ATSC RRC excess bandwidth
+ ntaps) # Length of filter
+
+ pfb = filter.pfb_arb_resampler_ccf(interp, rrc_taps, nfilts)
+
+ # Connect pipeline
+ self.connect(self, pfb, self)
diff --git a/gr-dtv/python/dtv/qa_dtv.py b/gr-dtv/python/dtv/qa_dtv.py
new file mode 100755
index 0000000000..a0f6edf801
--- /dev/null
+++ b/gr-dtv/python/dtv/qa_dtv.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+#
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest, dtv
+
+class test_dtv(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ pass
+
+if __name__ == '__main__':
+ gr_unittest.run(test_dtv, "test_dtv.xml")
diff --git a/gr-dtv/swig/CMakeLists.txt b/gr-dtv/swig/CMakeLists.txt
new file mode 100644
index 0000000000..f1899a4964
--- /dev/null
+++ b/gr-dtv/swig/CMakeLists.txt
@@ -0,0 +1,56 @@
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# Setup swig generation
+########################################################################
+include(GrPython)
+include(GrSwig)
+
+set(GR_SWIG_INCLUDE_DIRS
+ ${GR_DTV_INCLUDE_DIRS}
+ ${GNURADIO_RUNTIME_SWIG_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+)
+
+if(ENABLE_GR_CTRLPORT)
+ list(APPEND GR_SWIG_FLAGS "-DGR_CTRLPORT")
+ list(APPEND GR_SWIG_INCLUDE_DIRS ${ICE_INCLUDE_DIR})
+endif(ENABLE_GR_CTRLPORT)
+
+set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/dtv_swig_doc.i)
+set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/gnuradio/dtv)
+set(GR_SWIG_DOCS_TARGET_DEPS runtime_swig_swig_doc)
+set(GR_SWIG_LIBRARIES gnuradio-dtv)
+
+GR_SWIG_MAKE(dtv_swig dtv_swig.i)
+
+GR_SWIG_INSTALL(
+ TARGETS dtv_swig
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/dtv
+ COMPONENT "dtv_python"
+)
+
+install(
+ FILES
+ dtv_swig.i
+ ${CMAKE_CURRENT_BINARY_DIR}/dtv_swig_doc.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "dtv_swig"
+)
diff --git a/gr-dtv/swig/dtv_swig.i b/gr-dtv/swig/dtv_swig.i
new file mode 100644
index 0000000000..91c910d52a
--- /dev/null
+++ b/gr-dtv/swig/dtv_swig.i
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#define DTV_API
+
+%include "gnuradio.i"
+
+//load generated python docstrings
+%include "dtv_swig_doc.i"
+
+%{
+#include "gnuradio/dtv/atsc_deinterleaver.h"
+#include "gnuradio/dtv/atsc_depad.h"
+#include "gnuradio/dtv/atsc_derandomizer.h"
+#include "gnuradio/dtv/atsc_equalizer.h"
+#include "gnuradio/dtv/atsc_fpll.h"
+#include "gnuradio/dtv/atsc_fs_checker.h"
+#include "gnuradio/dtv/atsc_rs_decoder.h"
+#include "gnuradio/dtv/atsc_sync.h"
+#include "gnuradio/dtv/atsc_viterbi_decoder.h"
+%}
+
+%include "gnuradio/dtv/atsc_deinterleaver.h"
+%include "gnuradio/dtv/atsc_depad.h"
+%include "gnuradio/dtv/atsc_derandomizer.h"
+%include "gnuradio/dtv/atsc_equalizer.h"
+%include "gnuradio/dtv/atsc_fpll.h"
+%include "gnuradio/dtv/atsc_fs_checker.h"
+%include "gnuradio/dtv/atsc_rs_decoder.h"
+%include "gnuradio/dtv/atsc_sync.h"
+%include "gnuradio/dtv/atsc_viterbi_decoder.h"
+
+GR_SWIG_BLOCK_MAGIC2(dtv, atsc_deinterleaver);
+GR_SWIG_BLOCK_MAGIC2(dtv, atsc_depad);
+GR_SWIG_BLOCK_MAGIC2(dtv, atsc_derandomizer);
+GR_SWIG_BLOCK_MAGIC2(dtv, atsc_equalizer)
+GR_SWIG_BLOCK_MAGIC2(dtv, atsc_fpll);
+GR_SWIG_BLOCK_MAGIC2(dtv, atsc_fs_checker);
+GR_SWIG_BLOCK_MAGIC2(dtv, atsc_rs_decoder);
+GR_SWIG_BLOCK_MAGIC2(dtv, atsc_sync);
+GR_SWIG_BLOCK_MAGIC2(dtv, atsc_viterbi_decoder);