diff options
274 files changed, 40134 insertions, 3763 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 61a3762dbe..9803104d12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,8 +41,8 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) # Set the version information here set(VERSION_INFO_MAJOR_VERSION 3) set(VERSION_INFO_API_COMPAT 7) -set(VERSION_INFO_MINOR_VERSION 3) -set(VERSION_INFO_MAINT_VERSION 0) +set(VERSION_INFO_MINOR_VERSION 4) +set(VERSION_INFO_MAINT_VERSION git) include(GrVersion) #setup version info # Append -O2 optimization flag for Debug builds diff --git a/README.building-boost b/README.building-boost index a281e8bd78..eea4df3889 100644 --- a/README.building-boost +++ b/README.building-boost @@ -6,6 +6,29 @@ If running a distribution that requires boost 1.35 (or later) be built from scratch, these instructions explain how to do so, and in a way that allows it to peacefully coexist with earlier versions of boost. +There are two recommended methods: +Installing boost using the PyBOMBS utility, or building it from a source +tarball. + +1. Installing Boost using ByBOMBS +--------------------------------- + +Following http://gnuradio.org/redmine/projects/pybombs/wiki/Using you can +install a recent boost by downloading and executing the PyBombs utility: + +# go to a directory you have write access to +$ git clone git://github.com/pybombs/pybombs +$ cd pybombs +$ ./pybombs install boost + +The utility will take care of everything from thereon, install it from a +package source if a recent version is available for your system or build +it from source if necessary. + + +2. Building Boost from a source tarball +--------------------------------------- + Download the latest version of boost from boost.sourceforge.net. (boost_1_49_0.tar.bz2 was the latest when this was written). Different Boost versions often have different installations. If these @@ -36,7 +59,7 @@ required will just save compilation time. Installing GNU Radio with new Boost libraries. -Tell cmake to look for the Boost libraries and header files in the new location with the folloing command: +Tell Cmake to look for the Boost libraries and header files in the new location with the following command: $ cd <build directory> $ cmake -DBOOST_ROOT=$BOOST_PREFIX -DBoost_INCLUDE_DIR=$BOOST_PREFIX/include/boost-1_49/ -DBoost_LIBRARY_DIRS=$BOOST_PREFIX/lib <path to gnuradio source tree> diff --git a/README.hacking b/README.hacking index c22e00991d..21140ebeea 100644 --- a/README.hacking +++ b/README.hacking @@ -26,34 +26,32 @@ aren't done differently, etc, etc, * Boost 1.35 -Until boost 1.35 or later is common in distributions, you'll need to -build boost from source yourself. See README.building-boost. - +Boost 1.35 and later is fairly common in modern distributions. +If it isn't available for your system, please refer to +README.building-boost for instructions * C++ and Python -GNU Radio is now a hybrid system. Some parts of the system are built -in C++ and some of it in Python. In general, prefer Python to C++. -Signal processing primitives are still built in C++ for performance. +GNU Radio is a hybrid system. Some parts of the system are built +in C++ and some of it in Python. In general, prefer Python to C++ for +its simplicity; for performance-critical and system-related +functionality. Signal processing primitives are still built in C++ for +performance; the Vector-Optimized Library of Kernels (VOLK) is directly +accessible from C++. * C++ namespaces -In the cleanup process, I considered putting everything in the -gnuradio namespace and dropping the Gr|gr prefix. In fact, I think -it's probably the right idea, but when I tested it out, I ran into -problems with SWIG's handling of namespaces. Bottom line, SWIG -(1.3.21) got confused and generated bad code when I started playing -around with namespaces in a not particularly convoluted way. I saw -problems using the boost::shared_ptr template in combination with -classes defined in the gnuradio namespace. It wasn't pretty... - +GNU Radio is organized in modules. For example, the blocks of the gr-digital +module reside in the namespace gr::digital. Out-Of-Tree modules follow the +same convention, but should take care not to clash with the official modules. * Naming conventions Death to CamelCaseNames! We've returned to a kinder, gentler era. We're now using the "STL style" naming convention with a couple of -modifications since we're not using namespaces. +modifications. Refer to the classes in the official source tree for +examples. With the exception of macros and other constant values, all identifiers shall be lower case with words_separated_like_this. @@ -62,50 +60,22 @@ Macros and constant values (e.g., enumerated values, static const int FOO = 23) shall be in UPPER_CASE. -** Global names - -All globally visible names (types, functions, variables, consts, etc) -shall begin with a "package prefix", followed by an '_'. The bulk of -the code in GNU Radio logically belongs to the "gr" package, hence -names look like gr_open_file (...). - -Large coherent bodies of code may use other package prefixes, but -let's try to keep them to a well thought out list. See the list -below. - -*** Package prefixes - -These are the current package prefixes: - - gr_ Almost everything - - gri_ Implementation primitives. Sometimes we - have both a gr_<foo> and a gri_<foo>. In that case, - gr_<foo> would be derived from gr_block and gri_<foo> - would be the low level guts of the function. - - atsc_ Code related to the Advanced Television - Standards Committee HDTV implementation - - qa_ Quality Assurance. Test code. - - ** Class data members (instance variables) All class data members shall begin with d_<foo>. -The big win is when you're staring at a block of code it's obvious +The big benefit is when you're staring at a block of code it's obvious which of the things being assigned to persist outside of the block. This also keeps you from having to be creative with parameter names for methods and constructors. You just use the same name as the instance variable, without the d_. -class gr_wonderfulness { +class wonderfulness { std::string d_name; double d_wonderfulness_factor; public: - gr_wonderfulness (std::string name, double wonderfulness_factor) + wonderfulness (std::string name, double wonderfulness_factor) : d_name (name), d_wonderfulness_factor (wonderfulness_factor) { ... @@ -121,11 +91,7 @@ All class static data members shall begin with s_<foo>. ** File names -Each significant class shall be contained in it's own file. The -declaration of class gr_foo shall be in gr_foo.h, the definition in -gr_foo.cc. - - +Each significant class shall be contained in it's own file. * Storage management @@ -141,26 +107,13 @@ See http://www.boost.org/libs/smart_ptr/smart_ptr.htm * Unit tests -Build unit tests for everything non-trivial and run them after every -change. Check out Extreme Programming: -http://c2.com/cgi/wiki?ExtremeProgrammingRoadmap - -Unit tests should also be written for all examples. This should kill -off the bit rot we've been plagued with. - -** C++ unit tests - -For C++ we're using the cppunit framework. cppunit has its bad -smells, but it's mostly workable. http://cppunit.sf.net - -Currently each directory <dirname>/lib contains files qa_<dirname>.{h,cc} -that bring together all the qa_<foo> test suites in the directory. - - -** Python unit tests - -We use the standard unittest package for unit testing of Python code. +Unit tests are a useful tool for development -- they are less of a tool +to prove others that you can write code that works like you defined it but help +you and later maintainers identify corner cases, regressions and other malfunctions +of code. +GNU Radio has integrated versatile, easy to use testing facilities. Please refer to +http://gnuradio.org/redmine/projects/gnuradio/wiki/Coding_guide_impl#Unit-testing * Standard command line options @@ -171,7 +124,10 @@ and long) and types of the arguments. We list them below using the Python optparse syntax. In general, the default value should be coded into the help string using the "... [default=%default]" syntax. -** Mandatory options by gr_block +** Mandatory options by gr::block + +When designing flow graphs with the GNU Radio Companion, appropriate +option parsing will automatically be set up for you. *** Audio source diff --git a/cmake/Modules/FindICE-3.5.cmake b/cmake/Modules/FindICE-3.5.cmake index 7ac53c94e1..d4421abbad 100644 --- a/cmake/Modules/FindICE-3.5.cmake +++ b/cmake/Modules/FindICE-3.5.cmake @@ -90,17 +90,33 @@ if(ICE_ICE AND ICE_ICEUTIL) ${ICE_ICEUTIL} ) - FIND_PROGRAM(ICE_SLICE2CPP slice2cpp - HINTS ${CMAKE_INSTALL_PREFIX}/bin ${ICE_MANUAL_INSTALL_PATH}/bin/) - FIND_PROGRAM(ICE_SLICE2PY slice2py - HINTS ${CMAKE_INSTALL_PREFIX}/bin ${ICE_MANUAL_INSTALL_PATH}/bin/) - - # Check that the ICE Python package is installed - include(GrPython) - GR_PYTHON_CHECK_MODULE("Ice >= 3.5" Ice "Ice.stringVersion() >= '3.5.0'" PYTHON_ICE_FOUND) - if(PYTHON_ICE_FOUND) + if(CMAKE_CROSSCOMPILING) + # When cross-compiling, we set up the environment/toolchain to put + # the right slice2cpp/py in the path. We just need to grab that here. + FIND_PROGRAM(ICE_SLICE2CPP slice2cpp) + FIND_PROGRAM(ICE_SLICE2PY slice2py) + + # We also don't need to look for Python in this case, so just + # force this to TRUE here. set(ICE_FOUND TRUE) - endif(PYTHON_ICE_FOUND) + + else(CMAKE_CROSSCOMPILING) + + FIND_PROGRAM(ICE_SLICE2CPP slice2cpp + HINTS ${CMAKE_INSTALL_PREFIX}/bin ${ICE_MANUAL_INSTALL_PATH}/bin/) + FIND_PROGRAM(ICE_SLICE2PY slice2py + HINTS ${CMAKE_INSTALL_PREFIX}/bin ${ICE_MANUAL_INSTALL_PATH}/bin/) + + # Check that the ICE Python package is installed + include(GrPython) + GR_PYTHON_CHECK_MODULE("Ice >= 3.5" Ice "Ice.stringVersion() >= '3.5.0'" PYTHON_ICE_FOUND) + if(PYTHON_ICE_FOUND) + set(ICE_FOUND TRUE) + endif(PYTHON_ICE_FOUND) + endif(CMAKE_CROSSCOMPILING) + + message(STATUS " SLICE2CPP: ${ICE_SLICE2CPP}") + message(STATUS " SLICE2PY: ${ICE_SLICE2PY}") if(ICE_FOUND) message(STATUS "Ice-3.5 found") diff --git a/cmake/Modules/FindQwt.cmake b/cmake/Modules/FindQwt.cmake index 82f0780deb..1a246c8a62 100644 --- a/cmake/Modules/FindQwt.cmake +++ b/cmake/Modules/FindQwt.cmake @@ -39,13 +39,13 @@ if(QWT_INCLUDE_DIRS) QWT_STRING_VERSION REGEX "QWT_VERSION_STR") string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" QWT_VERSION ${QWT_STRING_VERSION}) string(COMPARE LESS ${QWT_VERSION} "5.2.0" QWT_WRONG_VERSION) - string(COMPARE GREATER ${QWT_VERSION} "6.1.2" QWT_WRONG_VERSION) + string(COMPARE GREATER ${QWT_VERSION} "6.2.0" QWT_WRONG_VERSION) message(STATUS "QWT Version: ${QWT_VERSION}") if(NOT QWT_WRONG_VERSION) set(QWT_FOUND TRUE) else(NOT QWT_WRONG_VERSION) - message(STATUS "QWT Version must be >= 5.2 and <= 6.0.2, Found ${QWT_VERSION}") + message(STATUS "QWT Version must be >= 5.2 and <= 6.2.0, Found ${QWT_VERSION}") endif(NOT QWT_WRONG_VERSION) endif(QWT_INCLUDE_DIRS) diff --git a/cmake/Toolchains/oe-sdk_cross.cmake b/cmake/Toolchains/oe-sdk_cross.cmake index ea77815c96..2a01d8f79f 100644 --- a/cmake/Toolchains/oe-sdk_cross.cmake +++ b/cmake/Toolchains/oe-sdk_cross.cmake @@ -5,7 +5,7 @@ set( CMAKE_CXX_FLAGS $ENV{CXXFLAGS} CACHE STRING "" FORCE ) set( CMAKE_C_FLAGS $ENV{CFLAGS} CACHE STRING "" FORCE ) #same flags for C sources set( CMAKE_LDFLAGS_FLAGS ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE ) #same flags for C sources set( CMAKE_LIBRARY_PATH ${OECORE_TARGET_SYSROOT}/usr/lib ) -set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_NATIVE_SYSROOT} $ENV{OECORE_TARGET_SYSROOT} ) +set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} $ENV{OECORE_NATIVE_SYSROOT} ) set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index 3dc58bfaf4..6afecbd1bf 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -1,14 +1,16 @@ -# Doxyfile 1.5.7.1 +# Doxyfile 1.8.4 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project +# doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored +# All text after a double hash (##) is considered a comment and is placed +# in front of the TAG it is preceding . +# All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") +# Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options @@ -22,16 +24,30 @@ DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. -PROJECT_NAME = "GNU Radio @VERSION@ C++ API" +PROJECT_NAME = "GNU Radio Manual and C++ API Reference" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = "@VERSION@" + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "The Free & Open Software Radio Ecosystem" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = @CMAKE_SOURCE_DIR@/docs/doxygen/gnuradio_logo_icon.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. @@ -54,11 +70,11 @@ CREATE_SUBDIRS = NO # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, -# Spanish, Swedish, and Ukrainian. +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English @@ -112,7 +128,9 @@ FULL_PATH_NAMES = NO # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the -# path to strip. +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. STRIP_FROM_PATH = @@ -146,7 +164,7 @@ STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@/gnuradio-runtime/include \ @CMAKE_SOURCE_DIR@/volk/include # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO @@ -201,6 +219,13 @@ TAB_SIZE = 8 ALIASES = +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list @@ -227,11 +252,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES @@ -247,10 +301,10 @@ CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. @@ -271,6 +325,22 @@ DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct @@ -281,21 +351,16 @@ SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 4 +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options @@ -304,7 +369,7 @@ SYMBOL_CACHE_SIZE = 4 # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES @@ -313,6 +378,11 @@ EXTRACT_ALL = YES EXTRACT_PRIVATE = NO +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. @@ -335,7 +405,7 @@ EXTRACT_LOCAL_METHODS = NO # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. +# anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO @@ -395,6 +465,12 @@ HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. @@ -414,6 +490,16 @@ SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. @@ -430,6 +516,15 @@ SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. @@ -455,15 +550,16 @@ GENERATE_BUGLIST = NO GENERATE_DEPRECATEDLIST= NO # The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in +# the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the +# The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. @@ -482,7 +578,8 @@ SHOW_USED_FILES = YES SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES @@ -497,15 +594,26 @@ SHOW_NAMESPACES = YES FILE_VERSION_FILTER = -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- @@ -534,7 +642,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for +# The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of @@ -566,7 +674,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @top_srcdir@ @top_builddir@ +INPUT = @top_srcdir@ \ + @top_builddir@ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -580,8 +689,9 @@ INPUT_ENCODING = UTF-8 # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.h \ *.dox @@ -592,12 +702,14 @@ FILE_PATTERNS = *.h \ RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should +# The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. EXCLUDE = @abs_top_builddir@/docs/doxygen/html \ - @abs_top_builddir@/docs/doxygen/xml \ + @abs_top_builddir@/docs/doxygen/xml \ @abs_top_builddir@/docs/doxygen/other/doxypy.py \ @abs_top_builddir@/dtools \ @abs_top_builddir@/gnuradio-runtime/lib/runtime/gr_error_handler.cc \ @@ -616,7 +728,7 @@ EXCLUDE = @abs_top_builddir@/docs/doxygen/html \ @abs_top_builddir@/gr-video-sdl/swig/video_sdl_swig.py \ @abs_top_builddir@/gr-wxgui/python \ @abs_top_builddir@/grc \ - @abs_top_builddir@/_CPack_Packages \ + @abs_top_builddir@/_CPack_Packages \ @abs_top_srcdir@/cmake \ @abs_top_srcdir@/gr-utils/python/modtool/gr-newmod \ @abs_top_srcdir@/docs/doxygen/doxyxml/example \ @@ -664,8 +776,8 @@ EXCLUDE = @abs_top_builddir@/docs/doxygen/html \ @abs_top_srcdir@/gr-wxgui/lib \ @abs_top_builddir@/gr-wxgui/lib -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO @@ -743,17 +855,22 @@ IMAGE_PATH = @abs_top_srcdir@/docs/doxygen/images/ # by executing (via popen()) the command <filter> <input-file>, where <filter> # is the value of the INPUT_FILTER tag, and <input-file> is the name of an # input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = *.py=@top_srcdir@/docs/doxygen/other/doxypy.py @@ -763,6 +880,21 @@ FILTER_PATTERNS = *.py=@top_srcdir@/docs/doxygen/other/doxypy.py FILTER_SOURCE_FILES = NO +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- @@ -781,7 +913,7 @@ INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. +# fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = NO @@ -800,7 +932,8 @@ REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. +# link to the source code. +# Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES @@ -864,7 +997,14 @@ HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a -# standard header. +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = @@ -876,21 +1016,80 @@ HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. HTML_STYLESHEET = +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# page has loaded. HTML_DYNAMIC_SECTIONS = NO +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). @@ -899,7 +1098,8 @@ HTML_DYNAMIC_SECTIONS = NO # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. GENERATE_DOCSET = NO @@ -917,6 +1117,16 @@ DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) @@ -961,10 +1171,10 @@ BINARY_TOC = NO TOC_EXPAND = YES -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO @@ -976,57 +1186,99 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#namespace">Qt Help Project / Namespace</a>. +# http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>. +# http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file . +# .qhp file. QHG_LOCATION = -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. -DISABLE_INDEX = YES +GENERATE_ECLIPSEHELP = NO -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. -ENUM_VALUES_PER_LINE = 4 +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = YES # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. -# If the tag value is set to FRAME, a side panel will be generated +# If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. Other possible values -# for this tag are: HIERARCHIES, which will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list; -# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which -# disables this behavior completely. For backwards compatibility with previous -# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE -# respectively. +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = YES +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 180 +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need @@ -1035,6 +1287,112 @@ TREEVIEW_WIDTH = 180 FORMULA_FONTSIZE = 10 +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- @@ -1052,6 +1410,9 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. LATEX_CMD_NAME = latex @@ -1068,8 +1429,8 @@ MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. PAPER_TYPE = letter @@ -1085,6 +1446,20 @@ EXTRA_PACKAGES = LATEX_HEADER = +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references @@ -1111,6 +1486,19 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1142,7 +1530,7 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's +# Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. @@ -1217,6 +1605,21 @@ XML_DTD = XML_PROGRAMLISTING = NO #--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -1247,8 +1650,10 @@ GENERATE_PERLMOD = NO PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. @@ -1285,7 +1690,7 @@ MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. +# pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES @@ -1315,15 +1720,15 @@ PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES @@ -1331,20 +1736,18 @@ SKIP_FUNCTION_MACROS = YES # Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. TAGFILES = @@ -1365,6 +1768,12 @@ ALLEXTERNALS = NO EXTERNAL_GROUPS = YES +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). @@ -1377,9 +1786,8 @@ PERL_PATH = /usr/bin/perl # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES @@ -1405,35 +1813,40 @@ HIDE_UNDOC_RELATIONS = YES HAVE_DOT = @HAVE_DOT@ -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. -DOT_FONTNAME = FreeSans +DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. +# CLASS_DIAGRAMS tag to NO. -CLASS_GRAPH = YES +CLASS_GRAPH = NO # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and @@ -1445,7 +1858,7 @@ COLLABORATION_GRAPH = NO # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies -GROUP_GRAPHS = YES +GROUP_GRAPHS = NO # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling @@ -1453,6 +1866,15 @@ GROUP_GRAPHS = YES UML_LOOK = NO +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. @@ -1489,23 +1911,34 @@ CALL_GRAPH = NO CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. +# will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. -DIRECTORY_GRAPH = YES +DIRECTORY_GRAPH = NO # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. @@ -1517,6 +1950,12 @@ DOT_PATH = DOTFILE_DIRS = +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is @@ -1563,12 +2002,3 @@ GENERATE_LEGEND = YES # the various graphs. DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/docs/doxygen/Doxyfile.swig_doc.in b/docs/doxygen/Doxyfile.swig_doc.in index c1423b30c2..37a4d2a710 100644 --- a/docs/doxygen/Doxyfile.swig_doc.in +++ b/docs/doxygen/Doxyfile.swig_doc.in @@ -1,14 +1,16 @@ -# Doxyfile 1.6.1 +# Doxyfile 1.8.4 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project +# doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored +# All text after a double hash (##) is considered a comment and is placed +# in front of the TAG it is preceding . +# All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") +# Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options @@ -22,8 +24,9 @@ DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. PROJECT_NAME = @CPACK_PACKAGE_NAME@ @@ -33,6 +36,19 @@ PROJECT_NAME = @CPACK_PACKAGE_NAME@ PROJECT_NUMBER = @CPACK_PACKAGE_VERSION@ +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location @@ -56,9 +72,9 @@ CREATE_SUBDIRS = NO # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English @@ -112,7 +128,9 @@ FULL_PATH_NAMES = YES # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the -# path to strip. +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. STRIP_FROM_PATH = @@ -126,7 +144,7 @@ STRIP_FROM_PATH = STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO @@ -181,6 +199,13 @@ TAB_SIZE = 8 ALIASES = +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list @@ -207,22 +232,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. EXTENSION_MAPPING = +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES @@ -238,10 +281,10 @@ CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. @@ -262,6 +305,22 @@ DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct @@ -272,21 +331,16 @@ SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options @@ -295,7 +349,7 @@ SYMBOL_CACHE_SIZE = 0 # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES @@ -304,6 +358,11 @@ EXTRACT_ALL = YES EXTRACT_PRIVATE = NO +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. @@ -326,7 +385,7 @@ EXTRACT_LOCAL_METHODS = NO # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. +# anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO @@ -386,6 +445,12 @@ HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. @@ -405,7 +470,13 @@ SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO @@ -425,6 +496,15 @@ SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. @@ -450,15 +530,16 @@ GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in +# the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the +# The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. @@ -493,15 +574,26 @@ SHOW_NAMESPACES = YES FILE_VERSION_FILTER = -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- @@ -530,7 +622,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for +# The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of @@ -576,8 +668,9 @@ INPUT_ENCODING = UTF-8 # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.h @@ -587,14 +680,16 @@ FILE_PATTERNS = *.h RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should +# The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. -EXCLUDE = +EXCLUDE = -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO @@ -647,8 +742,10 @@ IMAGE_PATH = # is the value of the INPUT_FILTER tag, and <input-file> is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. +# If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. INPUT_FILTER = @@ -658,8 +755,8 @@ INPUT_FILTER = # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = @@ -669,6 +766,21 @@ FILTER_PATTERNS = FILTER_SOURCE_FILES = NO +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- @@ -687,7 +799,7 @@ INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. +# fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES @@ -771,7 +883,14 @@ HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a -# standard header. +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = @@ -783,21 +902,80 @@ HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. HTML_STYLESHEET = +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# page has loaded. HTML_DYNAMIC_SECTIONS = NO +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). @@ -806,7 +984,8 @@ HTML_DYNAMIC_SECTIONS = NO # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. GENERATE_DOCSET = NO @@ -824,6 +1003,16 @@ DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) @@ -868,10 +1057,10 @@ BINARY_TOC = NO TOC_EXPAND = NO -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO @@ -893,20 +1082,24 @@ QHP_NAMESPACE = QHP_VIRTUAL_FOLDER = doc -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. QHP_CUST_FILTER_ATTRS = -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's # filter section matches. -# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. QHP_SECT_FILTER_ATTRS = @@ -917,16 +1110,30 @@ QHP_SECT_FILTER_ATTRS = QHG_LOCATION = -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. -DISABLE_INDEX = NO +GENERATE_ECLIPSEHELP = NO -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. -ENUM_VALUES_PER_LINE = 4 +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. @@ -935,15 +1142,29 @@ ENUM_VALUES_PER_LINE = 4 # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need @@ -952,13 +1173,112 @@ TREEVIEW_WIDTH = 250 FORMULA_FONTSIZE = 10 -# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) -# there is already a search function so this one should typically -# be disabled. +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- @@ -976,6 +1296,9 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. LATEX_CMD_NAME = latex @@ -992,8 +1315,8 @@ MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. PAPER_TYPE = a4wide @@ -1009,6 +1332,20 @@ EXTRA_PACKAGES = LATEX_HEADER = +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references @@ -1035,10 +1372,19 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1070,7 +1416,7 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's +# Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. @@ -1145,6 +1491,21 @@ XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -1215,7 +1576,7 @@ MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. +# pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES @@ -1245,15 +1606,15 @@ PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES @@ -1261,22 +1622,18 @@ SKIP_FUNCTION_MACROS = YES # Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. TAGFILES = @@ -1297,6 +1654,12 @@ ALLEXTERNALS = NO EXTERNAL_GROUPS = YES +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). @@ -1309,11 +1672,10 @@ PERL_PATH = /usr/bin/perl # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. -CLASS_DIAGRAMS = YES +CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see @@ -1337,33 +1699,38 @@ HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. -DOT_FONTNAME = FreeSans +DOT_FONTNAME = # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. +# CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES @@ -1385,6 +1752,15 @@ GROUP_GRAPHS = YES UML_LOOK = NO +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. @@ -1421,11 +1797,11 @@ CALL_GRAPH = NO CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. +# will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. @@ -1433,11 +1809,22 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. @@ -1449,6 +1836,12 @@ DOT_PATH = DOTFILE_DIRS = +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is diff --git a/docs/doxygen/gnuradio_logo_icon.png b/docs/doxygen/gnuradio_logo_icon.png Binary files differnew file mode 100644 index 0000000000..c9308fed17 --- /dev/null +++ b/docs/doxygen/gnuradio_logo_icon.png diff --git a/gnuradio-runtime/include/gnuradio/basic_block.h b/gnuradio-runtime/include/gnuradio/basic_block.h index ef2f9f16d7..69775865ee 100644 --- a/gnuradio-runtime/include/gnuradio/basic_block.h +++ b/gnuradio-runtime/include/gnuradio/basic_block.h @@ -59,26 +59,26 @@ namespace gr { public boost::enable_shared_from_this<basic_block> { typedef boost::function<void(pmt::pmt_t)> msg_handler_t; - + private: //msg_handler_t d_msg_handler; typedef std::map<pmt::pmt_t , msg_handler_t, pmt::comparator> d_msg_handlers_t; d_msg_handlers_t d_msg_handlers; - + typedef std::deque<pmt::pmt_t> msg_queue_t; typedef std::map<pmt::pmt_t, msg_queue_t, pmt::comparator> msg_queue_map_t; typedef std::map<pmt::pmt_t, msg_queue_t, pmt::comparator>::iterator msg_queue_map_itr; std::map<pmt::pmt_t, boost::shared_ptr<boost::condition_variable>, pmt::comparator> msg_queue_ready; - + gr::thread::mutex mutex; //< protects all vars - + protected: friend class flowgraph; friend class flat_flowgraph; // TODO: will be redundant friend class tpb_thread_body; - + enum vcolor { WHITE, GREY, BLACK }; - + std::string d_name; gr::io_signature::sptr d_input_signature; gr::io_signature::sptr d_output_signature; @@ -91,24 +91,24 @@ namespace gr { msg_queue_map_t msg_queue; std::vector<boost::any> d_rpc_vars; // container for all RPC variables - + basic_block(void) {} // allows pure virtual interface sub-classes - + //! Protected constructor prevents instantiation by non-derived classes basic_block(const std::string &name, gr::io_signature::sptr input_signature, gr::io_signature::sptr output_signature); - + //! may only be called during constructor void set_input_signature(gr::io_signature::sptr iosig) { d_input_signature = iosig; } - + //! may only be called during constructor void set_output_signature(gr::io_signature::sptr iosig) { d_output_signature = iosig; } - + /*! * \brief Allow the flowgraph to set for sorting and partitioning */ @@ -135,10 +135,10 @@ namespace gr { d_msg_handlers[which_port](msg); // Yes, invoke it. } } - + // Message passing interface pmt::pmt_t d_message_subscribers; - + public: pmt::pmt_t message_subscribers(pmt::pmt_t port); virtual ~basic_block(); @@ -153,18 +153,18 @@ namespace gr { std::string alias(){ return alias_set()?d_symbol_alias:symbol_name(); } pmt::pmt_t alias_pmt(){ return pmt::intern(alias()); } void set_block_alias(std::string name); - + // ** Message passing interface ** void message_port_register_in(pmt::pmt_t port_id); void message_port_register_out(pmt::pmt_t port_id); void message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg); void message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target); void message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target); - + virtual bool message_port_is_hier(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier\n"; return false; } virtual bool message_port_is_hier_in(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier_in\n"; return false; } virtual bool message_port_is_hier_out(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier_out\n"; return false; } - + /*! * \brief Get input message port names. * @@ -172,7 +172,7 @@ namespace gr { * return object is a PMT vector that is filled with PMT symbols. */ pmt::pmt_t message_ports_in(); - + /*! * \brief Get output message port names. * @@ -180,19 +180,19 @@ namespace gr { * return object is a PMT vector that is filled with PMT symbols. */ pmt::pmt_t message_ports_out(); - + /*! * Accept msg, place in queue, arrange for thread to be awakened if it's not already. */ void _post(pmt::pmt_t which_port, pmt::pmt_t msg); - + //! is the queue empty? - bool empty_p(pmt::pmt_t which_port) { + bool empty_p(pmt::pmt_t which_port) { if(msg_queue.find(which_port) == msg_queue.end()) throw std::runtime_error("port does not exist!"); - return msg_queue[which_port].empty(); + return msg_queue[which_port].empty(); } - bool empty_p() { + bool empty_p() { bool rv = true; BOOST_FOREACH(msg_queue_map_t::value_type &i, msg_queue) { rv &= msg_queue[i.first].empty(); @@ -204,7 +204,7 @@ namespace gr { bool empty_handled_p(pmt::pmt_t which_port){ return (empty_p(which_port) || !has_msg_handler(which_port)); } - bool empty_handled_p() { + bool empty_handled_p() { bool rv = true; BOOST_FOREACH(msg_queue_map_t::value_type &i, msg_queue) { rv &= empty_handled_p(i.first); @@ -213,24 +213,24 @@ namespace gr { } //! How many messages in the queue? - size_t nmsgs(pmt::pmt_t which_port) { + size_t nmsgs(pmt::pmt_t which_port) { if(msg_queue.find(which_port) == msg_queue.end()) throw std::runtime_error("port does not exist!"); - return msg_queue[which_port].size(); + return msg_queue[which_port].size(); } - + //| Acquires and release the mutex void insert_tail( pmt::pmt_t which_port, pmt::pmt_t msg); /*! * \returns returns pmt at head of queue or pmt::pmt_t() if empty. */ pmt::pmt_t delete_head_nowait( pmt::pmt_t which_port); - + /*! * \returns returns pmt at head of queue or pmt::pmt_t() if empty. */ pmt::pmt_t delete_head_blocking( pmt::pmt_t which_port); - + msg_queue_t::iterator get_iterator(pmt::pmt_t which_port) { return msg_queue[which_port].begin(); } @@ -238,7 +238,7 @@ namespace gr { void erase_msg(pmt::pmt_t which_port, msg_queue_t::iterator it) { msg_queue[which_port].erase(it); } - + virtual bool has_msg_port(pmt::pmt_t which_port) { if(msg_queue.find(which_port) != msg_queue.end()) { return true; @@ -290,7 +290,7 @@ namespace gr { * \brief When the block is registered with the RPC, set this. */ void rpc_set() { d_rpc_set = true; } - + /*! * \brief Confirm that ninputs and noutputs is an acceptable combination. * @@ -304,12 +304,12 @@ namespace gr { * This check is in addition to the constraints specified by the * input and output gr::io_signatures. */ - virtual bool check_topology(int ninputs, int noutputs) { + virtual bool check_topology(int ninputs, int noutputs) { (void)ninputs; (void)noutputs; return true; } - + /*! * \brief Set the callback that is fired when messages are available. * diff --git a/gnuradio-runtime/include/gnuradio/rpccallbackregister_base.h b/gnuradio-runtime/include/gnuradio/rpccallbackregister_base.h index 3d2d4cc79a..814749fe66 100644 --- a/gnuradio-runtime/include/gnuradio/rpccallbackregister_base.h +++ b/gnuradio-runtime/include/gnuradio/rpccallbackregister_base.h @@ -1,9 +1,9 @@ /* -*- c++ -*- */ -/* +/* * Copyright 2012 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) @@ -28,7 +28,7 @@ typedef uint32_t DisplayType; -// DisplayType Plotting types +//! DisplayType Plotting types const uint32_t DISPNULL = 0x0000; const uint32_t DISPTIME = 0x0001; const uint32_t DISPXY = 0x0002; @@ -36,7 +36,7 @@ const uint32_t DISPPSD = 0x0004; const uint32_t DISPSPEC = 0x0008; const uint32_t DISPRAST = 0x0010; -// DisplayType Options +//! DisplayType Options const uint32_t DISPOPTCPLX = 0x0100; const uint32_t DISPOPTLOG = 0x0200; const uint32_t DISPOPTSTEM = 0x0400; @@ -80,7 +80,7 @@ struct callbackregister_base class callback_t : public callback_base_t { public: - callback_t(T* callback_, priv_lvl_t priv_, + callback_t(T* callback_, priv_lvl_t priv_, const std::string& units_, const DisplayType display_, const:: std::string& desc_, const pmt::pmt_t& min_, const pmt::pmt_t& max_, const pmt::pmt_t& def_) : callback_base_t(priv_, units_, display_, desc_, min_, max_, def_), @@ -88,6 +88,12 @@ struct callbackregister_base { } + callback_t(T* callback_, priv_lvl_t priv_, const:: std::string& desc_) : + callback_base_t(priv_, "", 0, desc_, pmt::pmt_t(), pmt::pmt_t(), pmt::pmt_t()), + callback(callback_) + { + } + Tsptr callback; }; diff --git a/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h b/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h index 92adc0b768..ce21b9619c 100644 --- a/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h +++ b/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h @@ -1,9 +1,9 @@ /* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. +/* + * Copyright 2012,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) @@ -32,8 +32,17 @@ #include <gnuradio/rpcserver_base.h> #include <gnuradio/block_registry.h> -// Base classes -template<typename T, typename Tto> class rpcextractor_base + +/********************************************************************* + * RPC Extractor Base Classes + ********************************************************************/ + +/*! + *\brief Base class for registering a ControlPort Extractor. Acts as + * a message acceptor. + */ +template<typename T, typename Tto> +class rpcextractor_base : public virtual gr::messages::msg_accepter { public: @@ -50,15 +59,45 @@ protected: void (T::*_func)(Tto); }; +template<typename T> +class rpcextractor_base<T,void> + : public virtual gr::messages::msg_accepter +{ +public: + rpcextractor_base(T* source, void (T::*func)()) : + _source(source), _func(func) {;} + ~rpcextractor_base() {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) { + throw std::runtime_error("rpcextractor_base: no post defined for this data type.\n"); + } + +protected: + T* _source; + void (T::*_func)(); +}; + +/*! + * \brief Templated parent class for registering a ControlPort Extractor. + */ template<typename T, typename Tto> class rpcbasic_extractor : public virtual rpcextractor_base<T,Tto> { public: rpcbasic_extractor(T* source, void (T::*func)(Tto)) : - rpcextractor_base<T,Tto>(source, func) + rpcextractor_base<T,Tto>(source, func) {;} }; + +/********************************************************************* + * RPC Inserter Base Classes + ********************************************************************/ + +/*! + * \brief Base class for registering a ControlPort Inserter. Produces a + * message. + */ template<typename T, typename Tfrom> class rpcinserter_base : public virtual gr::messages::msg_producer { @@ -73,6 +112,11 @@ protected: Tfrom (T::*_func)(); }; + +/*! + * \brief Templated parent class for registering a ControlPort + * Inserter. + */ template<typename T, typename Tfrom> class rpcbasic_inserter : public virtual rpcinserter_base<T,Tfrom> @@ -86,14 +130,39 @@ public: : rpcinserter_base<T,Tfrom>(source, func) {;} - pmt::pmt_t retrieve() + pmt::pmt_t retrieve() { return pmt::mp((rpcinserter_base<T,Tfrom>:: _source->*rpcinserter_base<T,Tfrom>::_func)()); } }; -// Specialized Extractor Templates + +/********************************************************************* + * RPC Specialized Extractors + ********************************************************************/ + +/*! + * \brief Specialized extractor class to make calls to functions that + * do not take data (enable, reset, start, etc.). + */ +template<typename T> +class rpcbasic_extractor<T,void> : public virtual rpcextractor_base<T,void> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)()) + : rpcextractor_base<T,void>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,void>::_source->*rpcextractor_base<T,void>::_func)(); + } +}; + +/*! + * \brief Specialized extractor class for char data. + */ template<typename T> class rpcbasic_extractor<T,char> : public virtual rpcextractor_base<T,char> { @@ -109,6 +178,9 @@ public: } }; +/*! + * \brief Specialized extractor class for short data. + */ template<typename T> class rpcbasic_extractor<T,short> : public virtual rpcextractor_base<T,short> { @@ -124,6 +196,9 @@ public: } }; +/*! + * \brief Specialized extractor class for double data. + */ template<typename T> class rpcbasic_extractor<T,double> : public virtual rpcextractor_base<T,double> { @@ -139,6 +214,9 @@ public: } }; +/*! + * \brief Specialized extractor class for float data. + */ template<typename T> class rpcbasic_extractor<T,float> : public virtual rpcextractor_base<T,float> { @@ -154,6 +232,9 @@ public: } }; +/*! + * \brief Specialized extractor class for long data. + */ template<typename T> class rpcbasic_extractor<T,long> : public virtual rpcextractor_base<T,long> { @@ -169,6 +250,9 @@ public: } }; +/*! + * \brief Specialized extractor class for int data. + */ template<typename T> class rpcbasic_extractor<T,int> : public virtual rpcextractor_base<T,int> { @@ -184,6 +268,9 @@ public: } }; +/*! + * \brief Specialized extractor class for bool data. + */ template<typename T> class rpcbasic_extractor<T,bool> : public virtual rpcextractor_base<T,bool> { @@ -199,6 +286,9 @@ public: } }; +/*! + * \brief Specialized extractor class for complex (float) data. + */ template<typename T> class rpcbasic_extractor<T,std::complex<float> > : public virtual rpcextractor_base<T,std::complex<float> > @@ -216,6 +306,9 @@ public: } }; +/*! + * \brief Specialized extractor class for complex (double) data. + */ template<typename T> class rpcbasic_extractor<T,std::complex<double> > : public virtual rpcextractor_base<T,std::complex<double> > @@ -232,6 +325,9 @@ public: } }; +/*! + * \brief Specialized extractor class for string data. + */ template<typename T> class rpcbasic_extractor<T,std::string> : public virtual rpcextractor_base<T,std::string> @@ -244,10 +340,18 @@ public: void post(pmt::pmt_t which_port, pmt::pmt_t msg) { (rpcextractor_base<T,std::string>:: - _source->*rpcextractor_base<T,std::string>::_func)(pmt::symbol_to_string(msg)); + _source->*rpcextractor_base<T,std::string>::_func)(pmt::symbol_to_string(msg)); } }; + +/********************************************************************* + * RPC Specialized Inserters + ********************************************************************/ + +/*! + * \brief Specialized inserter class for uint64_t data. + */ template<typename T> class rpcbasic_inserter<T,uint64_t> : public virtual rpcinserter_base<T,uint64_t> { @@ -267,6 +371,9 @@ public: } }; +/*! + * \brief Specialized inserter class for vectors of signed char data. + */ template<typename T> class rpcbasic_inserter<T,std::vector< signed char > > : public virtual rpcinserter_base<T,std::vector< signed char > > @@ -284,11 +391,14 @@ public: { std::vector< signed char > vec((rpcinserter_base<T,std::vector< signed char > >:: - _source->*rpcinserter_base<T,std::vector< signed char > >::_func)()); + _source->*rpcinserter_base<T,std::vector< signed char > >::_func)()); return pmt::init_s8vector(vec.size(), &vec[0]); } }; +/*! + * \brief Specialized inserter class for vectors of short data. + */ template<typename T> class rpcbasic_inserter<T,std::vector< short > > : public virtual rpcinserter_base<T,std::vector< short > > @@ -306,11 +416,14 @@ public: { std::vector< short > vec((rpcinserter_base<T,std::vector< short > >:: - _source->*rpcinserter_base<T,std::vector< short > >::_func)()); + _source->*rpcinserter_base<T,std::vector< short > >::_func)()); return pmt::init_s16vector(vec.size(), &vec[0]); } }; +/*! + * \brief Specialized inserter class for vectors of int data. + */ template<typename T> class rpcbasic_inserter<T,std::vector< int > > : public virtual rpcinserter_base<T,std::vector< int > > @@ -328,11 +441,14 @@ public: { std::vector< int > vec((rpcinserter_base<T,std::vector<int > >:: - _source->*rpcinserter_base<T,std::vector< int > >::_func)()); + _source->*rpcinserter_base<T,std::vector< int > >::_func)()); return pmt::init_s32vector(vec.size(), &vec[0]); } }; +/*! + * \brief Specialized inserter class for vectors of complex (float) data. + */ template<typename T> class rpcbasic_inserter<T,std::vector< std::complex<float> > > : public virtual rpcinserter_base<T,std::vector< std::complex<float> > > @@ -350,11 +466,14 @@ public: { std::vector< std::complex<float> > vec((rpcinserter_base<T,std::vector<std::complex<float> > >:: - _source->*rpcinserter_base<T,std::vector< std::complex<float> > >::_func)()); + _source->*rpcinserter_base<T,std::vector< std::complex<float> > >::_func)()); return pmt::init_c32vector(vec.size(), &vec[0]); } }; +/*! + * \brief Specialized inserter class for vectors of float data. + */ template<typename T> class rpcbasic_inserter<T,std::vector< float> > : public virtual rpcinserter_base<T,std::vector< float > > @@ -363,7 +482,7 @@ public: rpcbasic_inserter(T* source, std::vector<float> (T::*func)() const) : rpcinserter_base<T,std::vector<float > >(source, func) {;} - + rpcbasic_inserter(T* source, std::vector<float> (T::*func)()) : rpcinserter_base<T,std::vector<float> >(source, func) {;} @@ -371,44 +490,50 @@ public: pmt::pmt_t retrieve() { std::vector< float > vec((rpcinserter_base<T,std::vector<float> >:: - _source->*rpcinserter_base<T,std::vector< float> >::_func)()); + _source->*rpcinserter_base<T,std::vector< float> >::_func)()); return pmt::init_f32vector(vec.size(), &vec[0]); } }; -template<typename T> -class rpcbasic_inserter<T,std::vector< uint8_t> > +/*! + * \brief Specialized inserter class for vectors of uint8_t data. + */ +template<typename T> +class rpcbasic_inserter<T,std::vector< uint8_t> > : public virtual rpcinserter_base<T,std::vector< uint8_t > > { public: - rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)() const) - : rpcinserter_base<T,std::vector<uint8_t > >(source, func) + rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)() const) + : rpcinserter_base<T,std::vector<uint8_t > >(source, func) {;} - rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)()) - : rpcinserter_base<T,std::vector<uint8_t> >(source, func) + rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)()) + : rpcinserter_base<T,std::vector<uint8_t> >(source, func) {;} - pmt::pmt_t retrieve() + pmt::pmt_t retrieve() { std::vector< uint8_t > vec((rpcinserter_base<T,std::vector<uint8_t> >:: _source->*rpcinserter_base<T,std::vector< uint8_t> >::_func)()); - return pmt::init_u8vector(vec.size(), &vec[0]); + return pmt::init_u8vector(vec.size(), &vec[0]); } }; -template<typename T> -class rpcbasic_inserter<T,std::complex<float> > +/*! + * \brief Specialized inserter class for complex (float) data. + */ +template<typename T> +class rpcbasic_inserter<T,std::complex<float> > : public virtual rpcinserter_base<T,std::complex<float > > { public: - rpcbasic_inserter(T* source, std::complex<float> (T::*func)() const) - : rpcinserter_base<T,std::complex<float> >(source, func) + rpcbasic_inserter(T* source, std::complex<float> (T::*func)() const) + : rpcinserter_base<T,std::complex<float> >(source, func) {;} - rpcbasic_inserter(T* source, std::complex<float> (T::*func)()) - : rpcinserter_base<T,std::complex<float> >(source, func) + rpcbasic_inserter(T* source, std::complex<float> (T::*func)()) + : rpcinserter_base<T,std::complex<float> >(source, func) {;} - pmt::pmt_t retrieve() + pmt::pmt_t retrieve() { std::complex<float > k((rpcinserter_base<T,std::complex<float> >:: _source->*rpcinserter_base<T,std::complex<float> >::_func)()); @@ -416,16 +541,19 @@ public: } }; -template<typename T> -class rpcbasic_inserter<T,std::complex<double> > +/*! + * \brief Specialized inserter class for complex (double) data. + */ +template<typename T> +class rpcbasic_inserter<T,std::complex<double> > : public virtual rpcinserter_base<T,std::complex<double > > { public: - rpcbasic_inserter(T* source, std::complex<double> (T::*func)() const) - : rpcinserter_base<T,std::complex<double> >(source, func) + rpcbasic_inserter(T* source, std::complex<double> (T::*func)() const) + : rpcinserter_base<T,std::complex<double> >(source, func) {;} - rpcbasic_inserter(T* source, std::complex<double> (T::*func)()) - : rpcinserter_base<T,std::complex<double> >(source, func) + rpcbasic_inserter(T* source, std::complex<double> (T::*func)()) + : rpcinserter_base<T,std::complex<double> >(source, func) {;} pmt::pmt_t retrieve() @@ -436,6 +564,9 @@ public: } }; +/*! + * \brief Base class for registering a ControlPort function. + */ template <typename T> struct rpc_register_base { @@ -443,7 +574,9 @@ struct rpc_register_base protected: static int count; }; -// Base class to inherit from and create universal shared pointers. +/*! + * Base class to inherit from and create universal shared pointers. + */ class rpcbasic_base { public: @@ -451,17 +584,80 @@ public: virtual ~rpcbasic_base() {}; }; + typedef boost::shared_ptr<rpcbasic_base> rpcbasic_sptr; + + +/********************************************************************* + * RPC Register Set Classes + ********************************************************************/ + +/*! + * \brief Registers a 'set' function to set a parameter over + * ControlPort. + * + * \details + * + * This class allows us to remotely set a value or parameter of the + * block over ControlPort. The set occurs by calling a setter accessor + * function of the class, usually set_[variable](), which is passed in + * as \p function. + * + * We can set the (expected) minimum (\p min), maximum (\p max), and + * default (\p def) of the variables being set. These values are not + * enforced, however, but can be useful for setting up graphs and + * other ways of bounding the data. + * + * This class also allows us to provide information to the user about + * the variable being set, such as an appropriate unit (\p units_) as + * well as a description (\p desc_) about what the variable does. + * + * The privilege (\p minpriv_) level is the minimum privilege level a + * remote must identify with to be able to call this function. + * + * We also provide display hints (\p display_), which can be used by + * the ControlPort client application to know how to best display or + * even print the data. This is a mask of options for variables set in + * rpccallbackregister_base.h. The mask is defined by one of the + * "DisplayType Plotting Types" and or'd with any of the "DisplayType + * Options" features. See "Display Options" in \ref page_ctrlport for + * details. + */ template<typename T, typename Tto> struct rpcbasic_register_set : public rpcbasic_base { - // Function used to add a 'set' RPC call using a basic_block's alias. + /*! + * \brief Adds the ability to set the variable over ControlPort. + * + * \details + * + * This constructor is specifically for gr::block's to use to add + * settable variables to ControlPort. Generally meant to be used + * in gr::block::setup_rpc. + * + * Uses the block's alias to create the ControlPort interface. This + * alias is cross-referenced by the global_block_registry (static + * variable of type gr::block_registry) to get the pointer to the + * block. + * + * \param block_alias Block's alias; use alias() to get it from the block. + * \param functionbase The name of the function that we'll access over ControlPort + * \param function A function pointer to the real function accessed when called + * something like: &[block class]\::set_[variable]() + * \param min Expected minimum value the parameter can hold + * \param max Expected maximum value the parameter can hold + * \param def Expected default value the parameter can hold + * \param units_ A string to describe what units to represent the variable with + * \param desc_ A string to describing the variable. + * \param minpriv_ The required minimum privilege level + * \param display_ The display mask + */ rpcbasic_register_set(const std::string& block_alias, const char* functionbase, - void (T::*function)(Tto), + void (T::*function)(Tto), const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, - const char* units_ = "", + const char* units_ = "", const char* desc_ = "", priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, DisplayType display_ = DISPNULL) @@ -476,7 +672,7 @@ struct rpcbasic_register_set : public rpcbasic_base d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); #ifdef RPCSERVER_ENABLED callbackregister_base::configureCallback_t - extractor(new rpcbasic_extractor<T,Tto>(d_object, function), + extractor(new rpcbasic_extractor<T,Tto>(d_object, function), minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); std::ostringstream oss(std::ostringstream::out); @@ -487,13 +683,35 @@ struct rpcbasic_register_set : public rpcbasic_base #endif } - // Function used to add a 'set' RPC call using a name and the object + /*! + * \brief Adds the ability to set the variable over ControlPort. + * + * \details + * + * Allows us to add non gr::block related objects to + * ControlPort. Instead of using the block's alias, we give it a \p + * name and the actual pointer to the object as \p obj. We just need + * to make sure that the pointer to this object is always valid. + * + * \param name Name of the object being set up for ControlPort access + * \param functionbase The name of the function that we'll access over ControlPort + * \param obj A pointer to the object itself + * \param function A function pointer to the real function accessed when called + * something like: &[block class]\::set_[variable]() + * \param min Expected minimum value the parameter can hold + * \param max Expected maximum value the parameter can hold + * \param def Expected default value the parameter can hold + * \param units_ A string to describe what units to represent the variable with + * \param desc_ A string to describing the variable. + * \param minpriv_ The required minimum privilege level + * \param display_ The display mask + */ rpcbasic_register_set(const std::string& name, const char* functionbase, T* obj, - void (T::*function)(Tto), + void (T::*function)(Tto), const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, - const char* units_ = "", + const char* units_ = "", const char* desc_ = "", priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, DisplayType display_ = DISPNULL) @@ -508,7 +726,7 @@ struct rpcbasic_register_set : public rpcbasic_base d_object = obj; #ifdef RPCSERVER_ENABLED callbackregister_base::configureCallback_t - extractor(new rpcbasic_extractor<T,Tto>(d_object, function), + extractor(new rpcbasic_extractor<T,Tto>(d_object, function), minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); std::ostringstream oss(std::ostringstream::out); @@ -553,17 +771,209 @@ private: }; +/********************************************************************* + * RPC Register Trigger Classes + ********************************************************************/ + +/*! + * \brief Registers a 'trigger' function to trigger an action over + * ControlPort. + * + * \details + * + * This class allows us to set up triggered events or function calls + * over ControlPort. When used from a ControlPort client, the \p + * function established here will be activated. Generally, this is + * meant to enable some kind of trigger or action that a block or + * object will perform, such as a reset, start, stop, etc. + * + * Simpler than the rpcbasic_register_set class, the constructor here + * only takes a few parameters, mostly because there is not actual + * variable associated with these function calls. It takes in the + * information to set up the pointer to the object that has the \p + * function, a ControlPort name (\p functionbase) for the triggered + * action, a description (\p desc_), and a privilege level (\p + * minpriv_). + */ +template<typename T> +struct rpcbasic_register_trigger : public rpcbasic_base +{ + /*! + * \brief Adds the ability to trigger a function over ControlPort. + * + * \details + * + * This constructor is specifically for gr::block's to use to add + * trigger functions to ControlPort. Generally meant to be used + * in gr::block::setup_rpc. + * + * Uses the block's alias to create the ControlPort interface. This + * alias is cross-referenced by the global_block_registry (static + * variable of type gr::block_registry) to get the pointer to the + * block. + * + * \param block_alias Block's alias; use alias() to get it from the block. + * \param functionbase The name of the function that we'll access over ControlPort + * \param function A function pointer to the real function accessed when called + * something like: &[block class]\::set_[variable] + * \param desc_ A string to describing the variable. + * \param minpriv_ The required minimum privilege level + */ + rpcbasic_register_trigger(const std::string& block_alias, + const char* functionbase, + void (T::*function)(), + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN) + { + d_desc = desc_; + d_minpriv = minpriv_; + d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); +#ifdef RPCSERVER_ENABLED + callbackregister_base::configureCallback_t + extractor(new rpcbasic_extractor<T,void>(d_object, function), + minpriv_, std::string(desc_)); + std::ostringstream oss(std::ostringstream::out); + oss << block_alias << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING TRIGGER: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); +#endif + } + + /*! + * \brief Adds the ability to trigger a function over ControlPort. + * + * \details + * + * Allows us to add non gr::block related objects to + * ControlPort. Instead of using the block's alias, we give it a \p + * name and the actual pointer to the object as \p obj. We just need + * to make sure that the pointer to this object is always valid. + * + * \param name Name of the object being set up for ControlPort access + * \param functionbase The name of the function that we'll access over ControlPort + * \param obj A pointer to the object itself + * \param function A function pointer to the real function accessed when called + * something like: &[block class]\::set_[variable] + * \param desc_ A string to describing the variable. + * \param minpriv_ The required minimum privilege level + */ + rpcbasic_register_trigger(const std::string& name, + const char* functionbase, + T* obj, + void (T::*function)(), + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN) + { + d_desc = desc_; + d_minpriv = minpriv_; + d_object = obj; +#ifdef RPCSERVER_ENABLED + callbackregister_base::configureCallback_t + extractor(new rpcbasic_extractor<T,void>(d_object, function), + minpriv_, std::string(desc_)); + std::ostringstream oss(std::ostringstream::out); + oss << name << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING TRIGGER: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); +#endif + } + + ~rpcbasic_register_trigger() + { +#ifdef RPCSERVER_ENABLED + rpcmanager::get()->i()->unregisterConfigureCallback(d_id); +#endif + } + + + std::string description() const { return d_desc; } + priv_lvl_t privilege_level() const { return d_minpriv; } + + void description(std::string d) { d_desc = d; } + void privilege_level(priv_lvl_t p) { d_minpriv = p; } + +private: + std::string d_id; + std::string d_desc; + priv_lvl_t d_minpriv; + T *d_object; +}; + + + +/********************************************************************* + * RPC Register Get Classes + ********************************************************************/ + +/*! + * \brief Registers a 'get' function to get a parameter over + * ControlPort. + * + * \details + * + * This class allows us to remotely get a value or parameter of the + * block over ControlPort. The get occurs by calling a getter accessor + * function of the class, usually [variable](), which is passed in + * as \p function. + * + * We can set the (expected) minimum (\p min), maximum (\p max), and + * default (\p def) of the variables we will get. These values are not + * enforced, however, but can be useful for setting up graphs and + * other ways of bounding the data. + * + * This class also allows us to provide information to the user about + * the variable, such as an appropriate unit (\p units_) as well as a + * description (\p desc_) about what the variable does. + * + * The privilege (\p minpriv_) level is the minimum privilege level a + * remote must identify with to be able to call this function. + * + * We also provide display hints (\p display_), which can be used by + * the ControlPort client application to know how to best display or + * even print the data. This is a mask of options for variables set in + * rpccallbackregister_base.h. The mask is defined by one of the + * "DisplayType Plotting Types" and or'd with any of the "DisplayType + * Options" features. See "Display Options" in \ref page_ctrlport for + * details. + */ template<typename T, typename Tfrom> class rpcbasic_register_get : public rpcbasic_base { public: - // Function used to add a 'set' RPC call using a basic_block's alias. - // primary constructor to allow for T get() functions + + /*! + * \brief Adds the ability to get the variable over ControlPort. + * + * \details + * + * This constructor is specifically for gr::block's to use to add + * gettable variables to ControlPort. Generally meant to be used + * in gr::block::setup_rpc. + * + * Uses the block's alias to create the ControlPort interface. This + * alias is cross-referenced by the global_block_registry (static + * variable of type gr::block_registry) to get the pointer to the + * block. + * + * \param block_alias Block's alias; use alias() to get it from the block. + * \param functionbase The name of the function that we'll access over ControlPort + * \param function A function pointer to the real function accessed when called + * something like: &[block class]\::[variable]() + * \param min Expected minimum value the parameter can hold + * \param max Expected maximum value the parameter can hold + * \param def Expected default value the parameter can hold + * \param units_ A string to describe what units to represent the variable with + * \param desc_ A string to describing the variable. + * \param minpriv_ The required minimum privilege level + * \param display_ The display mask + */ rpcbasic_register_get(const std::string& block_alias, const char* functionbase, - Tfrom (T::*function)(), + Tfrom (T::*function)(), const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, - const char* units_ = "", + const char* units_ = "", const char* desc_ = "", priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, DisplayType display_ = DISPNULL) @@ -578,7 +988,7 @@ public: d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); #ifdef RPCSERVER_ENABLED callbackregister_base::queryCallback_t - inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); std::ostringstream oss(std::ostringstream::out); oss << block_alias << "::" << functionbase; @@ -588,17 +998,20 @@ public: #endif } - - // alternate constructor to allow for T get() const functions + + /*! + * \brief Same as rpcbasic_register_get::rpcbasic_register_get that allows using + * '[variable]() const' getter functions. + */ rpcbasic_register_get(const std::string& block_alias, const char* functionbase, - Tfrom (T::*function)() const, + Tfrom (T::*function)() const, const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, - const char* units_ = "", + const char* units_ = "", const char* desc_ = "", priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, DisplayType display_ = DISPNULL) - { + { d_min = min; d_max = max; d_def = def; @@ -609,7 +1022,7 @@ public: d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); #ifdef RPCSERVER_ENABLED callbackregister_base::queryCallback_t - inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); std::ostringstream oss(std::ostringstream::out); oss << block_alias << "::" << functionbase; @@ -619,14 +1032,36 @@ public: #endif } - // Function used to add a 'set' RPC call using a name and the object - // primary constructor to allow for T get() functions + + /*! + * \brief Adds the ability to get the variable over ControlPort. + * + * \details + * + * Allows us to add non gr::block related objects to + * ControlPort. Instead of using the block's alias, we give it a \p + * name and the actual pointer to the object as \p obj. We just need + * to make sure that the pointer to this object is always valid. + * + * \param name Name of the object being set up for ControlPort access + * \param functionbase The name of the function that we'll access over ControlPort + * \param obj A pointer to the object itself + * \param function A function pointer to the real function accessed when called + * something like: &[block class]\::set_[variable]() + * \param min Expected minimum value the parameter can hold + * \param max Expected maximum value the parameter can hold + * \param def Expected default value the parameter can hold + * \param units_ A string to describe what units to represent the variable with + * \param desc_ A string to describing the variable. + * \param minpriv_ The required minimum privilege level + * \param display_ The display mask + */ rpcbasic_register_get(const std::string& name, const char* functionbase, T* obj, - Tfrom (T::*function)(), + Tfrom (T::*function)(), const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, - const char* units_ = "", + const char* units_ = "", const char* desc_ = "", priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, DisplayType display_ = DISPNULL) @@ -641,7 +1076,7 @@ public: d_object = obj; #ifdef RPCSERVER_ENABLED callbackregister_base::queryCallback_t - inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); std::ostringstream oss(std::ostringstream::out); oss << name << "::" << functionbase; @@ -651,18 +1086,21 @@ public: #endif } - - // alternate constructor to allow for T get() const functions + + /*! + * \brief Same as above that allows using '[variable]() const' + * getter functions. + */ rpcbasic_register_get(const std::string& name, const char* functionbase, T* obj, - Tfrom (T::*function)() const, + Tfrom (T::*function)() const, const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, - const char* units_ = "", + const char* units_ = "", const char* desc_ = "", priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, DisplayType display_ = DISPNULL) - { + { d_min = min; d_max = max; d_def = def; @@ -673,7 +1111,7 @@ public: d_object = obj; #ifdef RPCSERVER_ENABLED callbackregister_base::queryCallback_t - inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); std::ostringstream oss(std::ostringstream::out); oss << name << "::" << functionbase; @@ -715,23 +1153,64 @@ private: T *d_object; }; -/* - * This class can wrap a pre-existing variable type for you - * it will define the getter and rpcregister call for you. - * - * It should be used for read-only getters. + + +/********************************************************************* + * RPC Register Variable Classes + ********************************************************************/ + +/*! + * \brief Registers a read-only function to get a parameter over ControlPort. + * + * \details + * + * This class allows us to remotely get a value or parameter of the + * block over ControlPort. Unlike the rpcbasic_register_get class, + * this version is passed the variable directly and establishes a + * getter for us, so there is no need to have a getter function + * already in the object. + * + * This version is for read-only get access. + * + * We can set the (expected) minimum (\p min), maximum (\p max), and + * default (\p def) of the variables we will get. These values are not + * enforced, however, but can be useful for setting up graphs and + * other ways of bounding the data. + * + * This class also allows us to provide information to the user about + * the variable, such as an appropriate unit (\p units_) as well as a + * description (\p desc_) about what the variable does. * + * The privilege (\p minpriv_) level is the minimum privilege level a + * remote must identify with to be able to call this function. + * + * We also provide display hints (\p display_), which can be used by + * the ControlPort client application to know how to best display or + * even print the data. This is a mask of options for variables set in + * rpccallbackregister_base.h. The mask is defined by one of the + * "DisplayType Plotting Types" and or'd with any of the "DisplayType + * Options" features. See "Display Options" in \ref page_ctrlport for + * details. */ template<typename Tfrom> -class rpcbasic_register_variable : public rpcbasic_base +class rpcbasic_register_variable + : public rpcbasic_base { protected: rpcbasic_register_get< rpcbasic_register_variable<Tfrom>, Tfrom > d_rpc_reg; Tfrom *d_variable; Tfrom get() { return *d_variable; } + public: - // empty constructor which should never be called but needs to exist for ues in varous STL data structures - void setptr(Tfrom* _variable){ rpcbasic_register_variable<Tfrom>::d_variable = _variable; } + + void setptr(Tfrom* _variable) + { + rpcbasic_register_variable<Tfrom>::d_variable = _variable; + } + + /*! Empty constructor which should never be called but needs to + * exist for ues in varous STL data structures + */ rpcbasic_register_variable() : d_rpc_reg("FAIL", "FAIL", this, &rpcbasic_register_variable::get, pmt::PMT_NIL, pmt::PMT_NIL, pmt::PMT_NIL, DISPNULL, @@ -741,6 +1220,24 @@ public: throw std::runtime_error("ERROR: rpcbasic_register_variable called with no args. If this happens, someone has tried to use rpcbasic_register_variable incorrectly."); }; + /*! + * \brief Adds the ability to get the variable over ControlPort. + * + * \details + * + * Creates a new getter accessor function to read \p variable. + * + * \param namebase Name of the object being set up for ControlPort access + * \param functionbase The name of the function that we'll access over ControlPort + * \param variable A pointer to the variable, possibly as a member of a class + * \param min Expected minimum value the parameter can hold + * \param max Expected maximum value the parameter can hold + * \param def Expected default value the parameter can hold + * \param units_ A string to describe what units to represent the variable with + * \param desc_ A string to describing the variable. + * \param minpriv_ The required minimum privilege level + * \param display_ The display mask + */ rpcbasic_register_variable(const std::string& namebase, const char* functionbase, Tfrom *variable, @@ -748,7 +1245,7 @@ public: const char* units_ = "", const char* desc_ = "", priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, - DisplayType display_=DISPNULL) : + DisplayType display_ = DISPNULL) : d_rpc_reg(namebase, functionbase, this, &rpcbasic_register_variable::get, min, max, def, units_, desc_, minpriv_, display_), d_variable(variable) @@ -757,18 +1254,86 @@ public: } }; -template<typename Tfrom> class rpcbasic_register_variable_rw : public rpcbasic_register_variable<Tfrom> { - private: - rpcbasic_register_set< rpcbasic_register_variable_rw<Tfrom>, Tfrom > d_rpc_regset; - public: - // empty constructor which should never be called but needs to exist for ues in varous STL data structures - rpcbasic_register_variable_rw() : - d_rpc_regset("FAIL","FAIL",this,&rpcbasic_register_variable<Tfrom>::get,pmt::PMT_NIL,pmt::PMT_NIL,pmt::PMT_NIL,DISPNULL,"FAIL","FAIL",RPC_PRIVLVL_MIN) - { - throw std::runtime_error("ERROR: rpcbasic_register_variable_rw called with no args. if this happens someone used rpcbasic_register_variable_rw incorrectly.\n"); - }; - void set(Tfrom _variable){ *(rpcbasic_register_variable<Tfrom>::d_variable) = _variable; } - rpcbasic_register_variable_rw( + +/*! + * \brief Registers a read/write function to get and set a parameter + * over ControlPort. + * + * \details + * + * This class allows us to remotely get and/or set a value or + * parameter of the block over ControlPort. Unlike the + * rpcbasic_register_get class, this version is passed the variable + * directly and establishes a getter for us, so there is no need to + * have a getter function already in the object. + * + * This version establishes both get and set functions and so provides + * read/write access to the variable. + * + * We can set the (expected) minimum (\p min), maximum (\p max), and + * default (\p def) of the variables we will get. These values are not + * enforced, however, but can be useful for setting up graphs and + * other ways of bounding the data. + * + * This class also allows us to provide information to the user about + * the variable, such as an appropriate unit (\p units_) as well as a + * description (\p desc_) about what the variable does. + * + * The privilege (\p minpriv_) level is the minimum privilege level a + * remote must identify with to be able to call this function. + * + * We also provide display hints (\p display_), which can be used by + * the ControlPort client application to know how to best display or + * even print the data. This is a mask of options for variables set in + * rpccallbackregister_base.h. The mask is defined by one of the + * "DisplayType Plotting Types" and or'd with any of the "DisplayType + * Options" features. See "Display Options" in \ref page_ctrlport for + * details. + */ +template<typename Tfrom> +class rpcbasic_register_variable_rw + : public rpcbasic_register_variable<Tfrom> +{ +private: + rpcbasic_register_set< rpcbasic_register_variable_rw<Tfrom>, Tfrom > d_rpc_regset; + +public: + /*! Empty constructor which should never be called but needs to + * exist for ues in varous STL data structures. + */ + rpcbasic_register_variable_rw() : + d_rpc_regset("FAIL", "FAIL", this, + &rpcbasic_register_variable<Tfrom>::get, + pmt::PMT_NIL, pmt::PMT_NIL, pmt::PMT_NIL, + DISPNULL, "FAIL", "FAIL", RPC_PRIVLVL_MIN) + { + throw std::runtime_error("ERROR: rpcbasic_register_variable_rw called with no args. if this happens someone used rpcbasic_register_variable_rw incorrectly.\n"); + }; + + void set(Tfrom _variable) + { + *(rpcbasic_register_variable<Tfrom>::d_variable) = _variable; + } + + /*! + * \brief Adds the ability to set and get the variable over ControlPort. + * + * \details + * + * Creates new getter and setter accessor functions to read and write \p variable. + * + * \param namebase Name of the object being set up for ControlPort access + * \param functionbase The name of the function that we'll access over ControlPort + * \param variable A pointer to the variable, possibly as a member of a class + * \param min Expected minimum value the parameter can hold + * \param max Expected maximum value the parameter can hold + * \param def Expected default value the parameter can hold + * \param units_ A string to describe what units to represent the variable with + * \param desc_ A string to describing the variable. + * \param minpriv_ The required minimum privilege level + * \param display_ The display mask + */ + rpcbasic_register_variable_rw( const std::string& namebase, const char* functionbase, Tfrom *variable, @@ -776,12 +1341,15 @@ template<typename Tfrom> class rpcbasic_register_variable_rw : public rpcbasic_r const char* units_ = "", const char* desc_ = "", priv_lvl_t minpriv = RPC_PRIVLVL_MIN, - DisplayType display_=DISPNULL) : - rpcbasic_register_variable<Tfrom>(namebase,functionbase,variable,min,max,def,units_,desc_), - d_rpc_regset(namebase,functionbase,this,&rpcbasic_register_variable_rw::set,min,max,def,units_,desc_,minpriv,display_) - { - // no action - } + DisplayType display_=DISPNULL) + : rpcbasic_register_variable<Tfrom>(namebase, functionbase, variable, + min, max, def, units_, desc_), + d_rpc_regset(namebase, functionbase, this, + &rpcbasic_register_variable_rw::set, + min, max, def, units_, desc_, minpriv, display_) + { + // no action + } }; diff --git a/gnuradio-runtime/include/gnuradio/thread/thread.h b/gnuradio-runtime/include/gnuradio/thread/thread.h index a0c9e4f09d..6cd84ae7e5 100644 --- a/gnuradio-runtime/include/gnuradio/thread/thread.h +++ b/gnuradio-runtime/include/gnuradio/thread/thread.h @@ -149,6 +149,9 @@ namespace gr { * Note: this does not work on OSX */ GR_RUNTIME_API int set_thread_priority(gr_thread_t thread, int priority); + + GR_RUNTIME_API void set_thread_name(gr_thread_t thread, + std::string name); } /* namespace thread */ } /* namespace gr */ diff --git a/gnuradio-runtime/lib/block.cc b/gnuradio-runtime/lib/block.cc index 7a1364def9..bdf484e8db 100644 --- a/gnuradio-runtime/lib/block.cc +++ b/gnuradio-runtime/lib/block.cc @@ -30,6 +30,7 @@ #include <gnuradio/buffer.h> #include <gnuradio/prefs.h> #include <gnuradio/config.h> +#include <gnuradio/rpcregisterhelpers.h> #include <stdexcept> #include <iostream> @@ -739,6 +740,11 @@ namespace gr { d_pc_rpc_set = true; #if defined(GR_CTRLPORT) && defined(GR_PERFORMANCE_COUNTERS) d_rpc_vars.push_back( + rpcbasic_sptr(new rpcbasic_register_trigger<block>( + alias(), "reset_perf_counters", &block::reset_perf_counters, + "Reset the Performance Counters", RPC_PRIVLVL_MIN))); + + d_rpc_vars.push_back( rpcbasic_sptr(new rpcbasic_register_get<block, float>( alias(), "noutput_items", &block::pc_noutput_items, pmt::mp(0), pmt::mp(32768), pmt::mp(0), diff --git a/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc b/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc index efd2a5599c..1477ae2c8d 100644 --- a/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc +++ b/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc @@ -54,7 +54,7 @@ rpcpmtconverter::from_pmt(const pmt::pmt_t& knob, const Ice::Current& c) size_t size(pmt::length(knob)); const float* start((const float*) pmt::c32vector_elements(knob,size)); return new GNURadio::KnobVecF(std::vector<float>(start,start+size*2)); - } + } else if (pmt::is_s32vector(knob)) { size_t size(pmt::length(knob)); const int* start((const int*) pmt::s32vector_elements(knob,size)); @@ -69,7 +69,7 @@ rpcpmtconverter::from_pmt(const pmt::pmt_t& knob, const Ice::Current& c) size_t size(pmt::length(knob)); const float* start((const float*) pmt::f32vector_elements(knob,size)); return new GNURadio::KnobVecF(std::vector<float>(start,start+size)); - } + } else if (pmt::is_u8vector(knob)) { size_t size(pmt::length(knob)); const uint8_t* start((const uint8_t*) pmt::u8vector_elements(knob,size)); @@ -112,7 +112,10 @@ rpcpmtconverter::to_pmt(const GNURadio::KnobPtr& knob, const Ice::Current& c) } else if(id == "KnobB") { GNURadio::KnobBPtr k(GNURadio::KnobBPtr::dynamicCast(knob)); - return pmt::mp(k->value); + if((k->value == true) || (k->value > 0)) + return pmt::PMT_T; + else + return pmt::PMT_F; } else if(id == "KnobC") { GNURadio::KnobCPtr k(GNURadio::KnobCPtr::dynamicCast(knob)); @@ -121,16 +124,16 @@ rpcpmtconverter::to_pmt(const GNURadio::KnobPtr& knob, const Ice::Current& c) else if(id == "KnobL") { GNURadio::KnobLPtr k(GNURadio::KnobLPtr::dynamicCast(knob)); return pmt::mp((long)k->value); - } + } else if(id == "KnobZ") { GNURadio::KnobZPtr k(GNURadio::KnobZPtr::dynamicCast(knob)); std::complex<double> cpx(k->value.re, k->value.im); return pmt::from_complex(cpx); - } + } else if(id == "KnobVecC") { GNURadio::KnobVecCPtr k(GNURadio::KnobVecCPtr::dynamicCast(knob)); return pmt::init_u8vector(k->value.size(), &k->value[0]); - } + } else if(id == "KnobVecI") { GNURadio::KnobVecIPtr k(GNURadio::KnobVecIPtr::dynamicCast(knob)); return pmt::init_s32vector(k->value.size(), &k->value[0]); @@ -144,5 +147,5 @@ rpcpmtconverter::to_pmt(const GNURadio::KnobPtr& knob, const Ice::Current& c) std::cerr << "Error: Don't know how to handle Knob Type: " << id << std::endl; assert(0); } - return pmt::pmt_t(); + return pmt::pmt_t(); } diff --git a/gnuradio-runtime/lib/pmt/pmt.cc b/gnuradio-runtime/lib/pmt/pmt.cc index f3f7783839..a9907cabe1 100644 --- a/gnuradio-runtime/lib/pmt/pmt.cc +++ b/gnuradio-runtime/lib/pmt/pmt.cc @@ -942,8 +942,7 @@ msg_accepter_ref(const pmt_t &obj) bool is_blob(pmt_t x) { - // return is_u8vector(x); - return is_uniform_vector(x); + return is_u8vector(x); } pmt_t diff --git a/gnuradio-runtime/lib/thread/thread.cc b/gnuradio-runtime/lib/thread/thread.cc index 5e5874ec0f..53eb23b2f0 100644 --- a/gnuradio-runtime/lib/thread/thread.cc +++ b/gnuradio-runtime/lib/thread/thread.cc @@ -24,6 +24,7 @@ #endif #include <gnuradio/thread/thread.h> +#include <boost/format.hpp> #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) @@ -110,6 +111,41 @@ namespace gr { // Not implemented on Windows return -1; } +#pragma pack(push,8) + typedef struct tagTHREADNAME_INFO + { + DWORD dwType; // Must be 0x1000 + LPCSTR szName; // Pointer to name (in user addr space) + DWORD dwThreadID; // Thread ID (-1 = caller thread) + DWORD dwFlags; // Reserved for future use, must be zero + } THREADNAME_INFO; +#pragma pack(pop) + void + set_thread_name(gr_thread_t thread, std::string name) + { + const DWORD SET_THREAD_NAME_EXCEPTION = 0x406D1388; + + DWORD dwThreadId = GetThreadId(thread); + if (dwThreadId == 0) + return; + + if (name.empty()) + name = boost::str(boost::format("thread %lu") % dwThreadId); + + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name.c_str(); + info.dwThreadID = dwThreadId; + info.dwFlags = 0; + + __try + { + RaiseException(SET_THREAD_NAME_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } + } } /* namespace thread */ } /* namespace gr */ @@ -177,6 +213,12 @@ namespace gr { // Not implemented on OSX return -1; } + + void + set_thread_name(gr_thread_t thread, std::string name) + { + // Not implemented on OSX + } } /* namespace thread */ } /* namespace gr */ @@ -186,6 +228,7 @@ namespace gr { #include <sstream> #include <stdexcept> #include <pthread.h> +#include <sys/prctl.h> namespace gr { namespace thread { @@ -283,6 +326,34 @@ namespace gr { param.sched_priority = priority; return pthread_setschedparam(thread, policy, ¶m); } + + void + set_thread_name(gr_thread_t thread, std::string name) + { + if (thread != pthread_self()) // Naming another thread is not supported + return; + + if (name.empty()) + name = boost::str(boost::format("thread %llu") % ((unsigned long long)thread)); + + const int max_len = 16; // Maximum accepted by PR_SET_NAME + + if ((int)name.size() > max_len) // Shorten the name if necessary by taking as many characters from the front + { // so that the unique_id can still fit on the end + int i = name.size() - 1; + for (; i >= 0; --i) + { + std::string s = name.substr(i, 1); + int n = atoi(s.c_str()); + if ((n == 0) && (s != "0")) + break; + } + + name = name.substr(0, std::max(0, max_len - ((int)name.size() - (i + 1)))) + name.substr(i + 1); + } + + prctl(PR_SET_NAME, name.c_str(), 0, 0, 0); + } } /* namespace thread */ } /* namespace gr */ diff --git a/gnuradio-runtime/lib/top_block.cc b/gnuradio-runtime/lib/top_block.cc index 99f8330add..8918a8f12d 100644 --- a/gnuradio-runtime/lib/top_block.cc +++ b/gnuradio-runtime/lib/top_block.cc @@ -140,6 +140,22 @@ namespace gr { if(is_rpc_set()) return; + // Triggers + d_rpc_vars.push_back( + rpcbasic_sptr(new rpcbasic_register_trigger<top_block>( + alias(), "stop", &top_block::stop, + "Stop the flowgraph", RPC_PRIVLVL_MIN))); + + d_rpc_vars.push_back( + rpcbasic_sptr(new rpcbasic_register_trigger<top_block>( + alias(), "lock", &top_block::lock, + "Lock the flowgraph", RPC_PRIVLVL_MIN))); + + d_rpc_vars.push_back( + rpcbasic_sptr(new rpcbasic_register_trigger<top_block>( + alias(), "unlock", &top_block::unlock, + "Unock the flowgraph", RPC_PRIVLVL_MIN))); + // Getters add_rpc_variable( rpcbasic_sptr(new rpcbasic_register_get<top_block, int>( diff --git a/gnuradio-runtime/lib/tpb_thread_body.cc b/gnuradio-runtime/lib/tpb_thread_body.cc index 7cdee6a097..79abd0e61d 100644 --- a/gnuradio-runtime/lib/tpb_thread_body.cc +++ b/gnuradio-runtime/lib/tpb_thread_body.cc @@ -36,6 +36,8 @@ namespace gr { : d_exec(block, max_noutput_items) { //std::cerr << "tpb_thread_body: " << block << std::endl; + + thread::set_thread_name(pthread_self(), boost::str(boost::format("%s%d") % block->name() % block->unique_id())); block_detail *d = block->detail().get(); block_executor::state s; diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx b/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx index 5d9cdd114d..369922cbbf 100755 --- a/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx +++ b/gnuradio-runtime/python/gnuradio/ctrlport/gr-perf-monitorx @@ -46,7 +46,7 @@ class MAINWindow(QtGui.QMainWindow): return QtGui.QSize(800,600) def __init__(self, radio, port, interface): - + super(MAINWindow, self).__init__() self.conns = [] self.plots = [] @@ -75,7 +75,6 @@ class MAINWindow(QtGui.QMainWindow): icon = QtGui.QIcon(ctrlport.__path__[0] + "/icon.png" ) self.setWindowIcon(icon) - def newSubWindow(self, window, title): child = window; child.setWindowTitle(title) @@ -131,7 +130,6 @@ class MAINWindow(QtGui.QMainWindow): statusTip="Close all the windows", triggered=self.mdiArea.closeAllSubWindows) - qks = QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_T); self.tileAct = QtGui.QAction("&Tile", self, statusTip="Tile the windows", @@ -236,7 +234,7 @@ class ConInfoDialog(QtGui.QDialog): super(ConInfoDialog, self).__init__(parent) self.gridLayout = QtGui.QGridLayout(self) - + self.host = QtGui.QLineEdit(self); self.port = QtGui.QLineEdit(self); @@ -267,7 +265,7 @@ class DataTable(QtGui.QWidget): def __init__(self, radio, G): QtGui.QWidget.__init__( self) - + self.layout = QtGui.QVBoxLayout(self); self.hlayout = QtGui.QHBoxLayout(); self.layout.addLayout(self.hlayout); @@ -325,7 +323,7 @@ class DataTable(QtGui.QWidget): self.timer.start(500) for i in range(0,len(nodes)): - self.perfTable.setItem( + self.perfTable.setItem( i,0, Qt.QTableWidgetItem(nodes[i][0])) @@ -370,7 +368,7 @@ class DataTableBuffers(DataTable): for blk in buffer_fullness: for port in range(0,len(buffer_fullness[blk])): blockport_fullness["%s:%d"%(blk,port)] = buffer_fullness[blk][port]; - + self.table_update(blockport_fullness); if(self._sort): @@ -431,8 +429,8 @@ class DataTableRuntimes(DataTable): sorted_work[self._keymap.index(b)] = (b, work_times[b]) else: sorted_work = work_times.items() - - self.sp.clear(); + + self.sp.clear(); plt.figure(self.f.number) plt.subplot(111); self.sp.bar(range(0,len(sorted_work)), map(lambda x: x[1], sorted_work), @@ -441,7 +439,7 @@ class DataTableRuntimes(DataTable): self.sp.set_xticks( map(lambda x: x+0.5, range(0,len(sorted_work)))) self.sp.set_xticklabels( map(lambda x: " " + x[0], sorted_work), rotation="vertical", verticalalignment="bottom" ) - + self.canvas.draw(); self.canvas.show(); @@ -466,7 +464,7 @@ class MForm(QtGui.QWidget): nodes_stream = self.G_stream.nodes(); nodes_msg = self.G_msg.nodes(); - + # get current buffer depths of all output buffers kl = map(lambda x: "%s::%soutput %% full" % \ (x, self._statistics_table[self._statistic]), @@ -500,7 +498,7 @@ class MForm(QtGui.QWidget): self.G.nodes(), [0.1]*len(self.G.nodes()))) work_times_padded.update(work_times) - + for n in nodes_stream: # ne is the list of edges away from this node! ne = self.G.edges([n],True); @@ -520,7 +518,7 @@ class MForm(QtGui.QWidget): #newweight = buf_vals[n][sourceport] newweight = 0.01; e[2]["weight"] = newweight; - + # set updated weights #self.node_weights = map(lambda x: 20+2000*work_times[x], nodes_stream); self.node_weights = map(lambda x: 20+2000*work_times_padded[x], self.G.nodes()); @@ -532,7 +530,7 @@ class MForm(QtGui.QWidget): latency = td1 + td2; self.parent.statusBar().showMessage("Current GNU Radio Control Port Query Latency: %f ms"%\ (latency*1000)) - + except Exception, e: sys.stderr.write("ctrlport-monitor: radio.get threw exception ({0}).\n".format(e)) if(type(self.parent) is MAINWindow): @@ -551,13 +549,42 @@ class MForm(QtGui.QWidget): else: sys.exit(1) return - + def rtt(self): self.parent.newSubWindow( DataTableRuntimes(self.radio, self.G_stream), "Runtime Table" ); def bpt(self): self.parent.newSubWindow( DataTableBuffers(self.radio, self.G_stream), "Buffers Table" ); + def resetPCs(self): + knob = GNURadio.KnobB() + knob.value = False + km = {} + for b in self.blocks_list: + km[b + "::reset_perf_counters"] = knob + k = self.radio.set(km) + + def toggleFlowgraph(self): + if self.pauseFGAct.isChecked(): + self.pauseFlowgraph() + else: + self.unpauseFlowgraph() + + def pauseFlowgraph(self): + knob = GNURadio.KnobB() + knob.value = False + km = {} + km[self.top_block + "::lock"] = knob + km[self.top_block + "::stop"] = knob + k = self.radio.set(km) + + def unpauseFlowgraph(self): + knob = GNURadio.KnobB() + knob.value = False + km = {} + km[self.top_block + "::unlock"] = knob + k = self.radio.set(km) + def stat_changed(self, index): self._statistic = str(self.stattype.currentText()) @@ -586,7 +613,7 @@ class MForm(QtGui.QWidget): else: self.radio = None return - + self.uid = uid self.parent = parent @@ -597,7 +624,7 @@ class MForm(QtGui.QWidget): self.layoutTop.addLayout(self.ctlBox); self.layoutTop.addLayout(self.layout); - + self.rttAct = QtGui.QAction("Runtime Table", self, statusTip="Runtime Table", triggered=self.rtt) self.rttBut = Qt.QToolButton() @@ -610,6 +637,21 @@ class MForm(QtGui.QWidget): self.bptBut.setDefaultAction(self.bptAct); self.ctlBox.addWidget(self.bptBut); + self.resetPCsAct = QtGui.QAction("Reset", self, + statusTip="Reset all Performance Counters", + triggered=self.resetPCs) + self.resetPCsBut = Qt.QToolButton() + self.resetPCsBut.setDefaultAction(self.resetPCsAct); + self.ctlBox.addWidget(self.resetPCsBut); + + self.pauseFGAct = QtGui.QAction("Pause", self, + statusTip="Pause the Flowgraph", + triggered=self.toggleFlowgraph) + self.pauseFGAct.setCheckable(True) + self.pauseFGBut = Qt.QToolButton() + self.pauseFGBut.setDefaultAction(self.pauseFGAct); + self.ctlBox.addWidget(self.pauseFGBut); + self.prevent_clock_change = True; self.clockKey = None; self.clocks = {"MONOTONIC":1, "THREAD":3}; @@ -660,6 +702,7 @@ class MForm(QtGui.QWidget): keyname = propname[1] if(keyname == "edge list"): edgelist = knobs[k].value + self.top_block = blockname elif(keyname == "msg edges list"): msgedgelist = knobs[k].value elif(blockname not in tmplist): @@ -667,12 +710,14 @@ class MForm(QtGui.QWidget): if(knobs.has_key(input_name(blockname))): tmplist.append(blockname) + if not edgelist: sys.stderr.write("Could not find list of edges from flowgraph. " + \ "Make sure the option 'edges_list' is enabled " + \ "in the ControlPort configuration.\n\n") sys.exit(1) + self.blocks_list = tmplist edges = edgelist.split("\n")[0:-1] msgedges = msgedgelist.split("\n")[0:-1] @@ -690,7 +735,7 @@ class MForm(QtGui.QWidget): _e = e.split("->") edgepairs_msg.append( (_e[0].split(":")[0], _e[1].split(":")[0], {"type":"msg", "sourceport":_e[0].split(":")[1]}) ); - + self.G = nx.MultiDiGraph(); self.G_stream = nx.MultiDiGraph(); self.G_msg = nx.MultiDiGraph(); @@ -773,14 +818,14 @@ class MForm(QtGui.QWidget): item = self.table.treeWidget.itemFromIndex(index[0]) itemname = str(item.text(0)) self.parent.propertiesMenu(itemname, self.radio, self.uid) - + def updateGraph(self): self.canvas.updateGeometry() - self.sp.clear(); + self.sp.clear(); plt.figure(self.f.number) plt.subplot(111); - nx.draw(self.G, self.pos, + nx.draw(self.G, self.pos, edge_color=self.edge_weights, node_color='#A0CBE2', width=map(lambda x: 3+math.log(x), self.edge_weights), diff --git a/gnuradio-runtime/python/gnuradio/ctrlport/icon.png b/gnuradio-runtime/python/gnuradio/ctrlport/icon.png Binary files differindex 4beb204428..1c27323696 100644 --- a/gnuradio-runtime/python/gnuradio/ctrlport/icon.png +++ b/gnuradio-runtime/python/gnuradio/ctrlport/icon.png diff --git a/gnuradio-runtime/python/pmt/pmt_to_python.py b/gnuradio-runtime/python/pmt/pmt_to_python.py index e4797f9d44..3344eba163 100644 --- a/gnuradio-runtime/python/pmt/pmt_to_python.py +++ b/gnuradio-runtime/python/pmt/pmt_to_python.py @@ -63,13 +63,42 @@ def pmt_from_dict(p): d = pmt.dict_add(d, python_to_pmt(k), python_to_pmt(v)) return d -def numpy_to_blob(p): - p = p.view(numpy.uint8) - b = pmt.make_blob(len(p)) - pmt.blob_data(b)[:] = p - return b +numpy_mappings = { + numpy.dtype(numpy.float32): (pmt.init_f32vector, float, pmt.f32vector_elements, pmt.is_f32vector), + numpy.dtype(numpy.float64): (pmt.init_f64vector, float, pmt.f64vector_elements, pmt.is_f64vector), + numpy.dtype(numpy.complex64): (pmt.init_c32vector, complex, pmt.c32vector_elements, pmt.is_c32vector), + numpy.dtype(numpy.complex128): (pmt.init_c64vector, complex, pmt.c64vector_elements, pmt.is_c64vector), + numpy.dtype(numpy.int8): (pmt.init_s8vector, int, pmt.s8vector_elements, pmt.is_s8vector), + numpy.dtype(numpy.int16): (pmt.init_s16vector, int, pmt.s16vector_elements, pmt.is_s16vector), + numpy.dtype(numpy.int32): (pmt.init_s32vector, int, pmt.s32vector_elements, pmt.is_s32vector), +# numpy.dtype(numpy.int64): (pmt.init_s64vector, int, pmt.s64vector_elements, pmt.is_s64vector), + numpy.dtype(numpy.uint8): (pmt.init_u8vector, int, pmt.u8vector_elements, pmt.is_u8vector), + numpy.dtype(numpy.uint16): (pmt.init_u16vector, int, pmt.u16vector_elements, pmt.is_u16vector), + numpy.dtype(numpy.uint32): (pmt.init_u32vector, int, pmt.u32vector_elements, pmt.is_u32vector), +# numpy.dtype(numpy.uint64): (pmt.init_u64vector, int, pmt.u64vector_elements, pmt.is_u64vector), + numpy.dtype(numpy.byte): (pmt.init_u8vector, int, pmt.u8vector_elements, pmt.is_u8vector), +} -THE_TABLE = ( #python type, check pmt type, to python, from python +uvector_mappings = dict([ (numpy_mappings[key][3], (numpy_mappings[key][2], key)) for key in numpy_mappings ]) + +def numpy_to_uvector(numpy_array): + try: + mapping = numpy_mappings[numpy_array.dtype] + pc = map(mapping[1], numpy.ravel(numpy_array)) + return mapping[0](numpy_array.size, pc) + except KeyError: + raise ValueError("unsupported numpy array dtype for converstion to pmt %s"%(numpy_array.dtype)) + +def uvector_to_numpy(uvector): + match = None + for test_func in uvector_mappings.keys(): + if test_func(uvector): + match = uvector_mappings[test_func] + return numpy.array(match[0](uvector), dtype = match[1]) + else: + raise ValueError("unsupported uvector data type for conversion to numpy array %s"%(uvector)) + +type_mappings = ( #python type, check pmt type, to python, from python (None, pmt.is_null, lambda x: None, lambda x: pmt.PMT_NIL), (bool, pmt.is_bool, pmt.to_bool, pmt.from_bool), (str, pmt.is_symbol, pmt.symbol_to_string, pmt.string_to_symbol), @@ -81,18 +110,18 @@ THE_TABLE = ( #python type, check pmt type, to python, from python (tuple, pmt.is_tuple, pmt_to_tuple, pmt_from_tuple), (list, pmt.is_vector, pmt_to_vector, pmt_from_vector), (dict, pmt.is_dict, pmt_to_dict, pmt_from_dict), - (numpy.ndarray, pmt.is_blob, pmt.blob_data, numpy_to_blob), + (numpy.ndarray, pmt.is_uniform_vector, uvector_to_numpy, numpy_to_uvector), ) def pmt_to_python(p): - for python_type, pmt_check, to_python, from_python in THE_TABLE: + for python_type, pmt_check, to_python, from_python in type_mappings: if pmt_check(p): return to_python(p) - return p #give up, we return the same + raise ValueError("can't convert %s type to pmt (%s)"%(type(p),p)) def python_to_pmt(p): - for python_type, pmt_check, to_python, from_python in THE_TABLE: + for python_type, pmt_check, to_python, from_python in type_mappings: if python_type is None: if p == None: return from_python(p) elif isinstance(p, python_type): return from_python(p) - return p #give up, we return the same + raise ValueError("can't convert %s type to pmt (%s)"%(type(p),p)) diff --git a/gnuradio-runtime/python/pmt/qa_pmt_to_python.py b/gnuradio-runtime/python/pmt/qa_pmt_to_python.py index ae86fc6d53..39cfc05dd6 100755 --- a/gnuradio-runtime/python/pmt/qa_pmt_to_python.py +++ b/gnuradio-runtime/python/pmt/qa_pmt_to_python.py @@ -22,13 +22,27 @@ import unittest import pmt +import pmt_to_python as pmt2py class test_pmt_to_python(unittest.TestCase): - def test01 (self): + def test_pmt_from_double(self): b = pmt.from_double(123765) self.assertEqual(pmt.to_python(b), 123765) t = pmt.to_pmt(range(5)) + + def test_numpy_to_uvector_and_reverse(self): + import numpy as np + N = 100 + narr = np.ndarray(N, dtype=np.complex128) + narr.real[:] = np.random.uniform(size=N) + narr.imag[:] = np.random.uniform(size=N) + uvector = pmt2py.numpy_to_uvector(narr) + nparr = pmt2py.uvector_to_numpy(uvector) + self.assertTrue(nparr.dtype==narr.dtype) + self.assertTrue(np.alltrue(nparr == narr)) + + if __name__ == '__main__': unittest.main() diff --git a/gr-blocks/grc/blocks_socket_pdu.xml b/gr-blocks/grc/blocks_socket_pdu.xml index 1e897cfc4b..72dc38134c 100644 --- a/gr-blocks/grc/blocks_socket_pdu.xml +++ b/gr-blocks/grc/blocks_socket_pdu.xml @@ -8,7 +8,7 @@ <name>Socket PDU</name> <key>blocks_socket_pdu</key> <import>from gnuradio import blocks</import> - <make>blocks.socket_pdu($type, $host, $port, $mtu)</make> + <make>blocks.socket_pdu($type, $host, $port, $mtu, $tcp_no_delay)</make> <param> <name>Type</name> <key>type</key> @@ -49,6 +49,31 @@ <value>10000</value> <type>int</type> </param> + <param> + <name>TCP No Delay</name> + <key>tcp_no_delay</key> + <value>False</value> + <type>enum</type> + <hide> +#if (($type() == '"TCP_CLIENT"') or ($type() == '"TCP_SERVER"')) +#if (str($tcp_no_delay()) == 'False') +part +#else +none +#end if +#else +all +#end if +</hide> + <option> + <name>Enabled</name> + <key>True</key> + </option> + <option> + <name>Disabled</name> + <key>False</key> + </option> + </param> <sink> <name>pdus</name> <type>message</type> @@ -59,4 +84,5 @@ <type>message</type> <optional>1</optional> </source> + <doc>For server modes, leave Host blank to bind to all interfaces (equivalent to 0.0.0.0).</doc> </block> diff --git a/gr-blocks/grc/blocks_throttle.xml b/gr-blocks/grc/blocks_throttle.xml index 06f96b15cc..790e195750 100644 --- a/gr-blocks/grc/blocks_throttle.xml +++ b/gr-blocks/grc/blocks_throttle.xml @@ -58,6 +58,7 @@ <key>ignoretag</key> <value>True</value> <type>bool</type> + <hide>#if str($ignoretag()) == 'True' then 'part' else 'none'#</hide> </param> <check>$vlen > 0</check> <sink> diff --git a/gr-blocks/include/gnuradio/blocks/pack_k_bits_bb.h b/gr-blocks/include/gnuradio/blocks/pack_k_bits_bb.h index c8c4378c30..cd057725c1 100644 --- a/gr-blocks/include/gnuradio/blocks/pack_k_bits_bb.h +++ b/gr-blocks/include/gnuradio/blocks/pack_k_bits_bb.h @@ -32,6 +32,15 @@ namespace gr { /*! * \brief Converts a stream of bytes with 1 bit in the LSB to a * byte with k relevent bits. + * + * This block takes in K bytes at a time, and uses the least significant + * bit to form a new byte. + * + * Example: + * k = 4 + * in = [0,1,0,1, 0x81,0x00,0x00,0x00] + * out = [0x05, 0x08] + * * \ingroup byte_operators_blk */ class BLOCKS_API pack_k_bits_bb : virtual public sync_decimator diff --git a/gr-blocks/include/gnuradio/blocks/short_to_char.h b/gr-blocks/include/gnuradio/blocks/short_to_char.h index de4df623a1..22a157d341 100644 --- a/gr-blocks/include/gnuradio/blocks/short_to_char.h +++ b/gr-blocks/include/gnuradio/blocks/short_to_char.h @@ -31,6 +31,12 @@ namespace gr { /*! * \brief Convert stream of shorts to a stream of chars. + * + * This block strips off the least significant byte from the + * short value. + * + * [0x00ff, 0x0ff0, 0xff00] => [0x00, 0x0f, 0xff] + * * \ingroup type_converters_blk */ class BLOCKS_API short_to_char : virtual public sync_block diff --git a/gr-blocks/include/gnuradio/blocks/socket_pdu.h b/gr-blocks/include/gnuradio/blocks/socket_pdu.h index 82a7632e7b..31468a3f43 100644 --- a/gr-blocks/include/gnuradio/blocks/socket_pdu.h +++ b/gr-blocks/include/gnuradio/blocks/socket_pdu.h @@ -45,8 +45,9 @@ namespace gr { * \param addr network address to use * \param port network port to use * \param MTU maximum transmission unit + * \param tcp_no_delay TCP No Delay option (set to True to disable Nagle algorithm) */ - static sptr make(std::string type, std::string addr, std::string port, int MTU=10000); + static sptr make(std::string type, std::string addr, std::string port, int MTU=10000, bool tcp_no_delay=false); }; } /* namespace blocks */ diff --git a/gr-blocks/include/gnuradio/blocks/unpack_k_bits_bb.h b/gr-blocks/include/gnuradio/blocks/unpack_k_bits_bb.h index 926819502a..09d7ae912c 100644 --- a/gr-blocks/include/gnuradio/blocks/unpack_k_bits_bb.h +++ b/gr-blocks/include/gnuradio/blocks/unpack_k_bits_bb.h @@ -31,6 +31,14 @@ namespace gr { /*! * \brief Converts a byte with k relevent bits to k output bytes with 1 bit in the LSB. + * + * This block picks the K least significant bits from a byte, and expands + * them into K bytes of 0 or 1. + * + * Example: + * k = 4 + * in = [0xf5, 0x08] + * out = [0,1,0,1, 1,0,0,0] * \ingroup byte_operators_blk */ class BLOCKS_API unpack_k_bits_bb : virtual public sync_interpolator diff --git a/gr-blocks/lib/socket_pdu_impl.cc b/gr-blocks/lib/socket_pdu_impl.cc index 9daf8c30c9..a467452c3f 100644 --- a/gr-blocks/lib/socket_pdu_impl.cc +++ b/gr-blocks/lib/socket_pdu_impl.cc @@ -33,41 +33,60 @@ namespace gr { namespace blocks { socket_pdu::sptr - socket_pdu::make(std::string type, std::string addr, std::string port, int MTU) + socket_pdu::make(std::string type, std::string addr, std::string port, int MTU/*= 10000*/, bool tcp_no_delay/*= false*/) { - return gnuradio::get_initial_sptr(new socket_pdu_impl(type, addr, port, MTU)); + return gnuradio::get_initial_sptr(new socket_pdu_impl(type, addr, port, MTU, tcp_no_delay)); } - socket_pdu_impl::socket_pdu_impl(std::string type, std::string addr, std::string port, int MTU) - : block("socket_pdu", - io_signature::make (0, 0, 0), - io_signature::make (0, 0, 0)) + socket_pdu_impl::socket_pdu_impl(std::string type, std::string addr, std::string port, int MTU/*= 10000*/, bool tcp_no_delay/*= false*/) + : block("socket_pdu", + io_signature::make (0, 0, 0), + io_signature::make (0, 0, 0)), + d_tcp_no_delay(tcp_no_delay) { + d_rxbuf.resize(MTU); + message_port_register_in(PDU_PORT_ID); message_port_register_out(PDU_PORT_ID); - if ((type == "TCP_SERVER") || (type == "TCP_CLIENT")) { + if ((type == "TCP_SERVER") && ((addr.empty()) || (addr == "0.0.0.0"))) { // Bind on all interfaces + int port_num = atoi(port.c_str()); + if (port_num == 0) + throw std::invalid_argument("gr::blocks:socket_pdu: invalid port for TCP_SERVER"); + d_tcp_endpoint = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port_num); + } + else if ((type == "TCP_SERVER") || (type == "TCP_CLIENT")) { boost::asio::ip::tcp::resolver resolver(d_io_service); - boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), addr, port); - d_tcp_endpoint = *resolver.resolve(query); + boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), + addr, port, + boost::asio::ip::resolver_query_base::passive); + d_tcp_endpoint = *resolver.resolve(query); } - - if ((type == "UDP_SERVER") || (type == "UDP_CLIENT")) { - boost::asio::ip::udp::resolver resolver(d_io_service); - boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port); + else if ((type == "UDP_SERVER") && ((addr.empty()) || (addr == "0.0.0.0"))) { // Bind on all interfaces + int port_num = atoi(port.c_str()); + if (port_num == 0) + throw std::invalid_argument("gr::blocks:socket_pdu: invalid port for UDP_SERVER"); + d_udp_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port_num); + } + else if ((type == "UDP_SERVER") || (type == "UDP_CLIENT")) { + boost::asio::ip::udp::resolver resolver(d_io_service); + boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), + addr, port, + boost::asio::ip::resolver_query_base::passive); if (type == "UDP_SERVER") - d_udp_endpoint = *resolver.resolve(query); + d_udp_endpoint = *resolver.resolve(query); else - d_udp_endpoint_other = *resolver.resolve(query); + d_udp_endpoint_other = *resolver.resolve(query); } if (type == "TCP_SERVER") { d_acceptor_tcp.reset(new boost::asio::ip::tcp::acceptor(d_io_service, d_tcp_endpoint)); d_acceptor_tcp->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + start_tcp_accept(); + set_msg_handler(PDU_PORT_ID, boost::bind(&socket_pdu_impl::tcp_server_send, this, _1)); - } else if (type =="TCP_CLIENT") { boost::system::error_code error = boost::asio::error::host_not_found; @@ -75,34 +94,35 @@ namespace gr { d_tcp_socket->connect(d_tcp_endpoint, error); if (error) throw boost::system::system_error(error); + d_tcp_socket->set_option(boost::asio::ip::tcp::no_delay(d_tcp_no_delay)); set_msg_handler(PDU_PORT_ID, boost::bind(&socket_pdu_impl::tcp_client_send, this, _1)); - d_tcp_socket->async_read_some( - boost::asio::buffer(d_rxbuf), - boost::bind(&socket_pdu_impl::handle_tcp_read, this, - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred) - ); + d_tcp_socket->async_read_some(boost::asio::buffer(d_rxbuf), + boost::bind(&socket_pdu_impl::handle_tcp_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); } else if (type =="UDP_SERVER") { d_udp_socket.reset(new boost::asio::ip::udp::socket(d_io_service, d_udp_endpoint)); d_udp_socket->async_receive_from(boost::asio::buffer(d_rxbuf), d_udp_endpoint_other, - boost::bind(&socket_pdu_impl::handle_udp_read, this, - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred)); + boost::bind(&socket_pdu_impl::handle_udp_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + set_msg_handler(PDU_PORT_ID, boost::bind(&socket_pdu_impl::udp_send, this, _1)); } else if (type =="UDP_CLIENT") { d_udp_socket.reset(new boost::asio::ip::udp::socket(d_io_service, d_udp_endpoint)); d_udp_socket->async_receive_from(boost::asio::buffer(d_rxbuf), d_udp_endpoint_other, - boost::bind(&socket_pdu_impl::handle_udp_read, this, - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred)); + boost::bind(&socket_pdu_impl::handle_udp_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + set_msg_handler(PDU_PORT_ID, boost::bind(&socket_pdu_impl::udp_send, this, _1)); } else - throw std::runtime_error("gr::blocks:socket_pdu: unknown socket type"); + throw std::runtime_error("gr::blocks:socket_pdu: unknown socket type"); d_thread = gr::thread::thread(boost::bind(&socket_pdu_impl::run_io_service, this)); d_started = true; @@ -112,14 +132,14 @@ namespace gr { socket_pdu_impl::handle_tcp_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { - pmt::pmt_t vector = pmt::init_u8vector(bytes_transferred, (const uint8_t *)&d_rxbuf[0]); - pmt::pmt_t pdu = pmt::cons(pmt::PMT_NIL, vector); - message_port_pub(PDU_PORT_ID, pdu); - - d_tcp_socket->async_read_some(boost::asio::buffer(d_rxbuf), - boost::bind(&socket_pdu_impl::handle_tcp_read, this, - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred)); + pmt::pmt_t vector = pmt::init_u8vector(bytes_transferred, (const uint8_t *)&d_rxbuf[0]); + pmt::pmt_t pdu = pmt::cons(pmt::PMT_NIL, vector); + message_port_pub(PDU_PORT_ID, pdu); + + d_tcp_socket->async_read_some(boost::asio::buffer(d_rxbuf), + boost::bind(&socket_pdu_impl::handle_tcp_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); } else throw boost::system::system_error(error); @@ -128,11 +148,11 @@ namespace gr { void socket_pdu_impl::start_tcp_accept() { - tcp_connection::sptr new_connection = tcp_connection::make(d_acceptor_tcp->get_io_service()); + tcp_connection::sptr new_connection = tcp_connection::make(d_acceptor_tcp->get_io_service(), d_rxbuf.size(), d_tcp_no_delay); d_acceptor_tcp->async_accept(new_connection->socket(), - boost::bind(&socket_pdu_impl::handle_tcp_accept, this, - new_connection, boost::asio::placeholders::error)); + boost::bind(&socket_pdu_impl::handle_tcp_accept, this, + new_connection, boost::asio::placeholders::error)); } void @@ -147,12 +167,12 @@ namespace gr { socket_pdu_impl::handle_tcp_accept(tcp_connection::sptr new_connection, const boost::system::error_code& error) { if (!error) { - new_connection->start(this); - d_tcp_connections.push_back(new_connection); - start_tcp_accept(); + new_connection->start(this); + d_tcp_connections.push_back(new_connection); + start_tcp_accept(); } else - std::cout << error << std::endl; + std::cout << error << std::endl; } void @@ -160,22 +180,32 @@ namespace gr { { pmt::pmt_t vector = pmt::cdr(msg); size_t len = pmt::length(vector); - size_t offset(0); - boost::array<char, 10000> txbuf; - memcpy(&txbuf[0], pmt::uniform_vector_elements(vector, offset), len); - d_tcp_socket->send(boost::asio::buffer(txbuf,len)); + size_t offset = 0; + std::vector<char> txbuf(std::min(len, d_rxbuf.size())); + while (offset < len) { + size_t send_len = std::min((len - offset), txbuf.size()); + memcpy(&txbuf[0], pmt::uniform_vector_elements(vector, offset), send_len); + offset += send_len; + d_tcp_socket->send(boost::asio::buffer(txbuf, send_len)); + } } void socket_pdu_impl::udp_send(pmt::pmt_t msg) { + if (d_udp_endpoint_other.address().to_string() == "0.0.0.0") + return; + pmt::pmt_t vector = pmt::cdr(msg); size_t len = pmt::length(vector); - size_t offset(0); - boost::array<char, 10000> txbuf; - memcpy(&txbuf[0], pmt::uniform_vector_elements(vector, offset), len); - if (d_udp_endpoint_other.address().to_string() != "0.0.0.0") - d_udp_socket->send_to(boost::asio::buffer(txbuf,len), d_udp_endpoint_other); + size_t offset = 0; + std::vector<char> txbuf(std::min(len, d_rxbuf.size())); + while (offset < len) { + size_t send_len = std::min((len - offset), txbuf.size()); + memcpy(&txbuf[0], pmt::uniform_vector_elements(vector, offset), send_len); + offset += send_len; + d_udp_socket->send_to(boost::asio::buffer(txbuf, send_len), d_udp_endpoint_other); + } } void @@ -183,14 +213,14 @@ namespace gr { { if (!error) { pmt::pmt_t vector = pmt::init_u8vector(bytes_transferred, (const uint8_t*)&d_rxbuf[0]); - pmt::pmt_t pdu = pmt::cons( pmt::PMT_NIL, vector); + pmt::pmt_t pdu = pmt::cons(pmt::PMT_NIL, vector); message_port_pub(PDU_PORT_ID, pdu); d_udp_socket->async_receive_from(boost::asio::buffer(d_rxbuf), d_udp_endpoint_other, - boost::bind(&socket_pdu_impl::handle_udp_read, this, - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred)); + boost::bind(&socket_pdu_impl::handle_udp_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); } } diff --git a/gr-blocks/lib/socket_pdu_impl.h b/gr-blocks/lib/socket_pdu_impl.h index 3099d90e00..2d5bc33518 100644 --- a/gr-blocks/lib/socket_pdu_impl.h +++ b/gr-blocks/lib/socket_pdu_impl.h @@ -34,13 +34,14 @@ namespace gr { { private: boost::asio::io_service d_io_service; - boost::array<char, 10000> d_rxbuf; + std::vector<char> d_rxbuf; void run_io_service() { d_io_service.run(); } // TCP specific boost::asio::ip::tcp::endpoint d_tcp_endpoint; std::vector<tcp_connection::sptr> d_tcp_connections; void handle_tcp_read(const boost::system::error_code& error, size_t bytes_transferred); + bool d_tcp_no_delay; // TCP server specific boost::shared_ptr<boost::asio::ip::tcp::acceptor> d_acceptor_tcp; @@ -60,7 +61,7 @@ namespace gr { void udp_send(pmt::pmt_t msg); public: - socket_pdu_impl(std::string type, std::string addr, std::string port, int MTU); + socket_pdu_impl(std::string type, std::string addr, std::string port, int MTU = 10000, bool tcp_no_delay = false); }; } /* namespace blocks */ diff --git a/gr-blocks/lib/stream_mux_impl.cc b/gr-blocks/lib/stream_mux_impl.cc index 1e42c2504f..698cf89d09 100644 --- a/gr-blocks/lib/stream_mux_impl.cc +++ b/gr-blocks/lib/stream_mux_impl.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012,2014 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,10 +26,8 @@ #include "stream_mux_impl.h" #include <gnuradio/io_signature.h> -#include <string.h> -#include <cstdio> - -#define VERBOSE 0 +#include <boost/foreach.hpp> +#include <cstring> namespace gr { namespace blocks { @@ -48,8 +46,11 @@ namespace gr { d_residual(0), d_lengths(lengths) { - if(d_lengths[d_stream] == 0) { - increment_stream(); + while (d_lengths[d_stream] == 0) { + d_stream++; + if (d_stream == d_lengths.size()) { + throw std::invalid_argument("At least one size must be non-zero."); + } } d_residual = d_lengths[d_stream]; } @@ -58,69 +59,57 @@ namespace gr { stream_mux_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] = (d_lengths[i] == 0 ? 0 : 1); - } - - void - stream_mux_impl::increment_stream() - { - do { - d_stream = (d_stream+1) % d_lengths.size(); - } while(d_lengths[d_stream] == 0); - - d_residual = d_lengths[d_stream]; + for (unsigned i = 0; i < ninputs; i++) { + // Only active inputs *need* items, for the rest, it would just be nice + ninput_items_required[i] = (d_stream == i ? 1 : 0); + } } int stream_mux_impl::general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ char *out = (char *) output_items[0]; const char *in; - int out_index = 0; - std::vector<int> input_index(d_lengths.size(), 0); - - if(VERBOSE) { - printf("mux: nouput_items: %d d_stream: %d\n", noutput_items, d_stream); - for(size_t i = 0; i < d_lengths.size(); i++) - printf("\tninput_items[%zu]: %d\n", i, ninput_items[i]); - } - - while (1) { - int r = std::min(noutput_items - out_index, - std::min(d_residual, - ninput_items[d_stream] - input_index[d_stream])); - if(VERBOSE) { - printf("mux: r=%d\n", r); - printf("\tnoutput_items - out_index: %d\n", - noutput_items - out_index); - printf("\td_residual: %d\n", - d_residual); - printf("\tninput_items[d_stream] - input_index[d_stream]: %d\n", - ninput_items[d_stream] - input_index[d_stream]); - } - - if(r <= 0) { - return out_index; - } - - in = (const char *) input_items[d_stream] + input_index[d_stream]*d_itemsize; - - memcpy(&out[out_index*d_itemsize], in, r*d_itemsize); - out_index += r; - input_index[d_stream] += r; - d_residual -= r; - - consume(d_stream, r); - - if(d_residual == 0) { - increment_stream(); - } + int out_index = 0; // Items written + gr_vector_int input_index(d_lengths.size(), 0); // Items read + + while (out_index < noutput_items) { + if (ninput_items[d_stream] <= input_index[d_stream]) { + break; + } + int space_left_in_buffers = std::min( + noutput_items - out_index, // Space left in output buffer + ninput_items[d_stream] - input_index[d_stream] // Space left in input buffer + ); + int items_to_copy = std::min( + space_left_in_buffers, + d_residual + ); + in = (const char *) input_items[d_stream] + input_index[d_stream]*d_itemsize; + memcpy(&out[out_index*d_itemsize], in, items_to_copy*d_itemsize); + out_index += items_to_copy; + input_index[d_stream] += items_to_copy; + d_residual -= items_to_copy; + if (d_residual == 0) { + do { // Skip all those inputs with zero length + d_stream = (d_stream+1) % d_lengths.size(); + } while (d_lengths[d_stream] == 0); + d_residual = d_lengths[d_stream]; + } else { + break; + } + } // while + + for (size_t i = 0; i < input_index.size(); i++) { + consume((int) i, input_index[i]); } - } + + return out_index; + } /* work */ + } /* namespace blocks */ } /* namespace gr */ diff --git a/gr-blocks/lib/stream_mux_impl.h b/gr-blocks/lib/stream_mux_impl.h index 328eb0710e..67be9381af 100644 --- a/gr-blocks/lib/stream_mux_impl.h +++ b/gr-blocks/lib/stream_mux_impl.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012,2014 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -36,10 +36,8 @@ namespace gr { int d_residual; // number if items left to put into current stream gr_vector_int d_lengths; // number if items to pack per stream - void increment_stream(); - void forecast(int noutput_items, gr_vector_int &ninput_items_required); - + public: stream_mux_impl(size_t itemsize, const std::vector<int> &lengths); diff --git a/gr-blocks/lib/tcp_connection.cc b/gr-blocks/lib/tcp_connection.cc index ce719d1843..970732e656 100644 --- a/gr-blocks/lib/tcp_connection.cc +++ b/gr-blocks/lib/tcp_connection.cc @@ -31,55 +31,69 @@ namespace gr { namespace blocks { - tcp_connection::sptr tcp_connection::make(boost::asio::io_service& io_service) + tcp_connection::sptr tcp_connection::make(boost::asio::io_service& io_service, int MTU/*= 10000*/, bool no_delay/*=false*/) { - return sptr(new tcp_connection(io_service)); + return sptr(new tcp_connection(io_service, MTU, no_delay)); } - tcp_connection::tcp_connection(boost::asio::io_service& io_service) + tcp_connection::tcp_connection(boost::asio::io_service& io_service, int MTU/*= 10000*/, bool no_delay/*=false*/) : d_socket(io_service) + , d_block(NULL) + , d_no_delay(no_delay) { + d_buf.resize(MTU); + try { + d_socket.set_option(boost::asio::ip::tcp::no_delay(no_delay)); + } + catch (...) { + // Silently ignore failure (socket might be current in accept stage) and try again in 'start' + } } void tcp_connection::send(pmt::pmt_t vector) { size_t len = pmt::length(vector); - size_t offset(0); - boost::array<char, 10000> txbuf; - memcpy(&txbuf[0], pmt::uniform_vector_elements(vector, offset), len); - boost::asio::async_write(d_socket, boost::asio::buffer(txbuf, len), + size_t offset = 0; + std::vector<char> txbuf(std::min(len, d_buf.size())); + while (offset < len) { + size_t send_len = std::min((len - offset), txbuf.size()); + memcpy(&txbuf[0], pmt::uniform_vector_elements(vector, offset), send_len); + offset += send_len; + boost::asio::async_write(d_socket, boost::asio::buffer(txbuf, send_len), boost::bind(&tcp_connection::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + } } void tcp_connection::start(gr::basic_block *block) { d_block = block; + d_socket.set_option(boost::asio::ip::tcp::no_delay(d_no_delay)); d_socket.async_read_some(boost::asio::buffer(d_buf), - boost::bind(&tcp_connection::handle_read, this, - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred)); + boost::bind(&tcp_connection::handle_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); } void tcp_connection::handle_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { - pmt::pmt_t vector = pmt::init_u8vector(bytes_transferred, (const uint8_t*)&d_buf[0]); - pmt::pmt_t pdu = pmt::cons( pmt::PMT_NIL, vector); + if (d_block) { + pmt::pmt_t vector = pmt::init_u8vector(bytes_transferred, (const uint8_t*)&d_buf[0]); + pmt::pmt_t pdu = pmt::cons(pmt::PMT_NIL, vector); - d_block->message_port_pub(PDU_PORT_ID, pdu); + d_block->message_port_pub(PDU_PORT_ID, pdu); + } d_socket.async_read_some(boost::asio::buffer(d_buf), - boost::bind(&tcp_connection::handle_read, this, - boost::asio::placeholders::error, - boost::asio::placeholders::bytes_transferred)); - + boost::bind(&tcp_connection::handle_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); } } - } /* namespace blocks */ }/* namespace gr */ diff --git a/gr-blocks/lib/tcp_connection.h b/gr-blocks/lib/tcp_connection.h index f4d32fa90a..9193928c41 100644 --- a/gr-blocks/lib/tcp_connection.h +++ b/gr-blocks/lib/tcp_connection.h @@ -37,16 +37,16 @@ namespace gr { { private: boost::asio::ip::tcp::socket d_socket; - boost::array<char, 10000> d_buf; - std::string d_message; + std::vector<char> d_buf; basic_block *d_block; + bool d_no_delay; - tcp_connection(boost::asio::io_service& io_service); + tcp_connection(boost::asio::io_service& io_service, int MTU=10000, bool no_delay=false); public: typedef boost::shared_ptr<tcp_connection> sptr; - static sptr make(boost::asio::io_service& io_service); + static sptr make(boost::asio::io_service& io_service, int MTU=10000, bool no_delay=false); boost::asio::ip::tcp::socket& socket() { return d_socket; }; diff --git a/gr-blocks/python/blocks/qa_stream_mux.py b/gr-blocks/python/blocks/qa_stream_mux.py index 7abbced54c..00e32e955e 100755 --- a/gr-blocks/python/blocks/qa_stream_mux.py +++ b/gr-blocks/python/blocks/qa_stream_mux.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2005,2007,2010,2012,2013 Free Software Foundation, Inc. +# Copyright 2004,2005,2007,2010,2012,2013,2014 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -167,5 +167,19 @@ class test_stream_mux (gr_unittest.TestCase): self.assertEqual (exp_data, result_data) + def test_largeN_ff(self): + stream_sizes = [3, 8191] + r1 = (1,) * stream_sizes[0] + r2 = (2,) * stream_sizes[1] + v0 = blocks.vector_source_f(r1, repeat=False) + v1 = blocks.vector_source_f(r2, repeat=False) + mux = blocks.stream_mux(gr.sizeof_float, stream_sizes) + dst = blocks.vector_sink_f () + self.tb.connect (v0, (mux,0)) + self.tb.connect (v1, (mux,1)) + self.tb.connect (mux, dst) + self.tb.run () + self.assertEqual (r1 + r2, dst.data()) + if __name__ == '__main__': gr_unittest.run(test_stream_mux, "test_stream_mux.xml") diff --git a/gr-digital/examples/demod/test_corr_and_sync.grc b/gr-digital/examples/demod/test_corr_and_sync.grc index e0127878ad..8701690b88 100644 --- a/gr-digital/examples/demod/test_corr_and_sync.grc +++ b/gr-digital/examples/demod/test_corr_and_sync.grc @@ -1,6 +1,6 @@ <?xml version='1.0' encoding='ASCII'?> <flow_graph> - <timestamp>Thu Nov 7 11:05:37 2013</timestamp> + <timestamp>Thu Apr 10 15:34:59 2014</timestamp> <block> <key>options</key> <param> @@ -64,7 +64,7 @@ <key>variable</key> <param> <key>id</key> - <value>rrc_taps</value> + <value>samp_rate</value> </param> <param> <key>_enabled</key> @@ -72,11 +72,11 @@ </param> <param> <key>value</key> - <value>firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), eb, 5*sps*nfilts)</value> + <value>100000</value> </param> <param> <key>_coordinate</key> - <value>(1075, 73)</value> + <value>(11, 72)</value> </param> <param> <key>_rotation</key> @@ -87,7 +87,7 @@ <key>variable</key> <param> <key>id</key> - <value>nfilts</value> + <value>eb</value> </param> <param> <key>_enabled</key> @@ -95,11 +95,11 @@ </param> <param> <key>value</key> - <value>32</value> + <value>0.35</value> </param> <param> <key>_coordinate</key> - <value>(1074, 9)</value> + <value>(346, 72)</value> </param> <param> <key>_rotation</key> @@ -110,7 +110,7 @@ <key>variable</key> <param> <key>id</key> - <value>payload_size</value> + <value>matched_filter</value> </param> <param> <key>_enabled</key> @@ -118,11 +118,11 @@ </param> <param> <key>value</key> - <value>992</value> + <value>firdes.root_raised_cosine(nfilts, nfilts, 1, eb, int(11*sps*nfilts))</value> </param> <param> <key>_coordinate</key> - <value>(101, 73)</value> + <value>(429, 72)</value> </param> <param> <key>_rotation</key> @@ -133,7 +133,7 @@ <key>variable</key> <param> <key>id</key> - <value>gap</value> + <value>preamble</value> </param> <param> <key>_enabled</key> @@ -141,11 +141,11 @@ </param> <param> <key>value</key> - <value>20000</value> + <value>[1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1]</value> </param> <param> <key>_coordinate</key> - <value>(202, 72)</value> + <value>(279, 8)</value> </param> <param> <key>_rotation</key> @@ -156,7 +156,7 @@ <key>variable</key> <param> <key>id</key> - <value>bb_filter</value> + <value>sps</value> </param> <param> <key>_enabled</key> @@ -164,11 +164,11 @@ </param> <param> <key>value</key> - <value>firdes.root_raised_cosine(sps, sps, 1, eb, 101)</value> + <value>4</value> </param> <param> <key>_coordinate</key> - <value>(429, 8)</value> + <value>(278, 72)</value> </param> <param> <key>_rotation</key> @@ -179,7 +179,7 @@ <key>variable</key> <param> <key>id</key> - <value>sps</value> + <value>bb_filter</value> </param> <param> <key>_enabled</key> @@ -187,11 +187,11 @@ </param> <param> <key>value</key> - <value>4</value> + <value>firdes.root_raised_cosine(sps, sps, 1, eb, 101)</value> </param> <param> <key>_coordinate</key> - <value>(278, 72)</value> + <value>(429, 8)</value> </param> <param> <key>_rotation</key> @@ -202,7 +202,7 @@ <key>variable</key> <param> <key>id</key> - <value>preamble</value> + <value>gap</value> </param> <param> <key>_enabled</key> @@ -210,11 +210,11 @@ </param> <param> <key>value</key> - <value>[1,-1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,1,1,1,-1,-1,-1,1,-1,1,1,1,1,-1,-1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1]</value> + <value>20000</value> </param> <param> <key>_coordinate</key> - <value>(279, 8)</value> + <value>(202, 72)</value> </param> <param> <key>_rotation</key> @@ -225,7 +225,7 @@ <key>variable</key> <param> <key>id</key> - <value>matched_filter</value> + <value>payload_size</value> </param> <param> <key>_enabled</key> @@ -233,11 +233,11 @@ </param> <param> <key>value</key> - <value>firdes.root_raised_cosine(nfilts, nfilts, 1, eb, int(11*sps*nfilts))</value> + <value>992</value> </param> <param> <key>_coordinate</key> - <value>(429, 72)</value> + <value>(101, 73)</value> </param> <param> <key>_rotation</key> @@ -248,7 +248,7 @@ <key>variable</key> <param> <key>id</key> - <value>eb</value> + <value>nfilts</value> </param> <param> <key>_enabled</key> @@ -256,11 +256,11 @@ </param> <param> <key>value</key> - <value>0.35</value> + <value>32</value> </param> <param> <key>_coordinate</key> - <value>(346, 72)</value> + <value>(1074, 9)</value> </param> <param> <key>_rotation</key> @@ -271,7 +271,7 @@ <key>variable</key> <param> <key>id</key> - <value>samp_rate</value> + <value>rrc_taps</value> </param> <param> <key>_enabled</key> @@ -279,11 +279,11 @@ </param> <param> <key>value</key> - <value>100000</value> + <value>firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), eb, 5*sps*nfilts)</value> </param> <param> <key>_coordinate</key> - <value>(11, 72)</value> + <value>(1075, 73)</value> </param> <param> <key>_rotation</key> @@ -317,6 +317,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(1091, 303)</value> </param> @@ -348,6 +352,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(1235, 194)</value> </param> @@ -379,6 +387,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(1235, 149)</value> </param> @@ -418,6 +430,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(972, 174)</value> </param> @@ -457,6 +473,10 @@ <value>0</value> </param> <param> + <key>block_tags</key> + <value>False</value> + </param> + <param> <key>affinity</key> <value></value> </param> @@ -465,6 +485,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(772, 158)</value> </param> @@ -496,6 +520,10 @@ <value>1</value> </param> <param> + <key>ignoretag</key> + <value>True</value> + </param> + <param> <key>affinity</key> <value></value> </param> @@ -504,6 +532,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(586, 190)</value> </param> @@ -551,6 +583,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(15, 165)</value> </param> @@ -602,6 +638,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(312, 166)</value> </param> @@ -645,6 +685,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(568, 288)</value> </param> @@ -672,103 +716,28 @@ <value>1</value> </param> <param> - <key>affinity</key> - <value></value> - </param> - <param> - <key>minoutbuf</key> - <value>0</value> - </param> - <param> - <key>_coordinate</key> - <value>(402, 322)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> - <key>qtgui_time_sink_x</key> - <param> - <key>id</key> - <value>qtgui_time_sink_x_1</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>type</key> - <value>float</value> - </param> - <param> - <key>name</key> - <value>QT GUI Plot</value> - </param> - <param> - <key>size</key> - <value>80000</value> - </param> - <param> - <key>srate</key> - <value>samp_rate</value> - </param> - <param> - <key>ymin</key> - <value>-200</value> - </param> - <param> - <key>ymax</key> - <value>400</value> - </param> - <param> - <key>nconnections</key> - <value>3</value> - </param> - <param> - <key>update_time</key> - <value>0.10</value> - </param> - <param> - <key>tr_mode</key> - <value>qtgui.TRIG_MODE_NORM</value> + <key>num_outputs</key> + <value>1</value> </param> <param> - <key>tr_slope</key> - <value>qtgui.TRIG_SLOPE_POS</value> + <key>bus_conns</key> + <value>[[0,],]</value> </param> <param> - <key>tr_level</key> - <value>200</value> + <key>affinity</key> + <value></value> </param> <param> - <key>tr_delay</key> + <key>minoutbuf</key> <value>0</value> </param> <param> - <key>tr_chan</key> + <key>maxoutbuf</key> <value>0</value> </param> <param> - <key>tr_tag</key> - <value>""</value> - </param> - <param> - <key>entags</key> - <value>True</value> - </param> - <param> - <key>gui_hint</key> - <value>1,0,1,2</value> - </param> - <param> - <key>affinity</key> - <value></value> - </param> - <param> <key>_coordinate</key> - <value>(1433, 160)</value> + <value>(402, 322)</value> </param> <param> <key>_rotation</key> @@ -799,156 +768,6 @@ </param> </block> <block> - <key>qtgui_const_sink_x</key> - <param> - <key>id</key> - <value>qtgui_const_sink_x_0_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>type</key> - <value>complex</value> - </param> - <param> - <key>name</key> - <value>QT GUI Plot</value> - </param> - <param> - <key>size</key> - <value>20000</value> - </param> - <param> - <key>ymin</key> - <value>-2</value> - </param> - <param> - <key>ymax</key> - <value>2</value> - </param> - <param> - <key>xmin</key> - <value>-2</value> - </param> - <param> - <key>xmax</key> - <value>2</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>0,1,1,1</value> - </param> - <param> - <key>affinity</key> - <value></value> - </param> - <param> - <key>_coordinate</key> - <value>(1399, 291)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> - <key>qtgui_time_sink_x</key> - <param> - <key>id</key> - <value>qtgui_time_sink_x_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>type</key> - <value>complex</value> - </param> - <param> - <key>name</key> - <value>QT GUI Plot</value> - </param> - <param> - <key>size</key> - <value>50000</value> - </param> - <param> - <key>srate</key> - <value>samp_rate</value> - </param> - <param> - <key>ymin</key> - <value>-2</value> - </param> - <param> - <key>ymax</key> - <value>2</value> - </param> - <param> - <key>nconnections</key> - <value>1</value> - </param> - <param> - <key>update_time</key> - <value>0.10</value> - </param> - <param> - <key>tr_mode</key> - <value>qtgui.TRIG_MODE_TAG</value> - </param> - <param> - <key>tr_slope</key> - <value>qtgui.TRIG_SLOPE_POS</value> - </param> - <param> - <key>tr_level</key> - <value>1</value> - </param> - <param> - <key>tr_delay</key> - <value>0.1</value> - </param> - <param> - <key>tr_chan</key> - <value>0</value> - </param> - <param> - <key>tr_tag</key> - <value>time_est</value> - </param> - <param> - <key>entags</key> - <value>True</value> - </param> - <param> - <key>gui_hint</key> - <value>0,0,1,1</value> - </param> - <param> - <key>affinity</key> - <value>0</value> - </param> - <param> - <key>_coordinate</key> - <value>(1397, 358)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>variable_qtgui_range</key> <param> <key>id</key> @@ -1219,6 +1038,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(790, 289)</value> </param> @@ -1266,6 +1089,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(30, 324)</value> </param> @@ -1297,6 +1124,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(55, 274)</value> </param> @@ -1340,6 +1171,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(247, 318)</value> </param> @@ -1426,6 +1261,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(1125, 617)</value> </param> @@ -1516,6 +1355,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(752, 517)</value> </param> @@ -1547,6 +1390,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(576, 517)</value> </param> @@ -1590,6 +1437,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(390, 504)</value> </param> @@ -1617,6 +1468,14 @@ <value>1</value> </param> <param> + <key>num_outputs</key> + <value>1</value> + </param> + <param> + <key>bus_conns</key> + <value>[[0,],]</value> + </param> + <param> <key>affinity</key> <value></value> </param> @@ -1625,6 +1484,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(210, 538)</value> </param> @@ -1668,6 +1531,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(923, 518)</value> </param> @@ -1703,6 +1570,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(1112, 482)</value> </param> @@ -1738,6 +1609,10 @@ <value>samp_rate</value> </param> <param> + <key>autoscale</key> + <value>False</value> + </param> + <param> <key>ymin</key> <value>-2</value> </param> @@ -1754,6 +1629,14 @@ <value>0.10</value> </param> <param> + <key>entags</key> + <value>True</value> + </param> + <param> + <key>gui_hint</key> + <value>2,0,1,2</value> + </param> + <param> <key>tr_mode</key> <value>qtgui.TRIG_MODE_TAG</value> </param> @@ -1778,12 +1661,244 @@ <value>time_est</value> </param> <param> - <key>entags</key> - <value>True</value> + <key>label1</key> + <value></value> </param> <param> - <key>gui_hint</key> - <value>2,0,1,2</value> + <key>width1</key> + <value>1</value> + </param> + <param> + <key>color1</key> + <value>"blue"</value> + </param> + <param> + <key>style1</key> + <value>1</value> + </param> + <param> + <key>marker1</key> + <value>-1</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>style2</key> + <value>1</value> + </param> + <param> + <key>marker2</key> + <value>-1</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>style3</key> + <value>1</value> + </param> + <param> + <key>marker3</key> + <value>-1</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>style4</key> + <value>1</value> + </param> + <param> + <key>marker4</key> + <value>-1</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>style5</key> + <value>1</value> + </param> + <param> + <key>marker5</key> + <value>-1</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>style6</key> + <value>1</value> + </param> + <param> + <key>marker6</key> + <value>-1</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>style7</key> + <value>1</value> + </param> + <param> + <key>marker7</key> + <value>-1</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>style8</key> + <value>1</value> + </param> + <param> + <key>marker8</key> + <value>-1</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>style9</key> + <value>1</value> + </param> + <param> + <key>marker9</key> + <value>-1</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>"blue"</value> + </param> + <param> + <key>style10</key> + <value>1</value> + </param> + <param> + <key>marker10</key> + <value>-1</value> + </param> + <param> + <key>alpha10</key> + <value>1.0</value> </param> <param> <key>affinity</key> @@ -1821,6 +1936,10 @@ <value>0</value> </param> <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> <value>(1111, 433)</value> </param> @@ -1829,6 +1948,975 @@ <value>180</value> </param> </block> + <block> + <key>qtgui_time_sink_x</key> + <param> + <key>id</key> + <value>qtgui_time_sink_x_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>size</key> + <value>80000</value> + </param> + <param> + <key>srate</key> + <value>samp_rate</value> + </param> + <param> + <key>autoscale</key> + <value>False</value> + </param> + <param> + <key>ymin</key> + <value>-200</value> + </param> + <param> + <key>ymax</key> + <value>400</value> + </param> + <param> + <key>nconnections</key> + <value>3</value> + </param> + <param> + <key>update_time</key> + <value>0.10</value> + </param> + <param> + <key>entags</key> + <value>True</value> + </param> + <param> + <key>gui_hint</key> + <value>1,0,1,2</value> + </param> + <param> + <key>tr_mode</key> + <value>qtgui.TRIG_MODE_NORM</value> + </param> + <param> + <key>tr_slope</key> + <value>qtgui.TRIG_SLOPE_POS</value> + </param> + <param> + <key>tr_level</key> + <value>200</value> + </param> + <param> + <key>tr_delay</key> + <value>0</value> + </param> + <param> + <key>tr_chan</key> + <value>0</value> + </param> + <param> + <key>tr_tag</key> + <value>""</value> + </param> + <param> + <key>label1</key> + <value>|corr|^2</value> + </param> + <param> + <key>width1</key> + <value>1</value> + </param> + <param> + <key>color1</key> + <value>"blue"</value> + </param> + <param> + <key>style1</key> + <value>1</value> + </param> + <param> + <key>marker1</key> + <value>-1</value> + </param> + <param> + <key>alpha1</key> + <value>1.0</value> + </param> + <param> + <key>label2</key> + <value>Re{corr}</value> + </param> + <param> + <key>width2</key> + <value>1</value> + </param> + <param> + <key>color2</key> + <value>"red"</value> + </param> + <param> + <key>style2</key> + <value>1</value> + </param> + <param> + <key>marker2</key> + <value>-1</value> + </param> + <param> + <key>alpha2</key> + <value>1.0</value> + </param> + <param> + <key>label3</key> + <value>Im{corr}</value> + </param> + <param> + <key>width3</key> + <value>1</value> + </param> + <param> + <key>color3</key> + <value>"green"</value> + </param> + <param> + <key>style3</key> + <value>1</value> + </param> + <param> + <key>marker3</key> + <value>-1</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>style4</key> + <value>1</value> + </param> + <param> + <key>marker4</key> + <value>-1</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>style5</key> + <value>1</value> + </param> + <param> + <key>marker5</key> + <value>-1</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>style6</key> + <value>1</value> + </param> + <param> + <key>marker6</key> + <value>-1</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>style7</key> + <value>1</value> + </param> + <param> + <key>marker7</key> + <value>-1</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>style8</key> + <value>1</value> + </param> + <param> + <key>marker8</key> + <value>-1</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>style9</key> + <value>1</value> + </param> + <param> + <key>marker9</key> + <value>-1</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>"blue"</value> + </param> + <param> + <key>style10</key> + <value>1</value> + </param> + <param> + <key>marker10</key> + <value>-1</value> + </param> + <param> + <key>alpha10</key> + <value>1.0</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(1433, 160)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>qtgui_time_sink_x</key> + <param> + <key>id</key> + <value>qtgui_time_sink_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>size</key> + <value>50000</value> + </param> + <param> + <key>srate</key> + <value>samp_rate</value> + </param> + <param> + <key>autoscale</key> + <value>False</value> + </param> + <param> + <key>ymin</key> + <value>-2</value> + </param> + <param> + <key>ymax</key> + <value>2</value> + </param> + <param> + <key>nconnections</key> + <value>1</value> + </param> + <param> + <key>update_time</key> + <value>0.10</value> + </param> + <param> + <key>entags</key> + <value>True</value> + </param> + <param> + <key>gui_hint</key> + <value>0,0,1,1</value> + </param> + <param> + <key>tr_mode</key> + <value>qtgui.TRIG_MODE_TAG</value> + </param> + <param> + <key>tr_slope</key> + <value>qtgui.TRIG_SLOPE_POS</value> + </param> + <param> + <key>tr_level</key> + <value>1</value> + </param> + <param> + <key>tr_delay</key> + <value>0.1</value> + </param> + <param> + <key>tr_chan</key> + <value>0</value> + </param> + <param> + <key>tr_tag</key> + <value>time_est</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>style1</key> + <value>1</value> + </param> + <param> + <key>marker1</key> + <value>-1</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>style2</key> + <value>1</value> + </param> + <param> + <key>marker2</key> + <value>-1</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>style3</key> + <value>1</value> + </param> + <param> + <key>marker3</key> + <value>-1</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>style4</key> + <value>1</value> + </param> + <param> + <key>marker4</key> + <value>-1</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>style5</key> + <value>1</value> + </param> + <param> + <key>marker5</key> + <value>-1</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>style6</key> + <value>1</value> + </param> + <param> + <key>marker6</key> + <value>-1</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>style7</key> + <value>1</value> + </param> + <param> + <key>marker7</key> + <value>-1</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>style8</key> + <value>1</value> + </param> + <param> + <key>marker8</key> + <value>-1</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>style9</key> + <value>1</value> + </param> + <param> + <key>marker9</key> + <value>-1</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>"blue"</value> + </param> + <param> + <key>style10</key> + <value>1</value> + </param> + <param> + <key>marker10</key> + <value>-1</value> + </param> + <param> + <key>alpha10</key> + <value>1.0</value> + </param> + <param> + <key>affinity</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(1398, 370)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>qtgui_const_sink_x</key> + <param> + <key>id</key> + <value>qtgui_const_sink_x_0_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>size</key> + <value>20000</value> + </param> + <param> + <key>autoscale</key> + <value>False</value> + </param> + <param> + <key>ymin</key> + <value>-2</value> + </param> + <param> + <key>ymax</key> + <value>2</value> + </param> + <param> + <key>xmin</key> + <value>-2</value> + </param> + <param> + <key>xmax</key> + <value>2</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>0,1,1,1</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>style1</key> + <value>0</value> + </param> + <param> + <key>marker1</key> + <value>0</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>style2</key> + <value>0</value> + </param> + <param> + <key>marker2</key> + <value>0</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>"red"</value> + </param> + <param> + <key>style3</key> + <value>0</value> + </param> + <param> + <key>marker3</key> + <value>0</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>"red"</value> + </param> + <param> + <key>style4</key> + <value>0</value> + </param> + <param> + <key>marker4</key> + <value>0</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>"red"</value> + </param> + <param> + <key>style5</key> + <value>0</value> + </param> + <param> + <key>marker5</key> + <value>0</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>"red"</value> + </param> + <param> + <key>style6</key> + <value>0</value> + </param> + <param> + <key>marker6</key> + <value>0</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>"red"</value> + </param> + <param> + <key>style7</key> + <value>0</value> + </param> + <param> + <key>marker7</key> + <value>0</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>"red"</value> + </param> + <param> + <key>style8</key> + <value>0</value> + </param> + <param> + <key>marker8</key> + <value>0</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>"red"</value> + </param> + <param> + <key>style9</key> + <value>0</value> + </param> + <param> + <key>marker9</key> + <value>0</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>"red"</value> + </param> + <param> + <key>style10</key> + <value>0</value> + </param> + <param> + <key>marker10</key> + <value>0</value> + </param> + <param> + <key>alpha10</key> + <value>1.0</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(1399, 291)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> <connection> <source_block_id>digital_costas_loop_cc_0</source_block_id> <sink_block_id>qtgui_const_sink_x_0_0</sink_block_id> diff --git a/gr-digital/grc/digital_block_tree.xml b/gr-digital/grc/digital_block_tree.xml index 007a7e6106..9eca98ddb1 100644 --- a/gr-digital/grc/digital_block_tree.xml +++ b/gr-digital/grc/digital_block_tree.xml @@ -1,19 +1,19 @@ <?xml version="1.0"?> <!-- Copyright 2011-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, @@ -66,7 +66,7 @@ </cat> <cat> <name>Packet Operators</name> - <block>digital_correlate_access_code_bb</block> + <block>digital_correlate_access_code_tag_bb</block> <block>digital_crc32_bb</block> <block>digital_framer_sink_1</block> <block>digital_header_payload_demux</block> @@ -75,6 +75,8 @@ <block>digital_packet_headerparser_b</block> <block>digital_packet_headerparser_b_default</block> <block>digital_packet_sink</block> + <block>digital_hdlc_framer_pb</block> + <block>digital_hdlc_deframer_bp</block> <block>digital_simple_framer</block> <block>digital_simple_correlator</block> </cat> @@ -126,7 +128,6 @@ <cat> <name>Deprecated</name> <block>digital_correlate_access_code_bb</block> - <block>digital_correlate_access_code_tag_bb</block> <block>digital_simple_framer</block> <block>digital_simple_correlator</block> </cat> diff --git a/gr-digital/grc/digital_constellation_modulator.xml b/gr-digital/grc/digital_constellation_modulator.xml index 7b7ce24e47..9905197f93 100644 --- a/gr-digital/grc/digital_constellation_modulator.xml +++ b/gr-digital/grc/digital_constellation_modulator.xml @@ -86,7 +86,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_dxpsk_demod.xml b/gr-digital/grc/digital_dxpsk_demod.xml index 1c6314d305..5b26d5b8ec 100644 --- a/gr-digital/grc/digital_dxpsk_demod.xml +++ b/gr-digital/grc/digital_dxpsk_demod.xml @@ -114,7 +114,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_dxpsk_mod.xml b/gr-digital/grc/digital_dxpsk_mod.xml index 08a95f1a9c..02da10028e 100644 --- a/gr-digital/grc/digital_dxpsk_mod.xml +++ b/gr-digital/grc/digital_dxpsk_mod.xml @@ -91,7 +91,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_gfsk_demod.xml b/gr-digital/grc/digital_gfsk_demod.xml index ce3024d892..cbea39e63e 100644 --- a/gr-digital/grc/digital_gfsk_demod.xml +++ b/gr-digital/grc/digital_gfsk_demod.xml @@ -70,7 +70,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_gfsk_mod.xml b/gr-digital/grc/digital_gfsk_mod.xml index 2d6cd1ea54..08e2c84790 100644 --- a/gr-digital/grc/digital_gfsk_mod.xml +++ b/gr-digital/grc/digital_gfsk_mod.xml @@ -49,7 +49,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_gmsk_demod.xml b/gr-digital/grc/digital_gmsk_demod.xml index e037b8ea03..4d57f1a17a 100644 --- a/gr-digital/grc/digital_gmsk_demod.xml +++ b/gr-digital/grc/digital_gmsk_demod.xml @@ -63,7 +63,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_gmsk_mod.xml b/gr-digital/grc/digital_gmsk_mod.xml index ede76808ad..77f52ca2f2 100644 --- a/gr-digital/grc/digital_gmsk_mod.xml +++ b/gr-digital/grc/digital_gmsk_mod.xml @@ -42,7 +42,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_hdlc_deframer_bp.xml b/gr-digital/grc/digital_hdlc_deframer_bp.xml new file mode 100644 index 0000000000..41bd37c7ee --- /dev/null +++ b/gr-digital/grc/digital_hdlc_deframer_bp.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<block> + <name>HDLC Deframer</name> + <key>digital_hdlc_deframer_bp</key> + <import>from gnuradio import digital</import> + <make>digital.hdlc_deframer_bp($frame_tag_name, $min, $max)</make> + <param> + <name>Frame tag name</name> + <key>frame_tag_name</key> + <type>string</type> + </param> + <param> + <name>Min length</name> + <key>min</key> + <value>32</value> + <type>int</type> + </param> + <param> + <name>Max length</name> + <key>max</key> + <value>500</value> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>message</type> + </source> +</block> diff --git a/gr-digital/grc/digital_hdlc_framer_pb.xml b/gr-digital/grc/digital_hdlc_framer_pb.xml new file mode 100644 index 0000000000..8dc122d581 --- /dev/null +++ b/gr-digital/grc/digital_hdlc_framer_pb.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<block> + <name>HDLC Framer</name> + <key>digital_hdlc_framer_pb</key> + <import>from gnuradio import digital</import> + <make>digital.hdlc_framer_pb($frame_tag_name)</make> + <param> + <name>Frame tag name</name> + <key>frame_tag_name</key> + <type>string</type> + </param> + <sink> + <name>in</name> + <type>message</type> + </sink> + <source> + <name>out</name> + <type>byte</type> + </source> +</block> diff --git a/gr-digital/grc/digital_header_payload_demux.xml b/gr-digital/grc/digital_header_payload_demux.xml index 5d19e89e87..1037efde61 100644 --- a/gr-digital/grc/digital_header_payload_demux.xml +++ b/gr-digital/grc/digital_header_payload_demux.xml @@ -81,6 +81,11 @@ <key>short</key> <opt>itemsize:gr.sizeof_short</opt> </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>itemsize:gr.sizeof_char</opt> + </option> </param> <param> <name>Timing tag key</name> diff --git a/gr-digital/grc/digital_psk_demod.xml b/gr-digital/grc/digital_psk_demod.xml index 2e0e86ebc6..36e803ae73 100644 --- a/gr-digital/grc/digital_psk_demod.xml +++ b/gr-digital/grc/digital_psk_demod.xml @@ -120,7 +120,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_psk_mod.xml b/gr-digital/grc/digital_psk_mod.xml index cafcf4e505..e7788842a8 100644 --- a/gr-digital/grc/digital_psk_mod.xml +++ b/gr-digital/grc/digital_psk_mod.xml @@ -100,7 +100,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_qam_demod.xml b/gr-digital/grc/digital_qam_demod.xml index 5aaec1bd0a..21ccba856b 100644 --- a/gr-digital/grc/digital_qam_demod.xml +++ b/gr-digital/grc/digital_qam_demod.xml @@ -121,7 +121,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/grc/digital_qam_mod.xml b/gr-digital/grc/digital_qam_mod.xml index 4d73d9a685..435ca7058e 100644 --- a/gr-digital/grc/digital_qam_mod.xml +++ b/gr-digital/grc/digital_qam_mod.xml @@ -100,7 +100,7 @@ </option> </param> <param> - <name>Logging</name> + <name>Log</name> <key>log</key> <value>False</value> <type>bool</type> diff --git a/gr-digital/include/gnuradio/digital/CMakeLists.txt b/gr-digital/include/gnuradio/digital/CMakeLists.txt index 4d50f42ae0..63b65b9c77 100644 --- a/gr-digital/include/gnuradio/digital/CMakeLists.txt +++ b/gr-digital/include/gnuradio/digital/CMakeLists.txt @@ -101,6 +101,8 @@ install(FILES glfsr.h glfsr_source_b.h glfsr_source_f.h + hdlc_deframer_bp.h + hdlc_framer_pb.h header_payload_demux.h kurtotic_equalizer_cc.h lfsr.h diff --git a/gr-digital/include/gnuradio/digital/costas_loop_cc.h b/gr-digital/include/gnuradio/digital/costas_loop_cc.h index 5320d704c3..d924d969b7 100644 --- a/gr-digital/include/gnuradio/digital/costas_loop_cc.h +++ b/gr-digital/include/gnuradio/digital/costas_loop_cc.h @@ -1,19 +1,19 @@ /* -*- c++ -*- */ /* * Copyright 2006,2011,2012 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, @@ -30,7 +30,7 @@ namespace gr { namespace digital { - /*! + /*! * \brief A Costas loop carrier recovery module. * \ingroup synchronizers_blk * @@ -54,20 +54,20 @@ namespace gr { * signal processing, pp. 20-36, 2002. * * http://rfdesign.com/images/archive/0102Feigin20.pdf - * + * * The Costas loop can have two output streams: * \li stream 1 (required) is the baseband I and Q; * \li stream 2 (optional) is the normalized frequency of the loop */ class DIGITAL_API costas_loop_cc - : virtual public sync_block, + : virtual public sync_block, virtual public blocks::control_loop { public: // gr::digital::costas_loop_cc::sptr typedef boost::shared_ptr<costas_loop_cc> sptr; - /*! + /*! * Make a Costas loop carrier recovery block. * * \param loop_bw internal 2nd order loop bandwidth (~ 2pi/100) @@ -75,7 +75,7 @@ namespace gr { */ static sptr make(float loop_bw, int order); - /*! + /*! * Returns the current value of the loop error. */ virtual float error() const = 0; diff --git a/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h b/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.h new file mode 100644 index 0000000000..191f294344 --- /dev/null +++ b/gr-digital/include/gnuradio/digital/hdlc_deframer_bp.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_DIGITAL_HDLC_DEFRAMER_BP_H +#define INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_H + +#include <gnuradio/digital/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief HDLC deframer which takes in unpacked bits, and outputs PDU + * binary blobs. This is intended for use with the + * correlate_access_code_tag_bb block, which should have an access code + * of "01111110" for use with HDLC frames. Frames which do not pass CRC are + * rejected. + * + * \ingroup digital + * + */ + class DIGITAL_API hdlc_deframer_bp : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr<hdlc_deframer_bp> sptr; + + /*! + * \brief Return a shared_ptr to a new instance of digital::hdlc_deframer. + * + * \param frame_tag_name: The tag name from an upstream + * correlate_access_code_tag_bb block. + * \param length_min: Minimum frame size (default: 32) + * \param length_max: Maximum frame size (default: 500) + */ + static sptr make(const std::string frame_tag_name, int length_min, int length_max); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_H */ + diff --git a/gr-digital/include/gnuradio/digital/hdlc_framer_pb.h b/gr-digital/include/gnuradio/digital/hdlc_framer_pb.h new file mode 100644 index 0000000000..d2931a9fff --- /dev/null +++ b/gr-digital/include/gnuradio/digital/hdlc_framer_pb.h @@ -0,0 +1,65 @@ +/* -*- 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_DIGITAL_HDLC_FRAMER_PB_H +#define INCLUDED_DIGITAL_HDLC_FRAMER_PB_H + +#include <gnuradio/digital/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief HDLC framer which takes in PMT binary blobs and outputs HDLC + * frames as unpacked bits, with CRC and bit stuffing added. The first sample + * of the frame is tagged with the tag frame_tag_name and includes a + * length field for tagged_stream use. + * + * This block outputs one whole frame at a time; if there is not enough + * output buffer space to fit a frame, it is pushed onto a queue. As a result + * flowgraphs which only run for a finite number of samples may not receive + * all frames in the queue, due to the scheduler's granularity. For + * flowgraphs that stream continuously (anything using a USRP) this should + * not be an issue. + * + * \ingroup digital + * + */ + class DIGITAL_API hdlc_framer_pb : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr<hdlc_framer_pb> sptr; + + /*! + * \brief Return a shared_ptr to a new instance of digital::hdlc_framer. + * + * \param frame_tag_name: The tag to add to the first sample of each frame. + */ + static sptr make(const std::string frame_tag_name); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_HDLC_FRAMER_PB_H */ + diff --git a/gr-digital/include/gnuradio/digital/mpsk_receiver_cc.h b/gr-digital/include/gnuradio/digital/mpsk_receiver_cc.h index df67609d9c..618d192771 100644 --- a/gr-digital/include/gnuradio/digital/mpsk_receiver_cc.h +++ b/gr-digital/include/gnuradio/digital/mpsk_receiver_cc.h @@ -77,27 +77,27 @@ namespace gr { /*! * \brief Make a M-PSK receiver block. * - * \param M modulation order of the M-PSK modulation - * \param theta any constant phase rotation from the real axis of the constellation - * \param loop_bw Loop bandwidth to set gains of phase/freq tracking loop - * \param fmin minimum normalized frequency value the loop can achieve - * \param fmax maximum normalized frequency value the loop can achieve - * \param mu initial parameter for the interpolator [0,1] - * \param gain_mu gain parameter of the M&M error signal to adjust mu (~0.05) - * \param omega initial value for the number of symbols between samples (~number of samples/symbol) - * \param gain_omega gain parameter to adjust omega based on the error (~omega^2/4) - * \param omega_rel sets the maximum (omega*(1+omega_rel)) and minimum (omega*(1+omega_rel)) omega (~0.005) + * \param M modulation order of the M-PSK modulation + * \param theta any constant phase rotation from the real axis of the constellation + * \param loop_bw Loop bandwidth to set gains of phase/freq tracking loop + * \param fmin minimum normalized frequency value the loop can achieve + * \param fmax maximum normalized frequency value the loop can achieve + * \param mu initial parameter for the interpolator [0,1] + * \param gain_mu gain parameter of the M&M error signal to adjust mu (~0.05) + * \param omega initial value for the number of symbols between samples (~number of samples/symbol) + * \param gain_omega gain parameter to adjust omega based on the error (~omega^2/4) + * \param omega_rel sets the maximum (omega*(1+omega_rel)) and minimum (omega*(1+omega_rel)) omega (~0.005) * * The constructor also chooses which phase detector and * decision maker to use in the work loop based on the value of * M. */ - static sptr make(unsigned int M, float theta, + static sptr make(unsigned int M, float theta, float loop_bw, float fmin, float fmax, - float mu, float gain_mu, + float mu, float gain_mu, float omega, float gain_omega, float omega_rel); - + //! Returns the modulation order (M) currently set virtual float modulation_order() const = 0; @@ -127,8 +127,8 @@ namespace gr { //! Sets value of mu virtual void set_mu(float mu) = 0; - - //! Sets value of omega and its min and max values + + //! Sets value of omega and its min and max values virtual void set_omega(float omega) = 0; //! Sets value for mu gain factor diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt index 509a9a5bbf..00200d1dc3 100644 --- a/gr-digital/lib/CMakeLists.txt +++ b/gr-digital/lib/CMakeLists.txt @@ -137,6 +137,8 @@ list(APPEND digital_sources glfsr.cc glfsr_source_b_impl.cc glfsr_source_f_impl.cc + hdlc_deframer_bp_impl.cc + hdlc_framer_pb_impl.cc header_payload_demux_impl.cc kurtotic_equalizer_cc_impl.cc lms_dd_equalizer_cc_impl.cc diff --git a/gr-digital/lib/correlate_access_code_tag_bb_impl.cc b/gr-digital/lib/correlate_access_code_tag_bb_impl.cc index 0d64caa7ab..f6574dd517 100644 --- a/gr-digital/lib/correlate_access_code_tag_bb_impl.cc +++ b/gr-digital/lib/correlate_access_code_tag_bb_impl.cc @@ -27,7 +27,8 @@ #include "correlate_access_code_tag_bb_impl.h" #include <gnuradio/io_signature.h> #include <stdexcept> -#include <gnuradio/blocks/count_bits.h> +//#include <gnuradio/blocks/count_bits.h> +#include <volk/volk.h> #include <cstdio> #include <iostream> @@ -75,16 +76,18 @@ namespace gr { { d_len = access_code.length(); // # of bytes in string if(d_len > 64) - return false; + return false; - // set len top bits to 1. - d_mask = ((~0ULL) >> (64 - d_len)) << (64 - d_len); + // set d_len bottom bits to 1. + d_mask = (1ULL << d_len) - 1; d_access_code = 0; - for(unsigned i=0; i < 64; i++){ - d_access_code <<= 1; - if(i < d_len) - d_access_code |= access_code[i] & 1; // look at LSB only + for(unsigned i=0; i < d_len; i++){ + d_access_code = (d_access_code << 1) | (access_code[i] & 1); + } + if(VERBOSE) { + std::cerr << "Access code: " << std::hex << d_access_code << std::dec << std::endl; + std::cerr << "Mask: " << std::hex << d_mask << std::dec << std::endl; } return true; @@ -104,25 +107,21 @@ namespace gr { out[i] = in[i]; // compute hamming distance between desired access code and current data - unsigned long long wrong_bits = 0; - unsigned int nwrong = d_threshold+1; - int new_flag = 0; + uint64_t wrong_bits = 0; + uint64_t nwrong = d_threshold+1; wrong_bits = (d_data_reg ^ d_access_code) & d_mask; - nwrong = gr::blocks::count_bits64(wrong_bits); - - // test for access code with up to threshold errors - new_flag = (nwrong <= d_threshold); + volk_64u_popcnt(&nwrong, wrong_bits); // shift in new data and new flag d_data_reg = (d_data_reg << 1) | (in[i] & 0x1); - if(new_flag) { + if(nwrong <= d_threshold) { if(VERBOSE) std::cerr << "writing tag at sample " << abs_out_sample_cnt + i << std::endl; add_item_tag(0, //stream ID - abs_out_sample_cnt + i - 64 + d_len, //sample + abs_out_sample_cnt + i, //sample d_key, //frame info - pmt::pmt_t(), //data (unused) + pmt::from_long(nwrong), //data (number wrong) d_me //block src id ); } diff --git a/gr-digital/lib/costas_loop_cc_impl.cc b/gr-digital/lib/costas_loop_cc_impl.cc index 36a125b437..36f95ac022 100644 --- a/gr-digital/lib/costas_loop_cc_impl.cc +++ b/gr-digital/lib/costas_loop_cc_impl.cc @@ -1,19 +1,19 @@ /* -*- c++ -*- */ /* * Copyright 2006,2010-2012 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, @@ -62,7 +62,7 @@ namespace gr { d_phase_detector = &costas_loop_cc_impl::phase_detector_8; break; - default: + default: throw std::invalid_argument("order must be 2, 4, or 8"); break; } @@ -145,19 +145,19 @@ namespace gr { tags.erase(tags.begin()); } } - + nco_out = gr_expj(-d_phase); optr[i] = iptr[i] * nco_out; d_error = (*this.*d_phase_detector)(optr[i]); d_error = gr::branchless_clip(d_error, 1.0); - + advance_loop(d_error); phase_wrap(); frequency_limit(); foptr[i] = d_freq; - } + } } else { for(int i = 0; i < noutput_items; i++) { @@ -219,7 +219,7 @@ namespace gr { pmt::mp(0.0f), pmt::mp(2.0f), pmt::mp(0.0f), "", "Loop bandwidth", RPC_PRIVLVL_MIN, DISPTIME | DISPOPTSTRIP))); - + // Setters add_rpc_variable( rpcbasic_sptr(new rpcbasic_register_set<control_loop, float>( diff --git a/gr-digital/lib/costas_loop_cc_impl.h b/gr-digital/lib/costas_loop_cc_impl.h index 0559f907aa..665724236b 100644 --- a/gr-digital/lib/costas_loop_cc_impl.h +++ b/gr-digital/lib/costas_loop_cc_impl.h @@ -1,19 +1,19 @@ /* -*- c++ -*- */ /* * Copyright 2006,2011,2012 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, @@ -62,7 +62,7 @@ namespace gr { float error() const; void setup_rpc(); - + int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.cc b/gr-digital/lib/hdlc_deframer_bp_impl.cc new file mode 100644 index 0000000000..69f0f8c00d --- /dev/null +++ b/gr-digital/lib/hdlc_deframer_bp_impl.cc @@ -0,0 +1,160 @@ +/* -*- 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 <gnuradio/tags.h> +#include "hdlc_deframer_bp_impl.h" + +namespace gr { + namespace digital { + + hdlc_deframer_bp::sptr + hdlc_deframer_bp::make(const std::string frame_tag_name, + int length_min=32, + int length_max=500) + { + return gnuradio::get_initial_sptr + (new hdlc_deframer_bp_impl(frame_tag_name, length_min, length_max)); + } + + /* + * The private constructor + */ + hdlc_deframer_bp_impl::hdlc_deframer_bp_impl(const std::string frame_tag_name, + int length_min, + int length_max) + : gr::sync_block("hdlc_deframer_bp", + gr::io_signature::make(1, 1, sizeof(unsigned char)), + gr::io_signature::make(0, 0, 0)), + d_frame_tag_name(frame_tag_name), + d_length_min(length_min), + d_length_max(length_max) + { + set_output_multiple(length_max*2); + message_port_register_out(pmt::mp("out")); + } + + /* + * Our virtual destructor. + */ + hdlc_deframer_bp_impl::~hdlc_deframer_bp_impl() + { + } + + //undo HDLC bit stuffing operation. + static void unstuff(std::vector<unsigned char> &pkt) { + int consec = 0; + for(size_t i=0; i<pkt.size(); i++) { + if(pkt[i]) { + consec++; + } else { + if(consec == 5) { + pkt.erase(pkt.begin()+i); + i--; + } + consec = 0; + } + } + } + + //pack unpacked (1 bit per byte) data into bytes, in reverse bit order + //we reverse the bit order because HDLC uses LSbit format. + std::vector<unsigned char> + hdlc_deframer_bp_impl::pack(std::vector<unsigned char> &data) + { + std::vector<unsigned char> output(std::ceil(data.size()/8.0f), 0); + for(size_t i=0; i<data.size(); i++) { + output[i/8] |= (data[i]<<(i%8)); + } + return output; + } + + unsigned int + hdlc_deframer_bp_impl::crc_ccitt(std::vector<unsigned char> &data) { + unsigned int POLY=0x8408; //reflected 0x1021 + unsigned short crc=0xFFFF; + for(size_t i=0; i<data.size(); i++) { + crc ^= data[i]; + for(size_t j=0; j<8; j++) { + if(crc&0x01) crc = (crc >> 1) ^ POLY; + else crc = (crc >> 1); + } + } + return crc ^ 0xFFFF; + } + + int + hdlc_deframer_bp_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const unsigned char *in = (const unsigned char *) input_items[0]; + + //look for frame delimiter tags + std::vector<gr::tag_t> frame_tags; + uint64_t abs_sample_cnt = nitems_read(0); + get_tags_in_range(frame_tags, 0, abs_sample_cnt, abs_sample_cnt + noutput_items, pmt::string_to_symbol(d_frame_tag_name)); + + int end_pos = 0; + while(frame_tags.size() > 0) { + int start_pos = frame_tags[0].offset - abs_sample_cnt; + if(frame_tags.size() == 1) return start_pos; //start here next time + end_pos = frame_tags[1].offset - abs_sample_cnt; + int pkt_len = frame_tags[1].offset - frame_tags[0].offset - 8; //omit EOF delim + if(pkt_len > d_length_max) return end_pos; //arbitrary, too long for a real pkt + if(pkt_len <= d_length_min) return end_pos; + + //get bit array + std::vector<unsigned char> pkt_bits(pkt_len); + memcpy(&pkt_bits[0], &in[start_pos], pkt_bits.size()); + + unstuff(pkt_bits); + + //pack into bytes (and correct bit order) + std::vector<unsigned char> pkt_bytes = pack(pkt_bits); + + //strip off the CRC + unsigned int crc = (int(pkt_bytes[pkt_bytes.size()-1]) << 8) + + pkt_bytes[pkt_bytes.size()-2]; + pkt_bytes.erase(pkt_bytes.end()-2, pkt_bytes.end()); + unsigned int calc_crc = crc_ccitt(pkt_bytes); + + if(crc == calc_crc) { + //publish + //TODO manage padding + pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL, + pmt::make_blob(&pkt_bytes[0], pkt_bytes.size()))); + message_port_pub(pmt::mp("out"), pdu); + } + frame_tags.erase(frame_tags.begin()); + } + // Tell runtime system how many output items we produced. + return end_pos; + } + + } /* namespace digital */ +} /* namespace gr */ + diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.h b/gr-digital/lib/hdlc_deframer_bp_impl.h new file mode 100644 index 0000000000..de8f6b3db7 --- /dev/null +++ b/gr-digital/lib/hdlc_deframer_bp_impl.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_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H +#define INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H + +#include <gnuradio/digital/hdlc_deframer_bp.h> + +namespace gr { + namespace digital { + + class hdlc_deframer_bp_impl : public hdlc_deframer_bp + { + private: + std::string d_frame_tag_name; + int d_length_min; + int d_length_max; + unsigned int crc_ccitt(std::vector<unsigned char> &data); + std::vector<unsigned char> pack(std::vector<unsigned char> &pkt); + + public: + hdlc_deframer_bp_impl(const std::string frame_tag_name, int length_min, int length_max); + ~hdlc_deframer_bp_impl(); + + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_HDLC_DEFRAMER_BP_IMPL_H */ + diff --git a/gr-digital/lib/hdlc_framer_pb_impl.cc b/gr-digital/lib/hdlc_framer_pb_impl.cc new file mode 100644 index 0000000000..27dec5267e --- /dev/null +++ b/gr-digital/lib/hdlc_framer_pb_impl.cc @@ -0,0 +1,184 @@ +/* -*- 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 <gnuradio/tags.h> +#include "hdlc_framer_pb_impl.h" +#include <iostream> + +namespace gr { + namespace digital { + + hdlc_framer_pb::sptr + hdlc_framer_pb::make(const std::string frame_tag_name) + { + return gnuradio::get_initial_sptr + (new hdlc_framer_pb_impl(frame_tag_name)); + } + + /* + * The private constructor + */ + hdlc_framer_pb_impl::hdlc_framer_pb_impl(const std::string frame_tag_name) + : gr::sync_block("hdlc_framer_pb", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, sizeof(unsigned char))) + { + message_port_register_in(pmt::mp("in")); + d_frame_tag = pmt::string_to_symbol(frame_tag_name); + std::stringstream str; + str << name() << unique_id(); + d_me = pmt::string_to_symbol(str.str()); + } + + /* + * Our virtual destructor. + */ + hdlc_framer_pb_impl::~hdlc_framer_pb_impl() + { + } + + //bit stuff + void + hdlc_framer_pb_impl::stuff(std::vector<unsigned char> &pkt) { + int consec = 0; + for(size_t i=0; i < pkt.size(); i++) { + if(consec == 5) { + pkt.insert(pkt.begin()+i, 0); + consec = 0; + } + if(pkt[i]==1) consec++; + else consec=0; + } + } + + //unpack packed (8 bits per byte) into bits, in LSbit order. + //TODO: handle non-multiple-of-8 bit lengths (pad low) + std::vector<unsigned char> + hdlc_framer_pb_impl::unpack(std::vector<unsigned char> &data) { + std::vector<unsigned char> output(data.size()*8, 0); + for(size_t i=0; i<data.size(); i++) { + for(size_t j=0; j<8; j++) { + output[i*8+j] = (data[i] >> j) & 1; + } + } + return output; + } + + unsigned int + hdlc_framer_pb_impl::crc_ccitt(std::vector<unsigned char> &data) { + unsigned int POLY=0x8408; //reflected 0x1021 + unsigned short crc=0xFFFF; + for(size_t i=0; i<data.size(); i++) { + crc ^= data[i]; + for(size_t j=0; j<8; j++) { + if(crc&0x01) crc = (crc >> 1) ^ POLY; + else crc = (crc >> 1); + } + } + return crc ^ 0xFFFF; + } + + int + hdlc_framer_pb_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + unsigned char *out = (unsigned char *) output_items[0]; + + //send leftovers one chunk at a time. + //it'd be more efficient to send as much as possible, i.e. + //partial packets., but if we're to preserve tag boundaries + //this is much, much simpler. + int oidx = 0; + while(d_leftovers.size() > 0) { + if(noutput_items < (oidx+d_leftovers[0].size())) return oidx; + memcpy(out+oidx, &d_leftovers[0][0], d_leftovers[0].size()); + //start tag + add_item_tag(0, + nitems_written(0)+oidx, + d_frame_tag, + pmt::from_long(d_leftovers[0].size()), + d_me); + oidx += d_leftovers[0].size(); + d_leftovers.erase(d_leftovers.begin()); + } + + //get PDU + pmt::pmt_t msg(delete_head_nowait(pmt::mp("in"))); + if(msg.get() == NULL) return oidx; + + pmt::pmt_t len(pmt::car(msg)); //TODO for non-mult-8 nbits + pmt::pmt_t blob(pmt::cdr(msg)); + if(!pmt::is_blob(blob)) + throw std::runtime_error("HDLC framer: PMT must be blob"); + std::vector<unsigned char> pkt(pmt::blob_length(blob)); + memcpy(&pkt[0], (const unsigned char *) pmt::blob_data(blob), pkt.size()); + + //calc CRC + unsigned int crc = crc_ccitt(pkt); + + //append CRC + pkt.insert(pkt.end(), crc & 0xFF); + pkt.insert(pkt.end(), (crc >> 8) & 0xFF); + + //unpack to LSb bits + std::vector<unsigned char> pkt_bits = unpack(pkt); + + //bitstuff + stuff(pkt_bits); + + //add framing + const unsigned char framing[] = {0,1,1,1,1,1,1,0}; + std::vector<unsigned char> framing_vec(framing, framing+sizeof(framing)); + pkt_bits.insert(pkt_bits.begin(), framing_vec.begin(), framing_vec.end()); + pkt_bits.insert(pkt_bits.end(), framing_vec.begin(), framing_vec.end()); + + //make sure we have the space. unfortunately, we didn't know + //until now, since the stuffing must be calculated. we'll just + //save it for next time. + if(noutput_items < (oidx+pkt_bits.size())) { + d_leftovers.insert(d_leftovers.end(), pkt_bits); + return oidx; + } + + //produce + memcpy(out+oidx, &pkt_bits[0], pkt_bits.size()); + //start tag + add_item_tag(0, + nitems_written(0)+oidx, + d_frame_tag, + pmt::from_long(pkt_bits.size()), + d_me); + oidx += pkt_bits.size(); + + //return # output bits + return oidx; + } + + } /* namespace digital */ +} /* namespace gr */ + diff --git a/gr-digital/lib/hdlc_framer_pb_impl.h b/gr-digital/lib/hdlc_framer_pb_impl.h new file mode 100644 index 0000000000..90d51a96e6 --- /dev/null +++ b/gr-digital/lib/hdlc_framer_pb_impl.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_DIGITAL_HDLC_FRAMER_PB_IMPL_H +#define INCLUDED_DIGITAL_HDLC_FRAMER_PB_IMPL_H + +#include <gnuradio/digital/hdlc_framer_pb.h> +#include <pmt/pmt.h> + +namespace gr { + namespace digital { + + class hdlc_framer_pb_impl : public hdlc_framer_pb + { + private: + std::vector<std::vector<unsigned char> > d_leftovers; + pmt::pmt_t d_frame_tag, d_me; + unsigned int crc_ccitt(std::vector<unsigned char> &data); + std::vector<unsigned char> unpack(std::vector<unsigned char> &pkt); + void stuff(std::vector<unsigned char> &pkt); + + public: + hdlc_framer_pb_impl(const std::string frame_tag_name); + ~hdlc_framer_pb_impl(); + + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_HDLC_FRAMER_PB_IMPL_H */ + diff --git a/gr-digital/lib/mpsk_receiver_cc_impl.cc b/gr-digital/lib/mpsk_receiver_cc_impl.cc index 0d7464a0fb..d6c2ae6fa3 100644 --- a/gr-digital/lib/mpsk_receiver_cc_impl.cc +++ b/gr-digital/lib/mpsk_receiver_cc_impl.cc @@ -37,35 +37,35 @@ namespace gr { #define VERBOSE_MM 0 // Used for debugging symbol timing loop #define VERBOSE_COSTAS 0 // Used for debugging phase and frequency tracking - mpsk_receiver_cc::sptr + mpsk_receiver_cc::sptr mpsk_receiver_cc::make(unsigned int M, float theta, float loop_bw, float fmin, float fmax, - float mu, float gain_mu, + float mu, float gain_mu, float omega, float gain_omega, float omega_rel) { return gnuradio::get_initial_sptr (new mpsk_receiver_cc_impl(M, theta, loop_bw, fmin, fmax, - mu, gain_mu, - omega, gain_omega, + mu, gain_mu, + omega, gain_omega, omega_rel)); } - mpsk_receiver_cc_impl::mpsk_receiver_cc_impl(unsigned int M, float theta, + mpsk_receiver_cc_impl::mpsk_receiver_cc_impl(unsigned int M, float theta, float loop_bw, float fmin, float fmax, - float mu, float gain_mu, + float mu, float gain_mu, float omega, float gain_omega, float omega_rel) : block("mpsk_receiver_cc", - io_signature::make(1, 1, sizeof(gr_complex)), - io_signature::make(1, 1, sizeof(gr_complex))), - blocks::control_loop(loop_bw, fmax, fmin), - d_M(M), d_theta(theta), + io_signature::make(1, 1, sizeof(gr_complex)), + io_signature::make(1, 1, sizeof(gr_complex))), + blocks::control_loop(loop_bw, fmax, fmin), + d_M(M), d_theta(theta), d_current_const_point(0), - d_mu(mu), d_gain_mu(gain_mu), d_gain_omega(gain_omega), + d_mu(mu), d_gain_mu(gain_mu), d_gain_omega(gain_omega), d_omega_rel(omega_rel), d_max_omega(0), d_min_omega(0), d_p_2T(0), d_p_1T(0), d_p_0T(0), d_c_2T(0), d_c_1T(0), d_c_0T(0) { @@ -78,13 +78,13 @@ namespace gr { throw std::out_of_range("clock rate must be > 0"); if(gain_mu < 0 || gain_omega < 0) throw std::out_of_range("Gains must be non-negative"); - + assert(d_interp->ntaps() <= DLLEN); - + // zero double length delay line. for(unsigned int i = 0; i < 2 * DLLEN; i++) d_dl[i] = gr_complex(0.0,0.0); - + set_modulation_order(d_M); } @@ -98,7 +98,7 @@ namespace gr { { // build the constellation vector from M make_constellation(); - + // Select a phase detector and a decision maker for the modulation order switch(d_M) { case 2: // optimized algorithms for BPSK @@ -150,7 +150,7 @@ namespace gr { else phase_error = -sample.real(); } - + return phase_error; } @@ -193,7 +193,7 @@ namespace gr { // the Euclidean distance (error) with the sample for(unsigned int m = 0; m < d_M; m++) { gr_complex diff = norm(d_constellation[m] - sample); - + if(fabs(diff.real()) < min_s) { min_s = fabs(diff.real()); min_m = m; @@ -224,10 +224,10 @@ namespace gr { d_phase -= M_TWOPI; while(d_phase < -M_TWOPI) d_phase += M_TWOPI; - + nco = gr_expj(d_phase+d_theta); // get the NCO value for derotating the current sample sample = nco*symbol; // get the downconverted symbol - + // Fill up the delay line for the interpolator d_dl[d_dl_idx] = sample; d_dl[(d_dl_idx + DLLEN)] = sample; // put this in the second half of the buffer for overflows @@ -248,24 +248,24 @@ namespace gr { d_p_0T = sample; d_c_2T = d_c_1T; d_c_1T = d_c_0T; - + d_current_const_point = (*this.*d_decision)(d_p_0T); // make a decision on the sample value d_c_0T = d_constellation[d_current_const_point]; - + x = (d_c_0T - d_c_2T) * conj(d_p_1T); y = (d_p_0T - d_p_2T) * conj(d_c_1T); u = y - x; mm_error = u.real(); // the error signal is in the real part mm_error = gr::branchless_clip(mm_error, 1.0); // limit mm_val - + d_omega = d_omega + d_gain_omega * mm_error; // update omega based on loop error d_omega = d_omega_mid + gr::branchless_clip(d_omega-d_omega_mid, d_omega_rel); // make sure we don't walk away - + d_mu += d_omega + d_gain_mu * mm_error; // update mu based on loop error - + #if VERBOSE_MM - printf("mm: mu: %f omega: %f mm_error: %f sample: %f+j%f constellation: %f+j%f\n", - d_mu, d_omega, mm_error, sample.real(), sample.imag(), + printf("mm: mu: %f omega: %f mm_error: %f sample: %f+j%f constellation: %f+j%f\n", + d_mu, d_omega, mm_error, sample.real(), sample.imag(), d_constellation[d_current_const_point].real(), d_constellation[d_current_const_point].imag()); #endif } @@ -278,14 +278,14 @@ namespace gr { // Make phase and frequency corrections based on sampled value phase_error = (*this.*d_phase_error_detector)(sample); - + advance_loop(phase_error); phase_wrap(); frequency_limit(); - + #if VERBOSE_COSTAS printf("cl: phase_error: %f phase: %f freq: %f sample: %f+j%f constellation: %f+j%f\n", - phase_error, d_phase, d_freq, sample.real(), sample.imag(), + phase_error, d_phase, d_freq, sample.real(), sample.imag(), d_constellation[d_current_const_point].real(), d_constellation[d_current_const_point].imag()); #endif } @@ -306,7 +306,7 @@ namespace gr { mm_sampler(in[i]); // puts symbols into a buffer and adjusts d_mu i++; } - + if(i < ninput_items[0]) { gr_complex interp_sample = d_interp->interpolate(&d_dl[d_dl_idx], d_mu); diff --git a/gr-digital/lib/mpsk_receiver_cc_impl.h b/gr-digital/lib/mpsk_receiver_cc_impl.h index 8e404da54e..48a9e43e58 100644 --- a/gr-digital/lib/mpsk_receiver_cc_impl.h +++ b/gr-digital/lib/mpsk_receiver_cc_impl.h @@ -35,10 +35,10 @@ namespace gr { class mpsk_receiver_cc_impl : public mpsk_receiver_cc { public: - mpsk_receiver_cc_impl(unsigned int M, float theta, + mpsk_receiver_cc_impl(unsigned int M, float theta, float loop_bw, float fmin, float fmax, - float mu, float gain_mu, + float mu, float gain_mu, float omega, float gain_omega, float omega_rel); ~mpsk_receiver_cc_impl(); @@ -77,9 +77,9 @@ namespace gr { //! Sets value of mu void set_mu(float mu) { d_mu = mu; } - - //! Sets value of omega and its min and max values - void set_omega(float omega) { + + //! Sets value of omega and its min and max values + void set_omega(float omega) { d_omega = omega; d_min_omega = omega*(1.0 - d_omega_rel); d_max_omega = omega*(1.0 + d_omega_rel); @@ -94,7 +94,7 @@ namespace gr { //! Sets the relative omega limit and resets omega min/max values void set_gain_omega_rel(float omega_rel); - + protected: void make_constellation(); void mm_sampler(const gr_complex symbol); @@ -172,7 +172,7 @@ namespace gr { * \returns the index to d_constellation that minimizes the error/ */ unsigned int decision_bpsk(gr_complex sample) const; - + /*! * \brief Decision maker for QPSK constellation. * @@ -191,7 +191,7 @@ namespace gr { float d_theta; /*! - * \brief Decision maker function pointer + * \brief Decision maker function pointer * * \param sample the baseband I&Q sample from which to make the decision * @@ -213,7 +213,7 @@ namespace gr { gr_complex d_c_2T, d_c_1T, d_c_0T; /*! - * \brief Phase error detector function pointer + * \brief Phase error detector function pointer * * \param sample the I&Q sample from which to determine the phase error * @@ -225,13 +225,13 @@ namespace gr { //! get interpolated value gr::filter::mmse_fir_interpolator_cc *d_interp; - + //! delay line length. static const unsigned int DLLEN = 8; - + //! delay line plus some length for overflow protection __GR_ATTR_ALIGNED(8) gr_complex d_dl[2*DLLEN]; - + //! index to delay line unsigned int d_dl_idx; }; diff --git a/gr-digital/python/digital/gmsk.py b/gr-digital/python/digital/gmsk.py index 9a44837002..012c91f9d0 100644 --- a/gr-digital/python/digital/gmsk.py +++ b/gr-digital/python/digital/gmsk.py @@ -66,7 +66,7 @@ class gmsk_mod(gr.hier_block2): samples_per_symbol: samples per baud >= 2 (integer) bt: Gaussian filter bandwidth * symbol time (float) verbose: Print information about modulator? (boolean) - debug: Print modulation data to files? (boolean) + log: Print modulation data to files? (boolean) """ def __init__(self, @@ -176,12 +176,12 @@ class gmsk_demod(gr.hier_block2): Args: samples_per_symbol: samples per baud (integer) - verbose: Print information about modulator? (boolean) - log: Print modualtion data to files? (boolean) gain_mu: controls rate of mu adjustment (float) mu: fractional delay [0.0, 1.0] (float) omega_relative_limit: sets max variation in omega (float) freq_error: bit rate error as a fraction (float) + verbose: Print information about modulator? (boolean) + log: Print modualtion data to files? (boolean) """ def __init__(self, diff --git a/gr-digital/python/digital/packet_utils.py b/gr-digital/python/digital/packet_utils.py index 865f3adbb4..d7aa4e66ca 100644 --- a/gr-digital/python/digital/packet_utils.py +++ b/gr-digital/python/digital/packet_utils.py @@ -113,7 +113,9 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol, bits_per_symbol: (needed for padding calculation) (int) preamble: string of ascii 0's and 1's access_code: string of ascii 0's and 1's + pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples(512 bytes) whitener_offset: offset into whitener string to use [0-16) + whitening: Whether to turn on data whitening(scrambling) (boolean) Packet will have access code at the beginning, followed by length, payload and finally CRC-32. diff --git a/gr-digital/python/digital/psk.py b/gr-digital/python/digital/psk.py index 1816ffb4ba..0e0c65ea2b 100644 --- a/gr-digital/python/digital/psk.py +++ b/gr-digital/python/digital/psk.py @@ -85,9 +85,15 @@ class psk_mod(generic_mod): """ Hierarchical block for RRC-filtered PSK modulation. - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - + The input is a byte stream (unsigned char), treated as a series of packed + symbols. Symbols are grouped from MSB to LSB. + + The output is the complex modulated signal at baseband, with a given number + of samples per symbol. + + If "Samples/Symbol" is 2, and "Number of Constellation Points" is 4, a + single byte contains four symbols, and will produce eight samples. + Args: constellation_points: Number of constellation points (must be a power of two) (integer). mod_code: Whether to use a gray_code (digital.mod_codes.GRAY_CODE) or not (digital.mod_codes.NO_CODE). @@ -113,8 +119,10 @@ class psk_demod(generic_demod): """ Hierarchical block for RRC-filtered PSK modulation. - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. + The input is a complex modulated signal at baseband. + + The output is a stream of bytes, each representing a recovered bit. + The most significant bit is reported first. Args: constellation_points: Number of constellation points (must be a power of two) (integer). diff --git a/gr-digital/python/digital/qa_hdlc_framer.py b/gr-digital/python/digital/qa_hdlc_framer.py new file mode 100755 index 0000000000..f8d1923de1 --- /dev/null +++ b/gr-digital/python/digital/qa_hdlc_framer.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# Copyright 2006,2007,2010,2011,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. +# + +from gnuradio import gr, gr_unittest, digital, blocks +import pmt +import numpy +from time import sleep + +class test_hdlc_framer(gr_unittest.TestCase): + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001(self): + #test complementary operation of framer & deframer + #want to frame some random data that has enough consecutive bits to + #stuff at least a few bits + npkts = 20 + src_data = [0xFE, 0xDA, 0xAC, 0x29, 0x7F, 0xA2, 0x90, 0x0F, 0xF8] + frame = digital.hdlc_framer_pb("wat") + corr = digital.correlate_access_code_tag_bb("01111110", 0, "frame") + deframe = digital.hdlc_deframer_bp("frame", 32, 500) + debug = blocks.message_debug() + self.tb.connect(frame, corr, deframe) + self.tb.msg_connect(deframe, "out", debug, "store") + self.tb.start() + msg = pmt.cons(pmt.PMT_NIL, pmt.init_u8vector(len(src_data),src_data)) + for i in xrange(npkts): + frame.to_basic_block()._post(pmt.intern("in"), msg) + sleep(0.2) + self.tb.stop() + self.tb.wait() + rxmsg = debug.get_message(0) + result_len = pmt.blob_length(pmt.cdr(rxmsg)) + msg_data = [] + for j in xrange(result_len): + msg_data.append(pmt.u8vector_ref(pmt.cdr(rxmsg), j)) + self.assertEqual(src_data, msg_data) + + +if __name__ == '__main__': + gr_unittest.run(test_hdlc_framer, "test_hdlc_framer.xml") + diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i index 5a0cb4f415..ab9794af57 100644 --- a/gr-digital/swig/digital_swig.i +++ b/gr-digital/swig/digital_swig.i @@ -67,6 +67,8 @@ #include "gnuradio/digital/framer_sink_1.h" #include "gnuradio/digital/glfsr_source_b.h" #include "gnuradio/digital/glfsr_source_f.h" +#include "gnuradio/digital/hdlc_deframer_bp.h" +#include "gnuradio/digital/hdlc_framer_pb.h" #include "gnuradio/digital/header_payload_demux.h" #include "gnuradio/digital/kurtotic_equalizer_cc.h" #include "gnuradio/digital/lfsr.h" @@ -138,6 +140,8 @@ %include "gnuradio/digital/framer_sink_1.h" %include "gnuradio/digital/glfsr_source_b.h" %include "gnuradio/digital/glfsr_source_f.h" +%include "gnuradio/digital/hdlc_deframer_bp.h" +%include "gnuradio/digital/hdlc_framer_pb.h" %include "gnuradio/digital/header_payload_demux.h" %include "gnuradio/digital/kurtotic_equalizer_cc.h" %include "gnuradio/digital/lfsr.h" @@ -203,6 +207,8 @@ GR_SWIG_BLOCK_MAGIC2(digital, fll_band_edge_cc); GR_SWIG_BLOCK_MAGIC2(digital, framer_sink_1); GR_SWIG_BLOCK_MAGIC2(digital, glfsr_source_b); GR_SWIG_BLOCK_MAGIC2(digital, glfsr_source_f); +GR_SWIG_BLOCK_MAGIC2(digital, hdlc_deframer_bp); +GR_SWIG_BLOCK_MAGIC2(digital, hdlc_framer_pb); GR_SWIG_BLOCK_MAGIC2(digital, header_payload_demux); GR_SWIG_BLOCK_MAGIC2(digital, kurtotic_equalizer_cc); GR_SWIG_BLOCK_MAGIC2(digital, lms_dd_equalizer_cc); diff --git a/gr-filter/examples/channelizer_demo.grc b/gr-filter/examples/channelizer_demo.grc new file mode 100644 index 0000000000..b7b4c1cb79 --- /dev/null +++ b/gr-filter/examples/channelizer_demo.grc @@ -0,0 +1,1265 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Thu Mar 27 13:33:38 2014</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>top_block</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</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>_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>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(179, 9)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>analog_sig_source_x</key> + <param> + <key>id</key> + <value>analog_sig_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>analog.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>0.03 * samp_rate</value> + </param> + <param> + <key>amp</key> + <value>1</value> + </param> + <param> + <key>offset</key> + <value>0</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>(12, 71)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>analog_sig_source_x</key> + <param> + <key>id</key> + <value>analog_sig_source_x_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>analog.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>0.38 * samp_rate</value> + </param> + <param> + <key>amp</key> + <value>1</value> + </param> + <param> + <key>offset</key> + <value>0</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>(11, 177)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>qtgui_freq_sink_x</key> + <param> + <key>id</key> + <value>qtgui_freq_sink_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>fftsize</key> + <value>1024</value> + </param> + <param> + <key>wintype</key> + <value>firdes.WIN_BLACKMAN_hARRIS</value> + </param> + <param> + <key>fc</key> + <value>0</value> + </param> + <param> + <key>bw</key> + <value>samp_rate</value> + </param> + <param> + <key>autoscale</key> + <value>False</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></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>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(352, 35)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_add_xx</key> + <param> + <key>id</key> + <value>blocks_add_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_inputs</key> + <value>3</value> + </param> + <param> + <key>vlen</key> + <value>1</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>(228, 177)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>pfb_channelizer_hier_ccf</key> + <param> + <key>id</key> + <value>pfb_channelizer_hier_ccf_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>nchans</key> + <value>3</value> + </param> + <param> + <key>n_filterbanks</key> + <value>4</value> + </param> + <param> + <key>taps</key> + <value>None</value> + </param> + <param> + <key>outchans</key> + <value>None</value> + </param> + <param> + <key>atten</key> + <value>100</value> + </param> + <param> + <key>bw</key> + <value>0.6</value> + </param> + <param> + <key>tb</key> + <value>0.2</value> + </param> + <param> + <key>ripple</key> + <value>0.1</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>(333, 163)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>qtgui_freq_sink_x</key> + <param> + <key>id</key> + <value>qtgui_freq_sink_x_0_2</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>fftsize</key> + <value>1024</value> + </param> + <param> + <key>wintype</key> + <value>firdes.WIN_BLACKMAN_hARRIS</value> + </param> + <param> + <key>fc</key> + <value>0</value> + </param> + <param> + <key>bw</key> + <value>samp_rate/3.0</value> + </param> + <param> + <key>autoscale</key> + <value>False</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></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>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(768, 63)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>qtgui_freq_sink_x</key> + <param> + <key>id</key> + <value>qtgui_freq_sink_x_0_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>fftsize</key> + <value>1024</value> + </param> + <param> + <key>wintype</key> + <value>firdes.WIN_BLACKMAN_hARRIS</value> + </param> + <param> + <key>fc</key> + <value>samp_rate/3.0</value> + </param> + <param> + <key>bw</key> + <value>samp_rate/3.0</value> + </param> + <param> + <key>autoscale</key> + <value>False</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></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>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(768, 177)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>analog_sig_source_x</key> + <param> + <key>id</key> + <value>analog_sig_source_x_2</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>analog.GR_COS_WAVE</value> + </param> + <param> + <key>freq</key> + <value>0.70*samp_rate</value> + </param> + <param> + <key>amp</key> + <value>1</value> + </param> + <param> + <key>offset</key> + <value>0</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>(8, 282)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>qtgui_freq_sink_x</key> + <param> + <key>id</key> + <value>qtgui_freq_sink_x_0_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>name</key> + <value>QT GUI Plot</value> + </param> + <param> + <key>fftsize</key> + <value>1024</value> + </param> + <param> + <key>wintype</key> + <value>firdes.WIN_BLACKMAN_hARRIS</value> + </param> + <param> + <key>fc</key> + <value>-samp_rate/3.0</value> + </param> + <param> + <key>bw</key> + <value>samp_rate/3.0</value> + </param> + <param> + <key>autoscale</key> + <value>False</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></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>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(769, 287)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>analog_sig_source_x_1</source_block_id> + <sink_block_id>blocks_add_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>analog_sig_source_x_0</source_block_id> + <sink_block_id>blocks_add_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_add_xx_0</source_block_id> + <sink_block_id>pfb_channelizer_hier_ccf_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>analog_sig_source_x_2</source_block_id> + <sink_block_id>blocks_add_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>2</sink_key> + </connection> + <connection> + <source_block_id>blocks_add_xx_0</source_block_id> + <sink_block_id>qtgui_freq_sink_x_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>pfb_channelizer_hier_ccf_0</source_block_id> + <sink_block_id>qtgui_freq_sink_x_0_2</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>pfb_channelizer_hier_ccf_0</source_block_id> + <sink_block_id>qtgui_freq_sink_x_0_1</sink_block_id> + <source_key>1</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>pfb_channelizer_hier_ccf_0</source_block_id> + <sink_block_id>qtgui_freq_sink_x_0_0</sink_block_id> + <source_key>2</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-filter/grc/CMakeLists.txt b/gr-filter/grc/CMakeLists.txt index cc5c77ebc6..1315b11c28 100644 --- a/gr-filter/grc/CMakeLists.txt +++ b/gr-filter/grc/CMakeLists.txt @@ -23,6 +23,7 @@ install(FILES filter_fft_filter_xxx.xml filter_fir_filter_xxx.xml filter_filter_delay_fc.xml + filter_filterbank_vcvcf.xml filter_fractional_interpolator_xx.xml filter_fractional_resampler_xx.xml filter_freq_xlating_fir_filter_xxx.xml @@ -31,6 +32,7 @@ install(FILES filter_interp_fir_filter_xxx.xml filter_pfb_arb_resampler.xml filter_pfb_channelizer.xml + filter_pfb_channelizer_hier.xml filter_pfb_decimator.xml filter_pfb_interpolator.xml filter_pfb_synthesizer.xml diff --git a/gr-filter/grc/filter_block_tree.xml b/gr-filter/grc/filter_block_tree.xml index 617893ad54..8fe0d17a78 100644 --- a/gr-filter/grc/filter_block_tree.xml +++ b/gr-filter/grc/filter_block_tree.xml @@ -40,6 +40,7 @@ <block>dc_blocker_xx</block> <block>fft_filter_xxx</block> <block>fir_filter_xxx</block> + <block>filterbank_vcvcf</block> <block>filter_delay_fc</block> <block>hilbert_fc</block> <block>iir_filter_ffd</block> @@ -57,6 +58,7 @@ <name>Channelizers</name> <block>freq_xlating_fir_filter_xxx</block> <block>pfb_channelizer_ccf</block> + <block>pfb_channelizer_hier_ccf</block> <block>pfb_decimator_ccf</block> <block>pfb_interpolator_ccf</block> <block>pfb_synthesizer_ccf</block> diff --git a/gr-filter/grc/filter_filterbank_vcvcf.xml b/gr-filter/grc/filter_filterbank_vcvcf.xml new file mode 100644 index 0000000000..c8175358d1 --- /dev/null +++ b/gr-filter/grc/filter_filterbank_vcvcf.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<!-- +################################################### +## Generic Filterbank +################################################### + --> +<block> + <name>Generic Filterbank</name> + <key>filterbank_vcvcf</key> + <import>from gnuradio import filter</import> + <make>filter.filterbank_vcvcf($taps)</make> + <callback>set_taps($taps)</callback> + <param> + <name>Taps(list of lists)</name> + <key>taps</key> + <value></value> + <type>raw</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + <vlen>len($taps)</vlen> + </sink> + <source> + <name>out</name> + <type>complex</type> + <vlen>len($taps)</vlen> + </source> +</block> diff --git a/gr-filter/grc/filter_pfb_channelizer_hier.xml b/gr-filter/grc/filter_pfb_channelizer_hier.xml new file mode 100644 index 0000000000..356187d90c --- /dev/null +++ b/gr-filter/grc/filter_pfb_channelizer_hier.xml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Hierarchical Polyphase Channelizer +################################################### + --> +<block> + <name>Hierarchical Polyphase Channelizer</name> + <key>pfb_channelizer_hier_ccf</key> + <import>from gnuradio.filter import pfb</import> + <make>pfb.channelizer_hier_ccf( + $nchans, + $n_filterbanks, + $taps, + $outchans, + $atten, + $bw, + $tb, + $ripple + ) + </make> + <callback>set_taps($taps)</callback> + <param> + <name>Number of Channels</name> + <key>nchans</key> + <value>3</value> + <type>int</type> + </param> + <param> + <name>Number of Filterbanks</name> + <key>n_filterbanks</key> + <value>4</value> + <type>int</type> + </param> + <param> + <name>Taps</name> + <key>taps</key> + <value>None</value> + <type>raw</type> + </param> + <param> + <name>Output Channels</name> + <key>outchans</key> + <value>None</value> + <type>raw</type> + </param> + <param> + <name>Attenuation</name> + <key>atten</key> + <value>100</value> + <type>real</type> + </param> + <param> + <name>Fraction of Channel to Keep</name> + <key>bw</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Transition Band (as a fraction of channel width)</name> + <key>tb</key> + <value>0.2</value> + <type>real</type> + </param> + <param> + <name>Passband Ripple in dB</name> + <key>ripple</key> + <value>0.1</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + <nports>$nchans</nports> + </source> +</block> diff --git a/gr-filter/include/gnuradio/filter/CMakeLists.txt b/gr-filter/include/gnuradio/filter/CMakeLists.txt index 9dbc227887..1af91a6067 100644 --- a/gr-filter/include/gnuradio/filter/CMakeLists.txt +++ b/gr-filter/include/gnuradio/filter/CMakeLists.txt @@ -89,6 +89,8 @@ install(FILES mmse_fir_interpolator_ff.h pm_remez.h polyphase_filterbank.h + filterbank.h + filterbank_vcvcf.h single_pole_iir.h dc_blocker_cc.h dc_blocker_ff.h diff --git a/gr-filter/include/gnuradio/filter/filterbank.h b/gr-filter/include/gnuradio/filter/filterbank.h new file mode 100644 index 0000000000..f71d6c9fdd --- /dev/null +++ b/gr-filter/include/gnuradio/filter/filterbank.h @@ -0,0 +1,97 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012, 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_FILTER_FILTERBANK_H +#define INCLUDED_FILTER_FILTERBANK_H + +#include <gnuradio/filter/api.h> +#include <gnuradio/filter/fir_filter.h> + +namespace gr { + namespace filter { + namespace kernel { + + /*! + * \brief A filter bank with generic taps. + * + * This block takes in a vector of N complex inputs, passes + * them through N FIR filters, and outputs a vector of N complex + * outputs. + * + * The only advantage of using this block over N individual + * FIR filter blocks is that it places less of a load on the + * scheduler. + * + * The number of filters cannot be changed dynamically, however + * filters can be deactivated (i.e. no processing is done for + * them) by passing a vector of filter taps containing all zeros + * to them. In this case their entry in the output vector is a + * zero. + * + */ + + class FILTER_API filterbank + { + protected: + unsigned int d_nfilts; + unsigned int d_ntaps; + std::vector<kernel::fir_filter_ccf*> d_fir_filters; + std::vector< std::vector<float> > d_taps; + std::vector<bool> d_active; + unsigned int d_taps_per_filter; + + public: + /*! + * Build the filterbank. + * + * \param taps (vector of vector of floats / list of list of floats) + * Populates the filters. + */ + filterbank(const std::vector<std::vector<float> > &taps); + + ~filterbank(); + + /*! + * Update the filterbank's filter taps. + * + * \param taps (vector of vector of floats / list of list of floats) + * The prototype filter to populate the filterbank. + */ + virtual void set_taps(const std::vector<std::vector<float> > &taps); + + /*! + * Print all of the filterbank taps to screen. + */ + void print_taps(); + + /*! + * Return a vector<vector<>> of the filterbank taps + */ + std::vector<std::vector<float> > taps() const; + }; + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_FILTERBANK_H */ diff --git a/gr-filter/include/gnuradio/filter/filterbank_vcvcf.h b/gr-filter/include/gnuradio/filter/filterbank_vcvcf.h new file mode 100644 index 0000000000..dfacc24517 --- /dev/null +++ b/gr-filter/include/gnuradio/filter/filterbank_vcvcf.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2010,2012,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_FILTER_FILTERBANK_CHANNELIZER_VCVCF_H +#define INCLUDED_FILTER_FILTERBANK_CHANNELIZER_VCVCF_H + +#include <gnuradio/filter/api.h> +#include <gnuradio/block.h> + +namespace gr { + namespace filter { + + /*! + * \brief Filterbank with vector of gr_complex input, + * vector of gr_complex output and float taps + * \ingroup filter_blk + * + * \details + * This block takes in complex vectors and outputs complex vectors of the same + * size. Vectors of length N, rather than N normal streams are used to reduce + * overhead. + */ + class FILTER_API filterbank_vcvcf : virtual public block + { + public: + typedef boost::shared_ptr<filterbank_vcvcf> sptr; + + /*! + * Build the filterbank. + * \param taps (vector of vector of floats/list of list of floats) + * Used to populate the filters. + */ + static sptr make(const std::vector< std::vector<float> > &taps); + + /*! + * Resets the filterbank's filter taps with the new prototype filter + * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + */ + virtual void set_taps(const std::vector< std::vector<float> > &taps) = 0; + + /*! + * Print all of the filterbank taps to screen. + */ + virtual void print_taps() = 0; + + /*! + * Return a vector<vector<>> of the filterbank taps + */ + virtual std::vector<std::vector<float> > taps() const = 0; + + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_PFB_CHANNELIZER_VCVCF_H */ diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt index 27d1e0d013..0e444d5b5d 100644 --- a/gr-filter/lib/CMakeLists.txt +++ b/gr-filter/lib/CMakeLists.txt @@ -127,6 +127,8 @@ list(APPEND filter_sources dc_blocker_cc_impl.cc dc_blocker_ff_impl.cc filter_delay_fc_impl.cc + filterbank.cc + filterbank_vcvcf_impl.cc fft_filter_ccc_impl.cc fft_filter_ccf_impl.cc fft_filter_fff_impl.cc diff --git a/gr-filter/lib/filterbank.cc b/gr-filter/lib/filterbank.cc new file mode 100644 index 0000000000..516d0aaccb --- /dev/null +++ b/gr-filter/lib/filterbank.cc @@ -0,0 +1,112 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012,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/filter/filterbank.h> +#include <cstdio> +#include <iostream> +#include <stdexcept> + +namespace gr { + namespace filter { + namespace kernel { + + filterbank::filterbank(const std::vector<std::vector<float> > &taps) + : d_taps(taps) + { + d_nfilts = d_taps.size(); + d_fir_filters = std::vector<kernel::fir_filter_ccf*>(d_nfilts); + if (d_nfilts == 0) { + throw std::invalid_argument("The taps vector may not be empty."); + } + d_active.resize(d_nfilts); + // Create an FIR filter for each channel and zero out the taps + std::vector<float> vtaps(1, 0.0f); + for(unsigned int i = 0; i < d_nfilts; i++) { + d_fir_filters[i] = new kernel::fir_filter_ccf(1, vtaps); + } + // Now, actually set the filters' taps + set_taps(d_taps); + } + + filterbank::~filterbank() + { + for(unsigned int i = 0; i < d_nfilts; i++) { + delete d_fir_filters[i]; + } + } + + void + filterbank::set_taps(const std::vector<std::vector<float> > &taps) + { + d_taps = taps; + // Check that the number of filters is correct. + if (d_nfilts != d_taps.size()) { + throw std::runtime_error("The number of filters is incorrect."); + } + // Check that taps contains vectors of taps, where each vector + // is the same length. + d_ntaps = d_taps[0].size(); + for (unsigned int i = 1; i < d_nfilts; i++) { + if (d_taps[i].size() != d_ntaps) { + throw std::runtime_error("All sets of taps must be of the same length."); + } + } + for(unsigned int i = 0; i < d_nfilts; i++) { + // If filter taps are all zeros don't bother to crunch the numbers. + d_active[i] = false; + for (unsigned int j = 0; j < d_ntaps; j++) { + if (d_taps[i][j] != 0) { + d_active[i] = true; + break; + } + } + + d_fir_filters[i]->set_taps(d_taps[i]); + } + } + + void + filterbank::print_taps() + { + unsigned int i, j; + for(i = 0; i < d_nfilts; i++) { + printf("filter[%d]: [", i); + for(j = 0; j < d_taps_per_filter; j++) { + printf(" %.4e", d_taps[i][j]); + } + printf("]\n\n"); + } + } + + std::vector< std::vector<float> > + filterbank::taps() const + { + return d_taps; + } + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ diff --git a/gr-filter/lib/filterbank_vcvcf_impl.cc b/gr-filter/lib/filterbank_vcvcf_impl.cc new file mode 100644 index 0000000000..93c26bbdb8 --- /dev/null +++ b/gr-filter/lib/filterbank_vcvcf_impl.cc @@ -0,0 +1,125 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2010,2012,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 "filterbank_vcvcf_impl.h" +#include <gnuradio/io_signature.h> +#include <stdio.h> +#include <iostream> + +namespace gr { + namespace filter { + + filterbank_vcvcf::sptr + filterbank_vcvcf::make(const std::vector<std::vector<float> > &taps) + { + return gnuradio::get_initial_sptr(new filterbank_vcvcf_impl(taps)); + } + + filterbank_vcvcf_impl::filterbank_vcvcf_impl( + const std::vector< std::vector<float> > &taps) + : block("filterbank_vcvcf", + io_signature::make(1, 1, sizeof(gr_complex)*taps.size()), + io_signature::make(1, 1, sizeof(gr_complex)*taps.size())), + filterbank(taps) + { + set_history(d_ntaps+1); + } + + filterbank_vcvcf_impl::~filterbank_vcvcf_impl() + { + } + + void + filterbank_vcvcf_impl::set_taps(const std::vector<std::vector<float> > &taps) + { + gr::thread::scoped_lock guard(d_mutex); + filterbank::set_taps(taps); + set_history(d_ntaps+1); + d_updated = true; + } + + void + filterbank_vcvcf_impl::print_taps() + { + filterbank::print_taps(); + } + + std::vector<std::vector<float> > + filterbank_vcvcf_impl::taps() const + { + return filterbank::taps(); + } + + int + filterbank_vcvcf_impl::general_work( + int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr::thread::scoped_lock guard(d_mutex); + + gr_complex *in = (gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + if(d_updated) { + d_updated = false; + return 0; // history requirements may have changed. + } + + size_t noutputs = output_items.size(); + + gr_complex *working; + + working = new gr_complex [noutput_items + d_ntaps]; + + for (unsigned int i = 0; i < d_nfilts; i++) { + // Only call the filter method on active filters. + if (d_active[i]) { + for (unsigned int j = 0; j < noutput_items + d_ntaps-1; j++) { + unsigned int p = i + j*d_nfilts; + working[j] = in[p]; + } + for (unsigned int j = 0; j < (unsigned int)(noutput_items); j++) { + unsigned int p = i + j*d_nfilts; + out[p] = d_fir_filters[i]->filter(working + j); + } + } else { + // Otherwise just output 0s. + for (unsigned int j = 0; j < (unsigned int)(noutput_items); j++) { + unsigned int p = i + j*d_nfilts; + out[p] = 0; + } + } + } + + delete [] working; + consume_each(noutput_items); + return noutput_items; + } + + } /* namespace filter */ +} /* namespace gr */ diff --git a/gr-filter/lib/filterbank_vcvcf_impl.h b/gr-filter/lib/filterbank_vcvcf_impl.h new file mode 100644 index 0000000000..49fa1d0e68 --- /dev/null +++ b/gr-filter/lib/filterbank_vcvcf_impl.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2010,2012,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_FILTER_FILTERBANK_VCVCF_IMPL_H +#define INCLUDED_FILTER_FILTERBANK_VCVCF_IMPL_H + +#include <gnuradio/filter/filterbank_vcvcf.h> +#include <gnuradio/filter/filterbank.h> +#include <gnuradio/filter/fir_filter.h> +#include <gnuradio/thread/thread.h> + +namespace gr { + namespace filter { + + class FILTER_API filterbank_vcvcf_impl : public filterbank_vcvcf, kernel::filterbank + { + private: + bool d_updated; + gr::thread::mutex d_mutex; // mutex to protect set/work access + + public: + filterbank_vcvcf_impl(const std::vector<std::vector<float> > &taps); + ~filterbank_vcvcf_impl(); + + void set_taps(const std::vector<std::vector<float> > &taps); + void print_taps(); + std::vector<std::vector<float> > taps() const; + + 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 filter */ +} /* namespace gr */ + +#endif diff --git a/gr-filter/python/filter/pfb.py b/gr-filter/python/filter/pfb.py index 7ba19ec299..070412503b 100644 --- a/gr-filter/python/filter/pfb.py +++ b/gr-filter/python/filter/pfb.py @@ -20,9 +20,10 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr +import optfir, math + +from gnuradio import gr, fft import filter_swig as filter -import optfir try: from gnuradio import blocks @@ -379,3 +380,81 @@ class arb_resampler_ccc(gr.hier_block2): def set_rate(self, rate): self.pfb.set_rate(rate) + + +class channelizer_hier_ccf(gr.hier_block2): + """ + Make a Polyphase Filter channelizer (complex in, complex out, floating-point taps) + + Args: + n_chans - The number of channels to split into. + n_filterbanks - The number of filterbank blocks to use (default=2). + taps: The taps to use. If this is `None` then taps are generated using optfir.low_pass. + outchans - Which channels to output streams for (a list of integers) (default is all channels). + atten: Stop band attenuation. + bw: The fraction of the channel you want to keep. + tb: Transition band with as fraction of channel width. + ripple: Pass band ripple in dB. + """ + + def __init__(self, n_chans, n_filterbanks=1, taps=None, outchans=None, + atten=100, bw=1.0, tb=0.2, ripple=0.1): + if n_filterbanks > n_chans: + n_filterbanks = n_chans + if outchans is None: + outchans = range(n_chans) + gr.hier_block2.__init__( + self, "pfb_channelizer_hier_ccf", + gr.io_signature(1, 1, gr.sizeof_gr_complex), + gr.io_signature(len(outchans), len(outchans), gr.sizeof_gr_complex)) + if taps is None: + taps = optfir.low_pass(1, n_chans, bw, bw+tb, ripple, atten) + taps = list(taps) + extra_taps = int(math.ceil(1.0*len(taps)/n_chans)*n_chans - len(taps)) + taps = taps + [0] * extra_taps + # Make taps for each channel + chantaps = [list(reversed(taps[i: len(taps): n_chans])) for i in range(0, n_chans)] + # Convert the input stream into a stream of vectors. + self.s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, n_chans) + # Create a mapping to separate out each filterbank (a group of channels to be processed together) + # And a list of sets of taps for each filterbank. + low_cpp = int(n_chans/n_filterbanks) + extra = n_chans - low_cpp*n_filterbanks + cpps = [low_cpp+1]*extra + [low_cpp]*(n_filterbanks-extra) + splitter_mapping = [] + filterbanktaps = [] + total = 0 + for cpp in cpps: + splitter_mapping.append([(0, i) for i in range(total, total+cpp)]) + filterbanktaps.append(chantaps[total: total+cpp]) + total += cpp + assert(total == n_chans) + # Split the stream of vectors in n_filterbanks streams of vectors. + self.splitter = blocks.vector_map(gr.sizeof_gr_complex, [n_chans], splitter_mapping) + # Create the filterbanks + self.fbs = [filter.filterbank_vcvcf(taps) for taps in filterbanktaps] + # Combine the streams of vectors back into a single stream of vectors. + combiner_mapping = [[]] + for i, cpp in enumerate(cpps): + for j in range(cpp): + combiner_mapping[0].append((i, j)) + self.combiner = blocks.vector_map(gr.sizeof_gr_complex, cpps, combiner_mapping) + # Add the final FFT to the channelizer. + self.fft = fft.fft_vcc(n_chans, forward=True, window=[1.0]*n_chans) + # Select the desired channels + if outchans != range(n_chans): + selector_mapping = [[(0, i) for i in outchans]] + self.selector = blocks.vector_map(gr.sizeof_gr_complex, [n_chans], selector_mapping) + # Convert stream of vectors to a normal stream. + self.v2ss = blocks.vector_to_streams(gr.sizeof_gr_complex, len(outchans)) + self.connect(self, self.s2v, self.splitter) + for i in range(0, n_filterbanks): + self.connect((self.splitter, i), self.fbs[i], (self.combiner, i)) + self.connect(self.combiner, self.fft) + if outchans != range(n_chans): + self.connect(self.fft, self.selector, self.v2ss) + else: + self.connect(self.fft, self.v2ss) + for i in range(0, len(outchans)): + self.connect((self.v2ss, i), (self, i)) + diff --git a/gr-filter/python/filter/qa_filterbank.py b/gr-filter/python/filter/qa_filterbank.py new file mode 100644 index 0000000000..3423b10524 --- /dev/null +++ b/gr-filter/python/filter/qa_filterbank.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# +# Copyright 2012,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. +# + +import time +import random +import math + +from gnuradio import gr, gr_unittest, filter, blocks + +def convolution(A, B): + """ + Returns a convolution of the A and B vectors of length + len(A)-len(B). + """ + rs = [] + for i in range(len(B)-1, len(A)): + r = 0 + for j, b in enumerate(B): + r += A[i-j] * b + rs.append(r) + return rs + +class test_filterbank_vcvcf(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_000(self): + """ + Generates nfilts sets of random complex data. + Generates two sets of random taps for each filter. + Applies one set of the random taps, gets some output, + applies the second set of random taps, gets some more output, + The output is then compared with a python-implemented + convolution. + """ + myrand = random.Random(123).random + nfilts = 10 + ntaps = 5 + # Sets some of the taps to be all zeros. + zero_filts1 = (3, 7) + zero_filts2 = (1, 6, 9) + ndatapoints = 100 + # Generate some random sets of data + data_sets = [] + for i in range(0, nfilts): + data_sets.append([(myrand()-0.5) + (myrand()-0.5)*(0+1j) + for k in range(0, ndatapoints)]) + # Join them together to pass to vector_source block + data = [] + for dp in zip(*data_sets): + data += dp + # Generate some random taps. + taps1 = [] + taps2 = [] + for i in range(0, nfilts): + if i in zero_filts1: + taps1.append([0]*ntaps) + else: + taps1.append([myrand()-0.5 for k in range(0, ntaps)]) + if i in zero_filts2: + taps2.append([0]*ntaps) + else: + taps2.append([myrand()-0.5 for k in range(0, ntaps)]) + + # Calculate results with a python-implemented convolution. + results = [] + results2 = [] + for ds, ts, ts2 in zip(data_sets, taps1, taps2): + results.append(convolution(ds[-len(ts):]+ds[:-1], ts)) + results2.append(convolution(ds[-len(ts):]+ds[:-1], ts2)) + # Convert results from 2D arrays to 1D arrays for ease of comparison. + comb_results = [] + for rs in zip(*results): + comb_results += rs + comb_results2 = [] + for rs in zip(*results2): + comb_results2 += rs + # Construct the signal-processing chain. + src = blocks.vector_source_c(data, True, nfilts) + fb = filter.filterbank_vcvcf(taps1) + v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, nfilts) + s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, nfilts*ndatapoints) + snk = blocks.probe_signal_vc(nfilts*ndatapoints) + self.tb.connect(src, fb, v2s, s2v, snk) + # Run the signal-processing chain. + self.tb.start() + all_zero = True + outdata = None + waittime = 0.001 + # Wait until we have some data. + while (not outdata) or outdata[0]==0: + time.sleep(waittime) + outdata = snk.level() + # Apply the second set of taps. + fb.set_taps(taps2) + outdata2 = None + # Wait until we have new data. + while (not outdata2) or outdata[0] == outdata2[0]: + time.sleep(waittime) + outdata2 = snk.level() + self.tb.stop() + # Compare the datasets. + self.assertComplexTuplesAlmostEqual(comb_results, outdata, 6) + self.assertComplexTuplesAlmostEqual(comb_results2, outdata2, 6) + +if __name__ == '__main__': + gr_unittest.run(test_filterbank_vcvcf, "test_filterbank_vcvcf.xml") diff --git a/gr-filter/python/filter/qa_pfb_channelizer.py b/gr-filter/python/filter/qa_pfb_channelizer.py index 46c6e7b5ae..549e41d7f4 100755 --- a/gr-filter/python/filter/qa_pfb_channelizer.py +++ b/gr-filter/python/filter/qa_pfb_channelizer.py @@ -20,8 +20,8 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gr_unittest, filter, blocks -import math +from gnuradio import gr, gr_unittest, filter, blocks, analog +import math, cmath def sig_source_c(samp_rate, freq, amp, N): t = map(lambda x: float(x)/samp_rate, xrange(N)) @@ -29,88 +29,126 @@ def sig_source_c(samp_rate, freq, amp, N): 1j*math.sin(2.*math.pi*freq*x), t) return y + class test_pfb_channelizer(gr_unittest.TestCase): def setUp(self): self.tb = gr.top_block() + self.freqs = [110., -513., 203., -230, 121] + # Number of channels to channelize. + self.M = len(self.freqs) + # Number of samples to use. + self.N = 1000 + # Baseband sampling rate. + self.fs = 5000 + # Input samp rate to channelizer. + self.ifs = self.M*self.fs + + self.taps = filter.firdes.low_pass_2( + 1, self.ifs, self.fs/2, self.fs/10, + attenuation_dB=80, + window=filter.firdes.WIN_BLACKMAN_hARRIS) + + self.Ntest = 50 + def tearDown(self): self.tb = None - def test_000(self): - N = 1000 # number of samples to use - M = 5 # Number of channels to channelize - fs = 5000 # baseband sampling rate - ifs = M*fs # input samp rate to channelizer - - taps = filter.firdes.low_pass_2(1, ifs, fs/2, fs/10, - attenuation_dB=80, - window=filter.firdes.WIN_BLACKMAN_hARRIS) - + def test_0000(self): + self.check_channelizer(filter.pfb.channelizer_ccf( + self.M, taps=self.taps, oversample_rate=1)) + + def test_0001(self): + self.check_channelizer(filter.pfb.channelizer_hier_ccf( + self.M, n_filterbanks=1, taps=self.taps)) + + def get_input_data(self): + """ + Get the raw data generated by addition of sinusoids. + Useful for debugging. + """ + tb = gr.top_block() + signals = [] + add = blocks.add_cc() + for i in xrange(len(self.freqs)): + f = self.freqs[i] + i*self.fs + signals.append(analog.sig_source_c(self.ifs, analog.GR_SIN_WAVE, f, 1)) + tb.connect(signals[i], (add,i)) + head = blocks.head(gr.sizeof_gr_complex, self.N) + snk = blocks.vector_sink_c() + tb.connect(add, head, snk) + tb.run() + input_data = snk.data() + return input_data + + def check_channelizer(self, channelizer_block): signals = list() add = blocks.add_cc() - freqs = [-230., 121., 110., -513., 203.] - for i in xrange(len(freqs)): - f = freqs[i] + (M/2-M+i+1)*fs - data = sig_source_c(ifs, f, 1, N) + for i in xrange(len(self.freqs)): + f = self.freqs[i] + i*self.fs + data = sig_source_c(self.ifs, f, 1, self.N) signals.append(blocks.vector_source_c(data)) self.tb.connect(signals[i], (add,i)) - s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M) - pfb = filter.pfb_channelizer_ccf(M, taps, 1) + #s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, self.M) - self.tb.connect(add, s2ss) + #self.tb.connect(add, s2ss) + self.tb.connect(add, channelizer_block) snks = list() - for i in xrange(M): + for i in xrange(self.M): snks.append(blocks.vector_sink_c()) - self.tb.connect((s2ss,i), (pfb,i)) - self.tb.connect((pfb, i), snks[i]) + #self.tb.connect((s2ss,i), (channelizer_block,i)) + self.tb.connect((channelizer_block, i), snks[i]) self.tb.run() - Ntest = 50 L = len(snks[0].data()) - # Adjusted phase rotations for data - p0 = 0.11058379158914133 - p1 = 4.5108246571401693 - p2 = 3.9739891674564594 - p3 = 2.2820531095511924 - p4 = 1.3782797467397869 + expected_data = self.get_expected_data(L) + received_data = [snk.data() for snk in snks] + + for expected, received in zip(expected_data, received_data): + self.compare_data(expected, received) + + def compare_data(self, expected, received): + Ntest = 50 + expected = expected[-Ntest:] + received = received[-Ntest:] + expected = [x/expected[0] for x in expected] + received = [x/received[0] for x in received] + self.assertComplexTuplesAlmostEqual(expected, received, 3) + + + def get_freq(self, data): + freqs = [] + for r1, r2 in zip(data[:-1], data[1:]): + diff = cmath.phase(r1) - cmath.phase(r2) + if diff > math.pi: + diff -= 2*math.pi + if diff < -math.pi: + diff += 2*math.pi + freqs.append(diff) + freq = float(sum(freqs))/len(freqs) + freq /= 2*math.pi + return freq + + def get_expected_data(self, L): # Filter delay is the normal delay of each arm - tpf = math.ceil(len(taps) / float(M)) + tpf = math.ceil(len(self.taps) / float(self.M)) delay = -(tpf - 1.0) / 2.0 delay = int(delay) # Create a time scale that's delayed to match the filter delay - t = map(lambda x: float(x)/fs, xrange(delay, L+delay)) + t = map(lambda x: float(x)/self.fs, xrange(delay, L+delay)) # Create known data as complex sinusoids at the different baseband freqs # the different channel numbering is due to channelizer output order. - expected0_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+p0) + \ - 1j*math.sin(2.*math.pi*freqs[2]*x+p0), t) - expected1_data = map(lambda x: math.cos(2.*math.pi*freqs[3]*x+p1) + \ - 1j*math.sin(2.*math.pi*freqs[3]*x+p1), t) - expected2_data = map(lambda x: math.cos(2.*math.pi*freqs[4]*x+p2) + \ - 1j*math.sin(2.*math.pi*freqs[4]*x+p2), t) - expected3_data = map(lambda x: math.cos(2.*math.pi*freqs[0]*x+p3) + \ - 1j*math.sin(2.*math.pi*freqs[0]*x+p3), t) - expected4_data = map(lambda x: math.cos(2.*math.pi*freqs[1]*x+p4) + \ - 1j*math.sin(2.*math.pi*freqs[1]*x+p4), t) - - dst0_data = snks[0].data() - dst1_data = snks[1].data() - dst2_data = snks[2].data() - dst3_data = snks[3].data() - dst4_data = snks[4].data() - - self.assertComplexTuplesAlmostEqual(expected0_data[-Ntest:], dst0_data[-Ntest:], 3) - self.assertComplexTuplesAlmostEqual(expected1_data[-Ntest:], dst1_data[-Ntest:], 3) - self.assertComplexTuplesAlmostEqual(expected2_data[-Ntest:], dst2_data[-Ntest:], 3) - self.assertComplexTuplesAlmostEqual(expected3_data[-Ntest:], dst3_data[-Ntest:], 3) - self.assertComplexTuplesAlmostEqual(expected4_data[-Ntest:], dst4_data[-Ntest:], 3) + expected_data = [map(lambda x: math.cos(2.*math.pi*f*x) + + 1j*math.sin(2.*math.pi*f*x), t) for f in self.freqs] + return expected_data if __name__ == '__main__': gr_unittest.run(test_pfb_channelizer, "test_pfb_channelizer.xml") diff --git a/gr-filter/swig/filter_swig.i b/gr-filter/swig/filter_swig.i index 3eb3f3c634..ec1f522117 100644 --- a/gr-filter/swig/filter_swig.i +++ b/gr-filter/swig/filter_swig.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012,2014 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -33,6 +33,7 @@ #include "gnuradio/filter/dc_blocker_cc.h" #include "gnuradio/filter/dc_blocker_ff.h" #include "gnuradio/filter/filter_delay_fc.h" +#include "gnuradio/filter/filterbank_vcvcf.h" #include "gnuradio/filter/fir_filter_ccc.h" #include "gnuradio/filter/fir_filter_ccf.h" #include "gnuradio/filter/fir_filter_fcc.h" @@ -82,6 +83,7 @@ %include "gnuradio/filter/dc_blocker_cc.h" %include "gnuradio/filter/dc_blocker_ff.h" %include "gnuradio/filter/filter_delay_fc.h" +%include "gnuradio/filter/filterbank_vcvcf.h" %include "gnuradio/filter/fir_filter_ccc.h" %include "gnuradio/filter/fir_filter_ccf.h" %include "gnuradio/filter/fir_filter_fcc.h" @@ -128,6 +130,7 @@ GR_SWIG_BLOCK_MAGIC2(filter, dc_blocker_cc); GR_SWIG_BLOCK_MAGIC2(filter, dc_blocker_ff); GR_SWIG_BLOCK_MAGIC2(filter, filter_delay_fc); +GR_SWIG_BLOCK_MAGIC2(filter, filterbank_vcvcf); GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_ccc); GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_ccf); GR_SWIG_BLOCK_MAGIC2(filter, fir_filter_fcc); diff --git a/gr-qtgui/grc/qtgui_block_tree.xml b/gr-qtgui/grc/qtgui_block_tree.xml index 14516df71e..2fc1b0343e 100644 --- a/gr-qtgui/grc/qtgui_block_tree.xml +++ b/gr-qtgui/grc/qtgui_block_tree.xml @@ -2,19 +2,19 @@ <!-- Copyright 2012-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, @@ -38,6 +38,7 @@ <block>qtgui_waterfall_sink_x</block> <block>qtgui_time_raster_sink_x</block> <block>qtgui_histogram_sink_x</block> + <block>qtgui_number_sink</block> <block>qtgui_sink_x</block> </cat> </cat> diff --git a/gr-qtgui/grc/qtgui_const_sink_x.xml b/gr-qtgui/grc/qtgui_const_sink_x.xml index c751c89437..08f9064648 100644 --- a/gr-qtgui/grc/qtgui_const_sink_x.xml +++ b/gr-qtgui/grc/qtgui_const_sink_x.xml @@ -5,12 +5,12 @@ ################################################### --> <block> - <name>QT GUI Constellation Sink</name> - <key>qtgui_const_sink_x</key> - <import>from PyQt4 import Qt</import> - <import>from gnuradio import qtgui</import> - <import>import sip</import> - <make>#set $win = 'self._%s_win'%$id + <name>QT GUI Constellation Sink</name> + <key>qtgui_const_sink_x</key> + <import>from PyQt4 import Qt</import> + <import>from gnuradio import qtgui</import> + <import>import sip</import> + <make>#set $win = 'self._%s_win'%$id qtgui.$(type.fcn)( $size, \#size $name, \#name @@ -19,89 +19,684 @@ qtgui.$(type.fcn)( self.$(id).set_update_time($update_time) self.$(id).set_y_axis($ymin, $ymax) self.$(id).set_x_axis($xmin, $xmax) +self.$(id).enable_autoscale($autoscale) + +labels = [$label1, $label2, $label3, $label4, $label5, + $label6, $label7, $label8, $label9, $label10] +widths = [$width1, $width2, $width3, $width4, $width5, + $width6, $width7, $width8, $width9, $width10] +colors = [$color1, $color2, $color3, $color4, $color5, + $color6, $color7, $color8, $color9, $color10] +styles = [$style1, $style2, $style3, $style4, $style5, + $style6, $style7, $style8, $style9, $style10] +markers = [$marker1, $marker2, $marker3, $marker4, $marker5, + $marker6, $marker7, $marker8, $marker9, $marker10] +alphas = [$alpha1, $alpha2, $alpha3, $alpha4, $alpha5, + $alpha6, $alpha7, $alpha8, $alpha9, $alpha10] +for i in xrange($nconnections): + if len(labels[i]) == 0: + self.$(id).set_line_label(i, "Data {0}".format(i)) + else: + self.$(id).set_line_label(i, labels[i]) + self.$(id).set_line_width(i, widths[i]) + self.$(id).set_line_color(i, colors[i]) + self.$(id).set_line_style(i, styles[i]) + self.$(id).set_line_marker(i, markers[i]) + self.$(id).set_line_alpha(i, alphas[i]) + self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) $(gui_hint()($win))</make> - <callback>set_resize($width, $height)</callback> - <callback>set_update_time($update_time)</callback> - <callback>set_title($which, $title)</callback> - <callback>set_color($which, $color)</callback> - <param> - <name>Type</name> - <key>type</key> - <value>complex</value> - <type>enum</type> - <option><name>Complex</name><key>complex</key><opt>fcn:const_sink_c</opt></option> -<!-- <option><name>Float</name><key>float</key><opt>fcn:const_sink_f</opt></option> --> - </param> - <param> - <name>Name</name> - <key>name</key> - <value>QT GUI Plot</value> - <type>string</type> - </param> - <param> - <name>Number of Points</name> - <key>size</key> - <value>1024</value> - <type>int</type> - </param> - <param> - <name>Y min</name> - <key>ymin</key> - <value>-2</value> - <type>real</type> - <hide>part</hide> - </param> - <param> - <name>Y max</name> - <key>ymax</key> - <value>2</value> - <type>real</type> - <hide>part</hide> - </param> - <param> - <name>X min</name> - <key>xmin</key> - <value>-2</value> - <type>real</type> - <hide>part</hide> - </param> - <param> - <name>X max</name> - <key>xmax</key> - <value>2</value> - <type>real</type> - <hide>part</hide> - </param> - <param> - <name>Number of Inputs</name> - <key>nconnections</key> - <value>1</value> - <type>int</type> - <hide>part</hide> - </param> - <param> - <name>Update Period</name> - <key>update_time</key> - <value>0.10</value> - <type>real</type> - <hide>part</hide> - </param> - <param> - <name>GUI Hint</name> - <key>gui_hint</key> - <value></value> - <type>gui_hint</type> - <hide>part</hide> - </param> - <sink> - <name>in</name> - <type>$type</type> - <nports>$nconnections</nports> - </sink> - <doc> + <callback>set_resize($width, $height)</callback> + <callback>set_update_time($update_time)</callback> + <callback>set_title($which, $title)</callback> + <callback>set_color($which, $color)</callback> + + <param> + <name>Type</name> + <key>type</key> + <value>complex</value> + <type>enum</type> + <option><name>Complex</name><key>complex</key><opt>fcn:const_sink_c</opt></option> +<!--<option><name>Float</name><key>float</key><opt>fcn:const_sink_f</opt></option> --> + </param> + <param> + <name>Name</name> + <key>name</key> + <value>QT GUI Plot</value> + <type>string</type> + </param> + <param> + <name>Number of Points</name> + <key>size</key> + <value>1024</value> + <type>int</type> + </param> + + <param> + <name>Autoscale</name> + <key>autoscale</key> + <value>False</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + + <param> + <name>Y min</name> + <key>ymin</key> + <value>-2</value> + <type>real</type> + <hide>part</hide> + </param> + <param> + <name>Y max</name> + <key>ymax</key> + <value>2</value> + <type>real</type> + <hide>part</hide> + </param> + <param> + <name>X min</name> + <key>xmin</key> + <value>-2</value> + <type>real</type> + <hide>part</hide> + </param> + <param> + <name>X max</name> + <key>xmax</key> + <value>2</value> + <type>real</type> + <hide>part</hide> + </param> + <param> + <name>Number of Inputs</name> + <key>nconnections</key> + <value>1</value> + <type>int</type> + <hide>part</hide> + </param> + <param> + <name>Update Period</name> + <key>update_time</key> + <value>0.10</value> + <type>real</type> + <hide>part</hide> + </param> + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + + <param> + <name>Line 1 Label</name> + <key>label1</key> + <type>string</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Width</name> + <key>width1</key> + <value>1</value> + <type>int</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Color</name> + <key>color1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Blue</name> + <key>"blue"</key> + </option> + <option> + <name>Red</name> + <key>"red"</key> + </option> + <option> + <name>Green</name> + <key>"green"</key> + </option> + <option> + <name>Black</name> + <key>"black"</key> + </option> + <option> + <name>Cyan</name> + <key>"cyan"</key> + </option> + <option> + <name>Magenta</name> + <key>"magenta"</key> + </option> + <option> + <name>Yellow</name> + <key>"yellow"</key> + </option> + <option> + <name>Dark Red</name> + <key>"dark red"</key> + </option> + <option> + <name>Dark Green</name> + <key>"dark green"</key> + </option> + <option> + <name>Dark Blue</name> + <key>"Dark Blue"</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Style</name> + <key>style1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>None</name> + <key>0</key> + </option> + <option> + <name>Solid</name> + <key>1</key> + </option> + <option> + <name>Dash</name> + <key>2</key> + </option> + <option> + <name>Dots</name> + <key>3</key> + </option> + <option> + <name>Dash-Dot</name> + <key>4</key> + </option> + <option> + <name>Dash-Dot-Dot</name> + <key>5</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Marker</name> + <key>marker1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Circle</name> + <key>0</key> + </option> + <option> + <name>Rectangle</name> + <key>1</key> + </option> + <option> + <name>Diamond</name> + <key>2</key> + </option> + <option> + <name>Triangle</name> + <key>3</key> + </option> + <option> + <name>Down Triangle</name> + <key>4</key> + </option> + <option> + <name>Left Triangle</name> + <key>6</key> + </option> + <option> + <name>Right Triangle</name> + <key>7</key> + </option> + <option> + <name>Cross</name> + <key>8</key> + </option> + <option> + <name>X-Cross</name> + <key>9</key> + </option> + <option> + <name>None</name> + <key>-1</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Alpha</name> + <key>alpha1</key> + <value>1.0</value> + <type>float</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 2 Label</name> + <key>label2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 2 Width</name> + <key>width2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 2 Color</name> + <key>color2</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 2 Style</name> + <key>style2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 2 Marker</name> + <key>marker2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 2 Alpha</name> + <key>alpha2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 3 Label</name> + <key>label3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 3 Width</name> + <key>width3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 3 Color</name> + <key>color3</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 3 Style</name> + <key>style3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 3 Marker</name> + <key>marker3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 3 Alpha</name> + <key>alpha3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 4 Label</name> + <key>label4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 4 Width</name> + <key>width4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 4 Color</name> + <key>color4</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 4 Style</name> + <key>style4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 4 Marker</name> + <key>marker4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 4 Alpha</name> + <key>alpha4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 5 Label</name> + <key>label5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 5 Width</name> + <key>width5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 5 Color</name> + <key>color5</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 5 Style</name> + <key>style5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 5 Marker</name> + <key>marker5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 5 Alpha</name> + <key>alpha5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 6 Label</name> + <key>label6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 6 Width</name> + <key>width6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 6 Color</name> + <key>color6</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 6 Style</name> + <key>style6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 6 Marker</name> + <key>marker6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 6 Alpha</name> + <key>alpha6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 7 Label</name> + <key>label7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 7 Width</name> + <key>width7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 7 Color</name> + <key>color7</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 7 Style</name> + <key>style7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 7 Marker</name> + <key>marker7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 7 Alpha</name> + <key>alpha7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 8 Label</name> + <key>label8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 8 Width</name> + <key>width8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 8 Color</name> + <key>color8</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 8 Style</name> + <key>style8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 8 Marker</name> + <key>marker8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 8 Alpha</name> + <key>alpha8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 9 Label</name> + <key>label9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 9 Width</name> + <key>width9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 9 Color</name> + <key>color9</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 9 Style</name> + <key>style9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 9 Marker</name> + <key>marker9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 9 Alpha</name> + <key>alpha9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 10 Label</name> + <key>label10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 10 Width</name> + <key>width10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 10 Color</name> + <key>color10</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 10 Style</name> + <key>style10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 10 Marker</name> + <key>marker10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 10 Alpha</name> + <key>alpha10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + + + <sink> + <name>in</name> + <type>$type</type> + <nports>$nconnections</nports> + </sink> + <doc> The GUI hint can be used to position the widget within the application. \ The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \ Both the tab specification and the grid position are optional. - </doc> + </doc> </block> diff --git a/gr-qtgui/grc/qtgui_freq_sink_x.xml b/gr-qtgui/grc/qtgui_freq_sink_x.xml index 6a61a05e0f..761943eefc 100644 --- a/gr-qtgui/grc/qtgui_freq_sink_x.xml +++ b/gr-qtgui/grc/qtgui_freq_sink_x.xml @@ -5,13 +5,13 @@ ################################################### --> <block> - <name>QT GUI Frequency Sink</name> - <key>qtgui_freq_sink_x</key> - <import>from PyQt4 import Qt</import> - <import>from gnuradio import qtgui</import> - <import>from gnuradio.filter import firdes</import> - <import>import sip</import> - <make>#set $win = 'self._%s_win'%$id + <name>QT GUI Frequency Sink</name> + <key>qtgui_freq_sink_x</key> + <import>from PyQt4 import Qt</import> + <import>from gnuradio import qtgui</import> + <import>from gnuradio.filter import firdes</import> + <import>import sip</import> + <make>#set $win = 'self._%s_win'%$id qtgui.$(type.fcn)( $fftsize, \#size $wintype, \#wintype @@ -22,26 +22,53 @@ qtgui.$(type.fcn)( ) self.$(id).set_update_time($update_time) self.$(id).set_y_axis($ymin, $ymax) +self.$(id).enable_autoscale($autoscale) +self.$(id).set_fft_average($average) + +labels = [$label1, $label2, $label3, $label4, $label5, + $label6, $label7, $label8, $label9, $label10] +widths = [$width1, $width2, $width3, $width4, $width5, + $width6, $width7, $width8, $width9, $width10] +colors = [$color1, $color2, $color3, $color4, $color5, + $color6, $color7, $color8, $color9, $color10] +alphas = [$alpha1, $alpha2, $alpha3, $alpha4, $alpha5, + $alpha6, $alpha7, $alpha8, $alpha9, $alpha10] +for i in xrange($nconnections): + if len(labels[i]) == 0: + self.$(id).set_line_label(i, "Data {0}".format(i)) + else: + self.$(id).set_line_label(i, labels[i]) + self.$(id).set_line_width(i, widths[i]) + self.$(id).set_line_color(i, colors[i]) + self.$(id).set_line_alpha(i, alphas[i]) + self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) $(gui_hint()($win))</make> - <callback>set_frequency_range($fc, $bw)</callback> - <callback>set_update_time($update_time)</callback> - <callback>set_title($which, $title)</callback> - <callback>set_color($which, $color)</callback> - <param> - <name>Type</name> - <key>type</key> - <value>complex</value> - <type>enum</type> - <option><name>Complex</name><key>complex</key><opt>fcn:freq_sink_c</opt></option> - <option><name>Float</name><key>float</key><opt>fcn:freq_sink_f</opt></option> - </param> - <param> - <name>Name</name> - <key>name</key> - <value>QT GUI Plot</value> - <type>string</type> - </param> + <callback>set_frequency_range($fc, $bw)</callback> + <callback>set_update_time($update_time)</callback> + <callback>set_title($which, $title)</callback> + <callback>set_color($which, $color)</callback> + + <param_tab_order> + <tab>General</tab> + <tab>Config</tab> + </param_tab_order> + + <param> + <name>Type</name> + <key>type</key> + <value>complex</value> + <type>enum</type> + <option><name>Complex</name><key>complex</key><opt>fcn:freq_sink_c</opt></option> + <option><name>Float</name><key>float</key><opt>fcn:freq_sink_f</opt></option> + </param> + <param> + <name>Name</name> + <key>name</key> + <value>QT GUI Plot</value> + <type>string</type> + </param> + <param> <name>FFT Size</name> <key>fftsize</key> @@ -52,7 +79,7 @@ $(gui_hint()($win))</make> <name>Window Type</name> <key>wintype</key> <value>firdes.WIN_BLACKMAN_hARRIS</value> - <type>int</type> + <type>enum</type> <hide>part</hide> <option> <name>Blackman-harris</name> @@ -95,49 +122,437 @@ $(gui_hint()($win))</make> <value>samp_rate</value> <type>real</type> </param> - <param> - <name>Y min</name> - <key>ymin</key> - <value>-140</value> - <type>real</type> - <hide>part</hide> - </param> - <param> - <name>Y max</name> - <key>ymax</key> - <value>10</value> - <type>real</type> - <hide>part</hide> - </param> - <param> - <name>Number of Inputs</name> - <key>nconnections</key> - <value>1</value> - <type>int</type> - <hide>part</hide> - </param> - <param> - <name>Update Period</name> - <key>update_time</key> - <value>0.10</value> - <type>real</type> - <hide>part</hide> - </param> - <param> - <name>GUI Hint</name> - <key>gui_hint</key> - <value></value> - <type>gui_hint</type> - <hide>part</hide> - </param> - <sink> - <name>in</name> - <type>$type</type> - <nports>$nconnections</nports> - </sink> - <doc> + + <param> + <name>Autoscale</name> + <key>autoscale</key> + <value>False</value> + <type>enum</type> + <hide>part</hide> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + + <param> + <name>Average</name> + <key>average</key> + <value>False</value> + <type>enum</type> + <hide>part</hide> + <option> + <name>None</name> + <key>1.0</key> + </option> + <option> + <name>Low</name> + <key>0.2</key> + </option> + <option> + <name>Medium</name> + <key>0.1</key> + </option> + <option> + <name>High</name> + <key>0.05</key> + </option> + </param> + + <param> + <name>Y min</name> + <key>ymin</key> + <value>-140</value> + <type>real</type> + <hide>part</hide> + </param> + <param> + <name>Y max</name> + <key>ymax</key> + <value>10</value> + <type>real</type> + <hide>part</hide> + </param> + <param> + <name>Number of Inputs</name> + <key>nconnections</key> + <value>1</value> + <type>int</type> + <hide>part</hide> + </param> + <param> + <name>Update Period</name> + <key>update_time</key> + <value>0.10</value> + <type>real</type> + <hide>part</hide> + </param> + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + + + <param> + <name>Line 1 Label</name> + <key>label1</key> + <type>string</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Width</name> + <key>width1</key> + <value>1</value> + <type>int</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Color</name> + <key>color1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Blue</name> + <key>"blue"</key> + </option> + <option> + <name>Red</name> + <key>"red"</key> + </option> + <option> + <name>Green</name> + <key>"green"</key> + </option> + <option> + <name>Black</name> + <key>"black"</key> + </option> + <option> + <name>Cyan</name> + <key>"cyan"</key> + </option> + <option> + <name>Magenta</name> + <key>"magenta"</key> + </option> + <option> + <name>Yellow</name> + <key>"yellow"</key> + </option> + <option> + <name>Dark Red</name> + <key>"dark red"</key> + </option> + <option> + <name>Dark Green</name> + <key>"dark green"</key> + </option> + <option> + <name>Dark Blue</name> + <key>"dark blue"</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Alpha</name> + <key>alpha1</key> + <value>1.0</value> + <type>float</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 2 Label</name> + <key>label2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 2 Width</name> + <key>width2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 2 Color</name> + <key>color2</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 2 Alpha</name> + <key>alpha2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 3 Label</name> + <key>label3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 3 Width</name> + <key>width3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 3 Color</name> + <key>color3</key> + <value>"green"</value> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 3 Alpha</name> + <key>alpha3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 4 Label</name> + <key>label4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 4 Width</name> + <key>width4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 4 Color</name> + <key>color4</key> + <value>"black"</value> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 4 Alpha</name> + <key>alpha4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 5 Label</name> + <key>label5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 5 Width</name> + <key>width5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 5 Color</name> + <key>color5</key> + <value>"cyan"</value> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 5 Alpha</name> + <key>alpha5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 6 Label</name> + <key>label6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 6 Width</name> + <key>width6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 6 Color</name> + <key>color6</key> + <value>"magenta"</value> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 6 Alpha</name> + <key>alpha6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 7 Label</name> + <key>label7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 7 Width</name> + <key>width7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 7 Color</name> + <key>color7</key> + <value>"yellow"</value> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 7 Alpha</name> + <key>alpha7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 8 Label</name> + <key>label8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 8 Width</name> + <key>width8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 8 Color</name> + <key>color8</key> + <value>"dark red"</value> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 8 Alpha</name> + <key>alpha8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 9 Label</name> + <key>label9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 9 Width</name> + <key>width9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 9 Color</name> + <key>color9</key> + <value>"dark green"</value> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 9 Alpha</name> + <key>alpha9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 10 Label</name> + <key>label10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 10 Width</name> + <key>width10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 10 Color</name> + <key>color10</key> + <value>"dark blue"</value> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 10 Alpha</name> + <key>alpha10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + + <sink> + <name>in</name> + <type>$type</type> + <nports>$nconnections</nports> + </sink> + <doc> The GUI hint can be used to position the widget within the application. \ The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \ Both the tab specification and the grid position are optional. - </doc> + </doc> </block> diff --git a/gr-qtgui/grc/qtgui_histogram_sink_x.xml b/gr-qtgui/grc/qtgui_histogram_sink_x.xml index 8a810abab7..254089181b 100644 --- a/gr-qtgui/grc/qtgui_histogram_sink_x.xml +++ b/gr-qtgui/grc/qtgui_histogram_sink_x.xml @@ -19,14 +19,48 @@ qtgui.histogram_sink_f( $name, $nconnections ) + self.$(id).set_update_time($update_time) +self.$(id).enable_autoscale($autoscale) +self.$(id).enable_accumulate($accum) + +labels = [$label1, $label2, $label3, $label4, $label5, + $label6, $label7, $label8, $label9, $label10] +widths = [$width1, $width2, $width3, $width4, $width5, + $width6, $width7, $width8, $width9, $width10] +colors = [$color1, $color2, $color3, $color4, $color5, + $color6, $color7, $color8, $color9, $color10] +styles = [$style1, $style2, $style3, $style4, $style5, + $style6, $style7, $style8, $style9, $style10] +markers = [$marker1, $marker2, $marker3, $marker4, $marker5, + $marker6, $marker7, $marker8, $marker9, $marker10] +alphas = [$alpha1, $alpha2, $alpha3, $alpha4, $alpha5, + $alpha6, $alpha7, $alpha8, $alpha9, $alpha10] +for i in xrange($nconnections): + if len(labels[i]) == 0: + self.$(id).set_line_label(i, "Data {0}".format(i)) + else: + self.$(id).set_line_label(i, labels[i]) + self.$(id).set_line_width(i, widths[i]) + self.$(id).set_line_color(i, colors[i]) + self.$(id).set_line_style(i, styles[i]) + self.$(id).set_line_marker(i, markers[i]) + self.$(id).set_line_alpha(i, alphas[i]) + self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) $(gui_hint()($win))</make> <callback>set_update_time($update_time)</callback> <callback>set_title($which, $title)</callback> <callback>set_color($which, $color)</callback> <callback>set_bins($bins)</callback> - <callback>set_x_axis($bins)</callback> + <callback>set_bins($bins)</callback> + <callback>set_x_axis($xmin, $xmax)</callback> + + <param_tab_order> + <tab>General</tab> + <tab>Config</tab> + </param_tab_order> + <param> <name>Name</name> <key>name</key> @@ -45,6 +79,37 @@ $(gui_hint()($win))</make> <value>100</value> <type>int</type> </param> + + <param> + <name>Autoscale</name> + <key>autoscale</key> + <value>True</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + + <param> + <name>Accumulate</name> + <key>accum</key> + <value>False</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> <name>Min x-axis</name> <key>xmin</key> @@ -78,14 +143,569 @@ $(gui_hint()($win))</make> <type>gui_hint</type> <hide>part</hide> </param> - <sink> - <name>in</name> - <type>float</type> - <nports>$nconnections</nports> - </sink> - <doc> + + + <param> + <name>Line 1 Label</name> + <key>label1</key> + <type>string</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Width</name> + <key>width1</key> + <value>1</value> + <type>int</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Color</name> + <key>color1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Blue</name> + <key>"blue"</key> + </option> + <option> + <name>Red</name> + <key>"red"</key> + </option> + <option> + <name>Green</name> + <key>"green"</key> + </option> + <option> + <name>Black</name> + <key>"black"</key> + </option> + <option> + <name>Cyan</name> + <key>"cyan"</key> + </option> + <option> + <name>Magenta</name> + <key>"magenta"</key> + </option> + <option> + <name>Yellow</name> + <key>"yellow"</key> + </option> + <option> + <name>Dark Red</name> + <key>"dark red"</key> + </option> + <option> + <name>Dark Green</name> + <key>"dark green"</key> + </option> + <option> + <name>Dark Blue</name> + <key>"dark blue"</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Style</name> + <key>style1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Solid</name> + <key>1</key> + </option> + <option> + <name>Dash</name> + <key>2</key> + </option> + <option> + <name>Dots</name> + <key>3</key> + </option> + <option> + <name>Dash-Dot</name> + <key>4</key> + </option> + <option> + <name>Dash-Dot-Dot</name> + <key>5</key> + </option> + <option> + <name>None</name> + <key>0</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Marker</name> + <key>marker1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>None</name> + <key>-1</key> + </option> + <option> + <name>Circle</name> + <key>0</key> + </option> + <option> + <name>Rectangle</name> + <key>1</key> + </option> + <option> + <name>Diamond</name> + <key>2</key> + </option> + <option> + <name>Triangle</name> + <key>3</key> + </option> + <option> + <name>Down Triangle</name> + <key>4</key> + </option> + <option> + <name>Left Triangle</name> + <key>6</key> + </option> + <option> + <name>Right Triangle</name> + <key>7</key> + </option> + <option> + <name>Cross</name> + <key>8</key> + </option> + <option> + <name>X-Cross</name> + <key>9</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Alpha</name> + <key>alpha1</key> + <value>1.0</value> + <type>float</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 2 Label</name> + <key>label2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 2 Width</name> + <key>width2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 2 Color</name> + <key>color2</key> + <value>"red"</value> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 2 Style</name> + <key>style2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 2 Marker</name> + <key>marker2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 2 Alpha</name> + <key>alpha2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 3 Label</name> + <key>label3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 3 Width</name> + <key>width3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 3 Color</name> + <key>color3</key> + <value>"green"</value> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 3 Style</name> + <key>style3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 3 Marker</name> + <key>marker3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 3 Alpha</name> + <key>alpha3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 4 Label</name> + <key>label4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 4 Width</name> + <key>width4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 4 Color</name> + <key>color4</key> + <value>"black"</value> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 4 Style</name> + <key>style4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 4 Marker</name> + <key>marker4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 4 Alpha</name> + <key>alpha4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 5 Label</name> + <key>label5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 5 Width</name> + <key>width5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 5 Color</name> + <key>color5</key> + <value>"cyan"</value> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 5 Style</name> + <key>style5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 5 Marker</name> + <key>marker5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 5 Alpha</name> + <key>alpha5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 6 Label</name> + <key>label6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 6 Width</name> + <key>width6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 6 Color</name> + <key>color6</key> + <value>"magenta"</value> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 6 Style</name> + <key>style6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 6 Marker</name> + <key>marker6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 6 Alpha</name> + <key>alpha6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 7 Label</name> + <key>label7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 7 Width</name> + <key>width7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 7 Color</name> + <key>color7</key> + <value>"yellow"</value> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 7 Style</name> + <key>style7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 7 Marker</name> + <key>marker7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 7 Alpha</name> + <key>alpha7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 8 Label</name> + <key>label8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 8 Width</name> + <key>width8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 8 Color</name> + <key>color8</key> + <value>"dark red"</value> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 8 Style</name> + <key>style8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 8 Marker</name> + <key>marker8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 8 Alpha</name> + <key>alpha8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 9 Label</name> + <key>label9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 9 Width</name> + <key>width9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 9 Color</name> + <key>color9</key> + <value>"dark green"</value> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 9 Style</name> + <key>style9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 9 Marker</name> + <key>marker9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 9 Alpha</name> + <key>alpha9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 10 Label</name> + <key>label10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 10 Width</name> + <key>width10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 10 Color</name> + <key>color10</key> + <value>"dark blue"</value> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 10 Style</name> + <key>style10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 10 Marker</name> + <key>marker10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 10 Alpha</name> + <key>alpha10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + + + + <sink> + <name>in</name> + <type>float</type> + <nports>$nconnections</nports> + </sink> + <doc> The GUI hint can be used to position the widget within the application. \ The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \ Both the tab specification and the grid position are optional. - </doc> + </doc> </block> diff --git a/gr-qtgui/grc/qtgui_number_sink.xml b/gr-qtgui/grc/qtgui_number_sink.xml new file mode 100644 index 0000000000..af74bca0bf --- /dev/null +++ b/gr-qtgui/grc/qtgui_number_sink.xml @@ -0,0 +1,338 @@ +<?xml version="1.0"?> +<!-- +################################################### +##QT GUI Number Sink +################################################### + --> +<block> + <name>QT GUI Number Sink</name> + <key>qtgui_number_sink</key> + <import>from PyQt4 import Qt</import> + <import>from gnuradio import qtgui</import> + <import>import sip</import> + <make>#set $win = 'self._%s_win'%$id +qtgui.number_sink( + $type.size, + $avg, + $graph_type, + $nconnections +) +self.$(id).set_update_time($update_time) + +labels = [$label1, $label2, $label3, $label4, $label5, + $label6, $label7, $label8, $label9, $label10] +colors = [$color1, $color2, $color3, $color4, $color5, + $color6, $color7, $color8, $color9, $color10] +for i in xrange($nconnections): + self.$(id).set_min(i, $min) + self.$(id).set_max(i, $max) + self.$(id).set_color(i, colors[i][0], colors[i][1]) + if len(labels[i]) == 0: + self.$(id).set_label(i, "Data {0}".format(i)) + else: + self.$(id).set_label(i, labels[i]) + +self.$(id).enable_autoscale($autoscale) +self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) +$(gui_hint()($win))</make> + <callback>set_update_time($update_time)</callback> + + <param_tab_order> + <tab>General</tab> + <tab>Config</tab> + </param_tab_order> + + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + <tab>General</tab> + </param> + + <param> + <name>Autoscale</name> + <key>autoscale</key> + <value>False</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + + <param> + <name>Average</name> + <key>avg</key> + <value>0</value> + <type>float</type> + <tab>General</tab> + </param> + + <param> + <name>Graph Type</name> + <key>graph_type</key> + <type>enum</type> + <option> + <name>Horizontal</name> + <key>qtgui.NUM_GRAPH_HORIZ</key> + </option> + <option> + <name>Verticle</name> + <key>qtgui.NUM_GRAPH_VERT</key> + </option> + <option> + <name>None</name> + <key>qtgui.NUM_GRAPH_NONE</key> + </option> + <tab>General</tab> + </param> + + <param> + <name>Number of Inputs</name> + <key>nconnections</key> + <value>1</value> + <type>int</type> + <hide>part</hide> + <tab>General</tab> + </param> + + <param> + <name>Min</name> + <key>min</key> + <value>-1</value> + <type>float</type> + <hide>part</hide> + </param> + <param> + <name>max</name> + <key>max</key> + <value>1</value> + <type>float</type> + <hide>part</hide> + </param> + + <param> + <name>Update Period</name> + <key>update_time</key> + <value>0.10</value> + <type>float</type> + <hide>part</hide> + <tab>General</tab> + </param> + + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + <tab>General</tab> + </param> + + <param> + <name>Line 1 Label</name> + <key>label1</key> + <type>string</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Color</name> + <key>color1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Black</name> + <key>("black", "black")</key> + </option> + <option> + <name>Blue-Red</name> + <key>("blue", "red")</key> + </option> + <option> + <name>White Hot</name> + <key>("black", "white")</key> + </option> + <option> + <name>Black Hot</name> + <key>("white", "black")</key> + </option> + <option> + <name>Black-Red</name> + <key>("black", "red")</key> + </option> + <tab>Config</tab> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 2 Label</name> + <key>label2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 2 Color</name> + <key>color2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 3 Label</name> + <key>label3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 3 Color</name> + <key>color3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 4 Label</name> + <key>label4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 4 Color</name> + <key>color4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 5 Label</name> + <key>label5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 5 Color</name> + <key>color5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 6 Label</name> + <key>label6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 6 Color</name> + <key>color6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 7 Label</name> + <key>label7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 7 Color</name> + <key>color7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 8 Label</name> + <key>label8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 8 Color</name> + <key>color8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 9 Label</name> + <key>label9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 9 Color</name> + <key>color9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 10 Label</name> + <key>label10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 10 Color</name> + <key>color10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + + <sink> + <name>in</name> + <type>$type</type> + <nports>$nconnections</nports> + </sink> + <doc> + The GUI hint can be used to position the widget within the application. \ + The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \ + Both the tab specification and the grid position are optional. + </doc> +</block> diff --git a/gr-qtgui/grc/qtgui_time_raster_x.xml b/gr-qtgui/grc/qtgui_time_raster_x.xml index 7d880ab084..db13ce5f6a 100644 --- a/gr-qtgui/grc/qtgui_time_raster_x.xml +++ b/gr-qtgui/grc/qtgui_time_raster_x.xml @@ -20,7 +20,23 @@ qtgui.$(type.fcn)( $name, $nconnections, ) + self.$(id).set_update_time($update_time) + +labels = [$label1, $label2, $label3, $label4, $label5, + $label6, $label7, $label8, $label9, $label10] +colors = [$color1, $color2, $color3, $color4, $color5, + $color6, $color7, $color8, $color9, $color10] +alphas = [$alpha1, $alpha2, $alpha3, $alpha4, $alpha5, + $alpha6, $alpha7, $alpha8, $alpha9, $alpha10] +for i in xrange($nconnections): + if len(labels[i]) == 0: + self.$(id).set_line_label(i, "Data {0}".format(i)) + else: + self.$(id).set_line_label(i, labels[i]) + self.$(id).set_color_map(i, colors[i]) + self.$(id).set_line_alpha(i, alphas[i]) + self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) $(gui_hint()($win))</make> <callback>set_num_rows($nrows)</callback> @@ -30,6 +46,12 @@ $(gui_hint()($win))</make> <callback>set_update_time($update_time)</callback> <callback>set_title($which, $title)</callback> <callback>set_color($which, $color)</callback> + + <param_tab_order> + <tab>General</tab> + <tab>Config</tab> + </param_tab_order> + <param> <name>Type</name> <key>type</key> @@ -95,14 +117,256 @@ $(gui_hint()($win))</make> <type>gui_hint</type> <hide>part</hide> </param> - <sink> - <name>in</name> - <type>$type</type> - <nports>$nconnections</nports> - </sink> - <doc> + + + <param> + <name>Line 1 Label</name> + <key>label1</key> + <type>string</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Color</name> + <key>color1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Multi Color</name> + <key>0</key> + </option> + <option> + <name>White Hot</name> + <key>1</key> + </option> + <option> + <name>Black Hot</name> + <key>2</key> + </option> + <option> + <name>Incandescent</name> + <key>3</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Alpha</name> + <key>alpha1</key> + <value>1.0</value> + <type>float</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 2 Label</name> + <key>label2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 2 Color</name> + <key>color2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 2 Alpha</name> + <key>alpha2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 3 Label</name> + <key>label3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 3 Color</name> + <key>color3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 3 Alpha</name> + <key>alpha3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 4 Label</name> + <key>label4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 4 Color</name> + <key>color4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 4 Alpha</name> + <key>alpha4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 5 Label</name> + <key>label5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 5 Color</name> + <key>color5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 5 Alpha</name> + <key>alpha5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 6 Label</name> + <key>label6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 6 Color</name> + <key>color6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 6 Alpha</name> + <key>alpha6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 7 Label</name> + <key>label7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 7 Color</name> + <key>color7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 7 Alpha</name> + <key>alpha7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 8 Label</name> + <key>label8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 8 Color</name> + <key>color8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 8 Alpha</name> + <key>alpha8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 9 Label</name> + <key>label9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 9 Color</name> + <key>color9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 9 Alpha</name> + <key>alpha9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 10 Label</name> + <key>label10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 10 Color</name> + <key>color10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 10 Alpha</name> + <key>alpha10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + + <sink> + <name>in</name> + <type>$type</type> + <nports>$nconnections</nports> + </sink> + <doc> The GUI hint can be used to position the widget within the application. \ The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \ Both the tab specification and the grid position are optional. - </doc> + </doc> </block> diff --git a/gr-qtgui/grc/qtgui_time_sink_x.xml b/gr-qtgui/grc/qtgui_time_sink_x.xml index 3da87a9d29..172da7a02d 100644 --- a/gr-qtgui/grc/qtgui_time_sink_x.xml +++ b/gr-qtgui/grc/qtgui_time_sink_x.xml @@ -5,13 +5,13 @@ ################################################### --> <block> - <name>QT GUI Time Sink</name> - <key>qtgui_time_sink_x</key> - <import>from PyQt4 import Qt</import> - <import>from gnuradio import qtgui</import> - <import>from gnuradio.filter import firdes</import> - <import>import sip</import> - <make>#set $win = 'self._%s_win'%$id + <name>QT GUI Time Sink</name> + <key>qtgui_time_sink_x</key> + <import>from PyQt4 import Qt</import> + <import>from gnuradio import qtgui</import> + <import>from gnuradio.filter import firdes</import> + <import>import sip</import> + <make>#set $win = 'self._%s_win'%$id qtgui.$(type.fcn)( $size, \#size $srate, \#samp_rate @@ -22,174 +22,799 @@ self.$(id).set_update_time($update_time) self.$(id).set_y_axis($ymin, $ymax) self.$(id).enable_tags(-1, $entags) self.$(id).set_trigger_mode($tr_mode, $tr_slope, $tr_level, $tr_delay, $tr_chan, $tr_tag) +self.$(id).enable_autoscale($autoscale) + +labels = [$label1, $label2, $label3, $label4, $label5, + $label6, $label7, $label8, $label9, $label10] +widths = [$width1, $width2, $width3, $width4, $width5, + $width6, $width7, $width8, $width9, $width10] +colors = [$color1, $color2, $color3, $color4, $color5, + $color6, $color7, $color8, $color9, $color10] +styles = [$style1, $style2, $style3, $style4, $style5, + $style6, $style7, $style8, $style9, $style10] +markers = [$marker1, $marker2, $marker3, $marker4, $marker5, + $marker6, $marker7, $marker8, $marker9, $marker10] +alphas = [$alpha1, $alpha2, $alpha3, $alpha4, $alpha5, + $alpha6, $alpha7, $alpha8, $alpha9, $alpha10] + +#if($type() == "complex") +for i in xrange(2*$nconnections): + if len(labels[i]) == 0: + if(i % 2 == 0): + self.$(id).set_line_label(i, "Re{{Data {0}}}".format(i/2)) + else: + self.$(id).set_line_label(i, "Im{{Data {0}}}".format(i/2)) + else: + self.$(id).set_line_label(i, labels[i]) + self.$(id).set_line_width(i, widths[i]) + self.$(id).set_line_color(i, colors[i]) + self.$(id).set_line_style(i, styles[i]) + self.$(id).set_line_marker(i, markers[i]) + self.$(id).set_line_alpha(i, alphas[i]) +#else +for i in xrange($nconnections): + if len(labels[i]) == 0: + self.$(id).set_line_label(i, "Data {0}".format(i)) + else: + self.$(id).set_line_label(i, labels[i]) + self.$(id).set_line_width(i, widths[i]) + self.$(id).set_line_color(i, colors[i]) + self.$(id).set_line_style(i, styles[i]) + self.$(id).set_line_marker(i, markers[i]) + self.$(id).set_line_alpha(i, alphas[i]) +#end if + self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) $(gui_hint()($win))</make> - <callback>set_time_domain_axis($min, $max)</callback> - <callback>set_update_time($update_time)</callback> - <callback>set_title($which, $title)</callback> - <callback>set_color($which, $color)</callback> - <callback>set_y_axis($ymin, $ymax)</callback> - <callback>set_samp_rate($srate)</callback> - <param> - <name>Type</name> - <key>type</key> - <value>complex</value> - <type>enum</type> - <option><name>Complex</name><key>complex</key><opt>fcn:time_sink_c</opt></option> - <option><name>Float</name><key>float</key><opt>fcn:time_sink_f</opt></option> - </param> - <param> - <name>Name</name> - <key>name</key> - <value>QT GUI Plot</value> - <type>string</type> - </param> - <param> - <name>Number of Points</name> - <key>size</key> - <value>1024</value> - <type>int</type> - </param> - <param> - <name>Sample Rate</name> - <key>srate</key> - <value>samp_rate</value> - <type>float</type> - </param> - <param> - <name>Y min</name> - <key>ymin</key> - <value>-1</value> - <type>float</type> - <hide>part</hide> - </param> - <param> - <name>Y max</name> - <key>ymax</key> - <value>1</value> - <type>float</type> - <hide>part</hide> - </param> - <param> - <name>Number of Inputs</name> - <key>nconnections</key> - <value>1</value> - <type>int</type> - <hide>part</hide> - </param> - <param> - <name>Update Period</name> - <key>update_time</key> - <value>0.10</value> - <type>float</type> - <hide>part</hide> - </param> - - <param> - <name>Trigger Mode</name> - <key>tr_mode</key> - <value>qtgui.TRIG_MODE_FREE</value> - <type>enum</type> - <hide>part</hide> - <option> - <name>Free</name> - <key>qtgui.TRIG_MODE_FREE</key> - </option> - <option> - <name>Auto</name> - <key>qtgui.TRIG_MODE_AUTO</key> - </option> - <option> - <name>Normal</name> - <key>qtgui.TRIG_MODE_NORM</key> - </option> - <option> - <name>Tag</name> - <key>qtgui.TRIG_MODE_TAG</key> - </option> - </param> - - <param> - <name>Trigger Slope</name> - <key>tr_slope</key> - <value>qtgui.TRIG_MODE_POS</value> - <type>enum</type> - <hide>part</hide> - <option> - <name>Positive</name> - <key>qtgui.TRIG_SLOPE_POS</key> - </option> - <option> - <name>Negative</name> - <key>qtgui.TRIG_SLOPE_NEG</key> - </option> - </param> - - <param> - <name>Trigger Level</name> - <key>tr_level</key> - <value>0.0</value> - <type>float</type> - <hide>part</hide> - </param> - - <param> - <name>Trigger Delay</name> - <key>tr_delay</key> - <value>0</value> - <type>float</type> - <hide>part</hide> - </param> - - <param> - <name>Trigger Channel</name> - <key>tr_chan</key> - <value>0</value> - <type>int</type> - <hide>part</hide> - </param> - - <param> - <name>Trigger Tag Key</name> - <key>tr_tag</key> - <value>""</value> - <type>string</type> - <hide>part</hide> - </param> - - <param> - <name>Disp. Tags</name> - <key>entags</key> - <value>True</value> - <type>enum</type> - <hide>part</hide> - <option> - <name>Yes</name> - <key>True</key> - </option> - <option> - <name>No</name> - <key>False</key> - </option> - </param> - <param> - <name>GUI Hint</name> - <key>gui_hint</key> - <value></value> - <type>gui_hint</type> - <hide>part</hide> - </param> - - <check>$tr_chan < 2*$nconnections</check> - - <sink> - <name>in</name> - <type>$type</type> - <nports>$nconnections</nports> - </sink> - <doc> + <callback>set_time_domain_axis($min, $max)</callback> + <callback>set_update_time($update_time)</callback> + <callback>set_title($which, $title)</callback> + <callback>set_color($which, $color)</callback> + <callback>set_y_axis($ymin, $ymax)</callback> + <callback>set_samp_rate($srate)</callback> + + <param_tab_order> + <tab>General</tab> + <tab>Trigger</tab> + <tab>Config</tab> + </param_tab_order> + + <param> + <name>Type</name> + <key>type</key> + <value>complex</value> + <type>enum</type> + <option><name>Complex</name><key>complex</key><opt>fcn:time_sink_c</opt></option> + <option><name>Float</name><key>float</key><opt>fcn:time_sink_f</opt></option> + </param> + <param> + <name>Name</name> + <key>name</key> + <value>QT GUI Plot</value> + <type>string</type> + </param> + <param> + <name>Number of Points</name> + <key>size</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Sample Rate</name> + <key>srate</key> + <value>samp_rate</value> + <type>float</type> + </param> + + <param> + <name>Autoscale</name> + <key>autoscale</key> + <value>False</value> + <type>enum</type> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + + <param> + <name>Y min</name> + <key>ymin</key> + <value>-1</value> + <type>float</type> + <hide>part</hide> + </param> + <param> + <name>Y max</name> + <key>ymax</key> + <value>1</value> + <type>float</type> + <hide>part</hide> + </param> + <param> + <name>Number of Inputs</name> + <key>nconnections</key> + <value>1</value> + <type>int</type> + <hide>part</hide> + </param> + <param> + <name>Update Period</name> + <key>update_time</key> + <value>0.10</value> + <type>float</type> + <hide>part</hide> + </param> + <param> + <name>Disp. Tags</name> + <key>entags</key> + <value>True</value> + <type>enum</type> + <hide>part</hide> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> + <name>GUI Hint</name> + <key>gui_hint</key> + <value></value> + <type>gui_hint</type> + <hide>part</hide> + </param> + + + <param> + <name>Trigger Mode</name> + <key>tr_mode</key> + <value>qtgui.TRIG_MODE_FREE</value> + <type>enum</type> + <hide>part</hide> + <option> + <name>Free</name> + <key>qtgui.TRIG_MODE_FREE</key> + </option> + <option> + <name>Auto</name> + <key>qtgui.TRIG_MODE_AUTO</key> + </option> + <option> + <name>Normal</name> + <key>qtgui.TRIG_MODE_NORM</key> + </option> + <option> + <name>Tag</name> + <key>qtgui.TRIG_MODE_TAG</key> + </option> + <tab>Trigger</tab> + </param> + + <param> + <name>Trigger Slope</name> + <key>tr_slope</key> + <value>qtgui.TRIG_MODE_POS</value> + <type>enum</type> + <hide>part</hide> + <option> + <name>Positive</name> + <key>qtgui.TRIG_SLOPE_POS</key> + </option> + <option> + <name>Negative</name> + <key>qtgui.TRIG_SLOPE_NEG</key> + </option> + <tab>Trigger</tab> + </param> + + <param> + <name>Trigger Level</name> + <key>tr_level</key> + <value>0.0</value> + <type>float</type> + <hide>part</hide> + <tab>Trigger</tab> + </param> + + <param> + <name>Trigger Delay</name> + <key>tr_delay</key> + <value>0</value> + <type>float</type> + <hide>part</hide> + <tab>Trigger</tab> + </param> + + <param> + <name>Trigger Channel</name> + <key>tr_chan</key> + <value>0</value> + <type>int</type> + <hide>part</hide> + <tab>Trigger</tab> + </param> + + <param> + <name>Trigger Tag Key</name> + <key>tr_tag</key> + <value>""</value> + <type>string</type> + <hide>part</hide> + <tab>Trigger</tab> + </param> + + + + <param> + <name>Line 1 Label</name> + <key>label1</key> + <type>string</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Width</name> + <key>width1</key> + <value>1</value> + <type>int</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Color</name> + <key>color1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Blue</name> + <key>"blue"</key> + </option> + <option> + <name>Red</name> + <key>"red"</key> + </option> + <option> + <name>Green</name> + <key>"green"</key> + </option> + <option> + <name>Black</name> + <key>"black"</key> + </option> + <option> + <name>Cyan</name> + <key>"cyan"</key> + </option> + <option> + <name>Magenta</name> + <key>"magenta"</key> + </option> + <option> + <name>Yellow</name> + <key>"yellow"</key> + </option> + <option> + <name>Dark Red</name> + <key>"dark red"</key> + </option> + <option> + <name>Dark Green</name> + <key>"dark green"</key> + </option> + <option> + <name>Dark Blue</name> + <key>"Dark Blue"</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Style</name> + <key>style1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Solid</name> + <key>1</key> + </option> + <option> + <name>Dash</name> + <key>2</key> + </option> + <option> + <name>Dots</name> + <key>3</key> + </option> + <option> + <name>Dash-Dot</name> + <key>4</key> + </option> + <option> + <name>Dash-Dot-Dot</name> + <key>5</key> + </option> + <option> + <name>None</name> + <key>0</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Marker</name> + <key>marker1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>None</name> + <key>-1</key> + </option> + <option> + <name>Circle</name> + <key>0</key> + </option> + <option> + <name>Rectangle</name> + <key>1</key> + </option> + <option> + <name>Diamond</name> + <key>2</key> + </option> + <option> + <name>Triangle</name> + <key>3</key> + </option> + <option> + <name>Down Triangle</name> + <key>4</key> + </option> + <option> + <name>Left Triangle</name> + <key>6</key> + </option> + <option> + <name>Right Triangle</name> + <key>7</key> + </option> + <option> + <name>Cross</name> + <key>8</key> + </option> + <option> + <name>X-Cross</name> + <key>9</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Alpha</name> + <key>alpha1</key> + <value>1.0</value> + <type>float</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + + + <param> + <base_key>label1</base_key> + <name>Line 2 Label</name> + <key>label2</key> + <hide>#if (int($nconnections()) >= 2 or ($type() == "complex" and int($nconnections()) >= 1)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 2 Width</name> + <key>width2</key> + <hide>#if (int($nconnections()) >= 2 or ($type() == "complex" and int($nconnections()) >= 1)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 2 Color</name> + <key>color2</key> + <value>"red"</value> + <hide>#if (int($nconnections()) >= 2 or ($type() == "complex" and int($nconnections()) >= 1)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 2 Style</name> + <key>style2</key> + <hide>#if (int($nconnections()) >= 2 or ($type() == "complex" and int($nconnections()) >= 1)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 2 Marker</name> + <key>marker2</key> + <hide>#if (int($nconnections()) >= 2 or ($type() == "complex" and int($nconnections()) >= 1)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 2 Alpha</name> + <key>alpha2</key> + <hide>#if (int($nconnections()) >= 2 or ($type() == "complex" and int($nconnections()) >= 1)) then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 3 Label</name> + <key>label3</key> + <hide>#if (int($nconnections()) >= 3 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 3 Width</name> + <key>width3</key> + <hide>#if (int($nconnections()) >= 3 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 3 Color</name> + <key>color3</key> + <value>"green"</value> + <hide>#if (int($nconnections()) >= 3 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 3 Style</name> + <key>style3</key> + <hide>#if (int($nconnections()) >= 3 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 3 Marker</name> + <key>marker3</key> + <hide>#if (int($nconnections()) >= 3 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 3 Alpha</name> + <key>alpha3</key> + <hide>#if (int($nconnections()) >= 3 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 4 Label</name> + <key>label4</key> + <hide>#if (int($nconnections()) >= 4 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 4 Width</name> + <key>width4</key> + <hide>#if (int($nconnections()) >= 4 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 4 Color</name> + <key>color4</key> + <value>"black"</value> + <hide>#if (int($nconnections()) >= 4 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 4 Style</name> + <key>style4</key> + <hide>#if (int($nconnections()) >= 4 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 4 Marker</name> + <key>marker4</key> + <hide>#if (int($nconnections()) >= 4 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 4 Alpha</name> + <key>alpha4</key> + <hide>#if (int($nconnections()) >= 4 or ($type() == "complex" and int($nconnections()) >= 2)) then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 5 Label</name> + <key>label5</key> + <hide>#if (int($nconnections()) >= 5 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 5 Width</name> + <key>width5</key> + <hide>#if (int($nconnections()) >= 5 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 5 Color</name> + <key>color5</key> + <value>"cyan"</value> + <hide>#if (int($nconnections()) >= 5 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 5 Style</name> + <key>style5</key> + <hide>#if (int($nconnections()) >= 5 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 5 Marker</name> + <key>marker5</key> + <hide>#if (int($nconnections()) >= 5 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 5 Alpha</name> + <key>alpha5</key> + <hide>#if (int($nconnections()) >= 5 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 6 Label</name> + <key>label6</key> + <hide>#if (int($nconnections()) >= 6 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 6 Width</name> + <key>width6</key> + <hide>#if (int($nconnections()) >= 6 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 6 Color</name> + <key>color6</key> + <value>"magenta"</value> + <hide>#if (int($nconnections()) >= 6 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 6 Style</name> + <key>style6</key> + <hide>#if (int($nconnections()) >= 6 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 6 Marker</name> + <key>marker6</key> + <hide>#if (int($nconnections()) >= 6 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 6 Alpha</name> + <key>alpha6</key> + <hide>#if (int($nconnections()) >= 6 or ($type() == "complex" and int($nconnections()) >= 3)) then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 7 Label</name> + <key>label7</key> + <hide>#if (int($nconnections()) >= 7 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 7 Width</name> + <key>width7</key> + <hide>#if (int($nconnections()) >= 7 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 7 Color</name> + <key>color7</key> + <value>"yellow"</value> + <hide>#if (int($nconnections()) >= 7 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 7 Style</name> + <key>style7</key> + <hide>#if (int($nconnections()) >= 7 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 7 Marker</name> + <key>marker7</key> + <hide>#if (int($nconnections()) >= 7 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 7 Alpha</name> + <key>alpha7</key> + <hide>#if (int($nconnections()) >= 7 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 8 Label</name> + <key>label8</key> + <hide>#if (int($nconnections()) >= 8 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 8 Width</name> + <key>width8</key> + <hide>#if (int($nconnections()) >= 8 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 8 Color</name> + <key>color8</key> + <value>"dark red"</value> + <hide>#if (int($nconnections()) >= 8 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 8 Style</name> + <key>style8</key> + <hide>#if (int($nconnections()) >= 8 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 8 Marker</name> + <key>marker8</key> + <hide>#if (int($nconnections()) >= 8 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 8 Alpha</name> + <key>alpha8</key> + <hide>#if (int($nconnections()) >= 8 or ($type() == "complex" and int($nconnections()) >= 4)) then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 9 Label</name> + <key>label9</key> + <hide>#if (int($nconnections()) >= 9 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 9 Width</name> + <key>width9</key> + <hide>#if (int($nconnections()) >= 9 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 9 Color</name> + <key>color9</key> + <value>"dark green"</value> + <hide>#if (int($nconnections()) >= 9 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 9 Style</name> + <key>style9</key> + <hide>#if (int($nconnections()) >= 9 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 9 Marker</name> + <key>marker9</key> + <hide>#if (int($nconnections()) >= 9 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 9 Alpha</name> + <key>alpha9</key> + <hide>#if (int($nconnections()) >= 9 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 10 Label</name> + <key>label10</key> + <hide>#if (int($nconnections()) >= 10 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>width1</base_key> + <name>Line 10 Width</name> + <key>width10</key> + <hide>#if (int($nconnections()) >= 10 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 10 Color</name> + <key>color10</key> + <value>"dark blue"</value> + <hide>#if (int($nconnections()) >= 10 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>style1</base_key> + <name>Line 10 Style</name> + <key>style10</key> + <hide>#if (int($nconnections()) >= 10 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>marker1</base_key> + <name>Line 10 Marker</name> + <key>marker10</key> + <hide>#if (int($nconnections()) >= 10 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 10 Alpha</name> + <key>alpha10</key> + <hide>#if (int($nconnections()) >= 10 or ($type() == "complex" and int($nconnections()) >= 5)) then 'part' else 'all'#</hide> + </param> + + + <check>$tr_chan < 2*$nconnections</check> + + <sink> + <name>in</name> + <type>$type</type> + <nports>$nconnections</nports> + </sink> + <doc> The GUI hint can be used to position the widget within the application. \ The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \ Both the tab specification and the grid position are optional. - </doc> + </doc> </block> diff --git a/gr-qtgui/grc/qtgui_waterfall_sink_x.xml b/gr-qtgui/grc/qtgui_waterfall_sink_x.xml index ac08450730..943aa9d962 100644 --- a/gr-qtgui/grc/qtgui_waterfall_sink_x.xml +++ b/gr-qtgui/grc/qtgui_waterfall_sink_x.xml @@ -5,13 +5,13 @@ ################################################### --> <block> - <name>QT GUI Waterfall Sink</name> - <key>qtgui_waterfall_sink_x</key> - <import>from PyQt4 import Qt</import> - <import>from gnuradio import qtgui</import> - <import>from gnuradio.filter import firdes</import> - <import>import sip</import> - <make>#set $win = 'self._%s_win'%$id + <name>QT GUI Waterfall Sink</name> + <key>qtgui_waterfall_sink_x</key> + <import>from PyQt4 import Qt</import> + <import>from gnuradio import qtgui</import> + <import>from gnuradio.filter import firdes</import> + <import>import sip</import> + <make>#set $win = 'self._%s_win'%$id qtgui.$(type.fcn)( $fftsize, \#size $wintype, \#wintype @@ -21,12 +21,33 @@ qtgui.$(type.fcn)( $nconnections \#number of inputs ) self.$(id).set_update_time($update_time) + +labels = [$label1, $label2, $label3, $label4, $label5, + $label6, $label7, $label8, $label9, $label10] +colors = [$color1, $color2, $color3, $color4, $color5, + $color6, $color7, $color8, $color9, $color10] +alphas = [$alpha1, $alpha2, $alpha3, $alpha4, $alpha5, + $alpha6, $alpha7, $alpha8, $alpha9, $alpha10] +for i in xrange($nconnections): + if len(labels[i]) == 0: + self.$(id).set_line_label(i, "Data {0}".format(i)) + else: + self.$(id).set_line_label(i, labels[i]) + self.$(id).set_color_map(i, colors[i]) + self.$(id).set_line_alpha(i, alphas[i]) + self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget) $(gui_hint()($win))</make> - <callback>set_frequency_range($fc, $bw)</callback> - <callback>set_update_time($update_time)</callback> - <callback>set_title($which, $title)</callback> - <callback>set_color($which, $color)</callback> + <callback>set_frequency_range($fc, $bw)</callback> + <callback>set_update_time($update_time)</callback> + <callback>set_title($which, $title)</callback> + <callback>set_color($which, $color)</callback> + + <param_tab_order> + <tab>General</tab> + <tab>Config</tab> + </param_tab_order> + <param> <name>Type</name> <key>type</key> @@ -115,14 +136,257 @@ $(gui_hint()($win))</make> <type>gui_hint</type> <hide>part</hide> </param> - <sink> - <name>in</name> - <type>$type</type> - <nports>$nconnections</nports> - </sink> - <doc> + + + + <param> + <name>Line 1 Label</name> + <key>label1</key> + <type>string</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Color</name> + <key>color1</key> + <type>enum</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <option> + <name>Multi Color</name> + <key>0</key> + </option> + <option> + <name>White Hot</name> + <key>1</key> + </option> + <option> + <name>Black Hot</name> + <key>2</key> + </option> + <option> + <name>Incandescent</name> + <key>3</key> + </option> + <tab>Config</tab> + </param> + + <param> + <name>Line 1 Alpha</name> + <key>alpha1</key> + <value>1.0</value> + <type>float</type> + <hide>#if int($nconnections()) >= 1 then 'part' else 'all'#</hide> + <tab>Config</tab> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 2 Label</name> + <key>label2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 2 Color</name> + <key>color2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 2 Alpha</name> + <key>alpha2</key> + <hide>#if int($nconnections()) >= 2 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 3 Label</name> + <key>label3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 3 Color</name> + <key>color3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 3 Alpha</name> + <key>alpha3</key> + <hide>#if int($nconnections()) >= 3 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 4 Label</name> + <key>label4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 4 Color</name> + <key>color4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 4 Alpha</name> + <key>alpha4</key> + <hide>#if int($nconnections()) >= 4 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 5 Label</name> + <key>label5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 5 Color</name> + <key>color5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 5 Alpha</name> + <key>alpha5</key> + <hide>#if int($nconnections()) >= 5 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 6 Label</name> + <key>label6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 6 Color</name> + <key>color6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 6 Alpha</name> + <key>alpha6</key> + <hide>#if int($nconnections()) >= 6 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 7 Label</name> + <key>label7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 7 Color</name> + <key>color7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 7 Alpha</name> + <key>alpha7</key> + <hide>#if int($nconnections()) >= 7 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 8 Label</name> + <key>label8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 8 Color</name> + <key>color8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 8 Alpha</name> + <key>alpha8</key> + <hide>#if int($nconnections()) >= 8 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 9 Label</name> + <key>label9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 9 Color</name> + <key>color9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 9 Alpha</name> + <key>alpha9</key> + <hide>#if int($nconnections()) >= 9 then 'part' else 'all'#</hide> + </param> + + + <param> + <base_key>label1</base_key> + <name>Line 10 Label</name> + <key>label10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>color1</base_key> + <name>Line 10 Color</name> + <key>color10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + <param> + <base_key>alpha1</base_key> + <name>Line 10 Alpha</name> + <key>alpha10</key> + <hide>#if int($nconnections()) >= 10 then 'part' else 'all'#</hide> + </param> + + + <sink> + <name>in</name> + <type>$type</type> + <nports>$nconnections</nports> + </sink> + <doc> The GUI hint can be used to position the widget within the application. \ The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \ Both the tab specification and the grid position are optional. - </doc> + </doc> </block> diff --git a/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt b/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt index 3c6309d9c3..bb0d3cf953 100644 --- a/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt +++ b/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt @@ -36,6 +36,9 @@ install(FILES histogram_sink_f.h histogramdisplayform.h HistogramDisplayPlot.h + number_sink.h + numberdisplayform.h + NumberDisplayPlot.h plot_raster.h plot_waterfall.h qtgui_types.h diff --git a/gr-qtgui/include/gnuradio/qtgui/DisplayPlot.h b/gr-qtgui/include/gnuradio/qtgui/DisplayPlot.h index 517f69f603..73c744063b 100644 --- a/gr-qtgui/include/gnuradio/qtgui/DisplayPlot.h +++ b/gr-qtgui/include/gnuradio/qtgui/DisplayPlot.h @@ -50,7 +50,8 @@ Q_DECLARE_METATYPE ( QColorList ) * \brief QWidget base plot to build QTGUI plotting tools. * \ingroup qtgui_blk */ -class DisplayPlot:public QwtPlot{ +class DisplayPlot:public QwtPlot +{ Q_OBJECT Q_PROPERTY ( QColor line_color1 READ getLineColor1 WRITE setLineColor1 ) diff --git a/gr-qtgui/include/gnuradio/qtgui/NumberDisplayPlot.h b/gr-qtgui/include/gnuradio/qtgui/NumberDisplayPlot.h new file mode 100644 index 0000000000..307d806b87 --- /dev/null +++ b/gr-qtgui/include/gnuradio/qtgui/NumberDisplayPlot.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 NUMBER_DISPLAY_PLOT_H +#define NUMBER_DISPLAY_PLOT_H + +#include <stdint.h> +#include <cstdio> +#include <vector> +#include <gnuradio/qtgui/DisplayPlot.h> +#include <gnuradio/tags.h> +#include <qwt_plot.h> + +/*! + * \brief QWidget for displaying number plots. + * \ingroup qtgui_blk + */ +class NumberDisplayPlot: public DisplayPlot +{ + Q_OBJECT + +public: + NumberDisplayPlot(int nplots, QWidget*); + virtual ~NumberDisplayPlot(); + + void plotNewData(const std::vector<double> samples); + + void replot(); + +public slots: + +private: +}; + +#endif /* NUMBER_DISPLAY_PLOT_H */ diff --git a/gr-qtgui/include/gnuradio/qtgui/const_sink_c.h b/gr-qtgui/include/gnuradio/qtgui/const_sink_c.h index 6b305f6e0d..f413ce9b54 100644 --- a/gr-qtgui/include/gnuradio/qtgui/const_sink_c.h +++ b/gr-qtgui/include/gnuradio/qtgui/const_sink_c.h @@ -64,9 +64,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void set_y_axis(double min, double max) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/form_menus.h b/gr-qtgui/include/gnuradio/qtgui/form_menus.h index e7ebc3a797..1b26d289e6 100644 --- a/gr-qtgui/include/gnuradio/qtgui/form_menus.h +++ b/gr-qtgui/include/gnuradio/qtgui/form_menus.h @@ -81,7 +81,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -160,7 +160,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -229,7 +229,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -312,7 +312,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -384,7 +384,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -441,7 +441,7 @@ public: ~LineTitleAction() {} - + signals: void whichTrigger(int which, const QString &text); @@ -453,7 +453,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_which, d_text->text()); d_diag->accept(); } @@ -521,7 +521,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_text->text()); d_diag->accept(); } @@ -548,7 +548,7 @@ public: d_text0 = new QLineEdit(); d_text1 = new QLineEdit(); - + QLabel *_label0 = new QLabel(label0); QLabel *_label1 = new QLabel(label1); @@ -584,7 +584,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_text0->text(), d_text1->text()); d_diag->accept(); } @@ -699,7 +699,7 @@ public slots: //void get13() { emit whichTrigger(8192); } //void get14() { emit whichTrigger(16384); } //void get15() { emit whichTrigger(32768); } - void getOther(const QString &str) + void getOther(const QString &str) { int value = str.toInt(); emit whichTrigger(value); @@ -741,7 +741,7 @@ public: } d_act[0]->setChecked(true); - QDoubleValidator *valid = new QDoubleValidator(0.0, 1.0, 2, this); + QDoubleValidator *valid = new QDoubleValidator(0.0, 1.0, 3, this); ((OtherAction*)d_act[d_act.size()-1])->setValidator(valid); connect(d_act[0], SIGNAL(triggered()), this, SLOT(getOff())); @@ -792,6 +792,21 @@ public: return d_act[static_cast<int>(which)]; } + void setHigh(float x) + { + d_high = x; + } + + void setMedium(float x) + { + d_medium = x; + } + + void setLow(float x) + { + d_low = x; + } + signals: void whichTrigger(float alpha); @@ -800,7 +815,7 @@ public: void getHigh() { emit whichTrigger(d_high); } void getMedium() { emit whichTrigger(d_medium); } void getLow() { emit whichTrigger(d_low); } - void getOther(const QString &str) + void getOther(const QString &str) { float value = str.toFloat(); emit whichTrigger(value); @@ -863,7 +878,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -958,7 +973,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_text->text().toInt()); d_diag->accept(); } @@ -1088,7 +1103,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -1166,7 +1181,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -1231,7 +1246,7 @@ public: { return d_act.size(); } - + QAction * getAction(int which) { if(which < d_act.size()) @@ -1261,6 +1276,162 @@ private: /********************************************************************/ +class NumberLayoutMenu: public QMenu +{ + Q_OBJECT + +public: + NumberLayoutMenu(QWidget *parent) + : QMenu("Layout", parent) + { + d_grp = new QActionGroup(this); + d_act.push_back(new QAction("Horizontal", this)); + d_act.push_back(new QAction("Vertical", this)); + d_act.push_back(new QAction("None", this)); + + connect(d_act[0], SIGNAL(triggered()), this, SLOT(getHoriz())); + connect(d_act[1], SIGNAL(triggered()), this, SLOT(getVert())); + connect(d_act[2], SIGNAL(triggered()), this, SLOT(getNone())); + + QListIterator<QAction*> i(d_act); + while(i.hasNext()) { + QAction *a = i.next(); + a->setCheckable(true); + a->setActionGroup(d_grp); + addAction(a); + } + } + + ~NumberLayoutMenu() + {} + + int getNumActions() const + { + return d_act.size(); + } + + QAction * getAction(int which) + { + if(which < d_act.size()) + return d_act[which]; + else + throw std::runtime_error("NumberLayoutMenu::getAction: which out of range.\n"); + } + + QAction * getAction(gr::qtgui::graph_t layout) + { + switch(layout) { + case gr::qtgui::NUM_GRAPH_HORIZ: + return d_act[0]; + break; + case gr::qtgui::NUM_GRAPH_VERT: + return d_act[1]; + break; + case gr::qtgui::NUM_GRAPH_NONE: + return d_act[1]; + break; + default: + throw std::runtime_error("NumberLayoutMenu::getAction: unknown layout type.\n"); + } + } + +signals: + void whichTrigger(gr::qtgui::graph_t layout); + +public slots: + void getHoriz() { emit whichTrigger(gr::qtgui::NUM_GRAPH_HORIZ); } + void getVert() { emit whichTrigger(gr::qtgui::NUM_GRAPH_VERT); } + void getNone() { emit whichTrigger(gr::qtgui::NUM_GRAPH_NONE); } + +private: + QList<QAction *> d_act; + QActionGroup *d_grp; +}; + + +/********************************************************************/ + + +class NumberColorMapMenu: public QMenu +{ + Q_OBJECT + +public: + NumberColorMapMenu(int which, QWidget *parent) + : QMenu("Color Map", parent), d_which(which) + { + d_act.push_back(new QAction("Black", this)); + d_act.push_back(new QAction("Blue-Red", this)); + d_act.push_back(new QAction("White Hot", this)); + d_act.push_back(new QAction("Black Hot", this)); + d_act.push_back(new QAction("Black-Red", this)); + d_act.push_back(new QAction("Other", this)); + + connect(d_act[0], SIGNAL(triggered()), this, SLOT(getBlack())); + connect(d_act[1], SIGNAL(triggered()), this, SLOT(getBlueRed())); + connect(d_act[2], SIGNAL(triggered()), this, SLOT(getWhiteHot())); + connect(d_act[3], SIGNAL(triggered()), this, SLOT(getBlackHot())); + connect(d_act[4], SIGNAL(triggered()), this, SLOT(getBlackRed())); + connect(d_act[5], SIGNAL(triggered()), this, SLOT(getOther())); + + QListIterator<QAction*> i(d_act); + while(i.hasNext()) { + QAction *a = i.next(); + addAction(a); + } + + d_max_value = QColor("black"); + d_min_value = QColor("black"); + } + + ~NumberColorMapMenu() + {} + + int getNumActions() const + { + return d_act.size(); + } + + QAction * getAction(int which) + { + if(which < d_act.size()) + return d_act[which]; + else + throw std::runtime_error("ColorMapMenu::getAction: which out of range.\n"); + } + + signals: + void whichTrigger(int which, + const QColor &min_color, + const QColor &max_color); + + public slots: + void getBlack() { emit whichTrigger(d_which, QColor("black"), QColor("black")); } + void getBlueRed() { emit whichTrigger(d_which, QColor("blue"), QColor("red")); } + void getWhiteHot() { emit whichTrigger(d_which, QColor("black"), QColor("white")); } + void getBlackHot() { emit whichTrigger(d_which, QColor("white"), QColor("black")); } + void getBlackRed() { emit whichTrigger(d_which, QColor("black"), QColor("red")); } + void getOther() + { + QMessageBox::information(this, "Set low and high intensities", + "In the next windows, select the low and then the high intensity colors.", + QMessageBox::Ok); + d_min_value = QColorDialog::getColor(d_min_value, this); + d_max_value = QColorDialog::getColor(d_max_value, this); + + emit whichTrigger(d_which, d_min_value, d_max_value); + } + +private: + QList<QAction *> d_act; + QColor d_max_value, d_min_value; + int d_which; +}; + + +/********************************************************************/ + + class PopupMenu: public QAction { Q_OBJECT @@ -1308,7 +1479,7 @@ public slots: private slots: void getText() - { + { emit whichTrigger(d_text->text()); d_diag->accept(); } diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h index d0a4a3dba0..fcbfd72ec3 100644 --- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h +++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h @@ -34,7 +34,7 @@ namespace gr { namespace qtgui { - + /*! * \brief A graphical sink to display multiple signals in frequency. * \ingroup instrumentation_blk @@ -71,9 +71,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void set_fft_size(const int fftsize) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h index 25a4c80b49..c49b9d9ec0 100644 --- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h +++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h @@ -71,9 +71,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void set_fft_size(const int fftsize) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/histogram_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/histogram_sink_f.h index 07ad124c3b..96d2b57732 100644 --- a/gr-qtgui/include/gnuradio/qtgui/histogram_sink_f.h +++ b/gr-qtgui/include/gnuradio/qtgui/histogram_sink_f.h @@ -85,9 +85,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif public: diff --git a/gr-qtgui/include/gnuradio/qtgui/histogramdisplayform.h b/gr-qtgui/include/gnuradio/qtgui/histogramdisplayform.h index 16a64b703a..e235f1c0be 100644 --- a/gr-qtgui/include/gnuradio/qtgui/histogramdisplayform.h +++ b/gr-qtgui/include/gnuradio/qtgui/histogramdisplayform.h @@ -73,12 +73,13 @@ private: bool d_semilogx; bool d_semilogy; - + NPointsMenu *d_nptsmenu; - NPointsMenu *d_nbinsmenu; + NPointsMenu *d_nbinsmenu; QAction *d_semilogxmenu; QAction *d_semilogymenu; + QAction *d_accum_act; QAction *d_autoscalex_act; bool d_autoscalex_state; }; diff --git a/gr-qtgui/include/gnuradio/qtgui/number_sink.h b/gr-qtgui/include/gnuradio/qtgui/number_sink.h new file mode 100644 index 0000000000..a34eab38a5 --- /dev/null +++ b/gr-qtgui/include/gnuradio/qtgui/number_sink.h @@ -0,0 +1,108 @@ +/* -*- 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_QTGUI_NUMBER_SINK_H +#define INCLUDED_QTGUI_NUMBER_SINK_H + +#ifdef ENABLE_PYTHON +#include <Python.h> +#endif + +#include <gnuradio/qtgui/api.h> +#include <gnuradio/qtgui/trigger_mode.h> +#include <gnuradio/qtgui/qtgui_types.h> +#include <gnuradio/sync_block.h> +#include <qapplication.h> + +namespace gr { + namespace qtgui { + + /*! + * \brief A graphical sink to display numerical values of input streams. + * \ingroup instrumentation_blk + * \ingroup qtgui_blk + * + * \details + * Number sink + */ + class QTGUI_API number_sink : virtual public sync_block + { + public: + + // gr::qtgui::number_sink::sptr + typedef boost::shared_ptr<number_sink> sptr; + + /*! + * \brief Build a number sink + * + * \param itemsize Size of input item stream + * \param average Averaging coefficient (0 - 1) + * \param graph_type Type of graph to use (number_sink::graph_t) + * \param nconnections number of signals connected to sink + * \param parent a QWidget parent object, if any + */ + static sptr make(size_t itemsize, + float average=0, + graph_t graph_type=NUM_GRAPH_HORIZ, + int nconnections=1, + QWidget *parent=NULL); + + virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; + +#ifdef ENABLE_PYTHON + virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; +#endif + + virtual void set_update_time(double t) = 0; + virtual void set_average(const float avg) = 0; + virtual void set_graph_type(const graph_t type) = 0; + virtual void set_color(int which, + const std::string &min, + const std::string &max) = 0; + virtual void set_color(int which, int min, int max) = 0; + virtual void set_label(int which, const std::string &label) = 0; + virtual void set_min(int which, float min) = 0; + virtual void set_max(int which, float max) = 0; + + virtual float average() const = 0; + virtual graph_t graph_type() const = 0; + virtual std::string color_min(int which) const = 0; + virtual std::string color_max(int which) const = 0; + virtual std::string label(int which) const = 0; + virtual float min(int which) const = 0; + virtual float max(int which) const = 0; + + virtual void enable_menu(bool en=true) = 0; + virtual void enable_autoscale(bool en=true) = 0; + + virtual void reset() = 0; + + QApplication *d_qApplication; + }; + + } /* namespace qtgui */ +} /* namespace gr */ + +#endif /* INCLUDED_QTGUI_NUMBER_SINK_H */ diff --git a/gr-qtgui/include/gnuradio/qtgui/numberdisplayform.h b/gr-qtgui/include/gnuradio/qtgui/numberdisplayform.h new file mode 100644 index 0000000000..c33f9b455f --- /dev/null +++ b/gr-qtgui/include/gnuradio/qtgui/numberdisplayform.h @@ -0,0 +1,105 @@ +/* -*- 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 NUMBER_DISPLAY_FORM_H +#define NUMBER_DISPLAY_FORM_H + +#include <gnuradio/qtgui/spectrumUpdateEvents.h> +#include <gnuradio/qtgui/form_menus.h> +#include <QtGui/QtGui> +#include <qwt_thermo.h> +#include <vector> + +/*! + * \brief DisplayForm child for managing number sink plots. + * \ingroup qtgui_blk + */ +class NumberDisplayForm : public QWidget +{ + Q_OBJECT + + public: + NumberDisplayForm(int nplots=1, + gr::qtgui::graph_t type=gr::qtgui::NUM_GRAPH_HORIZ, + QWidget* parent = 0); + ~NumberDisplayForm(); + + gr::qtgui::graph_t graphType() const; + QColor colorMin(int which) const; + QColor colorMax(int which) const; + std::string label(int which) const; + float average() const; + float updateTime() const; + int scaleMin(int which); + int scaleMax(int which); + +public slots: + void mousePressEvent(QMouseEvent * e); + void customEvent(QEvent * e); + void setStop(bool on); + void setStop(); + void setGraphType(const gr::qtgui::graph_t type); + void setColor(int which, const QColor &min, const QColor &max); + void setColorMin(int which, QString min); + void setColorMax(int which, QString max); + void setLabel(int which, const std::string &label); + void setLabel(int which, QString label); + void setAverage(const float avg); + void setUpdateTime(const float time); + void setUpdateTime(QString time); + void saveFigure(); + void setScale(int which, int min, int max); + void setScaleMin(int which, int min); + void setScaleMax(int which, int max); + void autoScale(bool on); + +private slots: + void newData(const QEvent*); + +private: + int d_nplots; + QGridLayout *d_layout; + std::vector<QLabel*> d_label; + std::vector<QLabel*> d_text_box; + std::vector<QwtThermo*> d_indicator; + gr::qtgui::graph_t d_graph_type; + float d_avg, d_update_time; + std::vector<float> d_max, d_min; + + bool d_menu_on; + bool d_stop_state; + bool d_autoscale_state; + + QMenu *d_menu; + QAction *d_stop_act; + QList<QMenu*> d_label_menu; + std::vector<LineTitleAction*> d_label_act; + FFTAverageMenu *d_avg_menu; + NumberLayoutMenu *d_layout_menu; + std::vector<NumberColorMapMenu*> d_color_menu; + PopupMenu *d_maxcolor_menu; + QAction *d_autoscale_act; + PopupMenu *d_update_time_menu; + QAction *d_save_act; +}; + +#endif /* NUMBER_DISPLAY_FORM_H */ diff --git a/gr-qtgui/include/gnuradio/qtgui/qtgui_types.h b/gr-qtgui/include/gnuradio/qtgui/qtgui_types.h index f71ab9eda3..cde52547a9 100644 --- a/gr-qtgui/include/gnuradio/qtgui/qtgui_types.h +++ b/gr-qtgui/include/gnuradio/qtgui/qtgui_types.h @@ -75,16 +75,16 @@ public: _zeroTime = 0; _secondsPerLine = 1.0; } - + virtual ~TimeScaleData() - { + { } virtual gr::high_res_timer_type getZeroTime() const { return _zeroTime; } - + virtual void setZeroTime(const gr::high_res_timer_type newTime) { _zeroTime = newTime - gr::high_res_timer_epoch(); @@ -100,13 +100,13 @@ public: return _secondsPerLine; } - + protected: - + private: gr::high_res_timer_type _zeroTime; double _secondsPerLine; - + }; /*********************************************************************** @@ -136,6 +136,19 @@ private: }; +namespace gr { + namespace qtgui { + + enum graph_t { + NUM_GRAPH_NONE = 0, + NUM_GRAPH_HORIZ, + NUM_GRAPH_VERT, + }; + + } /* namespace qtgui */ +} /* namespace gr */ + + enum{ INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR = 0, INTENSITY_COLOR_MAP_TYPE_WHITE_HOT = 1, diff --git a/gr-qtgui/include/gnuradio/qtgui/sink_c.h b/gr-qtgui/include/gnuradio/qtgui/sink_c.h index d1c35ebda9..e0c770039f 100644 --- a/gr-qtgui/include/gnuradio/qtgui/sink_c.h +++ b/gr-qtgui/include/gnuradio/qtgui/sink_c.h @@ -77,9 +77,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void set_fft_size(const int fftsize) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/sink_f.h b/gr-qtgui/include/gnuradio/qtgui/sink_f.h index 7d56a7a499..0e8004b1ed 100644 --- a/gr-qtgui/include/gnuradio/qtgui/sink_f.h +++ b/gr-qtgui/include/gnuradio/qtgui/sink_f.h @@ -77,9 +77,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void set_fft_size(const int fftsize) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/spectrumUpdateEvents.h b/gr-qtgui/include/gnuradio/qtgui/spectrumUpdateEvents.h index dc31ba8601..d26f41e26d 100644 --- a/gr-qtgui/include/gnuradio/qtgui/spectrumUpdateEvents.h +++ b/gr-qtgui/include/gnuradio/qtgui/spectrumUpdateEvents.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008-2013 Free Software Foundation, Inc. + * Copyright 2008-2014 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -295,4 +295,28 @@ private: }; +/********************************************************************/ + + +class NumberUpdateEvent: public QEvent +{ +public: + NumberUpdateEvent(const std::vector<float> samples); + ~NumberUpdateEvent(); + + int which() const; + const std::vector<float> getSamples() const; + + static QEvent::Type Type() + { return QEvent::Type(SpectrumUpdateEventType); } + +protected: + +private: + size_t _nplots; + std::vector<float> _samples; +}; + + + #endif /* SPECTRUM_UPDATE_EVENTS_H */ diff --git a/gr-qtgui/include/gnuradio/qtgui/time_raster_sink_b.h b/gr-qtgui/include/gnuradio/qtgui/time_raster_sink_b.h index 5304dd4f84..586007bf5f 100644 --- a/gr-qtgui/include/gnuradio/qtgui/time_raster_sink_b.h +++ b/gr-qtgui/include/gnuradio/qtgui/time_raster_sink_b.h @@ -76,9 +76,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void set_update_time(double t) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/time_raster_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/time_raster_sink_f.h index 2c13265ae5..2c7699d923 100644 --- a/gr-qtgui/include/gnuradio/qtgui/time_raster_sink_f.h +++ b/gr-qtgui/include/gnuradio/qtgui/time_raster_sink_f.h @@ -73,9 +73,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void set_update_time(double t) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h b/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h index f02226cb8e..2d5248552b 100644 --- a/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h +++ b/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h @@ -69,9 +69,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void set_y_axis(double min, double max) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h index 64e347bf83..add53ef603 100644 --- a/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h +++ b/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h @@ -67,9 +67,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void set_y_axis(double min, double max) = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_c.h b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_c.h index e1e27a4cc8..17a656949e 100644 --- a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_c.h +++ b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_c.h @@ -78,9 +78,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void clear_data() = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h index 006f592bb5..3877158e7c 100644 --- a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h +++ b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h @@ -77,9 +77,12 @@ namespace gr { QWidget *parent=NULL); virtual void exec_() = 0; + virtual QWidget* qwidget() = 0; #ifdef ENABLE_PYTHON virtual PyObject* pyqwidget() = 0; +#else + virtual void* pyqwidget() = 0; #endif virtual void clear_data() = 0; diff --git a/gr-qtgui/lib/CMakeLists.txt b/gr-qtgui/lib/CMakeLists.txt index afaadb929b..f46fe838a3 100644 --- a/gr-qtgui/lib/CMakeLists.txt +++ b/gr-qtgui/lib/CMakeLists.txt @@ -30,6 +30,7 @@ set(qtgui_moc_hdrs ${qtgui_mod_includedir}/constellationdisplayform.h ${qtgui_mod_includedir}/waterfalldisplayform.h ${qtgui_mod_includedir}/histogramdisplayform.h + ${qtgui_mod_includedir}/numberdisplayform.h ${qtgui_mod_includedir}/form_menus.h ${qtgui_mod_includedir}/DisplayPlot.h ${qtgui_mod_includedir}/FrequencyDisplayPlot.h @@ -38,6 +39,7 @@ set(qtgui_moc_hdrs ${qtgui_mod_includedir}/WaterfallDisplayPlot.h ${qtgui_mod_includedir}/ConstellationDisplayPlot.h ${qtgui_mod_includedir}/HistogramDisplayPlot.h + ${qtgui_mod_includedir}/NumberDisplayPlot.h ) QT4_WRAP_CPP(qtgui_moc_srcs ${qtgui_moc_hdrs}) QT4_WRAP_UI(qtgui_ui_hdrs spectrumdisplayform.ui) @@ -68,6 +70,8 @@ set(qtgui_srcs freqdisplayform.cc constellationdisplayform.cc histogramdisplayform.cc + NumberDisplayPlot.cc + numberdisplayform.cc waterfalldisplayform.cc SpectrumGUIClass.cc spectrumUpdateEvents.cc @@ -85,6 +89,7 @@ set(qtgui_srcs waterfall_sink_c_impl.cc waterfall_sink_f_impl.cc histogram_sink_f_impl.cc + number_sink_impl.cc qtgui_util.cc ) diff --git a/gr-qtgui/lib/NumberDisplayPlot.cc b/gr-qtgui/lib/NumberDisplayPlot.cc new file mode 100644 index 0000000000..b1fbca9ded --- /dev/null +++ b/gr-qtgui/lib/NumberDisplayPlot.cc @@ -0,0 +1,63 @@ +/* -*- 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 NUMBER_DISPLAY_PLOT_C +#define NUMBER_DISPLAY_PLOT_C + +#include <gnuradio/qtgui/NumberDisplayPlot.h> + +#include <qwt_scale_draw.h> +#include <QColor> +#include <cmath> +#include <iostream> +#include <volk/volk.h> + +NumberDisplayPlot::NumberDisplayPlot(int nplots, QWidget* parent) + : DisplayPlot(nplots, parent) +{ + resize(0, 0); + + // Setup dataPoints and plot vectors + // Automatically deleted when parent is deleted + for(int i = 0; i < d_nplots; i++) { + + } +} + +NumberDisplayPlot::~NumberDisplayPlot() +{ +} + +void +NumberDisplayPlot::replot() +{ + QwtPlot::replot(); +} + +void +NumberDisplayPlot::plotNewData(const std::vector<double> samples) +{ + if(!d_stop) { + } +} + +#endif /* NUMBER_DISPLAY_PLOT_C */ diff --git a/gr-qtgui/lib/const_sink_c_impl.cc b/gr-qtgui/lib/const_sink_c_impl.cc index bc4b411958..fb0cdade6a 100644 --- a/gr-qtgui/lib/const_sink_c_impl.cc +++ b/gr-qtgui/lib/const_sink_c_impl.cc @@ -148,6 +148,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + const_sink_c_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/const_sink_c_impl.h b/gr-qtgui/lib/const_sink_c_impl.h index e2faa72eb0..3b1de226ff 100644 --- a/gr-qtgui/lib/const_sink_c_impl.h +++ b/gr-qtgui/lib/const_sink_c_impl.h @@ -70,6 +70,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_y_axis(double min, double max); diff --git a/gr-qtgui/lib/freq_sink_c_impl.cc b/gr-qtgui/lib/freq_sink_c_impl.cc index 0f37fe80a4..ff40ff3f43 100644 --- a/gr-qtgui/lib/freq_sink_c_impl.cc +++ b/gr-qtgui/lib/freq_sink_c_impl.cc @@ -174,6 +174,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + freq_sink_c_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/freq_sink_c_impl.h b/gr-qtgui/lib/freq_sink_c_impl.h index f068e657f5..15b513715c 100644 --- a/gr-qtgui/lib/freq_sink_c_impl.h +++ b/gr-qtgui/lib/freq_sink_c_impl.h @@ -87,6 +87,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_fft_size(const int fftsize); diff --git a/gr-qtgui/lib/freq_sink_f_impl.cc b/gr-qtgui/lib/freq_sink_f_impl.cc index b2054bc96d..b661f7b07b 100644 --- a/gr-qtgui/lib/freq_sink_f_impl.cc +++ b/gr-qtgui/lib/freq_sink_f_impl.cc @@ -174,6 +174,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + freq_sink_f_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/freq_sink_f_impl.h b/gr-qtgui/lib/freq_sink_f_impl.h index c7e9fe83dc..68cb8c66b4 100644 --- a/gr-qtgui/lib/freq_sink_f_impl.h +++ b/gr-qtgui/lib/freq_sink_f_impl.h @@ -87,6 +87,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_fft_size(const int fftsize); diff --git a/gr-qtgui/lib/freqdisplayform.cc b/gr-qtgui/lib/freqdisplayform.cc index 2ea01f33b6..16576b387b 100644 --- a/gr-qtgui/lib/freqdisplayform.cc +++ b/gr-qtgui/lib/freqdisplayform.cc @@ -173,6 +173,7 @@ FreqDisplayForm::autoScale(bool en) d_autoscale_state = false; } + d_autoscale_act->setChecked(en); getPlot()->setAutoScale(d_autoscale_state); getPlot()->replot(); } diff --git a/gr-qtgui/lib/histogram_sink_f_impl.cc b/gr-qtgui/lib/histogram_sink_f_impl.cc index 4b3aa29693..dc3e63cb01 100644 --- a/gr-qtgui/lib/histogram_sink_f_impl.cc +++ b/gr-qtgui/lib/histogram_sink_f_impl.cc @@ -150,6 +150,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + histogram_sink_f_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/histogram_sink_f_impl.h b/gr-qtgui/lib/histogram_sink_f_impl.h index e2558890b9..58d43e49d1 100644 --- a/gr-qtgui/lib/histogram_sink_f_impl.h +++ b/gr-qtgui/lib/histogram_sink_f_impl.h @@ -72,6 +72,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_y_axis(double min, double max); diff --git a/gr-qtgui/lib/histogramdisplayform.cc b/gr-qtgui/lib/histogramdisplayform.cc index 755992a873..c4e9b51f90 100644 --- a/gr-qtgui/lib/histogramdisplayform.cc +++ b/gr-qtgui/lib/histogramdisplayform.cc @@ -50,10 +50,10 @@ HistogramDisplayForm::HistogramDisplayForm(int nplots, QWidget* parent) connect(d_nbinsmenu, SIGNAL(whichTrigger(int)), this, SLOT(setNumBins(const int))); - QAction *accummenu = new QAction("Accumulate", this); - accummenu->setCheckable(true); - d_menu->addAction(accummenu); - connect(accummenu, SIGNAL(triggered(bool)), + d_accum_act = new QAction("Accumulate", this); + d_accum_act->setCheckable(true); + d_menu->addAction(d_accum_act); + connect(d_accum_act, SIGNAL(triggered(bool)), this, SLOT(setAccumulate(bool))); d_menu->removeAction(d_autoscale_act); @@ -199,6 +199,7 @@ HistogramDisplayForm::setAccumulate(bool en) if(en) { autoScale(true); } + d_accum_act->setChecked(en); getPlot()->setAccumulate(en); getPlot()->replot(); } diff --git a/gr-qtgui/lib/number_sink_impl.cc b/gr-qtgui/lib/number_sink_impl.cc new file mode 100644 index 0000000000..abfb8725f4 --- /dev/null +++ b/gr-qtgui/lib/number_sink_impl.cc @@ -0,0 +1,310 @@ +/* -*- 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 "number_sink_impl.h" +#include <gnuradio/io_signature.h> +#include <string.h> +#include <volk/volk.h> +#include <gnuradio/fft/fft.h> +#include <qwt_symbol.h> + +namespace gr { + namespace qtgui { + + number_sink::sptr + number_sink::make(size_t itemsize, + float average, + graph_t graph_type, + int nconnections, + QWidget *parent) + { + return gnuradio::get_initial_sptr + (new number_sink_impl(itemsize, average, + graph_type, nconnections, parent)); + } + + number_sink_impl::number_sink_impl(size_t itemsize, + float average, + graph_t graph_type, + int nconnections, + QWidget *parent) + : sync_block("number_sink", + io_signature::make(nconnections, nconnections, itemsize), + io_signature::make(0, 0, 0)), + d_itemsize(itemsize), d_average(average), + d_type(graph_type), d_nconnections(nconnections), d_parent(parent), + d_avg_value(nconnections), d_iir(nconnections) + { + for(int n = 0; n < d_nconnections; n++) { + d_avg_value[n] = 0; + d_iir[n].set_taps(d_average); + } + + // Required now for Qt; argc must be greater than 0 and argv + // must have at least one valid character. Must be valid through + // life of the qApplication: + // http://harmattan-dev.nokia.com/docs/library/html/qt4/qapplication.html + d_argc = 1; + d_argv = new char; + d_argv[0] = '\0'; + + d_main_gui = NULL; + + // Set alignment properties for VOLK + const int alignment_multiple = + volk_get_alignment() / d_itemsize; + set_alignment(std::max(1,alignment_multiple)); + + initialize(); + } + + number_sink_impl::~number_sink_impl() + { + //if(!d_main_gui->isClosed()) + // d_main_gui->close(); + + delete d_argv; + } + + bool + number_sink_impl::check_topology(int ninputs, int noutputs) + { + return ninputs == d_nconnections; + } + + void + number_sink_impl::initialize() + { + if(qApp != NULL) { + d_qApplication = qApp; + } + else { + d_qApplication = new QApplication(d_argc, &d_argv); + } + + d_main_gui = new NumberDisplayForm(d_nconnections, d_type, d_parent); + + // initialize update time to 10 times a second + set_update_time(0.1); + } + + void + number_sink_impl::exec_() + { + d_qApplication->exec(); + } + + QWidget* + number_sink_impl::qwidget() + { + return d_main_gui; + } + +#ifdef ENABLE_PYTHON + PyObject* + number_sink_impl::pyqwidget() + { + PyObject *w = PyLong_FromVoidPtr((void*)d_main_gui); + PyObject *retarg = Py_BuildValue("N", w); + return retarg; + } +#else + void * + number_sink_impl::pyqwidget() + { + return NULL; + } +#endif + + void + number_sink_impl::set_update_time(double t) + { + //convert update time to ticks + gr::high_res_timer_type tps = gr::high_res_timer_tps(); + d_main_gui->setUpdateTime(t); + d_update_time = t * tps; + d_last_time = 0; + } + + void + number_sink_impl::set_average(const float avg) + { + d_average = avg; + for(int n = 0; n < d_nconnections; n++) { + d_avg_value[n] = 0; + d_iir[n].set_taps(d_average); + } + } + + void + number_sink_impl::set_graph_type(const graph_t type) + { + d_main_gui->setGraphType(type); + } + + void + number_sink_impl::set_color(int which, + const std::string &min, + const std::string &max) + { + d_main_gui->setColor(which, + QColor(min.c_str()), + QColor(max.c_str())); + } + + void + number_sink_impl::set_color(int which, int min, int max) + { + d_main_gui->setColor(which, QColor(min), QColor(max)); + } + + void + number_sink_impl::set_label(int which, const std::string &label) + { + d_main_gui->setLabel(which, label); + } + + void + number_sink_impl::set_min(int which, float min) + { + d_main_gui->setScaleMin(which, min); + } + + void + number_sink_impl::set_max(int which, float max) + { + return d_main_gui->setScaleMax(which, max); + } + + float + number_sink_impl::average() const + { + return d_average; + } + + graph_t + number_sink_impl::graph_type() const + { + return d_main_gui->graphType(); + } + + std::string + number_sink_impl::color_min(int which) const + { + return d_main_gui->colorMin(which).name().toStdString(); + } + + std::string + number_sink_impl::color_max(int which) const + { + return d_main_gui->colorMax(which).name().toStdString(); + } + + std::string + number_sink_impl::label(int which) const + { + return d_main_gui->label(which); + } + + float + number_sink_impl::min(int which) const + { + return d_main_gui->scaleMin(which); + } + + float + number_sink_impl::max(int which) const + { + return d_main_gui->scaleMax(which); + } + + void + number_sink_impl::enable_menu(bool en) + { + //d_main_gui->enableMenu(en); + } + + void + number_sink_impl::enable_autoscale(bool en) + { + d_main_gui->autoScale(en); + } + + void + number_sink_impl::reset() + { + gr::thread::scoped_lock lock(d_mutex); + _reset(); + } + + void + number_sink_impl::_reset() + { + } + + int + number_sink_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr::thread::scoped_lock lock(d_mutex); + + float new_avg = d_main_gui->average(); + set_update_time(d_main_gui->updateTime()); + if(new_avg != d_average) { + set_average(new_avg); + } + + if(d_average > 0) { + for(int n = 0; n < d_nconnections; n++) { + float *in = (float*)input_items[n]; + for(int i = 0; i < noutput_items; i++) { + d_avg_value[n] = d_iir[n].filter(in[i]); + } + } + } + + // Plot if we are able to update + if(gr::high_res_timer_now() - d_last_time > d_update_time) { + d_last_time = gr::high_res_timer_now(); + std::vector<float> d(d_nconnections); + if(d_average > 0) { + for(int n = 0; n < d_nconnections; n++) + d[n] = d_avg_value[n]; + } + else { + for(int n = 0; n < d_nconnections; n++) + d[n] = ((float*)input_items[n])[0]; + } + d_qApplication->postEvent(d_main_gui, + new NumberUpdateEvent(d)); + } + + return noutput_items;; + } + + } /* namespace qtgui */ +} /* namespace gr */ diff --git a/gr-qtgui/lib/number_sink_impl.h b/gr-qtgui/lib/number_sink_impl.h new file mode 100644 index 0000000000..0f4fd48262 --- /dev/null +++ b/gr-qtgui/lib/number_sink_impl.h @@ -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. + */ + +#ifndef INCLUDED_QTGUI_NUMBER_SINK_IMPL_H +#define INCLUDED_QTGUI_NUMBER_SINK_IMPL_H + +#include <gnuradio/qtgui/number_sink.h> +#include <gnuradio/qtgui/numberdisplayform.h> +#include <gnuradio/filter/single_pole_iir.h> +#include <gnuradio/thread/thread.h> +#include <gnuradio/high_res_timer.h> + +namespace gr { + namespace qtgui { + + class QTGUI_API number_sink_impl : public number_sink + { + private: + void initialize(); + + gr::thread::mutex d_mutex; + + size_t d_itemsize; + float d_average; + graph_t d_type; + int d_nconnections; + + int d_index, d_start, d_end; + std::vector<double*> d_buffers; + std::vector< std::vector<gr::tag_t> > d_tags; + + int d_argc; + char *d_argv; + QWidget *d_parent; + NumberDisplayForm *d_main_gui; + + std::vector<float> d_avg_value; + std::vector<filter::single_pole_iir<float,float,float> > d_iir; + + gr::high_res_timer_type d_update_time; + gr::high_res_timer_type d_last_time; + + void _reset(); + void _npoints_resize(); + void _gui_update_trigger(); + + public: + number_sink_impl(size_t itemsize, + float average=0, + graph_t graph_type=NUM_GRAPH_HORIZ, + int nconnections=1, + QWidget *parent=NULL); + ~number_sink_impl(); + + bool check_topology(int ninputs, int noutputs); + + void exec_(); + QWidget* qwidget(); + +#ifdef ENABLE_PYTHON + PyObject* pyqwidget(); +#else + void* pyqwidget(); +#endif + + void set_update_time(double t); + void set_average(const float avg); + void set_graph_type(const graph_t type); + void set_color(int which, + const std::string &min, + const std::string &max); + void set_color(int which, int min, int max); + void set_label(int which, const std::string &label); + void set_min(int which, float min); + void set_max(int which, float max); + + float average() const; + graph_t graph_type() const; + std::string color_min(int which) const; + std::string color_max(int which) const; + std::string label(int which) const; + float min(int which) const; + float max(int which) const; + + void enable_menu(bool en); + void enable_autoscale(bool en=true); + + void reset(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace qtgui */ +} /* namespace gr */ + +#endif /* INCLUDED_QTGUI_NUMBER_SINK_IMPL_H */ diff --git a/gr-qtgui/lib/numberdisplayform.cc b/gr-qtgui/lib/numberdisplayform.cc new file mode 100644 index 0000000000..b2b3fe453a --- /dev/null +++ b/gr-qtgui/lib/numberdisplayform.cc @@ -0,0 +1,441 @@ +/* -*- 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 <cmath> +#include <QMessageBox> +#include <QFileDialog> +#include <gnuradio/qtgui/numberdisplayform.h> +#include <iostream> +#include <qwt_color_map.h> + +NumberDisplayForm::NumberDisplayForm(int nplots, gr::qtgui::graph_t type, + QWidget* parent) + : QWidget(parent) +{ + d_nplots = nplots; + d_layout = new QGridLayout(this); + for(int i = 0; i < d_nplots; i++) { + d_min.push_back(+1e32); + d_max.push_back(-1e32); + d_label.push_back(new QLabel(QString("Data %1").arg(i))); + d_text_box.push_back(new QLabel(QString("0"))); + + d_indicator.push_back(new QwtThermo()); + d_indicator[i]->setScale(-1, 1); + +#if QWT_VERSION < 0x060100 +#else + d_indicator[i]->setOriginMode(QwtThermo::OriginCustom); + d_indicator[i]->setOrigin(0.0); +#endif /* if QWT_VERSION < 0x060100 */ + + switch(type) { + case(gr::qtgui::NUM_GRAPH_HORIZ): +#if QWT_VERSION < 0x060100 + d_indicator[i]->setOrientation(Qt::Horizontal, QwtThermo::BottomScale); +#else + d_indicator[i]->setOrientation(Qt::Horizontal); +#endif /* if QWT_VERSION < 0x060100 */ + d_layout->addWidget(d_label[i], 2*i, 0); + d_layout->addWidget(d_text_box[i], 2*i, 1); + d_layout->addWidget(d_indicator[i], 2*i+1, 1); + break; + case(gr::qtgui::NUM_GRAPH_VERT): +#if QWT_VERSION < 0x060100 + d_indicator[i]->setOrientation(Qt::Vertical, QwtThermo::LeftScale); +#else + d_indicator[i]->setOrientation(Qt::Vertical); +#endif /* if QWT_VERSION < 0x060100 */ + d_layout->addWidget(d_label[i], 0, i); + d_layout->addWidget(d_text_box[i], 1, i); + d_layout->addWidget(d_indicator[i], 2, i); + break; + case(gr::qtgui::NUM_GRAPH_NONE): + default: + d_layout->addWidget(d_label[i], 0, i); + d_layout->addWidget(d_text_box[i], 1, i); + } + + setColor(i, QColor("black"), QColor("black")); + } + + d_avg = 0.0; + d_update_time = 0.1; + + d_menu_on = true; + d_menu = new QMenu(this); + + // Create a set of actions for the menu + d_stop_act = new QAction("Stop", this); + d_stop_act->setStatusTip(tr("Start/Stop")); + connect(d_stop_act, SIGNAL(triggered()), this, SLOT(setStop())); + d_stop_state = false; + d_menu->addAction(d_stop_act); + + // Menu items for each number line + for(int i = 0; i < d_nplots; i++) { + d_label_act.push_back(new LineTitleAction(i, this)); + connect(d_label_act[i], SIGNAL(whichTrigger(int, const QString&)), + this, SLOT(setLabel(int, const QString&))); + + d_label_menu.push_back(new QMenu(tr(""), this)); + d_label_menu[i]->addAction(d_label_act[i]); + + d_color_menu.push_back(new NumberColorMapMenu(i, this)); + connect(d_color_menu[i], SIGNAL(whichTrigger(int, const QColor&, const QColor&)), + this, SLOT(setColor(int, const QColor&, const QColor&))); + d_label_menu[i]->addMenu(d_color_menu[i]); + + d_menu->addMenu(d_label_menu[i]); + } + + d_avg_menu = new FFTAverageMenu(this); + d_avg_menu->setTitle("Average"); + d_avg_menu->setHigh(0.001); + d_avg_menu->setMedium(0.01); + d_avg_menu->setLow(0.1); + connect(d_avg_menu, SIGNAL(whichTrigger(float)), + this, SLOT(setAverage(const float))); + d_menu->addMenu(d_avg_menu); + + d_layout_menu = new NumberLayoutMenu(this); + connect(d_layout_menu, SIGNAL(whichTrigger(gr::qtgui::graph_t)), + this, SLOT(setGraphType(const gr::qtgui::graph_t))); + d_menu->addMenu(d_layout_menu); + + d_autoscale_act = new QAction("Auto Scale", this); + d_autoscale_act->setCheckable(true); + connect(d_autoscale_act, SIGNAL(triggered(bool)), + this, SLOT(autoScale(bool))); + d_autoscale_state = false; + d_menu->addAction(d_autoscale_act); + + d_update_time_menu = new PopupMenu("Update Time", this); + connect(d_update_time_menu, SIGNAL(whichTrigger(QString)), + this, SLOT(setUpdateTime(QString))); + d_menu->addAction(d_update_time_menu); + + d_save_act = new QAction("Save", this); + d_save_act->setStatusTip(tr("Save Figure")); + connect(d_save_act, SIGNAL(triggered()), this, SLOT(saveFigure())); + d_menu->addAction(d_save_act); + + setLayout(d_layout); +} + +NumberDisplayForm::~NumberDisplayForm() +{ + // Qt deletes children when parent is deleted +} + +void +NumberDisplayForm::mousePressEvent(QMouseEvent * e) +{ + bool ctrloff = Qt::ControlModifier != QApplication::keyboardModifiers(); + if((e->button() == Qt::MidButton) && ctrloff && (d_menu_on)) { + if(d_stop_state == false) + d_stop_act->setText(tr("Stop")); + else + d_stop_act->setText(tr("Start")); + + // Update the line titles if changed externally + for(int i = 0; i < d_nplots; i++) { + d_label_menu[i]->setTitle(label(i).c_str()); + } + d_menu->exec(e->globalPos()); + } +} + +void +NumberDisplayForm::setStop(bool on) +{ + if(!on) { + d_stop_state = false; + } + else { + d_stop_state = true; + } +} + +void +NumberDisplayForm::setStop() +{ + if(d_stop_state == false) + setStop(true); + else + setStop(false); +} + +void +NumberDisplayForm::saveFigure() +{ + QPixmap qpix = QPixmap::grabWidget(this); + + QString types = QString(tr("JPEG file (*.jpg);;Portable Network Graphics file (*.png);;Bitmap file (*.bmp);;TIFF file (*.tiff)")); + + QString filename, filetype; + QFileDialog *filebox = new QFileDialog(0, "Save Image", "./", types); + filebox->setViewMode(QFileDialog::Detail); + if(filebox->exec()) { + filename = filebox->selectedFiles()[0]; + filetype = filebox->selectedNameFilter(); + } + else { + return; + } + + if(filetype.contains(".jpg")) { + qpix.save(filename, "JPEG"); + } + else if(filetype.contains(".png")) { + qpix.save(filename, "PNG"); + } + else if(filetype.contains(".bmp")) { + qpix.save(filename, "BMP"); + } + else if(filetype.contains(".tiff")) { + qpix.save(filename, "TIFF"); + } + else { + qpix.save(filename, "JPEG"); + } + + delete filebox; +} + +void +NumberDisplayForm::newData(const QEvent* updateEvent) +{ + if(!d_stop_state) { + NumberUpdateEvent *tevent = (NumberUpdateEvent*)updateEvent; + const std::vector<float> samples = tevent->getSamples(); + + for(int i = 0; i < d_nplots; i++) { + d_text_box[i]->setText(QString("%1").arg(samples[i], 4, ' ')); + d_indicator[i]->setValue(samples[i]); + d_min[i] = std::min(d_min[i], samples[i]); + d_max[i] = std::max(d_max[i], samples[i]); + + if(d_autoscale_state) { + d_indicator[i]->setScale(d_min[i], d_max[i]); + } + } + + } +} + +void +NumberDisplayForm::customEvent(QEvent * e) +{ + if(e->type() == NumberUpdateEvent::Type()) { + newData(e); + } +} + +void +NumberDisplayForm::setGraphType(const gr::qtgui::graph_t type) +{ + d_graph_type = type; + for(int i = 0; i < d_nplots; i++) { + d_layout->removeWidget(d_indicator[i]); + d_layout->removeWidget(d_label[i]); + d_layout->removeWidget(d_text_box[i]); + + switch(d_graph_type) { + case(gr::qtgui::NUM_GRAPH_HORIZ): +#if QWT_VERSION < 0x060100 + d_indicator[i]->setOrientation(Qt::Horizontal, QwtThermo::BottomScale); +#else + d_indicator[i]->setOrientation(Qt::Horizontal); +#endif /* if QWT_VERSION < 0x060100 */ + d_indicator[i]->setVisible(true); + d_layout->addWidget(d_label[i], 2*i, 0); + d_layout->addWidget(d_text_box[i], 2*i, 1); + d_layout->addWidget(d_indicator[i], 2*i+1, 1); + break; + case(gr::qtgui::NUM_GRAPH_VERT): +#if QWT_VERSION < 0x060100 + d_indicator[i]->setOrientation(Qt::Vertical, QwtThermo::LeftScale); +#else + d_indicator[i]->setOrientation(Qt::Vertical); +#endif /* if QWT_VERSION < 0x060100 */ + d_indicator[i]->setVisible(true); + d_layout->addWidget(d_label[i], 0, i); + d_layout->addWidget(d_text_box[i], 1, i); + d_layout->addWidget(d_indicator[i], 2, i); + break; + case(gr::qtgui::NUM_GRAPH_NONE): + default: + d_indicator[i]->setVisible(false); + d_layout->addWidget(d_label[i], 0, i); + d_layout->addWidget(d_text_box[i], 1, i); + break; + } + } + +} + +void +NumberDisplayForm::setColor(int which, const QColor &min, const QColor &max) +{ + QwtLinearColorMap *map = new QwtLinearColorMap(); + map->setColorInterval(min, max); + +#if QWT_VERSION < 0x060000 + d_indicator[which]->setFillColor(max); +#else + d_indicator[which]->setColorMap(map); +#endif /* QWT_VERSION < 0x060000 */ +} + +void +NumberDisplayForm::setColorMin(int which, QString min) +{ + setColor(which, QColor(min), colorMax(which)); +} + +void +NumberDisplayForm::setColorMax(int which, QString max) +{ + setColor(which, colorMin(which), QColor(max)); +} + +void +NumberDisplayForm::setLabel(int which, const std::string &label) +{ + d_label[which]->setText(label.c_str()); +} + +void +NumberDisplayForm::setLabel(int which, QString label) +{ + d_label[which]->setText(label); +} + +void +NumberDisplayForm::setAverage(const float avg) +{ + d_avg = avg; +} + +void +NumberDisplayForm::setUpdateTime(const float time) +{ + d_update_time = time; +} + +void +NumberDisplayForm::setUpdateTime(QString time) +{ + setUpdateTime(time.toFloat()); +} + +void +NumberDisplayForm::setScale(int which, int min, int max) +{ + d_min[which] = min; + d_max[which] = max; + d_indicator[which]->setScale(min, max); +} + +void +NumberDisplayForm::setScaleMin(int which, int min) +{ + setScale(which, min, d_max[which]); +} + +void +NumberDisplayForm::setScaleMax(int which, int max) +{ + setScale(which, d_min[which], max); +} + +gr::qtgui::graph_t +NumberDisplayForm::graphType() const +{ + return d_graph_type; +} + +QColor +NumberDisplayForm::colorMin(int which) const +{ +#if QWT_VERSION < 0x060000 + return d_indicator[which]->fillColor(); +#else + QwtLinearColorMap *map = static_cast<QwtLinearColorMap*>(d_indicator[which]->colorMap()); + return map->color1(); +#endif /* QWT_VERSION < 0x060000 */ +} + +QColor +NumberDisplayForm::colorMax(int which) const +{ +#if QWT_VERSION < 0x060000 + return d_indicator[which]->fillColor(); +#else + QwtLinearColorMap *map = static_cast<QwtLinearColorMap*>(d_indicator[which]->colorMap()); + return map->color2(); +#endif /* QWT_VERSION < 0x060000 */ +} + +std::string +NumberDisplayForm::label(int which) const +{ + return d_label[which]->text().toStdString(); +} + +float +NumberDisplayForm::average() const +{ + return d_avg; +} + +float +NumberDisplayForm::updateTime() const +{ + return d_update_time; +} + +int +NumberDisplayForm::scaleMin(int which) +{ + return d_min[which]; +} + +int +NumberDisplayForm::scaleMax(int which) +{ + return d_max[which]; +} + +void +NumberDisplayForm::autoScale(bool on) +{ + d_autoscale_state = on; + d_autoscale_act->setChecked(on); + + // Reset the autoscale limits + for(int i = 0; i < d_nplots; i++) { + d_min.push_back(+1e32); + d_max.push_back(-1e32); + } +} diff --git a/gr-qtgui/lib/sink_c_impl.cc b/gr-qtgui/lib/sink_c_impl.cc index 12720bde2f..992512a999 100644 --- a/gr-qtgui/lib/sink_c_impl.cc +++ b/gr-qtgui/lib/sink_c_impl.cc @@ -180,6 +180,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + sink_c_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/sink_c_impl.h b/gr-qtgui/lib/sink_c_impl.h index 56c90f3f80..18508d30aa 100644 --- a/gr-qtgui/lib/sink_c_impl.h +++ b/gr-qtgui/lib/sink_c_impl.h @@ -85,6 +85,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_fft_size(const int fftsize); diff --git a/gr-qtgui/lib/sink_f_impl.cc b/gr-qtgui/lib/sink_f_impl.cc index a3567aec94..0a0e119181 100644 --- a/gr-qtgui/lib/sink_f_impl.cc +++ b/gr-qtgui/lib/sink_f_impl.cc @@ -172,6 +172,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + sink_f_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/sink_f_impl.h b/gr-qtgui/lib/sink_f_impl.h index 801a200bb8..68331cc4e6 100644 --- a/gr-qtgui/lib/sink_f_impl.h +++ b/gr-qtgui/lib/sink_f_impl.h @@ -83,6 +83,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_fft_size(const int fftsize); diff --git a/gr-qtgui/lib/spectrumUpdateEvents.cc b/gr-qtgui/lib/spectrumUpdateEvents.cc index 8c822efb4f..f48e079861 100644 --- a/gr-qtgui/lib/spectrumUpdateEvents.cc +++ b/gr-qtgui/lib/spectrumUpdateEvents.cc @@ -490,4 +490,26 @@ HistogramUpdateEvent::getNumDataPoints() const } + +/***************************************************************************/ + + +NumberUpdateEvent::NumberUpdateEvent(const std::vector<float> samples) + : QEvent(QEvent::Type(SpectrumUpdateEventType)) +{ + _samples = samples; + _nplots = samples.size(); +} + +NumberUpdateEvent::~NumberUpdateEvent() +{ +} + +const std::vector<float> +NumberUpdateEvent::getSamples() const +{ + return _samples; +} + + #endif /* SPECTRUM_UPDATE_EVENTS_C */ diff --git a/gr-qtgui/lib/time_raster_sink_b_impl.cc b/gr-qtgui/lib/time_raster_sink_b_impl.cc index 5e5a9f505d..a1189f4413 100644 --- a/gr-qtgui/lib/time_raster_sink_b_impl.cc +++ b/gr-qtgui/lib/time_raster_sink_b_impl.cc @@ -169,6 +169,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + time_raster_sink_b_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/time_raster_sink_b_impl.h b/gr-qtgui/lib/time_raster_sink_b_impl.h index 680056822c..bd568e91c0 100644 --- a/gr-qtgui/lib/time_raster_sink_b_impl.h +++ b/gr-qtgui/lib/time_raster_sink_b_impl.h @@ -78,6 +78,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_update_time(double t); diff --git a/gr-qtgui/lib/time_raster_sink_f_impl.cc b/gr-qtgui/lib/time_raster_sink_f_impl.cc index a68a503c7a..c8b865d55d 100644 --- a/gr-qtgui/lib/time_raster_sink_f_impl.cc +++ b/gr-qtgui/lib/time_raster_sink_f_impl.cc @@ -167,6 +167,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + time_raster_sink_f_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/time_raster_sink_f_impl.h b/gr-qtgui/lib/time_raster_sink_f_impl.h index f7caf75842..1e0dcf8370 100644 --- a/gr-qtgui/lib/time_raster_sink_f_impl.h +++ b/gr-qtgui/lib/time_raster_sink_f_impl.h @@ -77,6 +77,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_update_time(double t); diff --git a/gr-qtgui/lib/time_sink_c_impl.cc b/gr-qtgui/lib/time_sink_c_impl.cc index 0f723f8b3d..e86ffca227 100644 --- a/gr-qtgui/lib/time_sink_c_impl.cc +++ b/gr-qtgui/lib/time_sink_c_impl.cc @@ -153,6 +153,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + time_sink_c_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/time_sink_c_impl.h b/gr-qtgui/lib/time_sink_c_impl.h index 03dcbe2fc0..6a75789059 100644 --- a/gr-qtgui/lib/time_sink_c_impl.h +++ b/gr-qtgui/lib/time_sink_c_impl.h @@ -88,6 +88,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_y_axis(double min, double max); diff --git a/gr-qtgui/lib/time_sink_f_impl.cc b/gr-qtgui/lib/time_sink_f_impl.cc index f547185415..e571654615 100644 --- a/gr-qtgui/lib/time_sink_f_impl.cc +++ b/gr-qtgui/lib/time_sink_f_impl.cc @@ -155,6 +155,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + time_sink_f_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/time_sink_f_impl.h b/gr-qtgui/lib/time_sink_f_impl.h index bbad48dc48..7505642389 100644 --- a/gr-qtgui/lib/time_sink_f_impl.h +++ b/gr-qtgui/lib/time_sink_f_impl.h @@ -88,6 +88,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void set_y_axis(double min, double max); diff --git a/gr-qtgui/lib/timerasterdisplayform.cc b/gr-qtgui/lib/timerasterdisplayform.cc index 0121e2f544..382e91607c 100644 --- a/gr-qtgui/lib/timerasterdisplayform.cc +++ b/gr-qtgui/lib/timerasterdisplayform.cc @@ -61,6 +61,11 @@ TimeRasterDisplayForm::TimeRasterDisplayForm(int nplots, // Now create our own menus for(int i = 0; i < nplots; i++) { + d_line_title_act.push_back(new LineTitleAction(i, this)); + connect(d_line_title_act[i], SIGNAL(whichTrigger(int, const QString&)), + this, SLOT(setLineLabel(int, const QString&))); + d_lines_menu[i]->addAction(d_line_title_act[i]); + ColorMapMenu *colormap = new ColorMapMenu(i, this); connect(colormap, SIGNAL(whichTrigger(int, const int, const QColor&, const QColor&)), this, SLOT(setColorMap(int, const int, const QColor&, const QColor&))); diff --git a/gr-qtgui/lib/waterfall_sink_c_impl.cc b/gr-qtgui/lib/waterfall_sink_c_impl.cc index ded93d19d3..2c436db789 100644 --- a/gr-qtgui/lib/waterfall_sink_c_impl.cc +++ b/gr-qtgui/lib/waterfall_sink_c_impl.cc @@ -173,6 +173,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + waterfall_sink_c_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/waterfall_sink_c_impl.h b/gr-qtgui/lib/waterfall_sink_c_impl.h index 95781c564d..aad4a4debb 100644 --- a/gr-qtgui/lib/waterfall_sink_c_impl.h +++ b/gr-qtgui/lib/waterfall_sink_c_impl.h @@ -85,6 +85,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void clear_data(); diff --git a/gr-qtgui/lib/waterfall_sink_f_impl.cc b/gr-qtgui/lib/waterfall_sink_f_impl.cc index bb6c3e050d..fc6d9fab67 100644 --- a/gr-qtgui/lib/waterfall_sink_f_impl.cc +++ b/gr-qtgui/lib/waterfall_sink_f_impl.cc @@ -172,6 +172,12 @@ namespace gr { PyObject *retarg = Py_BuildValue("N", w); return retarg; } +#else + void * + waterfall_sink_f_impl::pyqwidget() + { + return NULL; + } #endif void diff --git a/gr-qtgui/lib/waterfall_sink_f_impl.h b/gr-qtgui/lib/waterfall_sink_f_impl.h index 97c6aa2def..172f873a7f 100644 --- a/gr-qtgui/lib/waterfall_sink_f_impl.h +++ b/gr-qtgui/lib/waterfall_sink_f_impl.h @@ -85,6 +85,8 @@ namespace gr { #ifdef ENABLE_PYTHON PyObject* pyqwidget(); +#else + void* pyqwidget(); #endif void clear_data(); diff --git a/gr-qtgui/swig/qtgui_swig.i b/gr-qtgui/swig/qtgui_swig.i index 234a8791b5..b753a666e8 100644 --- a/gr-qtgui/swig/qtgui_swig.i +++ b/gr-qtgui/swig/qtgui_swig.i @@ -28,6 +28,27 @@ //load generated python docstrings %include "qtgui_swig_doc.i" +namespace gr { + namespace qtgui { + + enum graph_t { + NUM_GRAPH_NONE = 0, + NUM_GRAPH_HORIZ, + NUM_GRAPH_VERT, + }; + + } /* namespace qtgui */ +} /* namespace gr */ + + +enum{ + INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR = 0, + INTENSITY_COLOR_MAP_TYPE_WHITE_HOT = 1, + INTENSITY_COLOR_MAP_TYPE_BLACK_HOT = 2, + INTENSITY_COLOR_MAP_TYPE_INCANDESCENT = 3, + INTENSITY_COLOR_MAP_TYPE_USER_DEFINED = 4 +}; + %include "gnuradio/qtgui/trigger_mode.h" // So we understand the firdes window types @@ -49,6 +70,7 @@ #include "gnuradio/qtgui/waterfall_sink_c.h" #include "gnuradio/qtgui/waterfall_sink_f.h" #include "gnuradio/qtgui/histogram_sink_f.h" +#include "gnuradio/qtgui/number_sink.h" %} %include "gnuradio/qtgui/sink_c.h" @@ -63,6 +85,7 @@ %include "gnuradio/qtgui/waterfall_sink_c.h" %include "gnuradio/qtgui/waterfall_sink_f.h" %include "gnuradio/qtgui/histogram_sink_f.h" +%include "gnuradio/qtgui/number_sink.h" GR_SWIG_BLOCK_MAGIC2(qtgui, sink_c); GR_SWIG_BLOCK_MAGIC2(qtgui, sink_f); @@ -76,3 +99,4 @@ GR_SWIG_BLOCK_MAGIC2(qtgui, const_sink_c); GR_SWIG_BLOCK_MAGIC2(qtgui, waterfall_sink_c); GR_SWIG_BLOCK_MAGIC2(qtgui, waterfall_sink_f); GR_SWIG_BLOCK_MAGIC2(qtgui, histogram_sink_f); +GR_SWIG_BLOCK_MAGIC2(qtgui, number_sink); diff --git a/gr-uhd/python/uhd/qa_uhd.py b/gr-uhd/python/uhd/qa_uhd.py index 511c098753..4df0d4273e 100644 --- a/gr-uhd/python/uhd/qa_uhd.py +++ b/gr-uhd/python/uhd/qa_uhd.py @@ -35,6 +35,14 @@ class test_uhd(gr_unittest.TestCase): They may not have a UHD device connected, etc. Don't try to run anything""" pass + def test_time_spec_t (self): + seconds = 42.0 + time = uhd.time_spec_t(seconds) + twice_time = time + time; + zero_time = time - time; + self.assertEqual(time.get_real_secs() * 2, seconds * 2 ) + self.assertEqual(time.get_real_secs() - time.get_real_secs() , 0.0) + def test_stream_args_channel_foo(self): """ Try to manipulate the stream args channels for proper swig'ing checks. diff --git a/gr-uhd/swig/uhd_swig.i b/gr-uhd/swig/uhd_swig.i index c98416f307..4eaef9112d 100644 --- a/gr-uhd/swig/uhd_swig.i +++ b/gr-uhd/swig/uhd_swig.i @@ -84,6 +84,21 @@ %include <uhd/types/time_spec.hpp> +%extend uhd::time_spec_t{ + uhd::time_spec_t __add__(const uhd::time_spec_t &what) + { + uhd::time_spec_t temp = *self; + temp += what; + return temp; + } + uhd::time_spec_t __sub__(const uhd::time_spec_t &what) + { + uhd::time_spec_t temp = *self; + temp -= what; + return temp; + } +}; + %include <uhd/types/stream_cmd.hpp> %include <uhd/types/clock_config.hpp> diff --git a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt index 1d2e37b6a6..50cba851ae 100644 --- a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt +++ b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt @@ -84,6 +84,7 @@ set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks) # Find gnuradio build dependencies ######################################################################## find_package(CppUnit) +find_package(Doxygen) # Search for GNU Radio and its components and versions. Add any # components required to the list of GR_REQUIRED_COMPONENTS (in all @@ -97,6 +98,15 @@ if(NOT CPPUNIT_FOUND) endif() ######################################################################## +# Setup doxygen option +######################################################################## +if(DOXYGEN_FOUND) + option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) +else(DOXYGEN_FOUND) + option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) +endif(DOXYGEN_FOUND) + +######################################################################## # Setup the include and linker paths ######################################################################## include_directories( diff --git a/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.in b/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.in index 71a6bb920b..55336d5f1d 100644 --- a/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.in +++ b/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.in @@ -1,14 +1,16 @@ -# Doxyfile 1.5.7.1 +# Doxyfile 1.8.4 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project +# doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored +# All text after a double hash (##) is considered a comment and is placed +# in front of the TAG it is preceding . +# All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") +# Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options @@ -22,8 +24,9 @@ DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. PROJECT_NAME = "GNU Radio's HOWTO Package" @@ -33,6 +36,19 @@ PROJECT_NAME = "GNU Radio's HOWTO Package" PROJECT_NUMBER = +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location @@ -54,11 +70,11 @@ CREATE_SUBDIRS = NO # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, -# Spanish, Swedish, and Ukrainian. +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English @@ -112,7 +128,9 @@ FULL_PATH_NAMES = NO # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the -# path to strip. +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. STRIP_FROM_PATH = @@ -126,7 +144,7 @@ STRIP_FROM_PATH = STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO @@ -181,6 +199,13 @@ TAB_SIZE = 8 ALIASES = +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list @@ -207,11 +232,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES @@ -227,10 +281,10 @@ CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. @@ -251,6 +305,22 @@ DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct @@ -261,21 +331,16 @@ SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 4 +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options @@ -284,7 +349,7 @@ SYMBOL_CACHE_SIZE = 4 # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES @@ -293,6 +358,11 @@ EXTRACT_ALL = YES EXTRACT_PRIVATE = NO +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. @@ -315,7 +385,7 @@ EXTRACT_LOCAL_METHODS = NO # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. +# anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO @@ -375,6 +445,12 @@ HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. @@ -394,6 +470,16 @@ SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. @@ -410,6 +496,15 @@ SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. @@ -435,15 +530,16 @@ GENERATE_BUGLIST = NO GENERATE_DEPRECATEDLIST= NO # The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in +# the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the +# The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. @@ -455,12 +551,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. @@ -468,7 +558,8 @@ SHOW_DIRECTORIES = NO SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = NO @@ -483,15 +574,26 @@ SHOW_NAMESPACES = NO FILE_VERSION_FILTER = -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- @@ -520,7 +622,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for +# The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of @@ -552,7 +654,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @top_srcdir@ @top_builddir@ +INPUT = @top_srcdir@ \ + @top_builddir@ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -566,8 +669,9 @@ INPUT_ENCODING = UTF-8 # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.h \ *.dox @@ -578,18 +682,20 @@ FILE_PATTERNS = *.h \ RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should +# The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. EXCLUDE = @abs_top_builddir@/docs/doxygen/html \ - @abs_top_builddir@/docs/doxygen/xml \ + @abs_top_builddir@/docs/doxygen/xml \ @abs_top_builddir@/docs/doxygen/other/doxypy.py \ - @abs_top_builddir@/_CPack_Packages \ + @abs_top_builddir@/_CPack_Packages \ @abs_top_srcdir@/cmake -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO @@ -667,17 +773,22 @@ IMAGE_PATH = # by executing (via popen()) the command <filter> <input-file>, where <filter> # is the value of the INPUT_FILTER tag, and <input-file> is the name of an # input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = *.py=@top_srcdir@/doc/doxygen/other/doxypy.py @@ -687,6 +798,21 @@ FILTER_PATTERNS = *.py=@top_srcdir@/doc/doxygen/other/doxypy.py FILTER_SOURCE_FILES = NO +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- @@ -705,7 +831,7 @@ INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. +# fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = NO @@ -724,7 +850,8 @@ REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. +# link to the source code. +# Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES @@ -788,7 +915,14 @@ HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a -# standard header. +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = @@ -800,27 +934,80 @@ HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 -HTML_ALIGN_MEMBERS = YES +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# page has loaded. HTML_DYNAMIC_SECTIONS = NO +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). @@ -829,7 +1016,8 @@ HTML_DYNAMIC_SECTIONS = NO # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. GENERATE_DOCSET = NO @@ -847,6 +1035,16 @@ DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) @@ -891,10 +1089,10 @@ BINARY_TOC = NO TOC_EXPAND = YES -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO @@ -906,57 +1104,99 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#namespace">Qt Help Project / Namespace</a>. +# http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>. +# http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file . +# .qhp file. QHG_LOCATION = -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. -DISABLE_INDEX = YES +GENERATE_ECLIPSEHELP = NO -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. -ENUM_VALUES_PER_LINE = 4 +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = YES # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. -# If the tag value is set to FRAME, a side panel will be generated +# If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. Other possible values -# for this tag are: HIERARCHIES, which will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list; -# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which -# disables this behavior completely. For backwards compatibility with previous -# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE -# respectively. +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = YES +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 180 +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need @@ -965,6 +1205,112 @@ TREEVIEW_WIDTH = 180 FORMULA_FONTSIZE = 10 +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- @@ -982,6 +1328,9 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. LATEX_CMD_NAME = latex @@ -998,8 +1347,8 @@ MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. PAPER_TYPE = letter @@ -1015,6 +1364,20 @@ EXTRA_PACKAGES = LATEX_HEADER = +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references @@ -1041,6 +1404,19 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1072,7 +1448,7 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's +# Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. @@ -1147,6 +1523,21 @@ XML_DTD = XML_PROGRAMLISTING = NO #--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -1177,8 +1568,10 @@ GENERATE_PERLMOD = NO PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. @@ -1215,7 +1608,7 @@ MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. +# pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES @@ -1245,15 +1638,15 @@ PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES @@ -1261,20 +1654,18 @@ SKIP_FUNCTION_MACROS = YES # Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. TAGFILES = @@ -1295,6 +1686,12 @@ ALLEXTERNALS = NO EXTERNAL_GROUPS = YES +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). @@ -1307,9 +1704,8 @@ PERL_PATH = /usr/bin/perl # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES @@ -1335,33 +1731,38 @@ HIDE_UNDOC_RELATIONS = YES HAVE_DOT = @HAVE_DOT@ -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 -DOT_FONTNAME = FreeSans +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. +# CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES @@ -1383,6 +1784,15 @@ GROUP_GRAPHS = YES UML_LOOK = NO +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. @@ -1419,11 +1829,11 @@ CALL_GRAPH = NO CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. +# will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. @@ -1431,11 +1841,22 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. @@ -1447,6 +1868,12 @@ DOT_PATH = DOTFILE_DIRS = +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is @@ -1493,12 +1920,3 @@ GENERATE_LEGEND = YES # the various graphs. DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.swig_doc.in b/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.swig_doc.in index 50b8aa81d6..57736d7d0c 100644 --- a/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.swig_doc.in +++ b/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.swig_doc.in @@ -1,14 +1,16 @@ -# Doxyfile 1.6.1 +# Doxyfile 1.8.4 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project +# doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored +# All text after a double hash (##) is considered a comment and is placed +# in front of the TAG it is preceding . +# All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") +# Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options @@ -22,8 +24,9 @@ DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. PROJECT_NAME = @CPACK_PACKAGE_NAME@ @@ -33,6 +36,19 @@ PROJECT_NAME = @CPACK_PACKAGE_NAME@ PROJECT_NUMBER = @CPACK_PACKAGE_VERSION@ +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location @@ -56,9 +72,9 @@ CREATE_SUBDIRS = NO # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English @@ -112,7 +128,9 @@ FULL_PATH_NAMES = YES # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the -# path to strip. +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. STRIP_FROM_PATH = @@ -126,7 +144,7 @@ STRIP_FROM_PATH = STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO @@ -181,6 +199,13 @@ TAB_SIZE = 8 ALIASES = +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list @@ -207,22 +232,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. EXTENSION_MAPPING = +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES @@ -238,10 +281,10 @@ CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. @@ -262,6 +305,22 @@ DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct @@ -272,21 +331,16 @@ SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options @@ -295,7 +349,7 @@ SYMBOL_CACHE_SIZE = 0 # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES @@ -304,6 +358,11 @@ EXTRACT_ALL = YES EXTRACT_PRIVATE = NO +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. @@ -326,7 +385,7 @@ EXTRACT_LOCAL_METHODS = NO # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. +# anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO @@ -386,6 +445,12 @@ HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. @@ -405,7 +470,13 @@ SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO @@ -425,6 +496,15 @@ SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. @@ -450,15 +530,16 @@ GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in +# the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the +# The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. @@ -470,12 +551,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. @@ -499,15 +574,26 @@ SHOW_NAMESPACES = YES FILE_VERSION_FILTER = -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- @@ -536,7 +622,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for +# The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of @@ -582,8 +668,9 @@ INPUT_ENCODING = UTF-8 # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.h @@ -593,14 +680,16 @@ FILE_PATTERNS = *.h RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should +# The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. EXCLUDE = -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO @@ -653,8 +742,10 @@ IMAGE_PATH = # is the value of the INPUT_FILTER tag, and <input-file> is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. +# If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. INPUT_FILTER = @@ -664,8 +755,8 @@ INPUT_FILTER = # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = @@ -675,6 +766,21 @@ FILTER_PATTERNS = FILTER_SOURCE_FILES = NO +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- @@ -693,7 +799,7 @@ INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. +# fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES @@ -777,7 +883,14 @@ HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a -# standard header. +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = @@ -789,27 +902,80 @@ HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. HTML_STYLESHEET = -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 -HTML_ALIGN_MEMBERS = YES +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# page has loaded. HTML_DYNAMIC_SECTIONS = NO +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). @@ -818,7 +984,8 @@ HTML_DYNAMIC_SECTIONS = NO # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. GENERATE_DOCSET = NO @@ -836,6 +1003,16 @@ DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) @@ -880,10 +1057,10 @@ BINARY_TOC = NO TOC_EXPAND = NO -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO @@ -905,20 +1082,24 @@ QHP_NAMESPACE = QHP_VIRTUAL_FOLDER = doc -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. QHP_CUST_FILTER_ATTRS = -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's # filter section matches. -# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. QHP_SECT_FILTER_ATTRS = @@ -929,16 +1110,30 @@ QHP_SECT_FILTER_ATTRS = QHG_LOCATION = -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. -DISABLE_INDEX = NO +GENERATE_ECLIPSEHELP = NO -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. -ENUM_VALUES_PER_LINE = 4 +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. @@ -947,13 +1142,17 @@ ENUM_VALUES_PER_LINE = 4 # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. -USE_INLINE_TREES = NO +ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree @@ -961,6 +1160,11 @@ USE_INLINE_TREES = NO TREEVIEW_WIDTH = 250 +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need @@ -969,13 +1173,112 @@ TREEVIEW_WIDTH = 250 FORMULA_FONTSIZE = 10 -# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) -# there is already a search function so this one should typically -# be disabled. +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- @@ -993,6 +1296,9 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. LATEX_CMD_NAME = latex @@ -1009,8 +1315,8 @@ MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. PAPER_TYPE = a4wide @@ -1026,6 +1332,20 @@ EXTRA_PACKAGES = LATEX_HEADER = +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references @@ -1052,10 +1372,19 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1087,7 +1416,7 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's +# Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. @@ -1162,6 +1491,21 @@ XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -1232,7 +1576,7 @@ MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. +# pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES @@ -1262,15 +1606,15 @@ PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES @@ -1278,22 +1622,18 @@ SKIP_FUNCTION_MACROS = YES # Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. TAGFILES = @@ -1314,6 +1654,12 @@ ALLEXTERNALS = NO EXTERNAL_GROUPS = YES +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). @@ -1326,9 +1672,8 @@ PERL_PATH = /usr/bin/perl # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES @@ -1354,33 +1699,38 @@ HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. -DOT_FONTNAME = FreeSans +DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. +# CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES @@ -1402,6 +1752,15 @@ GROUP_GRAPHS = YES UML_LOOK = NO +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. @@ -1438,11 +1797,11 @@ CALL_GRAPH = NO CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. +# will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. @@ -1450,11 +1809,22 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. @@ -1466,6 +1836,12 @@ DOT_PATH = DOTFILE_DIRS = +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is diff --git a/gr-vocoder/examples/codec2_audio_loopback.py b/gr-vocoder/examples/codec2_audio_loopback.py index bf95f39ce9..b63d508025 100755 --- a/gr-vocoder/examples/codec2_audio_loopback.py +++ b/gr-vocoder/examples/codec2_audio_loopback.py @@ -24,14 +24,15 @@ from gnuradio import gr from gnuradio import audio from gnuradio import blocks from gnuradio import vocoder +from gnuradio.vocoder import codec2 def build_graph(): tb = gr.top_block() src = audio.source(8000) src_scale = blocks.multiply_const_ff(32767) f2s = blocks.float_to_short() - enc = vocoder.codec2_encode_sp() - dec = vocoder.codec2_decode_ps() + enc = vocoder.codec2_encode_sp(codec2.MODE_2400) + dec = vocoder.codec2_decode_ps(codec2.MODE_2400) s2f = blocks.short_to_float() sink_scale = blocks.multiply_const_ff(1.0/32767.) sink = audio.sink(8000) diff --git a/gr-vocoder/grc/vocoder_codec2_decode_ps.xml b/gr-vocoder/grc/vocoder_codec2_decode_ps.xml index 8b5f348671..b6e10ef8ba 100644 --- a/gr-vocoder/grc/vocoder_codec2_decode_ps.xml +++ b/gr-vocoder/grc/vocoder_codec2_decode_ps.xml @@ -8,11 +8,42 @@ <name>CODEC2 Audio Decoder</name> <key>vocoder_codec2_decode_ps</key> <import>from gnuradio import vocoder</import> - <make>vocoder.codec2_decode_ps()</make> + <import>from gnuradio.vocoder import codec2</import> + <make>vocoder.codec2_decode_ps($mode)</make> + <param> + <name>Bit rate</name> + <key>mode</key> + <value>codec2.MODE_2400</value> + <type>int</type> + <option> + <name>3200 bps</name> + <key>codec2.MODE_3200</key> + </option> + <option> + <name>2400 bps</name> + <key>codec2.MODE_2400</key> + </option> + <option> + <name>1600 bps</name> + <key>codec2.MODE_1600</key> + </option> + <option> + <name>1400 bps</name> + <key>codec2.MODE_1400</key> + </option> + <option> + <name>1300 bps</name> + <key>codec2.MODE_1300</key> + </option> + <option> + <name>1200 bps</name> + <key>codec2.MODE_1200</key> + </option> + </param> <sink> <name>in</name> <type>byte</type> - <vlen>50</vlen> + <vlen>{ 0: 64, 1: 48, 2: 64, 3: 56, 4: 52, 5: 48 }[$mode]</vlen> </sink> <source> <name>out</name> diff --git a/gr-vocoder/grc/vocoder_codec2_encode_sp.xml b/gr-vocoder/grc/vocoder_codec2_encode_sp.xml index 0fb0ecc2ff..6af54fa586 100644 --- a/gr-vocoder/grc/vocoder_codec2_encode_sp.xml +++ b/gr-vocoder/grc/vocoder_codec2_encode_sp.xml @@ -8,7 +8,38 @@ <name>CODEC2 Audio Encoder</name> <key>vocoder_codec2_encode_sp</key> <import>from gnuradio import vocoder</import> - <make>vocoder.codec2_encode_sp()</make> + <import>from gnuradio.vocoder import codec2</import> + <make>vocoder.codec2_encode_sp($mode)</make> + <param> + <name>Bit rate</name> + <key>mode</key> + <value>codec2.MODE_2400</value> + <type>int</type> + <option> + <name>3200 bps</name> + <key>codec2.MODE_3200</key> + </option> + <option> + <name>2400 bps</name> + <key>codec2.MODE_2400</key> + </option> + <option> + <name>1600 bps</name> + <key>codec2.MODE_1600</key> + </option> + <option> + <name>1400 bps</name> + <key>codec2.MODE_1400</key> + </option> + <option> + <name>1300 bps</name> + <key>codec2.MODE_1300</key> + </option> + <option> + <name>1200 bps</name> + <key>codec2.MODE_1200</key> + </option> + </param> <sink> <name>in</name> <type>short</type> @@ -16,7 +47,7 @@ <source> <name>out</name> <type>byte</type> - <vlen>50</vlen> + <vlen>{ 0: 64, 1: 48, 2: 64, 3: 56, 4: 52, 5: 48 }[$mode]</vlen> </source> </block> diff --git a/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt b/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt index ea0562f36f..1ad2f711fc 100644 --- a/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt +++ b/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt @@ -24,6 +24,7 @@ install(FILES api.h alaw_decode_bs.h alaw_encode_sb.h + codec2.h codec2_decode_ps.h codec2_encode_sp.h cvsd_decode_bs.h diff --git a/gr-vocoder/include/gnuradio/vocoder/codec2.h b/gr-vocoder/include/gnuradio/vocoder/codec2.h new file mode 100644 index 0000000000..ca09e4dfc0 --- /dev/null +++ b/gr-vocoder/include/gnuradio/vocoder/codec2.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 _VOCODER_CODEC2_H_ +#define _VOCODER_CODEC2_H_ + +#include <gnuradio/vocoder/api.h> + +extern "C" { +#include "../lib/codec2/codec2.h" +} + +namespace gr { + namespace vocoder { + + class VOCODER_API codec2 { + public: + + enum bit_rate { + MODE_3200 = CODEC2_MODE_3200, + MODE_2400 = CODEC2_MODE_2400, + MODE_1600 = CODEC2_MODE_1600, + MODE_1400 = CODEC2_MODE_1400, + MODE_1300 = CODEC2_MODE_1300, + MODE_1200 = CODEC2_MODE_1200, + }; + + private: + + }; + + } /* namespace vocoder */ +} /* namespace gr */ + +#endif /* _VOCODER_CODEC2_H_ */ diff --git a/gr-vocoder/include/gnuradio/vocoder/codec2_decode_ps.h b/gr-vocoder/include/gnuradio/vocoder/codec2_decode_ps.h index 041877174b..49add0f9ee 100644 --- a/gr-vocoder/include/gnuradio/vocoder/codec2_decode_ps.h +++ b/gr-vocoder/include/gnuradio/vocoder/codec2_decode_ps.h @@ -24,6 +24,7 @@ #define INCLUDED_VOCODER_CODEC2_DECODE_PS_H #include <gnuradio/vocoder/api.h> +#include <gnuradio/vocoder/codec2.h> #include <gnuradio/sync_interpolator.h> namespace gr { @@ -33,7 +34,7 @@ namespace gr { * \brief CODEC2 Vocoder Decoder * \ingroup audio_blk * - * Input: A vector of 50 unpacked bits forming a Codec2 frame. + * Input: A vector of unpacked bits forming a Codec2 frame. * * Output: 16-bit short values of an audio signal with sampling rate 8 kHz. * @@ -47,8 +48,10 @@ namespace gr { /*! * \brief Make Codec2 decoder block. + * + * \param mode Encoded bit rate/mode */ - static sptr make(); + static sptr make(int mode=codec2::MODE_2400); }; } /* namespace vocoder */ diff --git a/gr-vocoder/include/gnuradio/vocoder/codec2_encode_sp.h b/gr-vocoder/include/gnuradio/vocoder/codec2_encode_sp.h index 12b91b0428..12ec00c687 100644 --- a/gr-vocoder/include/gnuradio/vocoder/codec2_encode_sp.h +++ b/gr-vocoder/include/gnuradio/vocoder/codec2_encode_sp.h @@ -24,6 +24,7 @@ #define INCLUDED_VOCODER_CODEC2_ENCODE_SP_H #include <gnuradio/vocoder/api.h> +#include <gnuradio/vocoder/codec2.h> #include <gnuradio/sync_decimator.h> namespace gr { @@ -35,13 +36,9 @@ namespace gr { * * Input: Speech (audio) signal as 16-bit shorts, sampling rate 8 kHz. * - * Output: Vector of 50 unpacked bits, forming one Codec2 frame, per 160 input samples. - * - * Note that the Codec2 library produces 7 bytes with a total of 50 bits - * per frame. The bits are MSB-first on these 7 bytes, so the first item - * of the output vector is the MSB of the first byte of the frame. - * If this block is combined with the gr::vocoder::codec2_decode_ps block, - * this will work out of the box. + * Output: Vector of unpacked bits, forming one Codec2 frame, per 160 + * input samples (in 2400 and 3200 bps modes) or per 320 input + * samples (in 1200, 1300, 1400 and 1600 bps modes). * */ class VOCODER_API codec2_encode_sp : virtual public sync_decimator @@ -52,8 +49,10 @@ namespace gr { /*! * \brief Make Codec2 encoder block. + * + * \param mode Encoded bit rate/mode */ - static sptr make(); + static sptr make(int mode=codec2::MODE_2400); }; } /* namespace vocoder */ diff --git a/gr-vocoder/lib/CMakeLists.txt b/gr-vocoder/lib/CMakeLists.txt index 08ff4108d3..e11b143c51 100644 --- a/gr-vocoder/lib/CMakeLists.txt +++ b/gr-vocoder/lib/CMakeLists.txt @@ -18,6 +18,62 @@ # Boston, MA 02110-1301, USA. ######################################################################## +# Check for system libgsm.... +######################################################################## +if(NOT GR_USE_SYSTEM_LIBGSM) + find_path(LIBGSM_INCLUDE_DIR NAMES gsm.h + PATHS + ${LIBGSM_PKG_INCLUDE_DIRS} + /usr/include/gsm + /usr/include + ) + + find_library(LIBGSM_LIBRARIES NAMES gsm + PATHS + ${LIBGSM_PKG_LIBRARY_DIRS} + /usr/lib + ) + +if(LIBGSM_INCLUDE_DIR AND LIBGSM_LIBRARIES) + set(GR_USE_SYSTEM_LIBGSM TRUE CACHE INTERNAL "system libgsm found") + message(STATUS "Found libgsm: ${LIBGSM_INCLUDE_DIR}, ${LIBGSM_LIBRARIES}") +else(LIBGSM_INCLUDE_DIR AND LIBGSM_LIBRARIES) + set(GR_USE_SYSTEM_LIBGSM FALSE CACHE INTERNAL "system libgsm found") + message(STATUS "system libgsm not found.") +endif(LIBGSM_INCLUDE_DIR AND LIBGSM_LIBRARIES) + +mark_as_advanced(LIBGSM_INCLUDE_DIR LIBGSM_LIBRARIES) +endif(NOT GR_USE_SYSTEM_LIBGSM) + +######################################################################## +# Check for system libcodec2.... +######################################################################## +if(NOT GR_USE_SYSTEM_LIBCODEC2) + find_path(LIBCODEC2_INCLUDE_DIR NAMES codec2.h + PATHS + ${LIBCODEC2_PKG_INCLUDE_DIRS} + /usr/include/codec2 + /usr/include + ) + + find_library(LIBCODEC2_LIBRARIES NAMES codec2 + PATHS + ${LIBCODEC2_PKG_LIBRARY_DIRS} + /usr/lib + ) + +if(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES) + set(GR_USE_SYSTEM_LIBCODEC2 TRUE CACHE INTERNAL "system libcodec2 found") + message(STATUS "Found libcodec2: ${LIBCODEC2_INCLUDE_DIR}, ${LIBCODEC2_LIBRARIES}") +else(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES) + set(GR_USE_SYSTEM_LIBCODEC2 FALSE CACHE INTERNAL "system libcodec2 found") + message(STATUS "system libcodec2 not found.") +endif(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES) + +mark_as_advanced(LIBCODEC2_INCLUDE_DIR LIBCODEC2_LIBRARIES) +endif(NOT GR_USE_SYSTEM_LIBCODEC2) + +######################################################################## # Setup the include and linker paths ######################################################################## include_directories( @@ -44,6 +100,7 @@ link_directories(${LOG4CPP_LIBRARY_DIRS}) list(APPEND gr_vocoder_sources alaw_decode_bs_impl.cc alaw_encode_sb_impl.cc + codec2.cc codec2_decode_ps_impl.cc codec2_encode_sp_impl.cc cvsd_decode_bs_impl.cc @@ -77,9 +134,15 @@ endif(MSVC) ######################################################################## # Include subdirs rather to populate to the sources lists. ######################################################################## -GR_INCLUDE_SUBDIRECTORY(codec2) GR_INCLUDE_SUBDIRECTORY(g7xx) -GR_INCLUDE_SUBDIRECTORY(gsm) + +if(NOT GR_USE_SYSTEM_LIBCODEC2) + GR_INCLUDE_SUBDIRECTORY(codec2) +endif(NOT GR_USE_SYSTEM_LIBCODEC2) + +if(NOT GR_USE_SYSTEM_LIBGSM) + GR_INCLUDE_SUBDIRECTORY(gsm) +endif(NOT GR_USE_SYSTEM_LIBGSM) list(APPEND vocoder_libs gnuradio-runtime @@ -87,6 +150,14 @@ list(APPEND vocoder_libs ${LOG4CPP_LIBRARIES} ) +if(GR_USE_SYSTEM_LIBCODEC2) + list(APPEND vocoder_libs ${LIBCODEC2_LIBRARIES}) +endif(GR_USE_SYSTEM_LIBCODEC2) + +if(GR_USE_SYSTEM_LIBGSM) + list(APPEND vocoder_libs ${LIBGSM_LIBRARIES}) +endif(GR_USE_SYSTEM_LIBGSM) + add_library(gnuradio-vocoder SHARED ${gr_vocoder_sources}) target_link_libraries(gnuradio-vocoder ${vocoder_libs}) GR_LIBRARY_FOO(gnuradio-vocoder RUNTIME_COMPONENT "vocoder_runtime" DEVEL_COMPONENT "vocoder_devel") diff --git a/gr-vocoder/lib/codec2.cc b/gr-vocoder/lib/codec2.cc new file mode 100644 index 0000000000..6d0ef61352 --- /dev/null +++ b/gr-vocoder/lib/codec2.cc @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2007,2008,2012,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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gnuradio/vocoder/codec2.h> + +namespace gr { + namespace vocoder { + + } /* namespace vocoder */ +} /* namespace gr */ diff --git a/gr-vocoder/lib/codec2/CMakeLists.txt b/gr-vocoder/lib/codec2/CMakeLists.txt index f4ccd22401..ac25b7cce7 100644 --- a/gr-vocoder/lib/codec2/CMakeLists.txt +++ b/gr-vocoder/lib/codec2/CMakeLists.txt @@ -73,20 +73,101 @@ add_custom_command( ) ######################################################################## -# Create codebookdvq +# Create codebookvq ######################################################################## -set(CODEBOOKSDVQ - ${CMAKE_CURRENT_SOURCE_DIR}/codebook/dlsp1.txt - ${CMAKE_CURRENT_SOURCE_DIR}/codebook/dlsp2.txt - ${CMAKE_CURRENT_SOURCE_DIR}/codebook/dlsp3.txt - ${CMAKE_CURRENT_SOURCE_DIR}/codebook/dlsp4.txt - ${CMAKE_CURRENT_SOURCE_DIR}/codebook/dlsp5.txt +set(CODEBOOKSVQ + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lsp1.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lsp2.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lsp3.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lsp4.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lsp45678910.txt +) + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookvq.c + DEPENDS generate_codebook ${CODEBOOKSVQ} + COMMAND generate_codebook lsp_cbvq ${CODEBOOKSVQ} > ${CMAKE_CURRENT_BINARY_DIR}/codebookvq.c +) + +######################################################################## +# Create codebookjnd +######################################################################## +set(CODEBOOKSJND + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lsp1.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lsp2.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lsp3.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lsp4.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspjnd5-10.txt +) + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookjnd.c + DEPENDS generate_codebook ${CODEBOOKSJND} + COMMAND generate_codebook lsp_cbjnd ${CODEBOOKSJND} > ${CMAKE_CURRENT_BINARY_DIR}/codebookjnd.c +) + +######################################################################## +# Create codebookjvm +######################################################################## +set(CODEBOOKSJVM + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspjvm1.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspjvm2.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspjvm3.txt +) + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookjvm.c + DEPENDS generate_codebook ${CODEBOOKSJVM} + COMMAND generate_codebook lsp_cbjvm ${CODEBOOKSJVM} > ${CMAKE_CURRENT_BINARY_DIR}/codebookjvm.c +) + +######################################################################## +# Create codebookvqanssi +######################################################################## +set(CODEBOOKSVQANSSI + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspvqanssi1.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspvqanssi2.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspvqanssi3.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspvqanssi4.txt +) + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookvqanssi.c + DEPENDS generate_codebook ${CODEBOOKSVQANSSI} + COMMAND generate_codebook lsp_cbvqanssi ${CODEBOOKSVQANSSI} > ${CMAKE_CURRENT_BINARY_DIR}/codebookvqanssi.c +) + +######################################################################## +# Create codebookdt +######################################################################## +set(CODEBOOKSDT + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt1.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt2.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt3.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt4.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt5.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt6.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt7.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt8.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt9.txt + ${CMAKE_CURRENT_SOURCE_DIR}/codebook/lspdt10.txt +) + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookdt.c + DEPENDS generate_codebook ${CODEBOOKSDT} + COMMAND generate_codebook lsp_cbdt ${CODEBOOKSDT} > ${CMAKE_CURRENT_BINARY_DIR}/codebookdt.c ) +######################################################################## +# Create codebookge +######################################################################## +set(CODEBOOKSGE ${CMAKE_CURRENT_SOURCE_DIR}/codebook/gecb.txt) + add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookdvq.c - DEPENDS generate_codebook ${CODEBOOKSDVQ} - COMMAND generate_codebook lsp_cbdvq ${CODEBOOKSDVQ} > ${CMAKE_CURRENT_BINARY_DIR}/codebookdvq.c + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookge.c + DEPENDS generate_codebook ${CODEBOOKSGE} + COMMAND generate_codebook ge_cb ${CODEBOOKSGE} > ${CMAKE_CURRENT_BINARY_DIR}/codebookge.c ) ######################################################################## @@ -95,7 +176,13 @@ add_custom_command( list(APPEND gr_vocoder_sources ${CMAKE_CURRENT_BINARY_DIR}/codebook.c ${CMAKE_CURRENT_BINARY_DIR}/codebookd.c - ${CMAKE_CURRENT_BINARY_DIR}/codebookdvq.c + ${CMAKE_CURRENT_BINARY_DIR}/codebookvq.c + ${CMAKE_CURRENT_BINARY_DIR}/codebookjnd.c + ${CMAKE_CURRENT_BINARY_DIR}/codebookjvm.c + ${CMAKE_CURRENT_BINARY_DIR}/codebookvqanssi.c + ${CMAKE_CURRENT_BINARY_DIR}/codebookdt.c + ${CMAKE_CURRENT_BINARY_DIR}/codebookge.c + ${CMAKE_CURRENT_SOURCE_DIR}/dump.c ${CMAKE_CURRENT_SOURCE_DIR}/lpc.c @@ -103,7 +190,8 @@ list(APPEND gr_vocoder_sources ${CMAKE_CURRENT_SOURCE_DIR}/postfilter.c ${CMAKE_CURRENT_SOURCE_DIR}/sine.c ${CMAKE_CURRENT_SOURCE_DIR}/codec2.c - ${CMAKE_CURRENT_SOURCE_DIR}/fft.c + ${CMAKE_CURRENT_SOURCE_DIR}/fifo.c + ${CMAKE_CURRENT_SOURCE_DIR}/fdmdv.c ${CMAKE_CURRENT_SOURCE_DIR}/kiss_fft.c ${CMAKE_CURRENT_SOURCE_DIR}/interp.c ${CMAKE_CURRENT_SOURCE_DIR}/lsp.c diff --git a/gr-vocoder/lib/codec2/ampexp.c b/gr-vocoder/lib/codec2/ampexp.c new file mode 100644 index 0000000000..ccec6dce8e --- /dev/null +++ b/gr-vocoder/lib/codec2/ampexp.c @@ -0,0 +1,1093 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: ampexp.c + AUTHOR......: David Rowe + DATE CREATED: 7 August 2012 + + Functions for experimenting with amplitude quantisation. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2012 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not,see <http://www.gnu.org/licenses/>. +*/ + + +#include <assert.h> +#include <ctype.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "ampexp.h" + + +#define PRED_COEFF 0.9 + +/* states for amplitude experiments */ + +struct codebook { + unsigned int k; + unsigned int log2m; + unsigned int m; + float *cb; + unsigned int offset; +}; + +struct AEXP { + float A_prev[MAX_AMP]; + int frames; + float snr; + int snr_n; + float var; + int var_n; + float vq_var; + int vq_var_n; + struct codebook *vq1,*vq2,*vq3,*vq4,*vq5; + + int indexes[5][3]; + MODEL model[3]; + float mag[3]; + MODEL model_uq[3]; +}; + + +/*---------------------------------------------------------------------------*\ + + Bruce Perens' funcs to load codebook files + +\*---------------------------------------------------------------------------*/ + + +static const char format[] = +"The table format must be:\n" +"\tTwo integers describing the dimensions of the codebook.\n" +"\tThen, enough numbers to fill the specified dimensions.\n"; + +static float get_float(FILE * in, const char * name, char * * cursor, char * buffer, int size) +{ + for ( ; ; ) { + char * s = *cursor; + char c; + + while ( (c = *s) != '\0' && !isdigit(c) && c != '-' && c != '.' ) + s++; + + /* Comments start with "#" and continue to the end of the line. */ + if ( c != '\0' && c != '#' ) { + char * end = 0; + float f = 0; + + f = strtod(s, &end); + + if ( end != s ) + *cursor = end; + return f; + } + + if ( fgets(buffer, size, in) == NULL ) { + fprintf(stderr, "%s: Format error. %s\n", name, format); + exit(1); + } + *cursor = buffer; + } +} + +static struct codebook *load(const char * name) +{ + FILE *file; + char line[2048]; + char *cursor = line; + struct codebook *b = malloc(sizeof(struct codebook)); + int i; + int size; + + file = fopen(name, "rt"); + assert(file != NULL); + + *cursor = '\0'; + + b->k = (int)get_float(file, name, &cursor, line, sizeof(line)); + b->m = (int)get_float(file, name ,&cursor, line, sizeof(line)); + size = b->k * b->m; + + b->cb = (float *)malloc(size * sizeof(float)); + + for ( i = 0; i < size; i++ ) { + b->cb[i] = get_float(file, name, &cursor, line, sizeof(line)); + } + + fclose(file); + + return b; +} + + +/*---------------------------------------------------------------------------* \ + + amp_experiment_create() + + Inits states for amplitude quantisation experiments. + +\*---------------------------------------------------------------------------*/ + +struct AEXP *amp_experiment_create() { + struct AEXP *aexp; + int i,j,m; + + aexp = (struct AEXP *)malloc(sizeof(struct AEXP)); + assert (aexp != NULL); + + for(i=0; i<MAX_AMP; i++) + aexp->A_prev[i] = 1.0; + aexp->frames = 0; + aexp->snr = 0.0; + aexp->snr_n = 0; + aexp->var = 0.0; + aexp->var_n = 0; + aexp->vq_var = 0.0; + aexp->vq_var_n = 0; + + //aexp->vq1 = load("amp_1_80_1024a.txt"); + //aexp->vq1 = load("../unittest/st1_10_1024.txt"); + //aexp->vq1 = load("../unittest/amp41_80_1024.txt"); + //aexp->vq1->offset = 40; + aexp->vq1 = load("../unittest/amp1_10_1024.txt"); + aexp->vq1->offset = 0; + aexp->vq2 = load("../unittest/amp11_20_1024.txt"); + aexp->vq2->offset = 10; + + aexp->vq3 = load("../unittest/amp21_40_1024.txt"); + aexp->vq3->offset = 20; + aexp->vq4 = load("../unittest/amp41_60_1024.txt"); + aexp->vq4->offset = 40; + aexp->vq5 = load("../unittest/amp61_80_256.txt"); + aexp->vq5->offset = 60; + + #ifdef CAND2_GS + //aexp->vq1 = load("../unittest/t1_amp1_20_1024.txt"); + //aexp->vq1 = load("../unittest/t2_amp1_20_1024.txt"); + aexp->vq1 = load("../unittest/amp1_20_1024.txt"); + aexp->vq1->offset = 0; + aexp->vq2 = load("../unittest/amp21_40_1024.txt"); + aexp->vq2->offset = 20; + aexp->vq3 = load("../unittest/amp41_60_1024.txt"); + aexp->vq3->offset = 40; + aexp->vq4 = load("../unittest/amp61_80_32.txt"); + aexp->vq4->offset = 60; + #endif + + //#define CAND2_GS + #ifdef CAND2_GS + aexp->vq1 = load("../unittest/amp1_20_1024.txt"); + aexp->vq2 = load("../unittest/amp21_40_1024.txt"); + aexp->vq3 = load("../unittest/amp41_80_1024.txt"); + aexp->vq4 = load("../unittest/amp61_80_32.txt"); + aexp->vq1->offset = 0; + aexp->vq2->offset = 20; + aexp->vq3->offset = 40; + aexp->vq4->offset = 60; + #endif + + //#define CAND1 + #ifdef CAND1 + aexp->vq1 = load("../unittest/amp1_10_128.txt"); + aexp->vq2 = load("../unittest/amp11_20_512.txt"); + aexp->vq3 = load("../unittest/amp21_40_1024.txt"); + aexp->vq4 = load("../unittest/amp41_60_1024.txt"); + aexp->vq5 = load("../unittest/amp61_80_32.txt"); + aexp->vq1->offset = 0; + aexp->vq2->offset = 10; + aexp->vq3->offset = 20; + aexp->vq4->offset = 40; + aexp->vq5->offset = 60; + #endif + + for(i=0; i<3; i++) { + for(j=0; j<5; j++) + aexp->indexes[j][i] = 0; + aexp->mag[i] = 1.0; + aexp->model[i].Wo = TWO_PI*100.0/8000.0; + aexp->model[i].L = floor(PI/aexp->model[i].Wo); + for(m=1; m<=MAX_AMP; m++) + aexp->model[i].A[m] = 10.0; + aexp->model_uq[i] = aexp->model[i]; + } + + return aexp; +} + + +/*---------------------------------------------------------------------------* \ + + amp_experiment_destroy() + +\*---------------------------------------------------------------------------*/ + +void amp_experiment_destroy(struct AEXP *aexp) { + assert(aexp != NULL); + if (aexp->snr != 0.0) + printf("snr: %4.2f dB\n", aexp->snr/aexp->snr_n); + if (aexp->var != 0.0) + printf("var...: %4.3f std dev...: %4.3f (%d amplitude samples)\n", + aexp->var/aexp->var_n, sqrt(aexp->var/aexp->var_n), aexp->var_n); + if (aexp->vq_var != 0.0) + printf("vq var: %4.3f std dev...: %4.3f (%d amplitude samples)\n", + aexp->vq_var/aexp->vq_var_n, sqrt(aexp->vq_var/aexp->vq_var_n), aexp->vq_var_n); + free(aexp); +} + + +/*---------------------------------------------------------------------------*\ + + Various test and experimental functions ................ + +\*---------------------------------------------------------------------------*/ + +/* + Quantisation noise simulation. Assume noise on amplitudes is a uniform + distribution, of +/- x dB. This means x = sqrt(3)*sigma. + + Note: for uniform distribution var = = sigma * sigma = (b-a)*(b-a)/12. +*/ + +static void add_quant_noise(struct AEXP *aexp, MODEL *model, int start, int end, float sigma_dB) +{ + int m; + float x_dB; + float noise_sam_dB; + float noise_sam_lin; + + x_dB = sqrt(3.0) * sigma_dB; + + for(m=start; m<=end; m++) { + noise_sam_dB = x_dB*(1.0 - 2.0*rand()/RAND_MAX); + //printf("%f\n", noise_sam_dB); + noise_sam_lin = pow(10.0, noise_sam_dB/20.0); + model->A[m] *= noise_sam_lin; + aexp->var += noise_sam_dB*noise_sam_dB; + aexp->var_n++; + } + +} + +/* + void print_sparse_pred_error() + + use to check pred error stats (e.g. of first 1kHz) in Octave: + + $ ./c2sim ../raw/hts1a.raw --ampexp > amppe.txt + + octave> load ../src/amppe.txt + octave> std(nonzeros(amppe(:,1:20))) + octave> hist(nonzeros(amppe(:,1:20)),20); + + */ + + +static void print_sparse_pred_error(struct AEXP *aexp, MODEL *model, float mag_thresh) +{ + int m, index; + float mag, error; + float sparse_pe[MAX_AMP]; + + mag = 0.0; + for(m=1; m<=model->L; m++) + mag += model->A[m]*model->A[m]; + mag = 10*log10(mag/model->L); + + if (mag > mag_thresh) { + for(m=0; m<MAX_AMP; m++) { + sparse_pe[m] = 0.0; + } + + for(m=1; m<=model->L; m++) { + assert(model->A[m] > 0.0); + error = PRED_COEFF*20.0*log10(aexp->A_prev[m]) - 20.0*log10(model->A[m]); + //error = 20.0*log10(model->A[m]) - mag; + + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe[index] = error; + } + + /* dump sparse amp vector */ + + for(m=0; m<MAX_AMP; m++) + printf("%f ", sparse_pe[m]); + printf("\n"); + } +} + + +static float frame_energy(MODEL *model, float *enormdB) { + int m; + float e, edB; + + e = 0.0; + for(m=1; m<=model->L; m++) + e += model->A[m]*model->A[m]; + edB = 10*log10(e); + + #define VER_E0 + + #ifdef VER_E0 + *enormdB = 10*log10(e/model->L); /* make high and low pitches have similar amps */ + #endif + + #ifdef VER_E1 + e = 0.0; + for(m=1; m<=model->L; m++) + e += 10*log10(model->A[m]*model->A[m]); + *enormdB = e; + #endif + + #ifdef VER_E2 + e = 0.0; + for(m=1; m<=model->L; m++) + e += 10*log10(model->A[m]*model->A[m]); + *enormdB = e/model->L; + #endif + //printf("%f\n", enormdB); + + return edB; +} + +static void print_sparse_amp_error(struct AEXP *aexp, MODEL *model, float edB_thresh) +{ + int m, index; + float edB, enormdB, error, dWo; + float sparse_pe[MAX_AMP]; + + edB = frame_energy(model, &enormdB); + //printf("%f\n", enormdB); + dWo = fabs((aexp->model_uq[2].Wo - aexp->model_uq[1].Wo)/aexp->model_uq[2].Wo); + + if ((edB > edB_thresh) && (dWo < 0.1)) { + for(m=0; m<MAX_AMP; m++) { + sparse_pe[m] = 0.0; + } + + for(m=1; m<=model->L; m++) { + assert(model->A[m] > 0.0); + error = 20.0*log10(model->A[m]) - enormdB; + + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe[index] = error; + } + + /* dump sparse amp vector */ + + for(m=0; m<MAX_AMP; m++) + printf("%f ", sparse_pe[m]); + printf("\n"); + } +} + + +int vq_amp(float cb[], float vec[], float weights[], int d, int e, float *se) +{ + float error; /* current error */ + int besti; /* best index so far */ + float best_error; /* best error so far */ + int i,j; + float diff, metric, best_metric; + + besti = 0; + best_metric = best_error = 1E32; + for(j=0; j<e; j++) { + metric = error = 0.0; + for(i=0; i<d; i++) { + if (vec[i] != 0.0) { + diff = (cb[j*d+i] - vec[i]); + error += diff*diff; + metric += weights[i]*diff*diff; + } + } + if (metric < best_metric) { + best_error = error; + best_metric = metric; + besti = j; + } + } + + *se += best_error; + + return(besti); +} + + +static int split_vq(float sparse_pe_out[], struct AEXP *aexp, struct codebook *vq, float weights[], float sparse_pe_in[]) +{ + int i, j, non_zero, vq_ind; + float se; + + vq_ind = vq_amp(vq->cb, &sparse_pe_in[vq->offset], &weights[vq->offset], vq->k, vq->m, &se); + printf("\n offset %d k %d m %d vq_ind %d j: ", vq->offset, vq->k, vq->m, vq_ind); + + non_zero = 0; + for(i=0, j=vq->offset; i<vq->k; i++,j++) { + if (sparse_pe_in[j] != 0.0) { + printf("%d ", j); + sparse_pe_in[j] -= vq->cb[vq->k * vq_ind + i]; + sparse_pe_out[j] += vq->cb[vq->k * vq_ind + i]; + non_zero++; + } + } + aexp->vq_var_n += non_zero; + return vq_ind; +} + + +static void sparse_vq_pred_error(struct AEXP *aexp, + MODEL *model +) +{ + int m, index; + float error, amp_dB, edB, enormdB; + float sparse_pe_in[MAX_AMP]; + float sparse_pe_out[MAX_AMP]; + float weights[MAX_AMP]; + + edB = frame_energy(model, &enormdB); + + for(m=0; m<MAX_AMP; m++) { + sparse_pe_in[m] = 0.0; + sparse_pe_out[m] = 0.0; + } + + for(m=1; m<=model->L; m++) { + assert(model->A[m] > 0.0); + error = PRED_COEFF*20.0*log10(aexp->A_prev[m]) - 20.0*log10(model->A[m]); + + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe_in[index] = error; + weights[index] = model->A[m]; + } + + /* vector quantise */ + + for(m=0; m<MAX_AMP; m++) { + sparse_pe_out[m] = sparse_pe_in[m]; + } + + //#define SIM_VQ + #ifndef SIM_VQ + split_vq(sparse_pe_out, aexp, aexp->vq1, weights, sparse_pe_in); + #else + for(m=aexp->vq->offset; m<aexp->vq->offset+aexp->vq->k; m++) { + if (sparse_pe_in[m] != 0.0) { + float error = 8*(1.0 - 2.0*rand()/RAND_MAX); + aexp->vq_var += error*error; + aexp->vq_var_n++; + sparse_pe_out[m] = sparse_pe_in[m] + error; + } + } + #endif + + if (edB > -100.0) + for(m=0; m<MAX_AMP; m++) { + if (sparse_pe_in[m] != 0.0) + aexp->vq_var += pow(sparse_pe_out[m] - sparse_pe_in[m], 2.0); + } + + /* transform quantised amps back */ + + for(m=1; m<=model->L; m++) { + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + amp_dB = PRED_COEFF*20.0*log10(aexp->A_prev[m]) - sparse_pe_out[index]; + //printf("in: %f out: %f\n", sparse_pe_in[index], sparse_pe_out[index]); + //printf("amp_dB: %f A[m] (dB) %f\n", amp_dB, 20.0*log10(model->A[m])); + model->A[m] = pow(10.0, amp_dB/20.0); + } + //exit(0); +} + + +static void split_error(struct AEXP *aexp, struct codebook *vq, float sparse_pe_in[], int ind) +{ + int i, j; + + for(i=0, j=vq->offset; i<vq->k; i++,j++) { + if (sparse_pe_in[j] != 0.0) { + sparse_pe_in[j] -= vq->cb[vq->k * ind + i]; + } + } +} + + +static void sparse_vq_amp(struct AEXP *aexp, MODEL *model) +{ + int m, index; + float error, amp_dB, enormdB; + float sparse_pe_in[MAX_AMP]; + float sparse_pe_out[MAX_AMP]; + float weights[MAX_AMP]; + + frame_energy(model, &enormdB); + + aexp->mag[2] = enormdB; + + for(m=0; m<MAX_AMP; m++) { + sparse_pe_in[m] = 0.0; + sparse_pe_out[m] = 0.0; + } + + for(m=1; m<=model->L; m++) { + assert(model->A[m] > 0.0); + error = 20.0*log10(model->A[m]) - enormdB; + + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe_in[index] = error; + weights[index] = pow(model->A[m],0.8); + } + + /* vector quantise */ + + for(m=0; m<MAX_AMP; m++) { + sparse_pe_out[m] = sparse_pe_in[m]; + } + + for(m=0; m<80; m++) + sparse_pe_out[m] = 0; + + #define SPLIT + #ifdef SPLIT + aexp->indexes[0][2] = split_vq(sparse_pe_out, aexp, aexp->vq1, weights, sparse_pe_in); + + aexp->indexes[1][2] = split_vq(sparse_pe_out, aexp, aexp->vq2, weights, sparse_pe_in); + aexp->indexes[2][2] = split_vq(sparse_pe_out, aexp, aexp->vq3, weights, sparse_pe_in); + aexp->indexes[3][2] = split_vq(sparse_pe_out, aexp, aexp->vq4, weights, sparse_pe_in); + aexp->indexes[4][2] = split_vq(sparse_pe_out, aexp, aexp->vq5, weights, sparse_pe_in); + #endif + //#define MULTISTAGE + #ifdef MULTISTAGE + aexp->indexes[0][2] = split_vq(sparse_pe_out, aexp, aexp->vq1, weights, sparse_pe_in); + aexp->indexes[1][2] = split_vq(sparse_pe_out, aexp, aexp->vq2, weights, sparse_pe_in); + aexp->indexes[2][2] = split_vq(sparse_pe_out, aexp, aexp->vq3, weights, sparse_pe_in); + //aexp->indexes[3][2] = split_vq(sparse_pe_out, aexp, aexp->vq4, weights, sparse_pe_in); + #endif + + for(m=0; m<MAX_AMP; m++) { + if (sparse_pe_in[m] != 0.0) + aexp->vq_var += pow(sparse_pe_out[m] - sparse_pe_in[m], 2.0); + } + + /* transform quantised amps back */ + + for(m=1; m<=model->L; m++) { + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + amp_dB = sparse_pe_out[index] + enormdB; + model->A[m] = pow(10.0, amp_dB/20.0); + } + //exit(0); +} + + +static void update_snr_calc(struct AEXP *aexp, MODEL *m1, MODEL *m2) +{ + int m; + float signal, noise, signal_dB; + + assert(m1->L == m2->L); + + signal = 0.0; noise = 1E-32; + for(m=1; m<=m1->L; m++) { + signal += m1->A[m]*m1->A[m]; + noise += pow(m1->A[m] - m2->A[m], 2.0); + //printf("%f %f\n", before[m], model->phi[m]); + } + signal_dB = 10*log10(signal); + if (signal_dB > -100.0) { + aexp->snr += 10.0*log10(signal/noise); + aexp->snr_n++; + } +} + + +/* gain/shape vq search. Returns index of best gain. Gain is additive (as we use log quantisers) */ + +int gain_shape_vq_amp(float cb[], float vec[], float weights[], int d, int e, float *se, float *best_gain) +{ + float error; /* current error */ + int besti; /* best index so far */ + float best_error; /* best error so far */ + int i,j,m; + float diff, metric, best_metric, gain, sumAm, sumCb; + + besti = 0; + best_metric = best_error = 1E32; + for(j=0; j<e; j++) { + + /* compute optimum gain */ + + sumAm = sumCb = 0.0; + m = 0; + for(i=0; i<d; i++) { + if (vec[i] != 0.0) { + m++; + sumAm += vec[i]; + sumCb += cb[j*d+i]; + } + } + gain = (sumAm - sumCb)/m; + + /* compute error */ + + metric = error = 0.0; + for(i=0; i<d; i++) { + if (vec[i] != 0.0) { + diff = vec[i] - cb[j*d+i] - gain; + error += diff*diff; + metric += weights[i]*diff*diff; + } + } + if (metric < best_metric) { + best_error = error; + best_metric = metric; + *best_gain = gain; + besti = j; + } + } + + *se += best_error; + + return(besti); +} + + +static void gain_shape_split_vq(float sparse_pe_out[], struct AEXP *aexp, struct codebook *vq, float weights[], float sparse_pe_in[], float *best_gain) +{ + int i, j, non_zero, vq_ind; + float se; + + vq_ind = gain_shape_vq_amp(vq->cb, &sparse_pe_in[vq->offset], &weights[vq->offset], vq->k, vq->m, &se, best_gain); + //printf("\n offset %d k %d m %d vq_ind %d gain: %4.2f j: ", vq->offset, vq->k, vq->m, vq_ind, *best_gain); + + non_zero = 0; + for(i=0, j=vq->offset; i<vq->k; i++,j++) { + if (sparse_pe_in[j] != 0.0) { + //printf("%d ", j); + sparse_pe_out[j] = vq->cb[vq->k * vq_ind + i] + *best_gain; + non_zero++; + } + } + aexp->vq_var_n += non_zero; +} + + +static void gain_shape_sparse_vq_amp(struct AEXP *aexp, MODEL *model) +{ + int m, index; + float amp_dB, best_gain; + float sparse_pe_in[MAX_AMP]; + float sparse_pe_out[MAX_AMP]; + float weights[MAX_AMP]; + + for(m=0; m<MAX_AMP; m++) { + sparse_pe_in[m] = 0.0; + sparse_pe_out[m] = 0.0; + } + + for(m=1; m<=model->L; m++) { + assert(model->A[m] > 0.0); + + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe_in[index] = 20.0*log10(model->A[m]); + weights[index] = model->A[m]; + } + + /* vector quantise */ + + for(m=0; m<MAX_AMP; m++) { + sparse_pe_out[m] = sparse_pe_in[m]; + } + + gain_shape_split_vq(sparse_pe_out, aexp, aexp->vq1, weights, sparse_pe_in, &best_gain); + gain_shape_split_vq(sparse_pe_out, aexp, aexp->vq2, weights, sparse_pe_in, &best_gain); + gain_shape_split_vq(sparse_pe_out, aexp, aexp->vq3, weights, sparse_pe_in, &best_gain); + gain_shape_split_vq(sparse_pe_out, aexp, aexp->vq4, weights, sparse_pe_in, &best_gain); + + for(m=0; m<MAX_AMP; m++) { + if (sparse_pe_in[m] != 0.0) + aexp->vq_var += pow(sparse_pe_out[m] - sparse_pe_in[m], 2.0); + } + + /* transform quantised amps back */ + + for(m=1; m<=model->L; m++) { + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + amp_dB = sparse_pe_out[index]; + model->A[m] = pow(10.0, amp_dB/20.0); + } + //exit(0); +} + + +static void interp_split_vq(float sparse_pe_out[], struct AEXP *aexp, struct codebook *vq, float sparse_pe_in[], int ind) +{ + int i, j; + float amp_dB; + + for(i=0, j=vq->offset; i<vq->k; i++,j++) { + if (sparse_pe_in[j] != 0.0) { + amp_dB = 0.5*(aexp->mag[0] + vq->cb[vq->k * aexp->indexes[ind][0] + i]); + amp_dB += 0.5*(aexp->mag[2] + vq->cb[vq->k * aexp->indexes[ind][2] + i]); + sparse_pe_out[j] = amp_dB; + } + } +} + + +static void vq_interp(struct AEXP *aexp, MODEL *model, int on) +{ + int i, j, m, index; + float amp_dB; + //struct codebook *vq = aexp->vq1; + float sparse_pe_in[MAX_AMP]; + float sparse_pe_out[MAX_AMP]; + + /* replace odd frames with interp */ + /* once we get an even input frame we can interpolate and output odd */ + /* using VQ to interpolate. This assumes some correlation in + adjacent VQ samples */ + + memcpy(&aexp->model[2], model, sizeof(MODEL)); + + /* once we get an even input frame we have enough information to + replace prev odd frame with interpolated version */ + + if (on && ((aexp->frames % 2) == 0)) { + + /* copy Wo, L, and phases */ + + memcpy(model, &aexp->model[1], sizeof(MODEL)); + //printf("mags: %4.2f %4.2f %4.2f Am: \n", aexp->mag[0], aexp->mag[1], aexp->mag[2]); + + /* now replace Am by interpolation, use similar design to VQ + to handle different bands */ + + for(m=1; m<=model->L; m++) { + assert(model->A[m] > 0.0); + + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe_in[index] = 20.0*log10(model->A[m]); + } + + /* this can be used for when just testing partial interpolation */ + + for(m=0; m<MAX_AMP; m++) { + //sparse_pe_out[m] = sparse_pe_in[m]; + sparse_pe_out[m] = 0; + } + + interp_split_vq(sparse_pe_out, aexp, aexp->vq1, sparse_pe_in, 0); + interp_split_vq(sparse_pe_out, aexp, aexp->vq2, sparse_pe_in, 1); + interp_split_vq(sparse_pe_out, aexp, aexp->vq3, sparse_pe_in, 2); + interp_split_vq(sparse_pe_out, aexp, aexp->vq4, sparse_pe_in, 3); + interp_split_vq(sparse_pe_out, aexp, aexp->vq5, sparse_pe_in, 4); + + for(m=1; m<=model->L; m++) { + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + amp_dB = sparse_pe_out[index]; + //printf(" %4.2f", 10.0*log10(model->A[m])); + model->A[m] = pow(10.0, amp_dB/20.0); + //printf(" %4.2f\n", 10.0*log10(model->A[m])); + } + + #ifdef INITIAL_VER + + for(m=1; m<=model->L; m++) { + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + + if (index < vq->k) { + amp_dB = 0.5*(aexp->mag[0] + vq->cb[vq->k * aexp->indexes[0] + index]); + amp_dB += 0.5*(aexp->mag[2] + vq->cb[vq->k * aexp->indexes[2] + index]); + //printf(" %4.2f", 10.0*log10(model->A[m])); + //amp_dB = 10; + model->A[m] = pow(10.0, amp_dB/20.0); + printf(" %4.2f\n", 10.0*log10(model->A[m])); + } + } + + #endif + } + else + memcpy(model, &aexp->model[1], sizeof(MODEL)); + + /* update memories */ + + for(i=0; i<2; i++) { + memcpy(&aexp->model[i], &aexp->model[i+1], sizeof(MODEL)); + for(j=0; j<5; j++) + aexp->indexes[j][i] = aexp->indexes[j][i+1]; + aexp->mag[i] = aexp->mag[i+1]; + } + +} + + +/* + This functions tests theory that some bands can be combined together + due to less frequency resolution at higher frequencies. This will + reduce the amount of information we need to encode. +*/ + +void smooth_samples(struct AEXP *aexp, MODEL *model, int mode) +{ + int m, i, j, index, step, nav, v, en; + float sparse_pe_in[MAX_AMP], av, amp_dB; + float sparse_pe_out[MAX_AMP]; + float smoothed[MAX_AMP], smoothed_out[MAX_AMP]; + float weights[MAX_AMP]; + float enormdB; + + frame_energy(model, &enormdB); + + for(m=0; m<MAX_AMP; m++) { + sparse_pe_in[m] = 0.0; + sparse_pe_out[m] = 0.0; + } + + /* set up sparse array */ + + for(m=1; m<=model->L; m++) { + assert(model->A[m] > 0.0); + + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe_out[index] = sparse_pe_in[index] = 20.0*log10(model->A[m]) - enormdB; + } + + /* now combine samples at high frequencies to reduce dimension */ + + step=4; + for(i=MAX_AMP/2,v=0; i<MAX_AMP; i+=step,v++) { + + /* average over one band */ + + av = 0.0; nav = 0; + en = i+step; + if (en > (MAX_AMP-1)) + en = MAX_AMP-1; + for(j=i; j<en; j++) { + if (sparse_pe_in[j] != 0.0) { + av += sparse_pe_in[j]; + nav++; + } + } + if (nav) { + av /= nav; + smoothed[v] = av; + weights[v] = pow(10.0,av/20.0); + //weights[v] = 1.0; + } + else + smoothed[v] = 0.0; + + } + + if (mode == 1) { + for(i=0; i<v; i++) + printf("%5.2f ", smoothed[i]); + printf("\n"); + } + + if (mode == 2) { + for(i=0; i<v; i++) + smoothed_out[i] = 0; + split_vq(smoothed_out, aexp, aexp->vq1, weights, smoothed); + for(i=0; i<v; i++) + smoothed[i] = smoothed_out[i]; + } + + /* set all samples to smoothed average */ + + step = 4; + for(i=MAX_AMP/2,v=0; i<MAX_AMP; i+=step,v++) { + en = i+step; + if (en > (MAX_AMP-1)) + en = MAX_AMP-1; + for(j=i; j<en; j++) + sparse_pe_out[j] = smoothed[v]; + } + + /* convert back to Am */ + + for(m=1; m<=model->L; m++) { + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + amp_dB = sparse_pe_out[index] + enormdB; + //printf("%d %4.2f %4.2f\n", m, 10.0*log10(model->A[m]), amp_dB); + model->A[m] = pow(10.0, amp_dB/20.0); + } + +} + +#define MAX_BINS 40 +static float bins[] = { + /*1000.0, 1200.0, 1400.0, 1600.0, 1800,*/ + 2000.0, 2400.0, 2800.0, + 3000.0, 3400.0, 3600.0, 4000.0}; + +void smooth_amp(struct AEXP *aexp, MODEL *model) { + int m, i; + int nbins; + int b; + float f; + float av[MAX_BINS]; + int nav[MAX_BINS]; + + nbins = sizeof(bins)/sizeof(float); + + /* clear all bins */ + + for(i=0; i<MAX_BINS; i++) { + av[i] = 0.0; + nav[i] = 0; + } + + /* add amps into each bin */ + + for(m=1; m<=model->L; m++) { + f = m*model->Wo*FS/TWO_PI; + if (f > bins[0]) { + + /* find bin */ + + for(i=0; i<nbins; i++) + if ((f > bins[i]) && (f <= bins[i+1])) + b = i; + assert(b < MAX_BINS); + + av[b] += model->A[m]*model->A[m]; + nav[b]++; + } + + } + + /* use averages to est amps */ + + for(m=1; m<=model->L; m++) { + f = m*model->Wo*FS/TWO_PI; + if (f > bins[0]) { + + /* find bin */ + + for(i=0; i<nbins; i++) + if ((f > bins[i]) && (f <= bins[i+1])) + b = i; + assert(b < MAX_BINS); + + /* add predicted phase error to this bin */ + + printf("L %d m %d f %4.f b %d\n", model->L, m, f, b); + + printf(" %d: %4.3f -> ", m, 20*log10(model->A[m])); + model->A[m] = sqrt(av[b]/nav[b]); + printf("%4.3f\n", 20*log10(model->A[m])); + } + } + printf("\n"); +} + +/*---------------------------------------------------------------------------* \ + + amp_experiment() + + Amplitude quantisation experiments. + +\*---------------------------------------------------------------------------*/ + +void amp_experiment(struct AEXP *aexp, MODEL *model, char *arg) { + int m,i; + + memcpy(&aexp->model_uq[2], model, sizeof(MODEL)); + + if (strcmp(arg, "qn") == 0) { + add_quant_noise(aexp, model, 1, model->L, 1); + update_snr_calc(aexp, &aexp->model_uq[2], model); + } + + /* print training samples that can be > train.txt for training VQ */ + + if (strcmp(arg, "train") == 0) + print_sparse_amp_error(aexp, model, 00.0); + + /* VQ of amplitudes, no interpolation (ie 10ms rate) */ + + if (strcmp(arg, "vq") == 0) { + sparse_vq_amp(aexp, model); + vq_interp(aexp, model, 0); + update_snr_calc(aexp, &aexp->model_uq[1], model); + } + + /* VQ of amplitudes, interpolation (ie 20ms rate) */ + + if (strcmp(arg, "vqi") == 0) { + sparse_vq_amp(aexp, model); + vq_interp(aexp, model, 1); + update_snr_calc(aexp, &aexp->model_uq[1], model); + } + + /* gain/shape VQ of amplitudes, 10ms rate (doesn't work that well) */ + + if (strcmp(arg, "gsvq") == 0) { + gain_shape_sparse_vq_amp(aexp, model); + vq_interp(aexp, model, 0); + update_snr_calc(aexp, &aexp->model_uq[1], model); + } + + if (strcmp(arg, "smooth") == 0) { + smooth_samples(aexp, model, 0); + update_snr_calc(aexp, &aexp->model_uq[2], model); + } + + if (strcmp(arg, "smoothtrain") == 0) { + smooth_samples(aexp, model, 1); + //update_snr_calc(aexp, &aexp->model_uq[2], model); + } + + if (strcmp(arg, "smoothvq") == 0) { + smooth_samples(aexp, model, 2); + update_snr_calc(aexp, &aexp->model_uq[2], model); + } + + if (strcmp(arg, "smoothamp") == 0) { + smooth_amp(aexp, model); + update_snr_calc(aexp, &aexp->model_uq[2], model); + } + + /* update states */ + + for(m=1; m<=model->L; m++) + aexp->A_prev[m] = model->A[m]; + aexp->frames++; + for(i=0; i<3; i++) + aexp->model_uq[i] = aexp->model_uq[i+1]; +} + diff --git a/gr-vocoder/lib/codec2/ampexp.h b/gr-vocoder/lib/codec2/ampexp.h new file mode 100644 index 0000000000..8954ea282e --- /dev/null +++ b/gr-vocoder/lib/codec2/ampexp.h @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: ampexp.h + AUTHOR......: David Rowe + DATE CREATED: & August 2012 + + Functions for experimenting with amplitude quantisation. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2012 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not,see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __AMPEX__ +#define __AMPEXP__ + +#include "defines.h" + +struct AEXP; + +struct AEXP *amp_experiment_create(); +void amp_experiment_destroy(struct AEXP *aexp); +void amp_experiment(struct AEXP *aexp, MODEL *model, char *arg); + +#endif diff --git a/gr-vocoder/lib/codec2/c2dec.c b/gr-vocoder/lib/codec2/c2dec.c index 3123e96fbc..df4e82f77a 100644 --- a/gr-vocoder/lib/codec2/c2dec.c +++ b/gr-vocoder/lib/codec2/c2dec.c @@ -27,54 +27,213 @@ #include "codec2.h" +#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> -#define BITS_SIZE ((CODEC2_BITS_PER_FRAME + 7) / 8) +#define NONE 0 /* no bit errors */ +#define UNIFORM 1 /* random bit errors */ +#define TWO_STATE 2 /* Two state error model */ +#define UNIFORM_RANGE 3 /* random bit errors over a certain range */ int main(int argc, char *argv[]) { - void *codec2; - FILE *fin; - FILE *fout; - short buf[CODEC2_SAMPLES_PER_FRAME]; - unsigned char bits[BITS_SIZE]; - - if (argc != 3) { - printf("usage: %s InputBitFile OutputRawSpeechFile\n", argv[0]); + int mode; + void *codec2; + FILE *fin; + FILE *fout; + FILE *fber = NULL; + short *buf; + unsigned char *bits, *prev_bits; + int nsam, nbit, nbyte, i, byte, frames, bits_proc, bit_errors, error_mode; + int nstart_bit, nend_bit, bit_rate; + int state, next_state; + float ber, r, burst_length, burst_period, burst_timer, ber_est; + unsigned char mask; + + if ((argc != 4) && (argc != 5) && (argc != 6) && (argc != 7)) { + printf("basic usage.................: c2dec 3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile\n"); + printf("uniform errors usage........: c2dec 3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile uniformBER startBit endBit\n"); + printf("uniform error on range usage: c2dec 3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile uniformBER\n"); + printf("demod BER estimate..........: c2dec 3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile BERfile\n"); + printf("two state fading usage......: c2dec 3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile burstLength burstPeriod\n"); + printf("e.g c2dec 1400 hts1a.c2 hts1a_1400.raw\n"); + printf("e.g c2dec 1400 hts1a.c2 hts1a_1400.raw 0.9\n"); + printf("e.g c2dec 1400 hts1a.c2 hts1a_1400.raw 0.99 0.9\n"); exit(1); } - if (strcmp(argv[1], "-") == 0) fin = stdin; - else if ( (fin = fopen(argv[1],"rb")) == NULL ) { + if (strcmp(argv[1],"3200") == 0) + mode = CODEC2_MODE_3200; + else if (strcmp(argv[1],"2400") == 0) + mode = CODEC2_MODE_2400; + else if (strcmp(argv[1],"1600") == 0) + mode = CODEC2_MODE_1600; + else if (strcmp(argv[1],"1400") == 0) + mode = CODEC2_MODE_1400; + else if (strcmp(argv[1],"1300") == 0) + mode = CODEC2_MODE_1300; + else if (strcmp(argv[1],"1200") == 0) + mode = CODEC2_MODE_1200; + else { + fprintf(stderr, "Error in mode: %s. Must be 3200, 2400, 1600, 1400, 1300 or 1200\n", argv[1]); + exit(1); + } + bit_rate = atoi(argv[1]); + + if (strcmp(argv[2], "-") == 0) fin = stdin; + else if ( (fin = fopen(argv[2],"rb")) == NULL ) { fprintf(stderr, "Error opening input bit file: %s: %s.\n", - argv[1], strerror(errno)); + argv[2], strerror(errno)); exit(1); } - if (strcmp(argv[2], "-") == 0) fout = stdout; - else if ( (fout = fopen(argv[2],"wb")) == NULL ) { + if (strcmp(argv[3], "-") == 0) fout = stdout; + else if ( (fout = fopen(argv[3],"wb")) == NULL ) { fprintf(stderr, "Error opening output speech file: %s: %s.\n", - argv[2], strerror(errno)); + argv[3], strerror(errno)); exit(1); } - codec2 = codec2_create(); + error_mode = NONE; + ber = 0.0; + burst_length = burst_period = 0.0; + burst_timer = 0.0; + + codec2 = codec2_create(mode); + nsam = codec2_samples_per_frame(codec2); + nbit = codec2_bits_per_frame(codec2); + buf = (short*)malloc(nsam*sizeof(short)); + nbyte = (nbit + 7) / 8; + bits = (unsigned char*)malloc(nbyte*sizeof(char)); + prev_bits = (unsigned char*)malloc(nbyte*sizeof(char)); + frames = bit_errors = bits_proc = 0; + nstart_bit = 0; + nend_bit = nbit-1; + + if (argc == 5) { + /* see if 4th argument is a valid file name */ + if ( (fber = fopen(argv[4],"rb")) == NULL ) { + /* otherwise it must be BER value for uniform errors */ + ber = atof(argv[4]); + error_mode = UNIFORM; + } + } + + if (argc == 6) { + error_mode = TWO_STATE; + burst_length = atof(argv[4]); + burst_period = atof(argv[5]); + nstart_bit = 0; + nend_bit = 2; + state = 0; + } + + if (argc == 7) { + error_mode = UNIFORM_RANGE; + ber = atof(argv[4]); + nstart_bit = atoi(argv[5]); + nend_bit = atoi(argv[6]); + fprintf(stderr, "ber: %f nstart_bit: %d nend_bit: %d\n", ber, nstart_bit, nend_bit); + state = 0; + } - while(fread(bits, sizeof(char), BITS_SIZE, fin) == BITS_SIZE) { - codec2_decode(codec2, buf, bits); - fwrite(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout); + assert(nend_bit <= nbit); + + while(fread(bits, sizeof(char), nbyte, fin) == (size_t)nbyte) { + frames++; + + // apply bit errors, MSB of byte 0 is bit 0 in frame */ + + if ((error_mode == UNIFORM) || (error_mode == UNIFORM_RANGE)) { + for(i=nstart_bit; i<nend_bit+1; i++) { + r = (float)rand()/RAND_MAX; + if (r < ber) { + byte = i/8; + //printf("nbyte %d nbit %d i %d byte %d bits[%d] 0x%0x ", nbyte, nbit, i, byte, byte, bits[byte]); + mask = 1 << (7 - i + byte*8); + bits[byte] ^= mask; + //printf("shift: %d mask: 0x%0x bits[%d] 0x%0x\n", 7 - i + byte*8, mask, byte, bits[byte] ); + bit_errors++; + } + bits_proc++; + } + } + + if (error_mode == TWO_STATE) { + burst_timer += (float)nbit/bit_rate; + fprintf(stderr, "burst_timer: %f state: %d\n", burst_timer, state); + + next_state = state; + switch(state) { + case 0: + + /* clear channel state - no bit errors */ + + if (burst_timer > (burst_period - burst_length)) + next_state = 1; + break; + + case 1: + + /* burst error state - 50% bit error rate */ + + for(i=nstart_bit; i<nend_bit+1; i++) { + r = (float)rand()/RAND_MAX; + if (r < 0.5) { + byte = i/8; + bits[byte] ^= 1 << (7 - i + byte*8); + bit_errors++; + } + bits_proc++; + } + + if (burst_timer > burst_period) { + burst_timer = 0.0; + next_state = 0; + } + break; + + } + + state = next_state; + } + + if (fber != NULL) { + if (fread(&ber_est, sizeof(float), 1, fber) != 1) { + fprintf(stderr, "ran out of BER estimates!\n"); + exit(1); + } + //fprintf(stderr, "ber_est: %f\n", ber_est); + } + else + ber_est = 0.0; + + /* frame repeat logic */ + if (ber_est > 0.15) { + //memcpy(bits, prev_bits, nbyte); + // fprintf(stderr, "repeat\n"); + } + + codec2_decode(codec2, buf, bits, ber_est); + fwrite(buf, sizeof(short), nsam, fout); //if this is in a pipeline, we probably don't want the usual //buffering to occur if (fout == stdout) fflush(stdout); if (fin == stdin) fflush(stdin); - } + memcpy(prev_bits, bits, nbyte); + } + + if (error_mode) + fprintf(stderr, "actual BER: %1.3f\n", (float)bit_errors/bits_proc); codec2_destroy(codec2); + free(buf); + free(bits); fclose(fin); fclose(fout); diff --git a/gr-vocoder/lib/codec2/c2demo.c b/gr-vocoder/lib/codec2/c2demo.c index b9e17a78eb..0090069c65 100644 --- a/gr-vocoder/lib/codec2/c2demo.c +++ b/gr-vocoder/lib/codec2/c2demo.c @@ -32,21 +32,26 @@ */ #include "codec2.h" +#include "sine.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> -#define BITS_SIZE ((CODEC2_BITS_PER_FRAME + 7) / 8) - int main(int argc, char *argv[]) { - void *codec2; - FILE *fin; - FILE *fout; - short buf[CODEC2_SAMPLES_PER_FRAME]; - unsigned char bits[BITS_SIZE]; + struct CODEC2 *codec2; + FILE *fin; + FILE *fout; + short *buf; + unsigned char *bits; + int nsam, nbit, i, r; + + for(i=0; i<10; i++) { + r = codec2_rand(); + printf("[%d] r = %d\n", i, r); + } if (argc != 3) { printf("usage: %s InputRawSpeechFile OutputRawSpeechFile\n", argv[0]); @@ -65,18 +70,27 @@ int main(int argc, char *argv[]) exit(1); } + #ifdef DUMP + dump_on("c2demo"); + #endif + /* Note only one set of Codec 2 states is required for an encoder and decoder pair. */ - codec2 = codec2_create(); + codec2 = codec2_create(CODEC2_MODE_1300); + nsam = codec2_samples_per_frame(codec2); + buf = (short*)malloc(nsam*sizeof(short)); + nbit = codec2_bits_per_frame(codec2); + bits = (unsigned char*)malloc(nbit*sizeof(char)); - while(fread(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fin) == - CODEC2_SAMPLES_PER_FRAME) { + while(fread(buf, sizeof(short), nsam, fin) == (size_t)nsam) { codec2_encode(codec2, bits, buf); - codec2_decode(codec2, buf, bits); - fwrite(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout); + codec2_decode(codec2, buf, bits, 0.0); + fwrite(buf, sizeof(short), nsam, fout); } + free(buf); + free(bits); codec2_destroy(codec2); fclose(fin); diff --git a/gr-vocoder/lib/codec2/c2enc.c b/gr-vocoder/lib/codec2/c2enc.c index 0e5b26cfdc..ab1ebe4387 100644 --- a/gr-vocoder/lib/codec2/c2enc.c +++ b/gr-vocoder/lib/codec2/c2enc.c @@ -33,49 +33,74 @@ #include <string.h> #include <errno.h> -#define BITS_SIZE ((CODEC2_BITS_PER_FRAME + 7) / 8) - int main(int argc, char *argv[]) { - void *codec2; - FILE *fin; - FILE *fout; - short buf[CODEC2_SAMPLES_PER_FRAME]; - unsigned char bits[BITS_SIZE]; - - if (argc != 3) { - printf("usage: %s InputRawspeechFile OutputBitFile\n", argv[0]); + int mode; + void *codec2; + FILE *fin; + FILE *fout; + short *buf; + unsigned char *bits; + int nsam, nbit, nbyte; + + if (argc != 4) { + printf("usage: c2enc 3200|2400|1600|1400|1300|1200 InputRawspeechFile OutputBitFile\n"); + printf("e.g c2enc 1400 ../raw/hts1a.raw hts1a.c2\n"); exit(1); } - if (strcmp(argv[1], "-") == 0) fin = stdin; - else if ( (fin = fopen(argv[1],"rb")) == NULL ) { - fprintf(stderr, "Error opening input bit file: %s: %s.\n", - argv[1], strerror(errno)); + if (strcmp(argv[1],"3200") == 0) + mode = CODEC2_MODE_3200; + else if (strcmp(argv[1],"2400") == 0) + mode = CODEC2_MODE_2400; + else if (strcmp(argv[1],"1600") == 0) + mode = CODEC2_MODE_1600; + else if (strcmp(argv[1],"1400") == 0) + mode = CODEC2_MODE_1400; + else if (strcmp(argv[1],"1300") == 0) + mode = CODEC2_MODE_1300; + else if (strcmp(argv[1],"1200") == 0) + mode = CODEC2_MODE_1200; + else { + fprintf(stderr, "Error in mode: %s. Must be 3200, 2400, 1600, 1400, 1300 or 1200\n", argv[1]); exit(1); } - if (strcmp(argv[2], "-") == 0) fout = stdout; - else if ( (fout = fopen(argv[2],"wb")) == NULL ) { - fprintf(stderr, "Error opening output speech file: %s: %s.\n", + if (strcmp(argv[2], "-") == 0) fin = stdin; + else if ( (fin = fopen(argv[2],"rb")) == NULL ) { + fprintf(stderr, "Error opening input speech file: %s: %s.\n", argv[2], strerror(errno)); exit(1); } - codec2 = codec2_create(); + if (strcmp(argv[3], "-") == 0) fout = stdout; + else if ( (fout = fopen(argv[3],"wb")) == NULL ) { + fprintf(stderr, "Error opening output compressed bit file: %s: %s.\n", + argv[3], strerror(errno)); + exit(1); + } + + codec2 = codec2_create(mode); + nsam = codec2_samples_per_frame(codec2); + nbit = codec2_bits_per_frame(codec2); + buf = (short*)malloc(nsam*sizeof(short)); + nbyte = (nbit + 7) / 8; + + bits = (unsigned char*)malloc(nbyte*sizeof(char)); - while(fread(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fin) == - CODEC2_SAMPLES_PER_FRAME) { + while(fread(buf, sizeof(short), nsam, fin) == (size_t)nsam) { codec2_encode(codec2, bits, buf); - fwrite(bits, sizeof(char), BITS_SIZE, fout); - //if this is in a pipeline, we probably don't want the usual - //buffering to occur + fwrite(bits, sizeof(char), nbyte, fout); + // if this is in a pipeline, we probably don't want the usual + // buffering to occur if (fout == stdout) fflush(stdout); if (fin == stdin) fflush(stdin); } codec2_destroy(codec2); + free(buf); + free(bits); fclose(fin); fclose(fout); diff --git a/gr-vocoder/lib/codec2/c2sim.c b/gr-vocoder/lib/codec2/c2sim.c index e335078b64..8f07299d0d 100644 --- a/gr-vocoder/lib/codec2/c2sim.c +++ b/gr-vocoder/lib/codec2/c2sim.c @@ -4,8 +4,9 @@ AUTHOR......: David Rowe DATE CREATED: 20/8/2010 - Codec2 simulation. Combines encoder and decoder and allows switching in - out various algorithms and quantisation steps. + Codec2 simulation. Combines encoder and decoder and allows + switching in and out various algorithms and quantisation steps. Used + for algorithm development. \*---------------------------------------------------------------------------*/ @@ -32,6 +33,8 @@ #include <string.h> #include <errno.h> #include <math.h> +#include <unistd.h> +#include <getopt.h> #include "defines.h" #include "sine.h" @@ -43,32 +46,12 @@ #include "phase.h" #include "postfilter.h" #include "interp.h" +#include "ampexp.h" +#include "phaseexp.h" -/*---------------------------------------------------------------------------*\ - - switch_present() - - Searches the command line arguments for a "switch". If the switch is - found, returns the command line argument where it ws found, else returns - NULL. - -\*---------------------------------------------------------------------------*/ - -int switch_present(sw,argc,argv) -register char sw[]; /* switch in string form */ -register int argc; /* number of command line arguments */ -register char *argv[]; /* array of command line arguments in string form */ -{ - register int i; /* loop variable */ - - for(i=1; i<argc; i++) - if (!strcmp(sw,argv[i])) - return(i); +void synth_one_frame(kiss_fft_cfg fft_inv_cfg, short buf[], MODEL *model, float Sn_[], float Pn[], int prede, float *de_mem, float gain); +void print_help(const struct option *long_options, int num_opts, char* argv[]); - return 0; -} - -void synth_one_frame(short buf[], MODEL *model, float Sn_[], float Pn[]); /*---------------------------------------------------------------------------*\ @@ -78,386 +61,829 @@ void synth_one_frame(short buf[], MODEL *model, float Sn_[], float Pn[]); int main(int argc, char *argv[]) { - FILE *fout; /* output speech file */ - FILE *fin; /* input speech file */ - short buf[N]; /* input/output buffer */ - float Sn[M]; /* float input speech samples */ - COMP Sw[FFT_ENC]; /* DFT of Sn[] */ - float w[M]; /* time domain hamming window */ - COMP W[FFT_ENC]; /* DFT of w[] */ - MODEL model; - float Pn[2*N]; /* trapezoidal synthesis window */ - float Sn_[2*N]; /* synthesised speech */ - int i; /* loop variable */ - int frames; - float prev_Wo; - float pitch; - int voiced1 = 0; - - char out_file[MAX_STR]; - int arg; - float snr; - float sum_snr; - - int lpc_model, order = LPC_ORD; - int lsp, lspd, lspdvq, lsp_quantiser; - float ak[LPC_MAX]; - COMP Sw_[FFT_ENC]; - COMP Ew[FFT_ENC]; - - int dump; - - int phase0; - float ex_phase[MAX_AMP+1]; - - int postfilt; - float bg_est; - - int hand_voicing; - FILE *fvoicing = 0; - - MODEL prev_model, interp_model; - int decimate; - float lsps[LPC_ORD]; - float prev_lsps[LPC_ORD]; - float e, prev_e; - float ak_interp[LPC_MAX]; - - void *nlp_states; - float hpf_states[2]; - int resample; - float AresdB_prev[MAX_AMP]; - - for(i=0; i<MAX_AMP; i++) - AresdB_prev[i] = 0.0; - - for(i=0; i<M; i++) - Sn[i] = 1.0; - for(i=0; i<2*N; i++) - Sn_[i] = 0; - - prev_Wo = TWO_PI/P_MAX; - - prev_model.Wo = TWO_PI/P_MIN; - prev_model.L = floor(PI/prev_model.Wo); - for(i=1; i<=prev_model.L; i++) { - prev_model.A[i] = 0.0; - prev_model.phi[i] = 0.0; - } - for(i=1; i<=MAX_AMP; i++) { - ex_phase[i] = 0.0; - } - for(i=0; i<LPC_ORD; i++) { - prev_lsps[i] = i*PI/(LPC_ORD+1); - } - e = prev_e = 1; - hpf_states[0] = hpf_states[1] = 0.0; - - nlp_states = nlp_create(); - - if (argc < 2) { - fprintf(stderr, "\nCodec2 - 2400 bit/s speech codec - Simulation Program\n" - "\thttp://rowetel.com/codec2.html\n\n" - "usage: %s InputFile [-o OutputFile]\n" - "\t[--lpc Order]\n" - "\t[--lsp]\n" - "\t[--lspd]\n" - "\t[--lspdvq]\n" - "\t[--phase0]\n" - "\t[--postfilter]\n" - "\t[--hand_voicing]\n" - "\t[--dec]\n" - "\t[--dump DumpFilePrefix]\n", argv[0]); - exit(1); - } - - /* Interpret command line arguments -------------------------------------*/ - - /* Input file */ - - if ((fin = fopen(argv[1],"rb")) == NULL) { - fprintf(stderr, "Error opening input speech file: %s: %s.\n", - argv[1], strerror(errno)); - exit(1); - } - - /* Output file */ - - if ((arg = switch_present("-o",argc,argv))) { - if ((fout = fopen(argv[arg+1],"wb")) == NULL) { - fprintf(stderr, "Error opening output speech file: %s: %s.\n", - argv[arg+1], strerror(errno)); - exit(1); + FILE *fout = NULL; /* output speech file */ + FILE *fin; /* input speech file */ + short buf[N]; /* input/output buffer */ + float Sn[M]; /* float input speech samples */ + float Sn_pre[M]; /* pre-emphasised input speech samples */ + COMP Sw[FFT_ENC]; /* DFT of Sn[] */ + kiss_fft_cfg fft_fwd_cfg; + kiss_fft_cfg fft_inv_cfg; + float w[M]; /* time domain hamming window */ + COMP W[FFT_ENC]; /* DFT of w[] */ + MODEL model; + float Pn[2*N]; /* trapezoidal synthesis window */ + float Sn_[2*N]; /* synthesised speech */ + int i; /* loop variable */ + int frames; + float prev_Wo, prev__Wo, uq_Wo, prev_uq_Wo; + float pitch; + int voiced1 = 0; + char out_file[MAX_STR]; + char ampexp_arg[MAX_STR]; + char phaseexp_arg[MAX_STR]; + float snr; + float sum_snr; + + int lpc_model = 0, order = LPC_ORD; + int lsp = 0, lspd = 0, lspvq = 0; + int lspres = 0; + int lspdt = 0, lspdt_mode = LSPDT_ALL; + int dt = 0, lspjvm = 0, lspanssi = 0, lspjnd = 0, lspmel = 0; + int prede = 0; + float pre_mem = 0.0, de_mem = 0.0; + float ak[LPC_MAX]; + COMP Sw_[FFT_ENC]; + COMP Ew[FFT_ENC]; + + int phase0 = 0; + float ex_phase[MAX_AMP+1]; + + int postfilt; + float bg_est; + + int hand_voicing = 0, phaseexp = 0, ampexp = 0, hi = 0, simlpcpf = 0; + int lpcpf = 0; + FILE *fvoicing = 0; + + MODEL prev_model, interp_model; + int decimate = 0; + float lsps[LPC_MAX]; + float prev_lsps[LPC_MAX], prev_lsps_[LPC_MAX]; + float lsps__prev[LPC_MAX]; + float lsps__prev2[LPC_MAX]; + float e, prev_e; + float ak_interp[LPC_MAX]; + int lsp_indexes[LPC_MAX]; + float lsps_[LPC_MAX]; + float Woe_[2]; + + void *nlp_states; + float hpf_states[2]; + int scalar_quant_Wo_e = 0; + int vector_quant_Wo_e = 0; + int dump_pitch_e = 0; + FILE *fjvm = NULL; + #ifdef DUMP + int dump; + #endif + struct PEXP *pexp = NULL; + struct AEXP *aexp = NULL; + float gain = 1.0; + + char* opt_string = "ho:"; + struct option long_options[] = { + { "lpc", required_argument, &lpc_model, 1 }, + { "lspjnd", no_argument, &lspjnd, 1 }, + { "lspmel", no_argument, &lspmel, 1 }, + { "lsp", no_argument, &lsp, 1 }, + { "lspd", no_argument, &lspd, 1 }, + { "lspvq", no_argument, &lspvq, 1 }, + { "lspres", no_argument, &lspres, 1 }, + #ifdef __EXPERIMENTAL__ + { "lspdt", no_argument, &lspdt, 1 }, + { "lspdt_mode", required_argument, NULL, 0 }, + #endif + { "lspjvm", no_argument, &lspjvm, 1 }, + #ifdef __EXPERIMENTAL__ + { "lspanssi", no_argument, &lspanssi, 1 }, + #endif + { "phase0", no_argument, &phase0, 1 }, + { "phaseexp", required_argument, &phaseexp, 1 }, + { "ampexp", required_argument, &exp, 1 }, + { "postfilter", no_argument, &postfilt, 1 }, + { "hand_voicing", required_argument, &hand_voicing, 1 }, + { "dec", no_argument, &decimate, 1 }, + { "dt", no_argument, &dt, 1 }, + { "hi", no_argument, &hi, 1 }, + { "simlpcpf", no_argument, &simlpcpf, 1 }, + { "lpcpf", no_argument, &lpcpf, 1 }, + { "prede", no_argument, &prede, 1 }, + { "dump_pitch_e", required_argument, &dump_pitch_e, 1 }, + { "sq_pitch_e", no_argument, &scalar_quant_Wo_e, 1 }, + { "vq_pitch_e", no_argument, &vector_quant_Wo_e, 1 }, + { "rate", required_argument, NULL, 0 }, + { "gain", required_argument, NULL, 0 }, + #ifdef DUMP + { "dump", required_argument, &dump, 1 }, + #endif + { "help", no_argument, NULL, 'h' }, + { NULL, no_argument, NULL, 0 } + }; + int num_opts=sizeof(long_options)/sizeof(struct option); + + for(i=0; i<M; i++) { + Sn[i] = 1.0; + Sn_pre[i] = 1.0; } - strcpy(out_file,argv[arg+1]); - } - else - fout = NULL; - - lpc_model = 0; - if ((arg = switch_present("--lpc",argc,argv))) { - lpc_model = 1; - order = atoi(argv[arg+1]); - if ((order < 4) || (order > 20)) { - fprintf(stderr, "Error in lpc order: %d\n", order); - exit(1); - } - } - - dump = switch_present("--dump",argc,argv); -#ifdef DUMP - if (dump) - dump_on(argv[dump+1]); -#endif - - lsp = switch_present("--lsp",argc,argv); - lsp_quantiser = 0; - if (lsp) - assert(order == LPC_ORD); + for(i=0; i<2*N; i++) + Sn_[i] = 0; - lspd = switch_present("--lspd",argc,argv); - if (lspd) - assert(order == LPC_ORD); + prev_uq_Wo = prev_Wo = prev__Wo = TWO_PI/P_MAX; - lspdvq = switch_present("--lspdvq",argc,argv); - if (lspdvq) - assert(order == LPC_ORD); + prev_model.Wo = TWO_PI/P_MIN; + prev_model.L = floor(PI/prev_model.Wo); + for(i=1; i<=prev_model.L; i++) { + prev_model.A[i] = 0.0; + prev_model.phi[i] = 0.0; + } + for(i=1; i<=MAX_AMP; i++) { + //ex_phase[i] = (PI/3)*(float)rand()/RAND_MAX; + ex_phase[i] = 0.0; + } + for(i=0; i<LPC_ORD; i++) { + lsps_[i] = prev_lsps[i] = prev_lsps_[i] = i*PI/(LPC_ORD+1); + lsps__prev[i] = lsps__prev2[i] = i*PI/(LPC_ORD+1); + } + e = prev_e = 1; + hpf_states[0] = hpf_states[1] = 0.0; - phase0 = switch_present("--phase0",argc,argv); - if (phase0) { - ex_phase[0] = 0; - } + nlp_states = nlp_create(M); - hand_voicing = switch_present("--hand_voicing",argc,argv); - if (hand_voicing) { - fvoicing = fopen(argv[hand_voicing+1],"rt"); - assert(fvoicing != NULL); - } + if (argc < 2) { + print_help(long_options, num_opts, argv); + } - bg_est = 0.0; - postfilt = switch_present("--postfilter",argc,argv); + /*----------------------------------------------------------------*\ + + Interpret Command Line Arguments + + \*----------------------------------------------------------------*/ + + while(1) { + int option_index = 0; + int opt = getopt_long(argc, argv, opt_string, + long_options, &option_index); + if (opt == -1) + break; + switch (opt) { + case 0: + if(strcmp(long_options[option_index].name, "lpc") == 0) { + order = atoi(optarg); + if((order < 4) || (order > 20)) { + fprintf(stderr, "Error in LPC order: %s\n", optarg); + exit(1); + } + #ifdef DUMP + } else if(strcmp(long_options[option_index].name, "dump") == 0) { + if (dump) + dump_on(optarg); + #endif + } else if(strcmp(long_options[option_index].name, "lsp") == 0 + || strcmp(long_options[option_index].name, "lspd") == 0 + || strcmp(long_options[option_index].name, "lspvq") == 0) { + assert(order == LPC_ORD); + } else if(strcmp(long_options[option_index].name, "lspdt_mode") == 0) { + if (strcmp(optarg,"all") == 0) + lspdt_mode = LSPDT_ALL; + else if (strcmp(optarg,"low") == 0) + lspdt_mode = LSPDT_LOW; + else if (strcmp(optarg,"high") == 0) + lspdt_mode = LSPDT_HIGH; + else { + fprintf(stderr, "Error in lspdt_mode: %s\n", optarg); + exit(1); + } + } else if(strcmp(long_options[option_index].name, "hand_voicing") == 0) { + if ((fvoicing = fopen(optarg,"rt")) == NULL) { + fprintf(stderr, "Error opening voicing file: %s: %s.\n", + optarg, strerror(errno)); + exit(1); + } + } else if(strcmp(long_options[option_index].name, "dump_pitch_e") == 0) { + if ((fjvm = fopen(optarg,"wt")) == NULL) { + fprintf(stderr, "Error opening pitch & energy dump file: %s: %s.\n", + optarg, strerror(errno)); + exit(1); + } + } else if(strcmp(long_options[option_index].name, "phaseexp") == 0) { + strcpy(phaseexp_arg, optarg); + } else if(strcmp(long_options[option_index].name, "ampexp") == 0) { + strcpy(ampexp_arg, optarg); + } else if(strcmp(long_options[option_index].name, "gain") == 0) { + gain = atof(optarg); + } else if(strcmp(long_options[option_index].name, "rate") == 0) { + if(strcmp(optarg,"3200") == 0) { + lpc_model = 1; order = 10; + scalar_quant_Wo_e = 1; + lspd = 1; + phase0 = 1; + postfilt = 1; + decimate = 1; + lpcpf = 1; + } else if(strcmp(optarg,"2400") == 0) { + lpc_model = 1; order = 10; + vector_quant_Wo_e = 1; + lsp = 1; + phase0 = 1; + postfilt = 1; + decimate = 1; + lpcpf = 1; + } else if(strcmp(optarg,"1400") == 0) { + lpc_model = 1; order = 10; + vector_quant_Wo_e = 1; + lsp = 1; lspdt = 1; + phase0 = 1; + postfilt = 1; + decimate = 1; + dt = 1; + lpcpf = 1; + } else if(strcmp(optarg,"1200") == 0) { + lpc_model = 1; order = 10; + scalar_quant_Wo_e = 1; + lspjvm = 1; lspdt = 1; + phase0 = 1; + postfilt = 1; + decimate = 1; + dt = 1; + lpcpf = 1; + } else { + fprintf(stderr, "Error: invalid output rate %s\n", optarg); + exit(1); + } + } + break; + + case 'h': + print_help(long_options, num_opts, argv); + break; + + case 'o': + if (strcmp(optarg, "-") == 0) fout = stdout; + else if ((fout = fopen(optarg,"wb")) == NULL) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + optarg, strerror(errno)); + exit(1); + } + strcpy(out_file,optarg); + break; + + default: + /* This will never be reached */ + break; + } + } - decimate = switch_present("--dec",argc,argv); + /* Input file */ - arg = switch_present("--resample",argc,argv); - resample = atoi(argv[arg+1]); + if ((fin = fopen(argv[optind],"rb")) == NULL) { + fprintf(stderr, "Error opening input speech file: %s: %s.\n", + argv[optind], strerror(errno)); + exit(1); + } - /* Initialise ------------------------------------------------------------*/ + ex_phase[0] = 0; + bg_est = 0.0; + Woe_[0] = Woe_[1] = 1.0; - make_analysis_window(w,W); - make_synthesis_window(Pn); - quantise_init(); + /* + printf("lspd: %d lspdt: %d lspdt_mode: %d phase0: %d postfilt: %d " + "decimate: %d dt: %d\n",lspd,lspdt,lspdt_mode,phase0,postfilt, + decimate,dt); + */ - /* Main loop ------------------------------------------------------------*/ + /* Initialise ------------------------------------------------------------*/ - frames = 0; - sum_snr = 0; - while(fread(buf,sizeof(short),N,fin)) { - frames++; - //printf("frame: %d", frames); + fft_fwd_cfg = kiss_fft_alloc(FFT_ENC, 0, NULL, NULL); /* fwd FFT,used in several places */ + fft_inv_cfg = kiss_fft_alloc(FFT_DEC, 1, NULL, NULL); /* inverse FFT, used just for synth */ + make_analysis_window(fft_fwd_cfg, w, W); + make_synthesis_window(Pn); + quantise_init(); + if (phaseexp) + pexp = phase_experiment_create(); + if (ampexp) + aexp = amp_experiment_create(); - /* Read input speech */ + /*----------------------------------------------------------------*\ - for(i=0; i<M-N; i++) - Sn[i] = Sn[i+N]; - for(i=0; i<N; i++) { - //Sn[i+M-N] = hpf((float)buf[i], hpf_states); - Sn[i+M-N] = (float)buf[i]; - } + Main Loop - /* Estimate pitch */ + \*----------------------------------------------------------------*/ - nlp(nlp_states,Sn,N,M,P_MIN,P_MAX,&pitch,Sw,&prev_Wo); - model.Wo = TWO_PI/pitch; + frames = 0; + sum_snr = 0; + while(fread(buf,sizeof(short),N,fin)) { + frames++; + //printf("frame: %d ", frames); - /* estimate model parameters */ + /* Read input speech */ - dft_speech(Sw, Sn, w); - two_stage_pitch_refinement(&model, Sw); - estimate_amplitudes(&model, Sw, W); -#ifdef DUMP - dump_Sn(Sn); dump_Sw(Sw); dump_model(&model); -#endif + for(i=0; i<M-N; i++) { + Sn[i] = Sn[i+N]; + Sn_pre[i] = Sn_pre[i+N]; + } + for(i=0; i<N; i++) + Sn[i+M-N] = buf[i]; - /* optional zero-phase modelling */ + pre_emp(&Sn_pre[M-N], &Sn[M-N], &pre_mem, N); - if (phase0) { - float Wn[M]; /* windowed speech samples */ - float Rk[LPC_MAX+1]; /* autocorrelation coeffs */ -#ifdef DUMP - dump_phase(&model.phi[0], model.L); -#endif + /*------------------------------------------------------------*\ - /* find aks here, these are overwritten if LPC modelling is enabled */ + Estimate Sinusoidal Model Parameters - for(i=0; i<M; i++) - Wn[i] = Sn[i]*w[i]; - autocorrelate(Wn,Rk,M,order); - levinson_durbin(Rk,ak,order); + \*------------------------------------------------------------*/ -#ifdef DUMP - dump_ak(ak, LPC_ORD); -#endif + nlp(nlp_states,Sn,N,P_MIN,P_MAX,&pitch,Sw,W,&prev_uq_Wo); + model.Wo = TWO_PI/pitch; - /* determine voicing */ + dft_speech(fft_fwd_cfg, Sw, Sn, w); + two_stage_pitch_refinement(&model, Sw); + estimate_amplitudes(&model, Sw, W, 1); + uq_Wo = model.Wo; - snr = est_voicing_mbe(&model, Sw, W, Sw_, Ew, prev_Wo); -#ifdef DUMP - dump_Sw_(Sw_); - dump_Ew(Ew); - dump_snr(snr); -#endif + #ifdef DUMP + dump_Sn(Sn); dump_Sw(Sw); dump_model(&model); + #endif - /* just to make sure we are not cheating - kill all phases */ + if (ampexp) + amp_experiment(aexp, &model, ampexp_arg); - for(i=0; i<MAX_AMP; i++) - model.phi[i] = 0; + if (phaseexp) { + #ifdef DUMP + dump_phase(&model.phi[0], model.L); + #endif + phase_experiment(pexp, &model, phaseexp_arg); + #ifdef DUMP + dump_phase_(&model.phi[0], model.L); + #endif + } - if (hand_voicing) { - fscanf(fvoicing,"%d\n",&model.voiced); + if (hi) { + int m; + for(m=1; m<model.L/2; m++) + model.A[m] = 0.0; + for(m=3*model.L/4; m<=model.L; m++) + model.A[m] = 0.0; } - } - /* optional LPC model amplitudes */ + /*------------------------------------------------------------*\ - if (lpc_model) { - int lsp_indexes[LPC_MAX]; + Zero-phase modelling - e = speech_to_uq_lsps(lsps, ak, Sn, w, order); + \*------------------------------------------------------------*/ - if (lsp) { - encode_lsps(lsp_indexes, lsps, LPC_ORD); - decode_lsps(lsps, lsp_indexes, LPC_ORD); - bw_expand_lsps(lsps, LPC_ORD); - lsp_to_lpc(lsps, ak, LPC_ORD); - } + if (phase0) { + float Wn[M]; /* windowed speech samples */ + float Rk[LPC_MAX+1]; /* autocorrelation coeffs */ - if (lspd) { - float lsps_[LPC_ORD]; + #ifdef DUMP + dump_phase(&model.phi[0], model.L); + #endif - lspd_quantise(lsps, lsps_, LPC_ORD); - lsp_to_lpc(lsps_, ak, LPC_ORD); - } + /* find aks here, these are overwritten if LPC modelling is enabled */ - if (lspdvq) { - float lsps_[LPC_ORD]; + if (prede) { + for(i=0; i<M; i++) + Wn[i] = Sn_pre[i]*w[i]; + } + else { - lspdvq_quantise(lsps, lsps_, LPC_ORD); - lsp_to_lpc(lsps_, ak, LPC_ORD); - } + for(i=0; i<M; i++) + Wn[i] = Sn[i]*w[i]; + } + autocorrelate(Wn,Rk,M,order); + levinson_durbin(Rk,ak,order); - e = decode_energy(encode_energy(e)); - model.Wo = decode_Wo(encode_Wo(model.Wo)); + /* determine voicing */ - aks_to_M2(ak, order, &model, e, &snr, 1); - apply_lpc_correction(&model); - sum_snr += snr; -#ifdef DUMP - dump_quantised_model(&model); -#endif - } + snr = est_voicing_mbe(&model, Sw, W, Sw_, Ew, prev_uq_Wo); - /* optional resampling of model amplitudes */ + if (dump_pitch_e) + fprintf(fjvm, "%f %f %d ", model.Wo, snr, model.voiced); - printf("frames=%d\n", frames); - if (resample) { - snr = resample_amp_nl(&model, resample, AresdB_prev); - sum_snr += snr; -#ifdef DUMP - dump_quantised_model(&model); -#endif - } + //printf("snr %3.2f v: %d Wo: %f prev_Wo: %f\n", snr, model.voiced, + // model.Wo, prev_uq_Wo); + #ifdef DUMP + dump_Sw_(Sw_); + dump_Ew(Ew); + dump_snr(snr); + #endif - /* option decimation to 20ms rate, which enables interpolation - routine to synthesise in between frame */ + /* just to make sure we are not cheating - kill all phases */ - if (decimate) { - if (!phase0) { - printf("needs --phase0 to resample phase for interpolated Wo\n"); - exit(0); - } - if (!lpc_model) { - printf("needs --lpc 10 to resample amplitudes\n"); - exit(0); + for(i=0; i<=MAX_AMP; i++) + model.phi[i] = 0; + + if (hand_voicing) { + fscanf(fvoicing,"%d\n",&model.voiced); + } } - /* odd frame - interpolate */ + /*------------------------------------------------------------*\ + + LPC model amplitudes and LSP quantisation + + \*------------------------------------------------------------*/ + + if (lpc_model) { + + if (prede) + e = speech_to_uq_lsps(lsps, ak, Sn_pre, w, order); + else + e = speech_to_uq_lsps(lsps, ak, Sn, w, order); + + #ifdef DUMP + dump_ak(ak, LPC_ORD); + #endif + + /* tracking down -ve energy values with BW expansion */ + /* + if (e < 0.0) { + int i; + FILE*f=fopen("x.txt","wt"); + for(i=0; i<M; i++) + fprintf(f,"%f\n", Sn[i]); + fclose(f); + printf("e = %f frames = %d\n", e, frames); + for(i=0; i<order; i++) + printf("%f ", ak[i]); + exit(0); + } + */ + + if (dump_pitch_e) + fprintf(fjvm, "%f\n", e); + + #ifdef DUMP + /* dump order is different if we are decimating */ + if (!decimate) + dump_lsp(lsps); + for(i=0; i<LPC_ORD; i++) + prev_lsps[i] = lsps[i]; + #endif + + /* various LSP quantisation schemes */ + + if (lsp) { + encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); + decode_lsps_scalar(lsps_, lsp_indexes, LPC_ORD); + bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0); + lsp_to_lpc(lsps_, ak, LPC_ORD); + } + + if (lspd) { + encode_lspds_scalar(lsp_indexes, lsps, LPC_ORD); + decode_lspds_scalar(lsps_, lsp_indexes, LPC_ORD); + lsp_to_lpc(lsps_, ak, LPC_ORD); + } + +#ifdef __EXPERIMENTAL__ + if (lspvq) { + lspvq_quantise(lsps, lsps_, LPC_ORD); + bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0); + lsp_to_lpc(lsps_, ak, LPC_ORD); + } +#endif + + if (lspjvm) { + /* Jean-Marc's multi-stage, split VQ */ + lspjvm_quantise(lsps, lsps_, LPC_ORD); + { + float lsps_bw[LPC_ORD]; + memcpy(lsps_bw, lsps_, sizeof(float)*LPC_ORD); + bw_expand_lsps(lsps_bw, LPC_ORD, 50.0, 100.0); + lsp_to_lpc(lsps_bw, ak, LPC_ORD); + } + } + +#ifdef __EXPERIMENTAL__ + if (lspanssi) { + /* multi-stage VQ from Anssi Ramo OH3GDD */ + + lspanssi_quantise(lsps, lsps_, LPC_ORD, 5); + bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0); + lsp_to_lpc(lsps_, ak, LPC_ORD); + } +#endif - if (frames%2) { + /* experimenting with non-linear LSP spacing to see if + it's just noticable */ + + if (lspjnd) { + for(i=0; i<LPC_ORD; i++) + lsps_[i] = lsps[i]; + locate_lsps_jnd_steps(lsps_, LPC_ORD); + lsp_to_lpc(lsps_, ak, LPC_ORD); + } + + /* Another experiment with non-linear LSP spacing, this + time using a scaled version of mel frequency axis + warping. The scaling is such that the integer output + can be directly sent over the channel. + */ + + if (lspmel) { + float f, f_; + int mel[LPC_ORD]; + + for(i=0; i<LPC_ORD; i++) { + f = (4000.0/PI)*lsps[i]; + mel[i] = floor(100.0*log10(1.0 + f/700.0) + 0.5); + } + + for(i=1; i<LPC_ORD; i++) { + if (mel[i] == mel[i-1]) + mel[i]++; + } + + for(i=0; i<LPC_ORD; i++) { + f_ = 700.0*( pow(10.0, (float)mel[i]/100.0) - 1.0); + lsps_[i] = f_*(PI/4000.0); + } + for(i=5; i<10; i++) { + lsps_[i] = lsps[i]; + } + + lsp_to_lpc(lsps_, ak, LPC_ORD); + } + + /* we need lsp__prev[] for lspdt and decimate. If no + other LSP quantisation is used we use original LSPs as + there is no quantised version available. TODO: this is + mess, we should have structures and standard + nomenclature for previous frames values, lsp_[] + shouldn't be overwritten as we may want to dump it for + analysis. Re-design some time. + */ + + if (!lsp && !lspd && !lspvq && !lspres && !lspjvm && !lspanssi && !lspjnd && !lspmel) + for(i=0; i<LPC_ORD; i++) + lsps_[i] = lsps[i]; + + /* Odd frames are generated by quantising the difference + between the previous frames LSPs and this frames */ + +#ifdef __EXPERIMENTAL__ + if (lspdt && !decimate) { + if (frames%2) { + lspdt_quantise(lsps, lsps_, lsps__prev, lspdt_mode); + bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0); + lsp_to_lpc(lsps_, ak, LPC_ORD); + } + for(i=0; i<LPC_ORD; i++) + lsps__prev[i] = lsps_[i]; + } +#endif - interp_model.voiced = voiced1; + /* + When decimation is enabled we only send LSPs to the + decoder on odd frames. In the Delta-time LSPs case we + encode every second odd frame (i.e. every 3rd frame out + of 4) by quantising the difference between the 1st + frames LSPs and the 3rd frames: + + 10ms, frame 1: discard (interpolate at decoder) + 20ms, frame 2: send "full" LSP frame + 30ms, frame 3: discard (interpolate at decoder) + 40ms, frame 4: send LSPs differences between frame 4 and frame 2 + */ + + if (lspdt && decimate) { + /* print previous LSPs to make sure we are using the right set */ + if ((frames%4) == 0) { + //printf(" lspdt "); + //#define LSPDT + #ifdef LSPDT + lspdt_quantise(lsps, lsps_, lsps__prev2, lspdt_mode); + #else + for(i=0; i<LPC_ORD; i++) + lsps_[i] = lsps__prev2[i]; + #endif + bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0); + lsp_to_lpc(lsps_, ak, LPC_ORD); + } + + for(i=0; i<LPC_ORD; i++) { + lsps__prev2[i] = lsps__prev[i]; + lsps__prev[i] = lsps_[i]; + } + } + #ifdef DUMP + /* if using decimated (20ms) frames we dump interp + LSPs below */ + if (!decimate) + dump_lsp_(lsps_); + #endif + + if (scalar_quant_Wo_e) { + + e = decode_energy(encode_energy(e)); + + if (!decimate) { + /* we send params every 10ms, delta-time every 20ms */ + if (dt && (frames % 2)) + model.Wo = decode_Wo_dt(encode_Wo_dt(model.Wo, prev_Wo),prev_Wo); + else + model.Wo = decode_Wo(encode_Wo(model.Wo)); + } + + if (decimate) { + /* we send params every 20ms */ + if (dt && ((frames % 4) == 0)) { + /* delta-time every 40ms */ + model.Wo = decode_Wo_dt(encode_Wo_dt(model.Wo, prev__Wo),prev__Wo); + } + else + model.Wo = decode_Wo(encode_Wo(model.Wo)); + } + + model.L = PI/model.Wo; /* if we quantise Wo re-compute L */ + } + + if (vector_quant_Wo_e) { + + /* JVM's experimental joint Wo & LPC energy quantiser */ + + //printf("\nWo %f e %f\n", model.Wo, e); + quantise_WoE(&model, &e, Woe_); + //printf("Wo %f e %f\n", model.Wo, e); + + } + + aks_to_M2(fft_fwd_cfg, ak, order, &model, e, &snr, 1, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA); + apply_lpc_correction(&model); + + #ifdef DUMP + dump_ak_(ak, LPC_ORD); + #endif + + /* note SNR on interpolated frames can't be measured properly + by comparing Am as L has changed. We can dump interp lsps + and compare them, + */ + #ifdef DUMP + dump_lpc_snr(snr); + #endif + sum_snr += snr; + #ifdef DUMP + dump_quantised_model(&model); + #endif + } - #ifdef LOG_LIN_INTERP - interpolate(&interp_model, &prev_model, &model); - #else - interpolate_lsp(&interp_model, &prev_model, &model, - prev_lsps, prev_e, lsps, e, ak_interp); - apply_lpc_correction(&interp_model); - #endif + /*------------------------------------------------------------*\ + + Decimation to 20ms frame rate + + \*------------------------------------------------------------*/ + + if (decimate) { + float lsps_interp[LPC_ORD]; + + if (!phase0) { + printf("needs --phase0 to resample phase for interpolated Wo\n"); + exit(0); + } + if (!lpc_model) { + printf("needs --lpc 10 to resample amplitudes\n"); + exit(0); + } + + /* + Each 20ms we synthesise two 10ms frames: + + frame 1: discard except for voicing bit + frame 2: interpolate frame 1 LSPs from frame 2 and frame 0 + synthesise frame 1 and frame 2 speech + frame 3: discard except for voicing bit + frame 4: interpolate frame 3 LSPs from frame 4 and frame 2 + synthesise frame 3 and frame 4 speech + */ + + if ((frames%2) == 0) { + //printf("frame: %d\n", frames); + + /* decode interpolated frame */ + + interp_model.voiced = voiced1; + + interpolate_lsp(fft_fwd_cfg, &interp_model, &prev_model, &model, + prev_lsps_, prev_e, lsps_, e, ak_interp, lsps_interp); + apply_lpc_correction(&interp_model); + + /* used to compare with c2enc/c2dec version + + printf(" Wo: %1.5f L: %d v1: %d prev_e: %f\n", + interp_model.Wo, interp_model.L, interp_model.voiced, prev_e); + printf(" lsps_interp: "); + for(i=0; i<LPC_ORD; i++) + printf("%5.3f ", lsps_interp[i]); + printf("\n A..........: "); + for(i=0; i<10; i++) + printf("%5.3f ",interp_model.A[i]); + + printf("\n Wo: %1.5f L: %d e: %3.2f v2: %d\n", + model.Wo, model.L, e, model.voiced); + printf(" lsps_......: "); + for(i=0; i<LPC_ORD; i++) + printf("%5.3f ", lsps_[i]); + printf("\n A..........: "); + for(i=0; i<10; i++) + printf("%5.3f ",model.A[i]); + printf("\n"); + */ + + #ifdef DUMP + /* do dumping here so we get lsp dump file in correct order */ + dump_lsp(prev_lsps); + dump_lsp(lsps_interp); + dump_lsp(lsps); + dump_lsp(lsps_); + #endif + + if (phase0) + phase_synth_zero_order(fft_fwd_cfg, &interp_model, ak_interp, ex_phase, + order); + if (postfilt) + postfilter(&interp_model, &bg_est); + synth_one_frame(fft_inv_cfg, buf, &interp_model, Sn_, Pn, prede, &de_mem, gain); + //printf(" buf[0] %d\n", buf[0]); + if (fout != NULL) + fwrite(buf,sizeof(short),N,fout); + + /* decode this frame */ + + if (phase0) + phase_synth_zero_order(fft_fwd_cfg, &model, ak, ex_phase, order); + if (postfilt) + postfilter(&model, &bg_est); + synth_one_frame(fft_inv_cfg, buf, &model, Sn_, Pn, prede, &de_mem, gain); + //printf(" buf[0] %d\n", buf[0]); + if (fout != NULL) + fwrite(buf,sizeof(short),N,fout); + + /* update states for next time */ + + prev_model = model; + for(i=0; i<LPC_ORD; i++) + prev_lsps_[i] = lsps_[i]; + prev_e = e; + } + else { + voiced1 = model.voiced; + } + } + else { + /* no decimation - sythesise each 10ms frame immediately */ if (phase0) - phase_synth_zero_order(&interp_model, ak_interp, ex_phase, - order); - if (postfilt) - postfilter(&interp_model, &bg_est); - synth_one_frame(buf, &interp_model, Sn_, Pn); - if (fout != NULL) fwrite(buf,sizeof(short),N,fout); + phase_synth_zero_order(fft_fwd_cfg, &model, ak, ex_phase, order); - if (phase0) - phase_synth_zero_order(&model, ak, ex_phase, order); if (postfilt) postfilter(&model, &bg_est); - synth_one_frame(buf, &model, Sn_, Pn); + synth_one_frame(fft_inv_cfg, buf, &model, Sn_, Pn, prede, &de_mem, gain); if (fout != NULL) fwrite(buf,sizeof(short),N,fout); - - prev_model = model; - for(i=0; i<LPC_ORD; i++) - prev_lsps[i] = lsps[i]; - prev_e = e; - } - else { - voiced1 = model.voiced; } + + prev__Wo = prev_Wo; + prev_Wo = model.Wo; + prev_uq_Wo = uq_Wo; + //if (frames == 8) { + // exit(0); + //} } - else { - if (phase0) - phase_synth_zero_order(&model, ak, ex_phase, order); - if (postfilt) - postfilter(&model, &bg_est); - synth_one_frame(buf, &model, Sn_, Pn); - if (fout != NULL) fwrite(buf,sizeof(short),N,fout); - } - prev_Wo = TWO_PI/pitch; - } - fclose(fin); - if (fout != NULL) - fclose(fout); + /*----------------------------------------------------------------*\ - if (lpc_model || resample) - printf("SNR av = %5.2f dB\n", sum_snr/frames); + End Main Loop -#ifdef DUMP - if (dump) - dump_off(); -#endif + \*----------------------------------------------------------------*/ + + fclose(fin); - if (hand_voicing) - fclose(fvoicing); + if (fout != NULL) + fclose(fout); - nlp_destroy(nlp_states); + if (lpc_model) + printf("SNR av = %5.2f dB\n", sum_snr/frames); - return 0; + if (phaseexp) + phase_experiment_destroy(pexp); + if (ampexp) + amp_experiment_destroy(aexp); + #ifdef DUMP + if (dump) + dump_off(); + #endif + + if (hand_voicing) + fclose(fvoicing); + + nlp_destroy(nlp_states); + + return 0; } -void synth_one_frame(short buf[], MODEL *model, float Sn_[], float Pn[]) +void synth_one_frame(kiss_fft_cfg fft_inv_cfg, short buf[], MODEL *model, float Sn_[], float Pn[], int prede, float *de_mem, float gain) { int i; - synthesise(Sn_, model, Pn, 1); + synthesise(fft_inv_cfg, Sn_, model, Pn, 1); + if (prede) + de_emp(Sn_, Sn_, de_mem, N); for(i=0; i<N; i++) { + Sn_[i] *= gain; if (Sn_[i] > 32767.0) buf[i] = 32767; else if (Sn_[i] < -32767.0) @@ -467,3 +893,36 @@ void synth_one_frame(short buf[], MODEL *model, float Sn_[], float Pn[]) } } + +void print_help(const struct option* long_options, int num_opts, char* argv[]) +{ + int i; + char *option_parameters; + + fprintf(stderr, "\nCodec2 - low bit rate speech codec - Simulation Program\n" + "\thttp://rowetel.com/codec2.html\n\n" + "usage: %s [OPTIONS] <InputFile>\n\n" + "Options:\n" + "\t-o <OutputFile>\n", argv[0]); + for(i=0; i<num_opts-1; i++) { + if(long_options[i].has_arg == no_argument) { + option_parameters=""; + } else if (strcmp("lpc", long_options[i].name) == 0) { + option_parameters = " <Order>"; + } else if (strcmp("lspdt_mode", long_options[i].name) == 0) { + option_parameters = " <all|high|low>"; + } else if (strcmp("hand_voicing", long_options[i].name) == 0) { + option_parameters = " <VoicingFile>"; + } else if (strcmp("dump_pitch_e", long_options[i].name) == 0) { + option_parameters = " <Dump File>"; + } else if (strcmp("rate", long_options[i].name) == 0) { + option_parameters = " <4800|2400|1400|1200>"; + } else if (strcmp("dump", long_options[i].name) == 0) { + option_parameters = " <DumpFilePrefix>"; + } else { + option_parameters = " <UNDOCUMENTED parameter>"; + } + fprintf(stderr, "\t--%s%s\n", long_options[i].name, option_parameters); + } + exit(1); +} diff --git a/gr-vocoder/lib/codec2/codebook/dlsp1.txt b/gr-vocoder/lib/codec2/codebook/dlsp1.txt index d126be7714..058d048d3c 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp1.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp1.txt @@ -1,4 +1,12 @@ -1 16 +1 32 +25 +50 +75 +100 +125 +150 +175 +200 225 250 275 @@ -15,3 +23,13 @@ 550 575 600 +625 +650 +675 +700 +725 +750 +775 +800 + + diff --git a/gr-vocoder/lib/codec2/codebook/dlsp10.txt b/gr-vocoder/lib/codec2/codebook/dlsp10.txt index dea9dd9d84..058d048d3c 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp10.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp10.txt @@ -1,9 +1,35 @@ -1 8 +1 32 +25 50 +75 100 +125 +150 +175 200 +225 +250 +275 300 +325 +350 +375 +400 425 +450 +475 +500 +525 550 +575 +600 +625 +650 675 +700 +725 +750 +775 800 + + diff --git a/gr-vocoder/lib/codec2/codebook/dlsp2.txt b/gr-vocoder/lib/codec2/codebook/dlsp2.txt index 234bf20671..058d048d3c 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp2.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp2.txt @@ -1,4 +1,4 @@ -1 16 +1 32 25 50 75 @@ -15,3 +15,21 @@ 350 375 400 +425 +450 +475 +500 +525 +550 +575 +600 +625 +650 +675 +700 +725 +750 +775 +800 + + diff --git a/gr-vocoder/lib/codec2/codebook/dlsp3.txt b/gr-vocoder/lib/codec2/codebook/dlsp3.txt index b2ee06da46..058d048d3c 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp3.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp3.txt @@ -1,9 +1,35 @@ -1 8 +1 32 +25 50 75 100 -120 +125 150 +175 +200 +225 250 +275 +300 +325 350 +375 +400 +425 450 +475 +500 +525 +550 +575 +600 +625 +650 +675 +700 +725 +750 +775 +800 + + diff --git a/gr-vocoder/lib/codec2/codebook/dlsp4.txt b/gr-vocoder/lib/codec2/codebook/dlsp4.txt index dea9dd9d84..4a5e9902a4 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp4.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp4.txt @@ -1,9 +1,35 @@ -1 8 +1 32 +25 50 +75 100 +125 +150 +175 200 +250 300 -425 +350 +400 +450 +500 550 -675 +600 +650 +700 +750 800 +850 +900 +950 +1000 +1050 +1100 +1150 +1200 +1250 +1300 +1350 +1400 + + diff --git a/gr-vocoder/lib/codec2/codebook/dlsp5.txt b/gr-vocoder/lib/codec2/codebook/dlsp5.txt index dea9dd9d84..4a5e9902a4 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp5.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp5.txt @@ -1,9 +1,35 @@ -1 8 +1 32 +25 50 +75 100 +125 +150 +175 200 +250 300 -425 +350 +400 +450 +500 550 -675 +600 +650 +700 +750 800 +850 +900 +950 +1000 +1050 +1100 +1150 +1200 +1250 +1300 +1350 +1400 + + diff --git a/gr-vocoder/lib/codec2/codebook/dlsp6.txt b/gr-vocoder/lib/codec2/codebook/dlsp6.txt index dea9dd9d84..4a5e9902a4 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp6.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp6.txt @@ -1,9 +1,35 @@ -1 8 +1 32 +25 50 +75 100 +125 +150 +175 200 +250 300 -425 +350 +400 +450 +500 550 -675 +600 +650 +700 +750 800 +850 +900 +950 +1000 +1050 +1100 +1150 +1200 +1250 +1300 +1350 +1400 + + diff --git a/gr-vocoder/lib/codec2/codebook/dlsp7.txt b/gr-vocoder/lib/codec2/codebook/dlsp7.txt index dea9dd9d84..058d048d3c 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp7.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp7.txt @@ -1,9 +1,35 @@ -1 8 +1 32 +25 50 +75 100 +125 +150 +175 200 +225 +250 +275 300 +325 +350 +375 +400 425 +450 +475 +500 +525 550 +575 +600 +625 +650 675 +700 +725 +750 +775 800 + + diff --git a/gr-vocoder/lib/codec2/codebook/dlsp8.txt b/gr-vocoder/lib/codec2/codebook/dlsp8.txt index dea9dd9d84..058d048d3c 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp8.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp8.txt @@ -1,9 +1,35 @@ -1 8 +1 32 +25 50 +75 100 +125 +150 +175 200 +225 +250 +275 300 +325 +350 +375 +400 425 +450 +475 +500 +525 550 +575 +600 +625 +650 675 +700 +725 +750 +775 800 + + diff --git a/gr-vocoder/lib/codec2/codebook/dlsp9.txt b/gr-vocoder/lib/codec2/codebook/dlsp9.txt index dea9dd9d84..058d048d3c 100644 --- a/gr-vocoder/lib/codec2/codebook/dlsp9.txt +++ b/gr-vocoder/lib/codec2/codebook/dlsp9.txt @@ -1,9 +1,35 @@ -1 8 +1 32 +25 50 +75 100 +125 +150 +175 200 +225 +250 +275 300 +325 +350 +375 +400 425 +450 +475 +500 +525 550 +575 +600 +625 +650 675 +700 +725 +750 +775 800 + + diff --git a/gr-vocoder/lib/codec2/codebook/gecb.txt b/gr-vocoder/lib/codec2/codebook/gecb.txt new file mode 100644 index 0000000000..bd3bb08a4a --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/gecb.txt @@ -0,0 +1,257 @@ +2 256 +2.709998 12.018395 +0.046750 -2.738813 +0.120993 8.388947 +-1.580275 -0.892307 +1.193065 -1.915609 +0.187101 -3.276788 +0.332251 -7.664550 +-1.479436 31.246122 +1.527612 27.709463 +-0.524379 5.250122 +0.553330 7.438797 +-0.843451 -1.952987 +2.263885 8.610286 +0.143143 2.365493 +0.616506 1.284268 +-1.711327 22.096672 +1.008128 17.396519 +-0.106718 1.418905 +-0.136246 14.273605 +-1.709087 -20.531881 +1.657866 -3.391068 +0.138049 -4.957845 +0.536729 -1.943748 +0.196307 36.851948 +1.272479 22.556494 +-0.670219 -1.906045 +0.382092 6.401132 +-0.756911 -4.901017 +1.829313 4.613800 +0.318794 0.736830 +0.612815 -2.075045 +-0.410151 24.787077 +1.776016 13.190924 +0.106457 -0.104492 +0.192206 10.183844 +-1.824423 -7.715654 +0.931346 4.348355 +0.308813 -4.086001 +0.397143 -11.808859 +-0.048715 41.227314 +0.877342 35.850311 +-0.759794 0.476634 +0.978593 7.674673 +-1.195056 3.038826 +2.639894 -3.411063 +0.191127 3.603507 +0.402932 1.084298 +-2.152022 18.107616 +1.546802 8.322713 +-0.143089 -4.075922 +-0.150142 5.866741 +-1.408444 -3.250696 +1.566148 -10.413164 +0.178171 -10.226697 +0.362164 -0.028556 +-0.070125 24.390722 +0.594752 17.482765 +-0.286980 -6.904069 +0.464818 10.205451 +-1.006841 -14.357209 +2.329569 -3.691613 +0.335745 2.407139 +1.019658 -3.155647 +-1.259455 7.991899 +2.383695 19.680567 +-0.094947 -2.413742 +0.209330 6.664768 +-2.221034 1.379860 +1.292387 2.046333 +0.243626 -0.890741 +0.428773 -7.193658 +-1.113744 41.341354 +2.609799 31.140514 +-0.446468 2.534188 +0.490104 4.627575 +-1.117226 -3.241744 +1.791562 8.414926 +0.156012 0.183336 +0.532447 3.154545 +-0.764484 18.513958 +0.952395 11.771298 +-0.332567 0.346987 +0.202165 14.716752 +-2.129240 -15.558954 +1.353583 -1.926790 +-0.010963 -16.336386 +0.399053 -2.790569 +0.750657 31.148336 +0.655743 24.481859 +-0.453210 -0.735879 +0.286900 6.546703 +-0.715673 -12.357815 +1.548488 3.872171 +0.271874 0.802339 +0.502073 -4.854850 +-0.497037 17.761904 +1.191161 13.954446 +0.015630 1.331566 +0.341867 8.935369 +-2.316009 -5.395058 +0.758610 1.964505 +0.241320 -3.237686 +0.267151 -11.234388 +-0.273126 32.624771 +1.753523 40.431995 +-0.784011 3.045757 +0.705987 5.661178 +-1.386400 1.353557 +2.376458 1.674851 +0.242973 4.732178 +0.491227 0.354061 +-1.606762 8.658955 +1.167111 5.987103 +-0.137601 -12.041750 +-0.251375 10.397204 +-1.431514 -8.904108 +0.988280 -13.208963 +0.261484 -6.354970 +0.395932 -0.702529 +0.283704 26.899563 +0.420959 15.441778 +-0.355804 -13.727784 +0.527372 12.398515 +-1.169559 -15.998457 +1.906688 -5.816055 +0.354492 3.851572 +0.825760 -4.162642 +-0.490190 13.057229 +2.255773 13.526449 +-0.004956 -3.237127 +0.026709 7.866448 +-1.810372 -0.451183 +1.083827 -0.183620 +0.135836 -2.266582 +0.375812 -5.512248 +-1.966443 38.682854 +1.977988 24.565481 +-0.704656 6.358810 +0.480786 7.051749 +-0.976417 -2.422727 +2.502148 6.759346 +0.083588 3.258795 +0.543629 0.910013 +-1.231959 23.091507 +0.785492 14.807000 +-0.213554 1.688002 +0.004748 18.171820 +-1.547192 -16.116837 +1.501045 -3.281141 +0.080133 -4.634724 +0.476592 -2.180929 +0.442470 40.303989 +1.072766 27.592009 +-0.594738 -4.166807 +0.422480 7.616091 +-0.927521 -7.274406 +1.991623 1.296359 +0.291307 2.398781 +0.721081 -1.950625 +-0.804256 24.929474 +1.648388 19.119692 +0.060852 -0.590639 +0.266085 9.103249 +-1.957399 -2.884607 +1.116929 2.672397 +0.354580 -2.748541 +0.330733 -14.156131 +-0.527851 39.575626 +0.991152 43.194984 +-0.589619 1.269186 +0.787401 8.730713 +-1.013800 1.025075 +2.825403 1.895381 +0.240890 2.745566 +0.427195 2.544456 +-1.953109 12.243958 +1.448616 12.060747 +-0.210492 -3.379058 +-0.056713 10.204020 +-1.652370 -5.102737 +1.294748 -12.270802 +0.111608 -8.675921 +0.326634 -1.167627 +0.021781 31.125782 +0.455335 21.468430 +-0.375440 -3.371207 +0.393620 11.301987 +-0.851456 -19.414892 +2.107030 -2.228865 +0.373233 1.924056 +0.884438 -1.720581 +-0.975127 9.840128 +2.003303 17.395407 +-0.036915 -1.111372 +0.148456 5.399970 +-1.914412 4.773819 +1.447907 0.537122 +0.194979 -1.038179 +0.495771 -9.955025 +-1.058987 32.947052 +2.011222 32.454418 +-0.309650 4.719106 +0.436082 4.635524 +-1.237105 -1.254284 +2.022740 9.428345 +0.190342 1.460767 +0.479017 2.484788 +-1.078483 16.221748 +1.207642 9.654212 +-0.258087 -1.672358 +0.071852 13.415978 +-1.877228 -16.072031 +1.289568 -4.871185 +0.067713 -13.442700 +0.435551 -4.165503 +0.466140 30.589535 +0.904895 21.597990 +-0.518369 -2.532048 +0.337363 5.637264 +-0.554975 -17.400511 +1.691879 1.145742 +0.227934 0.889297 +0.587303 -5.729732 +-0.262133 18.666620 +1.395048 17.002878 +-0.019090 4.308379 +0.304235 12.669943 +-2.074059 -6.460845 +0.920546 1.212957 +0.284927 -1.785466 +0.209724 -16.023964 +-0.636067 31.576820 +1.349887 34.677502 +-0.971625 5.300859 +0.590249 4.449709 +-1.567867 3.602385 +2.145497 4.516663 +0.296022 4.120170 +0.445299 0.868772 +-1.441931 14.128431 +1.355752 6.007401 +-0.012814 -7.496573 +-0.430000 8.500124 +-1.204693 -7.113256 +1.101018 -6.836818 +0.196463 -6.234002 +0.436747 -1.129788 +0.141052 22.854876 +0.290821 18.811443 +-0.529536 -7.732510 +0.634280 10.789847 +-1.334721 -20.325773 +1.815645 -1.903316 +0.394778 3.797577 +0.732682 -8.183819 +-0.741244 11.768337 diff --git a/gr-vocoder/lib/codec2/codebook/lsp45678910.txt b/gr-vocoder/lib/codec2/codebook/lsp45678910.txt new file mode 100644 index 0000000000..291d3cdbce --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp45678910.txt @@ -0,0 +1,4097 @@ +6 4096 +1.081234 1.578844 1.855572 1.937313 2.532441 2.649806 +1.062804 1.450009 1.839560 1.956503 2.488847 2.653463 +1.101587 1.361019 1.833584 1.932414 2.505176 2.629812 +1.079058 1.376855 1.872688 1.955078 2.541337 2.633780 +1.095536 1.631036 1.866273 2.066987 2.506661 2.570431 +1.093059 1.561358 1.772473 2.123863 2.547475 2.618258 +1.093649 1.500206 1.786047 2.077115 2.483767 2.572542 +1.035022 1.485983 1.678652 2.079363 2.402344 2.513315 +1.231720 1.630566 1.849906 2.023447 2.467212 2.571610 +1.206362 1.478193 1.855647 2.009197 2.437429 2.552382 +1.204249 1.495756 1.846404 2.039977 2.500628 2.592437 +1.272025 1.438353 1.854503 2.038713 2.518717 2.620094 +1.298912 1.483356 1.838869 1.983659 2.488374 2.597006 +1.385591 1.500184 1.819431 1.981705 2.505537 2.612529 +1.413670 1.566546 1.767180 1.994490 2.569613 2.625244 +1.469053 1.626083 1.751768 2.041187 2.608951 2.658775 +1.489505 1.617638 1.689177 2.053852 2.662243 2.705533 +1.431122 1.535578 1.647319 1.810924 2.575767 2.692196 +1.411673 1.606174 1.730361 1.969368 2.628110 2.691849 +1.341020 1.639970 2.197392 2.281319 2.449714 2.625998 +1.319877 1.674826 2.101177 2.281732 2.499782 2.611482 +1.274620 1.610124 1.901436 2.235657 2.518178 2.628876 +1.172210 1.365637 1.784703 1.904448 2.538076 2.646190 +1.096161 1.350109 1.754990 1.869673 2.486568 2.605496 +1.036538 1.326195 1.729890 1.862116 2.461192 2.575454 +1.016529 1.277247 1.688801 1.808376 2.462981 2.576244 +0.968031 1.329007 1.716412 1.821357 2.481150 2.561950 +0.940641 1.283342 1.767876 1.860537 2.503139 2.594903 +0.926995 1.243331 1.738909 1.901001 2.449501 2.557636 +0.839883 1.237117 1.702150 1.812616 2.421388 2.492978 +0.924474 1.188075 1.757524 1.824899 2.455944 2.611065 +0.964230 1.207274 1.666224 1.876812 2.507149 2.580412 +0.989772 1.189729 1.693447 1.807142 2.445712 2.561953 +0.919183 1.203118 1.673832 1.772614 2.385797 2.511668 +0.978552 1.175420 1.613855 1.726871 2.328959 2.516699 +1.014543 1.254251 1.587284 1.756626 2.403061 2.510828 +1.096718 1.231168 1.557405 1.843944 2.463584 2.555458 +1.168771 1.351177 1.613931 1.831029 2.476269 2.581218 +1.176515 1.264150 1.564916 1.760486 2.483522 2.581045 +1.017969 1.249828 1.424493 1.593545 2.458340 2.525030 +1.053988 1.216029 1.517421 1.851941 2.342751 2.502327 +0.908986 1.250795 1.593917 1.887100 2.373089 2.530129 +0.993871 1.164018 1.616620 1.775732 2.569459 2.658570 +1.102483 1.386153 1.573681 1.785642 2.317931 2.508557 +1.207240 1.390831 1.551049 1.850614 2.335983 2.494330 +0.905032 1.416478 1.580046 1.841825 2.503807 2.601603 +0.795890 1.107933 1.597705 2.015496 2.402148 2.534611 +0.732401 1.158610 1.557468 1.938003 2.626415 2.705430 +0.859670 1.129062 1.671859 1.953992 2.514790 2.615870 +0.921647 1.245355 1.683753 1.894457 2.599645 2.716564 +0.845409 1.194759 1.767314 1.844514 2.589767 2.716944 +0.977678 1.141401 1.667109 1.923833 2.632008 2.689070 +0.951137 1.122551 1.714183 1.885895 2.535763 2.672112 +1.029949 1.159554 1.739443 1.928325 2.488185 2.623518 +0.925634 1.225929 1.751801 1.970749 2.532895 2.621066 +1.012300 1.211427 1.793946 1.885857 2.467267 2.572492 +0.993978 1.137467 1.743472 1.840886 2.390082 2.566385 +0.989822 1.173068 1.687559 1.948929 2.325527 2.473423 +0.955854 1.237231 1.807406 2.116766 2.391031 2.502779 +1.103361 1.357985 1.852236 2.097091 2.392749 2.553242 +1.128873 1.440897 1.927907 2.176697 2.407985 2.544276 +1.316127 1.575436 1.964565 2.158944 2.485840 2.576132 +1.469605 1.772101 1.954837 2.164070 2.399616 2.481917 +1.506520 1.754882 2.018413 2.249491 2.486272 2.607615 +1.524190 1.776451 2.054579 2.275694 2.584977 2.669083 +1.518000 1.850281 2.026435 2.301875 2.577528 2.669180 +1.422050 1.788979 1.967476 2.184773 2.596851 2.699678 +1.208408 1.434703 1.923623 2.003769 2.602930 2.685007 +1.221170 1.436565 1.879969 2.033402 2.498146 2.695421 +1.217714 1.375982 1.908609 1.973031 2.480559 2.645396 +1.200348 1.412239 1.863276 2.054536 2.409232 2.646327 +1.439453 1.675933 2.064707 2.273226 2.606450 2.696215 +1.547568 1.956021 2.083785 2.387077 2.634316 2.711216 +1.745365 1.995260 2.176270 2.409488 2.632251 2.707416 +1.819289 1.982164 2.210166 2.452194 2.603770 2.664517 +1.669555 1.940179 2.100875 2.386942 2.530819 2.630866 +1.597684 1.945913 2.072836 2.338891 2.544245 2.608247 +1.656152 1.888690 1.984550 2.301133 2.510775 2.586360 +1.618800 1.898863 2.024738 2.291312 2.440530 2.560289 +1.481284 1.826210 1.971921 2.192909 2.417020 2.530293 +1.318733 1.581540 1.845445 2.163997 2.389227 2.505418 +1.341326 1.565852 1.802875 2.218482 2.430769 2.545834 +1.318506 1.412657 1.677620 2.182351 2.372753 2.476532 +1.243720 1.456674 1.665712 2.126711 2.332874 2.438449 +1.152502 1.458855 1.582937 2.037521 2.342102 2.428296 +1.025383 1.407599 1.551528 1.846789 2.282863 2.385436 +0.876560 1.384326 1.582900 1.741935 2.239923 2.338453 +0.953781 1.441879 1.592404 1.764174 2.294091 2.474201 +0.899968 1.454031 1.634363 1.724312 2.353403 2.597502 +0.784159 1.423933 1.737258 1.855960 2.390032 2.614540 +0.802442 1.397066 1.658548 1.816788 2.429390 2.500099 +0.863071 1.318492 1.646022 1.812971 2.398098 2.503855 +0.896870 1.306239 1.671592 1.902175 2.466526 2.601523 +0.999503 1.304292 1.708420 1.899036 2.512342 2.655191 +1.045277 1.266302 1.669631 1.846323 2.517066 2.637484 +1.038456 1.158529 1.643778 1.865279 2.583201 2.658938 +1.026317 1.219306 1.768348 1.840920 2.538168 2.673329 +1.080965 1.215431 1.730192 1.836927 2.236858 2.608870 +1.101801 1.431508 1.752078 1.918964 2.091244 2.538958 +1.178729 1.297314 1.724099 1.850753 2.310291 2.621525 +1.151182 1.239683 1.754792 1.850524 2.539101 2.705992 +1.202697 1.300604 1.763340 1.867428 2.470717 2.664655 +1.261122 1.368681 1.753282 1.846646 2.461515 2.652599 +1.263075 1.364289 1.797670 1.876939 2.543725 2.660224 +1.320149 1.415925 1.809830 1.903217 2.515554 2.648236 +1.339872 1.459354 1.806677 1.924576 2.491477 2.587047 +1.355170 1.451772 1.763405 1.944161 2.472633 2.561167 +1.327925 1.428910 1.704448 1.914816 2.397366 2.503472 +1.307600 1.415352 1.616295 1.840793 2.322166 2.470994 +1.248247 1.349207 1.617615 1.772735 2.250680 2.486533 +1.096572 1.355681 1.626115 1.941988 2.313846 2.498213 +1.012526 1.342839 1.647854 1.907164 2.435934 2.533191 +0.944393 1.399280 1.642998 1.931993 2.331977 2.489908 +0.883306 1.402338 1.706359 2.025366 2.373713 2.543710 +0.829559 1.235771 1.712746 2.184853 2.386736 2.544183 +0.923799 1.513109 1.703086 2.105291 2.476476 2.555162 +0.772688 1.443301 1.656120 2.053011 2.450442 2.532517 +0.776285 1.403196 1.734016 1.935257 2.464085 2.566799 +0.782396 1.418811 1.758875 1.973225 2.548330 2.610298 +0.789572 1.411082 1.771533 2.060410 2.540262 2.631254 +0.774326 1.288019 1.837269 1.960951 2.512420 2.581626 +0.811751 1.274027 1.810006 1.885738 2.565463 2.639219 +0.844982 1.320831 1.873915 1.944600 2.561048 2.661720 +0.881256 1.695357 1.906981 2.078886 2.618546 2.678654 +1.099890 1.727818 1.971319 2.153135 2.509688 2.602947 +1.173850 1.685437 1.917457 2.147432 2.383055 2.567035 +1.101548 1.543219 1.820605 2.055324 2.338724 2.585028 +0.975012 1.379716 1.776625 2.033293 2.194151 2.518224 +0.967054 1.082459 1.618973 2.077928 2.206837 2.370886 +1.009607 1.120613 1.534181 2.088528 2.282936 2.420584 +0.899159 1.208523 1.423691 1.970324 2.287269 2.498904 +0.879682 1.314480 1.479489 1.689360 2.209743 2.285765 +1.033473 1.243843 1.473137 1.667992 2.159422 2.255044 +1.048412 1.255890 1.536997 1.820047 2.142252 2.313751 +1.048246 1.189264 1.705109 1.835993 2.105450 2.372062 +1.034320 1.138878 1.514616 1.829657 2.170447 2.425608 +1.103878 1.217645 1.622150 1.805848 2.027526 2.376811 +1.087235 1.195012 1.559018 1.895036 2.250122 2.379205 +1.130013 1.293868 1.692397 1.858880 2.197201 2.349063 +1.162892 1.304601 1.691021 1.969323 2.268614 2.430288 +1.151808 1.257932 1.673832 1.902017 2.189155 2.458708 +1.168445 1.271828 1.557328 2.084152 2.308031 2.420367 +1.235095 1.340187 1.656794 2.095155 2.283187 2.409638 +1.252394 1.355363 1.609848 2.085193 2.332714 2.488870 +1.226314 1.343994 1.673049 2.215533 2.459996 2.546921 +1.408182 1.566449 1.701931 2.155097 2.540243 2.588591 +1.303998 1.548995 1.653578 2.128738 2.589470 2.633320 +1.312529 1.488936 1.690548 1.982880 2.558390 2.622521 +1.303590 1.485664 1.772996 1.991417 2.555629 2.650059 +1.257202 1.528917 1.880489 2.045674 2.400087 2.567493 +1.294719 1.634324 1.911539 2.046657 2.438083 2.611133 +1.328444 1.716065 1.850301 2.021260 2.507052 2.612864 +1.138077 1.269039 1.792588 1.898148 2.530410 2.653563 +1.024794 1.145542 1.688222 1.812928 2.425037 2.650928 +1.056656 1.178042 1.590336 1.747349 2.368449 2.618711 +0.994299 1.110839 1.632651 1.730538 2.337688 2.550296 +0.960030 1.103482 1.632800 1.745079 2.197252 2.530535 +0.952099 1.078914 1.704160 1.837306 2.319065 2.544307 +0.901034 1.074801 1.653662 1.788590 2.393831 2.533117 +0.970595 1.130054 1.568353 1.820966 2.445105 2.563373 +0.883200 1.029140 1.480583 1.884365 2.321620 2.470715 +0.817959 0.941844 1.410138 1.540709 2.174043 2.482774 +0.772028 0.888033 1.490117 1.717092 2.324349 2.560462 +0.874200 1.020101 1.571479 1.746811 2.437393 2.561332 +0.827282 1.010026 1.605382 1.750680 2.261846 2.481604 +0.790605 1.149000 1.653820 1.781055 2.358642 2.491606 +0.746581 0.961080 1.604908 1.879005 2.319270 2.551585 +0.845418 0.969530 1.696169 1.890927 2.301880 2.621489 +0.826083 1.016050 1.658604 1.852554 2.435884 2.572744 +0.804260 0.948999 1.684490 2.103337 2.475054 2.575853 +0.837016 1.029999 1.676991 1.796645 2.498023 2.631032 +0.779629 0.917041 1.607073 1.868904 2.459568 2.628902 +0.802981 0.922379 1.556141 1.967845 2.595450 2.692512 +0.821239 0.952349 1.585249 2.095797 2.593711 2.655934 +0.819528 1.109552 1.526845 1.767514 2.637798 2.710511 +0.846222 1.055717 1.707281 1.838626 2.113999 2.501403 +0.956553 1.439848 1.724902 1.939820 2.145194 2.431913 +1.334292 1.551594 1.721399 2.019173 2.178003 2.329439 +1.247359 1.571459 1.834521 2.114156 2.268206 2.489811 +1.223145 1.573420 1.846247 2.016089 2.219280 2.457849 +1.239932 1.537791 1.822800 2.046476 2.444455 2.578055 +1.299681 1.557742 1.798304 2.080692 2.393370 2.575201 +1.273117 1.474131 1.814869 2.014907 2.405011 2.602918 +1.229029 1.448502 1.757153 2.050565 2.417160 2.594614 +1.206296 1.515099 1.788958 2.042150 2.368561 2.585804 +1.158903 1.544803 1.861448 2.066653 2.405246 2.590991 +1.203257 1.479859 1.833516 2.070616 2.431802 2.585701 +1.170767 1.555780 1.826674 2.077078 2.467476 2.619408 +1.116279 1.593527 1.824249 2.160817 2.427806 2.600491 +1.250314 1.617299 1.962648 2.152242 2.531239 2.631433 +1.352996 1.645245 2.070194 2.180379 2.612026 2.688774 +1.460334 1.917189 2.086815 2.314592 2.641184 2.723059 +1.557095 1.916613 2.056898 2.263201 2.640329 2.702797 +1.410674 1.903388 2.077833 2.222944 2.615402 2.694117 +1.340491 1.804040 2.040016 2.149565 2.607705 2.678152 +1.090681 1.321064 1.862736 1.983775 2.475855 2.592436 +1.002459 1.265507 1.813017 1.904336 2.499258 2.626541 +1.051386 1.161286 1.832534 1.955080 2.502338 2.624753 +0.942516 1.064243 1.669560 1.977253 2.464181 2.598328 +0.869608 0.984141 1.454614 1.956177 2.507893 2.617868 +0.972489 1.135467 1.529146 1.729979 2.411574 2.571077 +1.051275 1.149410 1.547524 1.827149 2.511333 2.617618 +1.079744 1.191206 1.539363 1.944728 2.545236 2.632156 +1.182063 1.260030 1.596098 2.084659 2.511859 2.579406 +1.172004 1.352761 1.462749 2.015059 2.625356 2.679374 +1.200545 1.322975 1.515601 1.769202 2.523140 2.666825 +1.228092 1.307135 1.734031 1.914746 2.244815 2.562025 +1.176188 1.321661 1.782310 1.882580 2.271364 2.521450 +1.150025 1.486223 1.774146 1.970935 2.385075 2.612636 +1.103163 1.455003 1.720622 1.899593 2.356715 2.591383 +1.070467 1.386313 1.746928 1.891984 2.367512 2.543572 +0.953610 1.176163 1.643545 1.919980 2.372057 2.572461 +1.052319 1.405171 1.688954 1.831668 2.542879 2.632479 +0.996802 1.441427 1.684462 1.821948 2.595992 2.658845 +1.026550 1.334938 1.740944 1.840382 2.571653 2.678967 +1.108319 1.200840 1.706127 1.999085 2.514665 2.648206 +1.133324 1.219468 1.747774 2.013077 2.406643 2.640363 +1.142143 1.218723 1.814638 1.951061 2.430067 2.666180 +1.081563 1.207089 1.846455 1.946284 2.339144 2.612659 +1.146374 1.238625 1.874251 1.968098 2.427377 2.595630 +1.069408 1.393128 1.859759 1.941816 2.374471 2.538181 +1.060221 1.402928 1.784643 1.909954 2.080852 2.375424 +0.893759 1.225333 1.741426 1.895488 2.062213 2.441777 +0.911307 1.301394 1.651487 1.798169 1.996879 2.208655 +1.102905 1.503307 1.707775 1.808533 1.958631 2.311679 +1.149446 1.328058 1.738279 1.904609 2.061868 2.257965 +1.121345 1.230563 1.748776 1.950661 2.086466 2.389286 +0.948970 1.101893 1.676635 1.875393 2.016817 2.296681 +1.035082 1.162231 1.641377 1.952709 2.100948 2.358717 +0.994183 1.114307 1.547601 1.773728 1.966081 2.336299 +1.025110 1.139705 1.585236 1.912371 2.102465 2.482426 +0.955352 1.062216 1.659060 1.848407 2.043281 2.487426 +1.049103 1.120549 1.446982 1.949018 2.026898 2.560590 +1.012432 1.138276 1.367936 2.008468 2.189441 2.422416 +1.082028 1.234911 1.351755 1.827170 2.173158 2.300241 +1.094359 1.235138 1.416416 1.922593 2.128232 2.419413 +1.034512 1.151307 1.492358 1.980846 2.149036 2.365312 +1.013088 1.154539 1.459958 1.943044 2.281758 2.397269 +0.987103 1.274347 1.561873 1.917460 2.334292 2.495651 +0.989791 1.289172 1.623138 1.982329 2.345033 2.548052 +1.042013 1.225970 1.610016 1.974800 2.406311 2.537036 +1.019690 1.323725 1.679076 1.983690 2.443023 2.561932 +1.030978 1.249914 1.753285 1.970302 2.442750 2.577102 +1.078647 1.281367 1.821676 2.046994 2.512487 2.614303 +1.042503 1.318276 1.817538 1.977740 2.538774 2.643473 +1.033751 1.323431 1.885960 1.993635 2.587127 2.648293 +1.084158 1.434121 1.899660 1.974483 2.661669 2.717102 +1.095790 1.481301 1.916550 1.970409 2.671232 2.730973 +1.147960 1.553068 1.884541 1.960664 2.501839 2.667876 +1.137776 1.498910 1.962620 2.047239 2.537310 2.642351 +1.108862 1.435492 1.955490 2.195866 2.514284 2.601530 +1.191071 1.557850 1.984542 2.270790 2.541878 2.642064 +1.110737 1.553081 1.978127 2.211052 2.613375 2.706641 +1.114093 1.728016 1.975042 2.124483 2.602927 2.681942 +1.148485 1.627087 1.968135 2.073898 2.607358 2.686667 +1.109004 1.450655 1.961102 2.058609 2.611646 2.694610 +1.095904 1.318763 1.866640 2.096294 2.574677 2.658840 +1.116558 1.367968 1.922533 2.016505 2.549444 2.646230 +1.129468 1.529113 1.942204 2.003339 2.527872 2.699919 +1.139050 1.679536 1.945866 2.032922 2.537427 2.642172 +1.219207 1.599421 1.929600 2.011091 2.539104 2.705280 +1.233969 1.556201 1.930999 2.084786 2.578580 2.675834 +1.234430 1.653741 2.033213 2.256759 2.637546 2.699663 +1.255288 1.475044 2.022543 2.289234 2.587690 2.703947 +1.253389 1.472198 1.956397 2.211186 2.574243 2.676099 +1.126854 1.587210 1.950824 2.031487 2.416846 2.614459 +1.007062 1.608304 1.896229 1.986335 2.223017 2.524028 +1.067280 1.729449 1.931889 2.045329 2.164850 2.400910 +0.946660 1.699777 1.870624 1.981832 2.135670 2.447688 +1.002686 1.728563 1.939905 2.072520 2.274792 2.467485 +1.148787 1.600550 2.003063 2.128026 2.409105 2.506525 +1.191365 1.359514 1.908437 2.116985 2.369079 2.529393 +1.229740 1.316359 1.901465 2.001169 2.368350 2.575701 +1.167453 1.284078 1.851548 2.056283 2.446292 2.573763 +1.177049 1.282978 1.796076 2.014566 2.409896 2.524428 +1.166550 1.281729 1.804132 1.938592 2.383050 2.543803 +1.144710 1.266197 1.755782 1.865513 2.354119 2.575142 +1.168465 1.283561 1.695054 1.817537 2.302788 2.529561 +1.093474 1.316111 1.625831 1.791050 2.303314 2.408563 +1.072994 1.218877 1.586912 1.725308 2.219203 2.343524 +0.946241 1.172838 1.426290 1.551682 2.192575 2.321727 +1.001802 1.174980 1.507444 1.697862 2.240802 2.478241 +0.992564 1.257780 1.429092 1.819825 2.234153 2.434915 +0.933586 1.255559 1.372464 1.686266 2.265977 2.349467 +0.987914 1.162881 1.404420 1.563483 2.227668 2.485371 +1.058576 1.185833 1.325383 1.445585 2.164512 2.455141 +1.042271 1.149610 1.389036 1.473828 1.906671 2.390132 +0.966952 1.075537 1.288155 1.405105 2.061861 2.451990 +0.901530 1.194476 1.354732 1.705750 2.325032 2.434812 +1.038418 1.292428 1.527305 1.909844 2.230333 2.465135 +1.336010 1.441693 1.849134 2.208029 2.414400 2.532513 +1.436224 1.645653 2.008636 2.198160 2.502278 2.601413 +1.424341 1.684427 1.929812 2.122504 2.512280 2.604860 +1.452203 1.722988 1.962207 2.156659 2.484102 2.584594 +1.481999 1.735238 1.971190 2.222801 2.512305 2.623621 +1.392556 1.721267 1.940304 2.174966 2.488944 2.601854 +1.243347 1.558461 1.809822 1.990890 2.381971 2.537485 +1.199294 1.421504 1.763108 1.990880 2.358918 2.489556 +1.217773 1.348784 1.714665 1.916837 2.379728 2.456961 +1.219523 1.326854 1.719656 1.838075 2.299329 2.435406 +1.263073 1.353656 1.787228 1.918973 2.320389 2.448246 +1.270962 1.373799 1.718185 1.857935 2.366922 2.481748 +1.284351 1.368069 1.793907 1.895081 2.356790 2.524604 +1.244789 1.353657 1.782947 1.928688 2.225716 2.379949 +1.269283 1.368726 1.719184 1.909677 2.267163 2.491540 +1.249305 1.338194 1.799918 1.917097 2.274691 2.533224 +1.179498 1.259046 1.802972 1.927327 2.228930 2.503637 +1.140961 1.245902 1.708660 1.923794 2.243465 2.557345 +1.063955 1.209030 1.737289 1.945349 2.338697 2.573092 +1.003475 1.109161 1.745131 1.902188 2.308443 2.601614 +0.937618 1.077537 1.747804 1.869648 2.205055 2.570449 +0.885099 1.192451 1.790545 1.876157 2.360305 2.598108 +0.803485 0.966415 1.768458 1.928742 2.196723 2.530460 +0.797205 1.120717 1.776585 1.878573 2.370357 2.614341 +0.831514 1.059080 1.808800 1.905483 2.448208 2.573050 +0.806597 0.967446 1.829385 1.963682 2.358632 2.653242 +0.699378 0.851831 1.739446 1.933943 2.516377 2.655249 +0.739203 1.033985 1.902113 2.010327 2.494149 2.629822 +0.945605 1.079706 1.796352 2.039543 2.581863 2.699784 +0.843512 1.304861 1.835452 2.036832 2.600217 2.677826 +0.970152 1.414374 1.854051 1.957787 2.596045 2.665425 +1.067282 1.438542 1.888429 2.067094 2.531016 2.643177 +1.117619 1.563112 1.886324 2.218866 2.530223 2.624080 +1.209656 1.626913 1.943700 2.187427 2.555090 2.658675 +1.338891 1.812879 2.030890 2.305204 2.569275 2.661165 +1.303367 1.840104 2.035985 2.286745 2.614227 2.713359 +1.193428 1.727354 1.926203 2.184400 2.574784 2.631812 +1.063515 1.717188 1.903657 2.119051 2.444811 2.497667 +1.062175 1.188948 1.810480 2.044978 2.322378 2.578780 +1.073201 1.177557 1.654731 2.023264 2.200369 2.442874 +1.027815 1.165415 1.669466 1.859614 2.202142 2.462466 +1.035584 1.148236 1.604900 1.872549 2.257851 2.551682 +1.007205 1.131087 1.579146 1.969788 2.331637 2.507912 +0.908594 1.005601 1.463269 2.072372 2.304356 2.407363 +0.981614 1.126428 1.280565 1.886853 2.101922 2.487836 +1.006764 1.132557 1.253088 1.718315 2.189249 2.436605 +0.899830 1.156538 1.260748 1.696712 2.116655 2.228297 +0.896996 1.246551 1.436874 1.645194 2.073642 2.149130 +0.965481 1.069671 1.446489 1.949492 2.091582 2.298331 +0.898113 1.058765 1.617556 1.941551 2.113568 2.374743 +0.769481 1.159379 1.597415 1.959851 2.283842 2.418197 +0.908091 1.305340 1.473570 1.862549 2.164147 2.331091 +0.924282 1.334689 1.563201 2.043541 2.406015 2.515756 +0.972939 1.381971 1.549985 2.021238 2.268488 2.419332 +1.032229 1.484031 1.620031 1.952234 2.267322 2.486440 +1.005234 1.354692 1.620203 1.777917 2.223067 2.497574 +1.072742 1.245035 1.661666 1.819389 2.260496 2.468700 +1.134470 1.250480 1.737034 1.868971 2.303204 2.466426 +1.145935 1.293264 1.728505 1.950979 2.350982 2.504021 +1.226356 1.329795 1.750777 1.982144 2.347843 2.553027 +1.234801 1.328107 1.696728 2.060564 2.437310 2.535600 +1.247128 1.360496 1.742955 1.961348 2.474080 2.668447 +1.234736 1.329837 1.688634 1.913331 2.442940 2.627695 +1.230430 1.326635 1.697588 1.806044 2.381473 2.618535 +1.188567 1.273079 1.708983 1.969001 2.340683 2.588959 +1.204284 1.331218 1.835523 2.141256 2.463226 2.583492 +1.202374 1.397220 1.863749 2.155165 2.599733 2.681191 +1.217581 1.333297 1.763898 1.994983 2.601835 2.684817 +1.272368 1.364451 1.776352 1.952098 2.563424 2.676170 +1.330173 1.434654 1.825090 1.938032 2.579405 2.666102 +1.383550 1.514770 1.774712 2.134998 2.528583 2.614711 +1.488234 1.631245 1.795942 2.180588 2.497787 2.585930 +1.497854 1.598429 1.760395 1.985719 2.538066 2.622220 +1.446514 1.555686 1.675484 1.899620 2.547070 2.637129 +1.420188 1.651758 1.888119 2.201558 2.498716 2.624372 +1.524851 1.748918 1.939479 2.132594 2.426619 2.604303 +1.588214 1.786968 1.965710 2.123251 2.417433 2.579888 +1.603052 1.805249 1.932723 2.088062 2.490882 2.628467 +1.521714 1.853040 1.968163 2.198421 2.530921 2.597229 +1.496309 1.785807 2.001979 2.206169 2.574155 2.645280 +1.405201 1.500557 1.908673 2.179223 2.543732 2.645774 +1.369555 1.501308 1.848796 2.089859 2.551118 2.643621 +1.395377 1.488644 1.872404 2.028116 2.530256 2.599192 +1.354582 1.508972 1.848875 1.976677 2.504926 2.579355 +1.325752 1.411326 1.837129 1.970792 2.502717 2.584831 +1.264497 1.390436 1.764758 2.087338 2.519279 2.625037 +1.280904 1.355652 1.790288 1.995707 2.502567 2.587359 +1.267443 1.360843 1.858033 2.035632 2.509375 2.584870 +1.238902 1.487541 1.786660 2.080354 2.480913 2.582137 +1.228708 1.441140 1.715963 1.893335 2.507070 2.565131 +1.167347 1.397307 1.672051 1.923535 2.438392 2.523520 +1.169232 1.356809 1.567433 1.950379 2.378945 2.468006 +1.240244 1.470896 1.629735 2.024684 2.376716 2.454875 +1.370859 1.665288 1.831505 2.176433 2.486403 2.586565 +1.513368 1.657039 1.965014 2.298013 2.532148 2.623007 +1.446940 1.612676 1.929087 2.232303 2.466210 2.565149 +1.430659 1.664527 1.882163 2.234579 2.421664 2.527294 +1.511551 1.658934 1.944043 2.198499 2.451946 2.588348 +1.539441 1.741360 2.111062 2.229922 2.438935 2.615056 +1.510948 1.846893 2.061790 2.202452 2.484110 2.572628 +1.366393 1.611652 2.079365 2.260070 2.467062 2.588032 +1.383579 1.641339 1.997349 2.226153 2.491435 2.611630 +1.381458 1.706898 1.963061 2.125553 2.596797 2.681115 +1.360033 1.558255 1.949661 2.054826 2.599573 2.714554 +1.379339 1.491775 1.925897 2.046337 2.539371 2.696047 +1.313275 1.469403 1.863111 2.141749 2.553959 2.668104 +1.201520 1.563000 1.925029 2.093014 2.476606 2.614413 +0.965563 1.662126 1.836100 2.071866 2.530046 2.578446 +0.976435 1.635119 1.844726 2.005117 2.553083 2.614153 +1.098159 1.549476 1.826426 1.907908 2.490671 2.625630 +0.971599 1.431927 1.818186 1.923193 2.493841 2.568117 +0.881008 1.272866 1.901429 1.959221 2.513674 2.596017 +0.915929 1.478770 1.955701 2.082549 2.494350 2.585776 +1.008177 1.579393 1.898198 2.139172 2.477629 2.551209 +0.937399 1.507567 1.803910 1.922590 2.546047 2.637297 +0.848413 1.358228 1.783925 1.906229 2.477012 2.588525 +0.863404 1.488629 1.835502 1.930032 2.465498 2.545317 +0.844376 1.622282 1.826798 2.048364 2.490552 2.545809 +0.869731 1.705034 1.854703 2.111605 2.517014 2.593453 +0.862235 1.623015 1.899372 2.028710 2.527844 2.574800 +0.931658 1.576339 1.853614 1.975118 2.542237 2.614786 +0.848799 1.588406 1.847097 1.955899 2.534073 2.584561 +0.737814 1.457219 1.829993 1.966203 2.501271 2.579455 +0.786199 1.100080 1.860369 1.964282 2.419364 2.566134 +0.728962 1.040841 1.773818 1.963733 2.356948 2.578866 +0.733093 1.147783 1.789774 1.909293 2.349819 2.481103 +0.785959 1.280236 1.730487 1.926696 2.346913 2.422480 +0.784924 1.446821 1.669690 1.935370 2.368317 2.459601 +0.758523 1.466915 1.805902 1.946588 2.352213 2.426335 +0.767907 1.544295 1.768171 2.003937 2.239037 2.386192 +0.896374 1.562074 1.716926 1.903301 2.308243 2.430582 +0.834530 1.504812 1.737424 1.917731 2.409279 2.493291 +0.896027 1.406949 1.730026 1.903326 2.431247 2.539722 +1.039666 1.364116 1.806278 1.948174 2.440690 2.557972 +1.093454 1.412357 1.833723 1.940104 2.489654 2.564450 +1.190180 1.386167 1.848700 1.956202 2.481553 2.580885 +1.243158 1.350416 1.811797 1.893593 2.467576 2.613520 +1.221986 1.308711 1.815913 1.911989 2.417533 2.600995 +1.228372 1.343619 1.763163 1.872602 2.394885 2.582719 +1.278387 1.389710 1.738500 1.870267 2.420854 2.532852 +1.211636 1.401793 1.710146 1.811019 2.363826 2.482240 +1.161497 1.400684 1.766674 1.891745 2.392605 2.495922 +1.114937 1.405487 1.718336 1.927418 2.356818 2.468335 +1.074680 1.452959 1.668715 1.898094 2.336526 2.443457 +1.006705 1.356254 1.629477 1.848470 2.313894 2.426320 +0.966452 1.457923 1.654693 1.906386 2.320056 2.418339 +0.939007 1.519988 1.667014 1.989416 2.390669 2.488951 +0.946840 1.483985 1.701087 2.105572 2.391444 2.490066 +0.909129 1.501060 1.665371 2.004939 2.256700 2.389841 +0.958919 1.390613 1.680082 2.107156 2.297251 2.440839 +1.462160 1.588562 1.808539 2.109890 2.264826 2.417467 +1.301642 1.673806 1.892518 2.168109 2.477558 2.561621 +1.152769 1.529326 1.783781 2.014354 2.446614 2.560929 +1.128698 1.493018 1.748156 1.930275 2.530674 2.621591 +1.164356 1.496855 1.767664 1.871136 2.607250 2.684794 +1.122714 1.380513 1.762236 1.875604 2.441522 2.732814 +1.173906 1.545927 1.843801 1.933791 2.123448 2.629011 +1.155439 1.465806 1.793876 1.928550 2.168553 2.609610 +1.147812 1.484543 1.816424 1.908762 2.262620 2.704081 +1.185870 1.393524 1.811853 1.881115 2.544291 2.735905 +1.153304 1.451135 1.855404 1.888619 2.603314 2.738077 +1.208854 1.582363 1.784858 1.880089 2.596481 2.727884 +1.194841 1.542896 1.919056 2.023145 2.551891 2.634186 +1.230327 1.492063 1.937225 2.133605 2.615726 2.690226 +1.258764 1.581307 1.980070 2.138762 2.599037 2.691033 +1.220691 1.572961 1.917212 2.177536 2.599585 2.702012 +1.258143 1.556630 1.871736 2.132633 2.585514 2.673307 +1.233770 1.598238 1.849957 2.013674 2.542859 2.634481 +1.269759 1.560794 1.865225 2.076328 2.521082 2.617443 +1.116561 1.680882 1.781694 1.920497 2.592211 2.675845 +1.048209 1.662996 1.817400 1.915170 2.484585 2.623077 +0.954241 1.619674 1.813457 1.881694 2.550667 2.631971 +0.964363 1.579747 1.728712 1.862126 2.567566 2.636332 +1.296922 1.646884 1.889259 2.069271 2.320227 2.481389 +1.232775 1.619596 1.955470 2.066559 2.335277 2.456514 +1.238971 1.351788 1.877566 2.166413 2.317967 2.474389 +1.180292 1.388353 1.607451 1.950835 2.210855 2.477718 +1.124001 1.423538 1.617323 1.826801 2.206068 2.444078 +1.147794 1.487048 1.627974 1.926015 2.278418 2.486526 +1.092654 1.499725 1.623041 1.880156 2.411660 2.648649 +1.115294 1.468690 1.607626 1.814459 2.356904 2.576088 +1.176045 1.424631 1.614229 1.966337 2.352676 2.570354 +1.211051 1.467429 1.617777 1.851487 2.389770 2.591860 +1.287681 1.464858 1.633790 1.856231 2.349748 2.565320 +1.298585 1.495223 1.639003 1.942642 2.415390 2.518116 +1.309890 1.431142 1.757192 1.977209 2.414871 2.520878 +1.392241 1.477414 1.811303 1.909687 2.440417 2.573891 +1.414942 1.515382 1.858997 2.127937 2.490674 2.635418 +1.490435 1.565967 1.952412 2.049065 2.499936 2.600180 +1.485068 1.734116 1.997368 2.089376 2.524766 2.608159 +1.507131 1.787198 2.048100 2.128356 2.533629 2.624653 +1.485217 1.772591 2.048100 2.144373 2.595743 2.679785 +1.560042 1.744521 2.076144 2.156837 2.615057 2.698771 +1.506276 1.855445 2.064190 2.144534 2.585665 2.687788 +1.592877 1.903451 2.084530 2.163395 2.496904 2.633589 +1.609454 1.870860 2.119821 2.186594 2.599505 2.697819 +1.594779 1.855348 2.025620 2.142545 2.572299 2.637841 +1.527194 1.714086 2.076267 2.185169 2.526549 2.631137 +1.518012 1.628010 2.039263 2.134528 2.453843 2.576361 +1.531312 1.678082 2.035179 2.146889 2.504859 2.584171 +1.508627 1.632606 1.965140 2.148678 2.496640 2.592746 +1.499896 1.599423 1.913687 2.036860 2.450192 2.538166 +1.481158 1.583812 1.884461 2.013870 2.359497 2.481100 +1.475736 1.569698 1.799993 1.916182 2.329218 2.535901 +1.498641 1.623604 1.792824 1.945217 2.358627 2.490727 +1.431128 1.574627 1.743263 2.006116 2.347765 2.508896 +1.427064 1.536583 1.790690 1.943028 2.344465 2.452652 +1.436838 1.542023 1.758917 1.925622 2.242913 2.416844 +1.419788 1.509038 1.863320 1.995399 2.275792 2.424732 +1.424396 1.510477 1.882887 2.179017 2.304708 2.455667 +1.366051 1.461194 1.935323 2.147551 2.263420 2.465785 +1.407395 1.564972 1.981125 2.103440 2.445291 2.565104 +1.597013 1.877015 2.068503 2.270312 2.499356 2.604888 +1.484981 1.818125 2.149815 2.337593 2.504753 2.589439 +1.487878 1.937181 2.118271 2.308368 2.511781 2.604626 +1.682297 1.977033 2.192290 2.373676 2.522931 2.611282 +1.749459 1.905682 2.218271 2.352013 2.574227 2.681484 +1.676221 1.936512 2.237179 2.343782 2.535908 2.661271 +1.723362 1.989915 2.271236 2.413144 2.550828 2.649366 +1.756006 1.996913 2.312656 2.461484 2.625420 2.708736 +1.499770 1.763295 2.158871 2.346879 2.592716 2.682851 +1.747521 1.927133 2.248936 2.410841 2.604121 2.690881 +1.670354 1.938258 2.247669 2.447135 2.657540 2.730040 +1.669237 1.959610 2.179318 2.440527 2.588429 2.640800 +1.780231 2.015138 2.164810 2.399021 2.581913 2.646942 +1.739561 1.967219 2.065694 2.364479 2.589977 2.649441 +1.605008 1.875105 2.018901 2.227404 2.541181 2.603541 +1.511246 1.892601 2.027827 2.148110 2.520001 2.608199 +1.363362 1.568768 1.910845 2.057695 2.463506 2.558819 +1.338497 1.483825 1.883695 2.067074 2.448950 2.577904 +1.369193 1.437863 1.845222 2.078464 2.428504 2.615891 +1.377698 1.498294 1.867666 2.164965 2.492547 2.570908 +1.408098 1.487760 1.872414 2.097948 2.447272 2.551716 +1.402363 1.531952 1.897693 2.126667 2.419162 2.551442 +1.456496 1.554631 1.841067 2.095807 2.421290 2.561761 +1.434931 1.529146 1.795336 2.163704 2.446465 2.530309 +1.391108 1.495499 1.869679 2.161228 2.381406 2.532017 +1.388934 1.534466 1.797003 2.102941 2.398508 2.521270 +1.358571 1.471303 1.760049 2.100883 2.350197 2.546548 +1.276599 1.519215 1.779419 2.095819 2.442938 2.665941 +1.206661 1.457865 1.760464 2.244280 2.495881 2.644848 +1.214611 1.460274 1.979019 2.239454 2.398324 2.634473 +1.275473 1.473470 1.878570 2.203117 2.475028 2.687851 +1.291712 1.399288 1.813807 2.194118 2.502758 2.614888 +1.260058 1.397998 1.924890 2.186721 2.511667 2.644548 +1.210634 1.326713 1.897594 2.107441 2.460079 2.711722 +1.202657 1.319235 1.892634 2.079859 2.379418 2.679891 +0.967019 1.105970 1.761322 2.107426 2.328428 2.593155 +0.947746 1.035797 1.393730 2.061233 2.300744 2.668280 +0.996167 1.215029 1.378995 1.861982 2.329665 2.605022 +1.008823 1.198481 1.313837 1.693525 2.360746 2.604824 +1.054057 1.218510 1.368106 1.738006 2.174906 2.546071 +1.021568 1.133991 1.369174 1.935639 2.267798 2.544415 +1.033742 1.227769 1.451289 2.005917 2.412620 2.595031 +1.065155 1.168636 1.530185 2.061499 2.410743 2.485478 +1.121227 1.281283 1.432233 1.909928 2.202734 2.509308 +1.170032 1.306041 1.494945 1.981910 2.202815 2.351735 +1.152630 1.266186 1.620999 2.057673 2.214453 2.381642 +1.228128 1.313272 1.751468 2.118469 2.263417 2.453888 +1.307832 1.398650 1.799753 2.125735 2.260615 2.451800 +1.360104 1.477444 1.835740 2.121870 2.291563 2.499791 +1.398477 1.492966 1.806519 2.107140 2.241410 2.434146 +1.351212 1.462506 1.726393 2.122387 2.285789 2.421844 +1.297203 1.498868 1.766246 2.157839 2.376714 2.497158 +1.377349 1.518971 1.803789 2.191150 2.356374 2.478897 +1.289165 1.553241 1.674591 2.112634 2.403345 2.473877 +1.188972 1.700336 1.834324 2.055585 2.599531 2.700414 +1.077038 1.667666 1.902189 2.045693 2.602910 2.700056 +1.072057 1.272462 1.843743 1.901183 2.586254 2.720558 +1.084385 1.392072 1.823558 1.901299 2.589426 2.680029 +1.106319 1.441363 1.766145 1.853724 2.549356 2.627414 +1.094566 1.550024 1.771922 1.870952 2.559682 2.628051 +1.041899 1.598552 1.813702 1.928485 2.545630 2.671501 +1.090204 1.610510 1.812559 2.019257 2.556321 2.608793 +1.016528 1.626657 1.742411 2.041925 2.541538 2.602247 +1.075570 1.647752 1.870667 2.073970 2.574597 2.628798 +1.126656 1.586213 1.792572 1.982408 2.629180 2.725561 +1.027776 1.542665 1.831396 1.956878 2.603010 2.668523 +1.111897 1.543416 1.861469 1.942917 2.621957 2.672864 +1.080512 1.583194 1.857304 1.958456 2.633597 2.695142 +1.132239 1.449156 1.884949 1.977000 2.607850 2.709420 +1.232769 1.612605 1.960435 2.071693 2.644678 2.727118 +1.325014 1.779901 1.967304 2.113871 2.547837 2.668723 +1.404585 1.644448 2.058088 2.257112 2.519116 2.634613 +1.413485 1.609401 2.002521 2.184102 2.587532 2.696153 +1.354020 1.593877 2.014439 2.122204 2.617254 2.721812 +1.373822 1.656758 1.992185 2.189875 2.548725 2.702514 +1.421181 1.611084 1.958071 2.123616 2.569835 2.648136 +1.379179 1.620195 1.922636 2.093948 2.550690 2.641857 +1.367726 1.656675 1.838447 1.992123 2.596226 2.654039 +1.394553 1.750623 1.872269 2.038430 2.553215 2.623595 +1.464021 1.741591 1.912988 2.150261 2.565594 2.648823 +1.461132 1.809059 1.954612 2.209898 2.570276 2.642519 +1.434520 1.770834 1.904022 2.217315 2.631183 2.686995 +1.375527 1.631662 1.885996 2.086587 2.600503 2.671257 +1.339213 1.568724 1.817375 2.085568 2.591336 2.666455 +1.504403 1.779590 2.057141 2.272445 2.534600 2.634655 +1.474504 1.746318 2.044711 2.137376 2.474545 2.630529 +1.557045 1.755017 2.039661 2.080935 2.661339 2.741743 +1.573452 1.715361 2.056726 2.098368 2.691640 2.743685 +1.511431 1.831887 1.991585 2.156042 2.624346 2.709519 +1.501907 1.714027 2.012931 2.079434 2.554662 2.690409 +1.547183 1.671908 1.977966 2.104057 2.507158 2.614807 +1.563264 1.635971 1.990128 2.123718 2.563823 2.633190 +1.587772 1.697791 2.007538 2.127360 2.588839 2.656541 +1.618303 1.722230 2.008488 2.131284 2.618167 2.687641 +1.580078 1.684932 2.000646 2.087829 2.613984 2.687671 +1.572775 1.736323 1.961536 2.144351 2.641248 2.687943 +1.538985 1.652845 1.952108 2.156038 2.639302 2.685734 +1.537130 1.622797 1.963527 2.075940 2.612204 2.679327 +1.537449 1.633250 1.986524 2.075675 2.542791 2.643796 +1.543228 1.772021 2.053914 2.142473 2.536411 2.690489 +1.621800 1.829997 2.052741 2.210858 2.583215 2.665837 +1.609565 1.935324 2.146682 2.393315 2.597212 2.670556 +1.560818 1.935543 2.191435 2.444376 2.609921 2.692602 +1.704277 1.874585 2.010256 2.380095 2.528658 2.604802 +1.624784 1.837785 1.925361 2.193011 2.497168 2.569432 +1.556125 1.832653 1.986935 2.189317 2.453204 2.531630 +1.347428 1.669666 1.943932 2.108052 2.506631 2.608423 +1.278409 1.497251 1.838413 2.073920 2.454553 2.592324 +1.271049 1.415120 1.758107 2.232460 2.422770 2.554672 +1.260337 1.356714 1.913167 2.225895 2.380602 2.557250 +1.223099 1.307974 1.784088 2.207517 2.362875 2.487786 +1.249454 1.538164 1.716600 1.998319 2.362110 2.465531 +1.208014 1.503064 1.761303 1.917077 2.448048 2.525133 +1.151848 1.461146 1.783945 1.946886 2.452561 2.556307 +1.165555 1.347773 1.799946 1.920752 2.437876 2.546954 +1.109788 1.310449 1.815889 1.923381 2.427304 2.602804 +1.091990 1.233639 1.789609 1.925036 2.467804 2.611170 +1.052323 1.194748 1.809895 1.914231 2.390180 2.556318 +1.032267 1.189488 1.775623 1.889690 2.393248 2.640830 +0.992854 1.169627 1.814159 1.912252 2.320268 2.634324 +1.054415 1.177746 1.762755 1.907196 2.266178 2.516301 +1.029545 1.167365 1.780060 1.973540 2.227843 2.613887 +1.067777 1.184807 1.741322 1.919129 2.121959 2.500789 +1.167843 1.263051 1.778629 1.900717 2.150811 2.568660 +1.247027 1.323672 1.811046 1.934590 2.184022 2.674617 +1.331781 1.426137 1.785144 1.966030 2.114558 2.541825 +1.360900 1.444142 1.862535 1.949748 2.426744 2.646105 +1.408538 1.451788 1.866918 2.014230 2.478842 2.705911 +1.405554 1.483551 1.874980 1.960293 2.502764 2.662540 +1.442367 1.544656 1.883354 1.987590 2.562980 2.647761 +1.480719 1.536202 1.881818 2.018874 2.582349 2.661791 +1.513078 1.583246 1.895764 1.987154 2.586166 2.676009 +1.497760 1.602088 1.831006 1.985404 2.564090 2.643635 +1.497065 1.564915 1.844643 1.957697 2.539930 2.677163 +1.468106 1.523747 1.865842 1.940079 2.607970 2.684862 +1.468104 1.564389 1.858916 1.982405 2.606481 2.709686 +1.422735 1.519196 1.806791 1.891590 2.614823 2.703893 +1.396871 1.476698 1.776404 2.013253 2.607847 2.665988 +1.391532 1.504565 1.830535 2.081544 2.611020 2.720808 +1.372885 1.645062 1.833360 2.015761 2.631341 2.701342 +1.331289 1.747404 1.897953 2.146510 2.586685 2.658273 +1.503178 1.734690 1.914996 2.282089 2.598389 2.679187 +1.465242 1.711762 2.025166 2.284078 2.653659 2.717393 +1.423402 1.768761 2.084406 2.277880 2.636443 2.711524 +1.423821 1.724472 2.032594 2.300309 2.603340 2.686111 +1.433184 1.818868 2.053883 2.409241 2.628605 2.699461 +1.509846 1.793493 2.052637 2.357768 2.644126 2.718058 +1.575730 1.851530 2.032958 2.374899 2.583530 2.662235 +1.501264 1.780829 1.998554 2.329265 2.505605 2.606743 +1.460060 1.763209 1.912334 2.214416 2.494328 2.577616 +1.444041 1.657674 1.895357 2.148549 2.478458 2.595455 +1.454287 1.619858 1.935887 2.189754 2.478831 2.594880 +1.377243 1.642180 1.919668 2.142842 2.421514 2.541038 +1.051059 1.421021 1.830399 2.021216 2.373690 2.548829 +0.964571 1.071641 1.394899 2.151202 2.371776 2.464951 +0.966306 1.181025 1.302213 2.014819 2.375093 2.435135 +0.895560 1.207845 1.335308 1.823923 2.239924 2.363100 +1.006776 1.203093 1.317821 1.873977 2.336638 2.408782 +1.054129 1.225595 1.379006 2.024687 2.333311 2.421550 +1.090202 1.224770 1.409674 2.013195 2.245364 2.353229 +1.076475 1.203972 1.563890 2.033954 2.203362 2.369101 +1.127967 1.249133 1.664693 2.080426 2.256625 2.469541 +1.202013 1.429684 1.793680 2.080715 2.339984 2.460053 +1.517223 1.673904 1.927925 2.203642 2.386760 2.520143 +1.586618 1.786240 2.041674 2.198999 2.416371 2.581194 +1.593300 1.808548 2.148779 2.250278 2.372090 2.532412 +1.657294 1.783458 2.150393 2.258130 2.453915 2.616209 +1.571489 1.792659 2.117652 2.350385 2.577192 2.666949 +1.301994 1.729750 1.974424 2.093250 2.593899 2.663024 +1.100218 1.563399 1.919910 2.059220 2.562974 2.637757 +1.025074 1.540738 1.811898 2.057911 2.491877 2.603248 +1.015309 1.473504 1.802588 2.013084 2.436758 2.605319 +1.022065 1.158479 1.689786 2.183529 2.383778 2.492374 +1.212476 1.453108 1.823947 2.061442 2.396186 2.536578 +1.126243 1.452934 1.809587 2.071074 2.408943 2.549557 +0.880332 1.324785 1.621337 1.967251 2.313156 2.426927 +0.749583 1.358409 1.575073 1.870590 2.279227 2.377431 +0.901917 1.290215 1.674425 1.954410 2.233361 2.391524 +0.850971 1.252102 1.657646 1.816460 2.183885 2.328806 +0.881480 1.284101 1.698159 1.844661 2.341820 2.440909 +0.874499 1.182682 1.709489 1.917452 2.365966 2.499649 +0.833751 1.231132 1.803319 1.918020 2.459092 2.546881 +0.850970 1.127086 1.772073 1.855222 2.487580 2.582865 +0.881650 1.114802 1.820703 1.959079 2.521753 2.598731 +0.803558 1.150285 1.798477 1.952675 2.538917 2.634898 +0.867833 0.990496 1.832275 1.929767 2.547660 2.681084 +0.865057 1.067437 1.773263 1.860188 2.558331 2.702216 +0.832529 0.985960 1.756367 1.862925 2.438281 2.623782 +0.850804 1.060553 1.892217 1.984007 2.483774 2.661123 +0.873803 1.041984 1.746198 1.932438 2.338221 2.554585 +0.958594 1.103471 1.836438 1.936783 2.393758 2.573200 +1.014831 1.140873 1.825933 2.013713 2.401490 2.609423 +1.075369 1.457644 1.900463 2.033493 2.314190 2.490949 +1.201715 1.736170 1.914076 2.066503 2.386907 2.476963 +1.215217 1.873613 2.065903 2.182990 2.374981 2.489555 +1.620207 1.851261 2.111542 2.342798 2.527494 2.633887 +1.683879 1.860372 2.126009 2.404344 2.562983 2.636158 +1.703817 1.934383 2.133673 2.393214 2.601932 2.682469 +1.526877 1.900128 2.151100 2.361638 2.575171 2.658979 +1.587253 1.881390 2.129945 2.267860 2.577863 2.657840 +1.539163 1.871344 2.190283 2.360385 2.624615 2.705636 +1.625747 1.862181 2.120094 2.339463 2.592159 2.682142 +1.679527 1.920689 2.161166 2.317106 2.648896 2.712106 +1.635199 1.922826 2.174839 2.407399 2.630046 2.709271 +1.454186 1.975699 2.151850 2.371342 2.609179 2.685790 +1.672439 2.011404 2.183017 2.463917 2.652956 2.711525 +1.612105 1.987481 2.102582 2.293346 2.616125 2.670264 +1.528075 1.895073 2.053582 2.232503 2.544912 2.624122 +1.420355 1.683500 1.963431 2.159418 2.536725 2.620131 +1.456320 1.693132 1.969234 2.164744 2.587162 2.677588 +1.481106 1.637541 1.992642 2.178479 2.548138 2.632755 +1.488517 1.591174 2.016501 2.123324 2.528663 2.614918 +1.477429 1.651519 1.962894 2.102183 2.543300 2.618840 +1.473856 1.622302 1.992230 2.080352 2.572688 2.644430 +1.478216 1.633404 1.931202 2.064133 2.552282 2.629338 +1.452477 1.676763 1.945911 2.084750 2.600973 2.668889 +1.411560 1.706182 1.890249 2.169616 2.567319 2.650155 +1.383398 1.664625 1.803260 2.108612 2.595771 2.646221 +1.434597 1.645007 1.871751 2.115488 2.528958 2.660256 +1.444542 1.581834 1.898636 2.094074 2.528453 2.631504 +1.465558 1.562000 1.841423 2.051601 2.559944 2.632318 +1.499287 1.581053 1.857454 2.098994 2.511597 2.604341 +1.528680 1.651347 1.871308 2.071232 2.562548 2.622460 +1.514467 1.633477 1.778604 2.123502 2.606102 2.662390 +1.301476 1.683914 1.796063 2.170750 2.644952 2.691777 +1.154424 1.626935 1.749221 1.996410 2.579238 2.652899 +1.117912 1.569269 1.795380 1.885300 2.376717 2.739725 +1.251786 1.625672 1.839263 1.991314 2.350120 2.655047 +1.412131 1.694235 1.839362 1.998399 2.445222 2.739684 +1.370157 1.687258 1.879731 2.006454 2.329014 2.632962 +1.174780 1.729049 1.887372 2.013905 2.259388 2.557737 +1.317917 1.737041 1.878083 1.979313 2.175363 2.634863 +1.140130 1.586450 1.932219 2.027711 2.236840 2.484950 +1.100136 1.600099 1.851286 1.972375 2.604826 2.649449 +1.111969 1.525982 1.842706 2.011491 2.601600 2.669393 +1.080825 1.492576 1.810233 1.965312 2.556725 2.645171 +1.129345 1.635898 1.785176 2.137400 2.498003 2.572522 +1.003594 1.603010 1.722697 2.139397 2.431587 2.510996 +1.120169 1.425151 1.675683 2.050774 2.343247 2.460676 +1.328607 1.599151 1.873581 2.170450 2.470538 2.613529 +1.382087 1.595341 1.923462 2.082111 2.349552 2.510754 +1.466192 1.572864 1.870467 2.179996 2.346338 2.471868 +1.379765 1.633014 1.808273 2.166294 2.398723 2.492469 +1.305921 1.610021 1.856406 2.001543 2.390671 2.533908 +1.383086 1.586806 1.757224 1.934804 2.433540 2.587951 +1.307509 1.450943 1.675332 2.033940 2.244229 2.418123 +1.191501 1.484072 1.750272 2.096644 2.249380 2.504983 +1.241378 1.491790 1.776884 2.071735 2.367933 2.508071 +1.265701 1.459923 1.781754 2.009900 2.348578 2.516037 +1.279508 1.414652 1.795096 2.055938 2.395700 2.530542 +1.337338 1.445932 1.853009 2.075183 2.385984 2.535489 +1.288973 1.424709 1.797989 2.026295 2.299802 2.423713 +1.365284 1.471788 1.801705 1.937695 2.345304 2.466696 +1.353791 1.447746 1.736211 1.868886 2.274358 2.475584 +1.360863 1.449607 1.680466 1.802646 2.395536 2.513256 +1.388330 1.526246 1.673331 1.909867 2.385020 2.535430 +1.424428 1.544219 1.720205 1.936245 2.307968 2.491418 +1.448943 1.552009 1.797935 1.937520 2.406873 2.546121 +1.432034 1.521621 1.799322 2.021435 2.477329 2.571754 +1.463087 1.546282 1.834418 2.063488 2.489800 2.595267 +1.425467 1.556435 1.904716 2.110821 2.466374 2.587563 +1.384837 1.569415 1.925581 2.072374 2.561291 2.640537 +1.418492 1.539421 1.937535 2.014318 2.609201 2.676764 +1.397006 1.483285 1.936731 1.977746 2.595606 2.735850 +1.335615 1.441868 1.884738 1.994960 2.589628 2.695748 +1.357490 1.518997 1.871603 1.980199 2.629016 2.700305 +1.353558 1.524318 1.891083 1.963707 2.595814 2.679332 +1.295102 1.639282 1.907387 2.103139 2.583356 2.679778 +1.455545 1.667590 1.953202 2.240488 2.570672 2.673617 +1.460281 1.786653 1.997747 2.285131 2.582928 2.677618 +1.543121 1.729391 2.155674 2.280274 2.655577 2.744248 +1.434440 1.748782 2.042199 2.201295 2.606501 2.695862 +1.436079 1.747337 2.067838 2.253257 2.575944 2.679075 +1.470866 1.698245 2.083133 2.257574 2.565342 2.666191 +1.417419 1.693439 2.053193 2.243538 2.544836 2.632800 +1.412107 1.681588 2.081799 2.326098 2.472446 2.570581 +1.397226 1.764739 2.031556 2.297123 2.471645 2.575881 +1.466497 1.694305 2.005924 2.206325 2.534515 2.635757 +1.437113 1.746568 1.923838 2.127846 2.356631 2.464479 +1.324023 1.597918 1.757776 2.124352 2.347986 2.440470 +1.375387 1.626387 1.778068 2.068399 2.258938 2.397532 +1.379576 1.621789 1.857961 1.994277 2.306086 2.477213 +1.416412 1.648893 1.869117 2.098359 2.345397 2.475125 +1.426241 1.639197 1.925396 2.072677 2.448945 2.532546 +1.459052 1.615870 1.911170 2.125459 2.483704 2.592087 +1.459433 1.690704 1.852418 2.136068 2.529395 2.597199 +1.485144 1.578047 1.810569 2.150621 2.559043 2.618237 +1.529055 1.594664 1.738903 2.261216 2.595771 2.651620 +1.532488 1.585333 1.820935 2.229621 2.623157 2.658477 +1.374401 1.528078 1.848019 2.042459 2.458230 2.591088 +1.399870 1.597467 1.853082 2.096076 2.431604 2.556847 +1.457434 1.609510 1.930756 2.186100 2.392287 2.525064 +1.440508 1.607587 1.869980 2.158283 2.424280 2.555526 +1.376758 1.474791 1.750562 2.190623 2.406180 2.547123 +1.327713 1.454236 1.644635 2.110356 2.352447 2.455926 +1.302805 1.418954 1.609785 2.093121 2.263489 2.393252 +1.207712 1.379869 1.536412 2.059932 2.317302 2.455399 +1.154213 1.302966 1.499207 2.070378 2.322203 2.630828 +1.111474 1.224424 1.625635 2.176079 2.342546 2.606190 +0.945723 1.083298 1.625408 2.214532 2.389898 2.510077 +0.992344 1.116986 1.451917 2.008420 2.313589 2.437855 +1.117309 1.392988 1.713458 2.132315 2.276818 2.497613 +1.332868 1.580932 1.895512 2.129003 2.425104 2.576946 +1.322037 1.497740 1.819219 2.128645 2.443614 2.567952 +1.361937 1.547377 1.790968 2.062941 2.465318 2.546093 +1.252677 1.483878 1.758631 2.033450 2.416283 2.539220 +1.099384 1.344747 1.686531 2.016752 2.355863 2.530839 +1.126109 1.263617 1.649938 1.991544 2.309088 2.514895 +1.190621 1.289655 1.692709 2.009481 2.160091 2.417069 +1.174976 1.414314 1.797856 1.987597 2.278818 2.492762 +1.205354 1.482053 1.850760 2.025549 2.342281 2.523425 +1.248034 1.561185 1.852759 2.096445 2.428364 2.551865 +1.260728 1.601832 1.901052 2.131984 2.409850 2.565546 +1.265037 1.693841 2.000531 2.200039 2.503508 2.617708 +1.278843 1.738264 2.062020 2.289983 2.604440 2.678111 +1.339428 1.735918 2.050123 2.352408 2.597394 2.688219 +1.301064 1.708745 1.965976 2.286214 2.546707 2.653175 +1.278604 1.746157 1.950065 2.214767 2.605793 2.687616 +1.183771 1.523062 1.879119 2.004908 2.600314 2.690485 +1.186222 1.342133 1.817831 1.940077 2.504905 2.659254 +1.179389 1.243680 1.894260 1.979753 2.558019 2.721819 +1.175622 1.357037 1.853192 1.940810 2.646805 2.705660 +1.211124 1.369645 1.825254 1.913289 2.634717 2.712259 +1.169472 1.345149 1.764944 1.883669 2.591077 2.714522 +1.222090 1.389480 1.800177 1.935903 2.573766 2.702922 +1.287266 1.375911 1.878738 1.986045 2.625999 2.708468 +1.299711 1.389598 1.873905 1.942723 2.533485 2.691472 +1.271356 1.424203 1.849847 1.953565 2.555561 2.652372 +1.253571 1.448512 1.829531 1.919100 2.487837 2.630761 +1.223923 1.323017 1.841258 1.932730 2.226845 2.570717 +1.226170 1.321389 1.771794 1.948065 2.137880 2.563052 +1.316238 1.399466 1.789328 1.965570 2.132039 2.424710 +1.264391 1.363953 1.735531 2.005600 2.155844 2.418921 +1.214027 1.319779 1.662017 1.902948 2.064631 2.424833 +1.242602 1.342314 1.624757 1.929420 2.083549 2.318443 +1.241605 1.439119 1.646334 1.817919 1.997763 2.196632 +1.239348 1.336917 1.777062 2.028009 2.155853 2.328702 +1.178416 1.266326 1.802039 1.959820 2.145703 2.469513 +1.247702 1.328626 1.812686 1.992792 2.200638 2.499445 +1.270078 1.370907 1.882273 1.997225 2.254284 2.526050 +1.295553 1.376421 1.860437 2.076734 2.248998 2.567118 +1.304838 1.386085 1.832762 2.061619 2.219399 2.486348 +1.314313 1.381482 1.912831 2.017535 2.287746 2.576424 +1.275078 1.353772 1.858468 2.037031 2.362055 2.615420 +1.287115 1.366797 1.835524 1.961094 2.291985 2.562975 +1.256666 1.341161 1.798806 1.921264 2.333647 2.596913 +1.229284 1.337507 1.753982 1.942388 2.403549 2.602171 +1.224871 1.322981 1.792609 1.918908 2.363314 2.520583 +1.218452 1.321589 1.651493 1.884157 2.366537 2.521284 +1.193218 1.359120 1.632401 1.857625 2.322851 2.452708 +1.205474 1.368035 1.608030 1.815042 2.341851 2.574505 +1.061251 1.318432 1.545024 1.888740 2.401884 2.617020 +1.072522 1.365786 1.514127 1.893675 2.369617 2.474232 +1.111644 1.436790 1.606098 1.842456 2.382418 2.474111 +1.012061 1.316202 1.471593 1.799057 2.349432 2.455130 +1.089471 1.248571 1.572785 1.953061 2.298439 2.461784 +1.068360 1.195813 1.624024 2.111295 2.311476 2.419253 +1.147513 1.525224 1.724810 1.957167 2.387532 2.471314 +1.334336 1.568150 1.749039 1.962569 2.390633 2.484647 +1.298140 1.467881 1.814397 1.941570 2.384226 2.522176 +1.295007 1.418486 1.859466 1.962329 2.376315 2.521757 +1.335831 1.436636 1.858260 1.966332 2.446579 2.563483 +1.346492 1.477982 1.905644 1.998091 2.490052 2.584468 +1.407183 1.540763 1.879296 1.992980 2.487939 2.564009 +1.447665 1.628575 1.828196 2.053651 2.534046 2.605859 +1.524705 1.620051 1.837880 2.017915 2.592167 2.653373 +1.564584 1.647141 1.761178 2.024150 2.615248 2.656575 +1.529370 1.593981 1.683157 1.979831 2.601640 2.654391 +1.585075 1.652835 1.786770 2.031845 2.518000 2.620980 +1.588906 1.644232 1.813812 2.041481 2.610723 2.666049 +1.601362 1.686074 1.862952 2.127114 2.608859 2.655021 +1.640245 1.750920 1.921102 2.164412 2.547516 2.617193 +1.548602 1.638196 1.917398 2.092646 2.563829 2.615836 +1.515875 1.616955 1.844164 2.007026 2.528173 2.601071 +1.465872 1.572195 1.740969 2.011290 2.493415 2.581928 +1.411908 1.534275 1.669392 2.025507 2.419065 2.534991 +1.339405 1.524896 1.674545 2.018990 2.344004 2.443795 +1.300672 1.527060 1.673067 2.036189 2.269516 2.383792 +1.193083 1.476495 1.664464 1.933230 2.291004 2.414954 +1.192791 1.485591 1.649261 1.844048 2.295088 2.502001 +1.197824 1.364864 1.703691 1.827209 2.262766 2.499801 +1.138273 1.379249 1.658127 1.912486 2.389082 2.583381 +1.166597 1.357942 1.688915 1.942734 2.491527 2.589252 +1.170615 1.391547 1.721925 1.889510 2.506116 2.616390 +1.210959 1.452702 1.755617 1.844973 2.490062 2.624729 +1.212139 1.519716 1.785919 1.889270 2.551264 2.629492 +1.276001 1.664615 1.957757 2.249343 2.602286 2.677701 +1.400862 1.816183 1.994456 2.325956 2.651785 2.717305 +1.466054 1.834563 2.118572 2.372427 2.625377 2.704685 +1.578859 1.790938 2.136097 2.392831 2.638547 2.714022 +1.480700 1.816555 2.206450 2.432389 2.575887 2.645111 +1.617288 1.807665 2.241721 2.440067 2.567226 2.631745 +1.570100 1.785068 2.178210 2.348135 2.467045 2.556638 +1.579682 1.701535 2.005186 2.288766 2.434155 2.548589 +1.578691 1.674213 1.965474 2.199446 2.334867 2.479803 +1.640546 1.726915 1.991606 2.240338 2.400971 2.523628 +1.588532 1.709671 1.874418 2.160822 2.381523 2.517230 +1.447497 1.665484 1.900942 2.103382 2.397872 2.535571 +1.203022 1.599213 1.884283 2.032257 2.369015 2.504738 +1.146521 1.513193 1.880497 1.985787 2.407380 2.522482 +1.131266 1.435001 1.834092 2.111348 2.306550 2.531154 +1.176712 1.640343 1.870115 2.064938 2.313000 2.439124 +1.254490 1.590614 1.958487 2.200173 2.344272 2.479816 +1.243959 1.684492 2.016502 2.192945 2.451075 2.547334 +1.537310 1.763854 2.188639 2.371726 2.539927 2.648079 +1.646538 1.887574 2.280949 2.443446 2.593067 2.680775 +1.567456 1.876170 2.108713 2.427826 2.611726 2.691363 +1.341056 1.874127 2.114216 2.396197 2.621228 2.702770 +1.449196 1.837843 2.058401 2.307470 2.616907 2.689695 +1.313491 1.794349 1.961057 2.237499 2.597739 2.685191 +1.202175 1.706913 1.905104 2.139148 2.612890 2.693658 +1.080344 1.590487 1.846519 2.059279 2.631365 2.697376 +1.043219 1.601906 1.900346 2.141041 2.588352 2.662523 +0.984957 1.556146 1.841481 2.148769 2.577337 2.662952 +0.979403 1.553838 1.844172 2.052598 2.577754 2.641114 +0.947313 1.453890 1.836463 1.998780 2.566547 2.637546 +0.959460 1.441678 1.832870 2.106499 2.553643 2.630882 +0.951016 1.397882 1.793743 2.053066 2.492635 2.622573 +0.870727 1.369217 1.817794 2.107476 2.524230 2.627945 +0.902872 1.385159 1.754800 2.013432 2.536990 2.654823 +0.891101 1.362395 1.753579 1.878041 2.559805 2.662468 +0.835616 1.259326 1.757169 1.832338 2.486345 2.635682 +0.787419 1.132035 1.693975 1.776933 2.533180 2.616312 +0.791106 1.068132 1.697743 1.851598 2.571958 2.669553 +0.759951 1.112356 1.562357 1.855199 2.490682 2.601972 +0.792061 1.139999 1.724823 1.954458 2.608864 2.689684 +0.823952 1.270934 1.741090 2.077662 2.613199 2.669386 +0.736534 1.124969 1.743684 2.093250 2.579787 2.661721 +0.797043 1.051944 1.780229 2.240357 2.583476 2.662315 +0.923582 1.503155 1.776882 2.018470 2.613910 2.703042 +1.421538 1.735030 2.006889 2.210344 2.574319 2.670736 +1.350174 1.606122 1.963013 2.084969 2.478192 2.589945 +1.361799 1.656583 1.974082 2.173881 2.479634 2.612008 +1.319939 1.764454 2.027445 2.249293 2.529644 2.635744 +1.394028 1.664199 2.006309 2.246188 2.558094 2.671320 +1.385394 1.755426 2.080024 2.329874 2.630895 2.722673 +1.333690 1.669430 2.021492 2.250607 2.600265 2.689100 +1.341532 1.698164 1.975002 2.237112 2.560850 2.684376 +1.388610 1.785046 1.956888 2.281386 2.563576 2.643708 +1.345894 1.706236 1.842983 2.264164 2.606222 2.694785 +1.320329 1.694191 1.923363 2.218151 2.645478 2.750259 +1.332386 1.748388 2.014721 2.221780 2.602628 2.697461 +1.397603 1.715354 1.949721 2.236000 2.577802 2.661479 +1.618810 1.795968 2.016419 2.205191 2.506636 2.636829 +1.659811 1.735333 2.021086 2.175840 2.443378 2.641454 +1.539528 1.652064 1.946773 2.095081 2.446637 2.636547 +1.532272 1.592873 1.977822 2.053408 2.551491 2.674907 +1.509350 1.581109 2.004243 2.059379 2.524603 2.702937 +1.432533 1.504626 1.930707 2.042330 2.440661 2.690850 +1.194640 1.677037 2.023104 2.078391 2.446911 2.745852 +1.210373 1.824825 2.021515 2.139089 2.539931 2.659640 +1.276624 1.715436 1.952490 2.083815 2.473462 2.664346 +1.235656 1.548445 2.067341 2.118624 2.427438 2.727540 +1.283474 1.374296 1.963417 2.098418 2.474393 2.702856 +1.305021 1.394700 2.068003 2.139040 2.520168 2.706208 +1.284823 1.494312 2.055208 2.140334 2.602120 2.698828 +1.296593 1.587724 2.087205 2.156563 2.618559 2.718633 +1.252465 1.583350 2.108883 2.173872 2.600502 2.685035 +1.177439 1.612038 2.093884 2.155173 2.581066 2.695123 +1.132957 1.572991 2.135458 2.220598 2.615734 2.710569 +1.060318 1.542980 2.165747 2.230410 2.609442 2.697786 +0.993306 1.542205 2.170751 2.247209 2.631170 2.706892 +0.783750 1.568542 2.323323 2.398878 2.594196 2.690603 +0.866024 1.454427 2.113290 2.187039 2.662007 2.719943 +0.793002 1.437700 2.125666 2.225555 2.588880 2.664786 +0.863183 1.439828 2.031948 2.203948 2.586483 2.646886 +0.817301 1.443077 2.078742 2.356665 2.572146 2.635324 +0.840200 1.268198 1.973956 2.380693 2.546743 2.624124 +0.905910 1.472855 2.000805 2.420178 2.606009 2.662539 +0.885218 1.599132 2.063964 2.335379 2.688751 2.736255 +0.812099 1.480973 2.103159 2.193629 2.621360 2.702113 +0.727009 1.481278 2.088167 2.170556 2.575583 2.660557 +0.783755 1.482083 2.210773 2.281994 2.564635 2.658081 +0.810890 1.318001 2.156661 2.250146 2.565371 2.666169 +0.775372 1.352710 2.277457 2.371730 2.587244 2.655489 +0.765239 1.280609 2.227449 2.304899 2.577531 2.696870 +0.860727 1.309962 2.239215 2.358255 2.523746 2.681832 +0.828001 1.157509 2.157199 2.279201 2.554510 2.655379 +0.776568 1.131001 2.110470 2.282369 2.502240 2.634533 +0.662804 1.210648 2.214487 2.275268 2.480153 2.598167 +0.752595 1.172127 2.270252 2.354795 2.534373 2.613431 +0.769014 1.037539 2.239849 2.320190 2.523883 2.637275 +0.747299 1.036519 2.059875 2.380316 2.507719 2.677768 +0.818428 1.110448 2.132574 2.306792 2.442669 2.597844 +0.838124 1.256032 2.152521 2.304078 2.501081 2.591854 +0.842740 1.147341 2.045086 2.317073 2.459293 2.588472 +0.950977 1.150930 2.097644 2.290004 2.497415 2.643449 +0.932262 1.159756 1.945175 2.233748 2.538888 2.635754 +0.872640 1.294667 1.881084 2.112185 2.488729 2.612697 +0.953242 1.398337 1.906758 2.024454 2.396667 2.616332 +1.019160 1.447236 1.917323 2.023333 2.213019 2.528896 +0.980910 1.420444 1.857618 1.943436 2.294481 2.596120 +1.007917 1.474723 1.827586 1.921475 2.567362 2.643752 +1.057674 1.583820 1.862216 1.988312 2.507590 2.602780 +1.089480 1.610937 1.894205 2.067983 2.401427 2.589250 +1.155642 1.601524 1.853784 2.109924 2.266420 2.654880 +1.190394 1.403206 1.850320 2.129434 2.355479 2.599651 +1.165667 1.266234 1.847925 2.191760 2.352164 2.576809 +1.112543 1.237226 1.755553 2.196412 2.378413 2.515897 +1.093202 1.229320 1.630970 2.198491 2.394327 2.490062 +1.030916 1.160090 1.536996 2.150269 2.345755 2.526171 +1.090134 1.227459 1.470303 2.121663 2.325691 2.414263 +1.084185 1.353427 1.495774 2.165409 2.396637 2.501534 +1.128688 1.380138 1.551457 2.110309 2.296856 2.418999 +1.087172 1.454259 1.658795 2.020385 2.196298 2.381465 +1.039395 1.582193 1.728098 2.070179 2.301852 2.489432 +1.019025 1.646872 1.828918 2.125767 2.542468 2.624929 +1.017909 1.675444 2.009386 2.200627 2.432273 2.532754 +0.975365 1.568456 2.099629 2.243759 2.469669 2.558656 +1.045139 1.750545 2.091194 2.277034 2.473998 2.559636 +1.003490 1.670000 2.149872 2.216814 2.544142 2.591015 +0.972271 1.669349 2.066914 2.253461 2.528115 2.626794 +1.001400 1.910537 2.208899 2.322095 2.475052 2.594146 +1.106236 1.762398 2.170214 2.368326 2.532382 2.636954 +0.937567 1.570796 2.208314 2.312080 2.547601 2.604149 +0.984015 1.531648 2.154446 2.260403 2.519554 2.621365 +1.058045 1.589683 2.130473 2.238788 2.559220 2.636001 +1.126293 1.674296 2.142380 2.304378 2.581987 2.659797 +1.092169 1.547245 2.138847 2.246962 2.570924 2.653740 +1.164152 1.513575 2.120596 2.203037 2.555931 2.629117 +1.154436 1.451664 2.109876 2.193787 2.569383 2.668688 +1.171007 1.297549 2.105789 2.224294 2.529719 2.663245 +1.139370 1.343339 2.024942 2.161273 2.570054 2.662064 +1.214975 1.759488 2.013624 2.126711 2.350657 2.508933 +1.410441 1.787361 1.940449 2.082004 2.255781 2.406359 +1.192527 1.698280 1.956892 2.084836 2.235743 2.490643 +1.173627 1.448751 2.011122 2.145246 2.280142 2.534706 +1.172797 1.327177 1.938868 2.095910 2.247560 2.526844 +1.129709 1.376142 1.891533 1.985327 2.196351 2.582653 +1.195218 1.292910 1.887213 2.025135 2.200698 2.525594 +1.246281 1.338967 1.851654 2.072793 2.209074 2.457441 +1.244715 1.395538 1.916844 2.097048 2.296495 2.526646 +1.346432 1.453272 2.128410 2.313839 2.566271 2.666215 +1.392181 1.506569 2.060420 2.183828 2.523643 2.656421 +1.397671 1.478362 2.037869 2.140024 2.522879 2.634883 +1.405078 1.437969 2.064698 2.121678 2.484341 2.664086 +1.527970 1.731644 2.001400 2.182281 2.477459 2.609679 +1.602215 1.694049 2.065008 2.176143 2.567575 2.650751 +1.549243 1.668152 2.061940 2.136053 2.575954 2.678540 +1.590489 1.693208 1.921586 2.193585 2.522338 2.657822 +1.593120 1.715596 2.057856 2.172814 2.502009 2.607762 +1.508461 1.713948 2.053457 2.146855 2.383043 2.628673 +1.500942 1.577870 1.978516 2.080955 2.517866 2.640817 +1.503819 1.559203 1.933282 2.030596 2.516193 2.657495 +1.430951 1.506436 1.856364 2.014512 2.406913 2.583800 +1.394417 1.471155 1.914772 2.015327 2.414514 2.568928 +1.376718 1.476739 1.841743 1.961573 2.459621 2.552505 +1.304829 1.509257 1.807862 1.899025 2.532604 2.616563 +1.486241 1.646868 1.928992 2.176641 2.503384 2.645535 +1.477068 1.576408 1.937301 2.094449 2.468734 2.643633 +1.431493 1.551268 1.935807 2.027994 2.468760 2.605588 +1.427171 1.670820 1.944981 2.109944 2.482745 2.652433 +1.393190 1.649564 1.991075 2.070334 2.586450 2.667337 +1.406966 1.518528 1.967049 2.067755 2.501722 2.624107 +1.399129 1.487381 1.880327 1.972568 2.359193 2.604810 +1.419452 1.541906 1.920889 2.015257 2.416437 2.547537 +1.447736 1.626647 1.911603 2.037838 2.508304 2.609091 +1.507943 1.649223 1.954490 2.063843 2.515779 2.591471 +1.512511 1.697882 1.919266 2.077175 2.545774 2.631085 +1.577487 1.652922 1.969378 2.057105 2.533497 2.610477 +1.604710 1.687839 1.943635 2.030700 2.552461 2.659467 +1.634825 1.710086 1.943508 2.035741 2.553037 2.650522 +1.629110 1.721048 1.907265 2.020140 2.570097 2.652611 +1.653862 1.731013 1.917069 2.016503 2.551305 2.678978 +1.675623 1.740253 1.923108 1.995468 2.543890 2.693466 +1.704324 1.761003 1.892088 1.958603 2.520344 2.709583 +1.631746 1.698022 1.879765 1.974816 2.475043 2.688708 +1.563394 1.662351 1.863499 1.961656 2.492069 2.692141 +1.535271 1.621802 1.864516 2.016880 2.457202 2.701452 +1.463627 1.689995 1.942593 2.019493 2.516076 2.684085 +1.427161 1.545730 1.922601 1.983390 2.549083 2.724037 +1.387863 1.469421 1.874287 2.047091 2.486568 2.643007 +1.364743 1.462745 1.908513 2.076519 2.468769 2.627416 +1.421611 1.616670 2.074387 2.243630 2.604811 2.697119 +1.443567 1.802480 2.145890 2.311026 2.615127 2.704969 +1.402806 1.864810 2.209376 2.377972 2.654288 2.731440 +1.472673 1.860803 2.162882 2.447267 2.648421 2.719024 +1.518497 1.794725 2.075011 2.339205 2.552102 2.655931 +1.503597 1.758472 2.111549 2.304480 2.551002 2.643546 +1.466759 1.587712 2.046144 2.276602 2.546510 2.649906 +1.414608 1.499164 2.000686 2.080851 2.549084 2.654414 +1.324617 1.597419 1.961703 2.075259 2.518788 2.638260 +1.262448 1.666067 1.961546 2.098269 2.549101 2.630367 +1.220869 1.632115 1.947651 2.054954 2.515971 2.607563 +1.136650 1.569138 1.923253 2.011403 2.513979 2.612924 +1.058570 1.570577 1.921267 2.037973 2.484487 2.569497 +1.039823 1.492368 1.862383 2.113321 2.462634 2.586287 +1.291651 1.546687 1.888427 2.160338 2.444567 2.573682 +1.154151 1.629832 1.978719 2.114524 2.505413 2.616168 +1.018988 1.844229 2.003497 2.145640 2.430051 2.549664 +1.003639 1.900247 2.103968 2.200810 2.555267 2.678873 +1.007182 1.652528 2.033376 2.117896 2.534356 2.593837 +1.014065 1.625311 2.073565 2.163998 2.546138 2.611829 +1.009846 1.729007 2.001610 2.190071 2.554550 2.635426 +1.019489 1.599817 2.062920 2.180981 2.585351 2.651906 +1.042282 1.559849 2.061719 2.184907 2.608829 2.711272 +1.093985 1.606698 2.067049 2.179456 2.578115 2.647082 +1.117524 1.554503 2.010457 2.171257 2.524192 2.604614 +1.189148 1.687116 2.026818 2.220744 2.584656 2.673603 +1.184285 1.592927 2.011407 2.140558 2.575633 2.652764 +1.243271 1.544342 1.991354 2.103724 2.547726 2.633837 +1.249802 1.530059 1.930460 2.044509 2.489498 2.611045 +1.317227 1.550858 1.927474 2.019107 2.563575 2.632413 +1.300146 1.571198 1.817213 1.967321 2.572012 2.659755 +1.304786 1.459074 1.804350 1.873800 2.572345 2.677847 +1.272113 1.387927 1.710588 1.798443 2.519124 2.630967 +1.168824 1.271438 1.680467 1.847635 2.472587 2.636108 +1.127715 1.380423 1.702693 1.948341 2.254799 2.516590 +1.037344 1.362071 1.698870 1.943363 2.319984 2.576108 +0.912701 1.215239 1.774758 2.057933 2.407301 2.609739 +0.884045 1.283341 1.740086 2.012038 2.332329 2.530152 +0.859928 1.361393 1.787767 2.032428 2.439162 2.572497 +0.933575 1.497313 1.860114 2.007764 2.460777 2.636583 +0.980843 1.376674 1.808267 1.899302 2.551384 2.660680 +0.888314 1.390836 1.819063 1.938604 2.611726 2.713704 +0.839112 1.455052 1.864246 1.932569 2.561260 2.649480 +0.851738 1.633441 1.854938 2.065105 2.591532 2.637966 +0.927993 1.739190 1.882023 2.133201 2.585017 2.640778 +0.938681 1.795656 1.962111 2.138930 2.565233 2.627897 +0.939389 1.842127 2.021817 2.196345 2.611519 2.658322 +0.876668 1.922758 2.066598 2.238607 2.657831 2.709139 +0.928890 1.831807 2.053719 2.203623 2.653635 2.695408 +0.843177 1.785949 2.180039 2.258075 2.596807 2.669868 +0.904710 1.738574 2.045482 2.171335 2.659082 2.701770 +0.870576 1.672854 2.046684 2.160295 2.663395 2.706284 +0.863208 1.611276 2.039577 2.131986 2.662744 2.710206 +0.911587 1.521477 1.972249 2.117701 2.671514 2.736290 +0.857624 1.506231 1.927459 2.092066 2.599004 2.671353 +0.876724 1.386211 1.930102 2.020125 2.640246 2.715714 +0.822485 1.363083 1.951099 2.012089 2.546285 2.704224 +0.896312 1.299233 1.946153 2.039999 2.427568 2.660429 +0.993275 1.379765 2.001120 2.083441 2.476481 2.621083 +1.111974 1.369262 1.980570 2.050077 2.518420 2.654724 +1.168214 1.421156 1.929649 2.013732 2.513895 2.659462 +1.185532 1.477308 1.941700 2.021792 2.545835 2.636829 +1.134677 1.498395 1.996860 2.077054 2.487095 2.605961 +1.411729 1.500808 1.930565 2.251695 2.391409 2.514752 +1.387101 1.551631 1.939267 2.134432 2.390647 2.538102 +1.436468 1.601632 1.856306 2.001721 2.498428 2.579682 +1.490762 1.673865 1.865367 2.015258 2.490944 2.589599 +1.532290 1.665821 1.854110 1.987787 2.544314 2.634547 +1.563136 1.683249 1.819205 1.981344 2.592402 2.655991 +1.532691 1.642869 1.795089 1.955952 2.595574 2.688667 +1.506939 1.596868 1.724719 1.902522 2.497152 2.646767 +1.385229 1.553302 1.733776 1.993489 2.385677 2.620193 +1.191373 1.508094 1.914117 2.177183 2.460347 2.600638 +0.990202 1.268417 1.760300 1.988487 2.516663 2.661016 +1.004888 1.273030 1.919583 1.976961 2.621532 2.711155 +1.013289 1.479166 1.983769 2.021110 2.561293 2.681392 +1.094384 1.424205 1.985002 2.164791 2.592137 2.670975 +1.057765 1.377512 1.866113 2.165416 2.490671 2.623341 +1.001768 1.321304 1.902289 2.133880 2.499889 2.659347 +0.896048 1.414778 1.927546 2.127605 2.570653 2.658502 +0.862503 1.586972 1.946548 2.153624 2.615123 2.677873 +0.837783 1.700010 1.932982 2.209447 2.588567 2.687532 +0.901209 1.639772 1.999974 2.070577 2.515297 2.763152 +0.955829 1.601245 2.008965 2.112233 2.503888 2.592844 +0.939285 1.704094 2.027412 2.125922 2.430007 2.538916 +0.948268 1.700873 2.002768 2.088348 2.563468 2.622110 +0.959154 1.624274 2.005824 2.077760 2.577716 2.658733 +0.932538 1.593435 1.952831 2.044660 2.567978 2.644497 +0.933107 1.590563 1.945695 2.111900 2.534278 2.608873 +0.943808 1.649088 1.897019 2.104647 2.578170 2.689758 +1.003034 1.619161 1.930228 2.216721 2.582337 2.637890 +0.936810 1.692346 1.965525 2.118648 2.628517 2.684797 +0.973578 1.737821 1.975673 2.106344 2.658295 2.722445 +0.955324 1.750194 1.961437 2.075373 2.655612 2.731757 +0.994013 1.727390 1.946779 2.062413 2.643379 2.738490 +1.005363 1.693919 1.929868 2.100177 2.618754 2.684861 +0.967862 1.640078 1.930261 2.021548 2.639890 2.726662 +0.928258 1.579359 1.864413 1.973012 2.638908 2.717888 +1.058334 1.410591 1.870850 2.066023 2.451575 2.633697 +1.123046 1.486876 1.862969 2.086078 2.412975 2.591738 +1.177472 1.431539 1.849290 2.099756 2.423335 2.566135 +1.187028 1.443506 1.882075 1.983318 2.550673 2.639389 +1.267969 1.628389 1.932608 2.043278 2.552232 2.641727 +1.355546 1.701559 1.924241 2.034556 2.590180 2.660965 +1.472056 1.739983 1.914264 2.052330 2.573889 2.644926 +1.461490 1.790656 1.911310 2.057871 2.525599 2.587235 +1.542347 1.742399 1.901654 2.063063 2.499169 2.580661 +1.550813 1.642896 1.877392 1.995154 2.474361 2.561166 +1.625354 1.724756 1.899115 2.052586 2.447095 2.556852 +1.636703 1.742201 1.904488 2.155317 2.470314 2.569291 +1.608688 1.701026 1.957110 2.085583 2.465316 2.552203 +1.517569 1.685169 1.923050 2.028968 2.382899 2.503932 +1.215848 1.648126 1.842885 2.049966 2.393827 2.484346 +1.158500 1.452995 1.752665 1.859020 2.467269 2.575520 +1.128274 1.384146 1.801504 1.899178 2.472451 2.609988 +1.080623 1.414338 1.812493 1.916642 2.422686 2.620118 +1.104866 1.492913 1.854038 1.971940 2.444002 2.583583 +1.235805 1.437823 1.919484 2.042792 2.483999 2.617147 +1.167412 1.407601 1.774394 2.073573 2.390599 2.543323 +1.096565 1.317231 1.782210 2.013544 2.394372 2.571806 +1.104307 1.206800 1.718582 2.001006 2.351339 2.505639 +1.047321 1.316889 1.824322 2.050773 2.417158 2.531028 +1.087184 1.408401 1.843144 2.031666 2.440481 2.544264 +1.108521 1.394200 1.760026 2.005728 2.435035 2.552154 +1.121767 1.340590 1.749504 1.963633 2.493819 2.609645 +1.122415 1.452714 1.793131 2.030414 2.502133 2.593239 +1.026877 1.468099 1.745342 1.860466 2.483684 2.579747 +0.971670 1.244091 1.752977 1.837331 2.384716 2.625316 +0.917302 1.104410 1.674928 1.792426 2.336189 2.629469 +0.961560 1.088356 1.555776 1.663706 2.282322 2.579748 +0.919563 1.063279 1.573205 1.711100 2.422693 2.675976 +0.875889 1.022614 1.380839 1.829163 2.584656 2.667378 +0.763749 1.018806 1.506319 1.707976 2.471526 2.595865 +0.886944 1.031388 1.425057 1.710023 2.427922 2.576385 +0.890351 1.037652 1.443986 1.587883 2.520205 2.695833 +0.906256 1.035046 1.405613 1.523743 2.536532 2.596081 +0.929418 1.061071 1.157090 1.566597 2.528260 2.694068 +0.917396 1.106117 1.253042 1.389506 2.551566 2.709098 +0.910230 1.042070 1.162527 1.362129 2.393076 2.605349 +0.804288 1.059586 1.418081 1.530362 2.410566 2.663442 +0.907675 1.046288 1.392541 1.508232 2.495351 2.692340 +0.835212 1.126874 1.350498 1.463210 2.567735 2.694674 +0.770295 1.150701 1.428259 1.601173 2.610228 2.683669 +0.924536 1.075405 1.468526 1.669865 2.543683 2.693196 +0.972382 1.191757 1.544758 1.638670 2.535321 2.642972 +0.903877 1.101926 1.510782 1.602659 2.487038 2.638272 +0.881279 1.096901 1.554249 1.644297 2.424659 2.557575 +0.866115 1.118877 1.603042 1.702467 2.543898 2.649301 +0.906645 1.160248 1.672021 1.747258 2.517909 2.650863 +0.861085 1.205864 1.660991 1.847091 2.462741 2.632034 +0.837175 1.187776 1.806042 1.889495 2.508608 2.684557 +0.797709 1.178516 1.903177 2.021653 2.546180 2.690072 +0.802875 1.262753 1.923936 2.000576 2.568440 2.670106 +0.766638 1.320827 1.961021 2.058945 2.582312 2.646725 +0.811579 1.455194 2.011480 2.084784 2.548418 2.639933 +0.829770 1.484961 2.052714 2.127227 2.530640 2.608181 +0.799011 1.567454 2.155632 2.265108 2.573173 2.668504 +0.730379 1.358614 2.125791 2.194588 2.518703 2.605426 +0.720667 1.277836 2.042808 2.111923 2.592800 2.675300 +0.777663 1.163703 2.066790 2.179199 2.570004 2.675513 +0.839969 1.373176 2.185884 2.304679 2.509358 2.602576 +0.815752 1.915221 2.233635 2.288481 2.569983 2.628428 +1.191882 1.945689 2.175132 2.299053 2.523524 2.632041 +1.036281 1.742208 2.072713 2.141555 2.573194 2.641551 +1.042507 1.303046 2.012892 2.154612 2.530678 2.649182 +1.109942 1.204237 1.928687 2.058228 2.384097 2.639570 +1.187387 1.287703 1.954253 2.071260 2.382559 2.641811 +1.239189 1.327757 1.930550 2.015277 2.361685 2.627501 +1.292084 1.351985 1.938008 2.017320 2.411502 2.663432 +1.306236 1.382401 1.918450 2.038312 2.339392 2.637738 +1.330235 1.401641 1.873760 1.990443 2.185496 2.510909 +1.356391 1.459759 1.883388 1.980460 2.264547 2.541810 +1.347396 1.438637 1.891675 2.018006 2.302572 2.643809 +1.300877 1.390171 1.889271 1.972933 2.337515 2.605637 +1.318667 1.410121 1.895352 1.990366 2.384682 2.654040 +1.309274 1.425501 1.966145 2.021896 2.501117 2.698509 +1.293853 1.370923 1.908443 1.999149 2.465481 2.673998 +1.277395 1.382844 2.002299 2.066843 2.496853 2.664070 +1.245384 1.422441 2.002908 2.070718 2.556839 2.666388 +1.272587 1.491087 2.012301 2.129241 2.562307 2.657432 +1.265182 1.533940 2.020942 2.093088 2.498380 2.630954 +1.265700 1.477033 2.103009 2.196534 2.455284 2.619887 +1.288505 1.642454 2.093854 2.247833 2.561691 2.658788 +1.410258 1.828971 2.171872 2.374134 2.564587 2.653381 +1.353887 1.710043 2.209331 2.426043 2.629318 2.702189 +1.413615 1.766928 2.137724 2.434853 2.632060 2.702909 +1.459054 1.706939 2.135084 2.377030 2.626415 2.708945 +1.498018 1.687923 2.094822 2.342946 2.558778 2.665699 +1.413908 1.588267 2.086727 2.293084 2.513587 2.642131 +1.399998 1.553342 1.938772 2.183871 2.458665 2.610409 +1.373521 1.449791 1.880601 2.079841 2.298236 2.559768 +1.367538 1.440752 1.973770 2.086070 2.339106 2.621913 +1.368842 1.460821 2.006053 2.129789 2.391520 2.650517 +1.375993 1.496235 2.050052 2.130850 2.453915 2.698625 +1.340575 1.484156 2.084130 2.140940 2.549924 2.685428 +1.389975 1.553009 2.063781 2.147982 2.592260 2.703825 +1.247451 1.503376 2.044299 2.136485 2.344491 2.599169 +1.315110 1.540850 2.028329 2.116330 2.272535 2.431545 +1.298833 1.587487 2.071926 2.185875 2.335690 2.500779 +1.293658 1.562430 2.031101 2.149606 2.408168 2.517292 +1.357545 1.513305 1.998085 2.153047 2.450464 2.583804 +1.314414 1.517423 2.079463 2.179438 2.522288 2.616203 +1.237750 1.513563 2.052227 2.181066 2.539042 2.628158 +1.208558 1.486041 2.046503 2.194666 2.489982 2.636673 +1.196570 1.462494 2.073139 2.230856 2.547633 2.700603 +1.080935 1.459427 2.110500 2.217708 2.538133 2.678354 +1.094483 1.378608 2.167880 2.246181 2.567935 2.691322 +0.942435 1.463343 2.253533 2.330775 2.538479 2.626769 +0.828468 1.390170 2.152319 2.218028 2.545274 2.621490 +0.883311 1.334196 2.094816 2.191259 2.475576 2.573464 +0.863185 1.418682 2.080489 2.166381 2.556104 2.714086 +0.848520 1.391080 2.049319 2.134194 2.702541 2.780818 +0.826225 1.373582 2.037386 2.120576 2.736093 2.782594 +0.823246 1.343853 2.033890 2.111803 2.740872 2.787067 +0.833848 1.336791 2.045450 2.118012 2.699609 2.796181 +0.811654 1.321345 2.094991 2.178116 2.494230 2.649899 +0.947528 1.361146 2.127848 2.219008 2.511382 2.668194 +0.875759 1.251606 2.133422 2.241748 2.473825 2.662930 +0.933534 1.448444 2.139134 2.244510 2.486761 2.606936 +0.945109 1.280801 2.208944 2.335059 2.511318 2.614528 +0.956935 1.371241 2.107196 2.194521 2.403252 2.573030 +0.981000 1.251932 2.147964 2.266597 2.440418 2.624374 +1.061610 1.231691 2.076021 2.233401 2.438599 2.636988 +1.018874 1.354035 1.998033 2.260078 2.443139 2.554775 +1.080301 1.301891 2.034629 2.145600 2.415056 2.591218 +1.133867 1.359760 2.063950 2.164629 2.439392 2.628661 +1.125038 1.414128 1.997540 2.103717 2.392421 2.599578 +1.167273 1.393564 1.998177 2.076478 2.441776 2.643288 +1.198696 1.421193 1.967983 2.057020 2.432820 2.645067 +1.256230 1.378074 1.941853 2.019326 2.444584 2.608853 +1.295565 1.412154 1.932411 2.008349 2.430053 2.649016 +1.281347 1.464522 1.888236 2.006518 2.425280 2.635204 +1.270582 1.406704 1.901187 1.969293 2.470983 2.647901 +1.266697 1.372887 1.871811 1.957591 2.414971 2.648622 +1.194388 1.351744 1.888250 1.978092 2.400857 2.662660 +1.198872 1.299839 1.864283 1.963651 2.362794 2.619509 +1.126580 1.240104 1.902544 1.997646 2.331426 2.608634 +1.104618 1.214183 1.879788 2.014306 2.251659 2.573373 +1.024288 1.193207 1.868916 2.127876 2.376009 2.623451 +1.000362 1.230212 1.960304 2.075244 2.329353 2.584128 +0.977548 1.321985 1.988755 2.104256 2.381026 2.607919 +0.927608 1.447916 2.027888 2.123013 2.478479 2.585880 +0.887733 1.516534 2.046895 2.153890 2.480515 2.582006 +0.898681 1.564754 2.091528 2.179653 2.573940 2.676783 +0.974718 1.500859 2.081966 2.177780 2.532281 2.634995 +1.023818 1.390635 2.060590 2.142028 2.469386 2.636908 +1.106581 1.431053 1.977134 2.097146 2.471693 2.659120 +1.201259 1.485663 1.944652 2.112542 2.500250 2.665927 +1.285694 1.520657 1.911058 2.044248 2.487710 2.665801 +1.362495 1.534785 1.910552 1.990936 2.505705 2.661527 +1.434594 1.514838 1.934187 2.017407 2.501527 2.693875 +1.420840 1.519491 1.909348 1.986650 2.460403 2.688194 +1.404412 1.469806 1.964287 2.054233 2.366794 2.655269 +1.388287 1.466909 1.964052 2.058950 2.286531 2.604935 +1.367998 1.434810 1.857703 2.007116 2.196577 2.604187 +1.300836 1.380544 1.740254 2.046889 2.235228 2.521906 +1.231299 1.321604 1.867230 2.147627 2.354630 2.579138 +1.154924 1.255903 1.932323 2.164374 2.392832 2.605994 +1.098663 1.202218 1.948275 2.150159 2.492596 2.625742 +1.057458 1.221852 1.869129 2.268825 2.456540 2.580362 +1.033078 1.150105 1.708873 2.264876 2.476044 2.563612 +0.988998 1.159268 1.962027 2.302711 2.448723 2.560725 +1.028425 1.228689 2.025910 2.260366 2.561850 2.661757 +0.934860 1.348208 2.053889 2.214742 2.525301 2.647713 +0.919150 1.264565 2.068138 2.183398 2.534979 2.644315 +0.975247 1.362233 2.052147 2.231420 2.582800 2.724482 +0.954336 1.311177 1.977372 2.238157 2.478111 2.617046 +0.941853 1.335982 1.976422 2.219013 2.579491 2.714299 +0.928694 1.366450 1.884879 2.183146 2.580560 2.657594 +0.986067 1.338370 1.954317 2.187863 2.566522 2.638835 +0.912646 1.284402 1.814142 2.175069 2.553933 2.638518 +0.968965 1.310497 1.839690 2.078084 2.590335 2.660573 +0.977192 1.304629 1.880951 2.127022 2.598044 2.712114 +1.023839 1.299619 1.944708 2.103778 2.625919 2.730897 +1.110208 1.286313 1.959383 2.053969 2.564587 2.676132 +1.028136 1.324243 1.976740 2.094942 2.586202 2.754727 +1.129799 1.269907 2.011874 2.109219 2.588902 2.696539 +1.056967 1.340484 2.016171 2.105554 2.557611 2.747157 +1.037500 1.255766 2.029385 2.136193 2.511776 2.709627 +1.006157 1.417167 2.071949 2.132612 2.543898 2.701957 +1.136962 1.416211 2.050339 2.112042 2.449673 2.695205 +1.135319 1.436267 2.083850 2.194924 2.386385 2.656934 +1.094073 1.385456 2.015160 2.113333 2.320097 2.641531 +1.025929 1.360649 1.878300 1.981456 2.128037 2.458938 +1.142747 1.416162 1.901013 2.054884 2.170210 2.459052 +1.093211 1.488385 1.801376 2.073578 2.203432 2.494834 +1.161243 1.263262 1.784814 2.071204 2.194577 2.436217 +1.010788 1.141181 1.728171 2.118721 2.251271 2.426326 +1.083805 1.275984 1.888426 2.068392 2.227464 2.511105 +1.093824 1.303401 1.924085 2.183963 2.348527 2.531702 +1.409867 1.540059 1.722330 2.049905 2.235685 2.389249 +1.466595 1.617030 1.819393 2.035808 2.439730 2.543324 +1.526883 1.811727 1.926153 2.129197 2.481471 2.556058 +1.420465 1.731610 1.925362 2.081119 2.474447 2.570275 +1.248374 1.462520 1.699273 1.907107 2.355354 2.484796 +1.183224 1.558159 1.646615 1.999807 2.374069 2.461600 +1.143841 1.513288 1.675690 1.906750 2.428362 2.518793 +1.066986 1.500051 1.667526 1.961464 2.445898 2.521565 +1.046648 1.520761 1.705160 1.878376 2.459759 2.532729 +1.013709 1.559530 1.737535 1.955854 2.437820 2.515857 +1.021952 1.586883 1.737034 1.929179 2.523644 2.577879 +0.942307 1.579146 1.776104 2.060265 2.437220 2.517653 +0.914226 1.642076 1.812801 2.001091 2.508510 2.570062 +0.952017 1.688066 1.935018 2.016153 2.446793 2.563584 +0.856280 1.697514 1.902727 2.012686 2.522414 2.584398 +0.891878 1.553150 1.935497 2.046974 2.532664 2.594967 +0.845424 1.602286 1.937720 2.027521 2.583016 2.649168 +0.876501 1.716624 1.939566 2.067536 2.588264 2.625363 +0.901014 1.864369 1.978925 2.075191 2.462666 2.609798 +0.911677 1.767853 1.947788 2.072575 2.595744 2.634946 +0.937394 1.708734 1.927739 2.054606 2.574109 2.647431 +1.003647 1.614615 1.942062 2.035984 2.592009 2.664724 +1.089415 1.563712 1.910690 1.974956 2.590910 2.681816 +1.180196 1.457231 1.840836 1.921595 2.573409 2.659354 +1.239380 1.444276 1.818908 1.893870 2.559595 2.657419 +1.377315 1.528992 1.744904 1.862220 2.591155 2.669066 +1.504904 1.589455 1.777756 1.887229 2.506207 2.617754 +1.628411 1.697438 1.830602 1.957574 2.495413 2.652982 +1.655345 1.726761 1.914454 2.042947 2.589709 2.658972 +1.698171 1.754006 1.967189 2.090429 2.602705 2.677128 +1.676303 1.767709 2.042847 2.156668 2.628324 2.690687 +1.724974 1.789927 2.022254 2.138454 2.576232 2.671774 +1.748186 1.802674 2.037781 2.180248 2.542513 2.638948 +1.727494 1.820586 1.984490 2.159068 2.525266 2.641113 +1.681162 1.820947 1.975700 2.157376 2.485796 2.590414 +1.695585 1.807190 1.993679 2.180888 2.380331 2.560860 +1.706934 1.810695 2.008115 2.133097 2.420753 2.641751 +1.654579 1.765733 2.024758 2.124029 2.493478 2.660848 +1.482280 1.849534 2.039337 2.240485 2.457215 2.547774 +1.603912 1.832539 2.051601 2.251630 2.461138 2.560412 +1.611914 1.787316 2.134457 2.250322 2.620939 2.678279 +1.702258 1.857664 2.093573 2.245781 2.633559 2.687798 +1.692364 1.776254 2.026193 2.275357 2.580552 2.683245 +1.587105 1.750297 1.997944 2.242069 2.586538 2.691453 +1.535548 1.765338 2.053611 2.233619 2.646730 2.717875 +1.189624 1.336795 1.763750 2.001818 2.436073 2.594289 +1.190961 1.322629 1.662495 2.028538 2.347408 2.530977 +1.170930 1.394685 1.727435 2.022812 2.382661 2.552602 +1.082797 1.383312 1.623231 1.825654 2.463128 2.574492 +1.058861 1.316419 1.617844 1.734402 2.496675 2.607354 +1.031745 1.332707 1.534727 1.707419 2.433275 2.544209 +1.096632 1.405927 1.540583 1.719915 2.509655 2.573209 +1.088142 1.381934 1.507222 1.618554 2.484112 2.618437 +1.128355 1.341806 1.494171 1.715551 2.495969 2.579865 +1.175042 1.360111 1.572899 1.757164 2.481162 2.588909 +1.251837 1.388286 1.580411 1.744290 2.530232 2.614281 +1.310739 1.444267 1.657251 1.823494 2.515110 2.614602 +1.329594 1.483659 1.703926 1.871461 2.532374 2.621921 +1.364647 1.503101 1.755842 1.919028 2.547482 2.624406 +1.400143 1.516781 1.808646 1.943813 2.572341 2.655551 +1.403936 1.536778 1.854571 1.961169 2.527770 2.650144 +1.441635 1.534902 1.873629 1.970753 2.528116 2.670832 +1.448614 1.528669 1.860977 1.951947 2.473243 2.657815 +1.451619 1.547843 1.824154 2.019980 2.462454 2.654097 +1.474914 1.548478 1.890892 1.995469 2.484609 2.659992 +1.432352 1.541523 1.888921 2.060202 2.407091 2.630443 +1.443739 1.529785 1.892698 1.996592 2.373799 2.620977 +1.379224 1.489730 1.897357 2.016742 2.416784 2.627496 +1.377069 1.463119 1.911655 2.022620 2.355389 2.608649 +1.331805 1.431037 1.929174 2.046904 2.374045 2.605001 +1.261392 1.448545 1.975458 2.082519 2.366860 2.620796 +1.222534 1.418974 1.979786 2.116310 2.439587 2.664630 +1.142938 1.304442 1.984504 2.071356 2.473077 2.672948 +1.163073 1.268521 1.930445 2.046302 2.305097 2.594448 +1.102508 1.246087 1.951734 2.103272 2.299777 2.571979 +1.010568 1.147332 1.902536 2.046240 2.288021 2.566997 +1.010466 1.307000 1.827652 2.076872 2.333263 2.555967 +1.246338 1.534633 1.859079 2.187994 2.388066 2.541619 +1.200493 1.578943 1.899233 2.165025 2.448881 2.583181 +0.969958 1.321171 1.879198 2.166270 2.417955 2.602455 +0.883738 1.359575 2.004523 2.100728 2.516977 2.633388 +0.844286 1.405546 2.057051 2.140524 2.516435 2.660060 +0.862435 1.502332 2.107411 2.205164 2.558187 2.660491 +0.940459 1.428240 2.139821 2.233319 2.564481 2.673761 +0.930987 1.583981 2.021904 2.152394 2.404035 2.506344 +1.046556 1.798258 1.988424 2.129290 2.357578 2.453538 +1.053483 1.593749 2.104331 2.232679 2.372807 2.498150 +1.137645 1.642783 2.089155 2.231807 2.383165 2.575567 +1.180782 1.899843 2.114705 2.223340 2.453147 2.554915 +1.144768 1.795798 2.058166 2.194105 2.452139 2.558749 +1.132549 1.688302 1.980246 2.107445 2.321949 2.446573 +1.155835 1.527004 1.951246 2.101869 2.265669 2.423260 +1.218988 1.551877 1.978933 2.129503 2.365239 2.547894 +1.269955 1.592834 1.957403 2.059254 2.477360 2.620075 +1.304775 1.597146 1.974266 2.084408 2.414413 2.613437 +1.304611 1.645522 1.976796 2.100584 2.364468 2.510600 +1.357449 1.721619 2.013975 2.141789 2.385178 2.512136 +1.335725 1.833907 2.001270 2.155846 2.401439 2.496098 +1.311398 1.558292 1.938760 2.063279 2.307274 2.526616 +1.360360 1.440763 1.893578 2.075310 2.237527 2.504599 +1.331599 1.468494 1.928903 2.060963 2.318029 2.567821 +1.318611 1.537603 1.924470 2.015195 2.358808 2.593307 +1.214364 1.546191 1.882099 1.995250 2.377928 2.652939 +1.296335 1.566534 1.875140 2.003277 2.476321 2.631527 +1.397784 1.586154 1.861480 2.030113 2.587065 2.654646 +1.475237 1.644203 1.915883 2.047027 2.653267 2.714423 +1.524741 1.716019 1.957822 2.067654 2.623703 2.690243 +1.578686 1.677809 1.940919 2.066782 2.613829 2.704583 +1.558659 1.702533 1.930114 2.028274 2.615049 2.686527 +1.500895 1.699904 1.908920 1.998738 2.620634 2.691280 +1.442946 1.702672 1.900985 1.975333 2.624730 2.699244 +1.372883 1.638290 1.917707 2.028286 2.626184 2.697452 +1.284224 1.656214 1.897845 1.992564 2.644425 2.707381 +1.204035 1.651822 1.889771 1.992564 2.638494 2.709577 +1.149198 1.622068 1.884510 1.979246 2.632691 2.699244 +1.133732 1.618626 1.895041 1.977544 2.625046 2.694884 +1.157568 1.662329 1.889784 1.978395 2.626035 2.684544 +1.218943 1.667105 1.879063 2.005165 2.602271 2.658132 +1.224226 1.626864 1.791981 1.894650 2.517637 2.647870 +1.354348 1.558760 1.843077 1.930892 2.571225 2.630861 +1.339527 1.595092 1.762248 1.979267 2.546017 2.613198 +1.389217 1.592419 1.859636 1.962120 2.550950 2.637714 +1.441267 1.590433 1.879393 1.987047 2.582006 2.666738 +1.431033 1.609808 1.890274 2.037874 2.525040 2.672056 +1.468384 1.575421 1.945848 2.029866 2.551470 2.705315 +1.450092 1.601430 1.954103 2.062799 2.534132 2.666966 +1.482171 1.565438 1.973588 2.124154 2.520208 2.656022 +1.429418 1.560169 1.984368 2.078415 2.510933 2.668346 +1.440913 1.587927 1.976090 2.097963 2.464144 2.621669 +1.432466 1.582610 1.973345 2.159930 2.500511 2.668329 +1.429101 1.593924 1.974811 2.070207 2.527049 2.683794 +1.377247 1.571046 1.937033 2.094336 2.488609 2.653189 +1.485270 1.572718 1.935520 2.015863 2.471891 2.687018 +1.473606 1.569260 1.872618 1.962880 2.412797 2.654369 +1.486059 1.580245 1.866252 1.975544 2.318749 2.586712 +1.465213 1.581118 1.784993 1.913021 2.172477 2.555915 +1.433656 1.566339 1.728508 1.853259 2.061966 2.413952 +1.367612 1.543842 1.700068 1.854972 2.034622 2.282022 +1.503264 1.657179 1.809362 1.937669 2.143191 2.435605 +1.340742 1.593266 1.833843 2.129408 2.468938 2.572839 +1.336721 1.481696 1.944774 2.230613 2.480290 2.580121 +1.321318 1.603141 1.968333 2.203371 2.515102 2.650047 +1.341931 1.668341 1.988838 2.185252 2.564141 2.653216 +1.315554 1.648897 1.959899 2.147638 2.516885 2.612616 +1.277314 1.620218 2.001858 2.229409 2.531549 2.621818 +1.305168 1.578599 2.038627 2.295512 2.565341 2.654838 +1.330511 1.609911 1.991543 2.262708 2.563339 2.665956 +1.374004 1.683930 1.980067 2.338575 2.595603 2.682727 +1.268703 1.389752 1.885378 2.110404 2.488114 2.638645 +1.216813 1.310045 1.854691 2.036714 2.277594 2.566534 +1.234945 1.337806 1.949427 2.059361 2.295326 2.566468 +1.188939 1.302387 1.996200 2.107442 2.349193 2.585236 +1.268977 1.440154 2.024771 2.136855 2.444005 2.664042 +1.274373 1.383125 2.066734 2.151173 2.407560 2.654201 +1.264553 1.356123 2.001656 2.118864 2.287784 2.569535 +1.234337 1.329784 2.063392 2.150768 2.367188 2.598596 +1.155210 1.257442 2.082496 2.211439 2.390593 2.620100 +1.199455 1.265557 1.934979 2.226691 2.540894 2.664195 +1.304701 1.526851 1.954550 2.174656 2.477694 2.621713 +1.638067 1.896263 2.077081 2.361007 2.646027 2.718839 +1.643821 1.943109 2.131987 2.329624 2.578717 2.645464 +1.640898 1.989224 2.161468 2.269205 2.586475 2.655395 +1.723007 1.910073 2.070189 2.259565 2.564392 2.640342 +1.652067 1.998733 2.135937 2.352824 2.652512 2.717475 +1.680722 2.074091 2.269666 2.453470 2.699939 2.763041 +1.695085 2.058973 2.193637 2.313571 2.639345 2.699445 +1.782955 2.014033 2.224899 2.332287 2.645355 2.724401 +1.705960 1.974745 2.180829 2.256084 2.575177 2.716938 +1.662556 1.988643 2.115183 2.205279 2.548376 2.657655 +1.562053 1.843896 2.173269 2.265891 2.477950 2.695966 +1.685920 1.795837 2.078330 2.180138 2.465369 2.667314 +1.680613 1.738555 1.994736 2.131193 2.473191 2.649544 +1.659289 1.833639 2.000087 2.140167 2.564913 2.692724 +1.714890 1.784823 1.974907 2.085230 2.566670 2.701036 +1.729112 1.826059 1.895041 2.053724 2.603924 2.699244 +1.696294 1.791079 1.916038 2.017742 2.583106 2.704200 +1.626844 1.720989 1.890443 2.014482 2.589192 2.689135 +1.574181 1.677998 1.880801 1.982799 2.574984 2.664083 +1.432597 1.676378 1.834673 1.964658 2.535300 2.638654 +1.318535 1.535375 1.836957 1.932882 2.478408 2.578350 +1.226292 1.492951 1.836423 1.946067 2.430171 2.582074 +1.098912 1.499048 1.896293 2.028872 2.540535 2.618603 +1.034465 1.533372 1.964842 2.070966 2.578583 2.651519 +0.979835 1.480912 1.975960 2.089319 2.534240 2.632634 +0.916592 1.481293 1.967506 2.053292 2.558345 2.642742 +0.937338 1.474374 2.023762 2.110460 2.585438 2.665463 +0.873055 1.560533 2.028802 2.086416 2.575020 2.684778 +0.901938 1.628414 2.031806 2.102850 2.610158 2.685650 +0.862562 1.556144 1.997573 2.081742 2.533196 2.615757 +0.906140 1.665744 2.019373 2.133337 2.581928 2.661153 +0.872836 1.638660 2.038436 2.097283 2.645014 2.697786 +0.829264 1.441895 2.039191 2.111142 2.611659 2.688610 +0.825197 1.304534 2.056354 2.143792 2.590309 2.657819 +0.793520 1.521024 1.979438 2.058424 2.596225 2.668581 +0.849751 1.485532 1.986103 2.055458 2.624269 2.701899 +0.849936 1.385589 2.007518 2.060577 2.567229 2.678449 +0.829655 1.230975 1.988404 2.101475 2.530728 2.677331 +0.940677 1.264510 1.946316 2.046724 2.499806 2.677984 +1.038884 1.297487 1.958215 2.035997 2.406970 2.650323 +1.157909 1.247311 1.892511 1.984329 2.396990 2.663399 +1.237064 1.318827 1.843309 1.954773 2.420851 2.693910 +1.328871 1.403948 1.808685 1.946118 2.400888 2.683397 +1.393193 1.460812 1.822128 1.939601 2.242548 2.723232 +1.370957 1.526137 1.785367 1.963164 2.136749 2.644805 +1.501135 1.606768 1.841831 2.009462 2.198461 2.614649 +1.467944 1.551473 1.849852 1.982829 2.208604 2.514793 +1.405944 1.480977 1.855980 1.997060 2.178717 2.490007 +1.448170 1.520957 1.868813 1.975365 2.241031 2.616351 +1.380808 1.612670 1.869962 2.026788 2.443477 2.639977 +1.483716 1.596112 1.969733 2.100913 2.577431 2.688144 +1.467685 1.578222 1.986564 2.194709 2.570945 2.671094 +1.496302 1.614196 2.032020 2.218322 2.553463 2.681813 +1.596958 1.722731 2.144525 2.319980 2.604392 2.703958 +1.563283 1.830072 2.213128 2.432926 2.641108 2.721000 +1.591103 1.948477 2.288414 2.486581 2.666837 2.743573 +1.475707 1.718658 2.050982 2.217962 2.487280 2.571804 +1.558930 1.772302 2.094474 2.234464 2.518928 2.597737 +1.567586 1.822091 2.100593 2.286654 2.533948 2.648113 +1.750029 1.936668 2.135601 2.347638 2.546896 2.638316 +1.756882 1.998584 2.116800 2.223412 2.556559 2.647062 +1.700043 1.922262 2.075348 2.184374 2.556081 2.639062 +1.598667 1.709712 1.994558 2.098788 2.521397 2.628442 +1.609782 1.719799 1.937528 2.091978 2.547584 2.621070 +1.580745 1.686692 1.927934 2.059508 2.580331 2.643528 +1.541164 1.684662 1.944797 2.038248 2.568516 2.637104 +1.474497 1.633889 1.881331 1.988847 2.554704 2.623589 +1.427685 1.616808 1.898469 1.994121 2.545908 2.635844 +1.366974 1.583736 1.860760 2.018090 2.526247 2.594032 +1.257899 1.562399 1.870764 1.961750 2.512050 2.589589 +1.183313 1.571246 1.867445 1.988791 2.543767 2.607786 +1.137720 1.607193 1.879149 2.008769 2.536804 2.607481 +1.053818 1.511423 1.904439 2.002387 2.584849 2.657089 +1.029306 1.560669 1.913466 1.984439 2.613420 2.670916 +0.990299 1.520302 1.919708 2.005988 2.615870 2.705960 +0.927002 1.486845 1.900099 1.977768 2.614622 2.695757 +0.924166 1.500302 1.837270 1.915819 2.601787 2.702827 +0.901854 1.422756 1.898010 1.950141 2.572992 2.759299 +0.910623 1.286484 1.801282 1.925793 2.438152 2.671294 +0.904293 1.226137 1.873337 1.946907 2.485265 2.645532 +0.872654 1.122664 1.912497 2.047619 2.468062 2.645490 +1.136081 1.248013 1.725399 2.180627 2.493778 2.579400 +1.161500 1.346974 1.804044 2.157021 2.550312 2.633164 +1.287295 1.663717 2.044188 2.321923 2.599284 2.687129 +1.456799 1.758274 2.055266 2.310654 2.549315 2.660074 +1.416948 1.741370 2.104189 2.357764 2.591761 2.679543 +1.379535 1.752525 2.173415 2.361073 2.617497 2.699322 +1.361005 1.762025 2.115710 2.330663 2.562002 2.650389 +1.340777 1.685357 2.024889 2.281946 2.547415 2.639463 +1.278174 1.686145 1.961407 2.165468 2.554171 2.647873 +1.294524 1.547620 1.981967 2.183432 2.547510 2.637235 +1.201621 1.343641 2.007859 2.089427 2.535679 2.660742 +1.201995 1.332111 1.949153 2.051811 2.553202 2.665468 +1.180355 1.354250 1.890523 2.069912 2.515229 2.620120 +1.128725 1.419757 1.854779 2.056632 2.480702 2.583539 +1.133191 1.402342 1.822656 2.013606 2.539914 2.639438 +1.149266 1.376927 1.821187 1.914934 2.562423 2.664037 +1.080871 1.408443 1.788020 1.879929 2.517515 2.656681 +1.152439 1.509600 1.822338 1.939812 2.528944 2.619151 +1.227262 1.543782 1.935413 2.017678 2.575512 2.665626 +1.253647 1.485940 1.945543 1.987370 2.539186 2.715089 +1.224504 1.521337 1.982156 2.044940 2.522684 2.687446 +1.258716 1.476124 1.981858 2.073104 2.536174 2.634089 +1.255580 1.471131 1.983938 2.052555 2.541040 2.708650 +1.221419 1.556731 2.013319 2.089772 2.538596 2.706495 +1.178484 1.474650 2.007635 2.122088 2.560256 2.629434 +1.136643 1.459288 2.033733 2.100427 2.544702 2.689126 +1.035202 1.462561 2.024973 2.194093 2.530601 2.662208 +1.090875 1.522421 2.038442 2.129424 2.587618 2.687392 +1.054541 1.538340 2.000589 2.084015 2.516505 2.644331 +1.069567 1.471150 1.977006 2.102657 2.548224 2.645658 +1.084637 1.235068 1.999027 2.091007 2.405191 2.622410 +1.073907 1.180490 1.961383 2.101877 2.255303 2.531797 +1.185536 1.320277 2.006751 2.098846 2.443082 2.582972 +1.256811 1.419989 1.983529 2.130962 2.470417 2.558689 +1.290736 1.391916 1.995379 2.106560 2.351663 2.485168 +1.428569 1.748298 2.044813 2.277573 2.513087 2.625248 +1.495766 1.686660 2.135657 2.292230 2.499007 2.616505 +1.482459 1.632012 2.083877 2.297241 2.488552 2.605327 +1.538843 1.630868 2.111745 2.223107 2.576837 2.693238 +1.551627 1.628553 2.040601 2.158000 2.590177 2.713514 +1.570014 1.637722 1.958103 2.124258 2.570176 2.692788 +1.534589 1.607992 1.801643 2.087274 2.392697 2.600933 +1.502776 1.607625 1.843802 2.082344 2.323284 2.522392 +1.515698 1.613442 1.837842 2.027239 2.402910 2.602242 +1.510034 1.607577 1.826422 1.955465 2.340570 2.679619 +1.445827 1.566639 1.756421 1.869709 2.296147 2.601653 +1.410709 1.488515 1.820022 1.910438 2.358230 2.614654 +1.301575 1.428283 1.812427 1.902581 2.293360 2.725276 +1.106808 1.351509 1.888725 1.956330 2.320442 2.646886 +1.056263 1.366917 1.866615 1.968949 2.421463 2.653524 +1.148746 1.368055 1.809637 2.064105 2.437788 2.604096 +0.990270 1.453159 1.887277 2.035172 2.296937 2.600298 +0.943695 1.204266 1.748001 1.886445 2.181614 2.509804 +1.057049 1.221402 1.835972 1.972438 2.154951 2.492969 +0.936404 1.225524 1.895053 1.998065 2.539531 2.644930 +0.941516 1.224493 1.966408 2.055267 2.515087 2.609082 +1.000240 1.314972 1.942001 2.051921 2.535877 2.634783 +1.031394 1.407401 1.953467 2.045443 2.550815 2.634369 +1.118870 1.441951 1.952517 2.061995 2.494339 2.608036 +1.197103 1.553158 1.887646 2.009186 2.472098 2.550658 +1.293802 1.588339 1.868376 2.045916 2.481096 2.566107 +1.353770 1.610646 1.897619 2.083477 2.408292 2.543397 +1.403681 1.521997 1.891672 2.054144 2.357288 2.512253 +1.370402 1.446254 1.871326 1.998144 2.336676 2.570693 +1.499387 1.755248 2.090328 2.282953 2.484033 2.574394 +1.567708 1.842611 2.136623 2.278726 2.477117 2.576067 +1.591554 1.767544 2.169415 2.302935 2.525126 2.637496 +1.458272 1.799744 2.227216 2.397500 2.616529 2.705570 +1.496705 1.846042 2.279896 2.437186 2.649673 2.726623 +1.502759 1.731322 2.268727 2.464213 2.623623 2.706745 +1.497299 1.617932 2.156580 2.386255 2.579030 2.664716 +1.379977 1.538687 1.850634 2.109517 2.410662 2.586146 +1.405875 1.497926 1.741705 1.932278 2.337183 2.563846 +1.346170 1.431041 1.657425 1.884420 2.373948 2.587354 +1.307909 1.406366 1.734141 1.875825 2.460720 2.602094 +1.273940 1.571154 1.771276 1.912248 2.536452 2.595610 +1.200061 1.575178 1.770854 1.877630 2.508016 2.579146 +1.125813 1.539421 1.722626 1.859971 2.511653 2.574626 +1.064900 1.484512 1.690862 1.832750 2.519579 2.589278 +1.042869 1.483231 1.627118 1.867084 2.495867 2.550264 +0.950910 1.474823 1.576110 1.830086 2.519438 2.569906 +1.004516 1.423026 1.550120 1.835220 2.473605 2.544366 +1.026409 1.365688 1.510656 1.879110 2.467179 2.543867 +0.978321 1.338491 1.528018 1.913878 2.465066 2.524725 +0.922555 1.409585 1.520258 1.932657 2.404714 2.472216 +1.009019 1.345028 1.518729 1.999531 2.463064 2.544939 +0.989351 1.433164 1.573872 2.015438 2.401202 2.490979 +1.035325 1.556325 1.677312 2.086779 2.481518 2.567949 +1.004119 1.575292 1.796393 2.075521 2.402912 2.574238 +1.037355 1.681818 1.943106 2.065425 2.478887 2.598899 +1.005855 1.684746 1.972392 2.109307 2.565052 2.623513 +0.954873 1.719791 2.006188 2.112346 2.598630 2.682782 +0.937994 1.728321 1.993763 2.105254 2.632050 2.700706 +0.889626 1.709530 2.001291 2.090092 2.620540 2.709802 +0.912128 1.657624 1.966778 2.058636 2.626429 2.702918 +0.972006 1.569116 1.985953 2.130241 2.569149 2.677258 +1.038791 1.651170 2.008290 2.118109 2.599188 2.701292 +1.102203 1.624993 1.998759 2.125031 2.569760 2.646643 +1.187738 1.639367 2.059243 2.147304 2.475862 2.634964 +1.274099 1.590670 2.016754 2.099633 2.548725 2.668989 +1.373403 1.630011 1.981494 2.070929 2.505950 2.689328 +1.511208 1.602606 1.911343 2.022899 2.475945 2.645751 +1.553078 1.639398 1.870403 1.975613 2.473431 2.626572 +1.633420 1.773325 1.875127 1.959482 2.413151 2.625912 +1.596719 1.747314 1.878046 2.049018 2.587489 2.669276 +1.664674 1.933354 2.156044 2.280025 2.462736 2.571555 +1.551190 1.695801 2.047099 2.236977 2.447592 2.570843 +1.648304 1.728067 2.060789 2.273739 2.475137 2.631203 +1.633548 1.757572 2.089279 2.240980 2.436119 2.556847 +1.608644 1.684711 2.123747 2.256566 2.486503 2.598234 +1.653176 1.714541 2.105354 2.203230 2.509317 2.641781 +1.541046 1.679960 2.104266 2.247262 2.540379 2.626724 +1.559664 1.659637 2.101376 2.213674 2.473238 2.562999 +1.608810 1.671776 2.071434 2.184829 2.493283 2.639463 +1.538876 1.610189 2.083083 2.171544 2.554389 2.650993 +1.511021 1.595459 2.031637 2.130089 2.587598 2.660399 +1.340693 1.587842 1.931002 2.117119 2.599860 2.676574 +1.484682 1.533251 2.024488 2.113154 2.548321 2.659954 +1.534337 1.608310 2.031541 2.136001 2.537102 2.617716 +1.571577 1.618314 2.056726 2.139748 2.525414 2.622206 +1.564471 1.631266 2.060592 2.166039 2.469995 2.635657 +1.533650 1.663515 2.093962 2.190787 2.406743 2.622754 +1.570124 1.631042 2.049374 2.165169 2.393566 2.588498 +1.552473 1.634522 2.008478 2.098878 2.509195 2.669322 +1.498536 1.602806 2.008880 2.099726 2.525137 2.659175 +1.450925 1.660536 1.991759 2.103304 2.544073 2.696474 +1.447598 1.569099 1.993051 2.079756 2.587712 2.676395 +1.394567 1.544697 2.006663 2.078973 2.579015 2.721882 +1.347921 1.507746 1.993785 2.077331 2.510234 2.682685 +1.265189 1.355385 1.877848 2.063826 2.425800 2.657797 +1.266300 1.376932 2.008877 2.275008 2.479039 2.636159 +1.414729 1.680622 2.057398 2.332754 2.549975 2.652454 +1.499883 1.708789 2.054742 2.313580 2.521026 2.613915 +1.445680 1.741768 2.126388 2.338809 2.495118 2.597970 +1.459203 1.792340 2.113493 2.346074 2.563702 2.664973 +1.416845 1.644394 2.131474 2.322905 2.578800 2.677164 +1.447967 1.708221 2.144894 2.272584 2.593212 2.700869 +1.474608 1.742978 2.066944 2.341635 2.601749 2.685249 +1.346721 1.653940 1.999147 2.218537 2.633365 2.723602 +1.375208 1.551414 2.052682 2.232013 2.586844 2.697029 +1.260950 1.501751 1.925196 2.033937 2.546694 2.652031 +1.259339 1.500189 1.909647 1.982913 2.545881 2.638673 +1.252838 1.563842 1.910593 1.973683 2.579307 2.664280 +1.263002 1.546326 1.878080 2.031152 2.583468 2.653793 +1.265196 1.521273 1.905708 1.967385 2.581430 2.658715 +1.307704 1.547718 1.881421 1.962040 2.573475 2.658828 +1.291340 1.575015 1.915239 1.985560 2.602082 2.697699 +1.295431 1.626460 1.923299 2.023724 2.591291 2.680142 +1.301210 1.624080 1.878934 1.998083 2.560098 2.634506 +1.305813 1.620922 1.888028 1.989036 2.606227 2.669425 +1.308088 1.642328 1.885958 2.013573 2.611911 2.696648 +1.312101 1.627858 1.861841 1.974096 2.602616 2.658487 +1.292897 1.605725 1.877131 1.973395 2.599643 2.682844 +1.273139 1.591736 1.870416 1.947454 2.602328 2.674146 +1.283582 1.620817 1.847273 1.928033 2.590051 2.636876 +1.246205 1.560066 1.851625 1.954533 2.587535 2.673542 +1.260393 1.539639 1.831617 1.928432 2.552288 2.629629 +1.261220 1.505229 1.857309 1.933908 2.569004 2.696314 +1.283108 1.719865 1.823903 1.976026 2.565436 2.628748 +1.314387 1.617735 1.804065 1.960535 2.596814 2.686738 +1.338699 1.637284 1.896932 2.009128 2.523466 2.637375 +1.336475 1.577029 1.850025 1.943237 2.521339 2.596832 +1.398912 1.549275 1.724463 1.861933 2.166791 2.466332 +1.406894 1.497435 1.805042 1.909122 2.284281 2.542582 +1.474849 1.579373 1.970765 2.079699 2.371434 2.542616 +1.452309 1.539401 2.076665 2.137999 2.442972 2.649515 +1.450617 1.506612 2.036385 2.131452 2.484829 2.674720 +1.434796 1.583083 2.027674 2.136807 2.429113 2.578344 +1.087572 1.367208 1.786303 2.025035 2.298079 2.515673 +0.992092 1.436432 1.725512 1.965111 2.425717 2.549021 +0.969474 1.497321 1.730092 2.016045 2.414373 2.633316 +0.936277 1.413012 1.683609 2.029768 2.443096 2.552830 +1.176352 1.559638 1.748772 2.061891 2.311483 2.434690 +1.067106 1.406642 1.643885 1.978806 2.374725 2.547845 +0.989262 1.333111 1.475085 1.728650 2.492018 2.553467 +0.957471 1.308545 1.424561 1.823472 2.490215 2.552316 +1.035765 1.254486 1.352081 1.786247 2.539488 2.585779 +1.023678 1.232418 1.398476 1.875768 2.451677 2.540251 +1.037249 1.247286 1.387422 2.008554 2.419268 2.496115 +1.045924 1.231687 1.361952 1.887611 2.384450 2.471500 +1.000981 1.250837 1.376662 1.767666 2.398053 2.484439 +1.061773 1.214611 1.410756 1.728252 2.423979 2.514269 +1.168228 1.291194 1.597509 1.900015 2.415419 2.555014 +1.150788 1.412860 1.825953 1.953264 2.400052 2.535324 +1.166923 1.517635 1.943529 2.034246 2.373359 2.521470 +1.183183 1.523161 1.995315 2.119892 2.433461 2.591155 +1.159482 1.521728 2.072369 2.176962 2.514904 2.660759 +1.260320 1.722656 2.116773 2.249048 2.534123 2.645628 +1.450433 1.717713 2.048790 2.212752 2.499485 2.636128 +1.449227 1.653123 2.023641 2.196888 2.453054 2.612516 +1.388122 1.597569 1.968649 2.163453 2.425431 2.578033 +1.347603 1.449808 1.894138 2.168973 2.446471 2.602268 +1.398006 1.471755 1.922063 2.120957 2.396434 2.600718 +1.428663 1.541308 2.046052 2.132513 2.397088 2.643104 +1.492673 1.585159 2.059339 2.158303 2.480824 2.648749 +1.558991 1.648786 2.037511 2.153321 2.512380 2.647660 +1.587505 1.659085 2.020500 2.139692 2.537458 2.616564 +1.634348 1.739360 2.044485 2.218194 2.530130 2.622735 +1.650152 1.736774 2.049269 2.148919 2.551868 2.651288 +1.640705 1.707347 1.991329 2.119563 2.587595 2.642835 +1.655822 1.709750 1.941946 2.090791 2.570081 2.630366 +1.606441 1.695623 1.852762 2.047845 2.554897 2.628090 +1.484591 1.657033 1.822979 2.008956 2.584027 2.653723 +1.348381 1.627797 1.779073 1.897327 2.521867 2.646403 +1.155644 1.464872 1.763798 1.943553 2.555854 2.642088 +1.339453 1.676328 1.971041 2.186803 2.438887 2.571072 +1.297378 1.615525 1.946759 2.151180 2.429841 2.558129 +1.136457 1.519887 1.867226 2.107387 2.452727 2.553710 +0.943433 1.350976 1.714327 1.830884 2.380038 2.573606 +0.933950 1.078579 1.553087 1.662344 2.027950 2.453145 +0.896937 1.246931 1.586629 1.684078 2.397137 2.611707 +0.892078 1.350059 1.560075 1.689846 2.506278 2.607560 +0.772181 1.313675 1.525659 1.650282 2.468977 2.636413 +0.863603 1.328577 1.481135 1.768890 2.496778 2.546566 +0.908312 1.258415 1.382771 1.699751 2.448589 2.547326 +0.863083 1.273798 1.422414 1.575877 2.509924 2.567103 +0.798143 1.233378 1.328045 1.718547 2.545479 2.654885 +0.937997 1.297209 1.447389 1.659450 2.539430 2.664368 +1.015311 1.282646 1.449652 1.656931 2.519587 2.597241 +1.012603 1.308086 1.428756 1.742642 2.581377 2.654752 +1.075222 1.359942 1.466363 1.790456 2.582927 2.654917 +1.174719 1.354592 1.470683 1.808114 2.611814 2.690601 +1.304671 1.380565 1.486415 1.863253 2.499088 2.646637 +1.329253 1.458935 1.599739 1.985102 2.412241 2.489601 +1.326849 1.466962 1.650712 1.972882 2.173652 2.363777 +1.440729 1.597862 1.756923 1.942121 2.134420 2.330899 +1.490912 1.615283 1.799725 1.989183 2.307191 2.535959 +1.523001 1.676436 1.841390 2.084493 2.490067 2.619504 +1.536446 1.672927 1.834339 2.067942 2.594848 2.655730 +1.585206 1.673419 1.879347 2.026137 2.609162 2.691334 +1.576452 1.662112 1.868110 1.987273 2.629831 2.702492 +1.561137 1.629084 1.910414 2.005430 2.633437 2.726135 +1.531209 1.615548 1.873644 1.966279 2.522587 2.706064 +1.473294 1.591222 1.908945 1.973407 2.535042 2.733124 +1.412536 1.473645 1.871722 1.957323 2.341205 2.740704 +1.379808 1.473241 1.923919 1.986068 2.447172 2.657583 +1.333691 1.500115 1.933534 2.138032 2.501795 2.615830 +1.405765 1.570091 2.028114 2.332669 2.573681 2.664117 +1.386052 1.546746 2.101843 2.380119 2.607300 2.712463 +1.420552 1.664080 2.096840 2.287671 2.545433 2.645671 +1.429919 1.632895 2.056448 2.245342 2.469727 2.594625 +1.450338 1.542326 1.936139 2.160089 2.389658 2.594948 +1.458650 1.545840 1.973946 2.132840 2.280546 2.519107 +1.499624 1.621854 1.924363 2.086584 2.253820 2.393464 +1.480124 1.596614 1.822901 2.030079 2.212455 2.440593 +1.385572 1.515794 1.763525 2.007562 2.207014 2.505163 +1.363477 1.483710 1.745394 2.020826 2.177380 2.428417 +1.422412 1.526361 1.802470 2.041367 2.267629 2.509983 +1.451781 1.539504 1.888618 2.079745 2.258528 2.500819 +1.462745 1.548876 1.925748 2.065292 2.320100 2.591877 +1.459612 1.526791 1.937299 2.029745 2.425999 2.618215 +1.426774 1.495962 1.934803 2.028683 2.474317 2.639936 +1.395478 1.494605 1.923542 2.006865 2.508795 2.651596 +1.315323 1.475877 1.925867 2.012444 2.562544 2.642674 +1.216208 1.542312 1.867609 1.962911 2.578507 2.638914 +1.188119 1.592111 1.826165 1.956758 2.592728 2.659305 +1.157283 1.519027 1.841285 1.936129 2.596722 2.669387 +1.042732 1.334857 1.852810 1.927812 2.509256 2.721390 +1.076921 1.512728 1.892211 1.976017 2.370736 2.635640 +1.328644 1.555209 1.826957 2.080018 2.447934 2.607755 +1.271225 1.383527 1.740551 2.048721 2.356257 2.567108 +1.288765 1.385478 1.793872 1.977849 2.390396 2.604554 +1.328655 1.422241 1.805644 2.002822 2.289156 2.544301 +1.377945 1.493655 1.793682 2.031868 2.353733 2.518906 +1.384430 1.453654 1.838071 2.001840 2.390785 2.635123 +1.289457 1.403427 1.871018 1.986122 2.479981 2.723796 +1.207888 1.388220 1.865052 2.031661 2.450066 2.591415 +1.218628 1.309314 1.909852 2.003782 2.499425 2.604984 +1.178831 1.273297 1.832814 2.025041 2.508629 2.650229 +1.147475 1.259195 1.930161 2.027735 2.522075 2.634075 +1.100906 1.268026 1.857908 1.951898 2.508895 2.660387 +1.069825 1.225671 1.888950 1.974341 2.492132 2.592105 +1.042255 1.182210 1.891740 2.039958 2.559652 2.679327 +0.956414 1.180966 1.881463 1.994332 2.316474 2.617691 +1.061791 1.571696 1.926569 2.107177 2.404155 2.525452 +1.374312 1.475896 1.678426 1.972424 2.364289 2.516531 +1.363442 1.455771 1.763156 1.970798 2.368334 2.586977 +1.423043 1.591891 1.798197 2.012780 2.388112 2.602184 +1.527265 1.605781 1.909513 2.033429 2.406683 2.593463 +1.585135 1.664508 1.918013 2.026537 2.425727 2.600924 +1.611888 1.728561 1.907667 2.034036 2.395680 2.641770 +1.463013 1.624657 1.872286 1.998243 2.487821 2.662465 +1.507075 1.597912 1.893748 1.997011 2.535979 2.672459 +1.502401 1.618027 1.888560 2.024162 2.581852 2.656536 +1.553117 1.639479 1.918920 2.034284 2.576859 2.655677 +1.577358 1.648261 1.958093 2.053413 2.567886 2.656516 +1.595375 1.654628 1.997767 2.099746 2.531642 2.675206 +1.621639 1.704007 1.957750 2.074637 2.584314 2.660506 +1.618433 1.711386 1.954786 2.067454 2.533767 2.695229 +1.617851 1.716314 1.949677 2.103360 2.635944 2.686892 +1.649322 1.746309 1.901606 2.064352 2.606774 2.690238 +1.635059 1.769603 1.904617 2.019099 2.607597 2.713325 +1.645565 1.779500 1.868948 1.965332 2.592154 2.714895 +1.686573 1.757504 1.858066 1.922036 2.505271 2.698890 +1.612716 1.703234 1.831053 1.925901 2.373806 2.613684 +1.244351 1.409563 1.713462 1.967702 2.351463 2.537356 +1.269988 1.387301 1.640967 1.991832 2.324911 2.501768 +1.305349 1.455772 1.788777 2.091229 2.487237 2.614726 +1.413862 1.518807 1.888520 2.252275 2.448086 2.594722 +1.409418 1.591460 1.944717 2.196924 2.518393 2.638233 +1.399142 1.703314 1.966146 2.224863 2.616908 2.734082 +1.375311 1.636377 2.061764 2.292420 2.586624 2.705744 +1.394667 1.733415 2.073598 2.297154 2.573824 2.672888 +1.366082 1.738611 2.016634 2.285662 2.605490 2.693517 +1.360620 1.601685 1.967966 2.194839 2.564848 2.657918 +1.354700 1.471541 1.990171 2.165439 2.569000 2.679116 +1.319372 1.403922 2.030220 2.115007 2.452702 2.635911 +1.303257 1.374731 1.975040 2.111171 2.369818 2.660606 +1.325790 1.431051 2.036171 2.113943 2.475995 2.685073 +1.307478 1.510363 2.117703 2.179166 2.554579 2.695776 +1.311427 1.548305 2.128351 2.279725 2.551702 2.645499 +1.293775 1.442228 2.115561 2.289555 2.415905 2.531210 +1.278672 1.697114 2.092498 2.199540 2.368518 2.561138 +1.292641 1.867932 2.128826 2.206329 2.450839 2.551778 +1.234857 1.631071 2.143705 2.304460 2.491014 2.565728 +1.219953 1.367565 2.149802 2.218488 2.495215 2.635299 +1.208902 1.484837 2.180300 2.276690 2.526332 2.626732 +1.165264 1.458241 2.155590 2.227283 2.490182 2.596799 +1.116188 1.492178 2.177271 2.241905 2.532331 2.620529 +1.096897 1.524925 2.093489 2.345253 2.480356 2.611159 +1.043785 1.369028 2.229277 2.306648 2.527431 2.613026 +1.080719 1.336126 2.135541 2.240613 2.463443 2.634282 +1.126263 1.502538 2.065329 2.274832 2.512833 2.588250 +1.199125 1.448000 2.040575 2.216856 2.449127 2.544297 +1.244303 1.540831 2.036533 2.174834 2.470267 2.580345 +1.277190 1.574057 2.066371 2.150365 2.508540 2.611728 +1.341754 1.576876 2.031475 2.120651 2.496164 2.575343 +1.335444 1.541598 1.994337 2.108804 2.518844 2.622948 +1.351719 1.543708 2.003315 2.075354 2.579158 2.656631 +1.359299 1.470533 1.968461 2.042323 2.565151 2.664841 +1.368199 1.433218 1.983774 2.044947 2.438603 2.670598 +1.351177 1.426131 1.991290 2.087726 2.430748 2.616370 +1.349866 1.483300 2.000270 2.242826 2.535909 2.629047 +1.322061 1.596777 2.113123 2.408146 2.548980 2.625263 +1.381288 1.648758 2.192458 2.378361 2.579516 2.654496 +1.372134 1.542663 2.062546 2.307310 2.475587 2.580621 +1.363570 1.463481 1.864764 2.288459 2.467800 2.571685 +1.335793 1.536300 1.886159 2.221871 2.543381 2.670529 +1.259757 1.393352 1.604761 1.934288 2.430512 2.509599 +1.224722 1.349648 1.481936 1.836832 2.384963 2.463134 +1.253661 1.369206 1.505507 1.994342 2.366061 2.454562 +1.250448 1.372217 1.563439 2.133283 2.391531 2.461107 +1.298984 1.412532 1.560005 2.162846 2.475577 2.551467 +1.308701 1.487231 1.616571 2.140891 2.422519 2.527844 +1.362265 1.509740 1.691137 2.151850 2.425060 2.504008 +1.415186 1.573817 1.726343 2.145690 2.423615 2.518947 +1.468304 1.624569 1.768003 2.107079 2.433687 2.501879 +1.474213 1.645172 1.829377 2.150471 2.330539 2.454132 +1.488731 1.662220 1.853177 2.160434 2.390722 2.507469 +1.515371 1.685102 1.820897 2.090815 2.477135 2.541320 +1.533941 1.681022 1.911151 2.101052 2.431211 2.507421 +1.547022 1.762747 1.905315 2.057302 2.369967 2.496458 +1.524747 1.707503 1.880853 2.145136 2.331290 2.443298 +1.532670 1.689464 1.838440 2.066707 2.352074 2.487585 +1.449082 1.639914 1.786524 2.047043 2.328788 2.426218 +1.393415 1.607003 1.752128 2.065963 2.381000 2.473775 +1.234921 1.620384 1.751709 2.079353 2.400969 2.471820 +1.128649 1.589193 1.725978 2.097814 2.421776 2.507176 +1.205122 1.491109 1.707033 2.143134 2.407676 2.489596 +1.105985 1.524092 1.740260 2.142524 2.422755 2.532710 +1.146867 1.428089 1.698792 2.100330 2.423332 2.545496 +1.116015 1.351902 1.754307 2.146023 2.411698 2.527537 +1.178509 1.306840 1.824109 2.272040 2.452886 2.546314 +1.386046 1.686532 2.010818 2.148686 2.439205 2.570934 +1.334381 1.674050 1.962490 2.108725 2.403922 2.587496 +1.309542 1.519433 2.030598 2.119732 2.436082 2.620801 +1.199624 1.425192 2.037889 2.161327 2.493314 2.639529 +0.913804 1.251727 2.055079 2.176873 2.416854 2.644928 +0.822137 1.067331 2.019119 2.216592 2.395557 2.658189 +0.859923 0.985874 1.904285 2.160589 2.433708 2.639822 +0.906761 1.140617 2.010505 2.146239 2.469640 2.644134 +0.950845 1.253958 2.039526 2.095898 2.600275 2.711094 +0.953879 1.245319 1.985465 2.133152 2.543655 2.613003 +1.031672 1.286594 1.974619 2.037126 2.541018 2.690276 +1.051598 1.373163 1.905246 2.009638 2.495552 2.674053 +1.088262 1.297396 1.898694 2.018578 2.508840 2.690510 +1.146698 1.282269 1.930714 2.010155 2.439408 2.647009 +1.157205 1.343846 1.930823 2.029125 2.368152 2.598000 +1.247348 1.432742 1.942594 2.067451 2.392833 2.554304 +1.297617 1.516021 1.993391 2.079273 2.439458 2.548273 +1.386254 1.483598 1.965854 2.071612 2.444793 2.594366 +1.429692 1.499865 1.880633 2.074107 2.346203 2.604251 +1.569133 1.644482 1.942763 2.045196 2.370694 2.589367 +1.696361 1.745617 1.980943 2.093662 2.433481 2.583667 +1.694840 1.801151 1.961027 2.068322 2.452636 2.638290 +1.619793 1.785586 1.919626 2.055816 2.238163 2.498763 +1.223689 1.621225 1.791717 1.898693 2.161669 2.499947 +1.144413 1.452915 1.780893 1.866745 2.214208 2.494268 +1.135538 1.495124 1.820776 1.894356 2.115005 2.441578 +1.131378 1.535817 1.737318 1.842419 2.021638 2.425946 +1.212645 1.312165 1.752907 1.889323 2.108905 2.469701 +1.253951 1.352407 1.652652 1.960954 2.394436 2.568676 +1.362676 1.580790 1.913319 2.212617 2.381597 2.528987 +1.417331 1.582049 1.977630 2.237995 2.413078 2.580292 +1.383161 1.603552 2.016139 2.210126 2.449048 2.587234 +1.442111 1.544212 1.938946 2.141876 2.494998 2.590164 +1.381730 1.579156 1.982000 2.138775 2.485780 2.620572 +1.361593 1.597812 1.964935 2.138121 2.542610 2.622470 +1.360664 1.614689 2.010781 2.161500 2.460448 2.583897 +1.390092 1.628646 1.963826 2.130557 2.477732 2.613382 +1.346169 1.648499 2.082367 2.321708 2.555952 2.649424 +1.440422 1.742439 2.007648 2.208244 2.450993 2.577906 +1.444825 1.695062 2.026868 2.210477 2.414028 2.532766 +1.345541 1.589166 1.955423 2.129306 2.409889 2.543165 +1.400043 1.481922 1.947067 2.110259 2.313164 2.531167 +1.384776 1.484787 1.983872 2.107142 2.360088 2.585480 +1.429185 1.514936 2.019660 2.137662 2.329551 2.585292 +1.450546 1.518321 2.010034 2.102797 2.401692 2.603278 +1.441363 1.525406 1.964971 2.076719 2.376014 2.594808 +1.464787 1.521553 1.968987 2.077867 2.444963 2.621082 +1.486696 1.573684 2.001845 2.108515 2.433771 2.626158 +1.471032 1.543603 1.991659 2.111714 2.473307 2.645459 +1.415271 1.524488 2.012703 2.095751 2.458820 2.642016 +1.407514 1.501486 2.050311 2.156204 2.480187 2.623271 +1.376118 1.459583 2.009938 2.169415 2.480196 2.642689 +1.345946 1.472883 2.073124 2.184863 2.486126 2.610362 +1.306365 1.438379 2.090496 2.213143 2.554203 2.683954 +1.219262 1.423037 2.090917 2.170494 2.559623 2.668211 +1.180469 1.408080 1.935170 2.088177 2.548134 2.639438 +1.209541 1.528929 1.887266 1.961882 2.483440 2.649342 +1.219923 1.521384 1.939175 1.988023 2.460034 2.673476 +1.198754 1.474098 1.859112 1.981042 2.395346 2.719202 +1.118408 1.504845 1.897944 2.002376 2.242870 2.598523 +1.018525 1.459894 1.746590 2.051954 2.324856 2.458848 +0.866990 1.387782 1.654105 1.799741 2.325792 2.407380 +0.862252 1.365828 1.705762 1.802245 2.416352 2.493849 +0.928394 1.546454 1.716680 1.877069 2.379724 2.524594 +1.083354 1.487338 1.801149 2.005692 2.321736 2.558733 +1.057425 1.339797 1.834422 1.934601 2.279625 2.530701 +0.954787 1.140996 1.792870 1.891796 2.342908 2.492038 +0.996853 1.130036 1.792153 1.895409 2.236238 2.403350 +0.920268 1.069492 1.874858 2.072086 2.335228 2.486570 +0.954214 1.081065 1.827324 2.079149 2.238820 2.508120 +0.894487 1.013841 1.716536 2.018446 2.175347 2.482241 +0.842005 0.979634 1.644526 1.945897 2.271025 2.438632 +0.955710 1.090003 1.754054 1.967070 2.127836 2.448885 +0.954385 1.094473 1.727553 2.005579 2.266567 2.514397 +1.025620 1.137605 1.787527 2.002076 2.336896 2.511839 +1.013813 1.175105 1.881936 2.016643 2.345862 2.445716 +1.082667 1.227297 1.923243 2.022783 2.402376 2.520967 +1.118115 1.224136 1.824448 1.961745 2.245832 2.515829 +1.146448 1.298991 1.872929 1.995465 2.371727 2.526896 +1.188552 1.310653 1.902213 1.996780 2.290374 2.520538 +1.309924 1.416529 1.878448 2.050089 2.224176 2.387793 +1.394764 1.506270 1.934888 2.056817 2.271193 2.453341 +1.377933 1.572642 1.990697 2.083570 2.381595 2.606523 +1.444019 1.689297 1.997464 2.153207 2.361127 2.507701 +1.515035 1.642770 1.929088 2.159339 2.335507 2.497838 +1.540079 1.708314 1.883825 2.094981 2.398624 2.570098 +1.600911 1.698511 1.881481 2.085171 2.451013 2.653738 +1.502633 1.756061 2.040722 2.163397 2.376168 2.548669 +1.532107 1.855341 1.993840 2.139554 2.302488 2.430987 +1.484859 1.822055 1.964302 2.135961 2.337023 2.472337 +1.536688 1.766917 1.951249 2.090524 2.324175 2.529206 +1.582282 1.723852 1.912068 2.069366 2.302944 2.473896 +1.499712 1.593288 1.912697 2.034098 2.366553 2.553790 +1.434200 1.540709 1.867569 1.989167 2.323715 2.539399 +1.189101 1.500824 1.763417 1.976198 2.137279 2.441179 +1.165922 1.470178 1.772997 1.927098 2.088007 2.304301 +1.250154 1.600421 1.818068 1.922113 2.080252 2.241814 +1.122694 1.628796 1.814409 1.932949 2.099304 2.418672 +1.019615 1.510656 1.850726 1.995621 2.130205 2.457063 +0.958176 1.639680 1.840433 1.956534 2.104283 2.279028 +1.010543 1.537512 1.772221 1.930517 2.101622 2.248506 +0.904371 1.505016 1.664330 1.827875 2.278031 2.348418 +1.067733 1.454537 1.686858 1.803459 2.384372 2.499789 +1.262873 1.516004 1.882748 1.975559 2.353571 2.519731 +1.560637 1.698959 1.921539 2.000060 2.540292 2.605234 +1.665625 1.744091 1.995924 2.104003 2.538942 2.620162 +1.615168 1.748503 2.024112 2.126056 2.408165 2.614133 +1.678025 1.752954 2.027903 2.146564 2.382374 2.568508 +1.580352 1.680273 1.997415 2.122458 2.459846 2.587827 +1.590082 1.692050 1.934784 2.095757 2.552980 2.625876 +1.539000 1.620243 1.920765 2.031604 2.481670 2.592695 +1.408796 1.511786 1.744250 1.896588 2.412019 2.515579 +1.320558 1.487993 1.754964 1.896907 2.437159 2.563184 +1.174869 1.524851 1.708181 1.962955 2.513779 2.581010 +1.287639 1.559567 1.903084 2.105175 2.450979 2.599458 +1.224033 1.507999 1.922793 2.076370 2.372907 2.581210 +1.163218 1.444961 1.734673 2.020179 2.322152 2.541566 +1.212255 1.448003 1.638494 2.031919 2.229345 2.399467 +1.108889 1.283327 1.481151 1.907068 2.100013 2.293484 +1.155218 1.290372 1.476717 1.688065 2.089220 2.181765 +1.171472 1.290390 1.556515 1.825992 2.018143 2.243494 +1.149886 1.282652 1.601900 1.745296 2.110780 2.409060 +1.223914 1.360718 1.650069 1.792936 2.265100 2.370934 +1.254374 1.404539 1.706674 1.854649 2.276473 2.394690 +1.225833 1.442107 1.766130 1.924123 2.292396 2.394677 +1.211141 1.461886 1.804549 1.927018 2.361986 2.453285 +1.218638 1.405782 1.809530 1.914204 2.318449 2.520048 +1.222942 1.394674 1.840107 1.932398 2.391674 2.503193 +1.206898 1.372866 1.842954 1.943799 2.424465 2.578763 +1.246306 1.423826 1.866209 1.962415 2.436055 2.595659 +1.270919 1.455901 1.888055 1.976335 2.469281 2.582811 +1.198265 1.323940 1.880236 1.949408 2.471659 2.644805 +1.174323 1.293200 1.765612 2.019282 2.282243 2.576238 +1.141730 1.383190 1.882826 2.126532 2.453044 2.611191 +1.483342 1.650728 2.043593 2.193798 2.517271 2.622915 +1.446069 1.621898 1.999609 2.103532 2.493478 2.581923 +1.414671 1.630237 1.945678 2.061773 2.500655 2.588950 +1.438432 1.615586 1.903350 2.013028 2.426105 2.613642 +1.556674 1.623119 1.875461 1.972308 2.366695 2.629218 +1.466504 1.638319 1.796576 1.959267 2.457617 2.603231 +1.308284 1.481394 1.730539 1.979266 2.332265 2.538090 +1.301646 1.413738 1.674441 1.933375 2.143487 2.508142 +1.318907 1.416559 1.751644 1.913438 2.294089 2.555125 +1.324509 1.425623 1.844923 1.947411 2.375384 2.597366 +1.266998 1.359728 1.849155 1.950839 2.370723 2.579301 +1.162697 1.344305 1.906935 1.986568 2.470580 2.583422 +1.115998 1.365829 1.948029 2.040077 2.461135 2.583597 +1.061798 1.350291 2.006280 2.080459 2.451632 2.526961 +1.024331 1.233571 1.989411 2.085049 2.387181 2.495816 +0.962287 1.219238 1.967000 2.089191 2.424659 2.599861 +0.881533 1.356828 2.047429 2.155394 2.409074 2.508754 +0.856010 1.217716 2.008528 2.111528 2.424806 2.537738 +0.774065 0.965055 1.874139 2.035878 2.251024 2.527966 +0.820344 0.990331 1.960958 2.242123 2.349553 2.535465 +0.846158 1.062894 1.972506 2.169152 2.353165 2.556086 +0.748812 1.063441 1.949952 2.066846 2.364509 2.602003 +0.855725 1.158383 2.008420 2.144140 2.328495 2.600481 +0.862076 1.188230 1.906456 2.191351 2.368506 2.542645 +0.814218 1.194007 2.086397 2.156864 2.482953 2.574777 +0.811087 1.320952 2.038259 2.112835 2.508878 2.598939 +0.967874 1.191718 2.049318 2.146525 2.422668 2.566778 +1.008026 1.234198 2.040908 2.121036 2.480150 2.609085 +1.118175 1.312265 1.961423 2.071245 2.409323 2.600531 +1.189338 1.302425 1.961961 2.063211 2.432115 2.545303 +1.253885 1.371226 1.931879 2.030140 2.387565 2.558949 +1.307301 1.398036 1.910989 2.006938 2.409438 2.577142 +1.330085 1.468465 1.908521 2.012222 2.418015 2.537683 +1.367992 1.492291 1.942021 2.036750 2.498866 2.581003 +1.368367 1.443433 1.947482 2.013180 2.486344 2.585241 +1.418284 1.496850 1.933442 2.024630 2.473682 2.594036 +1.443886 1.551220 1.904909 2.018103 2.456717 2.542868 +1.473689 1.587097 1.899829 2.079006 2.421501 2.584477 +1.424674 1.611334 1.974517 2.142720 2.402882 2.620760 +1.431487 1.622660 1.940232 2.125436 2.429652 2.581851 +1.484538 1.690581 1.921860 2.109101 2.474401 2.607828 +1.498136 1.751579 1.925730 2.039135 2.440519 2.616180 +1.505248 1.789182 1.994666 2.114126 2.408417 2.599889 +1.609869 1.793035 1.986226 2.160600 2.519572 2.593245 +1.562825 1.739913 1.974184 2.143221 2.539588 2.620088 +1.650259 1.723964 2.002949 2.150399 2.532100 2.600746 +1.584628 1.665482 1.833853 1.979658 2.511168 2.576182 +1.547562 1.665631 1.805111 1.930451 2.428670 2.548606 +1.499078 1.595123 1.700269 1.824190 2.376924 2.575480 +1.300837 1.552954 1.664576 1.791707 2.488304 2.561078 +1.168605 1.311953 1.668583 1.872905 2.413570 2.493285 +1.047458 1.249963 1.699886 1.914183 2.417032 2.496381 +0.948776 1.275594 1.738944 1.998684 2.312154 2.462020 +0.921081 1.311946 1.775244 1.895491 2.382160 2.528440 +0.811311 1.125217 1.745194 2.094737 2.326109 2.511883 +0.796518 1.060230 1.740129 2.060503 2.179506 2.385501 +0.868836 1.153353 1.792833 1.945638 2.125498 2.248001 +0.915536 1.218160 1.818910 2.068347 2.243402 2.348648 +0.966595 1.301606 1.895255 2.111957 2.248646 2.389247 +0.995849 1.442084 1.952071 2.066120 2.240125 2.338587 +1.056392 1.372214 1.984171 2.119327 2.271702 2.372743 +1.098400 1.324164 1.781533 2.082856 2.218804 2.344318 +1.039157 1.356474 1.820178 2.114625 2.346728 2.450389 +0.988689 1.293884 1.916348 2.088201 2.362497 2.481270 +1.104406 1.230679 1.939434 2.122401 2.254811 2.377705 +1.086105 1.174481 1.826346 2.111318 2.237689 2.471667 +1.069802 1.206486 1.845381 2.118634 2.471087 2.575405 +1.074963 1.342794 1.955309 2.147713 2.511467 2.589270 +1.149198 1.418813 1.887043 1.966968 2.472616 2.587246 +1.455749 1.669829 1.964104 2.175182 2.469990 2.605009 +1.418548 1.603566 1.964426 2.175678 2.466765 2.583333 +1.389392 1.601163 1.925746 2.131857 2.442025 2.574229 +1.415333 1.507338 1.911262 2.087139 2.535199 2.629580 +1.382483 1.453710 1.872292 1.955406 2.554343 2.658507 +1.392944 1.482296 1.838526 1.928577 2.473732 2.633718 +1.390456 1.463044 1.839906 1.922012 2.514942 2.698788 +1.339376 1.470118 1.858751 1.959522 2.539427 2.686382 +1.353776 1.541029 1.822546 2.022164 2.542215 2.677200 +1.350868 1.631877 1.918792 2.183528 2.501087 2.617310 +1.407644 1.669128 2.000740 2.224226 2.522804 2.634897 +1.433780 1.586913 1.999627 2.192922 2.535981 2.626121 +1.413876 1.639426 1.952196 2.170695 2.501106 2.610591 +1.505388 1.613685 1.991590 2.214459 2.487873 2.612841 +1.409245 1.563694 2.048043 2.154145 2.483727 2.642180 +1.411023 1.646699 1.983177 2.152550 2.568807 2.661248 +1.384745 1.603808 1.934487 2.141949 2.507642 2.630050 +1.366120 1.551337 1.999561 2.177467 2.489112 2.596761 +1.355542 1.635015 2.008420 2.162675 2.465273 2.661406 +1.453972 1.673697 2.037857 2.180201 2.615971 2.709278 +1.369538 1.696466 1.999789 2.084847 2.482775 2.666286 +1.349740 1.462313 1.966717 2.051722 2.472616 2.652615 +1.327312 1.437762 1.928517 2.006392 2.505810 2.658921 +1.341350 1.419153 1.921202 1.991463 2.530825 2.613585 +1.342697 1.505329 1.946926 2.029431 2.538224 2.635583 +1.392743 1.535099 1.936104 2.024567 2.527279 2.614258 +1.432564 1.543790 1.951854 2.049855 2.546244 2.623711 +1.452940 1.569432 1.932369 2.037247 2.558693 2.638096 +1.467999 1.597453 1.920306 2.018574 2.536219 2.622824 +1.486806 1.569654 1.875855 1.966065 2.536740 2.631905 +1.454618 1.578126 1.811620 1.974659 2.537513 2.606334 +1.418040 1.507665 1.783572 1.893001 2.551797 2.628991 +1.264140 1.474380 1.770586 1.898927 2.524762 2.594073 +1.118340 1.456671 1.734720 1.996589 2.412285 2.519146 +1.096432 1.603123 1.808391 2.012238 2.409620 2.544361 +0.976303 1.473740 1.759171 1.855828 2.412929 2.483947 +0.990184 1.390703 1.710711 1.831672 2.377092 2.454935 +1.056900 1.387366 1.783109 1.873514 2.401419 2.486425 +0.989786 1.452622 1.851566 1.945924 2.403454 2.482939 +1.112084 1.364820 1.770002 1.921998 2.290405 2.437297 +1.096250 1.336388 1.741855 1.968572 2.211613 2.362493 +1.000030 1.346185 1.704531 1.966852 2.277389 2.389374 +1.027901 1.174070 1.793005 2.026854 2.178200 2.387232 +1.056882 1.167504 1.861000 2.204421 2.351246 2.485631 +1.075972 1.226420 1.997644 2.196176 2.330099 2.494137 +1.147221 1.258128 1.958667 2.258550 2.387749 2.552119 +1.162811 1.290567 2.052795 2.201829 2.424621 2.560484 +1.147890 1.265733 2.025675 2.130794 2.496878 2.620259 +1.239563 1.315734 2.018377 2.123513 2.463946 2.569207 +1.181131 1.358942 1.942155 2.159833 2.458701 2.593961 +1.247455 1.386435 1.898250 1.999009 2.446020 2.542764 +1.227695 1.504889 1.817998 1.908019 2.213334 2.552228 +1.201972 1.577872 1.771276 1.873354 2.061263 2.535817 +1.306230 1.516310 1.819234 1.923423 2.382025 2.582568 +1.505719 1.585654 1.949330 2.046203 2.448307 2.615962 +1.623749 1.698728 2.009543 2.108007 2.461522 2.647903 +1.690861 1.764294 2.036097 2.175502 2.515253 2.616822 +1.715336 1.828294 2.078551 2.252209 2.483666 2.607649 +1.659970 1.807170 1.975009 2.255594 2.481341 2.589617 +1.734824 1.850216 2.012044 2.276744 2.519359 2.608181 +1.635768 1.862548 1.956456 2.328743 2.568869 2.632471 +1.616355 1.825398 1.949523 2.281216 2.560861 2.641804 +1.592472 1.804360 1.927158 2.167339 2.577510 2.646873 +1.606484 1.895095 1.983153 2.112452 2.477608 2.576959 +1.708493 1.835068 1.966711 2.127238 2.427571 2.543077 +1.691093 1.889580 1.986069 2.206774 2.522399 2.601798 +1.702442 1.902120 2.076380 2.216219 2.484843 2.603543 +1.329491 1.542588 1.875436 2.105532 2.385234 2.536630 +1.321384 1.474161 1.932268 2.152505 2.374420 2.506710 +1.277750 1.458580 1.963094 2.182377 2.417003 2.558654 +1.208016 1.418710 2.009739 2.138531 2.396782 2.554506 +1.198910 1.299925 1.983625 2.150128 2.296124 2.505944 +1.250344 1.361156 2.010558 2.195944 2.340984 2.500873 +1.308664 1.585162 2.106341 2.214164 2.402673 2.635894 +1.330165 1.494630 2.141901 2.235810 2.459582 2.649465 +1.296306 1.434105 2.098086 2.204131 2.355208 2.600113 +1.309619 1.402978 1.892542 2.184955 2.333605 2.513160 +1.269067 1.491839 1.958963 2.174572 2.324689 2.543667 +1.434975 1.628849 1.981273 2.247282 2.476397 2.593980 +1.459644 1.650080 2.024368 2.267723 2.546314 2.675203 +1.381486 1.703195 2.138905 2.295559 2.545762 2.642527 +1.441842 1.700585 2.197906 2.276293 2.468211 2.694954 +1.539669 1.999668 2.206532 2.351484 2.651231 2.734825 +1.589576 1.926407 2.173457 2.256196 2.633242 2.707677 +1.434262 1.859373 2.141950 2.211447 2.511783 2.628376 +1.326814 1.596573 2.024769 2.115813 2.426136 2.609340 +1.229072 1.325550 1.838698 2.013045 2.471300 2.639281 +1.230813 1.329059 1.872619 1.964510 2.444752 2.594694 +1.193705 1.426297 1.898594 2.039364 2.502714 2.581046 +1.175637 1.473287 1.912423 2.002740 2.476222 2.606851 +1.099269 1.443896 1.892457 1.997567 2.522081 2.611086 +1.113739 1.439098 1.912268 2.000476 2.462769 2.559343 +1.085510 1.469634 1.914465 2.064613 2.427917 2.512412 +1.052481 1.501205 1.918797 1.999794 2.493684 2.571708 +1.043597 1.331616 1.927947 1.989186 2.445730 2.578082 +1.051981 1.200390 1.938627 2.026811 2.446750 2.629884 +0.978672 1.083042 1.868777 2.133583 2.430141 2.580267 +0.904772 1.105214 1.960566 2.064948 2.362564 2.604875 +0.859439 1.084629 1.901705 2.033000 2.276166 2.574716 +0.948943 1.043554 1.855644 2.050857 2.444431 2.661478 +0.974338 1.126459 1.927321 2.020910 2.455487 2.559782 +0.995629 1.175887 1.937743 2.013680 2.378974 2.617290 +1.001312 1.224390 1.901702 1.976467 2.425878 2.574844 +0.985969 1.282601 1.886614 2.032451 2.455957 2.599528 +0.927590 1.320448 1.924006 2.012174 2.498308 2.599681 +1.007942 1.383963 1.921628 2.007624 2.507570 2.607500 +0.972512 1.446775 1.920365 2.013492 2.490207 2.576492 +0.951123 1.452036 1.889861 1.987269 2.421483 2.562217 +0.924342 1.369953 1.851744 1.942740 2.475661 2.544282 +0.882605 1.301666 1.850813 2.032498 2.364632 2.541824 +0.933888 1.368996 1.943109 2.023849 2.405442 2.530330 +0.927916 1.112379 1.847430 1.979093 2.255596 2.563992 +1.031936 1.249132 1.833165 1.925221 2.310315 2.520141 +0.934046 1.239886 1.909603 2.008149 2.372869 2.548965 +0.984297 1.220031 1.823788 1.947602 2.264359 2.478653 +0.933366 1.278980 1.860469 1.942999 2.289801 2.465670 +0.983115 1.227707 1.842104 2.047699 2.272651 2.531979 +0.953311 1.245822 1.849685 1.945142 2.289569 2.572282 +0.994609 1.303464 1.868144 1.971560 2.372435 2.585257 +0.986061 1.364094 1.852132 1.917821 2.435113 2.633873 +0.975486 1.248848 1.848797 1.934434 2.402023 2.574203 +1.008388 1.304679 1.804310 1.888508 2.369473 2.598230 +0.999393 1.329937 1.901438 1.994378 2.397503 2.504548 +0.922186 1.321538 1.851082 1.962056 2.382159 2.472985 +0.897224 1.382187 1.780842 1.921734 2.359590 2.448091 +0.859516 1.447371 1.732311 1.881193 2.295231 2.380849 +0.986347 1.601641 1.752386 1.966362 2.314384 2.459101 +1.265264 1.616535 1.811273 2.097139 2.371242 2.550361 +1.318958 1.600426 1.755641 2.029814 2.329188 2.493144 +1.209901 1.470135 1.670187 1.970732 2.416208 2.523420 +1.122232 1.308395 1.457114 1.720231 2.384259 2.470421 +1.077675 1.245511 1.366478 1.664281 2.327344 2.419196 +1.075445 1.228131 1.365376 1.558947 2.238585 2.324563 +1.044502 1.215785 1.325993 1.645187 2.148642 2.225749 +0.955863 1.150609 1.283133 1.492306 2.177576 2.266677 +0.909204 1.045108 1.166160 1.320593 2.215965 2.352846 +0.960368 1.103540 1.278352 1.467726 2.260152 2.460237 +1.010220 1.186777 1.290055 1.578425 2.388733 2.500317 +1.020144 1.135718 1.239343 1.388838 2.438182 2.563922 +1.082493 1.206954 1.347455 1.490039 2.404819 2.494617 +1.144114 1.278638 1.434725 1.567887 2.322768 2.424800 +1.274296 1.348789 1.515602 1.632221 2.360105 2.552789 +1.301328 1.390629 1.638492 1.764907 2.347961 2.576115 +1.358515 1.444452 1.724492 1.843715 2.478143 2.574552 +1.399712 1.513306 1.791713 1.902169 2.495815 2.581592 +1.448866 1.534750 1.821506 1.931492 2.517823 2.622859 +1.438398 1.530057 1.831437 1.999329 2.531929 2.623280 +1.511918 1.581087 1.927484 2.041399 2.573287 2.663469 +1.535380 1.608310 1.924231 2.048796 2.546746 2.681650 +1.544368 1.620413 1.980425 2.068130 2.477398 2.626652 +1.558461 1.643007 2.024613 2.121014 2.451868 2.639494 +1.524202 1.613947 2.005898 2.115477 2.429090 2.663085 +1.504519 1.590381 1.966356 2.072628 2.376901 2.621094 +1.439395 1.512336 1.950354 2.058564 2.276407 2.573036 +1.315215 1.400050 1.854752 1.957633 2.246197 2.576501 +1.288117 1.488904 1.945571 2.024839 2.439848 2.605685 +1.436278 1.667254 2.056847 2.146443 2.548238 2.661743 +1.417389 1.819841 2.083572 2.220278 2.606693 2.690863 +1.373599 1.963014 2.144565 2.274057 2.547389 2.638900 +1.320367 1.918635 2.063208 2.237723 2.415847 2.517654 +1.223778 1.619753 1.890594 2.107915 2.520999 2.629701 +1.018748 1.427668 1.917566 2.001782 2.435507 2.564351 +1.026252 1.377048 1.949170 2.039209 2.393769 2.530053 +1.009988 1.472847 1.998049 2.079876 2.484961 2.553950 +1.053267 1.468372 2.016120 2.129309 2.456623 2.564128 +1.101072 1.355268 2.010441 2.107467 2.395605 2.537748 +1.132796 1.391658 2.016574 2.114099 2.497623 2.585099 +1.173305 1.443009 1.970633 2.104863 2.447883 2.535937 +1.209478 1.384097 1.972240 2.069587 2.457494 2.573686 +1.242419 1.453561 1.983731 2.068419 2.471041 2.593609 +1.320388 1.463651 1.997825 2.082334 2.472034 2.605892 +1.389516 1.477732 1.978692 2.094038 2.480170 2.644445 +1.413743 1.526085 1.963751 2.113919 2.403846 2.654427 +1.519419 1.592852 1.919458 2.024494 2.301172 2.668892 +1.513663 1.600129 1.922007 2.105104 2.278322 2.523416 +1.481852 1.659944 1.913552 2.049439 2.272255 2.493787 +1.567545 1.659167 1.930647 2.071517 2.312595 2.564270 +1.550890 1.677657 1.863928 2.010128 2.223475 2.520007 +1.572772 1.683020 1.863047 2.002198 2.320378 2.560791 +1.621943 1.734050 1.920642 2.062932 2.335107 2.576252 +1.631487 1.697136 1.952883 2.056578 2.459627 2.652858 +1.594706 1.671490 1.936091 2.013301 2.430776 2.669632 +1.601444 1.668704 1.945495 2.037168 2.503369 2.682121 +1.587570 1.664898 1.944621 2.032989 2.569757 2.703408 +1.556417 1.631245 1.930707 2.040513 2.453873 2.665177 +1.487851 1.565634 1.892869 2.011729 2.393945 2.647118 +1.406012 1.520184 1.791646 1.987880 2.289334 2.602762 +1.358221 1.436040 1.818480 1.957084 2.309801 2.605784 +1.309339 1.405329 1.835697 2.076369 2.340807 2.613062 +1.303792 1.415614 1.985149 2.129488 2.469355 2.643119 +1.358952 1.437733 1.988826 2.127374 2.537981 2.656471 +1.333866 1.480460 1.950069 2.122437 2.431168 2.587133 +1.384528 1.539708 1.964093 2.130549 2.510449 2.652805 +1.412625 1.544436 1.947280 2.173185 2.593018 2.716637 +1.433269 1.539892 2.004125 2.201951 2.515051 2.635244 +1.447580 1.554019 2.128269 2.240167 2.470753 2.657077 +1.480647 1.609898 2.097964 2.167566 2.473701 2.700702 +1.607823 1.675959 2.023409 2.146384 2.426913 2.636247 +1.643303 1.717783 2.060655 2.197557 2.415413 2.614329 +1.737392 1.816967 2.039362 2.219707 2.422999 2.623531 +1.694258 1.799366 2.042600 2.280098 2.418626 2.583273 +1.556188 1.831866 1.985355 2.207899 2.471677 2.630819 +1.421150 1.803896 1.984581 2.123513 2.438200 2.522496 +1.327444 1.668870 1.888433 2.029945 2.224455 2.461746 +1.109824 1.562199 1.862663 1.977860 2.139552 2.328644 +1.233875 1.580797 1.854187 2.021788 2.193504 2.355917 +1.207537 1.568638 1.872908 1.986671 2.137938 2.487653 +1.179978 1.625946 1.900003 2.008135 2.231660 2.594349 +1.469842 1.717204 1.875670 2.024433 2.325463 2.488422 +1.641097 1.809779 1.926763 2.062053 2.414037 2.542900 +1.648803 1.734123 1.966905 2.086726 2.354475 2.498840 +1.605468 1.689394 2.010048 2.114211 2.407628 2.527066 +1.520887 1.628733 1.977005 2.086771 2.340162 2.489336 +1.503816 1.600587 2.039010 2.130377 2.396482 2.513742 +1.437817 1.545316 2.043931 2.188366 2.356821 2.521449 +1.445398 1.549208 1.982213 2.096659 2.328629 2.462126 +1.416417 1.504357 1.973772 2.080427 2.393479 2.543532 +1.425822 1.528083 1.995729 2.162530 2.440693 2.562510 +1.394274 1.473952 2.043537 2.149086 2.432979 2.549080 +1.373755 1.476048 2.043903 2.160251 2.345351 2.501882 +1.370183 1.443588 2.092872 2.178103 2.413056 2.590595 +1.320393 1.466374 2.036782 2.137812 2.435621 2.578912 +1.286926 1.393325 2.060733 2.200945 2.500015 2.582353 +1.323391 1.421794 2.058500 2.153930 2.495548 2.638088 +1.295313 1.393216 2.004420 2.138189 2.526374 2.641535 +1.230979 1.355132 2.047369 2.156418 2.522379 2.664129 +1.233755 1.308524 1.939495 2.097348 2.487349 2.649836 +1.227589 1.355101 1.875835 1.977538 2.319288 2.575191 +1.227369 1.507108 1.853515 2.022894 2.212431 2.576493 +1.152896 1.470513 1.830430 1.954309 2.331452 2.533253 +1.336656 1.650185 1.779214 2.043424 2.444821 2.539640 +1.455824 1.582937 2.022254 2.176680 2.481340 2.592664 +1.437625 1.556245 2.081454 2.174959 2.482445 2.614573 +1.416470 1.620886 2.033007 2.157073 2.462925 2.601588 +1.376304 1.551493 2.117213 2.198338 2.416190 2.605635 +1.442804 1.657855 2.127088 2.206301 2.344857 2.578113 +1.368110 1.538734 2.060199 2.198045 2.366884 2.622242 +1.346445 1.428338 1.980453 2.126605 2.283275 2.530611 +1.304592 1.373259 1.923523 2.096362 2.239964 2.508433 +1.298027 1.371594 1.954971 2.107512 2.349707 2.545570 +1.307177 1.416169 1.980337 2.064455 2.389102 2.588444 +1.279296 1.390782 1.959784 2.090687 2.436145 2.612606 +1.317020 1.415866 1.921874 2.071794 2.463821 2.616221 +1.294309 1.412297 1.916195 2.019201 2.484708 2.611341 +1.310051 1.407774 1.853169 2.009907 2.466493 2.645013 +1.341298 1.422330 1.885156 1.967813 2.483863 2.626324 +1.428263 1.526125 1.885115 1.978529 2.499386 2.603389 +1.501165 1.580511 1.847282 2.000494 2.465952 2.608868 +1.538510 1.625396 1.813916 1.950057 2.522899 2.620472 +1.566628 1.639602 1.771792 1.878749 2.541764 2.663693 +1.543435 1.647821 1.748616 1.822597 2.434677 2.631280 +1.623389 1.680917 1.759152 1.844539 2.521467 2.653611 +1.574857 1.663719 1.767780 1.869740 2.453335 2.658218 +1.558309 1.661251 1.793844 1.895130 2.261873 2.572330 +1.543680 1.627756 1.817671 1.921282 2.432997 2.653342 +1.493536 1.575657 1.805687 1.939448 2.470642 2.665081 +1.440050 1.513838 1.832212 1.937802 2.530248 2.702867 +1.319101 1.506232 1.823485 1.931612 2.539554 2.676703 +1.307271 1.563371 1.847930 1.951724 2.251818 2.453220 +1.336405 1.661596 1.828825 1.988331 2.189506 2.354248 +1.342922 1.598751 1.784739 1.915122 2.109991 2.450644 +1.336704 1.646363 1.800742 1.891215 2.235913 2.558506 +1.311763 1.500014 1.830220 1.945042 2.430387 2.644578 +1.266113 1.431962 1.858757 2.059148 2.590485 2.674762 +1.317779 1.419948 1.916462 2.124820 2.574729 2.668476 +1.341519 1.436167 1.968421 2.097444 2.572787 2.685098 +1.305930 1.438859 1.933746 2.036080 2.569070 2.656417 +1.279130 1.406473 1.943094 2.031719 2.530080 2.630882 +1.286005 1.410029 1.969688 2.040243 2.448573 2.651374 +1.257538 1.391063 1.966565 2.039208 2.402422 2.646794 +1.224386 1.352129 1.931370 2.006343 2.456203 2.696151 +1.296292 1.488099 1.996948 2.068189 2.594535 2.695842 +1.334566 1.607716 1.922141 2.163161 2.545921 2.679970 +1.381781 1.646772 2.037640 2.204087 2.545791 2.639326 +1.416818 1.628929 2.045931 2.209348 2.523853 2.675794 +1.431463 1.694802 1.998932 2.159531 2.522928 2.664749 +1.384236 1.622936 2.036943 2.115706 2.528893 2.633929 +1.403832 1.558362 2.027347 2.138015 2.562774 2.659379 +1.390591 1.671936 2.017942 2.164595 2.592820 2.683609 +1.357527 1.553759 2.023137 2.212306 2.420463 2.558257 +1.301715 1.465816 2.052932 2.215957 2.420685 2.548524 +1.339331 1.597053 2.035156 2.145819 2.509602 2.644137 +1.346088 1.633870 2.006920 2.114724 2.570026 2.688879 +1.358438 1.501669 1.949578 2.027633 2.479635 2.637460 +1.427991 1.533690 1.853629 1.960806 2.437544 2.588461 +1.507003 1.585812 1.864642 1.950265 2.478769 2.624546 +1.535154 1.619477 1.784602 1.926332 2.537152 2.665799 +1.499658 1.574823 1.685832 1.822553 2.533986 2.705306 +1.585485 1.642424 1.721846 1.846735 2.524494 2.710346 +1.167359 1.627213 1.768394 1.853039 2.265556 2.540517 +1.110320 1.506953 1.805632 1.881807 2.361271 2.589961 +1.066434 1.539420 1.746305 1.936119 2.127988 2.461181 +1.110995 1.565351 1.852078 1.960462 2.214924 2.497897 +1.116118 1.590687 1.879184 1.969081 2.323294 2.532966 +1.148401 1.557455 1.819964 1.963793 2.380344 2.484532 +1.092558 1.569815 1.784004 1.959241 2.324259 2.468490 +1.212996 1.578928 1.751637 1.901569 2.271773 2.386093 +1.123979 1.626268 1.758062 1.983762 2.291127 2.408000 +1.075785 1.534831 1.784777 2.041940 2.236695 2.368112 +1.118783 1.415693 1.971932 2.122755 2.330245 2.440458 +1.016087 1.334517 1.899204 2.121574 2.425143 2.543872 +1.066196 1.289419 1.948157 2.081946 2.471493 2.593822 +1.064989 1.255756 1.935973 2.036951 2.493176 2.612753 +1.049670 1.228450 1.829530 2.025060 2.431071 2.670840 +1.019627 1.313583 1.880313 1.953952 2.491693 2.642660 +1.153477 1.551900 1.909752 2.133530 2.540066 2.626465 +1.293030 1.600480 2.035687 2.166885 2.572967 2.658261 +1.409308 1.624144 1.993621 2.268493 2.527057 2.651858 +1.426397 1.681509 2.039405 2.215283 2.559060 2.681401 +1.422045 1.752644 2.027991 2.231432 2.546485 2.631238 +1.403067 1.735547 2.007077 2.202109 2.635543 2.718353 +1.364124 1.687363 2.011927 2.293629 2.640697 2.705256 +1.328058 1.608269 1.989851 2.364958 2.590564 2.689451 +1.333592 1.644867 2.130503 2.308577 2.644140 2.732807 +1.405236 1.665965 2.123365 2.315861 2.656941 2.732874 +1.435372 1.679544 2.019100 2.254404 2.596082 2.674056 +1.041025 1.476515 1.923322 2.290557 2.592337 2.673623 +0.818396 1.189747 2.051367 2.233382 2.417100 2.622567 +0.745703 1.240251 2.139256 2.224179 2.476418 2.558791 +0.786217 1.296744 2.004359 2.245816 2.548718 2.631400 +0.781573 1.122340 1.875748 2.277284 2.459421 2.557207 +0.697586 1.327149 2.097985 2.173556 2.574671 2.693605 +0.773107 1.393007 1.971171 2.270220 2.591495 2.651543 +0.799951 1.252666 1.928383 2.211233 2.577718 2.683817 +0.737528 1.237907 1.827160 2.110526 2.476303 2.627671 +0.896067 1.421355 1.841161 2.104821 2.432869 2.585719 +0.920446 1.418578 1.943416 2.252701 2.491235 2.623110 +0.905094 1.284731 1.843688 2.269109 2.479541 2.595905 +1.049549 1.447497 1.841173 2.160358 2.575747 2.655700 +1.282800 1.445416 1.901230 2.290173 2.581640 2.678726 +1.174710 1.517021 1.867926 2.176617 2.547483 2.640154 +1.241259 1.518496 1.936773 2.208770 2.521322 2.619833 +1.321929 1.540199 1.998528 2.205769 2.605663 2.707912 +1.303802 1.622926 1.880392 2.189485 2.588909 2.669966 +1.360827 1.658553 1.903323 2.178010 2.554280 2.634772 +1.385461 1.623312 1.959095 2.257739 2.605390 2.694616 +1.467954 1.628168 2.003097 2.348920 2.596096 2.674558 +1.411837 1.691393 1.947010 2.259218 2.526145 2.615112 +1.415256 1.697464 2.003104 2.284290 2.526236 2.643365 +1.365343 1.610187 2.022103 2.171703 2.557595 2.642236 +1.343948 1.630769 2.040836 2.261714 2.477921 2.647359 +1.333580 1.630378 2.031205 2.210871 2.504057 2.623327 +1.344121 1.704685 2.065813 2.192571 2.541365 2.658520 +1.439884 1.666588 2.082726 2.206006 2.636341 2.699174 +1.344355 1.655936 2.026852 2.227832 2.565868 2.661265 +1.299677 1.585295 1.961552 2.231139 2.599559 2.677599 +1.184434 1.441654 1.888542 2.255409 2.554664 2.625508 +1.446570 1.792548 2.022664 2.179214 2.497160 2.591115 +1.464682 1.809276 2.060194 2.205446 2.545963 2.641910 +1.481290 1.729523 2.025686 2.250012 2.537459 2.667746 +1.476458 1.657788 2.008062 2.249201 2.503220 2.613116 +1.386264 1.589548 2.031702 2.218301 2.509210 2.619100 +1.386263 1.662864 2.052585 2.208677 2.488387 2.623049 +1.438117 1.646070 1.967818 2.212439 2.508718 2.629395 +1.437599 1.590230 2.089082 2.184453 2.566546 2.677847 +1.367022 1.652527 2.084373 2.169492 2.483600 2.655744 +1.403779 1.701337 2.062797 2.148537 2.443186 2.657250 +1.399193 1.706047 2.062427 2.144585 2.531224 2.635014 +1.409664 1.750569 2.005073 2.087238 2.602834 2.694068 +1.430153 1.760399 2.048802 2.118059 2.569383 2.657275 +1.418847 1.858926 2.018666 2.141412 2.597867 2.671139 +1.515040 1.815611 1.942165 2.089059 2.554645 2.634597 +1.420031 1.740119 1.953746 2.196133 2.502692 2.639749 +1.384099 1.723309 1.901165 2.160196 2.426618 2.522583 +1.341050 1.737372 1.894752 2.110869 2.407505 2.502838 +1.375756 1.553983 1.784274 1.981423 2.504116 2.571526 +1.414589 1.520552 1.715365 2.013015 2.511199 2.608636 +1.384971 1.519108 1.696689 1.939377 2.575701 2.644752 +1.377861 1.611683 1.751236 2.044564 2.493605 2.567974 +1.360853 1.553679 1.693976 2.036113 2.535885 2.588469 +1.391629 1.489335 1.631480 1.853083 2.529546 2.631825 +1.364077 1.476053 1.629040 1.949019 2.525741 2.587922 +1.243896 1.398594 1.539687 2.066323 2.528653 2.592221 +1.255509 1.429357 1.548843 1.950985 2.519984 2.574845 +1.213331 1.388798 1.505976 1.886640 2.486118 2.545361 +1.125797 1.286903 1.534946 1.982051 2.490209 2.570684 +1.132522 1.296198 1.460831 1.925246 2.355670 2.444037 +1.146734 1.365341 1.496067 2.020613 2.448334 2.510650 +1.192778 1.378937 1.491161 1.959258 2.459140 2.519716 +1.271605 1.383883 1.525856 1.953206 2.473140 2.526275 +1.199948 1.366094 1.519729 1.926772 2.562989 2.623739 +1.236017 1.383510 1.510394 1.793300 2.585490 2.677079 +1.277218 1.416561 1.539447 1.923790 2.599080 2.667723 +1.195957 1.408063 1.568713 2.090793 2.622180 2.668897 +1.174436 1.300805 1.706567 2.070327 2.332828 2.490999 +1.120253 1.252790 1.562102 2.057117 2.357857 2.488099 +1.176325 1.291966 1.760265 2.093355 2.395545 2.591528 +1.197722 1.415532 1.801926 2.033180 2.459620 2.592560 +1.170462 1.491249 1.888044 2.082479 2.392285 2.528149 +1.083509 1.491779 1.949458 2.046197 2.422471 2.591609 +1.059936 1.417978 1.954816 2.073246 2.480964 2.599125 +0.939633 1.348507 2.005684 2.094229 2.474051 2.580294 +0.849679 1.293534 1.998123 2.105266 2.410101 2.615907 +0.886534 1.432349 1.990451 2.089797 2.379083 2.539500 +0.973462 1.473622 1.944390 2.051837 2.393100 2.468610 +1.041989 1.576432 1.952733 2.062536 2.326319 2.437768 +1.048696 1.543946 1.799024 2.015259 2.415911 2.487382 +1.060745 1.463281 1.792003 1.940494 2.417438 2.517618 +1.086879 1.350511 1.715443 1.804481 2.481994 2.577240 +1.237763 1.487227 1.724896 1.808323 2.528530 2.614554 +1.398461 1.499585 1.705939 1.817865 2.537422 2.611149 +1.461839 1.549278 1.719489 1.835184 2.480052 2.656622 +1.411934 1.594838 1.722617 1.840214 2.536598 2.618705 +1.527085 1.609472 1.704839 1.832817 2.512769 2.605081 +1.549304 1.649714 1.747183 1.838847 2.593282 2.681523 +1.408650 1.622130 1.797760 1.950766 2.238972 2.463941 +1.463558 1.647961 1.790731 1.921407 2.348044 2.572625 +1.531892 1.700373 1.834041 2.005597 2.413477 2.570542 +1.595204 1.681563 1.857023 2.020177 2.475381 2.620261 +1.578383 1.651863 1.912263 2.011994 2.512496 2.625607 +1.551105 1.644360 1.936207 2.041608 2.527321 2.617243 +1.531973 1.623150 1.927602 2.007454 2.528038 2.634563 +1.492463 1.579493 1.908682 1.998228 2.490609 2.583094 +1.445430 1.548758 1.913697 2.002797 2.519245 2.610948 +1.397285 1.482251 1.891220 1.983837 2.474487 2.607776 +1.358299 1.562942 1.902050 2.003614 2.425639 2.585407 +1.313352 1.518886 1.923066 2.011942 2.496939 2.583703 +1.321679 1.506830 1.903064 1.990064 2.510610 2.619736 +1.272893 1.513437 1.897901 2.039656 2.536517 2.604144 +1.255738 1.431150 1.896619 1.960886 2.526746 2.624236 +1.253559 1.392826 1.893788 1.975079 2.520685 2.596673 +1.212336 1.375220 1.860311 1.964962 2.531189 2.598668 +1.177442 1.324186 1.806632 1.885288 2.487316 2.595463 +1.184996 1.383080 1.783224 1.863469 2.466568 2.570648 +1.162268 1.444731 1.797884 1.960244 2.515838 2.594432 +1.293132 1.612625 1.912866 2.113069 2.467202 2.592647 +1.354402 1.698025 1.960114 2.149465 2.532985 2.652695 +1.412069 1.729124 2.034085 2.172945 2.538810 2.643693 +1.391792 1.801757 1.944790 2.194546 2.467300 2.547714 +1.476077 1.743192 1.982548 2.141155 2.559049 2.642891 +1.423680 1.857196 1.998407 2.146989 2.499501 2.583857 +1.420678 1.878169 2.012321 2.298282 2.578266 2.665489 +1.455663 1.910540 2.069836 2.393055 2.593493 2.679808 +1.525575 1.925713 2.186470 2.400715 2.660126 2.743114 +1.376147 1.633438 1.934297 2.250493 2.494057 2.618970 +1.354498 1.560950 1.931259 2.207320 2.500701 2.611053 +1.308071 1.569512 1.967243 2.245460 2.461123 2.595512 +1.347009 1.654983 1.980907 2.251887 2.510089 2.634977 +1.478008 1.588438 2.038202 2.224140 2.499366 2.646631 +1.451530 1.630286 2.114101 2.249734 2.416504 2.651801 +1.412137 1.655832 2.128349 2.224639 2.525056 2.681740 +1.374504 1.848893 2.140832 2.291897 2.602827 2.691005 +1.378568 1.744853 2.106673 2.201221 2.626831 2.711996 +1.082739 1.603117 2.070774 2.129571 2.504286 2.657551 +1.013288 1.467910 1.960032 2.091788 2.362049 2.561554 +0.994100 1.328068 1.791699 1.902549 2.410628 2.501324 +0.999159 1.325245 1.722310 1.871377 2.281177 2.502088 +1.035282 1.338082 1.653023 1.759760 2.441464 2.540672 +1.077126 1.293589 1.565666 1.711796 2.330341 2.436256 +1.058117 1.243026 1.488328 1.623677 2.330121 2.429536 +1.150659 1.296201 1.574724 1.701839 2.390475 2.507354 +1.167918 1.382035 1.573815 1.795297 2.440653 2.490361 +1.221368 1.405075 1.535783 1.728642 2.412290 2.519375 +1.248273 1.383975 1.572280 1.826858 2.425352 2.494218 +1.274149 1.386267 1.557821 1.734106 2.378306 2.477968 +1.343890 1.456032 1.668535 1.815600 2.248744 2.419705 +1.356022 1.559300 1.731279 1.853333 2.343968 2.514760 +1.433214 1.575906 1.673186 1.781463 2.292800 2.491264 +1.354708 1.637604 1.875368 2.162870 2.408490 2.566375 +1.464664 1.591442 2.071219 2.235462 2.398887 2.563489 +1.424812 1.622646 2.020332 2.161315 2.328264 2.468190 +1.364274 1.516152 2.011760 2.109608 2.395705 2.554722 +1.342677 1.460516 2.038898 2.122976 2.506655 2.643449 +1.338308 1.519884 2.030044 2.100145 2.533338 2.674767 +1.321127 1.545574 1.977232 2.122268 2.557592 2.680218 +1.315091 1.467109 1.972429 2.068538 2.526845 2.645634 +1.304457 1.400689 1.954545 2.053140 2.562504 2.685886 +1.267182 1.376660 1.888057 2.029893 2.545417 2.669311 +1.225012 1.339338 1.887320 1.965236 2.543506 2.672285 +1.226210 1.403527 1.797664 1.959693 2.540988 2.627346 +1.347025 1.607942 1.966769 2.184515 2.477879 2.608821 +1.332099 1.755961 1.948416 2.176713 2.513390 2.601370 +1.349288 1.781404 1.922794 2.109230 2.462878 2.559863 +1.362379 1.693594 1.884339 2.088053 2.522473 2.613966 +1.320290 1.510299 1.857749 2.065435 2.494726 2.605564 +1.282991 1.459743 1.744910 1.961419 2.439941 2.623746 +1.251365 1.381919 1.673542 1.772697 2.323540 2.661592 +1.204256 1.435153 1.654230 1.737800 2.305057 2.581558 +1.181960 1.465280 1.670027 1.861303 2.444123 2.546129 +1.347122 1.628258 1.931339 2.123429 2.466851 2.598918 +1.170479 1.284934 1.552741 1.832546 2.299787 2.519811 +1.190040 1.284015 1.646086 1.969170 2.496917 2.620449 +1.255411 1.381474 1.781732 2.094994 2.431362 2.593520 +1.231880 1.334167 1.796249 2.040002 2.387081 2.554655 +1.180520 1.308571 1.818239 1.976323 2.293501 2.451796 +1.102564 1.266319 1.844247 1.961761 2.324841 2.514083 +1.004636 1.144874 1.835019 1.997102 2.182380 2.522076 +0.956994 1.212915 1.940923 2.060449 2.312226 2.441670 +0.795434 1.444280 1.932418 2.047161 2.365680 2.450523 +0.942462 1.606038 2.025121 2.119735 2.299947 2.431814 +0.812186 1.469389 2.078323 2.173021 2.391967 2.474051 +0.831008 1.620609 2.092943 2.167732 2.334863 2.416721 +0.917049 1.800997 2.121233 2.199383 2.347284 2.440519 +0.857286 1.679152 2.112428 2.203072 2.444738 2.529211 +0.809582 1.542552 2.182369 2.239437 2.461979 2.543366 +0.912283 1.779198 2.166321 2.251092 2.461682 2.576876 +0.774827 1.770199 2.179196 2.239611 2.487323 2.560225 +1.222989 1.574575 2.081078 2.223587 2.501523 2.661302 +1.394216 1.696320 2.036647 2.273328 2.570400 2.684130 +1.370771 1.698913 2.082660 2.245671 2.598794 2.695446 +1.372406 1.647175 2.142373 2.272905 2.608093 2.686558 +1.342788 1.694536 2.123284 2.256762 2.575277 2.690952 +1.380553 1.750680 2.123405 2.199744 2.488043 2.610243 +1.395056 1.883317 2.088702 2.189488 2.458258 2.548140 +1.413151 1.872836 2.020835 2.161956 2.396167 2.487013 +1.403097 1.764242 1.911249 2.055851 2.391006 2.484601 +1.250592 1.606846 1.834805 1.914414 2.344090 2.549461 +1.171007 1.406438 1.699124 1.858102 2.354073 2.471053 +1.132691 1.251867 1.521350 1.638290 2.355284 2.470608 +1.011681 1.287897 1.450262 1.663822 2.285463 2.371452 +1.030244 1.208417 1.366673 1.550352 2.337520 2.421401 +0.964915 1.171185 1.288162 1.588419 2.327292 2.388297 +0.953674 1.102888 1.263755 1.835591 2.316855 2.424820 +0.886544 1.074635 1.242245 1.964445 2.296815 2.412946 +0.853009 1.077083 1.184534 1.752324 2.283038 2.389217 +0.840278 1.033222 1.152546 1.520954 2.333984 2.454533 +0.910770 1.083873 1.223537 1.668076 2.346235 2.511845 +0.967915 1.121818 1.220258 1.806588 2.421129 2.498176 +0.992265 1.169069 1.260049 1.679990 2.398939 2.459143 +1.065276 1.230957 1.322385 1.753477 2.314399 2.415925 +1.081305 1.271782 1.458008 1.729400 2.332304 2.405121 +1.017815 1.349087 1.515836 1.721892 2.292963 2.398991 +1.097652 1.332937 1.570030 1.776462 2.377274 2.465894 +1.147644 1.302495 1.640156 1.797044 2.363880 2.474795 +1.127168 1.322009 1.684884 1.796463 2.407050 2.578659 +1.159532 1.266652 1.709552 1.830584 2.438156 2.572425 +1.137105 1.331512 1.749399 1.846000 2.414391 2.511488 +1.121271 1.351105 1.728223 1.846664 2.449211 2.564158 +1.118680 1.261543 1.794458 1.885767 2.429009 2.552772 +1.076991 1.212163 1.727637 1.861263 2.432992 2.564041 +1.082093 1.261697 1.760917 1.858031 2.315851 2.573591 +1.086353 1.279061 1.763123 1.864186 2.380786 2.485297 +0.988401 1.262393 1.737901 1.836710 2.375780 2.492390 +1.074712 1.196202 1.677279 1.806309 2.341401 2.560642 +1.067864 1.265290 1.689350 1.802993 2.401947 2.524062 +1.010475 1.289540 1.652721 1.778727 2.362305 2.466551 +0.977570 1.261308 1.576271 1.741327 2.297622 2.404091 +1.097180 1.464421 1.606664 1.717614 2.330709 2.412068 +1.383838 1.652270 1.898203 2.096608 2.476719 2.574183 +1.279735 1.700611 1.894987 2.029873 2.468395 2.584491 +1.236668 1.683312 1.791059 1.953368 2.533100 2.587084 +1.185052 1.599131 1.853897 1.944925 2.499951 2.572896 +1.163573 1.307316 1.872443 1.953987 2.544667 2.623228 +1.190969 1.449255 1.863288 1.937666 2.525272 2.599969 +1.118547 1.513105 1.856666 1.968822 2.497385 2.575529 +1.156521 1.630926 1.845452 2.051106 2.443167 2.534052 +1.410042 1.541981 2.135508 2.235609 2.575406 2.680553 +1.392791 1.720666 2.034946 2.192456 2.487154 2.653398 +1.581248 1.837838 2.109761 2.187484 2.497898 2.660089 +1.663078 1.901302 2.151665 2.248289 2.534789 2.639793 +1.623160 1.843067 2.177770 2.255312 2.543601 2.681190 +1.539709 1.846069 2.119080 2.315024 2.605425 2.695012 +1.532691 1.805362 2.166180 2.276515 2.582080 2.695324 +1.517203 1.864729 2.111840 2.241033 2.602399 2.678593 +1.481004 1.879771 2.183398 2.258504 2.624580 2.714706 +1.480064 1.947829 2.126591 2.239313 2.602703 2.689760 +1.615747 2.025678 2.188405 2.291472 2.673701 2.723276 +1.546688 2.023668 2.137583 2.233880 2.563573 2.627361 +1.517274 1.902434 2.132410 2.189277 2.548379 2.643352 +1.498762 1.602359 2.159933 2.275665 2.540579 2.682962 +1.573572 1.655201 2.071740 2.214602 2.523447 2.642142 +1.601993 1.680362 2.130147 2.247308 2.567706 2.670568 +1.632928 1.733671 2.134699 2.255127 2.559994 2.682076 +1.707428 1.752059 2.139704 2.252060 2.567637 2.647910 +1.680790 1.812582 2.189235 2.287297 2.578245 2.644737 +1.746130 1.778548 2.119511 2.283392 2.596379 2.686826 +1.680242 1.774944 2.097848 2.213994 2.558507 2.656276 +1.698158 1.777690 2.096918 2.211009 2.512421 2.625627 +1.757218 1.828197 2.092183 2.218630 2.459897 2.653906 +1.768299 1.815758 2.044601 2.174404 2.469800 2.674385 +1.740913 1.830010 2.044499 2.168426 2.442501 2.587668 +1.728988 1.801586 2.036902 2.135694 2.483000 2.647346 +1.740200 1.780349 2.039841 2.116482 2.460078 2.666408 +1.679167 1.810585 1.976200 2.085150 2.330970 2.574697 +1.675383 1.741676 1.986605 2.086988 2.444839 2.648385 +1.605366 1.684640 1.977146 2.084309 2.401376 2.626669 +1.593589 1.667011 1.993079 2.095793 2.477055 2.660517 +1.495436 1.677492 1.915438 2.107516 2.504100 2.687519 +1.371193 1.581007 1.812088 2.159971 2.540808 2.654514 +1.308897 1.652762 1.877696 2.100223 2.498357 2.635266 +1.257546 1.701192 1.908659 2.063978 2.330876 2.588480 +1.260641 1.733829 1.901311 2.046022 2.230421 2.379709 +1.192017 1.695443 1.866332 1.969861 2.131279 2.367813 +1.331300 1.727619 1.875686 1.967226 2.115488 2.461652 +1.221851 1.644785 1.861070 1.957289 2.263788 2.509227 +1.297010 1.684814 1.825106 1.981266 2.388696 2.497940 +1.292992 1.621691 1.795497 1.891584 2.430941 2.597238 +1.293338 1.412441 1.678427 2.013436 2.406265 2.575295 +1.355250 1.470521 1.748288 2.044830 2.411070 2.590823 +1.352085 1.474384 1.811950 2.028535 2.445376 2.597977 +1.380432 1.472981 1.836191 1.957768 2.390372 2.571170 +1.417568 1.514975 1.839991 1.974610 2.382486 2.510706 +1.396329 1.511621 1.743909 2.009524 2.414088 2.533502 +1.355999 1.511197 1.775041 1.973539 2.445398 2.568851 +1.357482 1.533305 1.820633 1.998326 2.395457 2.573696 +1.244544 1.446552 1.726849 1.935995 2.428985 2.555947 +1.206555 1.365874 1.510017 1.809039 2.464853 2.520241 +1.204707 1.340270 1.477154 1.731800 2.461076 2.525822 +1.152135 1.294762 1.429873 1.669780 2.436091 2.504828 +1.122329 1.284669 1.445441 1.811897 2.444467 2.535691 +1.167102 1.311995 1.430682 1.931216 2.579180 2.626367 +1.140963 1.255562 1.416924 1.913114 2.462643 2.552650 +1.175380 1.325094 1.434137 1.826282 2.534111 2.599692 +1.152952 1.311344 1.428753 1.733281 2.499163 2.555417 +1.208942 1.318147 1.450855 1.631131 2.484793 2.560756 +1.214984 1.312305 1.496973 1.602685 2.441060 2.513740 +1.154899 1.274352 1.497828 1.611080 2.493972 2.628464 +1.221737 1.324479 1.529355 1.668502 2.496342 2.572455 +1.265483 1.360436 1.574447 1.698291 2.465872 2.529454 +1.299969 1.411470 1.634331 1.790167 2.464188 2.546209 +1.296816 1.461296 1.674047 1.867297 2.472828 2.546532 +1.319231 1.493029 1.702922 1.867177 2.417583 2.503853 +1.307703 1.511731 1.795464 1.988697 2.415827 2.502063 +1.341439 1.567295 1.849636 2.054411 2.368545 2.484938 +1.346092 1.709857 1.847822 2.089875 2.320388 2.426929 +1.351207 1.582397 1.853947 2.087781 2.269740 2.406134 +1.403409 1.681258 1.930634 2.064741 2.317595 2.445510 +1.303563 1.800429 1.946546 2.064780 2.347899 2.575654 +1.401968 1.795117 2.043851 2.149158 2.337423 2.475421 +1.486349 1.896915 2.033679 2.164583 2.427213 2.516709 +1.581223 1.920360 2.032925 2.186636 2.458825 2.534175 +1.623672 1.949219 2.056949 2.220873 2.544733 2.612737 +1.720081 1.916335 2.069658 2.310061 2.503085 2.592652 +1.652066 1.993905 2.122170 2.282322 2.533728 2.604129 +1.696384 1.990268 2.088659 2.317899 2.562346 2.630795 +1.688613 1.976549 2.085500 2.354425 2.483404 2.567677 +1.791891 1.956617 2.084765 2.344129 2.473213 2.578020 +1.770146 1.955967 2.075143 2.263105 2.508576 2.594808 +1.688172 1.958387 2.097165 2.237127 2.443133 2.558386 +1.614095 1.858106 1.996129 2.151245 2.327315 2.485345 +1.517662 1.729778 1.975388 2.118726 2.390828 2.523423 +1.576388 1.764916 1.937347 2.159436 2.354537 2.476553 +1.596523 1.796717 1.930679 2.173774 2.415264 2.515193 +1.598274 1.758907 1.941525 2.242941 2.461919 2.548378 +1.564588 1.667806 1.910211 2.207508 2.432969 2.562295 +1.502258 1.598757 1.701036 1.993517 2.431658 2.568611 +1.261165 1.379257 1.669436 1.864259 2.424394 2.560278 +1.183142 1.291685 1.496242 1.775091 2.415349 2.571850 +1.176858 1.280643 1.397295 1.556275 2.482609 2.556911 +1.151406 1.269090 1.402613 1.529417 2.547298 2.660723 +1.138350 1.270088 1.386698 1.656508 2.516680 2.570828 +1.167637 1.288387 1.379397 1.815954 2.488744 2.544025 +1.191129 1.318584 1.433056 1.898734 2.440995 2.505523 +1.231547 1.339710 1.505832 1.865461 2.401919 2.567552 +1.249001 1.342543 1.526521 1.644629 2.260060 2.528113 +1.292116 1.385043 1.567293 1.928018 2.343597 2.526727 +1.553055 1.731196 1.875584 2.037623 2.189580 2.433617 +1.556332 1.807351 2.009873 2.134758 2.395110 2.517757 +1.700800 1.862996 2.016062 2.212872 2.465828 2.576608 +1.744516 1.892300 2.042875 2.203697 2.393022 2.529386 +1.614682 1.867043 2.024132 2.172368 2.402152 2.567866 +1.662548 1.926469 2.016222 2.153675 2.544682 2.636605 +1.607737 1.840632 2.036507 2.148869 2.475726 2.623423 +1.542603 1.789412 1.988210 2.133702 2.500071 2.623838 +1.520491 1.854019 1.966284 2.100229 2.465497 2.590987 +1.429100 1.726203 1.958566 2.068736 2.397125 2.578275 +1.230963 1.483915 1.909424 2.037168 2.278162 2.442677 +1.165473 1.402475 1.877668 1.985029 2.337001 2.482301 +1.060649 1.341795 1.891591 1.997803 2.342252 2.473851 +1.045982 1.264410 1.892878 2.028108 2.265711 2.418342 +0.872467 1.318607 1.941288 2.054895 2.265976 2.523000 +0.878165 1.208778 1.863524 2.074171 2.319885 2.460496 +0.871380 1.050930 1.866310 2.044293 2.184267 2.469225 +0.814866 1.206234 1.936241 2.046364 2.243986 2.391005 +0.791495 1.154802 1.950862 2.062225 2.270188 2.497120 +0.734873 1.117496 2.013891 2.146348 2.252079 2.340218 +0.717596 1.113315 2.145116 2.214288 2.350660 2.437091 +0.747897 1.181886 1.982640 2.073387 2.391063 2.461216 +0.814210 1.593704 1.930814 2.051889 2.279916 2.450975 +1.007998 1.635254 1.848698 1.998294 2.264960 2.399367 +1.058125 1.548258 1.725115 1.885874 2.174154 2.386746 +1.065325 1.446828 1.763113 2.061160 2.393931 2.533355 +1.245436 1.513106 1.699869 1.885972 2.163732 2.412556 +1.402218 1.550167 1.679097 2.104476 2.314265 2.464617 +1.439688 1.565541 1.746159 2.175756 2.353179 2.445969 +1.282789 1.467574 1.689789 2.057017 2.299566 2.506538 +1.157513 1.360077 1.531522 1.931682 2.277828 2.387362 +1.127719 1.287186 1.421085 1.844362 2.281074 2.385221 +1.172511 1.317506 1.497831 1.768329 2.327099 2.453399 +1.215615 1.351452 1.554622 1.706859 2.280267 2.410315 +1.162714 1.318505 1.568816 1.757107 2.225559 2.321236 +1.221146 1.364069 1.728202 1.867240 2.149636 2.323430 +1.274525 1.455876 1.651807 1.929882 2.119518 2.245371 +1.324827 1.466657 1.837727 1.982753 2.167839 2.294890 +1.207408 1.463737 1.907228 2.010942 2.187613 2.315377 +1.197505 1.325369 1.903945 2.104257 2.264375 2.406017 +0.964658 1.421326 1.800591 2.075541 2.249667 2.391422 +0.900184 1.419486 1.860531 2.052169 2.204670 2.414730 +0.976462 1.444988 1.837158 1.997086 2.133567 2.303194 +0.943062 1.543803 1.914625 1.993134 2.184650 2.344182 +0.896780 1.426973 1.923545 2.039994 2.257922 2.504524 +0.957615 1.553177 1.862682 2.044650 2.192655 2.484166 +1.024381 1.626871 1.891283 2.041787 2.304775 2.613132 +1.260699 1.570977 1.796922 1.938909 2.457980 2.543689 +1.433872 1.676893 2.020354 2.249287 2.488434 2.619226 +1.427791 1.605308 1.999841 2.197618 2.472581 2.628257 +1.344936 1.547750 2.019906 2.153463 2.482519 2.664904 +1.394553 1.830863 2.075753 2.146704 2.529848 2.662938 +1.393531 1.579984 2.005267 2.068322 2.595828 2.677955 +1.371670 1.501665 2.012362 2.069292 2.605716 2.701205 +1.365970 1.443760 1.893696 2.063362 2.540864 2.635754 +1.392813 1.470933 1.920415 1.985276 2.612047 2.670626 +1.393576 1.502340 1.926492 2.019514 2.571540 2.645701 +1.331438 1.470056 1.844344 1.945539 2.527331 2.620827 +1.280394 1.379998 1.822792 1.927676 2.470720 2.614037 +1.230446 1.394851 1.772237 1.910697 2.494879 2.569172 +1.103766 1.420997 1.742156 1.901028 2.458527 2.544960 +1.070834 1.438456 1.754789 1.827791 2.323725 2.484121 +1.023924 1.522342 1.713716 1.834742 2.289596 2.496846 +1.123843 1.539945 1.766275 1.866623 2.349980 2.441218 +1.046667 1.496581 1.791535 1.859477 2.400747 2.468296 +1.031227 1.504904 1.714267 1.944348 2.365219 2.459437 +1.201184 1.370120 1.882630 2.011333 2.411295 2.510294 +1.249461 1.324457 1.907616 2.059001 2.448619 2.551408 +1.308584 1.403015 1.961155 2.048592 2.475709 2.562469 +1.354357 1.476040 2.008730 2.111323 2.513237 2.591557 +1.415309 1.559632 2.020191 2.107847 2.505348 2.596462 +1.452150 1.536961 2.033461 2.120472 2.473458 2.600239 +1.476159 1.570668 1.981439 2.089874 2.441733 2.574939 +1.532138 1.607322 1.996255 2.099111 2.448993 2.575083 +1.578251 1.670901 1.946452 2.067931 2.484573 2.596033 +1.645992 1.719829 1.908426 2.034805 2.521504 2.630135 +1.675204 1.739089 1.858009 1.951150 2.549621 2.668138 +1.698801 1.740674 1.816221 1.872214 2.552990 2.675039 +1.589313 1.665941 1.751972 1.834254 2.495821 2.663916 +1.443571 1.535057 1.685496 1.788025 2.391781 2.644852 +1.389394 1.597558 1.884291 2.161052 2.453631 2.577281 +1.344693 1.573396 1.949051 2.033207 2.436483 2.650227 +1.340679 1.442192 1.904082 1.992387 2.427510 2.604339 +1.301569 1.363519 1.870210 1.953388 2.445808 2.609366 +1.265637 1.365516 1.838660 1.922174 2.431739 2.552480 +1.291868 1.451067 1.770742 1.900677 2.380488 2.474590 +1.319797 1.502062 1.686208 1.922008 2.291200 2.392613 +1.253224 1.445797 1.591748 1.893558 2.295028 2.381503 +1.171375 1.370630 1.523209 1.825821 2.336350 2.399182 +1.238986 1.365086 1.486833 1.790131 2.302513 2.384222 +1.186490 1.327527 1.463687 1.680778 2.322037 2.402246 +1.160765 1.294904 1.467635 1.613241 2.219663 2.329651 +1.167970 1.312269 1.458793 1.725469 2.182513 2.270653 +1.160491 1.371381 1.546645 1.859914 2.151480 2.267109 +1.060643 1.447736 1.589363 1.762026 2.187949 2.312538 +1.096873 1.449372 1.669939 1.880786 2.205157 2.322919 +0.965471 1.394985 1.664859 1.869740 2.130135 2.272101 +0.992815 1.276232 1.736324 1.883127 2.198488 2.291947 +0.989087 1.348989 1.869284 1.945029 2.217100 2.329616 +0.905850 1.296468 1.839413 1.984491 2.131357 2.261643 +0.913468 1.347104 1.974941 2.056808 2.233065 2.312403 +0.891335 1.518146 1.956057 2.017051 2.234247 2.369537 +0.838007 1.490697 2.017641 2.097784 2.331456 2.417972 +0.918242 1.411219 2.047094 2.157938 2.312207 2.414304 +0.737470 1.475335 2.131705 2.195099 2.336065 2.410088 +0.804454 1.247009 2.183193 2.253103 2.376866 2.457474 +0.910989 1.120584 2.031279 2.134740 2.301672 2.401323 +0.823657 1.023714 1.899299 2.153486 2.278157 2.468898 +0.820197 0.968457 1.655670 2.137310 2.320413 2.442552 +0.901009 1.047635 1.785794 2.126322 2.248142 2.419219 +0.908944 1.151536 1.941268 2.153759 2.287775 2.477861 +1.022921 1.329810 1.973526 2.121196 2.269160 2.496929 +1.008035 1.176565 1.832554 2.130737 2.263094 2.484071 +1.148404 1.261617 1.868165 2.138339 2.287914 2.475774 +1.131641 1.245536 1.746902 2.127206 2.273644 2.439518 +1.105449 1.230686 1.759865 2.023222 2.225896 2.485020 +1.232277 1.363476 1.914876 2.021647 2.314039 2.455927 +1.287966 1.377464 1.853658 2.039634 2.348077 2.502708 +1.285144 1.520789 1.951021 2.053636 2.366537 2.486110 +1.276358 1.656613 1.882329 2.084625 2.430619 2.524004 +1.305701 1.532539 1.861534 2.029161 2.435632 2.519577 +1.295725 1.474840 1.838375 2.045012 2.413018 2.545296 +1.232802 1.307215 1.786758 1.911450 2.533633 2.625793 +1.106012 1.252432 1.737311 1.827401 2.395470 2.658026 +1.080321 1.249736 1.763810 1.842229 2.488083 2.637970 +1.084809 1.302696 1.791104 1.915712 2.532753 2.626979 +1.024077 1.398495 1.758154 1.947685 2.536753 2.647797 +1.052552 1.486524 1.835972 2.013128 2.526539 2.621519 +0.980943 1.528894 1.887706 1.990429 2.559226 2.631730 +0.954706 1.355188 1.890849 1.968743 2.538301 2.645803 +0.894853 1.316420 1.931923 2.000630 2.617822 2.706960 +0.859848 1.166660 1.851854 2.011085 2.629872 2.731061 +0.817565 1.169139 1.975684 2.117069 2.593136 2.683713 +0.776768 0.999874 1.951669 2.126997 2.578530 2.719218 +0.750075 1.105669 2.015241 2.099156 2.469178 2.637879 +0.878438 1.039620 2.078822 2.189100 2.453168 2.610618 +0.915136 1.114879 2.017689 2.236527 2.370275 2.538277 +0.826110 1.208983 2.069074 2.156825 2.331864 2.463067 +0.869876 1.289563 2.061703 2.143050 2.313737 2.395809 +0.790056 1.421058 1.945728 2.025231 2.254924 2.384106 +0.782642 1.678142 1.928308 1.980152 2.169702 2.290020 +0.795940 1.409661 1.767797 1.894756 2.191648 2.280190 +0.832117 1.169093 1.828013 1.911028 2.228646 2.366162 +0.862231 1.189399 1.754948 1.924129 2.312126 2.412551 +1.034774 1.290469 1.783502 1.996158 2.343760 2.462730 +1.135806 1.358791 1.789192 1.980630 2.376359 2.495841 +1.303901 1.414996 1.787505 1.918440 2.435463 2.547746 +1.489246 1.592963 1.850578 1.950051 2.428039 2.571337 +1.631472 1.742640 1.887885 1.994933 2.493769 2.619665 +1.683853 1.800379 1.926611 2.064050 2.509149 2.592626 +1.745313 1.854259 1.988545 2.117137 2.504306 2.611340 +1.764270 1.890575 2.037993 2.174299 2.507724 2.600610 +1.680174 1.817366 1.937110 2.228976 2.550139 2.623314 +1.552625 1.819462 1.957322 2.263495 2.517281 2.580506 +1.558425 1.784912 2.021491 2.239374 2.543712 2.637456 +1.240665 1.739293 1.889814 2.105082 2.532436 2.618228 +0.928972 1.440269 1.769258 1.853352 2.400406 2.636877 +1.055767 1.488842 1.756065 1.832574 2.209682 2.650309 +1.013301 1.381032 1.704087 1.772713 2.155486 2.585135 +1.009186 1.333235 1.741382 1.846496 2.158765 2.517761 +1.006381 1.519900 1.813751 1.916290 2.407674 2.581853 +1.357730 1.530547 1.883639 2.141513 2.463268 2.614627 +1.426823 1.560875 1.882518 2.175206 2.488354 2.628703 +1.315984 1.579838 1.859556 2.083481 2.419884 2.564645 +1.213050 1.538899 1.800250 1.882067 2.341570 2.574606 +1.275056 1.543507 1.917099 2.127451 2.388939 2.542721 +1.438943 1.698143 1.856610 2.075189 2.266712 2.437372 +1.454331 1.663763 1.869820 2.011414 2.366272 2.533385 +1.382166 1.672920 1.827442 1.942032 2.453906 2.559856 +1.400656 1.585453 1.841334 2.002744 2.426997 2.517756 +1.382144 1.688087 1.819756 2.063153 2.417793 2.492551 +1.255095 1.603378 1.753915 2.047569 2.455562 2.569585 +1.134783 1.409147 1.705283 1.802106 2.488030 2.647140 +1.111876 1.260129 1.676050 1.778495 2.501588 2.627003 +1.060347 1.208811 1.660354 1.776864 2.488758 2.604456 +0.947120 1.164647 1.642037 1.723789 2.475156 2.567411 +0.902077 1.251204 1.664026 1.769008 2.499003 2.576704 +0.920170 1.243894 1.709681 1.794989 2.534352 2.623833 +0.938770 1.267684 1.725861 1.870157 2.549512 2.628197 +0.914357 1.254315 1.712915 1.784742 2.590431 2.707485 +0.930246 1.281241 1.802793 1.878861 2.560218 2.687216 +0.955350 1.148671 1.814732 1.902586 2.557821 2.684594 +0.968330 1.098589 1.813440 1.911875 2.463136 2.646490 +0.990311 1.185444 1.864673 1.941589 2.488112 2.664465 +1.186903 1.590929 1.954158 2.033697 2.597861 2.662179 +1.302643 1.694423 1.997444 2.169046 2.617414 2.693079 +1.379258 1.718278 1.993219 2.212202 2.543730 2.640859 +1.405165 1.780534 1.997893 2.151147 2.555776 2.632215 +1.297766 1.878255 2.020268 2.190566 2.546467 2.617338 +1.442158 1.856645 2.101038 2.299709 2.561481 2.644123 +1.370167 1.781207 2.114991 2.251821 2.446751 2.549845 +1.403451 1.703568 2.079302 2.221399 2.448766 2.593978 +1.413349 1.649169 2.009976 2.159164 2.518675 2.615138 +1.326655 1.719941 1.950443 2.025468 2.521068 2.635953 +1.385954 1.552749 1.856784 1.937506 2.496646 2.580159 +1.345409 1.488014 1.885538 2.017189 2.546874 2.625597 +1.335716 1.420210 1.787067 1.976842 2.501334 2.643553 +1.303803 1.408266 1.801454 1.901471 2.375048 2.575946 +1.312907 1.408086 1.837981 1.950093 2.318536 2.475897 +1.193613 1.293642 1.819061 1.974492 2.468077 2.585285 +1.191527 1.311470 1.711629 1.854585 2.395044 2.554024 +1.103176 1.332165 1.717922 1.857994 2.340287 2.445217 +0.996011 1.234172 1.751022 1.868274 2.285877 2.406723 +1.055311 1.378240 1.712116 1.841673 2.206702 2.440537 +1.078611 1.465910 1.787009 1.948977 2.231741 2.478981 +0.984520 1.420593 1.815304 1.925218 2.263433 2.430940 +0.984574 1.495178 1.774189 1.964126 2.221656 2.346849 +1.154842 1.507200 1.812101 1.949371 2.281741 2.426097 +1.170058 1.429376 1.745091 1.937927 2.235016 2.374769 +1.206485 1.487526 1.767298 2.009836 2.207048 2.339471 +1.073656 1.377733 1.828679 1.993004 2.130615 2.256776 +1.088454 1.495385 1.907767 1.996871 2.213903 2.390489 +1.122976 1.422213 1.865827 2.037113 2.253747 2.418388 +1.134166 1.382636 1.804236 1.963200 2.161170 2.473602 +1.245397 1.552607 1.960811 2.134690 2.453597 2.577539 +1.118704 1.567208 1.952615 2.176519 2.446630 2.578556 +1.141708 1.643603 2.013339 2.277434 2.557381 2.634785 +1.392514 1.807925 2.039343 2.237922 2.578023 2.668286 +1.433212 1.833712 2.020620 2.252182 2.518635 2.600857 +1.379262 1.712226 2.024999 2.242965 2.515533 2.602479 +1.366984 1.675637 1.976590 2.199474 2.516967 2.598815 +1.352760 1.801872 2.033607 2.181935 2.491382 2.589883 +1.323663 1.743572 2.009640 2.122701 2.474517 2.566379 +1.190092 1.540538 1.933066 2.088076 2.506726 2.570608 +1.519832 1.766187 1.906004 2.076747 2.261416 2.407680 +1.534691 1.714074 2.016476 2.130902 2.323259 2.457608 +1.522050 1.794760 2.050945 2.218278 2.408013 2.537728 +1.665365 1.906867 2.025658 2.232383 2.430131 2.550641 +1.666299 1.834650 1.998042 2.220240 2.401507 2.502391 +1.523608 1.730092 1.862962 2.164599 2.466262 2.549229 +1.216124 1.503465 1.760462 1.967473 2.381720 2.564350 +1.171128 1.429428 1.616628 1.917782 2.387933 2.477271 +1.091303 1.351374 1.568657 1.796196 2.437587 2.514874 +1.001277 1.386906 1.539603 1.775045 2.413270 2.482152 +0.952227 1.397307 1.527926 1.722524 2.442747 2.492370 +0.824979 1.388886 1.568976 1.735264 2.408751 2.471180 +0.794444 1.433059 1.588848 1.749579 2.489366 2.576364 +0.899067 1.521851 1.681397 1.780293 2.441748 2.508286 +0.922249 1.464613 1.592525 1.828442 2.418162 2.477264 +0.871556 1.444421 1.538321 1.889009 2.353691 2.412544 +0.857823 1.270248 1.501265 1.760257 2.355761 2.407297 +0.846263 1.176606 1.481984 1.614166 2.369933 2.485687 +0.882414 1.176092 1.377969 1.497390 2.380010 2.516508 +0.938718 1.100648 1.489109 1.576205 2.325566 2.543468 +0.932462 1.105586 1.294346 1.470956 2.400120 2.554718 +0.945253 1.161000 1.303877 1.580262 2.466680 2.584612 +1.018317 1.214740 1.330580 1.683749 2.482961 2.557157 +1.048240 1.175481 1.258095 1.599087 2.521448 2.642499 +1.073739 1.203513 1.298705 1.688758 2.555683 2.614473 +1.096788 1.260856 1.368595 1.755340 2.493034 2.606453 +1.105643 1.227026 1.404391 1.849702 2.523314 2.601568 +1.143864 1.269393 1.387340 1.829083 2.395167 2.496463 +1.099246 1.228614 1.344408 1.664420 2.440626 2.518066 +1.116181 1.228322 1.332947 1.667312 2.331673 2.512262 +1.201517 1.299388 1.478475 1.577915 2.003307 2.451583 +1.167995 1.292729 1.470730 1.814621 2.140965 2.436146 +1.280521 1.424881 1.595211 1.803880 2.205832 2.315376 +1.230157 1.364939 1.610435 2.002513 2.172872 2.355721 +1.302555 1.400606 1.734329 2.074003 2.208548 2.389274 +1.512686 1.818227 2.144783 2.266917 2.447736 2.569392 +1.507528 1.760422 2.164228 2.276872 2.479494 2.624837 +1.446511 1.760436 2.114696 2.256700 2.572570 2.661468 +1.468868 1.812355 2.114567 2.193023 2.617745 2.713842 +1.449647 1.776448 2.080604 2.210155 2.540909 2.713991 +1.441252 1.719517 2.114612 2.218690 2.511304 2.660049 +1.477657 1.619839 2.112699 2.198704 2.520599 2.655696 +1.532866 1.718145 2.132629 2.222301 2.551440 2.665729 +1.341030 1.814584 2.125039 2.245863 2.547976 2.649591 +1.361910 1.698086 2.076920 2.255113 2.524884 2.647043 +1.315333 1.592772 2.109776 2.210194 2.517745 2.666968 +1.382801 1.571593 2.106842 2.204058 2.495197 2.661417 +1.453626 1.641746 2.100313 2.199368 2.462404 2.608881 +1.376104 1.646574 1.987188 2.218409 2.413618 2.526810 +1.372839 1.632461 2.056237 2.163721 2.376186 2.586874 +1.432614 1.624632 2.074174 2.119889 2.480656 2.669026 +1.410683 1.662804 2.069219 2.130369 2.581373 2.714005 +1.174126 1.524516 2.032046 2.105255 2.502385 2.653307 +1.150832 1.249780 2.004788 2.158226 2.317980 2.588167 +1.057643 1.199724 2.043666 2.165479 2.371022 2.608171 +1.070330 1.169192 2.051065 2.187195 2.476449 2.671328 +0.989962 1.100883 1.959715 2.107656 2.451860 2.659328 +0.995945 1.125081 1.967729 2.171051 2.352755 2.586378 +0.951054 1.073408 1.768679 2.213097 2.362509 2.504270 +0.912647 1.063629 1.874306 2.209354 2.347793 2.515052 +0.880146 1.057702 1.939506 2.298197 2.447874 2.559719 +0.808391 0.999903 1.789456 2.221085 2.383243 2.512098 +0.872797 1.051306 1.907981 2.345885 2.551438 2.620384 +0.736864 0.925226 2.101552 2.273865 2.392948 2.568863 +0.704727 1.026198 2.094726 2.212489 2.474164 2.656197 +0.793545 1.029482 1.901019 2.333682 2.650248 2.721424 +0.890709 1.270067 2.139854 2.238320 2.544384 2.711324 +0.971655 1.317691 2.245472 2.351092 2.631963 2.711259 +1.080789 1.555771 2.010618 2.245992 2.528408 2.644890 +1.409512 1.769321 2.106696 2.284262 2.512254 2.638336 +1.248437 1.661986 2.035140 2.283241 2.534287 2.647326 +0.952460 1.123797 2.103484 2.258075 2.394744 2.604571 +0.989645 1.181656 2.023429 2.237371 2.369517 2.522527 +0.926042 1.348117 1.949341 2.062080 2.346962 2.449077 +0.919696 1.405301 1.834047 2.099696 2.376206 2.493394 +1.000811 1.371649 1.836653 2.224095 2.410108 2.539296 +1.200088 1.436788 1.839151 2.179281 2.398849 2.498430 +1.223520 1.486412 1.943988 2.252258 2.407325 2.540679 +1.113671 1.477208 1.844163 2.218008 2.381333 2.486877 +1.138107 1.498752 1.980951 2.297474 2.457848 2.560767 +1.146154 1.614539 1.898903 2.232476 2.416572 2.510958 +1.119673 1.589916 1.824415 2.111914 2.354760 2.453276 +1.032037 1.589416 1.852847 2.142988 2.324001 2.472943 +0.989427 1.528982 1.914645 2.179193 2.376737 2.494371 +1.095755 1.494564 1.866122 2.136805 2.283713 2.464058 +0.834557 1.463722 1.882565 2.150927 2.378636 2.463091 +0.835589 1.296069 1.771371 2.098776 2.286243 2.426378 +0.806577 1.403328 1.685216 2.040945 2.235736 2.356401 +0.800011 1.383092 1.814158 1.959934 2.309583 2.386791 +0.804745 1.318210 1.821360 1.908703 2.235131 2.427141 +0.895849 1.367225 1.864812 1.979670 2.324237 2.420788 +0.827390 1.425085 1.767158 2.058185 2.376232 2.469430 +0.917915 1.497920 1.855338 1.987207 2.315382 2.451640 +0.940855 1.409563 1.789190 1.988531 2.336666 2.534686 +0.972711 1.291697 1.786937 1.914881 2.323264 2.405491 +0.993281 1.368817 1.807237 1.958622 2.357274 2.459276 +1.074694 1.349312 1.840844 1.954844 2.269081 2.384056 +1.100597 1.218573 1.756134 1.900188 2.277874 2.406215 +1.165622 1.313695 1.843695 1.962222 2.157100 2.342911 +1.157768 1.372357 1.879963 1.991928 2.258080 2.390865 +1.286092 1.780986 1.959702 2.118874 2.324541 2.437595 +1.455169 1.738149 2.098885 2.235010 2.428464 2.539714 +1.500252 1.684257 2.161002 2.272591 2.399078 2.510334 +1.485672 1.846402 2.195717 2.305655 2.546282 2.650594 +1.727818 2.013707 2.167283 2.304214 2.586608 2.652160 +1.676773 1.960528 2.217006 2.368813 2.598284 2.681624 +1.631959 1.915752 2.227040 2.335178 2.603101 2.710218 +1.663857 1.973017 2.124709 2.222354 2.660483 2.724322 +1.542011 1.929582 2.075601 2.170628 2.628551 2.707745 +1.509689 1.706046 2.056908 2.197674 2.578326 2.653903 +1.482072 1.673728 2.131047 2.194868 2.586319 2.690293 +1.423447 1.643267 2.092317 2.178941 2.527205 2.636748 +1.355154 1.565169 2.023932 2.236487 2.538323 2.655495 +1.328421 1.553976 2.081558 2.161922 2.472742 2.656928 +1.330758 1.419042 2.026707 2.129051 2.367999 2.571017 +1.270648 1.377593 2.025948 2.140131 2.389237 2.575945 +1.236825 1.345428 2.022395 2.109848 2.478126 2.633911 +1.222076 1.320425 1.939670 2.021742 2.436807 2.628532 +1.252172 1.358274 1.972621 2.079346 2.371453 2.598928 +1.266234 1.470203 1.930446 2.145813 2.471858 2.618153 +1.332281 1.546411 2.025723 2.219524 2.464616 2.645111 +1.418604 1.649476 2.008305 2.128114 2.489878 2.676868 +1.455677 1.684682 1.988976 2.152647 2.470396 2.651526 +1.447490 1.600650 1.935900 2.271764 2.512990 2.631833 +1.444770 1.556361 2.020377 2.282318 2.475768 2.612336 +1.387476 1.487406 2.024679 2.244659 2.445046 2.582829 +1.353922 1.443279 1.957555 2.171307 2.336106 2.560084 +1.369786 1.447714 2.006181 2.191416 2.404713 2.604727 +1.425956 1.504279 2.072312 2.178177 2.417663 2.603411 +1.440235 1.540501 2.082397 2.211979 2.377070 2.637315 +1.497010 1.582681 2.056522 2.172175 2.389278 2.593845 +1.504963 1.584564 1.984094 2.149333 2.367563 2.559723 +1.519045 1.603989 1.993800 2.109929 2.327255 2.599694 +1.569559 1.651048 1.988942 2.116726 2.345772 2.569917 +1.569894 1.683682 1.980575 2.182917 2.357234 2.587282 +1.607074 1.712704 1.951468 2.125681 2.307168 2.547246 +1.645231 1.736599 1.952360 2.131487 2.376223 2.606463 +1.669612 1.763984 1.979653 2.173233 2.332349 2.516667 +1.632436 1.758871 1.980800 2.124271 2.285899 2.443828 +1.557406 1.667695 1.902055 2.106931 2.260859 2.483917 +1.470421 1.688945 1.846379 2.032834 2.185130 2.375868 +1.421944 1.531479 1.825667 2.026592 2.180382 2.360115 +1.385644 1.606158 1.846365 2.071388 2.488500 2.607454 +1.359715 1.577664 1.897105 2.111958 2.471108 2.603005 +1.339447 1.542640 1.933966 2.133741 2.454906 2.583194 +1.325808 1.691761 2.080233 2.164213 2.474164 2.605215 +1.347146 1.624704 2.074108 2.214395 2.430593 2.562946 +1.314857 1.541837 1.967631 2.164145 2.372693 2.606516 +1.312898 1.534081 1.917285 2.089949 2.411610 2.570672 +1.283019 1.557401 1.937879 2.103338 2.520615 2.623700 +1.138825 1.337472 1.871092 1.972746 2.433484 2.647653 +1.155936 1.281125 1.831346 1.919243 2.266602 2.600943 +1.166841 1.273824 1.843198 1.946026 2.318377 2.578792 +1.172291 1.275007 1.832581 2.025917 2.353813 2.624686 +1.082157 1.265436 1.892357 1.989008 2.383161 2.601421 +1.091903 1.208823 1.835009 2.034461 2.394722 2.562904 +1.098835 1.199487 1.757650 2.065888 2.390403 2.578893 +1.132798 1.244386 1.876625 2.071549 2.339183 2.537916 +1.180603 1.259469 1.823163 2.095055 2.256898 2.542724 +1.186987 1.312908 1.800793 2.105036 2.366989 2.496082 +1.266390 1.377139 1.810434 2.113272 2.329619 2.533152 +1.323586 1.404515 1.904242 2.145928 2.386113 2.580936 +1.352171 1.451401 1.949824 2.077051 2.390820 2.538573 +1.343859 1.452231 1.889889 2.026744 2.317477 2.482486 +1.244808 1.378854 1.792557 1.986745 2.422571 2.536950 +1.124619 1.253596 1.703825 1.951315 2.439640 2.545147 +0.995104 1.411750 1.728505 1.861639 2.456605 2.544957 +1.001072 1.409106 1.797727 1.897572 2.409482 2.555324 +1.033981 1.428160 1.786944 1.880286 2.326359 2.503159 +0.970169 1.320721 1.716642 1.841569 2.220200 2.388916 +0.930477 1.373382 1.798398 1.904734 2.305786 2.525304 +0.939935 1.418455 1.772704 1.878087 2.367491 2.461526 +0.949116 1.527114 1.765903 1.840735 2.164926 2.474337 +0.993353 1.629343 1.813445 1.910215 2.100772 2.492902 +1.013830 1.549621 1.796834 1.891936 2.239760 2.556346 +0.970121 1.509802 1.834006 1.938978 2.338575 2.504346 +0.947238 1.361377 1.783553 1.984713 2.423900 2.547178 +0.980991 1.388783 1.783307 2.131708 2.454635 2.558692 +1.002668 1.402339 1.807195 2.024461 2.464418 2.554280 +1.010697 1.404186 1.872558 2.079362 2.479332 2.569625 +0.972976 1.375802 1.843367 1.980698 2.513609 2.578272 +0.932062 1.277676 1.851126 1.985878 2.466286 2.566260 +0.938577 1.181150 1.833964 1.965034 2.458011 2.550532 +0.940095 1.145447 1.796688 2.078273 2.482897 2.610630 +0.909789 1.074084 1.717403 2.139110 2.462525 2.572261 +0.882446 1.066652 1.729556 2.284662 2.478899 2.555022 +0.938178 1.121504 1.828485 2.234041 2.474778 2.557100 +0.917165 1.283072 1.779497 2.100290 2.475831 2.590182 +1.062938 1.349043 1.762759 2.118297 2.504806 2.606788 +1.186965 1.461900 1.889039 2.112738 2.481323 2.621310 +1.480720 1.619232 1.979483 2.177103 2.436476 2.578983 +1.448723 1.566337 1.880134 2.138534 2.339676 2.554594 +1.407995 1.613546 1.828927 2.052703 2.344501 2.538078 +1.616019 1.691006 1.856347 1.980078 2.548246 2.637759 +1.628171 1.684163 1.886153 2.012867 2.563772 2.621577 +1.595743 1.688011 1.935400 2.025813 2.483630 2.616820 +1.641560 1.708656 1.955460 2.046989 2.519834 2.645741 +1.673668 1.752213 1.951288 2.080918 2.487394 2.640725 +1.656417 1.736239 1.991365 2.098321 2.571908 2.676827 +1.659820 1.732449 1.951246 2.077020 2.581642 2.693515 +1.654803 1.716207 1.966639 2.044230 2.563251 2.680200 +1.602729 1.682614 1.917410 1.994825 2.531087 2.673289 +1.582550 1.639535 1.926100 1.992074 2.532073 2.697110 +1.462370 1.585004 1.818300 1.897553 2.557132 2.706256 +1.453199 1.550734 1.815192 1.916461 2.399968 2.667684 +1.419387 1.557717 1.784441 1.909176 2.511382 2.669980 +1.395165 1.539820 1.847477 1.930837 2.583961 2.703625 +1.348853 1.610875 1.958146 2.043068 2.586086 2.664353 +1.372390 1.658144 1.958657 2.189437 2.450481 2.650316 +1.352586 1.528092 1.923141 2.194837 2.427729 2.562143 +1.380925 1.612272 1.993385 2.176111 2.508934 2.635056 +1.429580 1.686586 2.017126 2.172565 2.486420 2.609268 +1.392123 1.641039 1.952077 2.065066 2.421215 2.574909 +1.399593 1.788262 1.952093 2.098580 2.489935 2.629393 +1.383756 1.662435 1.983097 2.112236 2.532805 2.631814 +1.372732 1.673625 1.912122 2.134246 2.432996 2.612276 +1.396034 1.642619 1.962634 2.197392 2.521323 2.660686 +1.379360 1.623989 2.069404 2.243124 2.562033 2.668437 +1.338665 1.618629 2.042041 2.195119 2.570159 2.699099 +1.294124 1.712084 2.050162 2.120133 2.607839 2.681695 +1.293254 1.596252 1.993414 2.060041 2.583077 2.664144 +1.209917 1.362665 1.955116 2.028347 2.512957 2.625803 +1.381701 1.706617 2.003167 2.146470 2.500026 2.613009 +1.204671 1.734562 1.928802 2.109687 2.476898 2.549090 +1.114491 1.696319 1.888819 2.043672 2.539268 2.637168 +1.119312 1.601460 1.846733 2.085664 2.577543 2.645353 +1.128747 1.531175 1.858280 2.146770 2.596351 2.688725 +1.130254 1.674654 1.830664 2.172114 2.562554 2.672831 +1.100767 1.644406 1.833225 2.040605 2.599334 2.652288 +1.066968 1.530596 1.768634 2.003323 2.617323 2.678055 +1.063119 1.469356 1.797817 1.881851 2.568187 2.679145 +1.177293 1.703277 1.865510 2.061041 2.481068 2.581444 +1.404135 1.657504 1.927058 2.181851 2.457409 2.580431 +1.428360 1.663538 1.984994 2.183449 2.458664 2.569489 +1.403204 1.667154 1.955094 2.146449 2.462636 2.562658 +1.234126 1.597848 1.917754 2.034440 2.407548 2.560257 +1.224528 1.368625 1.848065 1.924719 2.494949 2.670207 +1.214772 1.588344 1.765811 2.003861 2.526784 2.635964 +1.264884 1.636472 1.825225 2.077058 2.563495 2.679292 +1.269611 1.588977 1.782182 2.095015 2.620415 2.691789 +1.296409 1.504336 1.802915 2.013382 2.605687 2.681621 +1.334375 1.520771 1.796606 1.963884 2.600418 2.703744 +1.397570 1.600583 1.845972 1.940123 2.616223 2.696111 +1.430879 1.559075 1.799241 1.994052 2.598948 2.674700 +1.482115 1.583037 1.807507 1.981426 2.575382 2.684729 +1.464344 1.565621 1.776029 1.917627 2.575000 2.659270 +1.455399 1.538232 1.730658 1.882074 2.563750 2.660443 +1.499577 1.584423 1.688069 1.892068 2.587098 2.688675 +1.479760 1.573703 1.695194 2.024437 2.558177 2.639037 +1.452267 1.547118 1.750567 2.072025 2.537014 2.673786 +1.447379 1.563037 1.794376 2.141633 2.353387 2.502548 +1.351721 1.450714 1.730230 1.991889 2.298349 2.463553 +1.318760 1.414624 1.641985 1.948338 2.326246 2.474291 +1.212051 1.346227 1.685099 1.959885 2.322238 2.512951 +1.209021 1.302946 1.634616 1.930848 2.282912 2.507545 +1.188947 1.292823 1.665660 2.177853 2.373563 2.474293 +1.257542 1.451148 1.836011 2.161476 2.447295 2.596642 +1.253420 1.370197 1.833717 2.244743 2.479769 2.576022 +1.179954 1.302011 1.592154 2.151577 2.455959 2.518120 +1.114477 1.257653 1.411579 2.042361 2.548294 2.620409 +1.099986 1.307070 1.407174 2.159418 2.585914 2.649358 +1.131151 1.246857 1.401279 2.116604 2.483756 2.546663 +1.173775 1.340865 1.449901 2.093705 2.561030 2.626482 +1.189575 1.346203 1.465586 2.003540 2.517749 2.575697 +1.217965 1.302991 1.569488 2.028970 2.455729 2.550140 +1.231915 1.393228 1.520464 1.955734 2.476226 2.642241 +1.277177 1.451138 1.591018 1.925992 2.458091 2.566561 +1.216236 1.483117 1.688680 1.988972 2.454628 2.599617 +1.184293 1.553039 1.838890 2.100265 2.385006 2.550049 +1.239174 1.792822 1.959073 2.182600 2.445294 2.529569 +1.624571 1.860854 2.120332 2.219916 2.429410 2.594102 +1.753243 1.889331 2.136521 2.254574 2.436331 2.562459 +1.757269 1.956924 2.242335 2.360108 2.493739 2.587626 +1.806843 1.985195 2.197761 2.338682 2.496335 2.600682 +1.859905 2.030422 2.282537 2.396000 2.548595 2.632629 +1.771104 1.896134 2.306763 2.421261 2.538338 2.625956 +1.505646 1.893235 2.019328 2.325790 2.487965 2.585530 +1.189137 1.771099 1.915068 2.254873 2.534430 2.612783 +1.103999 1.649346 1.834993 1.935938 2.534134 2.651998 +1.079006 1.522445 1.767276 1.934965 2.523135 2.596389 +1.106210 1.608040 1.751444 2.008392 2.491731 2.577152 +1.225135 1.597265 1.857833 2.103611 2.465420 2.593047 +1.375366 1.618359 1.930516 2.214454 2.445564 2.576198 +1.429991 1.698975 1.982144 2.233337 2.490443 2.605353 +1.482797 1.679463 1.997759 2.222400 2.464577 2.586822 +1.407997 1.676636 1.970849 2.221085 2.440364 2.592428 +1.279905 1.618797 1.920986 2.161088 2.438805 2.627424 +0.936959 1.310295 1.663367 2.010101 2.515991 2.597781 +1.014662 1.401511 1.590078 2.080875 2.556905 2.622152 +1.043648 1.384572 1.571501 1.988231 2.568660 2.647893 +1.107266 1.413973 1.562057 1.877144 2.554722 2.637289 +1.179476 1.467385 1.605003 1.839003 2.523485 2.640499 +1.218315 1.412023 1.591634 1.796526 2.519799 2.660570 +1.305370 1.427385 1.614577 1.763694 2.497267 2.657791 +1.338542 1.456340 1.642200 1.862353 2.448789 2.631625 +1.328675 1.442223 1.575230 1.858910 2.470665 2.570433 +1.351215 1.466285 1.601432 1.863743 2.425253 2.500336 +1.360914 1.476484 1.624624 1.832107 2.486273 2.563333 +1.401730 1.499881 1.613403 1.749733 2.423219 2.591408 +1.261551 1.402991 1.523781 1.802043 2.499740 2.605532 +1.160005 1.467049 1.605598 1.787691 2.508050 2.557362 +1.279521 1.535093 1.620574 1.758619 2.409621 2.676419 +1.161358 1.505461 1.626199 1.733096 2.398831 2.617482 +1.184633 1.528528 1.614286 1.698210 2.350337 2.667102 +1.117350 1.538074 1.658450 1.759625 2.281261 2.580678 +1.109838 1.492830 1.701966 1.789832 2.151236 2.489725 +1.010233 1.467118 1.631090 1.886421 2.420021 2.522779 +0.950861 1.336887 1.617005 1.789550 2.449618 2.528894 +1.028468 1.348095 1.571888 1.880393 2.543912 2.608014 +1.110746 1.415658 1.690546 2.005512 2.558177 2.650097 +1.110147 1.432665 1.669404 1.901594 2.516926 2.602743 +1.067829 1.543381 1.719440 1.979004 2.543666 2.617575 +1.422545 1.701061 1.940427 2.327061 2.557612 2.642956 +1.386122 1.781934 2.040679 2.383895 2.573951 2.633463 +1.512775 1.696332 2.184500 2.295985 2.578995 2.677261 +1.571845 1.705242 2.225227 2.319189 2.542604 2.676163 +1.514913 1.844285 2.247341 2.361592 2.529071 2.653297 +1.603580 1.948417 2.271813 2.429600 2.528208 2.617731 +1.620409 2.024184 2.379020 2.477983 2.622963 2.670765 +1.578823 1.906347 2.238314 2.378843 2.556955 2.647118 +1.611136 1.900666 2.185777 2.317384 2.517010 2.610141 +1.554611 1.941431 2.133055 2.249862 2.491762 2.571608 +1.469621 1.918901 2.094184 2.225177 2.490350 2.564343 +1.335366 1.697214 2.017085 2.232317 2.474337 2.571016 +1.221936 1.519055 1.814063 2.129404 2.458290 2.560125 +1.193348 1.426044 1.731637 2.009086 2.485687 2.566097 +1.140861 1.304138 1.724072 1.962123 2.456816 2.673582 +1.171988 1.316998 1.756942 2.050812 2.520621 2.679355 +1.135139 1.410213 1.715289 2.092595 2.499448 2.617713 +1.114534 1.487214 1.595404 2.013785 2.531961 2.628395 +1.185163 1.399888 1.582655 2.195793 2.518380 2.582468 +1.104552 1.423680 1.656289 2.262530 2.593187 2.664012 +1.164305 1.596992 1.717746 2.207846 2.563155 2.621398 +1.022593 1.596460 1.831763 2.287975 2.519037 2.580420 +0.920067 1.656499 1.829222 2.207172 2.535598 2.582536 +0.940069 1.577439 1.960575 2.189248 2.482820 2.549330 +0.824619 1.708493 1.932229 2.188611 2.551880 2.605484 +0.819752 1.688971 1.950607 2.083451 2.463192 2.515870 +0.820934 1.718478 2.021631 2.158415 2.521119 2.576288 +0.860984 1.615689 2.046857 2.146219 2.469888 2.571061 +0.722400 1.647372 1.973155 2.066104 2.438838 2.609071 +0.853506 1.577947 1.949855 2.082839 2.448741 2.512425 +0.745605 1.464510 1.993321 2.077513 2.469178 2.532474 +0.710718 1.533693 1.890047 2.013877 2.425598 2.516390 +0.877569 1.511979 1.831605 2.031903 2.441617 2.517441 +1.259618 1.519519 1.879696 2.138828 2.450290 2.614072 +1.326658 1.670099 1.919340 2.148365 2.362928 2.464453 +1.437714 1.671637 1.955052 2.166713 2.405950 2.557523 +1.603868 1.740291 1.989945 2.198778 2.467525 2.585653 +1.638499 1.743252 2.051089 2.149707 2.462625 2.569332 +1.631833 1.721768 2.002918 2.131145 2.438931 2.569221 +1.603157 1.763192 2.082194 2.174769 2.376719 2.502259 +1.630977 1.703944 2.009215 2.149268 2.369179 2.580570 +1.576599 1.658687 1.922940 2.124950 2.448734 2.578273 +1.516265 1.630706 1.860803 2.127036 2.444402 2.582277 +1.458879 1.547626 1.796080 2.046972 2.378056 2.535592 +1.376657 1.512511 1.733562 2.098209 2.361768 2.452137 +1.134749 1.320184 1.582547 2.052886 2.449062 2.527062 +1.079447 1.164059 1.573367 2.220764 2.500300 2.560928 +1.060468 1.186417 1.456658 2.155790 2.437004 2.526903 +0.974645 1.132811 1.563530 2.089864 2.504612 2.571780 +0.925733 1.049035 1.555693 2.095444 2.541677 2.614171 +1.012861 1.154680 1.283807 2.126165 2.558786 2.595811 +0.970704 1.088894 1.398803 1.969666 2.517460 2.621486 +0.996670 1.155602 1.284230 1.967741 2.478048 2.536750 +1.061875 1.172759 1.296847 1.890131 2.465313 2.550488 +0.971133 1.146895 1.425088 1.823656 2.310199 2.513193 +1.122316 1.246948 1.573931 1.945863 2.350666 2.546107 +1.130444 1.281802 1.711748 2.052845 2.471168 2.568969 +1.285794 1.425185 1.874398 2.085225 2.426111 2.576993 +1.273537 1.490213 1.878772 2.106249 2.402449 2.544368 +1.224244 1.462476 1.904611 2.128189 2.416565 2.570019 +1.252061 1.449849 1.802510 2.119875 2.418885 2.518798 +1.327124 1.417585 1.789962 2.174930 2.340651 2.468715 +1.346777 1.435555 1.734308 2.036035 2.356552 2.531051 +1.235820 1.315959 1.597124 1.897870 2.284217 2.575948 +0.955415 1.303770 1.560187 1.730070 2.449775 2.648120 +0.909089 1.471674 1.624478 1.890973 2.389653 2.627950 +0.919631 1.366873 1.506021 1.842587 2.342002 2.554492 +0.855197 1.279671 1.539553 1.688524 2.386911 2.502065 +0.807057 1.135620 1.541600 1.681299 2.243913 2.510869 +0.849115 1.190235 1.449935 1.541388 2.302579 2.655596 +0.832569 1.273363 1.592481 1.792808 2.284175 2.498482 +0.835449 1.168916 1.544629 1.718930 2.423889 2.632619 +0.826578 1.276188 1.407857 1.660287 2.378044 2.474526 +0.873632 1.360315 1.502868 1.758332 2.570802 2.712262 +0.828320 1.284633 1.462407 1.624198 2.575860 2.705612 +0.866930 1.133312 1.254056 1.429890 2.499289 2.562307 +0.807119 1.218080 1.346012 1.540621 2.487606 2.633103 +0.983680 1.146576 1.336648 1.479310 2.327156 2.614361 +0.991742 1.170728 1.296168 1.485606 2.543050 2.663819 +0.857243 1.172195 1.298593 1.623901 2.581253 2.675646 +1.024459 1.245164 1.335833 1.923956 2.623488 2.689817 +1.035260 1.293064 1.419811 1.882694 2.474976 2.673673 +0.981160 1.239841 1.334553 1.628448 2.544049 2.681735 +0.948338 1.227389 1.360095 1.572061 2.447980 2.668611 +1.097120 1.256099 1.362188 1.632542 2.507787 2.656424 +1.060738 1.283998 1.527933 1.676274 2.540944 2.638141 +0.999111 1.230695 1.531258 1.643979 2.373065 2.634336 +0.900037 1.357157 1.519901 1.691155 2.333453 2.605899 +0.906535 1.200477 1.615255 1.715962 2.288870 2.609565 +0.841267 1.337701 1.721187 1.799125 2.176356 2.627236 +0.950819 1.507117 1.718816 1.826725 2.050526 2.489892 +0.922437 1.447590 1.832061 1.920513 2.148990 2.509573 +0.797637 1.120473 1.756266 1.946112 2.209112 2.535941 +0.821846 1.168739 1.837911 1.977726 2.361612 2.642410 +0.802821 1.394640 1.945588 2.031517 2.337491 2.589953 +0.808599 1.214285 1.878529 2.002325 2.280219 2.577779 +0.825133 1.329296 1.896620 1.979559 2.455746 2.573104 +0.847939 1.235948 1.897295 2.016610 2.422214 2.651151 +0.793266 1.311794 1.885265 1.974869 2.493916 2.699921 +0.835729 1.418115 1.839725 1.903232 2.507962 2.645131 +0.849380 1.476197 1.836815 1.977378 2.321338 2.561101 +0.774570 1.284607 1.758190 1.864424 2.367732 2.561205 +0.896154 1.466437 1.770222 1.871354 2.586553 2.688477 +1.097803 1.576496 1.742325 1.910224 2.160666 2.658455 +0.950720 1.452865 1.760158 1.934774 2.196277 2.624191 +0.947778 1.334777 1.745609 1.830510 2.256113 2.667856 +0.970291 1.214911 1.745935 1.840709 2.268780 2.555177 +1.027483 1.193053 1.655411 1.770558 2.115990 2.502962 +1.108625 1.224039 1.556423 1.705900 2.019067 2.463824 +1.137334 1.248642 1.659896 1.835999 2.087298 2.494018 +1.192784 1.290313 1.652861 1.878632 2.086082 2.615960 +1.231829 1.343294 1.528206 1.646125 1.912160 2.354407 +1.043149 1.380698 1.679143 1.830121 2.008367 2.414010 +1.102887 1.243057 1.747479 1.861385 2.203092 2.504381 +1.049734 1.354368 1.735882 1.819000 2.248805 2.557794 +1.105977 1.571421 1.764806 1.953547 2.428854 2.560105 +1.290846 1.550164 1.837562 2.126596 2.488831 2.600779 +1.194236 1.426699 1.837665 1.914014 2.443207 2.635517 +1.165504 1.260088 1.790938 1.893312 2.400453 2.646643 +1.224955 1.308139 1.825926 1.919493 2.321356 2.695079 +1.248486 1.345382 1.775451 1.876708 2.353719 2.654140 +1.271138 1.399667 1.811535 1.897580 2.403493 2.653922 +1.309100 1.407658 1.806843 1.897827 2.339222 2.632347 +1.291018 1.383330 1.802439 1.887187 2.247718 2.662452 +1.261355 1.370512 1.755969 1.871246 2.101895 2.593588 +1.282645 1.376536 1.775534 1.904499 2.192341 2.507429 +1.361360 1.450864 1.791066 1.906164 2.221501 2.543343 +1.334993 1.431384 1.716268 1.905493 2.089197 2.378260 +1.385673 1.470423 1.765397 1.909217 2.173842 2.456572 +1.364318 1.455064 1.754884 1.871473 2.365039 2.572279 +1.387777 1.486887 1.712089 1.847504 2.243563 2.570692 +1.312448 1.425290 1.622893 1.756780 1.978470 2.367512 +1.347202 1.454345 1.683431 1.825472 2.087917 2.462563 +1.326447 1.405443 1.727641 1.835551 2.328868 2.614333 +1.333108 1.429712 1.796075 1.900347 2.445062 2.652912 +1.322803 1.421588 1.736939 1.843495 2.532120 2.646639 +1.344685 1.431856 1.766206 1.924579 2.550076 2.689857 +1.388277 1.485813 1.711960 1.826211 2.496137 2.658495 +1.411133 1.495610 1.776872 1.876674 2.492586 2.651345 +1.417795 1.491577 1.801693 1.890405 2.442446 2.706992 +1.406122 1.515595 1.757336 1.896968 2.382045 2.633633 +1.425860 1.514813 1.773260 1.901744 2.447546 2.634715 +1.476029 1.555032 1.745731 1.861617 2.398766 2.614978 +1.459852 1.561528 1.786445 1.911235 2.476542 2.591787 +1.403056 1.514189 1.720761 1.900939 2.489890 2.577333 +1.428127 1.523512 1.689756 1.835214 2.458899 2.565972 +1.328956 1.434709 1.604068 1.734252 2.466296 2.566835 +1.241317 1.343249 1.457997 1.696624 2.527818 2.645659 +1.136623 1.311125 1.429957 1.695364 2.542525 2.660410 +1.153111 1.344144 1.690808 1.985929 2.420013 2.553782 +1.231755 1.373918 1.668818 2.117444 2.401907 2.488883 +0.978581 1.115592 1.517126 2.000531 2.449025 2.526020 +0.951081 1.107962 1.208612 1.737223 2.474298 2.611849 +0.981806 1.127841 1.220590 1.720985 2.586528 2.698889 +0.977554 1.224067 1.337758 1.713271 2.593374 2.675408 +0.986078 1.260397 1.407440 1.571486 2.569420 2.631754 +1.068774 1.209396 1.464430 1.557978 2.551351 2.669751 +1.034191 1.174307 1.467256 1.555295 2.460490 2.642259 +1.056632 1.178692 1.509897 1.621544 2.153033 2.540535 +1.108939 1.240242 1.651384 1.778538 2.227605 2.571951 +1.040854 1.397785 1.709633 1.830019 2.398698 2.618954 +1.063080 1.564032 1.695538 1.794688 2.419017 2.577353 +1.156653 1.579890 1.742991 1.888966 2.419007 2.626873 +1.282148 1.604674 1.769820 1.984806 2.290529 2.408545 +1.414961 1.752587 1.937904 2.076787 2.287689 2.502281 +1.561586 1.882695 2.087185 2.199871 2.398595 2.509058 +1.741771 1.963051 2.161078 2.262211 2.516056 2.626131 +1.579553 1.916299 2.201667 2.301679 2.458486 2.648337 +1.656200 1.849299 2.101697 2.302170 2.487760 2.573832 +1.761707 1.935887 2.167102 2.423095 2.531309 2.619774 +1.747342 1.946460 2.129719 2.452120 2.591709 2.681100 +1.664774 1.950714 2.064839 2.452925 2.653282 2.719977 +1.182120 1.806988 2.031810 2.240448 2.589338 2.666952 +0.911793 1.444427 1.938199 2.009542 2.518849 2.662424 +0.906235 1.353950 1.860144 1.948940 2.570343 2.653728 +0.915756 1.182444 1.779374 1.918355 2.495182 2.685238 +0.923262 1.168083 1.705447 2.007985 2.401242 2.584424 +0.915338 1.196101 1.641183 1.957797 2.235160 2.502509 +1.116935 1.269153 1.597465 1.950801 2.129101 2.392503 +1.227147 1.344231 1.809259 1.999158 2.320768 2.545770 +1.307876 1.517973 1.832338 2.042156 2.347761 2.543408 +1.142909 1.427477 1.831520 2.022295 2.356478 2.589639 +1.020209 1.202712 1.780168 2.070788 2.565827 2.661648 +1.087846 1.265956 1.653284 2.093962 2.625661 2.709244 +1.146593 1.234170 1.666291 2.022252 2.605716 2.676253 +1.089057 1.311412 1.647149 1.833847 2.666682 2.722762 +1.188386 1.319963 1.725677 1.806948 2.571193 2.664171 +1.209565 1.358036 1.697429 1.794200 2.470455 2.640229 +1.246047 1.338292 1.695538 1.782003 2.565757 2.666941 +1.261251 1.384481 1.619675 1.779584 2.591799 2.712426 +1.337507 1.450232 1.646992 1.774207 2.578969 2.703367 +1.387688 1.478096 1.618920 1.747276 2.531990 2.665704 +1.301779 1.392643 1.541867 1.665649 2.484537 2.655063 +1.257012 1.398833 1.527358 1.734139 2.619531 2.689676 +1.211161 1.324264 1.664338 1.911508 2.589343 2.685254 +1.113028 1.325407 1.697702 1.940185 2.591124 2.679629 +1.000343 1.352231 1.719494 2.024790 2.577661 2.639096 +0.952537 1.564659 1.914580 2.021105 2.481262 2.553572 +0.941380 1.573371 1.898482 1.990822 2.388399 2.527824 +0.835656 1.426857 1.914902 2.006303 2.455843 2.544426 +0.762518 1.617975 1.848163 1.952719 2.511683 2.576889 +0.760103 1.720246 1.884039 1.972497 2.526184 2.668968 +0.788105 1.515939 1.760885 1.953721 2.498661 2.553903 +0.842390 1.235086 1.687435 2.011114 2.391471 2.529546 +0.970555 1.304880 1.689915 2.060096 2.386014 2.524270 +1.078507 1.220815 1.630394 2.103928 2.411414 2.518300 +1.035130 1.374294 1.739516 2.015391 2.383541 2.542893 +1.232775 1.466122 1.942876 2.112602 2.359872 2.476841 +1.032139 1.460157 1.843607 2.111319 2.405612 2.545609 +0.863004 1.575367 1.754339 2.026425 2.484055 2.545871 +0.781880 1.621135 1.876114 2.131620 2.591150 2.665213 +0.689257 1.567671 1.951319 2.246727 2.507788 2.649956 +0.762920 1.454508 2.052137 2.239950 2.408909 2.570384 +0.735313 1.369541 2.141121 2.226737 2.404256 2.515847 +0.692794 1.213217 2.021728 2.170012 2.409789 2.632609 +0.749191 1.327407 1.876305 2.159813 2.396372 2.543556 +0.723514 1.311926 1.779121 2.000990 2.333064 2.521625 +0.800844 1.399334 1.702525 1.886771 2.183805 2.391837 +0.935365 1.532399 1.746103 1.843273 2.027876 2.366925 +0.879717 1.390978 1.696694 1.873227 2.273388 2.532951 +1.115628 1.395380 1.552486 2.062541 2.379745 2.485662 +1.253460 1.379822 1.726521 2.164899 2.386851 2.507812 +1.288652 1.548609 1.769224 2.106137 2.428838 2.517503 +1.369653 1.611147 1.793668 1.970474 2.367649 2.558036 +1.399028 1.694930 1.865624 2.036762 2.409162 2.586430 +1.433335 1.745725 1.930732 2.159385 2.426554 2.579037 +1.267585 1.665867 1.971379 2.103318 2.444523 2.567741 +1.226120 1.497218 1.888612 2.083592 2.547854 2.623475 +1.217864 1.502320 1.850155 1.973913 2.506017 2.625566 +1.213794 1.595369 1.875039 1.979415 2.427150 2.606463 +1.239752 1.513874 1.766680 1.947926 2.281624 2.492074 +1.247634 1.585626 1.729740 1.894696 2.381964 2.522121 +1.201153 1.474465 1.746568 1.834238 2.289729 2.525183 +1.181465 1.555321 1.703604 1.823083 2.315827 2.443888 +1.196327 1.573762 1.735225 1.808031 2.403501 2.557243 +1.149081 1.631606 1.769163 1.925569 2.368122 2.542814 +1.071093 1.633545 1.761338 1.872468 2.408464 2.573521 +1.065230 1.551738 1.713412 1.880487 2.387426 2.512159 +0.987564 1.635727 1.785940 1.956709 2.413400 2.548618 +0.931677 1.526457 1.773013 1.896960 2.437956 2.513898 +0.900322 1.645882 1.787979 2.041039 2.334273 2.434592 +0.867303 1.714715 1.901607 2.099190 2.387096 2.475894 +0.868278 1.693735 1.917301 2.013076 2.274597 2.382531 +0.848816 1.567192 1.829012 1.929834 2.339398 2.425619 +0.789452 1.369290 1.826862 1.917268 2.414283 2.502071 +0.737031 1.173300 1.873028 1.972833 2.455130 2.541243 +0.759015 1.250729 1.781114 1.994631 2.420436 2.554945 +0.749485 1.363939 1.896372 1.993571 2.442257 2.509848 +0.749379 1.214662 1.940660 2.034076 2.450716 2.568302 +0.801242 1.269156 1.870897 1.955986 2.405162 2.473861 +0.823290 1.258951 1.879861 2.069704 2.411773 2.510105 +0.836531 1.273927 1.957305 2.047469 2.490158 2.582295 +0.834116 1.183883 1.886457 1.969193 2.499483 2.604335 +0.876413 1.171153 1.946619 2.030903 2.431350 2.553010 +0.839364 1.056108 1.853641 2.100590 2.392613 2.554339 +0.864173 1.164684 1.835487 1.968845 2.376306 2.516103 +0.932804 1.294569 1.830951 1.901036 2.445265 2.552572 +0.963048 1.356861 1.768829 1.893219 2.479918 2.614673 +1.037066 1.359723 1.820807 1.891047 2.519312 2.605020 +1.060607 1.462340 1.797954 1.939293 2.521868 2.591879 +1.079923 1.504167 1.802208 1.930535 2.465137 2.543195 +1.140112 1.339064 1.813350 1.905307 2.370068 2.530420 +1.151868 1.356167 1.772359 1.883710 2.370014 2.610806 +1.288085 1.638629 1.751055 2.279923 2.555394 2.623279 +1.451442 1.739489 1.916401 2.388700 2.636146 2.702827 +1.591253 1.851544 2.218282 2.385490 2.593754 2.679427 +1.592264 2.016137 2.233799 2.333758 2.544823 2.665169 +1.654199 1.941575 2.250965 2.372366 2.458905 2.599827 +1.703247 2.025498 2.229596 2.337095 2.468575 2.617655 +1.638815 2.005565 2.201946 2.268461 2.499537 2.618409 +1.924675 2.135325 2.458180 2.504168 2.593838 2.625401 +1.803809 2.062572 2.199354 2.289456 2.550039 2.643916 +1.773011 1.976616 2.107571 2.220874 2.444977 2.543841 +1.764952 2.001727 2.214453 2.254705 2.475610 2.579746 +1.678332 1.863913 2.244638 2.343674 2.471126 2.636086 +1.755810 1.860246 2.223719 2.353060 2.498302 2.586676 +1.693433 1.869241 2.283303 2.395805 2.519741 2.583673 +1.704396 1.791207 2.147185 2.336447 2.479029 2.590894 +1.683258 1.862251 2.163335 2.351843 2.520908 2.616034 +1.623219 1.804206 2.222072 2.360296 2.619900 2.699507 +1.657240 1.825612 2.258489 2.347345 2.545732 2.694714 +1.660069 1.860341 2.253569 2.364116 2.564093 2.630731 +1.596899 1.839512 2.218930 2.385793 2.546468 2.625886 +1.622317 1.851201 1.996215 2.377397 2.522071 2.595493 +1.029466 1.254529 1.748991 2.053525 2.445882 2.576112 +0.856689 0.993818 1.569607 2.213756 2.461855 2.547082 +1.016581 1.191900 1.293465 1.778141 2.455802 2.551646 +1.010542 1.228148 1.311431 1.820284 2.531515 2.656752 +0.908278 1.189582 1.285536 1.858600 2.525918 2.619924 +0.871987 1.171922 1.317490 1.826516 2.400744 2.518087 +1.033124 1.188852 1.439697 2.039008 2.572425 2.656103 +0.970197 1.295635 1.402442 2.035038 2.488178 2.549888 +1.088196 1.220650 1.553062 2.133376 2.535702 2.595055 +1.009947 1.389803 1.517057 2.115221 2.474188 2.550693 +0.993372 1.427374 1.539173 1.972396 2.525839 2.583860 +1.048290 1.482084 1.637176 2.161075 2.523169 2.614712 +1.024326 1.562855 1.692237 2.295162 2.594836 2.648573 +0.907692 1.612559 1.746134 2.162536 2.575745 2.616258 +0.890482 1.611128 1.773927 1.970733 2.577746 2.659601 +0.808392 1.597802 1.785959 2.006399 2.565042 2.638957 +0.766474 1.584421 1.835838 1.929741 2.581539 2.641074 +0.769957 1.626769 1.869258 2.029447 2.602778 2.660482 +0.798945 1.531859 1.834894 1.946531 2.628257 2.692621 +0.720628 1.380228 1.817598 1.895348 2.547755 2.607196 +0.717991 1.301269 1.753273 1.880568 2.501113 2.570677 +0.757538 1.197506 1.719315 1.863401 2.467197 2.580754 +0.753702 1.292466 1.691851 1.775796 2.472592 2.583782 +0.814552 1.234200 1.583851 1.688282 2.546255 2.601382 +0.892573 1.259415 1.548665 1.628711 2.465185 2.557477 +0.949846 1.260567 1.429248 1.620283 2.396748 2.457397 +1.035299 1.244100 1.498240 1.643920 2.381366 2.524331 +1.108074 1.337571 1.538192 1.800588 2.513582 2.617693 +1.182535 1.370472 1.561886 1.844157 2.545726 2.614455 +1.215270 1.374402 1.595386 1.940797 2.512277 2.594163 +1.232828 1.356701 1.648355 2.040665 2.518326 2.606889 +1.295532 1.441002 1.626009 2.063594 2.535454 2.607196 +1.317455 1.484169 1.666626 2.107203 2.509460 2.569563 +1.288135 1.404836 1.708442 2.142397 2.478263 2.558149 +1.301178 1.490634 1.688663 2.209739 2.516570 2.582597 +1.388908 1.488602 1.753074 2.249110 2.468447 2.532735 +1.432358 1.501949 1.756043 2.227378 2.540315 2.633816 +1.270629 1.444250 1.697177 2.167736 2.574168 2.667078 +1.377953 1.511825 1.619242 2.070588 2.580573 2.655449 +1.319093 1.437635 1.575159 1.826257 2.568503 2.646941 +1.273340 1.439378 1.614682 1.977816 2.589179 2.642268 +1.364811 1.491437 1.654641 1.914895 2.277580 2.491707 +1.381399 1.482330 1.625703 1.767453 2.292816 2.535410 +1.316122 1.410804 1.574518 1.696495 2.241547 2.544142 +1.249213 1.448411 1.651606 1.812013 2.166941 2.528826 +1.329985 1.430104 1.637785 1.753696 2.144268 2.491734 +1.212008 1.460184 1.663715 1.723968 2.452735 2.654868 +1.154672 1.427992 1.639839 1.703824 2.524782 2.647191 +1.132193 1.276380 1.638189 1.750734 2.360136 2.630237 +1.106796 1.292196 1.563991 1.737151 2.276384 2.673484 +1.009469 1.409199 1.605253 1.755880 2.549809 2.666897 +0.849242 1.424760 1.607336 1.770467 2.593061 2.697570 +0.884126 1.418674 1.690537 1.910365 2.648893 2.753562 +0.835786 1.505326 1.650834 1.839830 2.667508 2.731820 +0.830887 1.418426 1.698221 1.812786 2.546614 2.605179 +0.770144 1.456185 1.735350 1.839787 2.485317 2.539411 +0.741204 1.461201 1.720258 2.039661 2.613149 2.656617 +0.746126 1.436058 1.674916 1.868865 2.616457 2.659599 +0.785082 1.343492 1.675451 1.756554 2.550054 2.611912 +0.745773 1.354824 1.630019 1.938987 2.453600 2.549079 +0.845780 1.469252 1.629079 1.974969 2.499282 2.549783 +0.949421 1.462768 1.572994 2.286043 2.549581 2.602929 +1.025145 1.385363 1.648388 2.192934 2.440628 2.531024 +1.033724 1.436166 1.744094 2.132259 2.544044 2.618903 +1.082839 1.455838 1.597987 2.003093 2.628262 2.736133 +1.021616 1.380799 1.537805 2.007919 2.656179 2.725478 +0.934605 1.338311 1.721281 2.021380 2.452658 2.635942 +0.974987 1.280603 1.740482 1.988643 2.383388 2.588543 +0.963572 1.358626 1.775093 2.077077 2.374408 2.552547 +1.339392 1.606067 1.941038 2.159799 2.446540 2.587306 +1.268637 1.604063 1.940062 2.178915 2.487660 2.597501 +1.129807 1.522621 1.872974 2.075068 2.479707 2.633172 +1.135346 1.422302 1.865991 1.945310 2.523357 2.686142 +1.135540 1.562266 1.768152 1.922013 2.506054 2.736130 +1.173335 1.637622 1.845405 1.974533 2.379511 2.627590 +1.223094 1.477161 1.799506 1.945290 2.603703 2.697773 +1.285652 1.781420 1.972532 2.335252 2.649620 2.719252 +1.516066 1.862470 2.084987 2.386138 2.563370 2.650523 +1.622511 1.800884 2.074682 2.371099 2.494100 2.608952 +1.644218 1.730914 2.235251 2.344625 2.460604 2.621775 +1.646495 1.743836 2.118671 2.334538 2.487649 2.597304 +1.574474 1.666941 2.165682 2.294626 2.463016 2.642929 +1.568529 1.662679 2.068377 2.240071 2.374784 2.534291 +1.501088 1.675567 2.019200 2.253935 2.403957 2.560212 +1.333222 1.481857 1.810385 2.032438 2.235271 2.464023 +1.184189 1.376469 1.743067 2.077177 2.247370 2.436639 +0.860298 1.017970 1.399466 2.031356 2.445832 2.512045 +0.987543 1.187216 1.324668 2.086564 2.440265 2.507859 +0.987539 1.057392 1.400508 2.291033 2.462013 2.534542 +1.072567 1.168456 1.335425 2.281555 2.595283 2.641991 +1.042424 1.219473 1.328751 2.104394 2.481407 2.544847 +1.075840 1.204873 1.370286 2.206558 2.509524 2.557197 +1.075906 1.188083 1.414337 2.320102 2.530914 2.589422 +1.076149 1.267397 1.411982 2.218421 2.452294 2.540946 +1.154549 1.314810 1.500389 2.300970 2.505189 2.569795 +1.170382 1.300375 1.477782 2.201078 2.418226 2.511009 +1.164826 1.290783 1.436432 2.042173 2.434597 2.517154 +1.193857 1.293191 1.527594 2.008805 2.370813 2.473257 +1.263542 1.385669 1.596130 2.048764 2.427787 2.504082 +1.305187 1.421012 1.658876 2.095853 2.429425 2.518576 +1.378304 1.494361 1.710276 2.078040 2.477964 2.559482 +1.333727 1.475263 1.674044 2.039635 2.446712 2.527050 +1.346152 1.468526 1.673673 1.961087 2.462599 2.567158 +1.324261 1.466904 1.747093 2.009440 2.480558 2.571278 +1.306921 1.411049 1.740784 2.032398 2.466338 2.575794 +1.277304 1.408311 1.715677 1.956928 2.505971 2.597300 +1.239174 1.409858 1.635688 1.843138 2.511337 2.592493 +1.262271 1.377900 1.665878 1.785276 2.414923 2.519101 +1.223772 1.378608 1.706935 1.812010 2.472106 2.553503 +1.248275 1.560969 1.688454 2.024421 2.464682 2.532083 +1.551147 1.674831 1.863917 2.242605 2.425666 2.512306 +1.613538 1.736360 1.915832 2.284340 2.505100 2.575495 +1.675654 1.764549 2.013262 2.308596 2.479308 2.570877 +1.676790 1.732192 2.216913 2.350744 2.516807 2.584938 +1.672091 1.768085 2.170300 2.277530 2.411164 2.492525 +1.645851 1.881233 2.216349 2.320633 2.460809 2.564931 +1.714095 1.933206 2.220117 2.327698 2.453033 2.557432 +1.864162 1.965600 2.211890 2.354075 2.451546 2.543697 +1.840509 1.980901 2.141357 2.275924 2.487833 2.607026 +1.281628 1.508538 1.878088 2.153311 2.510390 2.597723 +1.285937 1.558518 1.895925 2.154502 2.510047 2.628884 +1.179704 1.457966 1.805824 2.088695 2.536834 2.648347 +1.213178 1.474144 1.796481 1.886388 2.426441 2.597142 +1.175759 1.566628 1.786803 1.959634 2.443976 2.621808 +1.241280 1.495544 1.772941 1.959431 2.513639 2.611886 +1.252864 1.547349 1.741300 1.873671 2.447277 2.674639 +1.234254 1.437033 1.742154 1.835750 2.372173 2.581494 +1.262397 1.351279 1.710277 1.833486 2.308910 2.583598 +1.330861 1.424104 1.673893 1.802977 2.271847 2.556762 +1.374920 1.473192 1.703358 1.804519 2.374494 2.625833 +1.350424 1.477644 1.741927 1.869579 2.468162 2.637851 +1.299448 1.409270 1.707326 1.828822 2.412618 2.660075 +1.283675 1.413183 1.694008 1.913840 2.235005 2.663358 +1.131349 1.545449 1.738197 1.927132 2.242548 2.529539 +1.310395 1.445321 1.800815 1.941760 2.224181 2.430698 +1.207823 1.407710 1.792289 1.897833 2.278582 2.588793 +1.172078 1.380374 1.769606 1.870709 2.420713 2.665411 +1.050374 1.292916 1.708676 1.815571 2.398301 2.647835 +1.012196 1.352840 1.710467 1.798435 2.501052 2.622110 +0.949688 1.511315 1.802233 2.051775 2.386590 2.543931 +1.239527 1.523312 1.992644 2.175922 2.535838 2.663321 +1.170409 1.423959 1.918088 2.072957 2.371327 2.600694 +1.153282 1.631638 1.943662 2.041389 2.426287 2.527936 +1.130992 1.687340 1.913097 1.982416 2.366644 2.592156 +0.876015 1.539120 1.952815 2.040387 2.354192 2.592474 +0.741027 1.330783 2.010264 2.088976 2.406380 2.512408 +0.692068 1.220984 1.966843 2.053168 2.527609 2.625367 +0.697907 1.406778 2.016010 2.085819 2.573177 2.652342 +0.747161 1.542479 1.982188 2.091091 2.573313 2.614600 +0.759939 1.518111 1.938220 2.162963 2.534355 2.639085 +0.752015 1.445930 2.097743 2.150626 2.479886 2.587138 +0.804190 1.428522 2.012448 2.195806 2.470749 2.577263 +0.757784 1.356544 1.878177 2.232246 2.530996 2.630296 +0.782189 1.251703 1.766911 2.206553 2.564453 2.617695 +0.692136 1.308291 1.593024 1.842927 2.504334 2.652647 +0.779817 1.264995 1.689687 1.803686 2.530498 2.669456 +0.774734 1.199620 1.649586 1.726576 2.437097 2.591528 +0.885025 1.311938 1.646470 1.739192 2.578721 2.671994 +0.949387 1.387109 1.641927 1.762570 2.528769 2.585787 +1.012043 1.455355 1.666729 1.752575 2.434270 2.553516 +1.104075 1.529375 1.682092 1.973044 2.345511 2.511577 +1.423997 1.619409 1.995513 2.298913 2.430779 2.521288 +1.582461 1.832072 2.275101 2.383131 2.482800 2.539316 +1.706366 2.001667 2.300029 2.394812 2.486966 2.586945 +1.532256 1.933761 2.284009 2.422313 2.622936 2.706043 +1.678938 1.889060 2.338973 2.512967 2.632369 2.679498 +1.634405 1.783714 2.124182 2.462997 2.610348 2.691361 +1.618353 1.751021 2.026128 2.418017 2.609402 2.678953 +1.565199 1.794303 1.902067 2.405664 2.629332 2.696870 +1.282138 1.591250 1.852032 2.314230 2.617777 2.722940 +1.220365 1.421679 1.694336 1.881742 2.556796 2.653179 +1.139402 1.299007 1.622371 1.770432 2.543866 2.640704 +1.214491 1.467423 1.628034 1.794008 2.563409 2.691705 +1.059626 1.521805 1.631948 1.865161 2.601036 2.683659 +1.180200 1.536587 1.671861 2.137961 2.587647 2.638393 +1.213651 1.582110 1.709505 2.157513 2.476799 2.574007 +1.248459 1.553050 1.645298 1.897537 2.577761 2.681279 +1.340584 1.601427 1.679985 1.889143 2.647088 2.755132 +1.194554 1.575563 1.697528 1.801365 2.596516 2.752368 +1.152988 1.531378 1.716414 1.812718 2.417149 2.696455 +1.175284 1.565269 1.657415 1.734779 2.517977 2.671209 +1.315878 1.515976 1.775170 2.058078 2.307304 2.449295 +1.247131 1.381271 1.568357 1.857012 2.157278 2.435014 +1.240254 1.383648 1.580575 1.991473 2.303569 2.411055 +1.286797 1.385847 1.730704 2.067540 2.326906 2.473042 +1.204107 1.337886 1.665492 2.038754 2.231416 2.543395 +1.182343 1.312111 1.522260 1.971028 2.237772 2.483629 +1.095429 1.319910 1.465710 2.032595 2.279936 2.523638 +1.152497 1.294508 1.458307 2.032534 2.306031 2.406760 +0.991441 1.274662 1.428222 1.940576 2.399100 2.509374 +0.850157 1.274723 1.453729 1.893527 2.382294 2.477664 +0.936060 1.313211 1.426739 1.888973 2.551745 2.604392 +0.972592 1.328333 1.432833 2.011050 2.573671 2.613672 +0.909400 1.422756 1.494628 2.073945 2.620634 2.662685 +0.828475 1.431701 1.569493 2.054254 2.622115 2.669741 +0.779249 1.375673 1.476635 1.949187 2.558998 2.622137 +0.815710 1.472687 1.650494 2.000905 2.565206 2.611683 +0.822357 1.333508 1.551653 1.864184 2.595847 2.706122 +0.736497 1.259887 1.490815 1.882220 2.494405 2.619982 +0.902240 1.431002 1.520505 1.910794 2.605395 2.678585 +0.900488 1.363048 1.461814 2.009771 2.665876 2.717180 +1.015394 1.361530 1.474854 1.920438 2.637482 2.702570 +0.950918 1.335184 1.440876 1.874351 2.678915 2.746244 +0.965674 1.306906 1.412895 1.727184 2.656317 2.739472 +1.121335 1.291332 1.412980 1.731394 2.624577 2.735999 +1.135486 1.299970 1.448634 1.635793 2.616713 2.687744 +1.120410 1.248201 1.383680 1.579760 2.397167 2.585237 +1.113415 1.294499 1.482373 1.602789 2.394835 2.634809 +1.241746 1.318174 1.473167 1.577503 2.426003 2.649775 +1.184376 1.272893 1.497747 1.608053 2.144455 2.537267 +1.283135 1.377322 1.543041 1.645177 2.105790 2.490904 +1.138008 1.380756 1.560480 1.640979 2.271006 2.625523 +1.243884 1.351538 1.603070 1.739791 2.038080 2.447512 +1.267258 1.509957 1.641649 1.831984 2.331327 2.472826 +1.276365 1.476401 1.625021 1.930342 2.319377 2.524369 +1.222679 1.559407 1.669982 1.805473 2.326911 2.580278 +1.265218 1.503892 1.830979 2.091536 2.396722 2.569088 +1.256047 1.528877 1.853033 2.106171 2.365139 2.503280 +1.236501 1.479118 1.728297 2.041463 2.528558 2.612900 +1.220644 1.605193 1.713770 1.950925 2.597639 2.649495 +1.255546 1.591871 1.706750 2.062713 2.561381 2.626901 +1.307080 1.580016 1.653547 1.941293 2.552727 2.643706 +1.310968 1.512803 1.656527 1.839190 2.592097 2.677706 +1.188596 1.316082 1.579370 1.690772 2.438500 2.641881 +1.114671 1.235994 1.591973 1.749192 2.359438 2.545213 +1.080067 1.277132 1.727997 2.041411 2.337068 2.549786 +1.032222 1.250210 1.680999 1.998340 2.318533 2.502200 +1.064719 1.159182 1.666731 2.019294 2.256570 2.573467 +1.026313 1.146367 1.672929 2.054063 2.433228 2.615716 +0.942929 1.092789 1.613522 2.077784 2.365142 2.499737 +0.980250 1.254777 1.492003 1.801193 2.445325 2.575711 +0.957395 1.251868 1.378337 1.744574 2.502966 2.665866 +0.840336 1.267995 1.397728 1.827984 2.555867 2.651285 +1.009902 1.175808 1.277770 2.048361 2.637904 2.700904 +0.883840 1.026780 1.146692 1.893681 2.518692 2.610564 +0.997171 1.138289 1.246408 1.837527 2.549820 2.642693 +0.992125 1.178874 1.282272 1.974399 2.559112 2.612968 +1.067589 1.255803 1.359021 1.963939 2.541420 2.596308 +1.086327 1.329068 1.432326 1.928840 2.528332 2.598239 +1.100351 1.345579 1.469529 1.942358 2.469723 2.561680 +1.101019 1.374382 1.561144 1.942560 2.484288 2.552996 +1.177497 1.455165 1.571485 1.943496 2.500309 2.550902 +1.260768 1.477903 1.601611 2.024022 2.487425 2.554237 +1.216439 1.470082 1.639601 1.957212 2.523832 2.588189 +1.257980 1.407199 1.651434 1.910722 2.464200 2.620868 +1.162091 1.436543 1.682166 1.896924 2.447302 2.677069 +1.250215 1.484632 1.653870 1.930473 2.493894 2.633436 +1.237977 1.513389 1.648781 1.880344 2.504094 2.581491 +1.223199 1.412456 1.634083 1.797183 2.451210 2.620618 +1.258745 1.358397 1.627717 1.726099 2.428287 2.621329 +1.234919 1.345606 1.552151 1.708675 2.385742 2.606052 +1.186417 1.341808 1.636911 1.754679 2.429716 2.544394 +1.216260 1.305888 1.632777 1.755770 2.320806 2.583785 +1.165343 1.284152 1.560527 1.682036 2.243217 2.494673 +1.085859 1.215111 1.590602 1.715333 2.231633 2.527227 +1.091652 1.384156 1.655159 1.716563 2.302785 2.535552 +1.060328 1.239077 1.627213 1.737571 2.420162 2.599147 +1.090079 1.394777 1.682485 1.799904 2.331813 2.532862 +1.169038 1.568116 1.785725 2.031553 2.372207 2.497865 +1.241903 1.662080 1.822491 2.169543 2.424542 2.525186 +1.040287 1.690414 1.853098 2.038593 2.472015 2.535969 +0.974879 1.689063 1.850137 2.151312 2.507415 2.562538 +0.879683 1.743838 1.968060 2.161147 2.463916 2.545849 +0.790116 1.794412 2.037297 2.159739 2.508403 2.564883 +0.793374 1.796169 2.060524 2.331075 2.591299 2.648578 +0.859332 1.800464 2.025451 2.200641 2.534316 2.611320 +0.825206 1.895126 2.063579 2.264528 2.514030 2.610797 +0.974068 1.904781 2.002639 2.315848 2.539666 2.595157 +0.961311 1.821283 2.015215 2.274545 2.600786 2.653365 +0.971040 1.737011 1.914953 2.243896 2.572362 2.612602 +0.999552 1.817902 1.953097 2.178591 2.574331 2.626275 +0.977300 1.756036 1.929137 2.135346 2.424209 2.556085 +1.065543 1.747638 1.899169 2.309745 2.587388 2.630589 +1.077057 1.655717 1.868334 2.238603 2.508913 2.571841 +1.077829 1.716423 1.791462 2.266223 2.615485 2.654046 +1.276021 1.713383 1.788825 2.101442 2.625616 2.679590 +1.263173 1.699086 1.776931 2.035107 2.610346 2.653421 +1.297137 1.667668 1.744010 2.030119 2.608062 2.678066 +1.262373 1.626459 1.781159 2.026178 2.636261 2.699179 +1.318031 1.657767 1.763578 1.939043 2.575450 2.705613 +0.980669 1.555891 1.722977 1.978553 2.568958 2.638420 +0.840013 1.463397 1.772781 2.164864 2.566894 2.666228 +0.832158 1.505750 1.937891 2.233974 2.630131 2.694884 +0.745541 1.530097 2.060727 2.162996 2.619130 2.692130 +0.832050 1.597985 2.127678 2.196662 2.528870 2.619304 +0.820544 1.616482 2.044842 2.133557 2.587661 2.668155 +0.789348 1.638569 1.996032 2.212800 2.572934 2.615430 +0.806795 1.742530 2.043915 2.183841 2.603407 2.660269 +0.843597 1.761377 1.998823 2.132969 2.596500 2.673163 +0.927714 1.759399 1.987169 2.201990 2.591677 2.650810 +1.070504 1.767115 1.978295 2.227191 2.642696 2.686380 +1.022852 1.856828 1.989822 2.217218 2.480936 2.574687 +0.886409 1.742690 1.863071 2.054904 2.542328 2.627054 +0.996501 1.553639 1.808061 1.948514 2.516726 2.605745 +1.218221 1.525015 1.878023 2.107205 2.423952 2.578894 +1.274705 1.491779 1.906237 2.101242 2.455724 2.563566 +1.319477 1.587082 1.879825 2.240443 2.439462 2.547992 +1.474513 1.699004 1.929257 2.228217 2.451873 2.563132 +1.545274 1.722709 1.892103 2.169162 2.520241 2.602958 +1.546160 1.668894 1.961486 2.212079 2.505999 2.621266 +1.535625 1.699287 2.016356 2.250824 2.550093 2.645619 +1.583411 1.687746 2.051949 2.332633 2.491721 2.598036 +1.500933 1.594052 1.929231 2.259850 2.422622 2.547761 +1.464918 1.614783 1.881701 2.216729 2.528952 2.623217 +1.406726 1.605026 1.805977 2.222725 2.509009 2.587841 +1.106418 1.527781 1.730182 2.045916 2.549464 2.637497 +1.008151 1.439718 1.665472 1.941372 2.652442 2.751095 +0.971347 1.402084 1.708896 1.953274 2.613325 2.684989 +0.946352 1.501044 1.672151 1.975870 2.527905 2.585573 +0.909229 1.453576 1.713898 2.065638 2.529315 2.613161 +0.975079 1.523288 1.839559 2.138553 2.498690 2.583725 +0.899524 1.552407 1.831637 2.068567 2.544880 2.611180 +0.805175 1.462327 1.860536 2.101344 2.570440 2.654850 +0.859011 1.514531 1.892400 2.012520 2.579679 2.648521 +0.763528 1.522433 1.902539 2.018517 2.556446 2.609582 +0.814387 1.494849 1.941715 2.077981 2.540329 2.612839 +0.853805 1.401871 1.942985 2.088086 2.488394 2.578614 +0.782036 1.348553 1.935300 2.025076 2.516816 2.598046 +0.754386 1.384949 1.900243 1.999656 2.600374 2.663763 +0.746921 1.421143 1.934567 2.038908 2.553273 2.612298 +0.731911 1.450761 1.924508 2.032744 2.497904 2.556491 +0.706741 1.543731 1.876596 1.992525 2.510176 2.565960 +0.852548 1.549952 1.899169 2.226497 2.522787 2.583939 +0.885718 1.656999 1.865791 2.162889 2.467388 2.553769 +0.951271 1.641721 1.813995 2.153059 2.427099 2.499612 +0.928485 1.502784 1.809440 2.224767 2.472400 2.553921 +0.816616 1.391098 1.665580 2.176141 2.510722 2.582819 +0.915934 1.390936 1.767514 2.169548 2.471665 2.652526 +1.115341 1.362311 1.722592 2.033033 2.406363 2.601875 +1.138664 1.252976 1.684517 1.937366 2.384311 2.623900 +1.084318 1.211953 1.633639 1.889936 2.413095 2.626228 +1.126224 1.344921 1.648605 2.071123 2.484189 2.605656 +1.123905 1.461556 1.845099 2.172457 2.462662 2.605139 +1.132557 1.468636 1.740223 2.184934 2.467938 2.580103 +1.148248 1.506173 1.676602 2.049290 2.446774 2.565419 +0.999544 1.404698 1.641769 1.863324 2.523843 2.592114 +0.932167 1.395984 1.709428 1.845739 2.524792 2.599616 +0.870085 1.476327 1.721511 1.897091 2.490256 2.593759 +0.891107 1.429106 1.789728 1.958425 2.519104 2.604987 +0.855550 1.421268 1.900935 2.011013 2.546617 2.609760 +0.895038 1.482579 1.873572 1.974828 2.519429 2.584450 +0.809092 1.486499 1.902272 2.000876 2.518374 2.597261 +0.808211 1.460169 1.881579 1.961398 2.468386 2.616332 +0.774237 1.471857 1.901217 2.013761 2.564870 2.665691 +0.800018 1.576948 1.938176 2.043718 2.494383 2.630097 +0.804705 1.570759 1.889356 1.975489 2.447653 2.555191 +0.840709 1.603377 1.827077 2.026318 2.442892 2.492424 +0.887288 1.536144 1.781616 1.952198 2.500811 2.576512 +0.847527 1.504701 1.792948 1.891589 2.578888 2.637316 +0.959025 1.533821 1.821486 1.979739 2.463750 2.544302 +1.036319 1.640786 1.886024 1.962887 2.358662 2.577756 +0.981142 1.486738 1.733096 1.878277 2.537973 2.610473 +1.046486 1.438515 1.740840 1.850012 2.590883 2.684137 +1.103404 1.489782 1.738241 1.817496 2.588368 2.701052 +1.176925 1.473684 1.732853 1.823270 2.524527 2.733540 +1.173320 1.438383 1.696555 1.792536 2.580785 2.665770 +1.134955 1.421862 1.604070 1.756135 2.617948 2.706644 +1.136007 1.384178 1.699100 1.855319 2.591013 2.683215 +1.201710 1.421935 1.737864 2.011199 2.540959 2.681093 +1.227450 1.624461 2.125226 2.340556 2.593435 2.671453 +1.265133 1.765689 2.131338 2.391774 2.613959 2.699849 +1.342282 1.581411 1.979244 2.297759 2.520391 2.602258 +1.449013 1.725546 2.176279 2.354739 2.538758 2.627319 +1.418726 1.898681 2.206330 2.275600 2.488746 2.586794 +1.555706 1.837600 2.165743 2.346188 2.530178 2.628757 +1.444437 1.790050 1.911014 2.301915 2.468862 2.540557 +1.378052 1.668499 1.845265 2.324889 2.537708 2.601471 +1.394741 1.682710 1.817346 2.075533 2.512120 2.566889 +1.297199 1.655884 1.825405 2.062105 2.513307 2.577371 +1.280659 1.669901 1.824567 2.168209 2.528166 2.601986 +1.306896 1.600808 1.767971 2.095291 2.509869 2.606002 +1.257678 1.559755 1.787804 2.076895 2.540388 2.627179 +1.196849 1.597550 1.817421 2.152662 2.580796 2.651246 +1.235935 1.676643 1.942307 2.326482 2.561542 2.645593 +1.189058 1.818895 2.081496 2.366454 2.608018 2.672086 +1.427589 1.885421 2.264907 2.424220 2.571371 2.651155 +1.714473 1.937868 2.390009 2.457149 2.552016 2.601930 +1.874136 2.073506 2.370468 2.511263 2.709177 2.749495 +1.647818 1.987798 2.281909 2.412099 2.604693 2.674821 +1.596366 1.881529 2.193995 2.380524 2.511918 2.584564 +1.555508 1.775218 2.064094 2.325699 2.512934 2.599262 +1.330054 1.712961 1.917624 2.285900 2.466591 2.579279 +0.990071 1.410874 1.632331 1.965889 2.466882 2.580417 +0.925150 1.299025 1.551401 1.897486 2.498481 2.645212 +0.968080 1.367127 1.520360 1.988159 2.313473 2.546943 +0.974374 1.283811 1.474810 2.078302 2.331089 2.455153 +1.000624 1.299150 1.415675 1.955760 2.261550 2.354258 +0.964045 1.136490 1.305931 1.936406 2.197537 2.299418 +1.013087 1.201143 1.372664 1.820179 2.063576 2.210659 +1.086478 1.216705 1.476655 1.604039 1.855963 2.324503 +1.090160 1.201207 1.460778 1.562225 2.016093 2.458980 +1.133754 1.257469 1.407186 1.787681 2.289532 2.530854 +1.134831 1.341221 1.636293 1.813775 2.219453 2.584652 +0.952747 1.300930 1.616891 1.751014 2.352113 2.547879 +1.078704 1.490043 1.571579 1.800532 2.468175 2.650436 +1.239045 1.333032 1.551379 1.707824 2.242922 2.604251 +1.176517 1.299114 1.588881 1.714081 2.128856 2.533523 +1.135831 1.253056 1.538412 1.634480 2.258093 2.593874 +1.092382 1.253236 1.541772 1.679875 2.423197 2.617584 +1.142663 1.256402 1.528284 1.629676 2.391580 2.589689 +1.172793 1.281248 1.479204 1.608878 2.335938 2.593681 +1.146782 1.251953 1.432916 1.553285 2.238941 2.534180 +1.109946 1.231415 1.412105 1.516055 2.308569 2.599903 +1.120273 1.235535 1.425736 1.509519 2.435529 2.643814 +1.085869 1.189296 1.392718 1.494347 2.129342 2.508989 +1.020500 1.173144 1.440965 1.574421 2.335855 2.524051 +1.040551 1.174338 1.525717 1.693110 2.493748 2.632352 +1.034516 1.205262 1.365087 1.513000 2.471788 2.578008 +1.079383 1.204002 1.332428 1.456604 2.502131 2.665633 +1.088863 1.236949 1.357003 1.564945 2.602020 2.707576 +1.106792 1.262402 1.367273 1.823952 2.598579 2.676300 +1.085013 1.233527 1.311463 1.730333 2.560087 2.690320 +1.069205 1.180224 1.343020 1.474834 2.268046 2.544311 +1.039392 1.375617 1.721445 2.038018 2.463998 2.600812 +1.267853 1.384109 1.659902 1.934021 2.207761 2.424577 +1.225276 1.316621 1.678147 1.819230 2.165345 2.498548 +1.114141 1.283029 1.655518 1.879671 2.352472 2.553537 +1.094762 1.370017 1.799126 2.082377 2.469494 2.578819 +1.041250 1.472757 1.748735 2.047588 2.511699 2.589828 +1.071665 1.456546 1.700524 1.927317 2.441484 2.607003 +0.929006 1.487241 1.669550 1.885619 2.544274 2.628318 +0.844366 1.339712 1.812456 2.300208 2.566012 2.631255 +0.761441 1.279951 1.670446 2.006350 2.526824 2.607557 +0.716643 1.374843 1.843436 2.126958 2.552993 2.613146 +0.749967 1.598458 1.883266 2.050443 2.579184 2.614111 +0.759376 1.596383 1.929103 1.984550 2.566734 2.654207 +0.724977 1.682905 1.888292 2.034796 2.503861 2.565502 +0.812327 1.669865 1.961771 2.102146 2.538781 2.598559 +0.767334 1.594629 1.984319 2.133419 2.501689 2.557813 +0.760230 1.650647 1.928366 2.094047 2.565241 2.596082 +0.766762 1.648062 1.858552 2.078593 2.587079 2.608213 +0.860938 1.629253 1.824855 2.067350 2.563373 2.603209 +0.960953 1.583632 1.752206 2.078444 2.555531 2.628507 +1.007927 1.548004 1.734955 2.185660 2.489350 2.551445 +1.040401 1.471117 1.643519 2.051558 2.508524 2.579168 +1.096025 1.457427 1.604009 1.926200 2.482033 2.552204 +1.130428 1.431534 1.592806 2.014740 2.510652 2.567779 +1.197898 1.465481 1.622929 2.075950 2.507052 2.582750 +1.258831 1.504797 1.659109 1.970653 2.595750 2.685651 +1.315451 1.467446 1.705718 1.898634 2.602572 2.704978 +1.272475 1.431894 1.712848 1.940258 2.650379 2.717166 +1.278865 1.528652 1.796202 1.995202 2.501761 2.587606 +1.458616 1.693943 2.067903 2.264838 2.506857 2.623939 +1.718797 1.909611 2.147601 2.354174 2.485581 2.591269 +1.813873 1.875483 2.097637 2.329683 2.497798 2.596247 +1.744286 1.859449 2.043169 2.284589 2.430897 2.538572 +1.514180 1.808296 1.933791 2.234651 2.462232 2.546237 +1.489264 1.781194 1.908004 2.144484 2.418589 2.513858 +1.434785 1.679793 1.817348 2.105365 2.431372 2.528241 +1.469581 1.589507 1.813510 2.213129 2.440502 2.520511 +1.496287 1.640049 1.893865 2.298621 2.484705 2.576207 +1.333417 1.584728 1.893019 2.121814 2.525345 2.632617 +1.518722 1.735840 1.956529 2.176426 2.465338 2.572342 +1.520953 1.742556 2.010582 2.133578 2.447458 2.566704 +1.458119 1.692227 2.001920 2.120543 2.431042 2.565112 +1.526915 1.662389 2.025135 2.125056 2.537873 2.626810 +1.498303 1.644212 1.960732 2.103288 2.440309 2.572412 +1.415476 1.548286 1.770800 2.099931 2.450265 2.599463 +1.367188 1.460632 1.739482 2.074030 2.551953 2.639997 diff --git a/gr-vocoder/lib/codec2/codebook/lsp8910.txt b/gr-vocoder/lib/codec2/codebook/lsp8910.txt deleted file mode 100644 index 759136bfec..0000000000 --- a/gr-vocoder/lib/codec2/codebook/lsp8910.txt +++ /dev/null @@ -1,65 +0,0 @@ -3 64 -2.048073 2.534502 2.645915 -2.019670 2.269744 2.605462 -1.961101 2.329646 2.562857 -1.968573 2.532712 2.616918 -2.183480 2.514381 2.629582 -2.259379 2.516615 2.620410 -2.172791 2.462460 2.567064 -2.097666 2.303933 2.421685 -2.052990 2.353242 2.546992 -2.043642 2.232362 2.499262 -2.106151 2.393131 2.488401 -2.099167 2.437862 2.558655 -2.013877 2.422875 2.530071 -2.033848 2.483776 2.584598 -2.114474 2.516856 2.602372 -2.229214 2.584056 2.678855 -2.131151 2.584299 2.674845 -1.472721 2.477091 2.630241 -2.010907 2.598415 2.682989 -2.353653 2.524066 2.619773 -2.419897 2.623938 2.699605 -2.319080 2.602148 2.689044 -1.860342 2.503881 2.616576 -1.910517 2.386693 2.610126 -1.748689 2.371809 2.496542 -1.618495 2.403425 2.554956 -1.844073 2.437026 2.533443 -1.924810 2.388543 2.502698 -1.937227 2.258363 2.501697 -1.687554 2.209123 2.545239 -1.851950 2.278628 2.565632 -1.868154 2.330150 2.444883 -1.874180 2.213118 2.351940 -1.757311 2.030626 2.433836 -1.650306 2.152371 2.243421 -1.612794 1.884686 2.339313 -1.745431 2.278895 2.389449 -1.590923 2.304155 2.408510 -1.475982 2.275548 2.509897 -1.508695 2.045463 2.455520 -1.872054 2.061777 2.246202 -1.983947 2.159155 2.445535 -1.745180 2.483765 2.593698 -1.900116 2.079600 2.407479 -1.841672 2.167042 2.486827 -1.932912 2.148464 2.569850 -2.134174 2.363673 2.584252 -2.106094 2.450645 2.638417 -1.954135 2.460313 2.666512 -1.907634 2.573801 2.674025 -1.625579 2.539569 2.656363 -1.785866 2.572616 2.676082 -1.798447 2.376454 2.624298 -2.020033 2.397244 2.619868 -1.946581 2.468791 2.564185 -2.008920 2.342400 2.469132 -1.983846 2.271044 2.395408 -1.988039 2.154150 2.317920 -2.077197 2.216622 2.389101 -2.117255 2.283907 2.512242 -2.177233 2.334622 2.458268 -2.214655 2.425510 2.620013 -2.199931 2.390272 2.520731 -2.271755 2.448682 2.552649 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt1.txt b/gr-vocoder/lib/codec2/codebook/lspdt1.txt new file mode 100644 index 0000000000..ba30880038 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt1.txt @@ -0,0 +1,9 @@ +1 8 +-75 +-50 +-25 + 0 + 25 + 50 + 75 +100 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt10.txt b/gr-vocoder/lib/codec2/codebook/lspdt10.txt new file mode 100644 index 0000000000..e72c16c92d --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt10.txt @@ -0,0 +1,3 @@ +1 2 +-50 + 50 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt2.txt b/gr-vocoder/lib/codec2/codebook/lspdt2.txt new file mode 100644 index 0000000000..ba30880038 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt2.txt @@ -0,0 +1,9 @@ +1 8 +-75 +-50 +-25 + 0 + 25 + 50 + 75 +100 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt3.txt b/gr-vocoder/lib/codec2/codebook/lspdt3.txt new file mode 100644 index 0000000000..7ebefd92d1 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt3.txt @@ -0,0 +1,5 @@ +1 4 +-50 + 0 + 50 + 100 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt4.txt b/gr-vocoder/lib/codec2/codebook/lspdt4.txt new file mode 100644 index 0000000000..7ebefd92d1 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt4.txt @@ -0,0 +1,5 @@ +1 4 +-50 + 0 + 50 + 100 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt5.txt b/gr-vocoder/lib/codec2/codebook/lspdt5.txt new file mode 100644 index 0000000000..7ebefd92d1 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt5.txt @@ -0,0 +1,5 @@ +1 4 +-50 + 0 + 50 + 100 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt6.txt b/gr-vocoder/lib/codec2/codebook/lspdt6.txt new file mode 100644 index 0000000000..7ebefd92d1 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt6.txt @@ -0,0 +1,5 @@ +1 4 +-50 + 0 + 50 + 100 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt7.txt b/gr-vocoder/lib/codec2/codebook/lspdt7.txt new file mode 100644 index 0000000000..e72c16c92d --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt7.txt @@ -0,0 +1,3 @@ +1 2 +-50 + 50 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt8.txt b/gr-vocoder/lib/codec2/codebook/lspdt8.txt new file mode 100644 index 0000000000..e72c16c92d --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt8.txt @@ -0,0 +1,3 @@ +1 2 +-50 + 50 diff --git a/gr-vocoder/lib/codec2/codebook/lspdt9.txt b/gr-vocoder/lib/codec2/codebook/lspdt9.txt new file mode 100644 index 0000000000..e72c16c92d --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspdt9.txt @@ -0,0 +1,3 @@ +1 2 +-50 + 50 diff --git a/gr-vocoder/lib/codec2/codebook/lspjnd5-10.txt b/gr-vocoder/lib/codec2/codebook/lspjnd5-10.txt new file mode 100644 index 0000000000..e4e500c160 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspjnd5-10.txt @@ -0,0 +1,8317 @@ +6 3369 +1400.0 2000.0 2400.0 2500.0 3300.0 3400.0 +1400.0 1900.0 2400.0 2500.0 3200.0 3400.0 +1400.0 1800.0 2400.0 2500.0 3200.0 3300.0 +1400.0 1800.0 2400.0 2500.0 3300.0 3400.0 +1400.0 2100.0 2400.0 2600.0 3300.0 3400.0 +1400.0 1900.0 2300.0 2600.0 3200.0 3300.0 +1400.0 1900.0 2100.0 2600.0 3100.0 3200.0 +1600.0 2100.0 2400.0 2500.0 3200.0 3300.0 +1500.0 1900.0 2300.0 2600.0 3100.0 3200.0 +1600.0 1800.0 2400.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2300.0 2500.0 3200.0 3300.0 +1800.0 1900.0 2300.0 2500.0 3200.0 3300.0 +1800.0 2000.0 2300.0 2500.0 3300.0 3400.0 +1900.0 2000.0 2200.0 2600.0 3300.0 3400.0 +1700.0 2000.0 2700.0 2900.0 3200.0 3300.0 +1700.0 2100.0 2600.0 2900.0 3200.0 3300.0 +1600.0 2000.0 2500.0 2800.0 3200.0 3400.0 +1500.0 1800.0 2300.0 2400.0 3200.0 3300.0 +1400.0 1700.0 2200.0 2400.0 3200.0 3300.0 +1300.0 1700.0 2200.0 2300.0 3200.0 3300.0 +1300.0 1600.0 2200.0 2300.0 3200.0 3300.0 +1200.0 1600.0 2200.0 2400.0 3200.0 3300.0 +1200.0 1600.0 2200.0 2300.0 3200.0 3300.0 +1200.0 1500.0 2200.0 2300.0 3100.0 3300.0 +1200.0 1500.0 2200.0 2300.0 3200.0 3300.0 +1300.0 1500.0 2100.0 2300.0 3000.0 3200.0 +1300.0 1600.0 2000.0 2200.0 3000.0 3200.0 +1400.0 1700.0 2000.0 2300.0 3100.0 3200.0 +1500.0 1700.0 2000.0 2300.0 3200.0 3300.0 +1300.0 1600.0 1900.0 2100.0 3100.0 3200.0 +1200.0 1500.0 2100.0 2300.0 3200.0 3300.0 +1500.0 1800.0 2000.0 2300.0 3000.0 3200.0 +1200.0 1500.0 2200.0 2400.0 3300.0 3400.0 +1200.0 1500.0 2200.0 2400.0 3200.0 3400.0 +1200.0 1500.0 2200.0 2400.0 3200.0 3300.0 +1300.0 1500.0 2300.0 2400.0 3200.0 3300.0 +1300.0 1500.0 2200.0 2500.0 3000.0 3200.0 +1300.0 1600.0 2300.0 2600.0 3000.0 3200.0 +1400.0 1800.0 2400.0 2600.0 3100.0 3200.0 +1700.0 2000.0 2500.0 2800.0 3200.0 3300.0 +1900.0 2200.0 2600.0 2700.0 3100.0 3200.0 +1900.0 2300.0 2600.0 2900.0 3200.0 3300.0 +2000.0 2300.0 2600.0 2900.0 3300.0 3400.0 +1900.0 2300.0 2500.0 2900.0 3300.0 3400.0 +1800.0 2300.0 2500.0 2800.0 3300.0 3400.0 +1600.0 1800.0 2400.0 2500.0 3200.0 3400.0 +1500.0 1800.0 2400.0 2600.0 3100.0 3400.0 +1800.0 2100.0 2600.0 2900.0 3300.0 3500.0 +2000.0 2500.0 2700.0 3000.0 3400.0 3500.0 +2200.0 2500.0 2700.0 3100.0 3300.0 3400.0 +2300.0 2500.0 2700.0 3100.0 3300.0 3400.0 +2100.0 2500.0 2600.0 3000.0 3200.0 3300.0 +2100.0 2400.0 2500.0 3000.0 3200.0 3300.0 +1700.0 2000.0 2300.0 2700.0 3100.0 3200.0 +1700.0 2000.0 2300.0 2800.0 3100.0 3300.0 +1600.0 1900.0 2200.0 2800.0 3000.0 3200.0 +1500.0 1900.0 2100.0 2700.0 3000.0 3200.0 +1400.0 1900.0 2000.0 2600.0 3000.0 3100.0 +1200.0 1600.0 2100.0 2400.0 3200.0 3300.0 +1500.0 1600.0 2300.0 2400.0 3200.0 3400.0 +1600.0 1700.0 2200.0 2400.0 3100.0 3400.0 +1600.0 1700.0 2200.0 2400.0 3200.0 3400.0 +1700.0 1800.0 2300.0 2400.0 3200.0 3400.0 +1700.0 1800.0 2300.0 2400.0 3200.0 3300.0 +1700.0 1800.0 2300.0 2400.0 3100.0 3200.0 +1700.0 1800.0 2200.0 2500.0 3100.0 3200.0 +1600.0 1800.0 2100.0 2400.0 3000.0 3100.0 +1500.0 1700.0 2100.0 2300.0 3000.0 3100.0 +1400.0 1700.0 2100.0 2500.0 3000.0 3200.0 +1000.0 1700.0 2300.0 2500.0 3200.0 3300.0 +1100.0 1700.0 2400.0 2500.0 3300.0 3400.0 +1500.0 2000.0 2300.0 2600.0 3000.0 3300.0 +1300.0 1600.0 1800.0 2600.0 2900.0 3100.0 +1300.0 1600.0 1900.0 2200.0 2900.0 3000.0 +1500.0 1700.0 2200.0 2500.0 2900.0 3000.0 +1500.0 1600.0 2100.0 2400.0 2900.0 3100.0 +1500.0 1600.0 2000.0 2600.0 3000.0 3100.0 +1600.0 1700.0 2100.0 2600.0 3100.0 3200.0 +1700.0 1900.0 2100.0 2500.0 3300.0 3400.0 +1700.0 1900.0 2200.0 2500.0 3300.0 3400.0 +1600.0 2000.0 2400.0 2600.0 3000.0 3300.0 +1700.0 2100.0 2400.0 2600.0 3100.0 3300.0 +1700.0 2100.0 2400.0 2600.0 3200.0 3400.0 +1400.0 1600.0 2300.0 2400.0 3300.0 3400.0 +1300.0 1400.0 2100.0 2200.0 2900.0 3200.0 +1000.0 1300.0 2200.0 2300.0 3200.0 3400.0 +1600.0 2000.0 2300.0 2600.0 2800.0 3100.0 +1600.0 2000.0 2300.0 2600.0 2900.0 3200.0 +1600.0 2000.0 2300.0 2600.0 3100.0 3300.0 +1700.0 2000.0 2300.0 2600.0 3100.0 3300.0 +1600.0 1900.0 2300.0 2500.0 3100.0 3400.0 +1500.0 1900.0 2300.0 2600.0 3000.0 3300.0 +1500.0 1900.0 2300.0 2600.0 3100.0 3300.0 +1500.0 2000.0 2300.0 2700.0 3100.0 3300.0 +2000.0 2500.0 2700.0 2900.0 3300.0 3400.0 +2000.0 2400.0 2600.0 2800.0 3300.0 3400.0 +1700.0 2300.0 2600.0 2800.0 3300.0 3400.0 +1400.0 1700.0 2400.0 2500.0 3200.0 3300.0 +1300.0 1600.0 2300.0 2500.0 3200.0 3300.0 +1300.0 1500.0 2000.0 2300.0 3200.0 3300.0 +1500.0 1800.0 2200.0 2400.0 2900.0 3300.0 +1500.0 1700.0 2200.0 2400.0 3000.0 3200.0 +1400.0 1800.0 2200.0 2400.0 3000.0 3300.0 +1400.0 1800.0 2200.0 2400.0 3000.0 3200.0 +1200.0 1500.0 2100.0 2400.0 3100.0 3300.0 +1300.0 1800.0 2200.0 2300.0 3300.0 3400.0 +1300.0 1700.0 2200.0 2400.0 3300.0 3400.0 +1400.0 1500.0 2300.0 2500.0 3100.0 3400.0 +1500.0 1600.0 2300.0 2500.0 3100.0 3300.0 +1500.0 1600.0 2400.0 2500.0 3100.0 3300.0 +1400.0 1800.0 2400.0 2500.0 3000.0 3300.0 +1300.0 1700.0 2100.0 2500.0 3000.0 3200.0 +1300.0 1600.0 2100.0 2500.0 3100.0 3200.0 +1300.0 1700.0 2200.0 2500.0 3100.0 3200.0 +1300.0 1600.0 2200.0 2500.0 3100.0 3300.0 +1300.0 1700.0 2300.0 2600.0 3200.0 3300.0 +1300.0 1700.0 2400.0 2500.0 3200.0 3400.0 +1500.0 1900.0 2500.0 2600.0 3200.0 3400.0 +1500.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1600.0 2100.0 2600.0 2900.0 3400.0 3500.0 +1600.0 1900.0 2500.0 2800.0 3300.0 3400.0 +1500.0 2000.0 2500.0 2600.0 3200.0 3300.0 +1600.0 2000.0 2500.0 2700.0 3100.0 3200.0 +1500.0 1700.0 2400.0 2700.0 3100.0 3200.0 +1500.0 1600.0 2400.0 2600.0 3100.0 3300.0 +1500.0 1600.0 2200.0 2400.0 3000.0 3200.0 +1500.0 1600.0 2200.0 2300.0 3000.0 3200.0 +1400.0 1700.0 2100.0 2300.0 3000.0 3100.0 +1700.0 1800.0 2300.0 2800.0 3100.0 3300.0 +1800.0 2100.0 2500.0 2800.0 3200.0 3300.0 +1800.0 2200.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2200.0 2500.0 2800.0 3200.0 3300.0 +1800.0 2200.0 2500.0 2800.0 3200.0 3300.0 +1600.0 2000.0 2300.0 2500.0 3000.0 3200.0 +1500.0 1900.0 2200.0 2500.0 3100.0 3200.0 +1500.0 1700.0 2200.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2200.0 2400.0 3000.0 3100.0 +1600.0 1700.0 2300.0 2400.0 3000.0 3100.0 +1600.0 1700.0 2300.0 2400.0 3000.0 3200.0 +1600.0 1700.0 2300.0 2400.0 2900.0 3100.0 +1600.0 1700.0 2300.0 2400.0 2900.0 3200.0 +1600.0 1700.0 2300.0 2500.0 2900.0 3200.0 +1500.0 1600.0 2300.0 2500.0 2900.0 3300.0 +1400.0 1500.0 2200.0 2500.0 3000.0 3300.0 +1200.0 1400.0 2300.0 2400.0 3000.0 3300.0 +1100.0 1400.0 2300.0 2400.0 3100.0 3300.0 +1200.0 1800.0 2400.0 2500.0 3300.0 3400.0 +1400.0 2000.0 2400.0 2700.0 3300.0 3400.0 +1600.0 2100.0 2500.0 2800.0 3300.0 3400.0 +1700.0 2300.0 2600.0 2900.0 3300.0 3400.0 +1400.0 2100.0 2400.0 2600.0 3100.0 3200.0 +1300.0 1600.0 2300.0 2500.0 3000.0 3200.0 +1200.0 1500.0 2100.0 2500.0 3000.0 3200.0 +1300.0 1700.0 2100.0 2300.0 2900.0 3200.0 +1500.0 1600.0 2200.0 2400.0 3000.0 3100.0 +1500.0 1600.0 2200.0 2500.0 3000.0 3200.0 +1600.0 1700.0 2200.0 2500.0 3100.0 3200.0 +1600.0 1700.0 2200.0 2500.0 3100.0 3300.0 +1600.0 1700.0 2200.0 2400.0 3100.0 3300.0 +1600.0 1700.0 2300.0 2500.0 3300.0 3400.0 +1700.0 1800.0 2300.0 2500.0 3300.0 3400.0 +1800.0 2000.0 2300.0 2700.0 3200.0 3300.0 +1900.0 2000.0 2300.0 2700.0 3300.0 3400.0 +1900.0 2000.0 2100.0 2400.0 3300.0 3400.0 +1800.0 2100.0 2400.0 2800.0 3200.0 3400.0 +2000.0 2200.0 2500.0 2700.0 3100.0 3300.0 +2000.0 2300.0 2500.0 2700.0 3100.0 3300.0 +2000.0 2300.0 2500.0 2800.0 3300.0 3400.0 +1900.0 2300.0 2500.0 2800.0 3300.0 3400.0 +1800.0 1900.0 2300.0 2600.0 3300.0 3400.0 +1800.0 1900.0 2400.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2500.0 3200.0 3300.0 +1700.0 1800.0 2300.0 2600.0 3200.0 3300.0 +1600.0 1700.0 2300.0 2600.0 3200.0 3300.0 +1600.0 1900.0 2300.0 2600.0 3200.0 3300.0 +1500.0 1800.0 2200.0 2400.0 3200.0 3300.0 +1500.0 1800.0 2100.0 2500.0 3100.0 3200.0 +1700.0 2100.0 2400.0 2800.0 3200.0 3300.0 +1900.0 2100.0 2500.0 2900.0 3200.0 3300.0 +1900.0 2100.0 2400.0 2900.0 3200.0 3300.0 +1800.0 2100.0 2400.0 2800.0 3100.0 3200.0 +2000.0 2200.0 2500.0 2800.0 3100.0 3300.0 +2000.0 2200.0 2700.0 2800.0 3100.0 3300.0 +2000.0 2300.0 2600.0 2800.0 3200.0 3300.0 +1800.0 2000.0 2600.0 2800.0 3200.0 3300.0 +1800.0 2100.0 2600.0 2800.0 3200.0 3400.0 +1800.0 2200.0 2500.0 2700.0 3300.0 3400.0 +1700.0 1900.0 2500.0 2600.0 3200.0 3400.0 +1700.0 1900.0 2400.0 2700.0 3200.0 3400.0 +1500.0 1900.0 2500.0 2600.0 3100.0 3300.0 +1200.0 2100.0 2400.0 2600.0 3200.0 3300.0 +1300.0 1800.0 2400.0 2500.0 3200.0 3300.0 +1200.0 1600.0 2400.0 2600.0 3200.0 3300.0 +1200.0 1900.0 2500.0 2700.0 3200.0 3300.0 +1300.0 2000.0 2400.0 2700.0 3200.0 3300.0 +1200.0 1900.0 2300.0 2500.0 3200.0 3300.0 +1100.0 1800.0 2300.0 2400.0 3200.0 3300.0 +1100.0 1900.0 2300.0 2500.0 3200.0 3300.0 +1100.0 2100.0 2400.0 2600.0 3200.0 3300.0 +1000.0 1900.0 2400.0 2500.0 3200.0 3300.0 +1000.0 1500.0 2400.0 2500.0 3100.0 3200.0 +1000.0 1500.0 2300.0 2400.0 3100.0 3200.0 +1000.0 1900.0 2300.0 2500.0 3000.0 3100.0 +1100.0 1900.0 2300.0 2400.0 3100.0 3200.0 +1200.0 1800.0 2300.0 2400.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2400.0 3100.0 3200.0 +1400.0 1800.0 2300.0 2400.0 3200.0 3300.0 +1600.0 1700.0 2300.0 2400.0 3100.0 3300.0 +1600.0 1700.0 2300.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2200.0 2400.0 3100.0 3200.0 +1500.0 1800.0 2200.0 2400.0 3100.0 3200.0 +1400.0 1800.0 2200.0 2400.0 3100.0 3200.0 +1400.0 1800.0 2200.0 2400.0 3000.0 3100.0 +1800.0 2000.0 2300.0 2800.0 2900.0 3100.0 +1500.0 1900.0 2300.0 2500.0 3100.0 3200.0 +1500.0 1900.0 2300.0 2400.0 3300.0 3400.0 +1500.0 2000.0 2400.0 2600.0 3300.0 3400.0 +1600.0 2000.0 2400.0 2700.0 3300.0 3400.0 +1600.0 2000.0 2400.0 2500.0 3300.0 3400.0 +1600.0 2000.0 2400.0 2600.0 3300.0 3400.0 +1700.0 2100.0 2400.0 2600.0 2900.0 3200.0 +1600.0 2000.0 2500.0 2700.0 2900.0 3200.0 +1500.0 1800.0 2400.0 2800.0 3000.0 3200.0 +1500.0 1800.0 2100.0 2400.0 2900.0 3100.0 +1600.0 1900.0 2100.0 2400.0 3100.0 3300.0 +1600.0 1900.0 2100.0 2500.0 3100.0 3200.0 +1800.0 1900.0 2300.0 2400.0 3100.0 3300.0 +1900.0 2000.0 2500.0 2600.0 3200.0 3300.0 +1900.0 2200.0 2600.0 2700.0 3300.0 3400.0 +1900.0 2300.0 2600.0 2700.0 3300.0 3400.0 +1900.0 2300.0 2700.0 2800.0 3300.0 3400.0 +2000.0 2200.0 2700.0 2800.0 3300.0 3400.0 +2000.0 2400.0 2700.0 2800.0 3300.0 3400.0 +2000.0 2300.0 2700.0 2800.0 3300.0 3400.0 +2000.0 2400.0 2600.0 2700.0 3300.0 3400.0 +2000.0 2200.0 2600.0 2700.0 3200.0 3300.0 +1900.0 2100.0 2600.0 2700.0 3200.0 3300.0 +1900.0 2100.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1900.0 2000.0 2400.0 2600.0 3100.0 3200.0 +1900.0 2000.0 2300.0 2500.0 3100.0 3200.0 +1800.0 2000.0 2300.0 2500.0 3100.0 3200.0 +1800.0 1900.0 2300.0 2500.0 3000.0 3100.0 +1800.0 1900.0 2400.0 2700.0 3000.0 3200.0 +1800.0 1900.0 2500.0 2700.0 3000.0 3200.0 +1800.0 2000.0 2500.0 2700.0 3100.0 3200.0 +2000.0 2300.0 2600.0 2900.0 3100.0 3300.0 +1900.0 2300.0 2700.0 3000.0 3200.0 3300.0 +2000.0 2400.0 2700.0 3000.0 3200.0 3300.0 +2100.0 2500.0 2800.0 3000.0 3200.0 3300.0 +2200.0 2400.0 2800.0 3000.0 3300.0 3400.0 +1900.0 2200.0 2700.0 2900.0 3300.0 3400.0 +2200.0 2400.0 2900.0 3100.0 3300.0 3400.0 +2100.0 2400.0 2800.0 3100.0 3300.0 3400.0 +2200.0 2500.0 2800.0 3100.0 3300.0 3400.0 +2100.0 2400.0 2600.0 2800.0 3300.0 3400.0 +2000.0 2400.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2400.0 2700.0 3200.0 3300.0 +1800.0 1900.0 2400.0 2700.0 3100.0 3200.0 +1800.0 1900.0 2400.0 2700.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2700.0 3100.0 3200.0 +1700.0 1900.0 2200.0 2700.0 3000.0 3300.0 +1700.0 1800.0 2300.0 2700.0 2900.0 3200.0 +1700.0 1900.0 2300.0 2700.0 2900.0 3200.0 +1700.0 1900.0 2200.0 2700.0 3000.0 3200.0 +1700.0 2000.0 2300.0 2800.0 3000.0 3200.0 +1400.0 1700.0 2300.0 2400.0 3300.0 3400.0 +1400.0 1800.0 2300.0 2400.0 3300.0 3400.0 +1400.0 1900.0 2300.0 2400.0 3300.0 3400.0 +1400.0 2100.0 2300.0 2500.0 3300.0 3400.0 +1400.0 2100.0 2300.0 2600.0 3300.0 3400.0 +1700.0 2200.0 2500.0 2700.0 3200.0 3400.0 +1800.0 2100.0 2600.0 2900.0 3200.0 3400.0 +1800.0 2100.0 2600.0 2800.0 3300.0 3400.0 +1800.0 2100.0 2600.0 2700.0 3300.0 3400.0 +1800.0 2000.0 2500.0 2700.0 3300.0 3400.0 +1800.0 2100.0 2400.0 2700.0 3300.0 3400.0 +1800.0 2100.0 2400.0 2600.0 3300.0 3400.0 +1800.0 2200.0 2400.0 2600.0 3300.0 3400.0 +1800.0 2200.0 2400.0 2700.0 3300.0 3400.0 +1900.0 2300.0 2600.0 2900.0 3200.0 3400.0 +1900.0 2200.0 2600.0 2700.0 3200.0 3400.0 +1900.0 2100.0 2600.0 2700.0 3300.0 3400.0 +2000.0 2100.0 2500.0 2700.0 3200.0 3300.0 +2000.0 2100.0 2500.0 2700.0 3300.0 3400.0 +2000.0 2200.0 2500.0 2700.0 3300.0 3400.0 +2000.0 2100.0 2600.0 2700.0 3300.0 3400.0 +2000.0 2100.0 2500.0 2700.0 3400.0 3500.0 +1900.0 2100.0 2500.0 2600.0 3200.0 3400.0 +2000.0 2200.0 2600.0 2700.0 3200.0 3400.0 +2100.0 2300.0 2600.0 2800.0 3300.0 3400.0 +2100.0 2500.0 2700.0 3100.0 3300.0 3400.0 +2100.0 2500.0 2800.0 3100.0 3300.0 3400.0 +2100.0 2300.0 2400.0 2700.0 3200.0 3300.0 +2000.0 2300.0 2500.0 2800.0 3200.0 3300.0 +1700.0 2100.0 2500.0 2700.0 3200.0 3300.0 +1600.0 1900.0 2300.0 2700.0 3100.0 3300.0 +1600.0 1800.0 2300.0 2800.0 3100.0 3300.0 +1500.0 1800.0 2300.0 2400.0 3100.0 3200.0 +1500.0 1700.0 2300.0 2400.0 3100.0 3300.0 +1400.0 1700.0 2300.0 2400.0 3100.0 3300.0 +1400.0 1500.0 2300.0 2400.0 3100.0 3300.0 +1300.0 1500.0 2300.0 2400.0 3100.0 3300.0 +1300.0 1500.0 2400.0 2500.0 3100.0 3300.0 +1300.0 1500.0 2400.0 2500.0 3000.0 3300.0 +1300.0 1500.0 2300.0 2400.0 2900.0 3300.0 +1400.0 1500.0 2400.0 2500.0 2900.0 3300.0 +1500.0 1600.0 2300.0 2500.0 2800.0 3300.0 +1600.0 1700.0 2300.0 2500.0 2800.0 3400.0 +1700.0 1800.0 2300.0 2500.0 2800.0 3300.0 +1800.0 1900.0 2400.0 2500.0 3100.0 3400.0 +1800.0 1900.0 2400.0 2500.0 3200.0 3400.0 +1900.0 2000.0 2400.0 2500.0 3300.0 3400.0 +1900.0 2000.0 2300.0 2500.0 3300.0 3400.0 +1900.0 2200.0 2600.0 2900.0 3400.0 3500.0 +1800.0 2200.0 2600.0 2900.0 3300.0 3400.0 +1900.0 2300.0 2600.0 3000.0 3400.0 3500.0 +2000.0 2300.0 2600.0 3000.0 3300.0 3400.0 +1800.0 2200.0 2500.0 2900.0 3200.0 3300.0 +1800.0 2100.0 2400.0 2700.0 3200.0 3300.0 +1900.0 2100.0 2500.0 2800.0 3200.0 3300.0 +1700.0 2100.0 2500.0 2700.0 3100.0 3300.0 +1400.0 1800.0 2300.0 2600.0 3100.0 3200.0 +1300.0 1600.0 1700.0 2400.0 3000.0 3100.0 +1500.0 1800.0 2300.0 2600.0 3000.0 3200.0 +1900.0 2200.0 2500.0 2800.0 3000.0 3300.0 +2000.0 2300.0 2600.0 2800.0 3100.0 3300.0 +2000.0 2300.0 2700.0 2900.0 3100.0 3300.0 +2100.0 2300.0 2700.0 2900.0 3100.0 3300.0 +2000.0 2300.0 2700.0 3000.0 3300.0 3400.0 +1700.0 2200.0 2500.0 2600.0 3300.0 3400.0 +1400.0 2000.0 2400.0 2600.0 3300.0 3400.0 +1300.0 1900.0 2300.0 2600.0 3100.0 3300.0 +1200.0 1600.0 2200.0 2400.0 3000.0 3100.0 +1100.0 1500.0 2200.0 2400.0 3100.0 3200.0 +1100.0 1400.0 2300.0 2400.0 3200.0 3300.0 +1100.0 1500.0 2300.0 2400.0 3200.0 3300.0 +1100.0 1500.0 2300.0 2400.0 3300.0 3400.0 +1300.0 1400.0 2400.0 2500.0 3100.0 3300.0 +1500.0 2200.0 2500.0 2600.0 3100.0 3200.0 +2100.0 2400.0 2700.0 3000.0 3200.0 3300.0 +2200.0 2400.0 2700.0 3000.0 3300.0 3400.0 +2000.0 2400.0 2700.0 3000.0 3300.0 3400.0 +2000.0 2400.0 2700.0 2900.0 3300.0 3400.0 +2000.0 2300.0 2700.0 3000.0 3400.0 3500.0 +2100.0 2400.0 2700.0 3000.0 3400.0 3500.0 +2100.0 2500.0 2700.0 3100.0 3400.0 3500.0 +1900.0 2400.0 2600.0 2800.0 3300.0 3400.0 +1900.0 2100.0 2600.0 2800.0 3300.0 3400.0 +1900.0 2100.0 2500.0 2700.0 3300.0 3400.0 +1900.0 2100.0 2500.0 2600.0 3300.0 3400.0 +1800.0 2200.0 2400.0 2800.0 3300.0 3400.0 +1800.0 2000.0 2400.0 2700.0 3300.0 3400.0 +1900.0 2000.0 2400.0 2700.0 3200.0 3300.0 +2000.0 2100.0 2400.0 2600.0 3300.0 3400.0 +1500.0 2100.0 2200.0 2500.0 3300.0 3400.0 +1400.0 1900.0 2300.0 2500.0 3300.0 3400.0 +1400.0 2000.0 2300.0 2600.0 3200.0 3300.0 +1400.0 1800.0 2200.0 2600.0 3100.0 3200.0 +1700.0 2100.0 2400.0 2700.0 3100.0 3300.0 +1800.0 2000.0 2400.0 2700.0 3000.0 3200.0 +1600.0 2000.0 2300.0 2500.0 3100.0 3200.0 +1700.0 2000.0 2300.0 2500.0 3100.0 3300.0 +1600.0 1900.0 2200.0 2600.0 2900.0 3200.0 +1600.0 1900.0 2300.0 2600.0 2900.0 3200.0 +1600.0 1900.0 2300.0 2600.0 3000.0 3200.0 +1600.0 1800.0 2200.0 2500.0 3000.0 3200.0 +1600.0 1800.0 2300.0 2600.0 3100.0 3200.0 +1700.0 1800.0 2400.0 2600.0 3100.0 3200.0 +1700.0 1800.0 2300.0 2500.0 3000.0 3100.0 +1700.0 1800.0 2300.0 2500.0 3100.0 3200.0 +1700.0 1800.0 2200.0 2400.0 3000.0 3200.0 +1700.0 1800.0 2100.0 2300.0 3100.0 3200.0 +1700.0 1900.0 2100.0 2400.0 3000.0 3200.0 +1800.0 2000.0 2200.0 2400.0 3000.0 3200.0 +1800.0 2000.0 2300.0 2500.0 3100.0 3300.0 +1800.0 2000.0 2300.0 2600.0 3200.0 3300.0 +1800.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1800.0 2000.0 2400.0 2600.0 3300.0 3400.0 +1800.0 1900.0 2400.0 2500.0 3300.0 3400.0 +1700.0 1900.0 2400.0 2500.0 3300.0 3400.0 +1700.0 2100.0 2400.0 2600.0 3300.0 3400.0 +1800.0 2100.0 2500.0 2900.0 3300.0 3400.0 +1800.0 2200.0 2600.0 2800.0 3300.0 3500.0 +1800.0 2100.0 2600.0 2900.0 3300.0 3400.0 +1800.0 2100.0 2600.0 3000.0 3200.0 3300.0 +1800.0 2200.0 2600.0 2900.0 3200.0 3300.0 +1800.0 2100.0 2600.0 2800.0 3200.0 3300.0 +1900.0 2200.0 2400.0 2700.0 3100.0 3200.0 +1700.0 2000.0 2300.0 2700.0 3000.0 3100.0 +1700.0 2000.0 2300.0 2600.0 3000.0 3100.0 +1800.0 2100.0 2400.0 2600.0 3100.0 3200.0 +1800.0 2100.0 2400.0 2700.0 3100.0 3200.0 +1900.0 2100.0 2400.0 2700.0 3200.0 3300.0 +1800.0 2000.0 2400.0 2700.0 3100.0 3300.0 +1700.0 2000.0 2400.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2300.0 2700.0 3100.0 3300.0 +1700.0 2000.0 2300.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2300.0 2600.0 3100.0 3200.0 +1400.0 1700.0 2200.0 2500.0 3000.0 3200.0 +1500.0 1700.0 2100.0 2500.0 2900.0 3100.0 +1500.0 1800.0 2300.0 2600.0 2900.0 3200.0 +1500.0 1900.0 2400.0 2600.0 3000.0 3200.0 +1600.0 2000.0 2300.0 2700.0 3100.0 3200.0 +1600.0 2000.0 2400.0 2700.0 3100.0 3300.0 +1600.0 2200.0 2600.0 2900.0 3300.0 3400.0 +1700.0 2200.0 2600.0 3000.0 3300.0 3400.0 +1700.0 2100.0 2500.0 2900.0 3300.0 3400.0 +1700.0 2200.0 2500.0 2900.0 3300.0 3400.0 +1500.0 1800.0 2400.0 2500.0 3200.0 3400.0 +1500.0 1700.0 2400.0 2500.0 3300.0 3400.0 +1500.0 1700.0 2300.0 2400.0 3300.0 3400.0 +1600.0 1800.0 2300.0 2400.0 3300.0 3400.0 +1600.0 1800.0 2400.0 2500.0 3300.0 3400.0 +1600.0 1700.0 2400.0 2500.0 2800.0 3300.0 +1600.0 1800.0 2300.0 2500.0 2700.0 3200.0 +1600.0 1700.0 2300.0 2500.0 2700.0 3200.0 +1600.0 1700.0 2200.0 2500.0 2700.0 3100.0 +1600.0 1700.0 2200.0 2500.0 2600.0 3000.0 +1600.0 1700.0 2400.0 2500.0 2700.0 3200.0 +1600.0 1700.0 2400.0 2500.0 2800.0 3200.0 +1700.0 1800.0 2400.0 2600.0 2900.0 3300.0 +1700.0 1800.0 2300.0 2600.0 2800.0 3300.0 +1700.0 1800.0 2400.0 2600.0 3000.0 3400.0 +1700.0 1800.0 2300.0 2500.0 2900.0 3300.0 +1600.0 1700.0 2300.0 2500.0 3000.0 3300.0 +1400.0 1800.0 2000.0 2400.0 3000.0 3200.0 +1400.0 1700.0 2000.0 2300.0 3000.0 3200.0 +1700.0 2000.0 2300.0 2500.0 3100.0 3200.0 +1700.0 1800.0 2400.0 2500.0 3100.0 3200.0 +1800.0 2000.0 2400.0 2500.0 3200.0 3300.0 +1900.0 2000.0 2400.0 2600.0 3300.0 3400.0 +1900.0 2000.0 2300.0 2600.0 3300.0 3400.0 +2000.0 2100.0 2200.0 2600.0 3300.0 3400.0 +2000.0 2100.0 2300.0 2600.0 3300.0 3400.0 +2100.0 2200.0 2500.0 2800.0 3300.0 3400.0 +2000.0 2100.0 2300.0 2500.0 3200.0 3300.0 +1900.0 2000.0 2200.0 2600.0 3200.0 3300.0 +1800.0 1900.0 2100.0 2600.0 3100.0 3200.0 +1700.0 1900.0 2100.0 2600.0 3000.0 3200.0 +1500.0 1800.0 2100.0 2300.0 3000.0 3200.0 +1500.0 1800.0 2100.0 2400.0 3100.0 3300.0 +1500.0 1700.0 2200.0 2500.0 3100.0 3300.0 +1500.0 1800.0 2200.0 2300.0 3200.0 3300.0 +1500.0 1900.0 2300.0 2500.0 3300.0 3400.0 +1800.0 2300.0 2600.0 3000.0 3400.0 3500.0 +1900.0 2300.0 2700.0 3000.0 3400.0 3500.0 +2000.0 2300.0 2800.0 3100.0 3300.0 3400.0 +2100.0 2300.0 2800.0 3100.0 3300.0 3400.0 +2000.0 2300.0 2700.0 3000.0 3200.0 3300.0 +2000.0 2200.0 2600.0 2900.0 3100.0 3300.0 +2000.0 2200.0 2500.0 2800.0 3000.0 3200.0 +2000.0 2200.0 2400.0 2800.0 3100.0 3200.0 +1600.0 2000.0 2400.0 2600.0 3100.0 3200.0 +1400.0 1900.0 2400.0 2500.0 3100.0 3200.0 +1400.0 1900.0 2300.0 2600.0 3000.0 3200.0 +1500.0 2000.0 2400.0 2700.0 2900.0 3200.0 +2000.0 2300.0 2800.0 3000.0 3200.0 3400.0 +2100.0 2300.0 2900.0 3100.0 3300.0 3400.0 +1800.0 2300.0 2600.0 2900.0 3400.0 3500.0 +1700.0 2300.0 2500.0 2900.0 3300.0 3400.0 +1300.0 2000.0 2400.0 2700.0 3300.0 3400.0 +1200.0 1900.0 2300.0 2600.0 3300.0 3400.0 +1200.0 1800.0 2300.0 2600.0 3300.0 3400.0 +1100.0 1800.0 2300.0 2500.0 3300.0 3400.0 +1800.0 2200.0 2600.0 2800.0 3300.0 3400.0 +1800.0 2000.0 2500.0 2700.0 3200.0 3400.0 +1700.0 2100.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2200.0 2600.0 2800.0 3300.0 3400.0 +1800.0 2200.0 2600.0 3000.0 3300.0 3500.0 +1700.0 2100.0 2600.0 2800.0 3300.0 3400.0 +1700.0 2100.0 2500.0 2800.0 3300.0 3400.0 +1700.0 2200.0 2500.0 2800.0 3300.0 3400.0 +1700.0 2200.0 2500.0 2800.0 3300.0 3500.0 +1800.0 2200.0 2500.0 2900.0 3300.0 3400.0 +2100.0 2200.0 2600.0 2700.0 3100.0 3400.0 +1900.0 2100.0 2500.0 2600.0 3100.0 3400.0 +1900.0 2000.0 2500.0 2600.0 3200.0 3400.0 +1900.0 2000.0 2600.0 2700.0 3200.0 3400.0 +1800.0 1900.0 2500.0 2600.0 3100.0 3400.0 +1600.0 2000.0 2700.0 2800.0 3300.0 3400.0 +1400.0 2000.0 2700.0 2800.0 3300.0 3400.0 +1000.0 1900.0 2700.0 2800.0 3300.0 3400.0 +1000.0 1400.0 2700.0 2900.0 3200.0 3400.0 +1100.0 1500.0 2700.0 2900.0 3200.0 3300.0 +1200.0 1700.0 2400.0 2500.0 3100.0 3300.0 +1300.0 1900.0 2400.0 2500.0 3300.0 3400.0 +1300.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1400.0 2000.0 2400.0 2600.0 3100.0 3300.0 +1500.0 2000.0 2400.0 2700.0 3000.0 3300.0 +1300.0 2100.0 2400.0 2700.0 3200.0 3300.0 +1400.0 1900.0 2700.0 2800.0 3300.0 3400.0 +1500.0 1900.0 2700.0 2800.0 3300.0 3400.0 +1400.0 1800.0 2600.0 2700.0 3200.0 3400.0 +1800.0 2300.0 2600.0 2700.0 2900.0 3200.0 +1500.0 1700.0 2400.0 2600.0 2800.0 3300.0 +1600.0 1700.0 2500.0 2700.0 2900.0 3300.0 +1800.0 1900.0 2600.0 2700.0 3200.0 3400.0 +1800.0 1900.0 2600.0 2700.0 3200.0 3300.0 +2000.0 2200.0 2600.0 2800.0 3200.0 3300.0 +2000.0 2100.0 2600.0 2700.0 3200.0 3400.0 +2000.0 2100.0 2500.0 2800.0 3200.0 3400.0 +2000.0 2100.0 2600.0 2700.0 3100.0 3300.0 +1900.0 2000.0 2400.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2400.0 2600.0 3100.0 3200.0 +1700.0 2000.0 2300.0 2400.0 3200.0 3300.0 +1900.0 2100.0 2500.0 2700.0 3200.0 3400.0 +1900.0 2000.0 2500.0 2700.0 3200.0 3400.0 +1800.0 2000.0 2500.0 2600.0 3200.0 3300.0 +1800.0 2100.0 2500.0 2700.0 3200.0 3400.0 +1800.0 2000.0 2500.0 2600.0 3200.0 3400.0 +1800.0 1900.0 2400.0 2500.0 3000.0 3300.0 +1800.0 2000.0 2400.0 2600.0 3100.0 3300.0 +1900.0 2100.0 2500.0 2600.0 3200.0 3300.0 +2000.0 2100.0 2500.0 2600.0 3300.0 3400.0 +2000.0 2200.0 2500.0 2600.0 3300.0 3400.0 +2100.0 2200.0 2500.0 2600.0 3300.0 3400.0 +2100.0 2200.0 2500.0 2600.0 3200.0 3400.0 +2100.0 2200.0 2400.0 2500.0 3200.0 3400.0 +2000.0 2100.0 2400.0 2500.0 3200.0 3400.0 +1800.0 1900.0 2400.0 2600.0 3200.0 3400.0 +1800.0 1900.0 2500.0 2600.0 3200.0 3400.0 +1800.0 2300.0 2700.0 2900.0 3300.0 3400.0 +1900.0 2400.0 2800.0 3000.0 3300.0 3500.0 +1900.0 2300.0 2800.0 3100.0 3300.0 3400.0 +2000.0 2300.0 2700.0 2900.0 3200.0 3400.0 +1800.0 2000.0 2600.0 2900.0 3300.0 3400.0 +1700.0 2000.0 2500.0 2600.0 3200.0 3400.0 +1600.0 2100.0 2500.0 2600.0 3300.0 3400.0 +1500.0 2100.0 2500.0 2600.0 3300.0 3400.0 +1500.0 2000.0 2400.0 2500.0 3200.0 3300.0 +1400.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1300.0 1900.0 2400.0 2600.0 3100.0 3300.0 +1300.0 2000.0 2600.0 2800.0 3300.0 3400.0 +1500.0 2000.0 2600.0 2700.0 3300.0 3400.0 +1600.0 2000.0 2500.0 2700.0 3200.0 3400.0 +1600.0 2000.0 2500.0 2600.0 3200.0 3400.0 +1600.0 2000.0 2400.0 2500.0 3200.0 3400.0 +1700.0 2000.0 2300.0 2500.0 3300.0 3400.0 +1600.0 1900.0 2300.0 2400.0 3300.0 3400.0 +1500.0 1700.0 2200.0 2400.0 3200.0 3300.0 +1500.0 1800.0 2200.0 2500.0 2900.0 3200.0 +1300.0 1700.0 2200.0 2500.0 3000.0 3300.0 +1200.0 1700.0 2200.0 2600.0 3000.0 3200.0 +1100.0 1700.0 2300.0 2600.0 3100.0 3300.0 +1200.0 1800.0 2300.0 2500.0 3300.0 3400.0 +1100.0 2100.0 2400.0 2600.0 3300.0 3400.0 +1200.0 2200.0 2400.0 2700.0 3300.0 3400.0 +1200.0 2300.0 2500.0 2700.0 3300.0 3400.0 +1200.0 2300.0 2500.0 2800.0 3300.0 3400.0 +1200.0 2300.0 2600.0 2800.0 3300.0 3400.0 +1100.0 1800.0 2500.0 2600.0 3400.0 3500.0 +1300.0 1700.0 2500.0 2600.0 3200.0 3400.0 +1400.0 1800.0 2500.0 2600.0 3200.0 3400.0 +1500.0 1900.0 2500.0 2600.0 3200.0 3300.0 +1500.0 1900.0 2500.0 2700.0 3200.0 3300.0 +1800.0 1900.0 2500.0 2700.0 3100.0 3200.0 +1900.0 2100.0 2400.0 2500.0 3200.0 3300.0 +2000.0 2100.0 2300.0 2500.0 3300.0 3400.0 +1500.0 1900.0 2400.0 2800.0 3100.0 3300.0 +1200.0 1700.0 2500.0 2600.0 3300.0 3400.0 +1300.0 1900.0 2500.0 2600.0 3300.0 3400.0 +1400.0 1800.0 2500.0 2700.0 3300.0 3400.0 +1300.0 1700.0 2400.0 2700.0 3200.0 3400.0 +1100.0 2100.0 2600.0 2700.0 3300.0 3400.0 +1200.0 2100.0 2600.0 2700.0 3300.0 3400.0 +1200.0 2100.0 2500.0 2700.0 3300.0 3400.0 +1200.0 2100.0 2500.0 2600.0 3300.0 3400.0 +1200.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1200.0 2200.0 2500.0 2700.0 3400.0 3500.0 +1400.0 1800.0 2400.0 2600.0 3100.0 3400.0 +1400.0 1900.0 2400.0 2600.0 3100.0 3300.0 +1500.0 1800.0 2400.0 2700.0 3100.0 3300.0 +1500.0 1900.0 2400.0 2600.0 3200.0 3400.0 +1600.0 2100.0 2400.0 2600.0 3300.0 3400.0 +1900.0 2200.0 2400.0 2600.0 3300.0 3400.0 +2000.0 2200.0 2400.0 2600.0 3200.0 3300.0 +2000.0 2100.0 2400.0 2500.0 3200.0 3300.0 +2100.0 2200.0 2500.0 2600.0 3200.0 3300.0 +2100.0 2200.0 2500.0 2700.0 3200.0 3300.0 +2000.0 2100.0 2400.0 2600.0 3100.0 3200.0 +1500.0 2100.0 2300.0 2600.0 3100.0 3200.0 +1500.0 1900.0 2300.0 2400.0 3100.0 3300.0 +1500.0 1800.0 2300.0 2400.0 3100.0 3300.0 +1400.0 1800.0 2300.0 2400.0 3100.0 3300.0 +1400.0 1900.0 2300.0 2500.0 3100.0 3300.0 +1600.0 1900.0 2500.0 2600.0 3200.0 3300.0 +1500.0 1800.0 2300.0 2600.0 3100.0 3300.0 +1400.0 1700.0 2200.0 2600.0 3100.0 3200.0 +1400.0 1600.0 2200.0 2500.0 3000.0 3200.0 +1300.0 1700.0 2400.0 2600.0 3100.0 3200.0 +1400.0 1700.0 2200.0 2500.0 3200.0 3300.0 +1400.0 1800.0 2300.0 2500.0 3200.0 3300.0 +1300.0 1900.0 2200.0 2400.0 3200.0 3300.0 +1100.0 1500.0 2300.0 2400.0 3200.0 3400.0 +1000.0 1600.0 2500.0 2600.0 3300.0 3400.0 +1000.0 1700.0 2500.0 2600.0 3300.0 3400.0 +1000.0 1800.0 2600.0 2700.0 3300.0 3400.0 +1000.0 1900.0 2600.0 2700.0 3300.0 3400.0 +1000.0 1800.0 2800.0 2900.0 3300.0 3400.0 +1400.0 1600.0 2500.0 2600.0 3100.0 3400.0 +1600.0 1700.0 2500.0 2600.0 3100.0 3400.0 +1600.0 1700.0 2500.0 2600.0 3000.0 3400.0 +1700.0 1800.0 2500.0 2600.0 3000.0 3400.0 +1700.0 1800.0 2400.0 2600.0 2800.0 3300.0 +1700.0 1800.0 2400.0 2600.0 2900.0 3400.0 +1700.0 1800.0 2500.0 2600.0 3200.0 3400.0 +1700.0 1800.0 2500.0 2600.0 3100.0 3400.0 +1600.0 1800.0 2500.0 2600.0 3200.0 3400.0 +1600.0 1800.0 2600.0 2700.0 3200.0 3400.0 +1600.0 1900.0 2600.0 2700.0 3300.0 3400.0 +1600.0 2000.0 2600.0 2700.0 3200.0 3400.0 +1800.0 2300.0 2800.0 3000.0 3300.0 3400.0 +1800.0 2100.0 2800.0 3100.0 3300.0 3400.0 +1900.0 2100.0 2700.0 2900.0 3300.0 3400.0 +1800.0 2000.0 2600.0 2800.0 3200.0 3400.0 +1700.0 1900.0 2500.0 2800.0 3100.0 3300.0 +1700.0 1800.0 2400.0 2600.0 3000.0 3300.0 +1700.0 1800.0 2500.0 2700.0 3000.0 3400.0 +1700.0 1900.0 2600.0 2700.0 3100.0 3400.0 +1600.0 1900.0 2600.0 2700.0 3000.0 3300.0 +1700.0 2000.0 2600.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2600.0 2700.0 3200.0 3300.0 +1700.0 1900.0 2600.0 2800.0 3200.0 3300.0 +1600.0 1900.0 2600.0 2800.0 3200.0 3400.0 +1200.0 1800.0 2700.0 2800.0 3200.0 3400.0 +1100.0 1700.0 2700.0 2800.0 3200.0 3300.0 +1500.0 1800.0 2600.0 2700.0 3100.0 3400.0 +1500.0 1800.0 2500.0 2600.0 3100.0 3400.0 +1600.0 1800.0 2500.0 2600.0 3100.0 3400.0 +1600.0 1800.0 2400.0 2500.0 3100.0 3400.0 +1500.0 1700.0 2400.0 2500.0 3000.0 3400.0 +1400.0 1600.0 2400.0 2500.0 3000.0 3400.0 +1400.0 1600.0 2400.0 2600.0 2900.0 3300.0 +1200.0 1700.0 2600.0 2700.0 3100.0 3300.0 +1200.0 1800.0 2600.0 2700.0 3200.0 3400.0 +1100.0 1900.0 2600.0 2700.0 3200.0 3400.0 +1400.0 1800.0 2500.0 2700.0 3200.0 3400.0 +1700.0 1900.0 2500.0 2600.0 2900.0 3300.0 +1600.0 1700.0 2500.0 2700.0 3000.0 3400.0 +1400.0 1500.0 2500.0 2700.0 3200.0 3400.0 +1400.0 1700.0 2500.0 2700.0 3000.0 3300.0 +1800.0 2000.0 2200.0 2600.0 2900.0 3200.0 +1900.0 2100.0 2400.0 2600.0 3100.0 3300.0 +1900.0 2300.0 2400.0 2700.0 3200.0 3300.0 +1800.0 2200.0 2400.0 2700.0 3200.0 3300.0 +1600.0 1900.0 2200.0 2400.0 3000.0 3200.0 +1500.0 1900.0 2100.0 2500.0 3100.0 3200.0 +1500.0 1900.0 2100.0 2400.0 3100.0 3200.0 +1400.0 1900.0 2100.0 2500.0 3200.0 3300.0 +1300.0 2000.0 2200.0 2500.0 3200.0 3300.0 +1200.0 2000.0 2200.0 2500.0 3200.0 3300.0 +1200.0 2100.0 2300.0 2600.0 3200.0 3300.0 +1100.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1200.0 2200.0 2500.0 2600.0 3300.0 3400.0 +1500.0 1800.0 2400.0 2500.0 3300.0 3400.0 +1800.0 1900.0 2300.0 2400.0 3300.0 3400.0 +2100.0 2200.0 2400.0 2600.0 3300.0 3400.0 +2200.0 2300.0 2600.0 2700.0 3300.0 3400.0 +2200.0 2300.0 2600.0 2800.0 3300.0 3400.0 +2100.0 2300.0 2500.0 2800.0 3100.0 3300.0 +2200.0 2300.0 2600.0 2700.0 3100.0 3400.0 +2100.0 2200.0 2600.0 2700.0 3200.0 3400.0 +1900.0 2300.0 2600.0 2900.0 3100.0 3300.0 +2000.0 2300.0 2600.0 2900.0 3200.0 3300.0 +2200.0 2300.0 2700.0 2900.0 3300.0 3400.0 +2000.0 2300.0 2500.0 2900.0 3300.0 3400.0 +1500.0 1700.0 2200.0 2600.0 3100.0 3300.0 +1500.0 1700.0 2200.0 2600.0 3000.0 3300.0 +1500.0 1800.0 2200.0 2600.0 3100.0 3300.0 +1500.0 1800.0 2000.0 2300.0 3200.0 3300.0 +1600.0 1800.0 2000.0 2300.0 3200.0 3300.0 +1600.0 1900.0 2100.0 2300.0 3200.0 3300.0 +1700.0 1900.0 2200.0 2400.0 3200.0 3300.0 +1700.0 1900.0 2300.0 2400.0 3300.0 3400.0 +1800.0 1900.0 2300.0 2500.0 3300.0 3400.0 +1800.0 2000.0 2400.0 2500.0 3200.0 3400.0 +1800.0 2000.0 2400.0 2600.0 3100.0 3400.0 +1800.0 1900.0 2400.0 2600.0 3100.0 3400.0 +1400.0 1600.0 2500.0 2600.0 2900.0 3300.0 +1300.0 1500.0 2500.0 2600.0 2900.0 3300.0 +1300.0 1700.0 2300.0 2700.0 3000.0 3200.0 +1600.0 1900.0 2400.0 2800.0 3100.0 3200.0 +1500.0 2000.0 2400.0 2800.0 3100.0 3300.0 +1100.0 1700.0 2600.0 2700.0 3200.0 3400.0 +1100.0 1800.0 2600.0 2700.0 3300.0 3400.0 +1100.0 1800.0 2700.0 2800.0 3300.0 3400.0 +1700.0 2000.0 2600.0 2700.0 3100.0 3400.0 +1700.0 2100.0 2500.0 2600.0 3000.0 3200.0 +1700.0 2200.0 2600.0 2700.0 3100.0 3200.0 +1700.0 2000.0 2500.0 2600.0 3000.0 3200.0 +1700.0 1900.0 2500.0 2600.0 3000.0 3300.0 +1700.0 1900.0 2400.0 2600.0 3000.0 3300.0 +2000.0 2200.0 2400.0 2600.0 3300.0 3400.0 +1800.0 2100.0 2400.0 2500.0 3300.0 3400.0 +1700.0 2100.0 2400.0 2500.0 3300.0 3400.0 +1500.0 2100.0 2400.0 2500.0 3300.0 3400.0 +1600.0 2100.0 2400.0 2500.0 3300.0 3400.0 +1700.0 2000.0 2300.0 2400.0 3300.0 3400.0 +1700.0 2000.0 2400.0 2500.0 3300.0 3400.0 +1800.0 2000.0 2400.0 2500.0 3300.0 3400.0 +1900.0 2000.0 2400.0 2500.0 3100.0 3400.0 +1900.0 2000.0 2400.0 2500.0 3000.0 3400.0 +1900.0 2000.0 2300.0 2400.0 2800.0 3300.0 +1800.0 2000.0 2200.0 2400.0 2600.0 3200.0 +1900.0 2000.0 2300.0 2500.0 2800.0 3200.0 +1700.0 2000.0 2300.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2500.0 2800.0 3200.0 3300.0 +1700.0 2000.0 2500.0 2800.0 3300.0 3400.0 +1700.0 2000.0 2600.0 2900.0 3300.0 3400.0 +1700.0 1800.0 2500.0 2700.0 3200.0 3400.0 +1600.0 1700.0 2400.0 2600.0 2900.0 3300.0 +1600.0 1700.0 2500.0 2600.0 2900.0 3300.0 +1600.0 1800.0 2600.0 2700.0 3100.0 3400.0 +1600.0 1700.0 2600.0 2700.0 3000.0 3300.0 +1600.0 1700.0 2600.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2500.0 2800.0 3200.0 3400.0 +2100.0 2500.0 2700.0 3000.0 3300.0 3400.0 +2100.0 2400.0 2700.0 2900.0 3300.0 3400.0 +2200.0 2500.0 2700.0 3000.0 3300.0 3400.0 +2200.0 2500.0 2800.0 2900.0 3400.0 3500.0 +2200.0 2500.0 2800.0 2900.0 3300.0 3500.0 +2100.0 2500.0 2700.0 2800.0 3300.0 3400.0 +2100.0 2400.0 2700.0 2900.0 3200.0 3400.0 +2100.0 2300.0 2600.0 2800.0 3100.0 3400.0 +2100.0 2200.0 2500.0 2700.0 3100.0 3400.0 +2200.0 2300.0 2500.0 2700.0 3200.0 3400.0 +1900.0 2100.0 2400.0 2500.0 3200.0 3400.0 +1700.0 2000.0 2400.0 2500.0 3200.0 3300.0 +1500.0 1900.0 2400.0 2500.0 3100.0 3300.0 +1400.0 1900.0 2500.0 2600.0 3300.0 3400.0 +1200.0 1900.0 2600.0 2700.0 3300.0 3400.0 +1100.0 2000.0 2600.0 2700.0 3300.0 3400.0 +1100.0 1700.0 2600.0 2700.0 3300.0 3400.0 +1300.0 1600.0 2500.0 2600.0 3100.0 3400.0 +1500.0 1600.0 2400.0 2500.0 3000.0 3400.0 +1600.0 1700.0 2400.0 2500.0 3100.0 3400.0 +1900.0 2000.0 2300.0 2500.0 2900.0 3400.0 +1900.0 2000.0 2400.0 2500.0 2800.0 3300.0 +1900.0 2000.0 2500.0 2700.0 3300.0 3400.0 +1900.0 2000.0 2500.0 2800.0 3300.0 3400.0 +2000.0 2200.0 2700.0 2900.0 3300.0 3400.0 +1900.0 2200.0 2700.0 2800.0 3200.0 3300.0 +1900.0 2200.0 2700.0 2900.0 3200.0 3300.0 +2000.0 2300.0 2700.0 2900.0 3200.0 3300.0 +2200.0 2600.0 2700.0 2900.0 3300.0 3400.0 +2100.0 2400.0 2700.0 2800.0 3300.0 3400.0 +2100.0 2200.0 2500.0 2700.0 3300.0 3400.0 +1900.0 2100.0 2400.0 2500.0 3300.0 3400.0 +1600.0 2000.0 2400.0 2500.0 3200.0 3300.0 +1500.0 2000.0 2400.0 2500.0 3300.0 3400.0 +1200.0 1900.0 2400.0 2500.0 3300.0 3500.0 +1200.0 1600.0 2400.0 2500.0 3200.0 3400.0 +1700.0 2100.0 2600.0 2900.0 3300.0 3400.0 +1800.0 2200.0 2700.0 3000.0 3300.0 3400.0 +1800.0 2200.0 2800.0 3000.0 3300.0 3400.0 +1700.0 2100.0 2600.0 2900.0 3200.0 3400.0 +1700.0 2000.0 2600.0 2800.0 3200.0 3400.0 +1600.0 1800.0 2500.0 2700.0 3200.0 3400.0 +1500.0 1700.0 2500.0 2600.0 3200.0 3400.0 +1500.0 1700.0 2400.0 2600.0 3200.0 3300.0 +1500.0 1800.0 2400.0 2600.0 3200.0 3300.0 +1500.0 1800.0 2300.0 2500.0 3200.0 3400.0 +1400.0 1800.0 2300.0 2500.0 3300.0 3400.0 +1400.0 1800.0 2300.0 2400.0 3200.0 3400.0 +1600.0 1900.0 2500.0 2600.0 3200.0 3400.0 +1500.0 1900.0 2600.0 2700.0 3200.0 3400.0 +1500.0 1900.0 2600.0 2700.0 3300.0 3400.0 +1400.0 1900.0 2600.0 2700.0 3300.0 3400.0 +1400.0 1900.0 2600.0 2700.0 3200.0 3400.0 +1500.0 1700.0 2600.0 2700.0 3100.0 3300.0 +1600.0 1800.0 2600.0 2700.0 3100.0 3200.0 +1900.0 2100.0 2700.0 2900.0 3200.0 3300.0 +2000.0 2100.0 2500.0 2700.0 3200.0 3400.0 +2000.0 2100.0 2400.0 2600.0 3100.0 3400.0 +2000.0 2100.0 2300.0 2600.0 3000.0 3300.0 +1900.0 2000.0 2300.0 2500.0 3000.0 3400.0 +1800.0 1900.0 2300.0 2400.0 3000.0 3400.0 +1600.0 1800.0 2300.0 2400.0 3000.0 3400.0 +1400.0 1700.0 2400.0 2500.0 2900.0 3400.0 +1300.0 1700.0 2400.0 2500.0 3100.0 3400.0 +1400.0 1700.0 2300.0 2600.0 3100.0 3300.0 +1200.0 1600.0 2400.0 2500.0 3200.0 3300.0 +1200.0 1600.0 2500.0 2600.0 3200.0 3300.0 +1300.0 1800.0 2500.0 2600.0 3200.0 3300.0 +1400.0 1800.0 2500.0 2600.0 3200.0 3300.0 +1700.0 2000.0 2400.0 2600.0 3100.0 3200.0 +1800.0 1900.0 2400.0 2600.0 3000.0 3300.0 +2000.0 2300.0 2700.0 2900.0 3300.0 3400.0 +1900.0 2300.0 2900.0 3100.0 3400.0 3500.0 +1900.0 2100.0 2700.0 3000.0 3300.0 3400.0 +1800.0 1900.0 2300.0 2700.0 3100.0 3300.0 +1800.0 1900.0 2200.0 2500.0 3100.0 3300.0 +1700.0 1800.0 2100.0 2400.0 3000.0 3300.0 +1700.0 1800.0 2200.0 2400.0 3100.0 3300.0 +1400.0 1900.0 2100.0 2300.0 3200.0 3300.0 +1300.0 1800.0 2000.0 2300.0 3200.0 3300.0 +1300.0 1800.0 1900.0 2500.0 3200.0 3300.0 +1300.0 1900.0 2100.0 2600.0 3200.0 3300.0 +2000.0 2100.0 2400.0 2500.0 3100.0 3400.0 +2100.0 2200.0 2400.0 2500.0 3100.0 3400.0 +2100.0 2400.0 2800.0 2900.0 3100.0 3300.0 +2000.0 2200.0 2600.0 2900.0 3200.0 3300.0 +2100.0 2200.0 2700.0 2800.0 3200.0 3300.0 +2000.0 2100.0 2700.0 2800.0 3200.0 3300.0 +2000.0 2100.0 2600.0 2800.0 3200.0 3400.0 +1900.0 2000.0 2600.0 2700.0 3300.0 3400.0 +1800.0 1900.0 2500.0 2700.0 3300.0 3400.0 +2000.0 2100.0 2600.0 2700.0 3200.0 3300.0 +2000.0 2100.0 2600.0 2700.0 3100.0 3400.0 +1900.0 2100.0 2600.0 2700.0 3200.0 3400.0 +1800.0 2000.0 2600.0 2700.0 3300.0 3400.0 +1800.0 2000.0 2600.0 2700.0 3300.0 3500.0 +1700.0 1900.0 2500.0 2700.0 3200.0 3400.0 +1800.0 2100.0 2700.0 2900.0 3200.0 3400.0 +1900.0 2200.0 2600.0 2900.0 3200.0 3300.0 +1900.0 2200.0 2700.0 2900.0 3200.0 3400.0 +1800.0 2200.0 2700.0 3000.0 3200.0 3400.0 +1800.0 2100.0 2700.0 2900.0 3300.0 3400.0 +1900.0 2200.0 2600.0 2900.0 3300.0 3500.0 +1700.0 2100.0 2500.0 2800.0 3400.0 3500.0 +1600.0 1900.0 2400.0 2600.0 3200.0 3400.0 +1600.0 1900.0 2400.0 2500.0 3300.0 3400.0 +1700.0 2000.0 2400.0 2500.0 3200.0 3400.0 +1700.0 2000.0 2300.0 2500.0 3200.0 3300.0 +1700.0 2000.0 2300.0 2400.0 2900.0 3200.0 +1900.0 2000.0 2600.0 2700.0 3100.0 3200.0 +1900.0 2000.0 2600.0 2700.0 3100.0 3400.0 +1800.0 2000.0 2600.0 2700.0 3100.0 3300.0 +1400.0 1800.0 2300.0 2600.0 3000.0 3200.0 +1300.0 1800.0 2200.0 2500.0 3100.0 3300.0 +1300.0 1900.0 2200.0 2600.0 3100.0 3300.0 +1400.0 1800.0 2100.0 2500.0 3000.0 3200.0 +1300.0 1600.0 1700.0 2500.0 3100.0 3200.0 +1300.0 1600.0 1700.0 2400.0 3100.0 3200.0 +1300.0 1600.0 1800.0 2300.0 3100.0 3200.0 +1500.0 1800.0 2400.0 2500.0 3100.0 3200.0 +1500.0 1900.0 2500.0 2600.0 3000.0 3200.0 +1800.0 2200.0 2600.0 2800.0 3200.0 3400.0 +1800.0 2000.0 2500.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2400.0 2700.0 3100.0 3300.0 +1800.0 1900.0 2500.0 2700.0 3100.0 3300.0 +1800.0 1900.0 2600.0 2700.0 3000.0 3300.0 +2100.0 2200.0 2600.0 2700.0 3200.0 3300.0 +2100.0 2200.0 2600.0 2700.0 3300.0 3400.0 +1900.0 2100.0 2300.0 2500.0 3300.0 3400.0 +1700.0 2100.0 2500.0 2800.0 3100.0 3300.0 +1600.0 2100.0 2500.0 2700.0 3100.0 3300.0 +1500.0 1900.0 2400.0 2700.0 3100.0 3300.0 +1200.0 1700.0 1800.0 2100.0 3200.0 3400.0 +1400.0 1700.0 1800.0 2200.0 3300.0 3400.0 +1600.0 1800.0 1900.0 2400.0 3200.0 3300.0 +1700.0 1900.0 2000.0 2500.0 3100.0 3200.0 +1700.0 1900.0 2100.0 2400.0 2900.0 3100.0 +1800.0 2000.0 2200.0 2400.0 2800.0 3200.0 +1900.0 2100.0 2300.0 2600.0 2900.0 3300.0 +1900.0 2100.0 2300.0 2600.0 3200.0 3400.0 +2000.0 2100.0 2400.0 2500.0 3300.0 3400.0 +1800.0 1900.0 2400.0 2500.0 3200.0 3500.0 +1700.0 1900.0 2500.0 2700.0 3200.0 3300.0 +1800.0 2000.0 2600.0 3000.0 3300.0 3400.0 +1900.0 2000.0 2500.0 2700.0 2900.0 3200.0 +1900.0 2000.0 2500.0 2700.0 2900.0 3100.0 +1900.0 2000.0 2400.0 2600.0 2900.0 3200.0 +1700.0 2000.0 2300.0 2600.0 2900.0 3200.0 +1800.0 2000.0 2300.0 2600.0 2900.0 3200.0 +1900.0 2000.0 2400.0 2600.0 2900.0 3300.0 +1900.0 2000.0 2400.0 2600.0 3000.0 3300.0 +1900.0 2000.0 2500.0 2600.0 3100.0 3400.0 +1600.0 1800.0 2200.0 2600.0 3000.0 3300.0 +1600.0 1800.0 2200.0 2500.0 3000.0 3300.0 +1700.0 1900.0 2300.0 2600.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2600.0 3000.0 3200.0 +1800.0 1900.0 2400.0 2500.0 3000.0 3400.0 +1700.0 1800.0 2400.0 2500.0 3200.0 3400.0 +1600.0 1700.0 2400.0 2600.0 3100.0 3300.0 +1600.0 1700.0 2400.0 2500.0 3200.0 3300.0 +1500.0 1600.0 2400.0 2500.0 3200.0 3400.0 +1400.0 1600.0 2400.0 2500.0 3200.0 3400.0 +1300.0 1600.0 2400.0 2500.0 3200.0 3300.0 +1400.0 2000.0 2500.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2200.0 2500.0 3000.0 3300.0 +1700.0 1900.0 2300.0 2500.0 3100.0 3300.0 +2000.0 2100.0 2400.0 2600.0 3100.0 3300.0 +2000.0 2200.0 2500.0 2600.0 3100.0 3300.0 +1900.0 2000.0 2400.0 2500.0 3200.0 3400.0 +2100.0 2200.0 2300.0 2400.0 3200.0 3400.0 +2000.0 2100.0 2300.0 2500.0 3000.0 3400.0 +1600.0 1800.0 2100.0 2500.0 3000.0 3200.0 +1700.0 1800.0 2200.0 2700.0 3200.0 3300.0 +1800.0 1900.0 2400.0 2800.0 3200.0 3400.0 +1800.0 2000.0 2500.0 2800.0 3200.0 3400.0 +1700.0 2100.0 2600.0 2900.0 3300.0 3500.0 +1800.0 2200.0 2600.0 2900.0 3300.0 3500.0 +1700.0 2200.0 2600.0 2900.0 3300.0 3400.0 +1700.0 2100.0 2500.0 2800.0 3200.0 3400.0 +1700.0 1900.0 2600.0 2700.0 3300.0 3400.0 +1700.0 1800.0 2600.0 2700.0 3100.0 3400.0 +1700.0 1800.0 2600.0 2700.0 3200.0 3400.0 +1700.0 1900.0 2700.0 2800.0 3200.0 3400.0 +1600.0 1900.0 2700.0 2800.0 3200.0 3300.0 +1400.0 1900.0 2800.0 2900.0 3200.0 3300.0 +1600.0 2000.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2000.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2000.0 2600.0 2700.0 3200.0 3400.0 +1700.0 2000.0 2600.0 2700.0 3300.0 3400.0 +1700.0 1900.0 2500.0 2600.0 3300.0 3400.0 +1700.0 1800.0 2500.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2500.0 2800.0 3300.0 3400.0 +1700.0 2000.0 2400.0 2800.0 3300.0 3400.0 +1600.0 1800.0 2100.0 2400.0 3100.0 3200.0 +1700.0 1800.0 2000.0 2700.0 3100.0 3200.0 +1700.0 1900.0 2100.0 2700.0 3100.0 3200.0 +1800.0 2000.0 2200.0 2700.0 3100.0 3200.0 +1900.0 2000.0 2300.0 2700.0 3100.0 3200.0 +1900.0 2100.0 2300.0 2700.0 3100.0 3200.0 +1900.0 2100.0 2400.0 2700.0 3100.0 3200.0 +2000.0 2100.0 2400.0 2700.0 3100.0 3200.0 +2000.0 2200.0 2400.0 2700.0 3100.0 3200.0 +1900.0 2100.0 2300.0 2600.0 3100.0 3200.0 +1800.0 2100.0 2200.0 2600.0 3100.0 3200.0 +1600.0 2000.0 2200.0 2600.0 3100.0 3200.0 +1500.0 2000.0 2200.0 2700.0 3100.0 3200.0 +1500.0 1900.0 2200.0 2700.0 3100.0 3200.0 +1500.0 1800.0 2200.0 2600.0 3100.0 3200.0 +1800.0 2100.0 2600.0 2700.0 3100.0 3300.0 +1700.0 2100.0 2600.0 2700.0 3100.0 3300.0 +1500.0 1800.0 2600.0 2700.0 3200.0 3400.0 +1200.0 1400.0 2500.0 2700.0 3200.0 3400.0 +1400.0 1700.0 2400.0 2600.0 3200.0 3400.0 +1400.0 1600.0 2400.0 2600.0 3100.0 3400.0 +1500.0 1700.0 2500.0 2600.0 3000.0 3300.0 +1600.0 1800.0 2500.0 2600.0 3100.0 3300.0 +1700.0 1900.0 2500.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2400.0 2600.0 3000.0 3400.0 +2000.0 2100.0 2500.0 2600.0 3000.0 3300.0 +2100.0 2200.0 2500.0 2600.0 3100.0 3400.0 +2200.0 2300.0 2500.0 2600.0 3100.0 3400.0 +1400.0 1900.0 2300.0 2400.0 2800.0 3200.0 +1400.0 1900.0 2300.0 2400.0 2700.0 3100.0 +1500.0 1700.0 2300.0 2400.0 2800.0 3200.0 +1600.0 1700.0 2100.0 2500.0 3000.0 3300.0 +1700.0 2000.0 2400.0 2800.0 3000.0 3300.0 +1800.0 2000.0 2600.0 2800.0 3100.0 3300.0 +1800.0 2000.0 2500.0 2700.0 3200.0 3300.0 +1800.0 2000.0 2600.0 2700.0 3200.0 3400.0 +1800.0 2000.0 2600.0 2700.0 3200.0 3300.0 +1800.0 2200.0 2600.0 2800.0 3200.0 3300.0 +1800.0 2100.0 2600.0 2800.0 3100.0 3300.0 +1700.0 1900.0 2500.0 2700.0 3000.0 3300.0 +1800.0 1900.0 2500.0 2700.0 3000.0 3300.0 +1900.0 2000.0 2500.0 2700.0 3100.0 3300.0 +1900.0 2000.0 2500.0 2700.0 3100.0 3400.0 +1700.0 1900.0 2600.0 2800.0 3200.0 3400.0 +1600.0 1900.0 2600.0 2800.0 3300.0 3400.0 +1500.0 1800.0 2500.0 2700.0 3300.0 3400.0 +1500.0 1900.0 2400.0 2500.0 3200.0 3400.0 +1200.0 1800.0 2200.0 2300.0 3100.0 3200.0 +1400.0 1900.0 2300.0 2600.0 3000.0 3300.0 +1300.0 1400.0 2300.0 2400.0 2800.0 3100.0 +1300.0 1400.0 2300.0 2500.0 3000.0 3200.0 +1300.0 1600.0 2400.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2400.0 2500.0 2900.0 3200.0 +1500.0 1600.0 2400.0 2600.0 3000.0 3200.0 +1500.0 1700.0 2400.0 2600.0 2900.0 3200.0 +1600.0 1800.0 2400.0 2600.0 2900.0 3100.0 +1800.0 2000.0 2500.0 2700.0 3000.0 3300.0 +1900.0 2100.0 2600.0 2700.0 3000.0 3300.0 +1900.0 2100.0 2500.0 2700.0 3000.0 3200.0 +2000.0 2100.0 2400.0 2700.0 3100.0 3300.0 +2000.0 2200.0 2400.0 2700.0 3100.0 3300.0 +1900.0 2300.0 2600.0 2700.0 3000.0 3200.0 +2000.0 2200.0 2500.0 2600.0 3000.0 3200.0 +1900.0 2000.0 2500.0 2600.0 3000.0 3300.0 +1800.0 2000.0 2400.0 2600.0 3000.0 3300.0 +1500.0 1900.0 2300.0 2500.0 2700.0 3000.0 +1500.0 2000.0 2400.0 2500.0 2700.0 3100.0 +1200.0 1900.0 2300.0 2500.0 2800.0 3000.0 +1300.0 1800.0 2200.0 2300.0 3100.0 3200.0 +1600.0 1900.0 2400.0 2500.0 3100.0 3200.0 +2100.0 2200.0 2600.0 2700.0 3100.0 3300.0 +2100.0 2200.0 2600.0 2700.0 3000.0 3300.0 +2000.0 2200.0 2600.0 2700.0 3100.0 3300.0 +2000.0 2100.0 2400.0 2600.0 3200.0 3300.0 +1800.0 2000.0 2300.0 2400.0 3100.0 3300.0 +1500.0 2000.0 2200.0 2500.0 3200.0 3300.0 +1600.0 1900.0 2400.0 2600.0 3100.0 3300.0 +1500.0 1800.0 2200.0 2600.0 3000.0 3200.0 +1500.0 1800.0 2100.0 2600.0 2900.0 3100.0 +1400.0 1700.0 1900.0 2300.0 2800.0 3000.0 +1500.0 1700.0 1900.0 2200.0 2800.0 2900.0 +1500.0 1700.0 2000.0 2200.0 2900.0 3000.0 +1500.0 1700.0 2100.0 2300.0 2900.0 3000.0 +1500.0 1800.0 2200.0 2300.0 3000.0 3100.0 +1500.0 1800.0 2200.0 2400.0 3000.0 3100.0 +1600.0 1800.0 2300.0 2400.0 3100.0 3200.0 +1600.0 1800.0 2300.0 2500.0 3100.0 3200.0 +1600.0 1800.0 2400.0 2500.0 3100.0 3200.0 +1600.0 1800.0 2400.0 2500.0 3100.0 3300.0 +1600.0 1800.0 2400.0 2500.0 3200.0 3300.0 +1500.0 1700.0 2400.0 2500.0 3200.0 3300.0 +1500.0 1700.0 2300.0 2500.0 2900.0 3300.0 +1800.0 2100.0 2500.0 2600.0 3200.0 3300.0 +1900.0 2100.0 2400.0 2500.0 3100.0 3400.0 +1900.0 2100.0 2200.0 2500.0 3100.0 3300.0 +1700.0 1800.0 2200.0 2500.0 2900.0 3300.0 +1700.0 1800.0 2400.0 2500.0 3000.0 3300.0 +1600.0 1700.0 2400.0 2500.0 3100.0 3300.0 +1500.0 1700.0 2400.0 2500.0 3100.0 3300.0 +1400.0 1700.0 2500.0 2600.0 3100.0 3200.0 +1300.0 1600.0 2500.0 2600.0 3100.0 3200.0 +1200.0 1600.0 2500.0 2600.0 3100.0 3200.0 +1100.0 1700.0 2600.0 2700.0 3100.0 3200.0 +1100.0 1500.0 2600.0 2700.0 3100.0 3200.0 +1100.0 1500.0 2600.0 2700.0 3100.0 3300.0 +1100.0 1500.0 2500.0 2700.0 3000.0 3300.0 +1000.0 1600.0 2600.0 2700.0 3100.0 3300.0 +1300.0 1600.0 2600.0 2700.0 3100.0 3300.0 +1300.0 1600.0 2600.0 2700.0 3200.0 3300.0 +1500.0 1700.0 2500.0 2600.0 3100.0 3300.0 +1700.0 1800.0 2500.0 2600.0 3100.0 3300.0 +1700.0 1900.0 2500.0 2600.0 3200.0 3300.0 +1800.0 1900.0 2500.0 2600.0 3200.0 3300.0 +1800.0 2000.0 2500.0 2700.0 3100.0 3400.0 +1800.0 2100.0 2500.0 2700.0 3100.0 3300.0 +1900.0 2200.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2200.0 2400.0 2600.0 3100.0 3300.0 +1900.0 2300.0 2500.0 2600.0 3100.0 3300.0 +1900.0 2000.0 2200.0 2400.0 3200.0 3300.0 +1600.0 1900.0 2200.0 2300.0 3200.0 3300.0 +1400.0 1600.0 2200.0 2400.0 3100.0 3200.0 +1100.0 1500.0 2300.0 2500.0 3000.0 3100.0 +1400.0 1700.0 2500.0 2700.0 3200.0 3300.0 +1500.0 1800.0 2400.0 2500.0 3200.0 3300.0 +1800.0 2100.0 2500.0 2800.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2500.0 3200.0 3400.0 +1700.0 1900.0 2300.0 2500.0 3200.0 3400.0 +1800.0 2100.0 2500.0 2800.0 3200.0 3400.0 +1800.0 2000.0 2500.0 2800.0 3200.0 3300.0 +1900.0 2100.0 2600.0 2800.0 3100.0 3400.0 +1700.0 2100.0 2600.0 2700.0 3200.0 3400.0 +1800.0 2100.0 2600.0 2700.0 3300.0 3500.0 +1900.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1600.0 1900.0 2200.0 2400.0 3200.0 3300.0 +1400.0 2000.0 2300.0 2600.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2400.0 3000.0 3100.0 +1300.0 1700.0 2300.0 2500.0 3000.0 3100.0 +1600.0 1700.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2000.0 2300.0 2400.0 3100.0 3300.0 +2200.0 2300.0 2600.0 2800.0 3200.0 3400.0 +2100.0 2300.0 2500.0 2900.0 3200.0 3300.0 +2200.0 2300.0 2500.0 2900.0 3200.0 3300.0 +2000.0 2300.0 2500.0 2700.0 3200.0 3300.0 +2200.0 2400.0 2500.0 2700.0 3200.0 3300.0 +2200.0 2400.0 2600.0 2800.0 3200.0 3300.0 +1700.0 2000.0 2400.0 2700.0 3000.0 3200.0 +1700.0 1900.0 2500.0 2700.0 3000.0 3200.0 +1700.0 1900.0 2600.0 2700.0 3100.0 3300.0 +1500.0 1800.0 2600.0 2700.0 3100.0 3300.0 +1600.0 1700.0 2600.0 2700.0 2900.0 3300.0 +1600.0 1700.0 2600.0 2800.0 3000.0 3300.0 +1700.0 2000.0 2700.0 2800.0 3100.0 3400.0 +1600.0 1900.0 2500.0 2700.0 3000.0 3300.0 +1800.0 2200.0 2800.0 2900.0 3300.0 3400.0 +2000.0 2500.0 2800.0 2900.0 3400.0 3500.0 +2000.0 2400.0 2800.0 2900.0 3400.0 3500.0 +2000.0 2300.0 2700.0 2800.0 3200.0 3400.0 +1600.0 1700.0 2400.0 2600.0 3200.0 3300.0 +1500.0 1900.0 2400.0 2500.0 3200.0 3300.0 +1400.0 1900.0 2400.0 2500.0 3200.0 3300.0 +1400.0 1900.0 2500.0 2600.0 3200.0 3300.0 +1300.0 1900.0 2500.0 2600.0 3200.0 3300.0 +1300.0 1700.0 2500.0 2600.0 3100.0 3300.0 +1300.0 1500.0 2500.0 2600.0 3100.0 3300.0 +1200.0 1400.0 2400.0 2500.0 3100.0 3300.0 +1200.0 1500.0 2400.0 2500.0 3100.0 3300.0 +1200.0 1600.0 2400.0 2500.0 3100.0 3300.0 +1200.0 1700.0 2500.0 2600.0 3100.0 3300.0 +1200.0 1700.0 2500.0 2600.0 3200.0 3300.0 +1200.0 1800.0 2500.0 2600.0 3200.0 3300.0 +1200.0 1800.0 2400.0 2500.0 3200.0 3300.0 +1200.0 1800.0 2400.0 2500.0 3100.0 3300.0 +1200.0 1700.0 2400.0 2500.0 3100.0 3200.0 +1200.0 1600.0 2400.0 2500.0 3000.0 3200.0 +1200.0 1600.0 2400.0 2500.0 2900.0 3100.0 +1200.0 1700.0 2400.0 2500.0 3000.0 3300.0 +1300.0 1700.0 2400.0 2500.0 3100.0 3300.0 +1200.0 1700.0 2400.0 2500.0 3000.0 3100.0 +1200.0 1700.0 2300.0 2400.0 3000.0 3100.0 +1600.0 2000.0 2300.0 2600.0 3000.0 3300.0 +1400.0 1600.0 1900.0 2200.0 3000.0 3100.0 +1400.0 1600.0 1800.0 2100.0 3000.0 3100.0 +1300.0 1500.0 1600.0 2000.0 3100.0 3200.0 +1300.0 1500.0 1700.0 1900.0 3100.0 3200.0 +1400.0 1600.0 1700.0 1900.0 3100.0 3200.0 +1600.0 1700.0 2000.0 2100.0 3100.0 3200.0 +1600.0 1800.0 2100.0 2200.0 3100.0 3200.0 +1800.0 1900.0 2300.0 2400.0 3200.0 3300.0 +1900.0 2100.0 2600.0 2700.0 3100.0 3400.0 +1900.0 2000.0 2500.0 2600.0 3000.0 3400.0 +1800.0 2100.0 2600.0 2700.0 3200.0 3400.0 +1800.0 2300.0 2600.0 2800.0 3300.0 3500.0 +1600.0 2100.0 2400.0 2600.0 3200.0 3300.0 +1300.0 1900.0 2500.0 2600.0 3100.0 3300.0 +1300.0 1800.0 2500.0 2600.0 3100.0 3300.0 +1400.0 1800.0 2600.0 2700.0 3100.0 3300.0 +1600.0 1800.0 2500.0 2700.0 3100.0 3300.0 +1600.0 1800.0 2500.0 2600.0 3200.0 3300.0 +1700.0 1800.0 2500.0 2600.0 3200.0 3300.0 +1900.0 2000.0 2500.0 2700.0 2900.0 3300.0 +2000.0 2100.0 2400.0 2600.0 2900.0 3200.0 +2000.0 2100.0 2400.0 2600.0 3000.0 3300.0 +2100.0 2200.0 2400.0 2600.0 3000.0 3300.0 +2000.0 2100.0 2500.0 2600.0 3100.0 3400.0 +1900.0 2000.0 2400.0 2600.0 3000.0 3400.0 +1800.0 1900.0 2300.0 2500.0 2900.0 3400.0 +1700.0 1800.0 2500.0 2700.0 3100.0 3400.0 +1700.0 1900.0 2500.0 2700.0 3100.0 3400.0 +1800.0 1900.0 2700.0 2800.0 3200.0 3400.0 +2100.0 2200.0 2600.0 2800.0 3100.0 3400.0 +2200.0 2300.0 2600.0 2800.0 3100.0 3400.0 +1800.0 2300.0 2500.0 2700.0 3100.0 3300.0 +1500.0 2000.0 2400.0 2500.0 2800.0 3100.0 +1600.0 2000.0 2400.0 2500.0 2800.0 3100.0 +1600.0 2000.0 2400.0 2500.0 2800.0 3200.0 +1600.0 2000.0 2400.0 2500.0 2900.0 3300.0 +1800.0 2200.0 2500.0 2600.0 3000.0 3300.0 +2100.0 2300.0 2500.0 2600.0 3100.0 3300.0 +2100.0 2200.0 2600.0 2700.0 3100.0 3200.0 +1800.0 1900.0 2600.0 2700.0 3100.0 3200.0 +1800.0 1900.0 2600.0 2700.0 3100.0 3300.0 +1700.0 1800.0 2600.0 2700.0 3100.0 3300.0 +1700.0 1800.0 2600.0 2700.0 3200.0 3300.0 +1600.0 1700.0 2600.0 2700.0 3200.0 3400.0 +1600.0 1700.0 2500.0 2700.0 3200.0 3300.0 +1500.0 1800.0 2400.0 2500.0 3000.0 3300.0 +1500.0 1900.0 2300.0 2500.0 3000.0 3200.0 +1700.0 2100.0 2300.0 2600.0 3100.0 3300.0 +1800.0 2000.0 2700.0 2800.0 3100.0 3300.0 +1700.0 1800.0 2500.0 2700.0 2900.0 3300.0 +1600.0 1800.0 2500.0 2700.0 3000.0 3300.0 +1700.0 1800.0 2400.0 2600.0 3100.0 3300.0 +1700.0 1800.0 2400.0 2500.0 3200.0 3300.0 +1800.0 1900.0 2400.0 2500.0 3200.0 3300.0 +1900.0 2000.0 2400.0 2500.0 3200.0 3300.0 +2000.0 2100.0 2300.0 2500.0 3200.0 3400.0 +2000.0 2100.0 2200.0 2400.0 3200.0 3400.0 +2000.0 2100.0 2300.0 2400.0 3100.0 3400.0 +1700.0 1900.0 2400.0 2500.0 3200.0 3400.0 +1700.0 1900.0 2400.0 2500.0 3100.0 3400.0 +1700.0 1800.0 2400.0 2600.0 3300.0 3400.0 +1700.0 1800.0 2500.0 2600.0 3300.0 3400.0 +1600.0 1900.0 2500.0 2600.0 3300.0 3400.0 +1700.0 1900.0 2600.0 2800.0 3100.0 3300.0 +1700.0 2100.0 2600.0 2700.0 3300.0 3400.0 +1800.0 2000.0 2400.0 2500.0 3100.0 3300.0 +2000.0 2100.0 2300.0 2400.0 3200.0 3400.0 +1400.0 1900.0 2300.0 2400.0 3000.0 3300.0 +1400.0 2000.0 2300.0 2500.0 3000.0 3100.0 +1400.0 1700.0 2500.0 2600.0 3100.0 3300.0 +1300.0 1600.0 2400.0 2600.0 3100.0 3300.0 +1300.0 1600.0 2400.0 2500.0 3200.0 3400.0 +1500.0 2000.0 2500.0 2700.0 3200.0 3400.0 +1800.0 2100.0 2500.0 2900.0 3200.0 3400.0 +1800.0 2200.0 2500.0 2800.0 3300.0 3400.0 +1700.0 2000.0 2500.0 2900.0 3300.0 3400.0 +1700.0 2100.0 2600.0 2900.0 3400.0 3500.0 +1500.0 1900.0 2400.0 2800.0 3300.0 3400.0 +1800.0 2100.0 2500.0 2800.0 3300.0 3400.0 +1700.0 2000.0 2600.0 2800.0 3300.0 3400.0 +1700.0 2100.0 2600.0 2800.0 3200.0 3400.0 +1900.0 2200.0 2600.0 2800.0 3200.0 3300.0 +1900.0 2100.0 2600.0 2800.0 3200.0 3300.0 +1800.0 2100.0 2700.0 2800.0 3300.0 3400.0 +1700.0 2100.0 2700.0 2800.0 3200.0 3400.0 +1800.0 2200.0 2600.0 2700.0 3200.0 3400.0 +1800.0 2200.0 2600.0 2700.0 3300.0 3400.0 +1800.0 2300.0 2600.0 2700.0 3300.0 3400.0 +1900.0 2300.0 2500.0 2700.0 3300.0 3400.0 +1800.0 2200.0 2500.0 2800.0 3200.0 3400.0 +1800.0 2200.0 2500.0 2700.0 3100.0 3300.0 +1700.0 2200.0 2400.0 2600.0 3100.0 3200.0 +1800.0 2000.0 2300.0 2500.0 3200.0 3300.0 +1800.0 2000.0 2200.0 2500.0 3300.0 3400.0 +1800.0 2000.0 2200.0 2600.0 3300.0 3400.0 +1500.0 1800.0 1900.0 2400.0 3200.0 3300.0 +1500.0 1700.0 1900.0 2500.0 3200.0 3300.0 +1500.0 1800.0 1900.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2000.0 2400.0 3300.0 3400.0 +1500.0 1700.0 2200.0 2600.0 3000.0 3200.0 +1400.0 1700.0 2000.0 2600.0 3000.0 3200.0 +1500.0 1900.0 2400.0 2600.0 3100.0 3200.0 +1400.0 1900.0 2500.0 2600.0 3100.0 3300.0 +1200.0 1600.0 2500.0 2700.0 3100.0 3300.0 +1200.0 1800.0 2500.0 2600.0 3100.0 3200.0 +1400.0 1800.0 2300.0 2400.0 3100.0 3200.0 +1400.0 1700.0 2200.0 2300.0 3200.0 3300.0 +1800.0 1900.0 2200.0 2300.0 3300.0 3400.0 +1800.0 2100.0 2300.0 2400.0 2900.0 3200.0 +1900.0 2100.0 2300.0 2500.0 3000.0 3300.0 +1900.0 2100.0 2400.0 2600.0 3300.0 3400.0 +1600.0 1900.0 2400.0 2500.0 3200.0 3300.0 +1500.0 1700.0 2300.0 2400.0 3200.0 3300.0 +1500.0 1900.0 2300.0 2500.0 3200.0 3300.0 +1600.0 2000.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2200.0 2500.0 2700.0 3300.0 3400.0 +1800.0 2300.0 2500.0 2700.0 3300.0 3400.0 +1800.0 2400.0 2500.0 2900.0 3300.0 3400.0 +1900.0 2400.0 2600.0 3000.0 3300.0 3400.0 +2000.0 2400.0 2700.0 3000.0 3400.0 3500.0 +1800.0 2100.0 2500.0 2900.0 3200.0 3300.0 +1700.0 2100.0 2500.0 2900.0 3200.0 3400.0 +1800.0 2100.0 2600.0 2800.0 3100.0 3400.0 +1800.0 2200.0 2700.0 2800.0 3200.0 3400.0 +1800.0 2300.0 2700.0 2900.0 3300.0 3500.0 +1400.0 2000.0 2600.0 2700.0 3200.0 3400.0 +1300.0 1800.0 2200.0 2300.0 3000.0 3100.0 +1300.0 1700.0 2100.0 2200.0 3100.0 3200.0 +1400.0 1700.0 2000.0 2200.0 3000.0 3100.0 +1400.0 1600.0 2000.0 2100.0 3000.0 3100.0 +1500.0 1800.0 2000.0 2300.0 3100.0 3200.0 +1600.0 1800.0 2000.0 2300.0 3100.0 3200.0 +1600.0 1800.0 2000.0 2200.0 3100.0 3200.0 +1700.0 2000.0 2200.0 2300.0 3000.0 3200.0 +1700.0 2100.0 2400.0 2800.0 3100.0 3300.0 +1800.0 2000.0 2600.0 2800.0 3000.0 3200.0 +1700.0 1900.0 2600.0 2700.0 3200.0 3400.0 +1600.0 1700.0 2400.0 2600.0 3200.0 3400.0 +1600.0 1700.0 2400.0 2500.0 3200.0 3400.0 +1700.0 2100.0 2500.0 2800.0 3200.0 3300.0 +1700.0 2200.0 2500.0 2800.0 3200.0 3300.0 +1700.0 2100.0 2400.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2600.0 3200.0 3300.0 +1600.0 1900.0 2200.0 2500.0 3100.0 3300.0 +1500.0 1900.0 2100.0 2400.0 3100.0 3300.0 +1500.0 1600.0 2000.0 2300.0 3000.0 3200.0 +1500.0 1700.0 2100.0 2500.0 3100.0 3300.0 +1600.0 1800.0 2300.0 2700.0 3100.0 3300.0 +1600.0 1700.0 2300.0 2600.0 3100.0 3200.0 +1500.0 1700.0 2300.0 2500.0 3000.0 3200.0 +1400.0 1700.0 2400.0 2500.0 3000.0 3200.0 +1200.0 1500.0 2500.0 2600.0 3000.0 3100.0 +1100.0 1900.0 2600.0 2700.0 3000.0 3100.0 +1500.0 2000.0 2700.0 2800.0 3200.0 3400.0 +1700.0 2100.0 2700.0 2800.0 3300.0 3400.0 +1800.0 2200.0 2700.0 2800.0 3300.0 3400.0 +1800.0 2400.0 2700.0 2800.0 3200.0 3300.0 +1800.0 2300.0 2500.0 2600.0 3100.0 3200.0 +1500.0 1800.0 2100.0 2400.0 3000.0 3200.0 +1400.0 1600.0 1800.0 2200.0 3000.0 3100.0 +1300.0 1600.0 1700.0 2100.0 3000.0 3100.0 +1200.0 1400.0 1600.0 2400.0 3000.0 3100.0 +1300.0 1500.0 1600.0 2100.0 3000.0 3100.0 +1400.0 1600.0 1700.0 2100.0 3000.0 3100.0 +1400.0 1700.0 2100.0 2300.0 3100.0 3200.0 +1400.0 1700.0 2200.0 2300.0 3100.0 3200.0 +1400.0 1600.0 2200.0 2300.0 3100.0 3200.0 +1400.0 1700.0 2200.0 2400.0 3100.0 3200.0 +1400.0 1700.0 2300.0 2400.0 3100.0 3200.0 +1400.0 1600.0 2300.0 2400.0 3100.0 3200.0 +1400.0 1600.0 2200.0 2300.0 3000.0 3200.0 +1500.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1700.0 2000.0 2700.0 2800.0 3200.0 3400.0 +2100.0 2400.0 2800.0 2900.0 3200.0 3400.0 +2000.0 2500.0 2700.0 2800.0 3400.0 3500.0 +2100.0 2600.0 2800.0 2900.0 3400.0 3500.0 +2000.0 2500.0 2700.0 2800.0 3300.0 3400.0 +1900.0 2100.0 2700.0 2800.0 3200.0 3400.0 +2100.0 2200.0 2700.0 2800.0 3200.0 3400.0 +2100.0 2200.0 2700.0 2900.0 3300.0 3400.0 +2200.0 2300.0 2700.0 2800.0 3200.0 3400.0 +1700.0 2100.0 2400.0 2700.0 3200.0 3400.0 +1600.0 2100.0 2400.0 2600.0 2900.0 3200.0 +1500.0 2100.0 2400.0 2500.0 2800.0 3100.0 +1600.0 2100.0 2400.0 2500.0 2800.0 3200.0 +1600.0 2100.0 2400.0 2500.0 2900.0 3200.0 +1600.0 2100.0 2400.0 2500.0 3000.0 3200.0 +1600.0 2100.0 2300.0 2500.0 3200.0 3300.0 +1700.0 1800.0 2200.0 2600.0 3100.0 3300.0 +1700.0 1900.0 2300.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2500.0 3100.0 3300.0 +1800.0 1900.0 2400.0 2500.0 3100.0 3200.0 +1600.0 1800.0 2200.0 2500.0 3100.0 3300.0 +1500.0 1700.0 1900.0 2200.0 3100.0 3200.0 +1500.0 1700.0 1900.0 2100.0 3100.0 3200.0 +1500.0 1700.0 1900.0 2300.0 3200.0 3300.0 +1500.0 1700.0 1900.0 2400.0 3200.0 3300.0 +1500.0 1700.0 1800.0 2400.0 3200.0 3300.0 +1500.0 1700.0 1900.0 2200.0 3200.0 3300.0 +1500.0 1700.0 1900.0 2100.0 3200.0 3300.0 +1500.0 1600.0 1900.0 2000.0 3100.0 3200.0 +1500.0 1700.0 2000.0 2100.0 3200.0 3300.0 +1600.0 1700.0 2000.0 2100.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2300.0 3200.0 3300.0 +1700.0 1900.0 2300.0 2500.0 3100.0 3200.0 +1700.0 2000.0 2400.0 2600.0 3000.0 3100.0 +1700.0 2100.0 2400.0 2600.0 3000.0 3100.0 +1600.0 2000.0 2400.0 2600.0 2900.0 3100.0 +1800.0 2200.0 2600.0 2800.0 3000.0 3200.0 +2000.0 2400.0 2500.0 2800.0 3100.0 3200.0 +2100.0 2500.0 2600.0 2800.0 3200.0 3300.0 +2200.0 2500.0 2700.0 3000.0 3200.0 3300.0 +2100.0 2500.0 2700.0 3000.0 3200.0 3300.0 +2200.0 2500.0 2600.0 3000.0 3200.0 3300.0 +2200.0 2500.0 2600.0 2900.0 3200.0 3300.0 +2200.0 2400.0 2600.0 2800.0 3100.0 3300.0 +2000.0 2300.0 2500.0 2700.0 3100.0 3200.0 +2000.0 2200.0 2500.0 2700.0 3100.0 3200.0 +2000.0 2300.0 2500.0 2800.0 3100.0 3200.0 +2000.0 2300.0 2400.0 2800.0 3100.0 3200.0 +2100.0 2200.0 2500.0 2800.0 3100.0 3200.0 +2000.0 2100.0 2500.0 2800.0 3200.0 3300.0 +1900.0 2000.0 2200.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2400.0 3100.0 3300.0 +1500.0 1600.0 1800.0 2100.0 3200.0 3300.0 +1500.0 1700.0 1800.0 2100.0 3200.0 3300.0 +1500.0 1700.0 1800.0 2300.0 3200.0 3300.0 +2000.0 2200.0 2400.0 2600.0 3000.0 3200.0 +2000.0 2400.0 2600.0 2800.0 3100.0 3300.0 +2000.0 2400.0 2500.0 2700.0 3100.0 3300.0 +1800.0 2200.0 2500.0 2600.0 3100.0 3300.0 +1600.0 1800.0 2400.0 2500.0 3000.0 3200.0 +1500.0 1800.0 2400.0 2500.0 3000.0 3100.0 +1800.0 2000.0 2200.0 2700.0 3000.0 3300.0 +1600.0 1900.0 2100.0 2600.0 3000.0 3200.0 +1500.0 1700.0 1900.0 2300.0 3000.0 3100.0 +1500.0 1700.0 1900.0 2200.0 3000.0 3100.0 +1600.0 1700.0 2200.0 2400.0 2900.0 3000.0 +1600.0 1800.0 2200.0 2400.0 2900.0 3000.0 +1800.0 2300.0 2600.0 2700.0 3200.0 3400.0 +1800.0 1900.0 2500.0 2600.0 3300.0 3400.0 +1800.0 1900.0 2400.0 2600.0 3300.0 3400.0 +1700.0 1900.0 2300.0 2500.0 3300.0 3400.0 +1600.0 1800.0 2300.0 2400.0 3200.0 3300.0 +1300.0 1900.0 2300.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2400.0 2600.0 3100.0 3200.0 +2000.0 2100.0 2500.0 2600.0 3200.0 3300.0 +2100.0 2200.0 2400.0 2600.0 3200.0 3400.0 +1700.0 2000.0 2400.0 2600.0 3100.0 3400.0 +1700.0 1800.0 2400.0 2500.0 3100.0 3300.0 +1600.0 1900.0 2300.0 2400.0 3100.0 3200.0 +1600.0 1900.0 2200.0 2500.0 3000.0 3100.0 +1500.0 1800.0 2000.0 2300.0 3000.0 3100.0 +1500.0 1700.0 1900.0 2100.0 2900.0 3000.0 +1400.0 1600.0 2400.0 2700.0 2900.0 3100.0 +1400.0 1600.0 2300.0 2600.0 3000.0 3100.0 +1500.0 1600.0 2300.0 2500.0 2900.0 3100.0 +1600.0 1700.0 2400.0 2600.0 3000.0 3200.0 +1600.0 1800.0 2400.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2400.0 2600.0 3100.0 3200.0 +1700.0 2100.0 2400.0 2600.0 3100.0 3200.0 +1600.0 2000.0 2300.0 2600.0 3100.0 3200.0 +1400.0 1600.0 2200.0 2300.0 3100.0 3300.0 +1400.0 1600.0 2200.0 2300.0 3200.0 3300.0 +1300.0 1800.0 2300.0 2500.0 3300.0 3400.0 +1200.0 1900.0 2400.0 2500.0 3300.0 3400.0 +1200.0 1700.0 2400.0 2500.0 3300.0 3400.0 +1500.0 1700.0 2300.0 2500.0 3100.0 3200.0 +1900.0 2000.0 2300.0 2400.0 3200.0 3300.0 +2200.0 2300.0 2500.0 2700.0 3200.0 3300.0 +2100.0 2300.0 2500.0 2800.0 3300.0 3400.0 +1300.0 1900.0 2300.0 2400.0 3100.0 3300.0 +1800.0 2000.0 2400.0 2700.0 3200.0 3300.0 +1500.0 2000.0 2300.0 2400.0 3000.0 3300.0 +1600.0 2000.0 2400.0 2700.0 3000.0 3200.0 +1800.0 2100.0 2400.0 2600.0 3000.0 3200.0 +1800.0 2100.0 2400.0 2600.0 3000.0 3300.0 +1800.0 2100.0 2400.0 2500.0 3100.0 3300.0 +1700.0 2100.0 2300.0 2600.0 3100.0 3200.0 +1600.0 2000.0 2200.0 2500.0 3200.0 3300.0 +1500.0 1800.0 2200.0 2300.0 3200.0 3400.0 +1400.0 1600.0 2200.0 2300.0 3200.0 3400.0 +1300.0 1500.0 2200.0 2300.0 3200.0 3300.0 +1200.0 1600.0 2300.0 2400.0 3300.0 3400.0 +1200.0 1500.0 2300.0 2400.0 3200.0 3400.0 +1200.0 1400.0 2300.0 2400.0 3100.0 3400.0 +1300.0 1500.0 2400.0 2500.0 3200.0 3400.0 +1700.0 2300.0 2600.0 2700.0 3300.0 3400.0 +1800.0 2400.0 2700.0 3000.0 3300.0 3400.0 +1800.0 2300.0 2700.0 2800.0 3200.0 3300.0 +1800.0 2200.0 2500.0 2600.0 3300.0 3400.0 +1700.0 1900.0 2400.0 2600.0 3200.0 3400.0 +1700.0 1800.0 2200.0 2500.0 3200.0 3400.0 +1500.0 1700.0 2300.0 2500.0 3100.0 3300.0 +1400.0 1700.0 2200.0 2400.0 3000.0 3200.0 +1300.0 1600.0 2200.0 2300.0 3000.0 3100.0 +1300.0 1900.0 2200.0 2400.0 2900.0 3100.0 +1400.0 1900.0 2300.0 2400.0 3000.0 3100.0 +1400.0 1900.0 2300.0 2500.0 2900.0 3100.0 +1400.0 1800.0 2400.0 2600.0 2800.0 3100.0 +1600.0 2000.0 2500.0 2700.0 3100.0 3300.0 +1500.0 2000.0 2500.0 2700.0 3200.0 3300.0 +1500.0 2100.0 2600.0 2900.0 3300.0 3400.0 +1800.0 2300.0 2600.0 2800.0 3300.0 3400.0 +1700.0 2200.0 2600.0 2700.0 3300.0 3400.0 +2000.0 2200.0 2500.0 2700.0 3000.0 3100.0 +2000.0 2300.0 2600.0 2800.0 3100.0 3200.0 +2100.0 2400.0 2500.0 2900.0 3200.0 3300.0 +2100.0 2300.0 2500.0 2800.0 3100.0 3200.0 +1900.0 2200.0 2300.0 2700.0 3100.0 3200.0 +1200.0 1900.0 2000.0 2300.0 3100.0 3200.0 +1300.0 1600.0 1700.0 2100.0 3200.0 3300.0 +1400.0 1600.0 1700.0 2100.0 3200.0 3300.0 +1400.0 1600.0 1700.0 2200.0 3200.0 3300.0 +1600.0 1700.0 2200.0 2600.0 2900.0 3100.0 +1900.0 2300.0 2700.0 2900.0 3200.0 3300.0 +1700.0 2100.0 2700.0 2900.0 3200.0 3400.0 +1800.0 2100.0 2700.0 2800.0 3100.0 3400.0 +1800.0 2100.0 2600.0 2800.0 3000.0 3200.0 +1800.0 2100.0 2700.0 2800.0 3200.0 3400.0 +1400.0 1600.0 2600.0 2700.0 3000.0 3300.0 +1400.0 1500.0 2600.0 2700.0 3000.0 3400.0 +1300.0 1400.0 2400.0 2800.0 3000.0 3300.0 +1800.0 2200.0 2600.0 2900.0 3200.0 3400.0 +1600.0 2100.0 2600.0 2900.0 3200.0 3400.0 +1200.0 1700.0 2500.0 2600.0 3000.0 3100.0 +1200.0 1800.0 2300.0 2600.0 3000.0 3100.0 +1200.0 1800.0 2300.0 2500.0 3000.0 3100.0 +1300.0 1700.0 2400.0 2500.0 3000.0 3100.0 +1500.0 1800.0 2400.0 2500.0 2900.0 3000.0 +1600.0 2300.0 2500.0 2700.0 3000.0 3100.0 +1900.0 2200.0 2700.0 2900.0 3100.0 3200.0 +1900.0 2200.0 2800.0 2900.0 3100.0 3200.0 +1900.0 2300.0 2800.0 2900.0 3200.0 3300.0 +2200.0 2500.0 2800.0 3000.0 3300.0 3400.0 +2100.0 2500.0 2800.0 3000.0 3300.0 3400.0 +2000.0 2400.0 2700.0 2800.0 3300.0 3500.0 +1900.0 2200.0 2600.0 2800.0 3300.0 3400.0 +1900.0 2100.0 2700.0 2800.0 3300.0 3400.0 +1700.0 1900.0 2600.0 2700.0 3000.0 3300.0 +1600.0 1700.0 2500.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2600.0 2800.0 3100.0 3300.0 +1800.0 1900.0 2500.0 2800.0 3000.0 3300.0 +1900.0 2000.0 2600.0 2800.0 3100.0 3400.0 +2000.0 2100.0 2500.0 2700.0 3000.0 3300.0 +2100.0 2200.0 2500.0 2700.0 3000.0 3300.0 +2100.0 2200.0 2500.0 2800.0 3000.0 3300.0 +2000.0 2100.0 2400.0 2700.0 2900.0 3200.0 +1900.0 2000.0 2400.0 2600.0 2800.0 3100.0 +1700.0 2000.0 2500.0 2700.0 3100.0 3300.0 +1700.0 2100.0 2700.0 2800.0 3100.0 3300.0 +1500.0 1700.0 2400.0 2600.0 3100.0 3400.0 +1500.0 1600.0 2400.0 2500.0 3000.0 3300.0 +1400.0 1600.0 2300.0 2600.0 3100.0 3300.0 +1400.0 1500.0 2300.0 2600.0 3100.0 3300.0 +1500.0 1600.0 2400.0 2600.0 2900.0 3200.0 +1600.0 1700.0 2300.0 2600.0 3000.0 3200.0 +1600.0 1700.0 2300.0 2700.0 3000.0 3200.0 +1700.0 1800.0 2400.0 2600.0 3000.0 3200.0 +1600.0 1700.0 2300.0 2500.0 3100.0 3200.0 +1500.0 1600.0 2200.0 2400.0 3100.0 3200.0 +1300.0 1800.0 2200.0 2400.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2400.0 3000.0 3200.0 +1200.0 1700.0 2300.0 2400.0 2900.0 3100.0 +1200.0 1800.0 2400.0 2500.0 2900.0 3200.0 +1200.0 1800.0 2300.0 2500.0 3100.0 3200.0 +1300.0 1800.0 2400.0 2600.0 3200.0 3300.0 +1300.0 1700.0 2400.0 2500.0 3200.0 3300.0 +1200.0 1700.0 2400.0 2500.0 3200.0 3300.0 +1200.0 1500.0 2400.0 2500.0 3200.0 3300.0 +1900.0 2100.0 2500.0 2800.0 3100.0 3300.0 +1800.0 2000.0 2400.0 2700.0 3000.0 3300.0 +1800.0 2000.0 2300.0 2600.0 3000.0 3300.0 +1900.0 2000.0 2300.0 2400.0 3200.0 3500.0 +1900.0 2000.0 2300.0 2400.0 3100.0 3400.0 +1800.0 2000.0 2300.0 2500.0 3200.0 3400.0 +1700.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1800.0 2100.0 2500.0 2800.0 3100.0 3400.0 +1800.0 2000.0 2500.0 2800.0 3100.0 3300.0 +1800.0 2100.0 2500.0 2600.0 3100.0 3300.0 +1700.0 2100.0 2500.0 2700.0 3100.0 3400.0 +1600.0 1700.0 2500.0 2600.0 3200.0 3300.0 +1500.0 2200.0 2400.0 2700.0 3200.0 3300.0 +1400.0 2000.0 2300.0 2700.0 3300.0 3400.0 +1400.0 2000.0 2300.0 2500.0 3300.0 3400.0 +1600.0 2000.0 2400.0 2600.0 3100.0 3300.0 +1600.0 2000.0 2300.0 2600.0 3300.0 3400.0 +1600.0 2100.0 2300.0 2600.0 3300.0 3400.0 +1700.0 1900.0 2300.0 2600.0 3300.0 3400.0 +1900.0 2000.0 2300.0 2400.0 3300.0 3400.0 +1900.0 2000.0 2200.0 2400.0 3300.0 3400.0 +1700.0 1800.0 2200.0 2500.0 3000.0 3200.0 +1700.0 1800.0 2100.0 2500.0 3000.0 3200.0 +1500.0 1700.0 2100.0 2500.0 3000.0 3200.0 +1500.0 1600.0 2100.0 2500.0 3000.0 3200.0 +1500.0 1700.0 2200.0 2700.0 3100.0 3200.0 +1600.0 1900.0 2300.0 2700.0 3200.0 3300.0 +1500.0 1700.0 1800.0 2600.0 3200.0 3300.0 +1600.0 1900.0 2100.0 2500.0 3100.0 3300.0 +2000.0 2300.0 2700.0 2800.0 3100.0 3300.0 +2200.0 2500.0 2900.0 3000.0 3200.0 3300.0 +2300.0 2500.0 2900.0 3000.0 3200.0 3300.0 +1400.0 1900.0 2300.0 2500.0 3200.0 3300.0 +1600.0 2000.0 2300.0 2700.0 3200.0 3300.0 +1500.0 1900.0 2000.0 2400.0 3200.0 3300.0 +1300.0 1800.0 2000.0 2400.0 3300.0 3400.0 +1400.0 1900.0 2200.0 2500.0 3200.0 3300.0 +1800.0 2200.0 2600.0 3000.0 3300.0 3400.0 +1900.0 2200.0 2800.0 2900.0 3300.0 3400.0 +2000.0 2500.0 2900.0 3100.0 3200.0 3300.0 +2000.0 2400.0 2900.0 3000.0 3300.0 3400.0 +2100.0 2400.0 2800.0 3000.0 3200.0 3300.0 +2000.0 2400.0 2700.0 2900.0 3200.0 3300.0 +1700.0 2100.0 2600.0 2800.0 3200.0 3300.0 +1500.0 1900.0 2300.0 2700.0 3100.0 3300.0 +1500.0 1800.0 2200.0 2600.0 3200.0 3300.0 +1500.0 1700.0 2200.0 2500.0 3200.0 3400.0 +1100.0 2200.0 2500.0 2800.0 3200.0 3300.0 +1000.0 2100.0 2500.0 2700.0 3200.0 3300.0 +1000.0 2000.0 2500.0 2700.0 3200.0 3300.0 +1000.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1100.0 1900.0 2400.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2400.0 2700.0 3100.0 3400.0 +1700.0 2100.0 2500.0 2700.0 3000.0 3200.0 +2000.0 2200.0 2600.0 2800.0 3100.0 3300.0 +2100.0 2200.0 2600.0 2800.0 3100.0 3300.0 +1900.0 2100.0 2400.0 2700.0 3100.0 3300.0 +1900.0 2000.0 2300.0 2600.0 3100.0 3200.0 +1800.0 1900.0 2200.0 2600.0 3100.0 3200.0 +1500.0 1700.0 2000.0 2600.0 3100.0 3200.0 +1400.0 1500.0 1800.0 2800.0 3200.0 3300.0 +1300.0 1500.0 1700.0 2600.0 3200.0 3300.0 +1600.0 1900.0 2400.0 2700.0 3100.0 3200.0 +1600.0 1900.0 2400.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2300.0 2700.0 3000.0 3200.0 +1700.0 1900.0 2200.0 2600.0 3000.0 3200.0 +1200.0 1600.0 1800.0 2000.0 3100.0 3400.0 +1100.0 1600.0 2400.0 2500.0 3000.0 3300.0 +1400.0 1700.0 2300.0 2400.0 2900.0 3200.0 +1700.0 2000.0 2300.0 2700.0 3200.0 3300.0 +1600.0 1700.0 2300.0 2400.0 3000.0 3400.0 +1700.0 1800.0 2300.0 2400.0 2900.0 3400.0 +1700.0 1800.0 2300.0 2400.0 2800.0 3300.0 +1800.0 1900.0 2300.0 2400.0 2800.0 3200.0 +1800.0 1900.0 2300.0 2400.0 3000.0 3300.0 +1800.0 1900.0 2300.0 2400.0 2900.0 3300.0 +1700.0 1800.0 2200.0 2300.0 2600.0 3200.0 +1700.0 1800.0 2200.0 2300.0 2700.0 3200.0 +1700.0 1800.0 2300.0 2400.0 3000.0 3300.0 +1700.0 1800.0 2300.0 2400.0 3100.0 3400.0 +1700.0 1800.0 2200.0 2400.0 3200.0 3400.0 +1700.0 1900.0 2200.0 2400.0 3300.0 3400.0 +1800.0 1900.0 2200.0 2400.0 3200.0 3400.0 +1800.0 1900.0 2300.0 2400.0 3200.0 3400.0 +1800.0 1900.0 2300.0 2400.0 3100.0 3400.0 +1800.0 2000.0 2200.0 2400.0 3200.0 3300.0 +1800.0 1900.0 2200.0 2400.0 3200.0 3300.0 +1700.0 1800.0 2000.0 2200.0 3200.0 3300.0 +1400.0 1700.0 1800.0 2200.0 3200.0 3300.0 +1400.0 1800.0 2100.0 2500.0 3100.0 3300.0 +1500.0 1800.0 2200.0 2700.0 3100.0 3200.0 +1600.0 2000.0 2300.0 2500.0 2900.0 3200.0 +1800.0 2200.0 2500.0 2700.0 3000.0 3300.0 +2000.0 2400.0 2700.0 2800.0 3100.0 3300.0 +2200.0 2500.0 2800.0 2900.0 3200.0 3300.0 +1500.0 2300.0 2500.0 2900.0 3300.0 3400.0 +1500.0 1700.0 2300.0 2600.0 3000.0 3200.0 +1700.0 1900.0 2300.0 2600.0 3000.0 3300.0 +1600.0 1700.0 2200.0 2300.0 3200.0 3400.0 +1600.0 1700.0 2200.0 2300.0 3300.0 3400.0 +1200.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1000.0 1800.0 2400.0 2500.0 3200.0 3300.0 +1000.0 2000.0 2300.0 2500.0 3200.0 3300.0 +1300.0 1700.0 2200.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2500.0 2700.0 3000.0 3200.0 +1300.0 1900.0 2400.0 2700.0 3000.0 3200.0 +1600.0 1800.0 2200.0 2700.0 3100.0 3200.0 +1700.0 2100.0 2300.0 2500.0 3100.0 3300.0 +1600.0 1900.0 2400.0 2500.0 3200.0 3400.0 +1600.0 2000.0 2300.0 2500.0 3100.0 3300.0 +1600.0 1900.0 2300.0 2400.0 3000.0 3200.0 +1500.0 1900.0 2200.0 2300.0 3000.0 3200.0 +1500.0 2000.0 2200.0 2400.0 3100.0 3200.0 +1400.0 2000.0 2200.0 2400.0 3100.0 3200.0 +1300.0 2000.0 2200.0 2500.0 3100.0 3200.0 +1100.0 2100.0 2300.0 2600.0 3100.0 3200.0 +1000.0 2000.0 2400.0 2500.0 3100.0 3200.0 +1000.0 1700.0 2400.0 2500.0 3100.0 3200.0 +1000.0 1600.0 2400.0 2500.0 3100.0 3200.0 +1100.0 1600.0 2400.0 2500.0 3100.0 3200.0 +1100.0 1600.0 2400.0 2600.0 3100.0 3200.0 +1100.0 1600.0 2500.0 2600.0 3200.0 3300.0 +1100.0 1500.0 2500.0 2600.0 3200.0 3300.0 +1100.0 1500.0 2500.0 2600.0 3100.0 3200.0 +1200.0 1400.0 2400.0 2600.0 3100.0 3200.0 +1300.0 1700.0 2300.0 2400.0 3200.0 3300.0 +1300.0 1800.0 2300.0 2400.0 3200.0 3300.0 +1300.0 1900.0 2300.0 2400.0 3200.0 3300.0 +1400.0 1900.0 2300.0 2400.0 3100.0 3300.0 +1500.0 1700.0 2300.0 2400.0 3000.0 3200.0 +1500.0 1700.0 2300.0 2400.0 3000.0 3300.0 +2100.0 2300.0 2800.0 3000.0 3300.0 3400.0 +2200.0 2400.0 2900.0 3000.0 3200.0 3300.0 +2100.0 2300.0 2900.0 3000.0 3300.0 3400.0 +2000.0 2300.0 2600.0 3000.0 3200.0 3300.0 +1300.0 1600.0 2200.0 2600.0 3100.0 3300.0 +1000.0 2000.0 2300.0 2500.0 3300.0 3400.0 +1000.0 2100.0 2400.0 2600.0 3300.0 3400.0 +1300.0 1700.0 1900.0 2100.0 3100.0 3200.0 +1500.0 1800.0 2000.0 2400.0 3200.0 3300.0 +1600.0 1800.0 2000.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2100.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2500.0 3300.0 3400.0 +1700.0 1900.0 2100.0 2500.0 2900.0 3200.0 +1600.0 1900.0 2100.0 2300.0 2800.0 3200.0 +1200.0 1700.0 2200.0 2600.0 3000.0 3300.0 +1200.0 1700.0 2300.0 2600.0 3100.0 3300.0 +1600.0 2100.0 2400.0 2700.0 3100.0 3300.0 +1500.0 2000.0 2400.0 2600.0 3100.0 3400.0 +2100.0 2200.0 2700.0 3000.0 3200.0 3300.0 +2100.0 2200.0 2700.0 2900.0 3100.0 3300.0 +1500.0 1800.0 2200.0 2600.0 2900.0 3200.0 +1400.0 1600.0 1800.0 2900.0 3200.0 3300.0 +1600.0 1700.0 1900.0 2500.0 3100.0 3200.0 +1700.0 1800.0 2000.0 2600.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2200.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2200.0 2600.0 3100.0 3200.0 +1700.0 1900.0 2200.0 2500.0 3100.0 3200.0 +1700.0 1800.0 2200.0 2600.0 3200.0 3300.0 +1700.0 1800.0 2200.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2300.0 3100.0 3200.0 +2300.0 2500.0 2800.0 2900.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2700.0 3200.0 3300.0 +1700.0 2000.0 2400.0 2800.0 3200.0 3300.0 +1500.0 1900.0 2300.0 2700.0 3200.0 3300.0 +1500.0 2000.0 2300.0 2500.0 3200.0 3300.0 +1600.0 1900.0 2200.0 2500.0 3200.0 3300.0 +1600.0 1900.0 2200.0 2400.0 3100.0 3300.0 +1600.0 1800.0 2200.0 2300.0 3000.0 3300.0 +1700.0 1800.0 2200.0 2300.0 3000.0 3300.0 +1700.0 1900.0 2200.0 2400.0 3100.0 3300.0 +1700.0 1900.0 2200.0 2400.0 3100.0 3400.0 +1700.0 1800.0 2200.0 2400.0 3100.0 3400.0 +1500.0 1800.0 2300.0 2400.0 2900.0 3300.0 +1500.0 1700.0 2200.0 2400.0 3100.0 3400.0 +1400.0 1700.0 2200.0 2300.0 3100.0 3400.0 +1600.0 1900.0 2500.0 2700.0 3200.0 3400.0 +1500.0 1800.0 2400.0 2600.0 3000.0 3300.0 +1400.0 2100.0 2500.0 2600.0 3100.0 3300.0 +1200.0 1800.0 2100.0 2300.0 3200.0 3300.0 +1800.0 2100.0 2600.0 2900.0 3100.0 3200.0 +2000.0 2400.0 2900.0 3100.0 3300.0 3400.0 +1500.0 1800.0 2200.0 2400.0 3300.0 3400.0 +1500.0 2000.0 2100.0 2700.0 3300.0 3400.0 +1600.0 1800.0 2000.0 2400.0 2900.0 3100.0 +1600.0 1800.0 2200.0 2600.0 3000.0 3200.0 +1500.0 1800.0 2100.0 2600.0 3000.0 3200.0 +1600.0 1900.0 2100.0 2400.0 3000.0 3300.0 +1600.0 2000.0 2200.0 2500.0 3300.0 3400.0 +1600.0 2000.0 2100.0 2400.0 3300.0 3400.0 +1400.0 1700.0 2200.0 2600.0 3000.0 3200.0 +1300.0 1600.0 2200.0 2500.0 3000.0 3200.0 +1300.0 1500.0 2100.0 2500.0 3000.0 3300.0 +1200.0 1600.0 1700.0 2400.0 3300.0 3400.0 +1300.0 1600.0 1700.0 2500.0 3300.0 3400.0 +1300.0 1600.0 1700.0 2500.0 3200.0 3300.0 +1400.0 1700.0 1800.0 2500.0 3200.0 3300.0 +1500.0 1800.0 2000.0 2500.0 3200.0 3300.0 +1500.0 1900.0 2000.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2400.0 3200.0 3300.0 +1600.0 1900.0 2100.0 2400.0 3200.0 3300.0 +1500.0 1700.0 2100.0 2200.0 3000.0 3300.0 +1400.0 1600.0 2100.0 2200.0 3000.0 3200.0 +1400.0 1800.0 2100.0 2300.0 3000.0 3200.0 +1600.0 2100.0 2300.0 2700.0 3100.0 3300.0 +1200.0 2100.0 2400.0 2700.0 3300.0 3400.0 +1600.0 2100.0 2200.0 2600.0 3300.0 3400.0 +1300.0 2000.0 2200.0 2500.0 3300.0 3400.0 +1300.0 2300.0 2500.0 2800.0 3300.0 3400.0 +1300.0 2000.0 2300.0 2500.0 3200.0 3300.0 +1700.0 2000.0 2400.0 2800.0 3100.0 3300.0 +1900.0 2200.0 2500.0 2900.0 3100.0 3300.0 +2000.0 2100.0 2600.0 2800.0 3200.0 3300.0 +2000.0 2100.0 2700.0 2900.0 3200.0 3300.0 +1000.0 1900.0 2400.0 2600.0 3300.0 3400.0 +1000.0 1900.0 2500.0 2600.0 3200.0 3300.0 +1000.0 1900.0 2500.0 2600.0 3300.0 3400.0 +1000.0 1800.0 2400.0 2600.0 3200.0 3300.0 +1000.0 1800.0 2400.0 2600.0 3300.0 3400.0 +1000.0 1900.0 2400.0 2600.0 3200.0 3300.0 +1400.0 1700.0 2200.0 2600.0 3100.0 3300.0 +1400.0 1600.0 2100.0 2500.0 3000.0 3300.0 +1300.0 1800.0 2100.0 2400.0 3200.0 3300.0 +1100.0 1900.0 2200.0 2400.0 3200.0 3300.0 +1100.0 1900.0 2300.0 2500.0 3300.0 3400.0 +1100.0 1900.0 2400.0 2500.0 3200.0 3300.0 +1100.0 1900.0 2400.0 2600.0 3200.0 3300.0 +1100.0 1900.0 2300.0 2400.0 3300.0 3400.0 +1200.0 2000.0 2300.0 2500.0 3200.0 3300.0 +1300.0 1900.0 2200.0 2400.0 3300.0 3400.0 +1500.0 1800.0 2200.0 2300.0 3300.0 3400.0 +1700.0 2200.0 2700.0 3000.0 3300.0 3400.0 +1900.0 2200.0 2800.0 3000.0 3200.0 3300.0 +1900.0 2200.0 2500.0 3000.0 3200.0 3300.0 +1600.0 2100.0 2300.0 2700.0 3300.0 3400.0 +1600.0 2000.0 2300.0 2700.0 3300.0 3400.0 +1600.0 2100.0 2500.0 3000.0 3300.0 3400.0 +1600.0 2200.0 2600.0 3000.0 3300.0 3400.0 +1900.0 2400.0 2900.0 3100.0 3300.0 3400.0 +2100.0 2500.0 2900.0 3000.0 3300.0 3400.0 +2000.0 2400.0 2900.0 3000.0 3200.0 3300.0 +1700.0 2200.0 2400.0 2900.0 3200.0 3300.0 +1300.0 1800.0 2100.0 2500.0 3200.0 3300.0 +1500.0 1600.0 1800.0 2300.0 3000.0 3200.0 +1500.0 1600.0 1900.0 2000.0 3000.0 3300.0 +1400.0 1800.0 2200.0 2600.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2400.0 2900.0 3100.0 +1500.0 1700.0 2100.0 2400.0 2900.0 3100.0 +1400.0 1700.0 2100.0 2400.0 3000.0 3200.0 +1400.0 1700.0 2300.0 2600.0 3200.0 3300.0 +1300.0 1900.0 2300.0 2600.0 3200.0 3300.0 +1000.0 2100.0 2500.0 2700.0 3300.0 3400.0 +1400.0 1900.0 2000.0 2500.0 3200.0 3300.0 +1600.0 1900.0 2100.0 2500.0 3300.0 3400.0 +1600.0 2000.0 2300.0 2500.0 3200.0 3300.0 +2200.0 2400.0 2800.0 3000.0 3200.0 3300.0 +1900.0 2300.0 2400.0 2700.0 3100.0 3200.0 +1900.0 2200.0 2300.0 2600.0 3100.0 3200.0 +1900.0 2100.0 2300.0 2800.0 3200.0 3300.0 +1700.0 2000.0 2400.0 2700.0 3200.0 3300.0 +1900.0 2200.0 2500.0 2700.0 3100.0 3300.0 +1700.0 1800.0 2200.0 2500.0 3300.0 3400.0 +1700.0 1900.0 2200.0 2700.0 3200.0 3300.0 +1700.0 1900.0 2300.0 2700.0 3300.0 3400.0 +1800.0 2000.0 2400.0 2800.0 3300.0 3400.0 +1800.0 2000.0 2300.0 2600.0 3300.0 3400.0 +1900.0 2000.0 2300.0 2500.0 3200.0 3300.0 +1900.0 2100.0 2400.0 2600.0 3200.0 3300.0 +2000.0 2200.0 2400.0 2700.0 3200.0 3300.0 +2100.0 2200.0 2500.0 2900.0 3200.0 3300.0 +2200.0 2300.0 2600.0 2900.0 3200.0 3300.0 +2200.0 2300.0 2700.0 2900.0 3100.0 3300.0 +2100.0 2400.0 2600.0 2800.0 3200.0 3300.0 +1900.0 2200.0 2600.0 2800.0 3000.0 3200.0 +1800.0 2100.0 2400.0 2700.0 3000.0 3200.0 +1800.0 2000.0 2400.0 2700.0 3100.0 3200.0 +1600.0 2000.0 2200.0 2500.0 3100.0 3200.0 +1300.0 1900.0 2100.0 2300.0 3100.0 3300.0 +1200.0 1600.0 2100.0 2200.0 3200.0 3400.0 +1100.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1400.0 1700.0 2100.0 2300.0 3100.0 3300.0 +1400.0 1900.0 2200.0 2500.0 3300.0 3400.0 +1300.0 1800.0 2200.0 2700.0 3200.0 3300.0 +1300.0 1900.0 2200.0 2600.0 3200.0 3300.0 +1400.0 2000.0 2200.0 2700.0 3200.0 3300.0 +1400.0 2000.0 2200.0 2600.0 3300.0 3400.0 +1400.0 2000.0 2200.0 2500.0 3200.0 3300.0 +1400.0 1900.0 2200.0 2400.0 3200.0 3300.0 +1400.0 1800.0 2200.0 2300.0 3000.0 3300.0 +1400.0 1800.0 2200.0 2300.0 3100.0 3300.0 +1400.0 1800.0 2100.0 2300.0 3200.0 3400.0 +1500.0 2000.0 2400.0 2700.0 3300.0 3400.0 +1700.0 2100.0 2500.0 3000.0 3300.0 3400.0 +1400.0 1900.0 2300.0 2800.0 3200.0 3300.0 +1400.0 2000.0 2200.0 2400.0 3200.0 3300.0 +1200.0 1900.0 2200.0 2400.0 3200.0 3300.0 +1200.0 1900.0 2200.0 2500.0 3200.0 3300.0 +1200.0 2000.0 2200.0 2500.0 3300.0 3400.0 +1700.0 2100.0 2300.0 2400.0 3200.0 3400.0 +1400.0 1600.0 1800.0 2500.0 3100.0 3200.0 +1500.0 1800.0 2100.0 2500.0 3000.0 3200.0 +1700.0 1800.0 2200.0 2500.0 3100.0 3300.0 +2000.0 2100.0 2500.0 2800.0 3100.0 3300.0 +1900.0 2100.0 2200.0 2700.0 3100.0 3200.0 +1500.0 1800.0 2100.0 2300.0 3200.0 3400.0 +1600.0 1800.0 2000.0 2300.0 3200.0 3400.0 +1600.0 1800.0 2100.0 2300.0 3200.0 3400.0 +1500.0 1800.0 2000.0 2300.0 3300.0 3400.0 +1500.0 1700.0 1900.0 2400.0 3300.0 3400.0 +1600.0 1900.0 2000.0 2700.0 3100.0 3200.0 +1700.0 1900.0 2200.0 2600.0 3100.0 3300.0 +1700.0 1900.0 2200.0 2500.0 3200.0 3300.0 +1700.0 2000.0 2400.0 2600.0 3100.0 3300.0 +1700.0 2000.0 2400.0 2700.0 3100.0 3200.0 +2300.0 2400.0 2700.0 3000.0 3200.0 3300.0 +2200.0 2400.0 2600.0 2900.0 3200.0 3300.0 +2200.0 2400.0 2500.0 2800.0 3200.0 3300.0 +2100.0 2400.0 2500.0 2800.0 3200.0 3300.0 +2000.0 2400.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2300.0 2400.0 2800.0 3200.0 3300.0 +1900.0 2300.0 2600.0 2700.0 3100.0 3300.0 +2000.0 2400.0 2800.0 2900.0 3200.0 3300.0 +1700.0 2200.0 2500.0 2800.0 3200.0 3400.0 +1500.0 2100.0 2400.0 2600.0 3100.0 3300.0 +1500.0 1900.0 2300.0 2500.0 3200.0 3400.0 +1400.0 1900.0 2300.0 2400.0 3200.0 3300.0 +1100.0 1700.0 2400.0 2600.0 3200.0 3300.0 +1100.0 1700.0 2400.0 2600.0 3300.0 3400.0 +1100.0 1800.0 2400.0 2500.0 3300.0 3400.0 +1100.0 1800.0 2400.0 2500.0 3200.0 3300.0 +1100.0 2000.0 2500.0 2600.0 3200.0 3300.0 +1100.0 2100.0 2500.0 2600.0 3200.0 3300.0 +1100.0 2100.0 2500.0 2700.0 3200.0 3300.0 +1000.0 2200.0 2600.0 2700.0 3200.0 3300.0 +1100.0 2300.0 2600.0 2800.0 3200.0 3300.0 +1100.0 2100.0 2500.0 2700.0 3100.0 3200.0 +1500.0 1700.0 2300.0 2500.0 2900.0 3200.0 +1600.0 1700.0 2200.0 2600.0 2800.0 3100.0 +1600.0 1700.0 2100.0 2600.0 2800.0 3000.0 +1500.0 1700.0 2100.0 2500.0 2800.0 3000.0 +1500.0 1600.0 2200.0 2500.0 2800.0 3100.0 +1500.0 1600.0 2300.0 2600.0 2800.0 3100.0 +1400.0 1500.0 2300.0 2700.0 2900.0 3100.0 +1400.0 1500.0 2200.0 2700.0 2800.0 3100.0 +1400.0 1600.0 2000.0 2700.0 2900.0 3100.0 +1500.0 1700.0 2200.0 2700.0 3100.0 3300.0 +1500.0 1800.0 2300.0 2700.0 3100.0 3300.0 +1600.0 1700.0 2300.0 2700.0 3000.0 3300.0 +1700.0 1800.0 2200.0 2700.0 2900.0 3200.0 +1800.0 1900.0 2200.0 2700.0 2900.0 3100.0 +1700.0 1900.0 2200.0 2600.0 2900.0 3000.0 +1800.0 2000.0 2300.0 2700.0 2900.0 3100.0 +1800.0 2000.0 2300.0 2800.0 3000.0 3200.0 +1800.0 2000.0 2400.0 2800.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2800.0 3000.0 3200.0 +1500.0 1700.0 2200.0 2500.0 3000.0 3100.0 +1700.0 2100.0 2400.0 2800.0 3100.0 3200.0 +1800.0 2200.0 2700.0 2900.0 3400.0 3500.0 +1900.0 2400.0 2700.0 2900.0 3400.0 3500.0 +2000.0 2400.0 2600.0 2900.0 3300.0 3400.0 +1900.0 2400.0 2500.0 2800.0 3200.0 3300.0 +1900.0 2300.0 2500.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2500.0 3100.0 3200.0 +1600.0 1700.0 2300.0 2600.0 2900.0 3100.0 +1600.0 1700.0 2400.0 2600.0 2900.0 3100.0 +1600.0 2100.0 2600.0 2800.0 3300.0 3400.0 +1700.0 2200.0 2700.0 3000.0 3200.0 3300.0 +1700.0 2300.0 2800.0 2900.0 3200.0 3300.0 +1700.0 2300.0 2700.0 3000.0 3200.0 3300.0 +1600.0 2100.0 2700.0 2900.0 3300.0 3400.0 +1200.0 1600.0 2400.0 2600.0 3000.0 3300.0 +1100.0 1400.0 2400.0 2700.0 2900.0 3100.0 +1200.0 1800.0 2200.0 2500.0 3100.0 3300.0 +1200.0 1700.0 2200.0 2500.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2500.0 2900.0 3200.0 +1900.0 2000.0 2400.0 2500.0 2800.0 3100.0 +2000.0 2200.0 2400.0 2500.0 2800.0 3100.0 +2000.0 2200.0 2400.0 2600.0 2800.0 3200.0 +2000.0 2100.0 2500.0 2700.0 3100.0 3400.0 +1900.0 2000.0 2600.0 2700.0 3100.0 3300.0 +1900.0 2000.0 2600.0 2700.0 3200.0 3300.0 +1900.0 2400.0 2700.0 3000.0 3300.0 3400.0 +2000.0 2400.0 2800.0 2900.0 3200.0 3400.0 +1900.0 2000.0 2300.0 2600.0 3000.0 3200.0 +1900.0 2100.0 2400.0 2700.0 3000.0 3200.0 +1900.0 2100.0 2400.0 2800.0 3100.0 3200.0 +1900.0 2100.0 2400.0 2800.0 3300.0 3400.0 +1500.0 1800.0 2100.0 2600.0 3100.0 3300.0 +1600.0 1800.0 2100.0 2200.0 3000.0 3300.0 +1800.0 2100.0 2300.0 2500.0 3000.0 3200.0 +2000.0 2100.0 2300.0 2500.0 3000.0 3300.0 +2000.0 2100.0 2300.0 2500.0 2900.0 3300.0 +2000.0 2100.0 2300.0 2400.0 2900.0 3300.0 +1600.0 1800.0 2300.0 2500.0 2900.0 3200.0 +1700.0 1900.0 2400.0 2700.0 3000.0 3200.0 +1700.0 2000.0 2400.0 2600.0 3000.0 3300.0 +1600.0 2000.0 2300.0 2700.0 3000.0 3200.0 +1500.0 1800.0 2300.0 2600.0 3100.0 3200.0 +1700.0 1800.0 2300.0 2400.0 2800.0 3000.0 +1800.0 2000.0 2400.0 2500.0 2900.0 3200.0 +1800.0 2000.0 2400.0 2600.0 3000.0 3200.0 +1900.0 2000.0 2400.0 2500.0 3000.0 3200.0 +1900.0 2000.0 2300.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2200.0 2400.0 2900.0 3200.0 +1800.0 1900.0 2200.0 2300.0 2900.0 3200.0 +1600.0 1800.0 2200.0 2400.0 3100.0 3300.0 +1600.0 2000.0 2400.0 2700.0 3100.0 3200.0 +1800.0 2100.0 2500.0 2700.0 3000.0 3200.0 +2000.0 2200.0 2500.0 2700.0 3000.0 3200.0 +2000.0 2300.0 2500.0 2700.0 3000.0 3200.0 +2000.0 2300.0 2400.0 2700.0 3000.0 3200.0 +2100.0 2200.0 2400.0 2500.0 3000.0 3300.0 +1900.0 2000.0 2300.0 2600.0 2800.0 3300.0 +1900.0 2000.0 2400.0 2700.0 3100.0 3300.0 +1500.0 2000.0 2400.0 2700.0 3100.0 3300.0 +1600.0 1900.0 2500.0 2800.0 3000.0 3300.0 +1900.0 2000.0 2400.0 2700.0 2900.0 3200.0 +2000.0 2200.0 2400.0 2700.0 2900.0 3200.0 +2100.0 2200.0 2400.0 2700.0 2900.0 3200.0 +2100.0 2300.0 2400.0 2600.0 2800.0 3200.0 +1300.0 2000.0 2300.0 2500.0 2700.0 3100.0 +1800.0 1900.0 2100.0 2400.0 2900.0 3100.0 +1700.0 1900.0 2100.0 2500.0 2900.0 3100.0 +1800.0 1900.0 2300.0 2600.0 3100.0 3300.0 +1600.0 1700.0 2300.0 2600.0 2800.0 3200.0 +1700.0 1800.0 2300.0 2600.0 2800.0 3100.0 +1700.0 1800.0 2300.0 2700.0 2800.0 3200.0 +1500.0 1700.0 2300.0 2600.0 3000.0 3300.0 +1400.0 1700.0 2200.0 2500.0 3000.0 3300.0 +1400.0 1600.0 2200.0 2300.0 3000.0 3300.0 +1400.0 1600.0 2200.0 2400.0 2800.0 3300.0 +1500.0 1600.0 2200.0 2400.0 2900.0 3300.0 +1500.0 1600.0 2200.0 2400.0 2800.0 3300.0 +1500.0 1700.0 2200.0 2500.0 3000.0 3200.0 +1700.0 1900.0 2300.0 2700.0 3000.0 3300.0 +1600.0 1800.0 2400.0 2700.0 3000.0 3200.0 +1600.0 2000.0 2500.0 2800.0 3000.0 3300.0 +2000.0 2200.0 2500.0 2600.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2500.0 3100.0 3200.0 +1500.0 1700.0 1800.0 2300.0 3300.0 3400.0 +1400.0 1600.0 1800.0 2000.0 3200.0 3400.0 +1400.0 1600.0 1800.0 1900.0 3100.0 3400.0 +1400.0 1600.0 1900.0 2000.0 2900.0 3300.0 +1400.0 1500.0 1900.0 2000.0 2900.0 3200.0 +1900.0 2200.0 2500.0 2800.0 3100.0 3200.0 +1800.0 2200.0 2500.0 2700.0 3000.0 3200.0 +1800.0 2200.0 2600.0 2700.0 3100.0 3200.0 +2000.0 2300.0 2700.0 2800.0 3200.0 3300.0 +2100.0 2200.0 2600.0 2800.0 3000.0 3300.0 +2100.0 2200.0 2500.0 2700.0 3100.0 3300.0 +1700.0 1800.0 2000.0 2100.0 2800.0 3200.0 +1600.0 1700.0 1900.0 2000.0 2800.0 3200.0 +1400.0 1500.0 1800.0 1900.0 2800.0 3200.0 +1400.0 1800.0 2100.0 2400.0 3000.0 3200.0 +1600.0 1900.0 2300.0 2600.0 3000.0 3300.0 +1600.0 1900.0 2300.0 2500.0 3100.0 3300.0 +1600.0 1900.0 2400.0 2700.0 3000.0 3200.0 +1600.0 1900.0 2400.0 2700.0 3000.0 3300.0 +1500.0 1900.0 2400.0 2700.0 3000.0 3300.0 +1100.0 1400.0 2500.0 2800.0 3000.0 3300.0 +1100.0 1300.0 2300.0 2800.0 3000.0 3200.0 +1400.0 1500.0 2100.0 2700.0 2900.0 3100.0 +1500.0 1600.0 2100.0 2700.0 2900.0 3100.0 +1700.0 1800.0 2200.0 2600.0 2800.0 3100.0 +1800.0 2000.0 2300.0 2600.0 2800.0 3000.0 +1900.0 2100.0 2300.0 2600.0 2800.0 3100.0 +2000.0 2100.0 2300.0 2600.0 2800.0 3100.0 +2000.0 2100.0 2400.0 2500.0 2800.0 3200.0 +1900.0 2100.0 2300.0 2500.0 2800.0 3200.0 +1800.0 1900.0 2300.0 2500.0 2800.0 3300.0 +1700.0 1800.0 2300.0 2500.0 3000.0 3300.0 +1700.0 1900.0 2400.0 2600.0 3000.0 3200.0 +1500.0 1900.0 2200.0 2600.0 3100.0 3300.0 +1300.0 1500.0 1800.0 1900.0 2900.0 3200.0 +1300.0 1500.0 1800.0 1900.0 2900.0 3300.0 +1300.0 1500.0 1800.0 1900.0 2800.0 3200.0 +1400.0 1500.0 1700.0 1900.0 2800.0 3200.0 +1400.0 1500.0 1700.0 1800.0 2800.0 3200.0 +1700.0 2000.0 2400.0 2500.0 3100.0 3300.0 +2100.0 2400.0 2700.0 2800.0 3300.0 3500.0 +1800.0 2300.0 2700.0 2900.0 3200.0 3400.0 +1700.0 2300.0 2700.0 2900.0 3300.0 3400.0 +1700.0 2100.0 2700.0 2900.0 3300.0 3400.0 +1800.0 2400.0 2700.0 2900.0 3300.0 3400.0 +1900.0 2500.0 2800.0 3000.0 3300.0 3400.0 +2000.0 2500.0 2800.0 3000.0 3300.0 3400.0 +2000.0 2400.0 2700.0 3000.0 3200.0 3400.0 +1900.0 2300.0 2700.0 3000.0 3200.0 3400.0 +1800.0 2000.0 2500.0 2700.0 2900.0 3200.0 +1800.0 2000.0 2400.0 2700.0 2900.0 3100.0 +1900.0 2000.0 2300.0 2700.0 2900.0 3000.0 +1900.0 2000.0 2400.0 2700.0 2900.0 3100.0 +1800.0 1900.0 2400.0 2700.0 2900.0 3100.0 +1800.0 1900.0 2300.0 2700.0 2800.0 3100.0 +1800.0 1900.0 2300.0 2600.0 2800.0 3100.0 +1500.0 1800.0 2400.0 2700.0 3200.0 3400.0 +1600.0 1800.0 2500.0 2700.0 3100.0 3400.0 +1500.0 1700.0 2400.0 2700.0 3000.0 3300.0 +1400.0 1500.0 2400.0 2700.0 2900.0 3200.0 +1300.0 1500.0 2300.0 2700.0 2900.0 3100.0 +1400.0 1600.0 2100.0 2600.0 2800.0 3000.0 +1500.0 1600.0 2100.0 2600.0 2800.0 3000.0 +1400.0 1600.0 2200.0 2400.0 3000.0 3200.0 +1300.0 1600.0 2200.0 2500.0 2900.0 3200.0 +1300.0 1700.0 2200.0 2600.0 3000.0 3300.0 +1300.0 1700.0 2200.0 2700.0 3100.0 3200.0 +1200.0 1400.0 2200.0 2700.0 2900.0 3100.0 +1100.0 1400.0 2300.0 2700.0 2900.0 3100.0 +1100.0 1300.0 2400.0 2800.0 3000.0 3200.0 +1200.0 1600.0 2300.0 2600.0 3100.0 3200.0 +1500.0 2100.0 2400.0 2700.0 3200.0 3300.0 +1800.0 2100.0 2400.0 2800.0 3200.0 3300.0 +1600.0 2100.0 2400.0 2800.0 3200.0 3300.0 +1600.0 2000.0 2500.0 2900.0 3200.0 3300.0 +1800.0 2000.0 2500.0 2900.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2800.0 3100.0 3300.0 +1600.0 1800.0 2400.0 2700.0 3100.0 3300.0 +1500.0 1600.0 2200.0 2500.0 2900.0 3200.0 +1500.0 1600.0 2200.0 2500.0 2800.0 3200.0 +1400.0 1600.0 2100.0 2500.0 2800.0 3100.0 +1200.0 1400.0 2200.0 2500.0 2700.0 3100.0 +1100.0 1400.0 2400.0 2800.0 2900.0 3100.0 +1400.0 1700.0 2300.0 2600.0 2900.0 3200.0 +1500.0 1800.0 2300.0 2500.0 2900.0 3300.0 +1500.0 1700.0 2000.0 2100.0 3000.0 3300.0 +1500.0 1700.0 2000.0 2200.0 3100.0 3300.0 +1500.0 1700.0 2100.0 2300.0 3100.0 3200.0 +1600.0 1900.0 2500.0 2700.0 3100.0 3200.0 +1800.0 2300.0 2800.0 3100.0 3300.0 3400.0 +1800.0 2200.0 2700.0 2900.0 3200.0 3400.0 +1700.0 2200.0 2700.0 2800.0 3200.0 3400.0 +1500.0 1800.0 2600.0 2700.0 3000.0 3200.0 +1500.0 1700.0 2300.0 2700.0 2800.0 3100.0 +1400.0 1500.0 2100.0 2200.0 2700.0 3200.0 +1400.0 1500.0 2000.0 2100.0 2600.0 3100.0 +1300.0 1500.0 1900.0 2000.0 2500.0 3100.0 +1400.0 1500.0 1800.0 1900.0 2700.0 3200.0 +1500.0 1600.0 2000.0 2100.0 2600.0 3100.0 +1700.0 1800.0 2000.0 2200.0 2600.0 3100.0 +1700.0 1800.0 2100.0 2200.0 2700.0 3100.0 +1600.0 2000.0 2400.0 2500.0 3000.0 3200.0 +2000.0 2200.0 2500.0 2900.0 3100.0 3300.0 +1900.0 2200.0 2400.0 2600.0 2900.0 3100.0 +1600.0 1700.0 2200.0 2400.0 2700.0 3300.0 +1700.0 1800.0 2300.0 2400.0 2800.0 3200.0 +1800.0 1900.0 2300.0 2500.0 2800.0 3200.0 +1900.0 2100.0 2400.0 2500.0 3000.0 3300.0 +2100.0 2200.0 2500.0 2600.0 3000.0 3300.0 +2000.0 2100.0 2500.0 2700.0 2900.0 3200.0 +1700.0 1900.0 2200.0 2700.0 2800.0 3100.0 +1800.0 1900.0 2400.0 2700.0 2800.0 3200.0 +1800.0 1900.0 2400.0 2700.0 2900.0 3200.0 +1700.0 1800.0 2200.0 2700.0 2800.0 3100.0 +1700.0 1800.0 2200.0 2700.0 3000.0 3200.0 +1900.0 2100.0 2500.0 2900.0 3100.0 3300.0 +1700.0 2000.0 2500.0 2700.0 3200.0 3400.0 +1900.0 2200.0 2700.0 3000.0 3300.0 3400.0 +2000.0 2400.0 2800.0 3100.0 3400.0 3500.0 +2100.0 2400.0 2600.0 2900.0 3200.0 3300.0 +2100.0 2400.0 2500.0 2700.0 3100.0 3300.0 +1800.0 2100.0 2500.0 2700.0 3200.0 3300.0 +1700.0 2100.0 2400.0 2700.0 3200.0 3300.0 +1500.0 1600.0 1800.0 1900.0 2600.0 3100.0 +1500.0 1600.0 1900.0 2000.0 2500.0 3100.0 +1600.0 1700.0 2000.0 2100.0 2500.0 3100.0 +1800.0 2100.0 2300.0 2500.0 2800.0 3200.0 +1900.0 2100.0 2300.0 2500.0 2700.0 3200.0 +2000.0 2200.0 2400.0 2600.0 2900.0 3300.0 +2000.0 2200.0 2400.0 2600.0 2900.0 3200.0 +2000.0 2100.0 2400.0 2500.0 2900.0 3300.0 +1800.0 2200.0 2500.0 2900.0 3400.0 3500.0 +1800.0 2300.0 2500.0 2900.0 3300.0 3400.0 +2000.0 2300.0 2500.0 2800.0 3000.0 3300.0 +1800.0 2000.0 2400.0 2500.0 2800.0 3300.0 +1100.0 1400.0 2600.0 2800.0 3000.0 3200.0 +1300.0 1500.0 2200.0 2700.0 2900.0 3200.0 +1400.0 1600.0 2200.0 2700.0 3000.0 3200.0 +1400.0 1600.0 2200.0 2600.0 3100.0 3200.0 +1500.0 1800.0 2200.0 2400.0 3100.0 3300.0 +1700.0 1800.0 2200.0 2500.0 3000.0 3300.0 +1700.0 1800.0 2200.0 2600.0 3000.0 3200.0 +1700.0 1800.0 2300.0 2600.0 3000.0 3200.0 +1700.0 1800.0 2400.0 2700.0 3000.0 3100.0 +1600.0 1700.0 2500.0 2800.0 3000.0 3200.0 +1400.0 1500.0 2200.0 2700.0 2900.0 3100.0 +1300.0 1400.0 2100.0 2700.0 2900.0 3200.0 +1500.0 1900.0 2300.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2200.0 2500.0 2700.0 3100.0 +1600.0 1700.0 2200.0 2500.0 2800.0 3200.0 +1600.0 1800.0 2100.0 2500.0 2900.0 3200.0 +1600.0 1800.0 2100.0 2600.0 3000.0 3200.0 +1800.0 2100.0 2400.0 2800.0 3100.0 3300.0 +1800.0 2100.0 2400.0 2700.0 3000.0 3300.0 +2000.0 2100.0 2500.0 2800.0 3000.0 3200.0 +1800.0 2000.0 2500.0 2700.0 3000.0 3200.0 +1600.0 1900.0 2300.0 2700.0 2900.0 3200.0 +1600.0 1900.0 2100.0 2500.0 2800.0 3100.0 +1700.0 1900.0 2100.0 2500.0 2800.0 3000.0 +1700.0 1800.0 2100.0 2600.0 2800.0 3000.0 +1600.0 1700.0 2000.0 2600.0 2800.0 3000.0 +1400.0 1700.0 2200.0 2700.0 3000.0 3200.0 +1500.0 1800.0 2300.0 2700.0 3000.0 3200.0 +1600.0 1800.0 2300.0 2600.0 3000.0 3300.0 +1600.0 1800.0 2300.0 2600.0 3100.0 3300.0 +1600.0 1900.0 2300.0 2600.0 3100.0 3300.0 +1200.0 1300.0 2100.0 2700.0 3000.0 3100.0 +1300.0 1400.0 2100.0 2700.0 2900.0 3100.0 +1300.0 1400.0 2200.0 2700.0 2900.0 3100.0 +1300.0 1400.0 2100.0 2600.0 2800.0 3100.0 +1300.0 1500.0 2100.0 2600.0 2800.0 3100.0 +1500.0 1600.0 1900.0 2500.0 2900.0 3100.0 +1500.0 1700.0 2100.0 2700.0 2900.0 3200.0 +1600.0 1900.0 2400.0 2700.0 3200.0 3300.0 +1900.0 2100.0 2500.0 2800.0 3200.0 3400.0 +1700.0 2000.0 2400.0 2800.0 3200.0 3400.0 +1600.0 1700.0 2200.0 2400.0 2800.0 3300.0 +1500.0 1600.0 2200.0 2400.0 3000.0 3300.0 +1500.0 1700.0 2300.0 2700.0 3100.0 3300.0 +1400.0 1500.0 2000.0 2600.0 2900.0 3100.0 +1400.0 1500.0 2100.0 2500.0 2800.0 3100.0 +1400.0 1700.0 2200.0 2600.0 3000.0 3300.0 +1000.0 1500.0 2600.0 2800.0 3100.0 3400.0 +1300.0 1500.0 2500.0 2700.0 2900.0 3300.0 +1500.0 1600.0 2200.0 2600.0 2800.0 3100.0 +1700.0 1800.0 2200.0 2400.0 2700.0 3200.0 +1700.0 1800.0 2100.0 2400.0 2600.0 3100.0 +1600.0 1700.0 2100.0 2400.0 2700.0 3200.0 +1600.0 1900.0 2300.0 2700.0 3000.0 3300.0 +1500.0 1600.0 2000.0 2400.0 3000.0 3300.0 +1600.0 1800.0 2300.0 2600.0 3200.0 3300.0 +1700.0 1800.0 2400.0 2600.0 3200.0 3400.0 +1600.0 1800.0 2400.0 2600.0 3200.0 3400.0 +1700.0 1800.0 2300.0 2600.0 3000.0 3300.0 +1700.0 1800.0 2100.0 2500.0 2900.0 3200.0 +1800.0 1900.0 2100.0 2600.0 2800.0 3000.0 +1800.0 1900.0 2200.0 2600.0 2800.0 3000.0 +1800.0 1900.0 2200.0 2600.0 2900.0 3100.0 +1700.0 1800.0 2100.0 2600.0 2900.0 3100.0 +1600.0 1700.0 2100.0 2700.0 2900.0 3100.0 +1400.0 1600.0 2100.0 2700.0 2900.0 3200.0 +1200.0 1600.0 2200.0 2400.0 3000.0 3300.0 +1600.0 1900.0 2300.0 2700.0 3100.0 3400.0 +1200.0 1800.0 2300.0 2700.0 3100.0 3300.0 +1600.0 2000.0 2400.0 2800.0 3100.0 3300.0 +1700.0 1900.0 2100.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2600.0 3100.0 3400.0 +1900.0 2000.0 2300.0 2600.0 3200.0 3300.0 +1900.0 2000.0 2300.0 2600.0 3100.0 3300.0 +1900.0 2100.0 2300.0 2700.0 3100.0 3300.0 +1200.0 1400.0 2200.0 2800.0 3000.0 3100.0 +1800.0 2100.0 2400.0 2700.0 3200.0 3400.0 +1600.0 2100.0 2500.0 2800.0 3100.0 3300.0 +1600.0 2000.0 2500.0 2800.0 3200.0 3300.0 +1700.0 2000.0 2500.0 2800.0 3200.0 3400.0 +1700.0 1900.0 2700.0 2800.0 3100.0 3400.0 +1600.0 1800.0 2400.0 2600.0 3100.0 3400.0 +1600.0 1800.0 2300.0 2500.0 3100.0 3400.0 +1600.0 1800.0 2200.0 2500.0 3100.0 3400.0 +1600.0 1800.0 2100.0 2300.0 3100.0 3400.0 +1500.0 1700.0 2000.0 2200.0 3000.0 3300.0 +1500.0 1600.0 1900.0 2000.0 3000.0 3200.0 +1300.0 1500.0 1700.0 1900.0 2800.0 3200.0 +1800.0 2000.0 2300.0 2600.0 3000.0 3200.0 +1700.0 2000.0 2200.0 2600.0 3000.0 3200.0 +1600.0 1900.0 2400.0 2600.0 3000.0 3300.0 +1300.0 1700.0 2100.0 2400.0 2900.0 3200.0 +1600.0 1800.0 2400.0 2600.0 3000.0 3300.0 +1300.0 1600.0 2200.0 2300.0 2900.0 3200.0 +1300.0 1400.0 2100.0 2200.0 3000.0 3200.0 +1300.0 1500.0 1800.0 2000.0 3000.0 3200.0 +1300.0 1400.0 1800.0 1900.0 2800.0 3200.0 +1300.0 1700.0 2200.0 2500.0 3000.0 3200.0 +1200.0 1800.0 2300.0 2600.0 3200.0 3300.0 +1400.0 1900.0 2300.0 2700.0 3100.0 3300.0 +1500.0 2000.0 2400.0 2600.0 3000.0 3300.0 +1600.0 2000.0 2500.0 2600.0 3100.0 3300.0 +1600.0 1900.0 2500.0 2700.0 3100.0 3300.0 +1600.0 2000.0 2500.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2300.0 2600.0 2800.0 3200.0 +1300.0 1500.0 2000.0 2600.0 2700.0 3000.0 +1300.0 1500.0 2200.0 2600.0 2800.0 3100.0 +1400.0 1500.0 2100.0 2600.0 2800.0 3100.0 +1400.0 1500.0 2100.0 2600.0 2800.0 3000.0 +1500.0 1600.0 2000.0 2500.0 2700.0 3000.0 +1500.0 1700.0 2000.0 2500.0 2700.0 3000.0 +1600.0 1700.0 2000.0 2500.0 2800.0 3000.0 +1700.0 1800.0 2100.0 2500.0 2900.0 3100.0 +1700.0 1900.0 2100.0 2500.0 2900.0 3000.0 +1800.0 2000.0 2200.0 2600.0 2800.0 3000.0 +1800.0 2100.0 2300.0 2600.0 2800.0 3100.0 +1800.0 2100.0 2300.0 2600.0 2900.0 3100.0 +1800.0 2000.0 2200.0 2600.0 2900.0 3100.0 +1800.0 2000.0 2300.0 2600.0 2900.0 3100.0 +1800.0 2000.0 2300.0 2600.0 2800.0 3100.0 +1700.0 1900.0 2200.0 2600.0 2800.0 3000.0 +1700.0 1800.0 2100.0 2500.0 2700.0 3000.0 +1500.0 1700.0 2200.0 2400.0 2800.0 3300.0 +1500.0 1900.0 2300.0 2500.0 3100.0 3300.0 +1700.0 1800.0 2200.0 2800.0 3100.0 3200.0 +1700.0 1900.0 2100.0 2700.0 3000.0 3200.0 +1900.0 2100.0 2400.0 2600.0 3000.0 3200.0 +2000.0 2200.0 2400.0 2700.0 3000.0 3200.0 +1900.0 2300.0 2400.0 2700.0 3100.0 3300.0 +1500.0 1600.0 1800.0 2000.0 3100.0 3300.0 +1200.0 1400.0 1900.0 2500.0 2900.0 3100.0 +1600.0 1700.0 2000.0 2100.0 2900.0 3300.0 +1700.0 1800.0 2100.0 2200.0 2900.0 3300.0 +1800.0 1900.0 2200.0 2300.0 3000.0 3300.0 +1900.0 2000.0 2200.0 2300.0 3100.0 3300.0 +2000.0 2100.0 2300.0 2500.0 3100.0 3400.0 +1900.0 2100.0 2300.0 2500.0 3000.0 3200.0 +1800.0 2000.0 2300.0 2400.0 2900.0 3200.0 +1900.0 2200.0 2600.0 2800.0 3100.0 3300.0 +2000.0 2400.0 2600.0 2700.0 3200.0 3400.0 +1800.0 2200.0 2600.0 2700.0 3100.0 3300.0 +1600.0 2100.0 2600.0 2700.0 3100.0 3300.0 +1600.0 2100.0 2500.0 2800.0 3200.0 3400.0 +1900.0 2200.0 2500.0 2800.0 3200.0 3400.0 +1800.0 2000.0 2500.0 2800.0 3300.0 3400.0 +1700.0 1900.0 2600.0 2800.0 3100.0 3400.0 +1600.0 1700.0 2400.0 2700.0 3100.0 3300.0 +1400.0 1600.0 2200.0 2500.0 2800.0 3200.0 +1400.0 1600.0 2300.0 2500.0 2900.0 3200.0 +1400.0 1500.0 2300.0 2600.0 2900.0 3200.0 +1300.0 1500.0 2400.0 2600.0 3000.0 3300.0 +1200.0 1400.0 2400.0 2600.0 2900.0 3300.0 +1200.0 1300.0 2300.0 2600.0 2800.0 3200.0 +1200.0 1300.0 2300.0 2600.0 2800.0 3100.0 +1200.0 1400.0 2300.0 2600.0 2800.0 3200.0 +1200.0 1400.0 2300.0 2500.0 2800.0 3200.0 +1200.0 1400.0 2300.0 2500.0 2700.0 3200.0 +1300.0 1400.0 2300.0 2500.0 2700.0 3200.0 +1300.0 1400.0 2300.0 2400.0 2900.0 3200.0 +1300.0 1600.0 2300.0 2400.0 2900.0 3200.0 +1600.0 1700.0 2200.0 2500.0 3000.0 3200.0 +1600.0 1700.0 2200.0 2500.0 2900.0 3200.0 +1600.0 1800.0 2300.0 2400.0 2900.0 3200.0 +1600.0 1800.0 2200.0 2400.0 2900.0 3200.0 +1700.0 1900.0 2400.0 2700.0 3000.0 3300.0 +1600.0 1800.0 2400.0 2700.0 3000.0 3300.0 +1600.0 1800.0 2300.0 2600.0 2900.0 3200.0 +1600.0 1800.0 2500.0 2700.0 2900.0 3200.0 +1600.0 1900.0 2500.0 2800.0 3100.0 3300.0 +1600.0 1900.0 2500.0 2800.0 3000.0 3200.0 +1400.0 1700.0 2400.0 2700.0 2900.0 3200.0 +1400.0 1500.0 2200.0 2600.0 2800.0 3100.0 +1300.0 1500.0 2300.0 2600.0 2800.0 3100.0 +1200.0 1400.0 2300.0 2500.0 2700.0 3100.0 +1300.0 1600.0 2200.0 2600.0 3000.0 3300.0 +1200.0 1600.0 2500.0 2700.0 3100.0 3400.0 +1300.0 1800.0 2400.0 2700.0 3200.0 3400.0 +1300.0 1700.0 2300.0 2700.0 3100.0 3300.0 +1300.0 1700.0 2200.0 2500.0 3100.0 3300.0 +1300.0 1600.0 2200.0 2600.0 2900.0 3200.0 +1400.0 1600.0 2200.0 2700.0 2800.0 3100.0 +1600.0 1700.0 2200.0 2700.0 3100.0 3200.0 +1800.0 2000.0 2400.0 2800.0 3100.0 3300.0 +1800.0 2000.0 2400.0 2800.0 3200.0 3300.0 +1700.0 1800.0 2200.0 2700.0 2900.0 3100.0 +1700.0 1800.0 2300.0 2700.0 3000.0 3300.0 +1800.0 1900.0 2600.0 2800.0 3300.0 3400.0 +1900.0 2100.0 2300.0 2600.0 2900.0 3100.0 +1900.0 2200.0 2400.0 2700.0 3000.0 3100.0 +1800.0 2300.0 2400.0 2700.0 3000.0 3100.0 +1800.0 2300.0 2400.0 2600.0 3100.0 3200.0 +2000.0 2300.0 2400.0 2700.0 3100.0 3200.0 +2100.0 2300.0 2500.0 2700.0 3000.0 3200.0 +2000.0 2100.0 2500.0 2700.0 3000.0 3200.0 +1900.0 2000.0 2300.0 2700.0 2900.0 3100.0 +1600.0 1800.0 2200.0 2500.0 2700.0 3000.0 +1500.0 1800.0 2300.0 2500.0 2700.0 3000.0 +1500.0 1800.0 2200.0 2500.0 2700.0 3000.0 +1600.0 1800.0 2300.0 2500.0 2800.0 3000.0 +1700.0 1800.0 2400.0 2700.0 3000.0 3200.0 +1700.0 1800.0 2500.0 2700.0 3000.0 3200.0 +1700.0 1800.0 2400.0 2700.0 3000.0 3300.0 +1600.0 1700.0 2400.0 2600.0 2900.0 3200.0 +1500.0 1700.0 2400.0 2600.0 2800.0 3200.0 +1500.0 1700.0 2400.0 2500.0 2800.0 3200.0 +1400.0 1600.0 2400.0 2500.0 3000.0 3300.0 +1500.0 1700.0 2300.0 2400.0 2900.0 3200.0 +1500.0 1800.0 2200.0 2400.0 2800.0 3000.0 +1600.0 1900.0 2200.0 2600.0 2900.0 3100.0 +1800.0 2000.0 2300.0 2600.0 2900.0 3000.0 +1600.0 2000.0 2300.0 2500.0 2900.0 3100.0 +1600.0 1800.0 2100.0 2300.0 2900.0 3100.0 +1300.0 1500.0 2200.0 2400.0 3000.0 3200.0 +1300.0 1500.0 2200.0 2400.0 2900.0 3200.0 +1300.0 1500.0 2200.0 2500.0 2900.0 3200.0 +1400.0 1500.0 2300.0 2500.0 2900.0 3200.0 +1600.0 1700.0 2100.0 2500.0 2800.0 3100.0 +1600.0 1700.0 2100.0 2600.0 2800.0 3100.0 +1700.0 1800.0 2100.0 2500.0 2800.0 3100.0 +1700.0 1800.0 2200.0 2600.0 2900.0 3100.0 +1700.0 1900.0 2300.0 2600.0 2900.0 3200.0 +1800.0 2100.0 2300.0 2600.0 2900.0 3200.0 +1800.0 2100.0 2300.0 2700.0 2900.0 3200.0 +1900.0 2200.0 2400.0 2700.0 2900.0 3200.0 +1900.0 2100.0 2300.0 2700.0 2900.0 3100.0 +1900.0 2000.0 2300.0 2600.0 2800.0 3100.0 +1900.0 2200.0 2500.0 2800.0 3100.0 3300.0 +1900.0 2200.0 2400.0 2800.0 3000.0 3200.0 +1900.0 2200.0 2400.0 2700.0 2900.0 3100.0 +1900.0 2300.0 2400.0 2800.0 3100.0 3200.0 +2000.0 2300.0 2500.0 2800.0 3100.0 3300.0 +1900.0 2400.0 2500.0 2800.0 3100.0 3200.0 +1800.0 2000.0 2200.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2100.0 2400.0 2900.0 3200.0 +1500.0 1600.0 2200.0 2400.0 2700.0 3200.0 +1300.0 1400.0 2200.0 2500.0 2700.0 3200.0 +1200.0 1500.0 2500.0 2700.0 3000.0 3300.0 +1300.0 1600.0 2400.0 2600.0 3000.0 3300.0 +2000.0 2200.0 2600.0 2700.0 3000.0 3300.0 +2100.0 2300.0 2500.0 2700.0 3000.0 3300.0 +2100.0 2300.0 2600.0 2700.0 3000.0 3300.0 +2000.0 2200.0 2600.0 2700.0 3000.0 3200.0 +1800.0 2300.0 2500.0 2600.0 2900.0 3200.0 +1800.0 2300.0 2500.0 2700.0 2900.0 3100.0 +1800.0 2200.0 2400.0 2600.0 2900.0 3200.0 +1800.0 2200.0 2400.0 2600.0 2800.0 3100.0 +1800.0 2200.0 2300.0 2600.0 2900.0 3100.0 +1800.0 2000.0 2200.0 2800.0 3000.0 3200.0 +1800.0 1900.0 2200.0 2800.0 3000.0 3200.0 +1700.0 1900.0 2300.0 2800.0 3000.0 3300.0 +1600.0 1800.0 2300.0 2800.0 3000.0 3300.0 +1400.0 1700.0 2200.0 2500.0 2800.0 2900.0 +1400.0 1700.0 2100.0 2500.0 2900.0 3200.0 +1700.0 2000.0 2200.0 2800.0 3200.0 3300.0 +1800.0 1900.0 2200.0 2700.0 2900.0 3200.0 +1800.0 2000.0 2200.0 2700.0 2900.0 3100.0 +1800.0 2000.0 2200.0 2700.0 2800.0 3000.0 +1800.0 2000.0 2200.0 2700.0 2800.0 3100.0 +1600.0 1900.0 2100.0 2600.0 2900.0 3200.0 +2000.0 2100.0 2600.0 2900.0 3000.0 3200.0 +2000.0 2200.0 2700.0 2900.0 3100.0 3300.0 +2000.0 2200.0 2400.0 2800.0 3000.0 3200.0 +2000.0 2200.0 2300.0 2700.0 3000.0 3200.0 +1700.0 2200.0 2400.0 2600.0 2900.0 3100.0 +1800.0 2200.0 2400.0 2700.0 3000.0 3200.0 +1900.0 2300.0 2500.0 2700.0 3000.0 3200.0 +1900.0 2300.0 2500.0 2700.0 2900.0 3100.0 +1900.0 2300.0 2500.0 2800.0 3000.0 3200.0 +1900.0 2300.0 2500.0 2700.0 2900.0 3200.0 +1800.0 2200.0 2400.0 2700.0 2900.0 3100.0 +1800.0 2000.0 2300.0 2700.0 3000.0 3200.0 +1600.0 1700.0 2100.0 2800.0 3100.0 3200.0 +1400.0 1800.0 2200.0 2500.0 3000.0 3100.0 +1400.0 1800.0 2300.0 2500.0 3000.0 3100.0 +1400.0 1800.0 2300.0 2500.0 2900.0 3100.0 +1600.0 1800.0 2500.0 2800.0 3100.0 3200.0 +1700.0 2000.0 2400.0 2700.0 3200.0 3400.0 +1700.0 2000.0 2500.0 2800.0 3100.0 3400.0 +1500.0 1700.0 2300.0 2600.0 2900.0 3200.0 +1500.0 1700.0 2200.0 2600.0 2800.0 3200.0 +1500.0 1700.0 2200.0 2600.0 2900.0 3300.0 +1400.0 1700.0 2200.0 2600.0 2900.0 3300.0 +1200.0 1500.0 2200.0 2300.0 3100.0 3400.0 +1200.0 1600.0 2300.0 2400.0 3200.0 3300.0 +1200.0 1700.0 2300.0 2400.0 3100.0 3300.0 +1100.0 1700.0 2400.0 2500.0 3100.0 3300.0 +1100.0 1800.0 2500.0 2600.0 3100.0 3300.0 +1100.0 1800.0 2500.0 2600.0 3200.0 3300.0 +1000.0 1800.0 2500.0 2600.0 3200.0 3300.0 +1000.0 1700.0 2400.0 2500.0 3200.0 3300.0 +1100.0 1600.0 2400.0 2500.0 3200.0 3300.0 +1100.0 1600.0 2300.0 2400.0 3200.0 3300.0 +1300.0 1600.0 2300.0 2500.0 3100.0 3300.0 +1400.0 1700.0 2300.0 2500.0 3100.0 3300.0 +2000.0 2100.0 2500.0 2600.0 3200.0 3400.0 +1700.0 2100.0 2600.0 2800.0 3100.0 3200.0 +1800.0 2200.0 2700.0 2900.0 3100.0 3300.0 +2100.0 2400.0 2700.0 2900.0 3200.0 3300.0 +2100.0 2500.0 2700.0 2900.0 3300.0 3400.0 +2100.0 2400.0 2600.0 2800.0 3200.0 3400.0 +1700.0 1900.0 2400.0 2600.0 2900.0 3000.0 +1600.0 1900.0 2400.0 2500.0 2800.0 2900.0 +1300.0 2000.0 2400.0 2500.0 2900.0 3200.0 +1500.0 2000.0 2400.0 2500.0 2900.0 3100.0 +1600.0 2000.0 2400.0 2600.0 3000.0 3100.0 +1700.0 1900.0 2500.0 2600.0 3100.0 3200.0 +1600.0 1800.0 2600.0 2700.0 3300.0 3400.0 +1500.0 1600.0 2600.0 2700.0 3200.0 3400.0 +1500.0 1700.0 2600.0 2700.0 3200.0 3400.0 +1500.0 2100.0 2600.0 2800.0 3300.0 3400.0 +1700.0 2200.0 2700.0 2900.0 3300.0 3400.0 +1700.0 2300.0 2700.0 2800.0 3300.0 3400.0 +1800.0 2300.0 2700.0 2800.0 3300.0 3400.0 +1400.0 1700.0 2500.0 2600.0 3000.0 3300.0 +1400.0 1800.0 2500.0 2600.0 3000.0 3300.0 +1800.0 2200.0 2700.0 2900.0 3300.0 3400.0 +1800.0 2300.0 2600.0 2900.0 3300.0 3400.0 +1400.0 1900.0 2500.0 2600.0 3200.0 3400.0 +1400.0 2000.0 2400.0 2500.0 3200.0 3300.0 +1400.0 2100.0 2400.0 2600.0 3200.0 3300.0 +1200.0 2000.0 2400.0 2700.0 3200.0 3300.0 +1300.0 1900.0 2300.0 2600.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2500.0 3100.0 3200.0 +1200.0 1700.0 2300.0 2500.0 3000.0 3100.0 +1200.0 1800.0 2400.0 2500.0 3000.0 3100.0 +1100.0 2100.0 2300.0 2600.0 3000.0 3100.0 +1400.0 1800.0 2200.0 2700.0 3100.0 3200.0 +1600.0 2000.0 2400.0 2600.0 3200.0 3300.0 +1600.0 1900.0 2400.0 2600.0 3300.0 3400.0 +1600.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1600.0 2000.0 2300.0 2500.0 3300.0 3400.0 +1500.0 2400.0 2700.0 2800.0 3100.0 3300.0 +1300.0 2000.0 2500.0 2600.0 3200.0 3300.0 +1400.0 2000.0 2500.0 2600.0 3200.0 3300.0 +1600.0 1900.0 2400.0 2600.0 3200.0 3300.0 +1600.0 2000.0 2300.0 2600.0 3200.0 3300.0 +1600.0 2100.0 2300.0 2500.0 3000.0 3100.0 +1800.0 2100.0 2400.0 2700.0 2900.0 3200.0 +1500.0 1700.0 2000.0 2600.0 3200.0 3300.0 +1400.0 1700.0 2000.0 2400.0 3200.0 3300.0 +1400.0 1900.0 2200.0 2500.0 3100.0 3300.0 +1500.0 1900.0 2200.0 2500.0 3100.0 3300.0 +1200.0 1900.0 2500.0 2600.0 3100.0 3300.0 +1000.0 1700.0 2600.0 2800.0 3300.0 3400.0 +1200.0 1500.0 2400.0 2700.0 2900.0 3200.0 +1700.0 2100.0 2400.0 2800.0 3200.0 3400.0 +1700.0 2000.0 2600.0 2800.0 3100.0 3400.0 +1700.0 2000.0 2600.0 2700.0 3000.0 3300.0 +1500.0 1700.0 2500.0 2700.0 3000.0 3300.0 +1600.0 2000.0 2600.0 2800.0 3100.0 3300.0 +1500.0 2000.0 2500.0 2800.0 3200.0 3400.0 +1400.0 1800.0 2500.0 2800.0 3300.0 3400.0 +1700.0 2200.0 2600.0 2900.0 3200.0 3400.0 +1700.0 2200.0 2600.0 2800.0 3200.0 3400.0 +1800.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1500.0 1800.0 2200.0 2500.0 3100.0 3200.0 +1600.0 2100.0 2400.0 2700.0 3300.0 3400.0 +1400.0 1800.0 2500.0 2700.0 3000.0 3300.0 +1300.0 1600.0 2500.0 2600.0 3200.0 3400.0 +1400.0 1700.0 2500.0 2600.0 3300.0 3400.0 +1500.0 1700.0 2400.0 2500.0 3200.0 3400.0 +1900.0 2000.0 2300.0 2500.0 3200.0 3400.0 +1600.0 1900.0 2100.0 2500.0 3000.0 3200.0 +1600.0 2100.0 2500.0 2800.0 3200.0 3300.0 +1400.0 2000.0 2400.0 2700.0 3200.0 3300.0 +900.0 1800.0 2400.0 2600.0 3200.0 3300.0 +1100.0 1600.0 2700.0 2800.0 3200.0 3400.0 +1200.0 1600.0 2600.0 2800.0 3200.0 3400.0 +1300.0 1700.0 2500.0 2700.0 3100.0 3300.0 +1400.0 1700.0 2400.0 2700.0 3200.0 3300.0 +1400.0 1800.0 2300.0 2500.0 3100.0 3200.0 +1400.0 2100.0 2400.0 2600.0 2900.0 3100.0 +1300.0 2000.0 2400.0 2600.0 3100.0 3200.0 +1200.0 1800.0 2300.0 2500.0 3200.0 3300.0 +1300.0 1900.0 2300.0 2500.0 3100.0 3300.0 +1600.0 2000.0 2400.0 2600.0 3200.0 3400.0 +1800.0 2000.0 2300.0 2500.0 3100.0 3400.0 +1700.0 1900.0 2300.0 2400.0 3100.0 3300.0 +1600.0 1800.0 2300.0 2400.0 2900.0 3300.0 +1600.0 1800.0 2300.0 2400.0 3000.0 3300.0 +1600.0 1700.0 2300.0 2400.0 3000.0 3300.0 +1600.0 1700.0 2300.0 2400.0 2800.0 3200.0 +1600.0 1700.0 2300.0 2400.0 2900.0 3300.0 +1500.0 1700.0 2300.0 2500.0 3000.0 3300.0 +1400.0 1700.0 2500.0 2600.0 3200.0 3300.0 +1300.0 1600.0 2500.0 2700.0 3100.0 3300.0 +1300.0 1500.0 2500.0 2700.0 3100.0 3300.0 +1300.0 1600.0 2400.0 2700.0 3000.0 3400.0 +1800.0 2300.0 2600.0 2800.0 3100.0 3300.0 +1800.0 2200.0 2500.0 2800.0 3100.0 3300.0 +1700.0 2100.0 2500.0 2700.0 3000.0 3300.0 +1600.0 1900.0 2500.0 2700.0 2900.0 3200.0 +1700.0 2000.0 2500.0 2700.0 3000.0 3200.0 +1700.0 2300.0 2600.0 2700.0 3200.0 3400.0 +1400.0 1700.0 1900.0 2200.0 3200.0 3300.0 +1200.0 1900.0 2100.0 2600.0 3100.0 3200.0 +1200.0 1900.0 2200.0 2700.0 3100.0 3200.0 +1200.0 1900.0 2300.0 2700.0 3200.0 3300.0 +1100.0 2000.0 2300.0 2600.0 3200.0 3300.0 +1200.0 1900.0 2400.0 2700.0 3200.0 3300.0 +1200.0 1800.0 2300.0 2600.0 3200.0 3400.0 +1200.0 1600.0 2400.0 2700.0 3200.0 3400.0 +1200.0 1500.0 2400.0 2600.0 3000.0 3200.0 +1300.0 1500.0 2100.0 2500.0 2700.0 3000.0 +1200.0 1800.0 2400.0 2600.0 3100.0 3200.0 +1200.0 2000.0 2400.0 2500.0 3200.0 3300.0 +1700.0 2400.0 2700.0 3100.0 3300.0 3400.0 +2000.0 2500.0 2700.0 3100.0 3400.0 3500.0 +1900.0 2400.0 2700.0 3100.0 3400.0 3500.0 +1900.0 2200.0 2700.0 3100.0 3300.0 3400.0 +1800.0 2200.0 2700.0 3100.0 3300.0 3400.0 +1500.0 1700.0 2100.0 2500.0 3200.0 3300.0 +1400.0 1800.0 2100.0 2600.0 3200.0 3300.0 +1200.0 1700.0 2000.0 2300.0 3300.0 3400.0 +1300.0 1500.0 1600.0 2300.0 3100.0 3200.0 +1500.0 1900.0 2400.0 2600.0 3000.0 3300.0 +1500.0 2000.0 2400.0 2500.0 2800.0 3200.0 +1400.0 2000.0 2400.0 2500.0 2900.0 3200.0 +1300.0 1600.0 1700.0 2300.0 3300.0 3400.0 +1300.0 1600.0 1700.0 2100.0 3200.0 3400.0 +2000.0 2200.0 2500.0 2900.0 3300.0 3400.0 +2100.0 2300.0 2500.0 2700.0 3300.0 3400.0 +1900.0 2200.0 2400.0 2700.0 3300.0 3400.0 +1500.0 1900.0 2200.0 2400.0 3000.0 3300.0 +1500.0 1900.0 2400.0 2700.0 3300.0 3400.0 +1500.0 1700.0 2500.0 2700.0 3200.0 3400.0 +1500.0 1700.0 2500.0 2600.0 3100.0 3400.0 +1600.0 2000.0 2400.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2600.0 3000.0 3100.0 +1500.0 1800.0 2200.0 2600.0 3000.0 3100.0 +1500.0 1900.0 2400.0 2500.0 3000.0 3200.0 +1200.0 1500.0 2400.0 2600.0 3200.0 3300.0 +1500.0 2000.0 2500.0 2700.0 3100.0 3300.0 +1700.0 2100.0 2500.0 2900.0 3200.0 3300.0 +1400.0 1800.0 2400.0 2500.0 3100.0 3300.0 +1400.0 2000.0 2300.0 2500.0 3200.0 3400.0 +1200.0 1900.0 2200.0 2400.0 3300.0 3400.0 +1200.0 1900.0 2300.0 2500.0 3300.0 3400.0 +1200.0 1900.0 2300.0 2400.0 3300.0 3400.0 +1200.0 1700.0 2300.0 2400.0 3300.0 3400.0 +1200.0 1600.0 2200.0 2300.0 3300.0 3400.0 +1200.0 1600.0 2200.0 2400.0 3300.0 3400.0 +1300.0 1600.0 2100.0 2400.0 3200.0 3300.0 +1500.0 1700.0 2200.0 2600.0 2900.0 3200.0 +2100.0 2200.0 2500.0 2800.0 3200.0 3300.0 +1600.0 1800.0 2300.0 2500.0 3100.0 3300.0 +1500.0 1800.0 2300.0 2500.0 3100.0 3300.0 +1400.0 1800.0 2300.0 2600.0 3100.0 3300.0 +1400.0 1800.0 2400.0 2600.0 3100.0 3300.0 +1300.0 1800.0 2400.0 2700.0 3200.0 3300.0 +1100.0 1800.0 2400.0 2700.0 3200.0 3300.0 +1400.0 2000.0 2500.0 2600.0 2900.0 3200.0 +1500.0 2100.0 2500.0 2600.0 2900.0 3200.0 +1500.0 1900.0 2400.0 2600.0 3100.0 3300.0 +1300.0 1900.0 2400.0 2800.0 3100.0 3300.0 +1300.0 2000.0 2500.0 2700.0 3200.0 3300.0 +1300.0 1800.0 2600.0 2700.0 3100.0 3400.0 +1300.0 1700.0 2600.0 2700.0 3100.0 3300.0 +1300.0 1700.0 2600.0 2700.0 3100.0 3400.0 +1400.0 1900.0 2400.0 2600.0 2900.0 3100.0 +1500.0 1800.0 2300.0 2600.0 2900.0 3100.0 +1600.0 1900.0 2400.0 2600.0 3000.0 3200.0 +1700.0 2000.0 2600.0 2900.0 3100.0 3300.0 +1800.0 2300.0 2500.0 2800.0 3200.0 3400.0 +1900.0 2300.0 2600.0 2900.0 3300.0 3400.0 +1600.0 1900.0 2500.0 2600.0 3000.0 3100.0 +1600.0 1900.0 2500.0 2600.0 3000.0 3200.0 +1500.0 1800.0 2200.0 2500.0 3200.0 3300.0 +1500.0 1900.0 2200.0 2500.0 3300.0 3400.0 +1500.0 1800.0 2200.0 2400.0 3200.0 3400.0 +1500.0 1800.0 2100.0 2400.0 3200.0 3400.0 +1600.0 1800.0 2100.0 2200.0 3200.0 3400.0 +1700.0 1800.0 2100.0 2400.0 3100.0 3300.0 +1600.0 1700.0 2300.0 2400.0 2700.0 3100.0 +1600.0 1900.0 2400.0 2500.0 3000.0 3300.0 +1600.0 2100.0 2500.0 2600.0 3200.0 3400.0 +1200.0 2000.0 2400.0 2500.0 3400.0 3500.0 +1200.0 1600.0 2300.0 2400.0 3200.0 3400.0 +1400.0 1900.0 2400.0 2500.0 3000.0 3200.0 +1300.0 1800.0 2100.0 2500.0 3100.0 3300.0 +1300.0 1700.0 2300.0 2500.0 3100.0 3300.0 +1300.0 1700.0 2200.0 2400.0 3200.0 3300.0 +1300.0 1800.0 2200.0 2400.0 3200.0 3300.0 +1500.0 1800.0 2300.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2300.0 2500.0 3300.0 3400.0 +1700.0 1900.0 2400.0 2600.0 3300.0 3400.0 +1700.0 1900.0 2500.0 2700.0 3000.0 3100.0 +1700.0 1800.0 2500.0 2600.0 3100.0 3200.0 +1700.0 1800.0 2500.0 2600.0 3000.0 3200.0 +1600.0 1800.0 2400.0 2600.0 3000.0 3200.0 +1600.0 1800.0 2400.0 2600.0 3100.0 3300.0 +1500.0 1700.0 2400.0 2600.0 3100.0 3300.0 +1300.0 1700.0 2400.0 2600.0 3100.0 3300.0 +1300.0 1700.0 2400.0 2600.0 3200.0 3300.0 +1400.0 1800.0 2400.0 2600.0 3200.0 3300.0 +1400.0 1800.0 2300.0 2600.0 3200.0 3300.0 +1500.0 1800.0 2300.0 2600.0 3300.0 3400.0 +1500.0 1800.0 2300.0 2500.0 3300.0 3400.0 +1500.0 1700.0 2200.0 2400.0 3300.0 3400.0 +1800.0 2200.0 2400.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2300.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2000.0 2600.0 3200.0 3300.0 +1900.0 2000.0 2200.0 2500.0 3300.0 3400.0 +1900.0 2100.0 2300.0 2600.0 3300.0 3400.0 +1800.0 1900.0 2200.0 2600.0 3100.0 3300.0 +1100.0 1900.0 2600.0 2700.0 3200.0 3300.0 +1000.0 1700.0 2700.0 2800.0 3200.0 3300.0 +1000.0 1800.0 2600.0 2700.0 3000.0 3100.0 +1200.0 2000.0 2600.0 2800.0 3200.0 3300.0 +1200.0 2000.0 2500.0 2700.0 3200.0 3300.0 +1200.0 2000.0 2500.0 2600.0 3200.0 3300.0 +1200.0 2000.0 2400.0 2500.0 3300.0 3400.0 +1300.0 2000.0 2300.0 2500.0 3300.0 3400.0 +1300.0 1900.0 2300.0 2500.0 3300.0 3400.0 +1400.0 1900.0 2300.0 2600.0 3300.0 3400.0 +2200.0 2400.0 2500.0 2900.0 3200.0 3300.0 +2100.0 2200.0 2400.0 2800.0 3200.0 3300.0 +2000.0 2200.0 2400.0 2800.0 3200.0 3300.0 +1900.0 2100.0 2400.0 2800.0 3200.0 3300.0 +1600.0 1800.0 2000.0 2400.0 2800.0 3000.0 +1600.0 1900.0 2300.0 2400.0 2900.0 3300.0 +1800.0 2100.0 2400.0 2500.0 3100.0 3200.0 +1800.0 2300.0 2500.0 2700.0 3200.0 3300.0 +1800.0 2100.0 2500.0 2700.0 3300.0 3400.0 +1500.0 1900.0 2100.0 2700.0 3000.0 3100.0 +1500.0 1700.0 1800.0 2600.0 3300.0 3400.0 +1500.0 1700.0 1800.0 2500.0 3300.0 3400.0 +1300.0 1500.0 1600.0 2500.0 3200.0 3300.0 +1300.0 1500.0 1700.0 2400.0 3000.0 3100.0 +1600.0 2000.0 2500.0 2700.0 3300.0 3400.0 +2000.0 2100.0 2400.0 2700.0 3300.0 3400.0 +1800.0 2000.0 2200.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2100.0 2600.0 3200.0 3300.0 +1700.0 2000.0 2100.0 2700.0 3200.0 3300.0 +1700.0 2100.0 2200.0 2700.0 3200.0 3300.0 +1700.0 2200.0 2400.0 2700.0 3200.0 3300.0 +1700.0 2200.0 2400.0 2600.0 3200.0 3300.0 +1700.0 2100.0 2500.0 2600.0 3200.0 3300.0 +1800.0 2400.0 2600.0 3000.0 3300.0 3400.0 +1800.0 2400.0 2800.0 3100.0 3300.0 3400.0 +1900.0 2400.0 2800.0 3100.0 3300.0 3500.0 +1900.0 2300.0 2800.0 3000.0 3300.0 3400.0 +1600.0 1800.0 2400.0 2600.0 3000.0 3100.0 +1500.0 1700.0 1900.0 2500.0 3300.0 3400.0 +1200.0 1700.0 2200.0 2300.0 3100.0 3300.0 +1100.0 1500.0 2300.0 2400.0 3000.0 3300.0 +1200.0 1600.0 2300.0 2400.0 3100.0 3300.0 +1200.0 1600.0 2300.0 2400.0 3100.0 3400.0 +1300.0 1600.0 2200.0 2400.0 3200.0 3300.0 +1500.0 1600.0 2100.0 2400.0 3000.0 3300.0 +1600.0 1700.0 2100.0 2400.0 3100.0 3300.0 +1500.0 1600.0 2100.0 2500.0 3100.0 3300.0 +1600.0 1900.0 2200.0 2600.0 3100.0 3300.0 +1500.0 1800.0 2200.0 2500.0 3000.0 3200.0 +1400.0 1800.0 2200.0 2500.0 2900.0 3200.0 +1300.0 1600.0 2200.0 2600.0 3000.0 3200.0 +1700.0 2000.0 2400.0 2800.0 3000.0 3100.0 +1700.0 2100.0 2400.0 2700.0 3000.0 3100.0 +1800.0 2200.0 2500.0 2800.0 3000.0 3200.0 +1700.0 2100.0 2500.0 2800.0 3100.0 3200.0 +1800.0 2200.0 2500.0 2700.0 3200.0 3400.0 +1600.0 1900.0 2300.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2000.0 2400.0 3200.0 3300.0 +1500.0 1700.0 1900.0 2300.0 3300.0 3400.0 +1400.0 1600.0 1800.0 2200.0 3300.0 3400.0 +1500.0 1600.0 1900.0 2600.0 3000.0 3200.0 +1500.0 2000.0 2300.0 2600.0 3200.0 3300.0 +1200.0 1900.0 2100.0 2500.0 3200.0 3300.0 +1900.0 2100.0 2300.0 2600.0 3200.0 3300.0 +1800.0 2100.0 2300.0 2600.0 3300.0 3400.0 +1700.0 2100.0 2300.0 2600.0 3200.0 3300.0 +1600.0 2100.0 2300.0 2700.0 3200.0 3300.0 +1500.0 1900.0 2400.0 2700.0 3200.0 3300.0 +1400.0 1900.0 2400.0 2700.0 3200.0 3300.0 +1400.0 1900.0 2400.0 2600.0 3200.0 3300.0 +1500.0 2100.0 2500.0 2600.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2500.0 2900.0 3100.0 +1800.0 2000.0 2500.0 2800.0 3000.0 3200.0 +1400.0 1600.0 2100.0 2600.0 3000.0 3300.0 +1700.0 2000.0 2400.0 2700.0 3300.0 3400.0 +1700.0 2100.0 2500.0 2700.0 3300.0 3400.0 +1700.0 2100.0 2600.0 2700.0 3000.0 3300.0 +1800.0 2100.0 2500.0 2700.0 3100.0 3200.0 +2200.0 2300.0 2500.0 2800.0 3200.0 3300.0 +2100.0 2300.0 2500.0 2800.0 3200.0 3300.0 +2000.0 2200.0 2500.0 2800.0 3200.0 3300.0 +1900.0 2000.0 2400.0 2700.0 3100.0 3200.0 +1600.0 2000.0 2400.0 2700.0 3100.0 3400.0 +1300.0 1800.0 2100.0 2500.0 3100.0 3200.0 +1300.0 1800.0 2200.0 2800.0 3100.0 3200.0 +1300.0 2000.0 2200.0 2600.0 3200.0 3300.0 +1900.0 2100.0 2400.0 2500.0 3000.0 3200.0 +1800.0 2100.0 2400.0 2600.0 3200.0 3300.0 +1500.0 1900.0 2400.0 2600.0 3300.0 3400.0 +1500.0 1800.0 2400.0 2600.0 3200.0 3400.0 +1500.0 1700.0 2400.0 2600.0 3200.0 3400.0 +1400.0 1700.0 2400.0 2600.0 3100.0 3300.0 +1400.0 1900.0 2500.0 2600.0 2900.0 3200.0 +1400.0 1900.0 2400.0 2700.0 3000.0 3200.0 +1400.0 1900.0 2400.0 2600.0 3000.0 3100.0 +1400.0 1900.0 2300.0 2500.0 2700.0 3000.0 +1300.0 1800.0 2200.0 2500.0 3300.0 3400.0 +1300.0 1800.0 2200.0 2400.0 3300.0 3400.0 +1300.0 1700.0 2100.0 2400.0 3200.0 3400.0 +1400.0 1900.0 2300.0 2600.0 3100.0 3300.0 +1900.0 2200.0 2400.0 2800.0 3100.0 3200.0 +1600.0 2200.0 2400.0 2700.0 3300.0 3400.0 +1600.0 2100.0 2400.0 2700.0 3200.0 3300.0 +1400.0 1700.0 2000.0 2500.0 3000.0 3200.0 +1400.0 1800.0 2300.0 2500.0 3000.0 3200.0 +1700.0 1900.0 2100.0 2400.0 3200.0 3300.0 +1800.0 1900.0 2200.0 2500.0 3200.0 3300.0 +1900.0 2000.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2000.0 2500.0 2600.0 3100.0 3300.0 +1400.0 1900.0 2300.0 2500.0 2800.0 3200.0 +1400.0 1900.0 2300.0 2500.0 2900.0 3300.0 +1400.0 1600.0 2300.0 2500.0 3000.0 3200.0 +1400.0 1600.0 2200.0 2500.0 3100.0 3200.0 +2000.0 2200.0 2500.0 2700.0 3000.0 3300.0 +1600.0 2100.0 2600.0 2900.0 3200.0 3300.0 +1500.0 1700.0 2100.0 2500.0 3100.0 3200.0 +1200.0 2100.0 2600.0 2700.0 3200.0 3300.0 +1100.0 2100.0 2600.0 2800.0 3200.0 3300.0 +1000.0 2000.0 2800.0 2900.0 3100.0 3200.0 +1600.0 1900.0 2100.0 2500.0 3000.0 3100.0 +1700.0 1900.0 2200.0 2500.0 3000.0 3100.0 +1700.0 1900.0 2300.0 2400.0 3100.0 3200.0 +1400.0 2000.0 2300.0 2400.0 3200.0 3300.0 +1300.0 2000.0 2200.0 2400.0 3100.0 3200.0 +1200.0 2000.0 2300.0 2500.0 3100.0 3200.0 +1200.0 1800.0 2300.0 2600.0 3100.0 3200.0 +1300.0 1600.0 2300.0 2700.0 3100.0 3200.0 +1300.0 1700.0 2300.0 2700.0 3100.0 3200.0 +1100.0 2000.0 2300.0 2600.0 3100.0 3200.0 +1300.0 2000.0 2400.0 2500.0 3200.0 3300.0 +1300.0 1900.0 2400.0 2500.0 3200.0 3300.0 +1500.0 1800.0 2100.0 2600.0 3300.0 3400.0 +1500.0 1900.0 2100.0 2500.0 2800.0 3000.0 +1500.0 2000.0 2200.0 2500.0 3000.0 3100.0 +1500.0 2000.0 2200.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2300.0 2500.0 3100.0 3200.0 +1600.0 1900.0 2200.0 2400.0 3100.0 3200.0 +1600.0 1900.0 2400.0 2600.0 2900.0 3100.0 +1900.0 2300.0 2600.0 2800.0 3100.0 3200.0 +2000.0 2400.0 2700.0 2800.0 3100.0 3200.0 +1300.0 1800.0 2000.0 2400.0 3100.0 3200.0 +1100.0 1700.0 2100.0 2400.0 3100.0 3200.0 +1300.0 1600.0 2100.0 2500.0 3000.0 3100.0 +1200.0 1700.0 2200.0 2500.0 3000.0 3200.0 +1400.0 1800.0 2100.0 2300.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2200.0 3200.0 3300.0 +1700.0 1900.0 2100.0 2300.0 3200.0 3300.0 +1800.0 1900.0 2400.0 2800.0 3100.0 3200.0 +2000.0 2300.0 2800.0 3000.0 3100.0 3300.0 +2100.0 2300.0 2700.0 3000.0 3200.0 3300.0 +2100.0 2300.0 2600.0 2900.0 3200.0 3300.0 +2200.0 2400.0 2700.0 2800.0 3200.0 3300.0 +1700.0 2000.0 2300.0 2500.0 3000.0 3100.0 +1600.0 2000.0 2300.0 2400.0 2800.0 3200.0 +1700.0 2100.0 2300.0 2400.0 2900.0 3200.0 +1400.0 1800.0 2300.0 2600.0 3000.0 3300.0 +1500.0 2200.0 2400.0 2700.0 3100.0 3200.0 +1500.0 2200.0 2500.0 2700.0 3200.0 3300.0 +1400.0 1600.0 2400.0 2500.0 3100.0 3400.0 +1600.0 2200.0 2500.0 2800.0 3300.0 3400.0 +1600.0 2000.0 2500.0 2800.0 3300.0 3400.0 +1400.0 1700.0 2400.0 2500.0 3200.0 3400.0 +1400.0 1600.0 2400.0 2600.0 3200.0 3300.0 +1400.0 1700.0 2300.0 2500.0 3200.0 3300.0 +1500.0 2000.0 2300.0 2400.0 2800.0 3200.0 +1500.0 2000.0 2300.0 2400.0 2700.0 3200.0 +1400.0 1900.0 2300.0 2500.0 3000.0 3300.0 +1200.0 1400.0 2300.0 2600.0 2900.0 3100.0 +1500.0 2000.0 2300.0 2500.0 3000.0 3200.0 +1800.0 2000.0 2500.0 2600.0 3100.0 3200.0 +1500.0 1800.0 2400.0 2600.0 3000.0 3200.0 +1200.0 1500.0 2200.0 2400.0 3000.0 3100.0 +1500.0 1900.0 2400.0 2600.0 3200.0 3300.0 +1700.0 2000.0 2600.0 2800.0 3200.0 3300.0 +1500.0 1900.0 2100.0 2500.0 3200.0 3300.0 +1700.0 1800.0 2000.0 2300.0 3000.0 3100.0 +1600.0 1900.0 2300.0 2500.0 2800.0 3100.0 +1600.0 1800.0 2300.0 2500.0 3000.0 3200.0 +1700.0 1800.0 2300.0 2500.0 3200.0 3300.0 +1700.0 1800.0 2300.0 2500.0 3100.0 3300.0 +1600.0 1700.0 2200.0 2400.0 3000.0 3300.0 +1500.0 1700.0 2300.0 2500.0 3200.0 3400.0 +1500.0 1700.0 2300.0 2400.0 2800.0 3300.0 +1600.0 1700.0 2200.0 2400.0 2600.0 3200.0 +1700.0 1800.0 2200.0 2400.0 2900.0 3300.0 +1900.0 2100.0 2400.0 2500.0 3100.0 3300.0 +1900.0 2000.0 2400.0 2500.0 3100.0 3300.0 +1900.0 2300.0 2500.0 2900.0 3200.0 3300.0 +2200.0 2400.0 2700.0 3100.0 3300.0 3400.0 +2200.0 2400.0 2800.0 3100.0 3300.0 3400.0 +1500.0 1900.0 2300.0 2400.0 3200.0 3300.0 +1500.0 1800.0 2200.0 2300.0 3100.0 3300.0 +1700.0 2000.0 2600.0 2900.0 3200.0 3400.0 +1500.0 2000.0 2300.0 2500.0 3100.0 3200.0 +1300.0 1600.0 2000.0 2500.0 3000.0 3200.0 +1800.0 2000.0 2200.0 2500.0 3000.0 3100.0 +1200.0 1800.0 2200.0 2400.0 3100.0 3200.0 +1300.0 1500.0 2100.0 2200.0 3100.0 3200.0 +1400.0 1900.0 2200.0 2300.0 3200.0 3300.0 +1900.0 2300.0 2600.0 3000.0 3200.0 3400.0 +1900.0 2300.0 2600.0 2800.0 3200.0 3300.0 +1900.0 2200.0 2600.0 2900.0 3100.0 3300.0 +1200.0 1500.0 2500.0 2600.0 3100.0 3200.0 +1400.0 1900.0 2300.0 2400.0 2600.0 3100.0 +1500.0 1600.0 2100.0 2400.0 2900.0 3200.0 +1400.0 1600.0 2200.0 2600.0 2900.0 3200.0 +1700.0 1800.0 2100.0 2300.0 3000.0 3100.0 +1700.0 1900.0 2100.0 2300.0 3100.0 3200.0 +1800.0 1900.0 2200.0 2300.0 3200.0 3300.0 +1700.0 1900.0 2200.0 2300.0 3200.0 3300.0 +1700.0 1800.0 2200.0 2300.0 3200.0 3300.0 +1600.0 1700.0 2200.0 2300.0 3100.0 3300.0 +1700.0 2100.0 2400.0 2900.0 3300.0 3400.0 +1600.0 2100.0 2500.0 2700.0 3300.0 3400.0 +1500.0 2000.0 2400.0 2600.0 3100.0 3200.0 +1600.0 2000.0 2300.0 2500.0 2800.0 3000.0 +1500.0 1700.0 1800.0 2200.0 2800.0 2900.0 +1500.0 1700.0 1900.0 2100.0 2700.0 2800.0 +1600.0 2000.0 2300.0 2500.0 3000.0 3300.0 +1900.0 2300.0 2500.0 2800.0 3100.0 3200.0 +2200.0 2400.0 2600.0 3000.0 3200.0 3300.0 +2300.0 2500.0 2800.0 3100.0 3300.0 3400.0 +1900.0 2400.0 2700.0 3000.0 3400.0 3500.0 +1900.0 2400.0 2600.0 3000.0 3400.0 3500.0 +1800.0 2300.0 2700.0 3100.0 3400.0 3500.0 +1800.0 2300.0 2700.0 3000.0 3300.0 3400.0 +1400.0 1700.0 2200.0 2500.0 3200.0 3400.0 +1600.0 1900.0 2500.0 2600.0 3100.0 3300.0 +2000.0 2300.0 2600.0 2800.0 3300.0 3400.0 +1900.0 2200.0 2500.0 2800.0 3300.0 3400.0 +1700.0 2100.0 2400.0 2700.0 3300.0 3400.0 +1600.0 1700.0 2300.0 2500.0 3200.0 3400.0 +1600.0 1700.0 2300.0 2400.0 3300.0 3400.0 +1600.0 1800.0 2400.0 2600.0 3300.0 3400.0 +1500.0 1700.0 2300.0 2700.0 3300.0 3400.0 +1400.0 1800.0 2300.0 2400.0 3100.0 3400.0 +1500.0 2000.0 2300.0 2400.0 2900.0 3200.0 +1500.0 1900.0 2300.0 2400.0 2800.0 3200.0 +1300.0 1800.0 2200.0 2500.0 3000.0 3100.0 +1200.0 1700.0 2200.0 2300.0 3200.0 3300.0 +1200.0 1700.0 2200.0 2400.0 3200.0 3300.0 +1100.0 1700.0 2200.0 2400.0 3200.0 3300.0 +1100.0 1700.0 2300.0 2500.0 3100.0 3200.0 +1100.0 1700.0 2300.0 2600.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2600.0 3000.0 3200.0 +1300.0 1900.0 2300.0 2600.0 3000.0 3300.0 +1300.0 1800.0 2300.0 2600.0 3100.0 3300.0 +1400.0 2000.0 2500.0 2800.0 3200.0 3300.0 +1200.0 1600.0 2400.0 2700.0 3200.0 3300.0 +1500.0 1800.0 2300.0 2500.0 3100.0 3200.0 +1500.0 1600.0 2200.0 2600.0 3000.0 3200.0 +1500.0 1600.0 2200.0 2500.0 3000.0 3300.0 +1200.0 1600.0 2400.0 2600.0 3200.0 3400.0 +1000.0 2300.0 2800.0 2900.0 3100.0 3200.0 +900.0 1700.0 2700.0 2800.0 3200.0 3300.0 +1500.0 1700.0 2400.0 2500.0 3100.0 3200.0 +1500.0 1900.0 2400.0 2500.0 3100.0 3200.0 +1400.0 1900.0 2400.0 2500.0 2900.0 3100.0 +1600.0 2100.0 2400.0 2600.0 3000.0 3100.0 +1700.0 1900.0 2300.0 2500.0 3000.0 3100.0 +2100.0 2400.0 2600.0 2900.0 3100.0 3300.0 +2200.0 2400.0 2700.0 2900.0 3200.0 3300.0 +2100.0 2200.0 2700.0 2800.0 3100.0 3300.0 +2000.0 2100.0 2300.0 2600.0 3100.0 3300.0 +1800.0 2000.0 2100.0 2600.0 3100.0 3200.0 +1800.0 1900.0 2200.0 2500.0 2900.0 3000.0 +1800.0 1900.0 2300.0 2400.0 3000.0 3100.0 +1800.0 1900.0 2200.0 2400.0 3000.0 3100.0 +1800.0 2000.0 2200.0 2500.0 3100.0 3200.0 +1800.0 2000.0 2300.0 2800.0 3100.0 3200.0 +1800.0 2000.0 2400.0 2800.0 3100.0 3200.0 +1800.0 2000.0 2400.0 2800.0 3000.0 3100.0 +1700.0 1900.0 2300.0 2700.0 2900.0 3100.0 +1700.0 1900.0 2200.0 2700.0 2900.0 3100.0 +1600.0 1800.0 2000.0 2600.0 2800.0 3000.0 +1500.0 1700.0 2000.0 2500.0 2900.0 3100.0 +1700.0 1900.0 2200.0 2500.0 3000.0 3200.0 +1700.0 1800.0 2300.0 2400.0 3100.0 3300.0 +1800.0 2000.0 2300.0 2500.0 3000.0 3100.0 +1800.0 1900.0 2200.0 2400.0 3100.0 3200.0 +1400.0 1600.0 2100.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2000.0 2500.0 3000.0 3200.0 +1400.0 1800.0 2000.0 2400.0 3200.0 3300.0 +1200.0 1900.0 2100.0 2500.0 3100.0 3200.0 +1100.0 1700.0 2100.0 2300.0 3000.0 3100.0 +1300.0 1500.0 1700.0 2000.0 2900.0 3100.0 +1600.0 1900.0 2200.0 2400.0 2900.0 3100.0 +1700.0 2000.0 2200.0 2500.0 3200.0 3300.0 +1700.0 1800.0 2100.0 2500.0 3100.0 3300.0 +2000.0 2300.0 2500.0 2700.0 3100.0 3400.0 +1900.0 2200.0 2500.0 2600.0 3000.0 3300.0 +1900.0 2000.0 2300.0 2400.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2400.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2500.0 3100.0 3200.0 +1700.0 1800.0 2300.0 2400.0 3000.0 3100.0 +1500.0 1600.0 2500.0 2600.0 2900.0 3300.0 +1500.0 1700.0 2500.0 2600.0 3100.0 3200.0 +1900.0 2300.0 2500.0 2800.0 3200.0 3300.0 +1400.0 1600.0 2000.0 2600.0 3000.0 3200.0 +1700.0 1900.0 2100.0 2600.0 3000.0 3100.0 +1800.0 1900.0 2400.0 2900.0 3100.0 3300.0 +1800.0 1900.0 2500.0 2900.0 3100.0 3300.0 +1600.0 1800.0 2100.0 2700.0 3000.0 3200.0 +1700.0 2000.0 2300.0 2700.0 2900.0 3200.0 +1600.0 2000.0 2400.0 2600.0 2900.0 3200.0 +1500.0 1700.0 2300.0 2500.0 3300.0 3400.0 +1400.0 1600.0 2200.0 2400.0 3100.0 3300.0 +1500.0 1600.0 2200.0 2500.0 3200.0 3400.0 +1600.0 1700.0 2300.0 2400.0 3200.0 3300.0 +1600.0 1700.0 2300.0 2500.0 3200.0 3300.0 +1600.0 1700.0 2200.0 2500.0 3200.0 3300.0 +1700.0 2100.0 2300.0 2400.0 3100.0 3300.0 +1600.0 2000.0 2400.0 2500.0 3000.0 3300.0 +1500.0 1800.0 2300.0 2400.0 2900.0 3200.0 +1600.0 2000.0 2400.0 2800.0 3200.0 3400.0 +1900.0 2200.0 2600.0 2800.0 3200.0 3400.0 +1900.0 2200.0 2500.0 2800.0 3100.0 3400.0 +1300.0 1800.0 2400.0 2600.0 3100.0 3400.0 +1300.0 1500.0 2400.0 2500.0 2900.0 3300.0 +1300.0 1700.0 2500.0 2600.0 3100.0 3200.0 +1300.0 1700.0 2600.0 2700.0 3200.0 3300.0 +1400.0 1900.0 2600.0 2700.0 3200.0 3300.0 +1400.0 2000.0 2600.0 2700.0 3200.0 3300.0 +1700.0 1900.0 2100.0 2600.0 3200.0 3300.0 +1700.0 2000.0 2100.0 2300.0 3200.0 3300.0 +2000.0 2100.0 2400.0 2600.0 3200.0 3400.0 +2100.0 2200.0 2500.0 2700.0 3200.0 3400.0 +1800.0 1900.0 2500.0 2700.0 3200.0 3400.0 +1700.0 2000.0 2500.0 2700.0 3300.0 3400.0 +1400.0 1900.0 2500.0 2700.0 3100.0 3200.0 +1500.0 1800.0 2500.0 2600.0 3100.0 3300.0 +1600.0 2000.0 2300.0 2600.0 3000.0 3200.0 +1600.0 1900.0 2300.0 2700.0 3000.0 3200.0 +1600.0 1800.0 2300.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2100.0 2500.0 3000.0 3200.0 +1400.0 1800.0 2200.0 2500.0 2700.0 3100.0 +1400.0 1900.0 2300.0 2500.0 3100.0 3200.0 +1300.0 2000.0 2300.0 2500.0 3100.0 3200.0 +1300.0 1900.0 2300.0 2500.0 3100.0 3200.0 +1800.0 2100.0 2500.0 2700.0 3000.0 3300.0 +1800.0 2100.0 2400.0 2700.0 3100.0 3300.0 +1900.0 2100.0 2500.0 2700.0 3100.0 3300.0 +1600.0 1800.0 2300.0 2400.0 3200.0 3400.0 +1700.0 1800.0 2400.0 2500.0 3300.0 3400.0 +1900.0 2000.0 2700.0 2800.0 3200.0 3400.0 +1900.0 2000.0 2600.0 2900.0 3100.0 3300.0 +2000.0 2200.0 2800.0 2900.0 3300.0 3400.0 +2000.0 2100.0 2700.0 2800.0 3300.0 3400.0 +1900.0 2100.0 2400.0 2700.0 3300.0 3400.0 +1600.0 1900.0 2100.0 2500.0 3200.0 3300.0 +1400.0 1900.0 2100.0 2400.0 3200.0 3300.0 +1200.0 1900.0 2100.0 2400.0 3100.0 3200.0 +1200.0 1800.0 2100.0 2500.0 2900.0 3200.0 +1300.0 1700.0 1900.0 2400.0 2800.0 2900.0 +1900.0 2300.0 2600.0 3000.0 3200.0 3300.0 +1800.0 2300.0 2600.0 3000.0 3300.0 3400.0 +1800.0 2200.0 2500.0 2800.0 3300.0 3500.0 +1700.0 1900.0 2300.0 2400.0 3200.0 3400.0 +1800.0 1900.0 2400.0 2500.0 3100.0 3300.0 +2100.0 2200.0 2400.0 2500.0 3100.0 3300.0 +1800.0 2100.0 2500.0 2800.0 3100.0 3200.0 +2000.0 2300.0 2600.0 2700.0 3100.0 3300.0 +2100.0 2200.0 2500.0 2600.0 3100.0 3300.0 +2000.0 2200.0 2300.0 2500.0 3100.0 3300.0 +1800.0 1900.0 2100.0 2300.0 3200.0 3300.0 +1800.0 1900.0 2100.0 2400.0 3300.0 3400.0 +1700.0 1800.0 2200.0 2300.0 3300.0 3400.0 +1700.0 1800.0 2200.0 2300.0 3200.0 3400.0 +1600.0 1700.0 2200.0 2300.0 2900.0 3400.0 +1400.0 1600.0 2500.0 2600.0 3100.0 3200.0 +1300.0 1400.0 2400.0 2600.0 3000.0 3100.0 +1300.0 1500.0 2400.0 2500.0 3000.0 3200.0 +1300.0 1800.0 2400.0 2500.0 3100.0 3200.0 +1300.0 1900.0 2400.0 2500.0 3100.0 3200.0 +1800.0 1900.0 2200.0 2400.0 3300.0 3400.0 +1000.0 1500.0 2500.0 2600.0 3200.0 3400.0 +1000.0 1700.0 2500.0 2600.0 3200.0 3300.0 +1300.0 1700.0 2200.0 2600.0 3000.0 3200.0 +900.0 1800.0 2400.0 2600.0 3300.0 3400.0 +900.0 1800.0 2300.0 2400.0 3300.0 3400.0 +1000.0 1600.0 2300.0 2400.0 3300.0 3400.0 +1400.0 1900.0 2200.0 2600.0 3300.0 3400.0 +1500.0 1900.0 2300.0 2600.0 3300.0 3400.0 +1300.0 2000.0 2200.0 2500.0 3000.0 3200.0 +1100.0 1800.0 2300.0 2500.0 3200.0 3300.0 +1100.0 1800.0 2400.0 2600.0 3200.0 3300.0 +1100.0 1900.0 2400.0 2700.0 3200.0 3300.0 +1300.0 2000.0 2200.0 2400.0 3200.0 3300.0 +1800.0 2100.0 2400.0 2800.0 3300.0 3400.0 +1700.0 2200.0 2500.0 2700.0 3300.0 3400.0 +1700.0 2000.0 2300.0 2700.0 3200.0 3400.0 +1200.0 1600.0 2500.0 2600.0 3200.0 3400.0 +1100.0 1900.0 2500.0 2600.0 3200.0 3300.0 +1500.0 1600.0 2400.0 2700.0 2900.0 3200.0 +1500.0 1800.0 2500.0 2700.0 3100.0 3400.0 +1600.0 1900.0 2600.0 2800.0 3100.0 3300.0 +1700.0 1800.0 2600.0 2700.0 3000.0 3300.0 +1700.0 1800.0 2500.0 2600.0 2900.0 3200.0 +1700.0 1800.0 2500.0 2600.0 3000.0 3300.0 +1600.0 1700.0 2500.0 2600.0 3000.0 3300.0 +1700.0 2000.0 2400.0 2700.0 3100.0 3400.0 +1700.0 1800.0 2400.0 2600.0 2900.0 3200.0 +1800.0 1900.0 2500.0 2600.0 2900.0 3200.0 +1700.0 1800.0 2200.0 2500.0 2700.0 3200.0 +1700.0 1800.0 2300.0 2500.0 2800.0 3200.0 +1500.0 1600.0 2000.0 2400.0 2600.0 2900.0 +1200.0 1300.0 2100.0 2400.0 2600.0 3200.0 +1700.0 2200.0 2500.0 2900.0 3200.0 3400.0 +1700.0 2200.0 2600.0 2900.0 3400.0 3500.0 +1700.0 2100.0 2700.0 2900.0 3400.0 3500.0 +1500.0 1800.0 2400.0 2600.0 3100.0 3300.0 +1100.0 1700.0 2500.0 2600.0 3200.0 3300.0 +1300.0 1700.0 2600.0 2700.0 3200.0 3400.0 +1400.0 1900.0 2600.0 2800.0 3200.0 3300.0 +1600.0 2000.0 2500.0 2900.0 3300.0 3400.0 +1500.0 1700.0 2500.0 2700.0 3100.0 3300.0 +1800.0 2000.0 2500.0 2700.0 2900.0 3300.0 +1900.0 2000.0 2600.0 2700.0 2900.0 3300.0 +1900.0 2100.0 2400.0 2700.0 2900.0 3200.0 +1900.0 2000.0 2500.0 2700.0 3000.0 3300.0 +1900.0 2000.0 2400.0 2700.0 3000.0 3300.0 +1700.0 1900.0 2500.0 2600.0 3100.0 3400.0 +1600.0 1900.0 2500.0 2600.0 3200.0 3500.0 +1900.0 2100.0 2600.0 2900.0 3200.0 3400.0 +2100.0 2300.0 2700.0 2900.0 3200.0 3300.0 +1600.0 2000.0 2200.0 2400.0 3100.0 3200.0 +1700.0 1900.0 2200.0 2400.0 2900.0 3100.0 +1700.0 1800.0 2100.0 2400.0 2800.0 3200.0 +1900.0 2200.0 2500.0 2700.0 3000.0 3200.0 +1900.0 2300.0 2600.0 2700.0 3100.0 3200.0 +1800.0 2400.0 2600.0 2900.0 3200.0 3300.0 +1800.0 2300.0 2500.0 2900.0 3200.0 3300.0 +1600.0 1800.0 2500.0 2600.0 3300.0 3400.0 +1500.0 1700.0 2200.0 2400.0 2900.0 3200.0 +1500.0 1600.0 2200.0 2300.0 2800.0 3200.0 +1400.0 1500.0 2100.0 2200.0 2800.0 3200.0 +1400.0 1500.0 2100.0 2300.0 2800.0 3200.0 +1400.0 1500.0 2200.0 2400.0 2700.0 3100.0 +1700.0 1900.0 2400.0 2800.0 3100.0 3200.0 +1700.0 1800.0 2400.0 2700.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2700.0 2900.0 3300.0 +2000.0 2100.0 2400.0 2700.0 3000.0 3300.0 +1400.0 1600.0 2500.0 2700.0 3100.0 3400.0 +1000.0 1600.0 2300.0 2400.0 3100.0 3200.0 +1100.0 1700.0 2400.0 2500.0 3200.0 3300.0 +1200.0 1700.0 2300.0 2400.0 3100.0 3200.0 +2000.0 2100.0 2400.0 2500.0 3100.0 3300.0 +1900.0 2000.0 2300.0 2500.0 3100.0 3300.0 +1600.0 1800.0 2300.0 2500.0 3200.0 3300.0 +1400.0 1600.0 2300.0 2400.0 3100.0 3300.0 +1300.0 1500.0 2300.0 2500.0 3000.0 3300.0 +1300.0 1500.0 2300.0 2500.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2600.0 3100.0 3200.0 +1800.0 1900.0 2400.0 2500.0 3000.0 3200.0 +1900.0 2400.0 2600.0 3000.0 3200.0 3300.0 +1400.0 1500.0 2400.0 2600.0 2900.0 3300.0 +1400.0 1500.0 2200.0 2600.0 2800.0 3300.0 +1400.0 1500.0 2200.0 2500.0 2800.0 3200.0 +1400.0 1500.0 2300.0 2500.0 3000.0 3300.0 +1600.0 2000.0 2400.0 2700.0 3200.0 3400.0 +1700.0 2200.0 2600.0 2800.0 3100.0 3300.0 +1800.0 2100.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2200.0 2500.0 2700.0 3200.0 3300.0 +1500.0 1700.0 2200.0 2300.0 3000.0 3300.0 +1600.0 1700.0 2200.0 2500.0 3200.0 3400.0 +1600.0 1800.0 2300.0 2400.0 3100.0 3300.0 +1700.0 1800.0 2200.0 2400.0 3000.0 3300.0 +1700.0 1800.0 2200.0 2300.0 3000.0 3200.0 +1700.0 1800.0 2200.0 2300.0 3100.0 3300.0 +1700.0 2000.0 2200.0 2600.0 3200.0 3300.0 +1800.0 1900.0 2200.0 2500.0 3100.0 3200.0 +1600.0 1700.0 2100.0 2400.0 2900.0 3200.0 +1500.0 1800.0 2300.0 2700.0 3000.0 3300.0 +1500.0 1800.0 2200.0 2600.0 3000.0 3300.0 +1700.0 2000.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2000.0 2600.0 2800.0 3200.0 3400.0 +1800.0 1900.0 2500.0 2800.0 3100.0 3300.0 +1600.0 1800.0 2500.0 2600.0 3000.0 3300.0 +1200.0 1500.0 2500.0 2700.0 3100.0 3200.0 +1100.0 1900.0 2500.0 2600.0 3100.0 3200.0 +1200.0 1900.0 2400.0 2500.0 3100.0 3200.0 +1500.0 1700.0 2100.0 2200.0 3200.0 3300.0 +1600.0 1800.0 2000.0 2200.0 3300.0 3400.0 +1500.0 1600.0 1800.0 2000.0 3300.0 3400.0 +1400.0 1600.0 1800.0 1900.0 3300.0 3400.0 +1400.0 1600.0 2400.0 2600.0 3000.0 3400.0 +1400.0 1800.0 2500.0 2600.0 3100.0 3200.0 +1500.0 1700.0 2400.0 2700.0 3100.0 3300.0 +1500.0 1800.0 2500.0 2700.0 3000.0 3300.0 +1400.0 1500.0 2400.0 2600.0 3000.0 3300.0 +1200.0 1400.0 2300.0 2400.0 3000.0 3200.0 +1200.0 1600.0 2300.0 2400.0 3100.0 3200.0 +1400.0 2000.0 2400.0 2700.0 3100.0 3300.0 +1600.0 1900.0 2300.0 2700.0 3100.0 3200.0 +1500.0 1900.0 2300.0 2700.0 3100.0 3200.0 +1200.0 1400.0 2300.0 2500.0 3100.0 3300.0 +1800.0 1900.0 2400.0 2600.0 3000.0 3100.0 +1800.0 1900.0 2500.0 2600.0 2900.0 3100.0 +1600.0 2000.0 2400.0 2700.0 3000.0 3300.0 +1600.0 1900.0 2400.0 2500.0 3100.0 3300.0 +1600.0 1900.0 2500.0 2600.0 3100.0 3200.0 +1700.0 1800.0 2400.0 2500.0 2900.0 3300.0 +1700.0 1800.0 2300.0 2500.0 2900.0 3200.0 +1700.0 1800.0 2400.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2200.0 2500.0 3000.0 3200.0 +1700.0 2000.0 2300.0 2500.0 3000.0 3200.0 +1800.0 2000.0 2300.0 2500.0 3000.0 3200.0 +1900.0 2100.0 2300.0 2600.0 3000.0 3200.0 +1900.0 2100.0 2400.0 2600.0 3000.0 3300.0 +2000.0 2100.0 2300.0 2500.0 3000.0 3200.0 +1700.0 1800.0 2300.0 2600.0 3100.0 3300.0 +1700.0 2100.0 2500.0 2700.0 3200.0 3400.0 +1700.0 1900.0 2300.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2200.0 2400.0 2900.0 3300.0 +1800.0 1900.0 2300.0 2500.0 3000.0 3300.0 +1800.0 2000.0 2200.0 2500.0 2900.0 3200.0 +1900.0 2200.0 2400.0 2600.0 2900.0 3200.0 +1700.0 2100.0 2600.0 2800.0 3100.0 3300.0 +1800.0 2300.0 2700.0 2900.0 3200.0 3300.0 +2000.0 2300.0 2800.0 2900.0 3100.0 3300.0 +2100.0 2200.0 2600.0 2800.0 3200.0 3300.0 +1800.0 1900.0 2300.0 2400.0 3100.0 3200.0 +1700.0 1800.0 2300.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2600.0 3100.0 3200.0 +1800.0 2000.0 2300.0 2600.0 3100.0 3200.0 +1400.0 1600.0 1800.0 2000.0 3100.0 3300.0 +1300.0 1700.0 2300.0 2400.0 3100.0 3200.0 +1500.0 1700.0 2300.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2300.0 2500.0 2900.0 3100.0 +1500.0 1700.0 2300.0 2500.0 2900.0 3100.0 +1500.0 1700.0 2300.0 2500.0 2800.0 3000.0 +1500.0 1600.0 2300.0 2500.0 2800.0 3200.0 +1400.0 1500.0 2300.0 2600.0 3000.0 3200.0 +1200.0 1600.0 2400.0 2500.0 3000.0 3300.0 +1400.0 1600.0 2200.0 2500.0 2900.0 3200.0 +1500.0 1900.0 2300.0 2600.0 2900.0 3200.0 +1400.0 1800.0 2400.0 2700.0 3200.0 3400.0 +1500.0 1900.0 2400.0 2700.0 3200.0 3400.0 +1700.0 2100.0 2400.0 2800.0 3000.0 3300.0 +1700.0 2000.0 2500.0 2700.0 3100.0 3400.0 +1800.0 1900.0 2400.0 2800.0 3200.0 3300.0 +1800.0 1900.0 2300.0 2900.0 3200.0 3300.0 +1800.0 1900.0 2500.0 2800.0 3200.0 3300.0 +1700.0 1800.0 2400.0 2800.0 3200.0 3300.0 +1700.0 1800.0 2400.0 2700.0 3200.0 3300.0 +1600.0 1700.0 2300.0 2600.0 3000.0 3300.0 +1600.0 1700.0 2200.0 2500.0 2900.0 3300.0 +1500.0 1600.0 2300.0 2500.0 3000.0 3300.0 +1500.0 1900.0 2400.0 2500.0 3300.0 3400.0 +1500.0 2000.0 2400.0 2800.0 3200.0 3300.0 +1400.0 1800.0 2400.0 2700.0 3200.0 3300.0 +1400.0 1900.0 2400.0 2700.0 3200.0 3400.0 +1300.0 1700.0 2300.0 2500.0 3200.0 3400.0 +1100.0 1700.0 2300.0 2400.0 3100.0 3200.0 +1500.0 1700.0 1900.0 2200.0 3300.0 3400.0 +1900.0 2300.0 2600.0 2800.0 3200.0 3400.0 +1900.0 2400.0 2700.0 2800.0 3300.0 3400.0 +2000.0 2300.0 2700.0 2900.0 3400.0 3500.0 +1900.0 2300.0 2700.0 2900.0 3400.0 3500.0 +1900.0 2100.0 2800.0 2900.0 3300.0 3400.0 +1700.0 1800.0 2700.0 2800.0 3100.0 3300.0 +1500.0 1700.0 2700.0 2800.0 3200.0 3300.0 +1500.0 1600.0 2600.0 2700.0 3000.0 3300.0 +1400.0 1600.0 2600.0 2800.0 3000.0 3200.0 +1200.0 1400.0 2600.0 2700.0 3000.0 3200.0 +1000.0 1500.0 2600.0 2800.0 3200.0 3400.0 +1100.0 1300.0 2500.0 2800.0 3000.0 3200.0 +1500.0 1600.0 2500.0 2600.0 3000.0 3300.0 +1400.0 1500.0 2300.0 2600.0 2800.0 3200.0 +1400.0 1600.0 2200.0 2600.0 2800.0 3100.0 +1500.0 1600.0 2300.0 2700.0 2900.0 3200.0 +1400.0 1500.0 2500.0 2600.0 3100.0 3400.0 +1400.0 1500.0 2400.0 2600.0 2800.0 3300.0 +1400.0 1600.0 2400.0 2600.0 2800.0 3200.0 +1300.0 1600.0 2300.0 2600.0 2900.0 3300.0 +1700.0 2200.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2300.0 2600.0 2700.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2600.0 3100.0 3200.0 +1800.0 2300.0 2500.0 2600.0 3200.0 3300.0 +1900.0 2400.0 2500.0 2800.0 3300.0 3400.0 +1800.0 2000.0 2600.0 2800.0 3300.0 3400.0 +1600.0 1900.0 2400.0 2800.0 3200.0 3300.0 +1700.0 1800.0 2600.0 2800.0 3000.0 3300.0 +1900.0 2000.0 2600.0 2800.0 3200.0 3300.0 +2000.0 2100.0 2700.0 2800.0 3200.0 3400.0 +2000.0 2100.0 2600.0 2800.0 3300.0 3400.0 +1600.0 1700.0 2300.0 2600.0 2900.0 3300.0 +1400.0 1600.0 2400.0 2500.0 2800.0 3200.0 +1800.0 1900.0 2500.0 2700.0 3000.0 3400.0 +1900.0 2000.0 2600.0 2700.0 3000.0 3300.0 +1700.0 2000.0 2400.0 2600.0 2900.0 3200.0 +1500.0 1600.0 2300.0 2600.0 3000.0 3300.0 +1500.0 1600.0 2400.0 2600.0 2900.0 3300.0 +1400.0 1500.0 2300.0 2700.0 3000.0 3300.0 +1600.0 1800.0 2500.0 2600.0 2900.0 3200.0 +2000.0 2100.0 2400.0 2600.0 3000.0 3200.0 +1800.0 2000.0 2300.0 2400.0 3200.0 3300.0 +1600.0 1900.0 2300.0 2400.0 3200.0 3300.0 +1500.0 1800.0 2400.0 2700.0 3200.0 3300.0 +1700.0 1900.0 2300.0 2400.0 3000.0 3200.0 +2000.0 2200.0 2400.0 2500.0 3200.0 3300.0 +2200.0 2300.0 2600.0 2700.0 3200.0 3300.0 +2100.0 2200.0 2400.0 2700.0 3000.0 3200.0 +2100.0 2200.0 2500.0 2700.0 3000.0 3200.0 +2200.0 2300.0 2600.0 2800.0 3000.0 3300.0 +1900.0 2200.0 2600.0 2700.0 3000.0 3300.0 +1700.0 1800.0 2500.0 2700.0 2800.0 3200.0 +1700.0 1800.0 2600.0 2700.0 3000.0 3200.0 +1700.0 1900.0 2500.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2500.0 2700.0 3300.0 3400.0 +1800.0 2000.0 2400.0 2600.0 3100.0 3200.0 +1700.0 2200.0 2300.0 2500.0 3200.0 3300.0 +1700.0 2200.0 2300.0 2600.0 3100.0 3200.0 +1600.0 1700.0 2400.0 2600.0 3300.0 3400.0 +1600.0 1700.0 2400.0 2500.0 3300.0 3400.0 +1900.0 2100.0 2500.0 2800.0 3000.0 3100.0 +1800.0 2100.0 2500.0 2800.0 3000.0 3100.0 +1800.0 2100.0 2600.0 2800.0 3100.0 3200.0 +1800.0 2000.0 2500.0 2800.0 3100.0 3200.0 +1900.0 2100.0 2500.0 2600.0 3000.0 3200.0 +1800.0 1900.0 2600.0 2800.0 3200.0 3400.0 +1500.0 2100.0 2500.0 2700.0 3300.0 3400.0 +1100.0 2000.0 2400.0 2600.0 3300.0 3400.0 +1100.0 1900.0 2400.0 2500.0 3300.0 3400.0 +1300.0 1500.0 2200.0 2400.0 2900.0 3300.0 +1600.0 1700.0 2300.0 2500.0 2900.0 3300.0 +1600.0 1700.0 2400.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2500.0 2600.0 3100.0 3300.0 +1900.0 2000.0 2500.0 2700.0 3100.0 3200.0 +2100.0 2200.0 2400.0 2600.0 3100.0 3400.0 +2100.0 2200.0 2500.0 2600.0 3000.0 3400.0 +1900.0 2100.0 2400.0 2700.0 3000.0 3100.0 +1600.0 1800.0 2200.0 2400.0 3000.0 3200.0 +1600.0 1700.0 2200.0 2300.0 2900.0 3300.0 +1600.0 1700.0 2100.0 2300.0 2800.0 3100.0 +2200.0 2300.0 2600.0 2800.0 3100.0 3300.0 +2200.0 2300.0 2700.0 2800.0 3100.0 3400.0 +2000.0 2100.0 2600.0 2800.0 3100.0 3400.0 +1700.0 1800.0 2400.0 2700.0 2900.0 3200.0 +1600.0 1800.0 2400.0 2700.0 3100.0 3200.0 +1600.0 1800.0 2300.0 2400.0 3000.0 3200.0 +1800.0 1900.0 2400.0 2600.0 3100.0 3300.0 +1900.0 2000.0 2300.0 2600.0 2900.0 3200.0 +1900.0 2100.0 2300.0 2700.0 2800.0 3000.0 +1800.0 2000.0 2600.0 2700.0 3000.0 3300.0 +1800.0 1900.0 2400.0 2600.0 2900.0 3300.0 +1700.0 1800.0 2300.0 2400.0 2900.0 3300.0 +1600.0 1700.0 2100.0 2500.0 3000.0 3200.0 +1600.0 1800.0 2200.0 2600.0 3100.0 3200.0 +1500.0 1700.0 2200.0 2500.0 2900.0 3300.0 +1500.0 1600.0 2300.0 2400.0 2800.0 3300.0 +1400.0 1600.0 2300.0 2400.0 3000.0 3300.0 +1500.0 2000.0 2500.0 2800.0 3200.0 3300.0 +1300.0 1500.0 2600.0 2700.0 3100.0 3300.0 +1200.0 1400.0 1700.0 1900.0 3100.0 3300.0 +1200.0 1700.0 1900.0 2300.0 3200.0 3300.0 +1200.0 1900.0 2000.0 2300.0 3200.0 3300.0 +1200.0 2000.0 2100.0 2500.0 3300.0 3400.0 +1200.0 2000.0 2200.0 2600.0 3300.0 3400.0 +1200.0 2000.0 2300.0 2400.0 3200.0 3300.0 +1000.0 1900.0 2300.0 2500.0 3200.0 3300.0 +1200.0 1800.0 2200.0 2500.0 3100.0 3200.0 +1400.0 1600.0 2300.0 2500.0 3200.0 3300.0 +1500.0 1600.0 2500.0 2700.0 2900.0 3200.0 +1600.0 1900.0 2400.0 2800.0 3100.0 3300.0 +1700.0 1800.0 2400.0 2800.0 3100.0 3200.0 +1700.0 1800.0 2500.0 2800.0 3100.0 3200.0 +1500.0 1800.0 2400.0 2500.0 2900.0 3100.0 +1500.0 1600.0 2400.0 2500.0 2900.0 3200.0 +1300.0 1500.0 2200.0 2500.0 2800.0 3100.0 +1300.0 1400.0 2000.0 2400.0 2600.0 2900.0 +1400.0 1500.0 2100.0 2500.0 2700.0 3100.0 +1500.0 2000.0 2300.0 2600.0 3000.0 3200.0 +1700.0 2100.0 2400.0 2600.0 2900.0 3100.0 +1400.0 1500.0 2300.0 2600.0 3000.0 3300.0 +1500.0 1700.0 2200.0 2300.0 3200.0 3300.0 +1400.0 1600.0 2000.0 2400.0 3100.0 3300.0 +1500.0 1700.0 2000.0 2100.0 3100.0 3300.0 +1600.0 1900.0 2200.0 2500.0 2900.0 3200.0 +1500.0 1600.0 2200.0 2400.0 2800.0 3200.0 +1500.0 1600.0 2100.0 2500.0 3000.0 3300.0 +1500.0 1600.0 2000.0 2500.0 2900.0 3300.0 +1500.0 1600.0 2100.0 2500.0 2900.0 3200.0 +1500.0 1600.0 2200.0 2700.0 2800.0 3100.0 +1300.0 1400.0 2200.0 2600.0 3000.0 3200.0 +1400.0 1900.0 2400.0 2700.0 3100.0 3300.0 +1600.0 1800.0 2500.0 2600.0 3000.0 3200.0 +1500.0 1700.0 2300.0 2500.0 2800.0 3200.0 +1700.0 1800.0 2200.0 2400.0 3200.0 3300.0 +1700.0 1900.0 2200.0 2300.0 3000.0 3300.0 +1600.0 1700.0 2000.0 2400.0 3000.0 3200.0 +1700.0 1800.0 2300.0 2600.0 2900.0 3200.0 +1500.0 2000.0 2300.0 2600.0 3100.0 3400.0 +1400.0 1900.0 2500.0 2700.0 3100.0 3300.0 +1400.0 1700.0 2600.0 2700.0 3100.0 3300.0 +1500.0 1600.0 2300.0 2600.0 2800.0 3200.0 +1700.0 1800.0 2300.0 2500.0 3100.0 3400.0 +1500.0 1600.0 2200.0 2300.0 3100.0 3300.0 +1400.0 1500.0 2200.0 2400.0 3100.0 3200.0 +1400.0 1600.0 2200.0 2400.0 3000.0 3100.0 +1700.0 2100.0 2300.0 2700.0 3100.0 3200.0 +1900.0 2300.0 2500.0 2700.0 3100.0 3200.0 +1900.0 2300.0 2600.0 2800.0 3100.0 3300.0 +1900.0 2400.0 2600.0 2900.0 3200.0 3300.0 +1900.0 2300.0 2600.0 2800.0 3300.0 3400.0 +1800.0 2400.0 2600.0 2800.0 3300.0 3400.0 +1600.0 1800.0 2600.0 2700.0 3000.0 3300.0 +1600.0 1700.0 2600.0 2700.0 2900.0 3200.0 +1500.0 1600.0 2500.0 2700.0 3000.0 3300.0 +1300.0 1400.0 2400.0 2700.0 2900.0 3300.0 +1300.0 1400.0 2300.0 2700.0 2800.0 3100.0 +1300.0 1400.0 2500.0 2800.0 3000.0 3300.0 +1500.0 1700.0 2400.0 2500.0 2800.0 3300.0 +1900.0 2000.0 2500.0 2600.0 3000.0 3200.0 +1800.0 2000.0 2400.0 2500.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2300.0 2800.0 3100.0 +1700.0 1800.0 2200.0 2400.0 2800.0 3200.0 +1600.0 1700.0 2200.0 2400.0 2800.0 3200.0 +1500.0 1600.0 2200.0 2400.0 2700.0 3300.0 +1400.0 1500.0 2200.0 2400.0 2900.0 3200.0 +1600.0 1700.0 2300.0 2500.0 2700.0 3000.0 +1600.0 1700.0 2200.0 2500.0 2700.0 3000.0 +1700.0 1900.0 2200.0 2500.0 2800.0 3100.0 +1900.0 2000.0 2300.0 2500.0 2900.0 3100.0 +1900.0 2100.0 2300.0 2500.0 2900.0 3200.0 +1900.0 2100.0 2300.0 2500.0 3100.0 3300.0 +2000.0 2200.0 2600.0 2800.0 3000.0 3200.0 +1900.0 2200.0 2500.0 2700.0 2900.0 3200.0 +2100.0 2300.0 2600.0 2800.0 3100.0 3300.0 +2100.0 2300.0 2600.0 2700.0 3000.0 3200.0 +2100.0 2200.0 2500.0 2600.0 3000.0 3200.0 +1500.0 1600.0 2300.0 2400.0 2900.0 3200.0 +1400.0 1500.0 2100.0 2400.0 2800.0 3100.0 +1300.0 1600.0 2100.0 2400.0 3100.0 3200.0 +1300.0 1400.0 2300.0 2600.0 2800.0 3200.0 +1400.0 1500.0 2200.0 2500.0 2700.0 3200.0 +1400.0 1500.0 2300.0 2500.0 2700.0 3200.0 +1500.0 1600.0 2400.0 2500.0 2800.0 3200.0 +1600.0 1700.0 2400.0 2500.0 2900.0 3200.0 +1700.0 1800.0 2400.0 2500.0 2900.0 3100.0 +1800.0 1900.0 2400.0 2600.0 3000.0 3200.0 +2100.0 2200.0 2700.0 2900.0 3200.0 3300.0 +1800.0 2100.0 2500.0 2900.0 3100.0 3300.0 +1700.0 1800.0 2500.0 2800.0 2900.0 3300.0 +1200.0 1600.0 2100.0 2400.0 3000.0 3200.0 +1600.0 1700.0 2100.0 2600.0 2900.0 3000.0 +1600.0 1700.0 2200.0 2700.0 2900.0 3000.0 +1600.0 1800.0 2200.0 2500.0 2900.0 3000.0 +1700.0 1800.0 2300.0 2500.0 2900.0 3100.0 +1700.0 1900.0 2300.0 2600.0 2900.0 3100.0 +1500.0 1700.0 2000.0 2600.0 2900.0 3100.0 +1400.0 1600.0 1800.0 2600.0 3000.0 3100.0 +1300.0 1500.0 1700.0 2700.0 3100.0 3200.0 +1300.0 1700.0 2400.0 2700.0 3100.0 3300.0 +1200.0 1600.0 2400.0 2600.0 2900.0 3200.0 +1300.0 1400.0 2000.0 2700.0 2800.0 3000.0 +1400.0 1500.0 2000.0 2600.0 2800.0 3000.0 +1500.0 1700.0 2100.0 2600.0 2800.0 3000.0 +1600.0 1800.0 2200.0 2700.0 2800.0 3000.0 +1600.0 1800.0 2100.0 2700.0 2900.0 3100.0 +1500.0 1900.0 2300.0 2700.0 3000.0 3100.0 +1500.0 1900.0 2300.0 2700.0 3000.0 3200.0 +1500.0 2000.0 2300.0 2700.0 3000.0 3200.0 +1800.0 2100.0 2300.0 2700.0 3100.0 3300.0 +1500.0 2000.0 2300.0 2600.0 3000.0 3100.0 +1500.0 2100.0 2300.0 2700.0 3100.0 3200.0 +1600.0 2100.0 2200.0 2700.0 3100.0 3200.0 +1500.0 2100.0 2200.0 2600.0 3100.0 3200.0 +1400.0 2300.0 2500.0 2700.0 3100.0 3200.0 +1700.0 2100.0 2300.0 2700.0 2900.0 3100.0 +1500.0 1800.0 2300.0 2700.0 3000.0 3100.0 +1500.0 1700.0 2300.0 2700.0 3000.0 3100.0 +1500.0 1600.0 2100.0 2700.0 3000.0 3100.0 +1400.0 1500.0 1900.0 2600.0 3100.0 3200.0 +1200.0 1300.0 1900.0 2600.0 2900.0 3100.0 +1100.0 1200.0 1800.0 2700.0 3000.0 3100.0 +1200.0 1300.0 1800.0 2700.0 3000.0 3100.0 +1200.0 1400.0 1900.0 2700.0 3000.0 3100.0 +1300.0 1500.0 1800.0 2600.0 3000.0 3100.0 +1200.0 1400.0 2300.0 2700.0 2900.0 3100.0 +1300.0 1400.0 2200.0 2700.0 2800.0 3100.0 +1300.0 1500.0 2000.0 2600.0 2900.0 3100.0 +1300.0 1500.0 2100.0 2700.0 2900.0 3100.0 +1400.0 1800.0 2100.0 2600.0 2800.0 3000.0 +1400.0 1800.0 2100.0 2500.0 2900.0 3100.0 +1700.0 2000.0 2500.0 2800.0 3000.0 3200.0 +1900.0 2000.0 2700.0 2800.0 3100.0 3400.0 +1900.0 2100.0 2600.0 2800.0 3100.0 3300.0 +1600.0 2100.0 2400.0 2700.0 3200.0 3400.0 +1700.0 2000.0 2300.0 2500.0 2800.0 3200.0 +1500.0 1700.0 2100.0 2300.0 3000.0 3200.0 +1400.0 1900.0 2200.0 2500.0 2900.0 3200.0 +1400.0 1900.0 2300.0 2500.0 2700.0 3100.0 +1300.0 1500.0 2100.0 2700.0 2800.0 3100.0 +1300.0 1500.0 2000.0 2600.0 2800.0 3100.0 +1300.0 1400.0 2100.0 2600.0 2800.0 3000.0 +1300.0 1400.0 2000.0 2600.0 2800.0 3000.0 +1200.0 1300.0 2000.0 2700.0 2800.0 3000.0 +1200.0 1400.0 2300.0 2600.0 2900.0 3200.0 +1300.0 1600.0 2300.0 2700.0 2900.0 3200.0 +1600.0 1900.0 2300.0 2800.0 3100.0 3200.0 +1700.0 1900.0 2300.0 2800.0 3000.0 3200.0 +1700.0 1900.0 2100.0 2600.0 2900.0 3000.0 +1700.0 1900.0 2400.0 2600.0 2800.0 3100.0 +1700.0 2100.0 2400.0 2500.0 2800.0 3100.0 +1700.0 2000.0 2400.0 2500.0 2900.0 3100.0 +1900.0 2200.0 2400.0 2600.0 3000.0 3200.0 +1700.0 2000.0 2400.0 2700.0 3000.0 3100.0 +1500.0 1900.0 2300.0 2600.0 3000.0 3100.0 +1500.0 1600.0 2100.0 2600.0 2900.0 3200.0 +1400.0 1600.0 1800.0 2300.0 2800.0 2900.0 +1400.0 1600.0 1700.0 2500.0 3200.0 3300.0 +1400.0 1600.0 1800.0 2400.0 3200.0 3300.0 +1400.0 1700.0 1900.0 2200.0 3100.0 3200.0 +1300.0 1700.0 1900.0 2300.0 3100.0 3200.0 +1100.0 1600.0 2000.0 2300.0 3000.0 3100.0 +1500.0 1900.0 2500.0 2800.0 3200.0 3300.0 +1800.0 2000.0 2300.0 2800.0 3000.0 3100.0 +1800.0 1900.0 2300.0 2700.0 2900.0 3200.0 +1700.0 1900.0 2300.0 2600.0 2800.0 3100.0 +1700.0 1900.0 2100.0 2500.0 2700.0 3000.0 +1700.0 1900.0 2100.0 2600.0 2800.0 3000.0 +1700.0 1900.0 2100.0 2700.0 2900.0 3100.0 +1700.0 1900.0 2500.0 2800.0 3000.0 3300.0 +1400.0 1600.0 1900.0 2600.0 2900.0 3000.0 +1500.0 1600.0 2000.0 2200.0 3200.0 3300.0 +1300.0 1500.0 1700.0 2600.0 3100.0 3200.0 +1300.0 1500.0 1700.0 2700.0 3000.0 3100.0 +1500.0 1700.0 2300.0 2700.0 3000.0 3200.0 +1700.0 2000.0 2500.0 2800.0 3100.0 3200.0 +1200.0 1300.0 1800.0 2600.0 3000.0 3100.0 +1300.0 1600.0 2000.0 2400.0 3000.0 3200.0 +1500.0 1600.0 2000.0 2600.0 3200.0 3300.0 +1600.0 1700.0 2100.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2700.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2700.0 3200.0 3300.0 +1600.0 1900.0 2100.0 2700.0 3200.0 3300.0 +1100.0 1800.0 2200.0 2400.0 3000.0 3200.0 +1800.0 1900.0 2200.0 2800.0 3100.0 3200.0 +1700.0 1900.0 2100.0 2700.0 3000.0 3100.0 +1500.0 1800.0 2200.0 2800.0 3100.0 3200.0 +1600.0 1900.0 2200.0 2800.0 3100.0 3200.0 +1600.0 1900.0 2100.0 2700.0 3100.0 3200.0 +1500.0 1900.0 2100.0 2600.0 3100.0 3200.0 +1700.0 2100.0 2400.0 2700.0 3000.0 3300.0 +1900.0 2400.0 2700.0 2900.0 3200.0 3300.0 +1700.0 2200.0 2700.0 2900.0 3200.0 3300.0 +1700.0 2100.0 2700.0 2900.0 3200.0 3300.0 +1700.0 2200.0 2600.0 2900.0 3200.0 3300.0 +1800.0 2400.0 2600.0 2800.0 3100.0 3200.0 +1800.0 2400.0 2500.0 2800.0 3100.0 3200.0 +1800.0 2300.0 2400.0 2700.0 3100.0 3200.0 +1600.0 2300.0 2500.0 2700.0 3100.0 3200.0 +1500.0 2200.0 2400.0 2600.0 3100.0 3200.0 +1600.0 2200.0 2400.0 2600.0 3100.0 3200.0 +1500.0 2200.0 2500.0 2700.0 3100.0 3200.0 +1500.0 2200.0 2400.0 2600.0 3000.0 3100.0 +1600.0 2200.0 2400.0 2700.0 3000.0 3100.0 +1500.0 2100.0 2400.0 2700.0 3000.0 3100.0 +1400.0 1800.0 2100.0 2400.0 3200.0 3300.0 +1200.0 1300.0 2100.0 2800.0 3000.0 3200.0 +1300.0 1400.0 2100.0 2700.0 3000.0 3200.0 +1500.0 1700.0 2200.0 2800.0 3000.0 3100.0 +1800.0 2200.0 2400.0 2600.0 3000.0 3200.0 +1700.0 1900.0 2400.0 2500.0 3000.0 3200.0 +1700.0 1800.0 2500.0 2800.0 3000.0 3200.0 +1600.0 1800.0 2500.0 2700.0 3000.0 3200.0 +1600.0 1700.0 2300.0 2700.0 2900.0 3100.0 +1500.0 1700.0 2100.0 2700.0 3000.0 3100.0 +1500.0 1600.0 2000.0 2600.0 2900.0 3000.0 +1500.0 1600.0 1900.0 2600.0 3000.0 3100.0 +1500.0 1700.0 2000.0 2500.0 3000.0 3100.0 +1500.0 1700.0 2000.0 2500.0 3100.0 3200.0 +1500.0 1700.0 2000.0 2600.0 3000.0 3100.0 +1500.0 1800.0 2000.0 2700.0 3000.0 3100.0 +1700.0 2000.0 2500.0 2800.0 3100.0 3300.0 +1800.0 2000.0 2600.0 2900.0 3200.0 3300.0 +1800.0 2000.0 2500.0 2900.0 3100.0 3300.0 +1400.0 1600.0 1900.0 2600.0 3000.0 3100.0 +1400.0 1600.0 1900.0 2700.0 3000.0 3100.0 +1500.0 1700.0 2300.0 2800.0 3000.0 3200.0 +1700.0 2000.0 2500.0 2700.0 3100.0 3200.0 +1800.0 2300.0 2600.0 2800.0 3200.0 3300.0 +1800.0 2100.0 2600.0 3000.0 3300.0 3400.0 +1800.0 2100.0 2600.0 3000.0 3200.0 3400.0 +1600.0 1800.0 2300.0 2700.0 3100.0 3200.0 +1500.0 1800.0 2100.0 2600.0 3100.0 3200.0 +1100.0 1400.0 2100.0 2800.0 3100.0 3200.0 +1200.0 1700.0 2200.0 2400.0 3000.0 3200.0 +1500.0 2100.0 2500.0 2800.0 3200.0 3400.0 +1500.0 2000.0 2200.0 2400.0 3100.0 3300.0 +1400.0 1900.0 2200.0 2300.0 3000.0 3200.0 +1500.0 1800.0 2200.0 2400.0 3000.0 3200.0 +1200.0 1600.0 2300.0 2500.0 3100.0 3200.0 +1300.0 1900.0 2200.0 2700.0 3200.0 3300.0 +1100.0 1300.0 2000.0 2700.0 3100.0 3200.0 +1400.0 1500.0 2400.0 2700.0 2900.0 3300.0 +1500.0 1800.0 2500.0 2700.0 3000.0 3100.0 +1500.0 1700.0 2500.0 2800.0 3000.0 3200.0 +1400.0 1600.0 2200.0 2400.0 2700.0 3200.0 +1300.0 1400.0 2000.0 2400.0 2600.0 3000.0 +1200.0 1300.0 2100.0 2500.0 2700.0 3100.0 +1800.0 2100.0 2400.0 2600.0 2800.0 3100.0 +1800.0 2100.0 2400.0 2600.0 2800.0 3000.0 +1900.0 2200.0 2500.0 2700.0 2900.0 3100.0 +1900.0 2300.0 2500.0 2800.0 3000.0 3100.0 +1900.0 2400.0 2500.0 2700.0 3100.0 3200.0 +1800.0 2400.0 2500.0 2700.0 3100.0 3200.0 +1800.0 2400.0 2600.0 2700.0 3100.0 3200.0 +1800.0 2400.0 2600.0 2800.0 3200.0 3300.0 +1900.0 2400.0 2600.0 2800.0 3100.0 3300.0 +1900.0 2400.0 2600.0 2800.0 3200.0 3300.0 +1700.0 2400.0 2600.0 2800.0 3200.0 3300.0 +1700.0 2200.0 2600.0 2800.0 3200.0 3300.0 +2000.0 2200.0 2800.0 3000.0 3200.0 3300.0 +1700.0 1900.0 2200.0 2700.0 3100.0 3300.0 +1900.0 2100.0 2400.0 2800.0 3000.0 3200.0 +1900.0 2100.0 2300.0 2800.0 3000.0 3200.0 +1800.0 2100.0 2300.0 2700.0 3000.0 3200.0 +1600.0 2000.0 2200.0 2700.0 3000.0 3100.0 +1600.0 2000.0 2200.0 2500.0 3000.0 3100.0 +1700.0 2000.0 2200.0 2700.0 3000.0 3200.0 +1700.0 2000.0 2200.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2200.0 2700.0 3100.0 3200.0 +1500.0 1900.0 2200.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2300.0 2800.0 3000.0 3100.0 +1600.0 1900.0 2200.0 2700.0 3000.0 3100.0 +1600.0 1900.0 2300.0 2700.0 3000.0 3100.0 +1600.0 2000.0 2400.0 2800.0 3100.0 3200.0 +1700.0 2000.0 2200.0 2700.0 3100.0 3200.0 +1800.0 2000.0 2200.0 2700.0 3000.0 3100.0 +1700.0 2000.0 2100.0 2700.0 3100.0 3200.0 +1900.0 2100.0 2700.0 3000.0 3100.0 3300.0 +1800.0 2100.0 2700.0 3000.0 3200.0 3300.0 +1900.0 2100.0 2600.0 2900.0 3100.0 3200.0 +1900.0 2100.0 2500.0 3000.0 3100.0 3200.0 +1700.0 2000.0 2500.0 2900.0 3100.0 3200.0 +1800.0 2100.0 2600.0 2900.0 3200.0 3300.0 +1900.0 2100.0 2600.0 2900.0 3200.0 3300.0 +1700.0 2100.0 2500.0 2900.0 3100.0 3300.0 +1800.0 2100.0 2500.0 2900.0 3100.0 3200.0 +1600.0 2000.0 2300.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2100.0 2600.0 2900.0 3100.0 +1800.0 2000.0 2200.0 2700.0 3000.0 3200.0 +2000.0 2100.0 2300.0 2600.0 3100.0 3200.0 +1800.0 2100.0 2300.0 2700.0 3200.0 3300.0 +1700.0 2100.0 2300.0 2700.0 3000.0 3200.0 +1600.0 2200.0 2400.0 2800.0 3200.0 3300.0 +1600.0 1700.0 2000.0 2300.0 2700.0 3100.0 +1800.0 2000.0 2200.0 2400.0 2700.0 3100.0 +1700.0 1800.0 2100.0 2400.0 2700.0 3000.0 +1500.0 1600.0 2200.0 2500.0 2800.0 3300.0 +1500.0 1600.0 2100.0 2500.0 2700.0 3000.0 +1500.0 2000.0 2300.0 2500.0 2700.0 2900.0 +1700.0 2100.0 2300.0 2600.0 2800.0 3000.0 +1700.0 2200.0 2400.0 2700.0 3000.0 3100.0 +1500.0 2200.0 2400.0 2600.0 3000.0 3200.0 +1500.0 2100.0 2400.0 2600.0 3100.0 3200.0 +1600.0 2100.0 2400.0 2600.0 3000.0 3200.0 +1500.0 2100.0 2300.0 2600.0 3000.0 3100.0 +1600.0 2000.0 2300.0 2700.0 3000.0 3100.0 +1600.0 1900.0 2200.0 2600.0 3100.0 3200.0 +1500.0 1800.0 2000.0 2500.0 3100.0 3200.0 +1600.0 1800.0 2000.0 2500.0 3100.0 3200.0 +1500.0 1700.0 2000.0 2300.0 3000.0 3100.0 +1400.0 1800.0 2100.0 2400.0 2900.0 3100.0 +1600.0 1900.0 2200.0 2500.0 3100.0 3200.0 +1600.0 1900.0 2200.0 2500.0 3000.0 3200.0 +1600.0 1800.0 2200.0 2800.0 3100.0 3200.0 +1500.0 1800.0 2100.0 2600.0 3000.0 3100.0 +1600.0 1800.0 2100.0 2600.0 2900.0 3100.0 +1600.0 1900.0 2100.0 2500.0 2900.0 3100.0 +1600.0 1900.0 2100.0 2600.0 2900.0 3100.0 +1600.0 1900.0 2100.0 2600.0 2800.0 3100.0 +1600.0 1800.0 2200.0 2600.0 2800.0 3000.0 +1600.0 1900.0 2200.0 2700.0 2900.0 3100.0 +1600.0 1900.0 2200.0 2600.0 2900.0 3000.0 +1900.0 2000.0 2200.0 2800.0 3000.0 3100.0 +1400.0 1900.0 2100.0 2500.0 3100.0 3200.0 +1400.0 1900.0 2100.0 2400.0 3100.0 3200.0 +1500.0 1800.0 2100.0 2400.0 3200.0 3300.0 +1500.0 1700.0 2100.0 2300.0 3100.0 3300.0 +1400.0 1700.0 2100.0 2300.0 3200.0 3300.0 +1400.0 1600.0 2100.0 2300.0 3200.0 3300.0 +1300.0 1600.0 2100.0 2300.0 3200.0 3300.0 +1300.0 1600.0 2100.0 2300.0 3100.0 3300.0 +1200.0 1400.0 2000.0 2200.0 3100.0 3300.0 +1200.0 1400.0 2000.0 2600.0 3100.0 3200.0 +1200.0 1400.0 2000.0 2800.0 3100.0 3200.0 +1200.0 1400.0 2100.0 2800.0 3100.0 3200.0 +1400.0 1500.0 2200.0 2700.0 3000.0 3100.0 +1700.0 1900.0 2200.0 2500.0 2900.0 3200.0 +1400.0 1600.0 2200.0 2700.0 2900.0 3100.0 +1500.0 1600.0 1900.0 2700.0 2900.0 3000.0 +1500.0 1600.0 1900.0 2700.0 3000.0 3100.0 +1500.0 1600.0 2000.0 2700.0 3000.0 3100.0 +1400.0 1600.0 2000.0 2600.0 2900.0 3100.0 +1300.0 1500.0 2400.0 2700.0 2900.0 3200.0 +1600.0 1800.0 2300.0 2700.0 3100.0 3400.0 +1600.0 2100.0 2400.0 2800.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2700.0 3000.0 3100.0 +1600.0 1900.0 2100.0 2700.0 3000.0 3100.0 +1600.0 1800.0 2100.0 2700.0 3000.0 3100.0 +1700.0 1800.0 2300.0 2800.0 3100.0 3200.0 +1800.0 1900.0 2400.0 2900.0 3100.0 3200.0 +1500.0 1700.0 1800.0 2600.0 3000.0 3100.0 +1700.0 1800.0 2200.0 2800.0 3000.0 3200.0 +1800.0 2100.0 2600.0 2900.0 3100.0 3300.0 +1700.0 2300.0 2500.0 2700.0 3100.0 3200.0 +2000.0 2400.0 2500.0 2700.0 3100.0 3200.0 +1900.0 2500.0 2600.0 2800.0 3100.0 3200.0 +1800.0 2400.0 2700.0 2900.0 3200.0 3300.0 +1900.0 2400.0 2600.0 2800.0 3100.0 3200.0 +1700.0 2200.0 2500.0 2700.0 3100.0 3200.0 +1800.0 2200.0 2300.0 2600.0 3100.0 3200.0 +1800.0 2200.0 2300.0 2700.0 3100.0 3200.0 +1800.0 2200.0 2400.0 2800.0 3100.0 3300.0 +1900.0 2100.0 2500.0 2900.0 3300.0 3400.0 +1900.0 2100.0 2400.0 2900.0 3100.0 3200.0 +1900.0 2200.0 2400.0 2800.0 3000.0 3100.0 +1800.0 2200.0 2500.0 2700.0 3100.0 3200.0 +1800.0 2300.0 2500.0 2800.0 3100.0 3200.0 +1800.0 2300.0 2400.0 2800.0 3100.0 3200.0 +1800.0 2100.0 2300.0 2700.0 2900.0 3100.0 +1700.0 2000.0 2500.0 2800.0 3000.0 3300.0 +1100.0 1300.0 2300.0 2600.0 2800.0 3200.0 +1400.0 1600.0 2200.0 2500.0 2800.0 3100.0 +1400.0 1600.0 2000.0 2500.0 2700.0 3000.0 +1400.0 1500.0 1900.0 2500.0 2800.0 2900.0 +1400.0 1500.0 1900.0 2600.0 2900.0 3000.0 +1400.0 1600.0 1900.0 2700.0 2900.0 3000.0 +1500.0 1600.0 2000.0 2700.0 2900.0 3100.0 +1500.0 1600.0 2000.0 2700.0 2900.0 3000.0 +1500.0 1600.0 2100.0 2800.0 3000.0 3100.0 +1600.0 1700.0 2100.0 2800.0 3000.0 3100.0 +1900.0 2200.0 2600.0 2900.0 3300.0 3400.0 +2000.0 2200.0 2600.0 3000.0 3300.0 3400.0 +2000.0 2200.0 2600.0 3000.0 3200.0 3300.0 +1800.0 2100.0 2700.0 3000.0 3400.0 3500.0 +1300.0 1600.0 2300.0 2500.0 3000.0 3300.0 +1400.0 1700.0 2400.0 2500.0 2800.0 2900.0 +1400.0 1700.0 2400.0 2500.0 2800.0 3000.0 +1500.0 2000.0 2400.0 2500.0 3100.0 3200.0 +1400.0 1800.0 2400.0 2500.0 3100.0 3200.0 +1400.0 1500.0 2400.0 2500.0 3100.0 3300.0 +1900.0 2200.0 2600.0 2900.0 3200.0 3400.0 +1600.0 2000.0 2600.0 2700.0 3300.0 3400.0 +1800.0 2200.0 2800.0 3100.0 3400.0 3500.0 +1900.0 2200.0 2700.0 3000.0 3400.0 3500.0 +1900.0 2400.0 2800.0 3000.0 3200.0 3400.0 +1300.0 1900.0 2100.0 2400.0 2800.0 3000.0 +1800.0 2100.0 2300.0 2500.0 2800.0 3100.0 +1800.0 2100.0 2400.0 2600.0 2900.0 3100.0 +1600.0 1800.0 2500.0 2600.0 2900.0 3000.0 +1700.0 1900.0 2200.0 2400.0 2900.0 3200.0 +1600.0 1800.0 2000.0 2300.0 3000.0 3200.0 +1600.0 1700.0 1900.0 2300.0 3100.0 3300.0 +1400.0 1600.0 1800.0 2200.0 3200.0 3300.0 +1400.0 1600.0 1800.0 2300.0 3100.0 3200.0 +1400.0 1600.0 1800.0 2300.0 3000.0 3200.0 +1100.0 2200.0 2500.0 2600.0 2700.0 2900.0 +1200.0 1900.0 2500.0 2600.0 2800.0 3000.0 +1200.0 1800.0 2500.0 2600.0 2800.0 2900.0 +1300.0 1900.0 2500.0 2600.0 2800.0 3100.0 +1500.0 2100.0 2400.0 2500.0 2900.0 3200.0 +1400.0 2100.0 2400.0 2500.0 3000.0 3200.0 +1400.0 2000.0 2400.0 2500.0 3000.0 3300.0 +1300.0 1700.0 2300.0 2400.0 3200.0 3400.0 +1700.0 1900.0 2400.0 2500.0 3000.0 3300.0 +1900.0 2000.0 2500.0 2600.0 2900.0 3200.0 +1900.0 2100.0 2500.0 2700.0 2900.0 3200.0 +2000.0 2100.0 2600.0 2700.0 3000.0 3200.0 +2000.0 2100.0 2600.0 2700.0 3000.0 3300.0 +1900.0 2100.0 2500.0 2600.0 2900.0 3200.0 +1800.0 1900.0 2500.0 2700.0 3100.0 3400.0 +1600.0 2100.0 2400.0 2600.0 3100.0 3300.0 +1700.0 1800.0 2500.0 2600.0 2900.0 3300.0 +1500.0 1900.0 2400.0 2500.0 2800.0 3200.0 +1500.0 2000.0 2400.0 2500.0 2700.0 3000.0 +2100.0 2400.0 2700.0 3000.0 3300.0 3400.0 +1900.0 2200.0 2600.0 2800.0 3100.0 3400.0 +1800.0 2100.0 2600.0 2700.0 3100.0 3400.0 +1800.0 2000.0 2300.0 2500.0 2800.0 3200.0 +1700.0 2100.0 2200.0 2600.0 2900.0 3100.0 +1400.0 2100.0 2200.0 2600.0 2900.0 3100.0 +1500.0 1700.0 2100.0 2400.0 2800.0 3000.0 +1500.0 2000.0 2400.0 2600.0 3000.0 3200.0 +1500.0 1800.0 2400.0 2500.0 3000.0 3200.0 +1500.0 1700.0 2400.0 2500.0 3000.0 3300.0 +1700.0 2100.0 2500.0 2600.0 3200.0 3400.0 +1800.0 2300.0 2500.0 2800.0 3200.0 3300.0 +1800.0 2300.0 2600.0 2900.0 3200.0 3300.0 +1900.0 2300.0 2600.0 3000.0 3300.0 3400.0 +1800.0 1900.0 2300.0 2400.0 2700.0 3100.0 +1600.0 1800.0 2200.0 2500.0 2900.0 3200.0 +1700.0 1900.0 2400.0 2700.0 3100.0 3400.0 +1800.0 2200.0 2400.0 2800.0 3200.0 3400.0 +1900.0 2200.0 2800.0 3000.0 3300.0 3400.0 +2300.0 2600.0 2700.0 2900.0 3200.0 3300.0 +1700.0 2100.0 2500.0 2600.0 3100.0 3300.0 +1700.0 1900.0 2400.0 2500.0 2900.0 3100.0 +1900.0 2100.0 2400.0 2500.0 2900.0 3200.0 +2000.0 2100.0 2400.0 2500.0 2900.0 3200.0 +2000.0 2100.0 2500.0 2600.0 3000.0 3200.0 +2000.0 2200.0 2500.0 2600.0 3000.0 3300.0 +2000.0 2200.0 2600.0 2700.0 2900.0 3100.0 +1700.0 2000.0 2600.0 2700.0 3000.0 3100.0 +1900.0 2200.0 2700.0 2800.0 3100.0 3200.0 +1900.0 2400.0 2700.0 2800.0 3200.0 3300.0 +2100.0 2400.0 2600.0 2800.0 3100.0 3300.0 +2200.0 2500.0 2700.0 2900.0 3200.0 3300.0 +2000.0 2400.0 2800.0 3000.0 3300.0 3400.0 +1300.0 2000.0 2300.0 2400.0 3200.0 3300.0 +1400.0 1800.0 2200.0 2500.0 3000.0 3200.0 +1300.0 1600.0 2100.0 2500.0 2900.0 3200.0 +1300.0 1500.0 2100.0 2400.0 2900.0 3200.0 +1500.0 1700.0 1800.0 2200.0 2600.0 3200.0 +1500.0 1900.0 2200.0 2400.0 2800.0 3100.0 +1300.0 1600.0 2200.0 2300.0 3200.0 3400.0 +1300.0 1700.0 2200.0 2400.0 3100.0 3300.0 +1500.0 2100.0 2300.0 2700.0 3200.0 3400.0 +2000.0 2300.0 2800.0 3000.0 3300.0 3400.0 +1800.0 2300.0 2800.0 3000.0 3400.0 3500.0 +1800.0 2300.0 2700.0 3000.0 3300.0 3500.0 +2000.0 2500.0 2800.0 3100.0 3400.0 3500.0 +2000.0 2500.0 2800.0 3100.0 3300.0 3400.0 +2000.0 2400.0 2800.0 3100.0 3300.0 3400.0 +2100.0 2500.0 2800.0 2900.0 3300.0 3400.0 +2000.0 2300.0 2800.0 2900.0 3200.0 3300.0 +2000.0 2300.0 2700.0 2800.0 3100.0 3200.0 +1900.0 2200.0 2500.0 2700.0 3100.0 3200.0 +1600.0 2200.0 2400.0 2600.0 2900.0 3100.0 +1500.0 2200.0 2400.0 2600.0 2900.0 3200.0 +1400.0 1900.0 2200.0 2400.0 2700.0 3000.0 +1400.0 1900.0 2300.0 2500.0 2800.0 3100.0 +1600.0 1900.0 2400.0 2500.0 2800.0 3000.0 +1600.0 1800.0 2400.0 2600.0 2900.0 3000.0 +1600.0 1900.0 2500.0 2600.0 2900.0 3100.0 +1600.0 1900.0 2400.0 2500.0 3000.0 3100.0 +1600.0 2000.0 2400.0 2600.0 3000.0 3200.0 +1400.0 2100.0 2300.0 2600.0 3100.0 3200.0 +1400.0 1900.0 2200.0 2500.0 3000.0 3100.0 +1400.0 1800.0 2000.0 2400.0 3000.0 3100.0 +1400.0 1700.0 1900.0 2400.0 2800.0 2900.0 +1700.0 2100.0 2400.0 2600.0 3000.0 3300.0 +1900.0 2100.0 2500.0 2600.0 3000.0 3300.0 +1900.0 2100.0 2400.0 2500.0 2800.0 3200.0 +1800.0 2000.0 2300.0 2400.0 2900.0 3300.0 +1600.0 1800.0 2000.0 2300.0 2700.0 3200.0 +1300.0 1500.0 2100.0 2500.0 3000.0 3200.0 +1400.0 2000.0 2200.0 2400.0 2900.0 3200.0 +1800.0 1900.0 2300.0 2600.0 3000.0 3300.0 +1900.0 2000.0 2300.0 2500.0 3000.0 3100.0 +1900.0 2000.0 2300.0 2400.0 2800.0 3100.0 +1700.0 2000.0 2400.0 2500.0 2800.0 3000.0 +1600.0 2100.0 2500.0 2700.0 3100.0 3200.0 +1900.0 2200.0 2400.0 2700.0 3000.0 3200.0 +1900.0 2100.0 2300.0 2500.0 2800.0 3000.0 +1700.0 2000.0 2300.0 2500.0 2900.0 3100.0 +1700.0 2100.0 2300.0 2500.0 2900.0 3100.0 +1500.0 1700.0 1900.0 2500.0 2800.0 3100.0 +1600.0 1800.0 2000.0 2500.0 2700.0 3000.0 +1700.0 1800.0 2100.0 2500.0 2700.0 2900.0 +2000.0 2300.0 2700.0 2900.0 3100.0 3200.0 +2000.0 2300.0 2600.0 2900.0 3100.0 3200.0 +1600.0 2000.0 2500.0 2600.0 3100.0 3200.0 +1600.0 2100.0 2400.0 2500.0 2800.0 3000.0 +1400.0 2000.0 2400.0 2500.0 2900.0 3100.0 +1500.0 2000.0 2400.0 2500.0 3100.0 3300.0 +1700.0 2100.0 2500.0 2800.0 3300.0 3500.0 +1500.0 1600.0 2300.0 2500.0 2800.0 3100.0 +1500.0 1800.0 2300.0 2500.0 2700.0 2900.0 +1400.0 2000.0 2300.0 2400.0 2700.0 3100.0 +1400.0 2100.0 2400.0 2500.0 2800.0 3200.0 +1400.0 2100.0 2400.0 2500.0 2900.0 3200.0 +1800.0 2000.0 2300.0 2400.0 3000.0 3300.0 +1900.0 2200.0 2500.0 2600.0 2900.0 3100.0 +1800.0 2200.0 2600.0 2900.0 3100.0 3200.0 +2100.0 2500.0 2700.0 2800.0 3200.0 3300.0 +1900.0 2400.0 2600.0 2700.0 3200.0 3300.0 +1900.0 2100.0 2600.0 2700.0 3100.0 3200.0 +1800.0 2000.0 2500.0 2600.0 2900.0 3100.0 +1800.0 2100.0 2500.0 2600.0 2900.0 3100.0 +1900.0 2100.0 2500.0 2600.0 2900.0 3100.0 +1900.0 2100.0 2400.0 2500.0 2900.0 3100.0 +1900.0 2200.0 2300.0 2500.0 2900.0 3200.0 +1800.0 2200.0 2400.0 2600.0 3000.0 3100.0 +1800.0 2200.0 2400.0 2700.0 3000.0 3100.0 +1700.0 2000.0 2300.0 2800.0 3200.0 3400.0 +1600.0 2100.0 2300.0 2700.0 3200.0 3400.0 +1800.0 2200.0 2600.0 2700.0 3000.0 3200.0 +1900.0 2200.0 2600.0 3000.0 3200.0 3400.0 +2000.0 2400.0 2900.0 3000.0 3300.0 3500.0 +2100.0 2500.0 2800.0 2900.0 3400.0 3500.0 +2100.0 2600.0 2800.0 3000.0 3300.0 3400.0 +2300.0 2600.0 2800.0 3000.0 3200.0 3300.0 +2200.0 2500.0 2600.0 2800.0 3200.0 3300.0 +2200.0 2400.0 2600.0 2700.0 3200.0 3300.0 +2100.0 2300.0 2500.0 2700.0 3100.0 3300.0 +2100.0 2300.0 2500.0 2800.0 3000.0 3200.0 +1900.0 2100.0 2200.0 2500.0 3000.0 3200.0 +1700.0 2000.0 2400.0 2600.0 3000.0 3200.0 +1900.0 2200.0 2700.0 3000.0 3200.0 3300.0 +2000.0 2300.0 2900.0 3000.0 3300.0 3400.0 +2100.0 2400.0 2800.0 3000.0 3300.0 3400.0 +2000.0 2500.0 2800.0 2900.0 3300.0 3400.0 +2100.0 2600.0 2800.0 2900.0 3300.0 3400.0 +1800.0 2100.0 2700.0 2900.0 3200.0 3300.0 +1800.0 2200.0 2600.0 2800.0 3100.0 3300.0 +1700.0 2000.0 2400.0 2500.0 2700.0 2900.0 +1500.0 1800.0 2400.0 2600.0 2900.0 3200.0 +1500.0 2000.0 2400.0 2500.0 2800.0 3000.0 +1500.0 1900.0 2400.0 2500.0 2700.0 3000.0 +1500.0 2000.0 2400.0 2600.0 2800.0 3100.0 +1500.0 1800.0 2500.0 2600.0 3000.0 3300.0 +1500.0 2100.0 2400.0 2500.0 3000.0 3300.0 +1600.0 2100.0 2400.0 2600.0 3000.0 3300.0 +1600.0 2000.0 2400.0 2600.0 2800.0 3100.0 +1900.0 2300.0 2700.0 2900.0 3300.0 3400.0 +1800.0 2300.0 2700.0 3100.0 3300.0 3400.0 +2000.0 2100.0 2300.0 2700.0 3000.0 3300.0 +2100.0 2300.0 2600.0 2700.0 3100.0 3300.0 +2100.0 2300.0 2500.0 2700.0 3200.0 3300.0 +2100.0 2300.0 2600.0 2800.0 3200.0 3300.0 +1600.0 2100.0 2400.0 2600.0 3100.0 3200.0 +1500.0 2100.0 2500.0 2600.0 3000.0 3100.0 +1600.0 2100.0 2300.0 2600.0 3100.0 3300.0 +1800.0 2100.0 2500.0 2600.0 3000.0 3300.0 +1600.0 1800.0 2500.0 2700.0 3100.0 3200.0 +1500.0 1800.0 2500.0 2700.0 3100.0 3200.0 +1500.0 1800.0 2400.0 2600.0 2900.0 3100.0 +1700.0 2100.0 2500.0 2800.0 3000.0 3200.0 +1600.0 1800.0 2300.0 2700.0 3000.0 3300.0 +1600.0 1800.0 2200.0 2700.0 3100.0 3300.0 +1600.0 1700.0 2100.0 2700.0 3100.0 3200.0 +1600.0 1700.0 2300.0 2600.0 3100.0 3300.0 +1400.0 1600.0 2200.0 2500.0 3100.0 3300.0 +1400.0 1600.0 2100.0 2300.0 3100.0 3300.0 +1400.0 1600.0 2100.0 2300.0 3200.0 3400.0 +1300.0 1600.0 2100.0 2200.0 3200.0 3300.0 +1300.0 1700.0 2200.0 2400.0 3200.0 3400.0 +1300.0 1600.0 2200.0 2300.0 3100.0 3400.0 +1400.0 1600.0 2200.0 2300.0 2900.0 3300.0 +1400.0 1600.0 2200.0 2400.0 2900.0 3300.0 +1300.0 1500.0 2200.0 2400.0 3000.0 3300.0 +1300.0 1500.0 2200.0 2400.0 3100.0 3300.0 +1200.0 1500.0 2200.0 2400.0 3100.0 3300.0 +1200.0 1700.0 2300.0 2500.0 3200.0 3300.0 +1800.0 2000.0 2300.0 2400.0 3200.0 3400.0 +2000.0 2100.0 2400.0 2500.0 3000.0 3400.0 +2000.0 2200.0 2500.0 2700.0 3200.0 3400.0 +2000.0 2500.0 2700.0 2900.0 3400.0 3500.0 +1700.0 2000.0 2500.0 2600.0 3000.0 3300.0 +1600.0 1700.0 2100.0 2400.0 2800.0 3200.0 +1400.0 1600.0 2200.0 2300.0 3000.0 3400.0 +1300.0 1500.0 2200.0 2300.0 2800.0 3200.0 +1500.0 1700.0 2400.0 2500.0 3000.0 3200.0 +1600.0 1700.0 2400.0 2500.0 3000.0 3300.0 +1700.0 1800.0 2400.0 2500.0 2900.0 3200.0 +1800.0 1900.0 2400.0 2500.0 2900.0 3100.0 +1700.0 1900.0 2400.0 2500.0 2900.0 3200.0 +1500.0 1700.0 2300.0 2400.0 3100.0 3400.0 +1400.0 1600.0 2200.0 2400.0 2800.0 3100.0 +1400.0 1600.0 2200.0 2400.0 2800.0 3200.0 +1400.0 1600.0 2100.0 2300.0 2800.0 3200.0 +1500.0 1600.0 2100.0 2400.0 2700.0 3100.0 +1600.0 1700.0 2200.0 2400.0 2800.0 3100.0 +1600.0 2200.0 2500.0 2700.0 3300.0 3400.0 +1500.0 2000.0 2500.0 2900.0 3300.0 3400.0 +1400.0 2000.0 2400.0 2800.0 3200.0 3400.0 +1400.0 1700.0 2300.0 2600.0 3000.0 3200.0 +1300.0 1600.0 2300.0 2400.0 3100.0 3200.0 +1300.0 1600.0 2300.0 2400.0 3000.0 3200.0 +1200.0 1500.0 2200.0 2300.0 3000.0 3300.0 +1300.0 1700.0 2300.0 2400.0 3100.0 3300.0 +1300.0 1600.0 2300.0 2400.0 3000.0 3300.0 +1300.0 1700.0 2300.0 2400.0 3000.0 3300.0 +1300.0 1600.0 2200.0 2300.0 3000.0 3300.0 +1300.0 1600.0 2200.0 2300.0 3100.0 3300.0 +1300.0 1400.0 2200.0 2300.0 3000.0 3300.0 +1300.0 1600.0 2200.0 2400.0 3100.0 3300.0 +1400.0 1800.0 2200.0 2300.0 3200.0 3300.0 +1400.0 1600.0 2300.0 2400.0 3200.0 3400.0 +1400.0 1600.0 2300.0 2400.0 3100.0 3400.0 +1400.0 1600.0 2300.0 2400.0 3000.0 3400.0 +1400.0 1500.0 2400.0 2500.0 3000.0 3300.0 +1400.0 1900.0 2300.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2300.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2300.0 3200.0 3400.0 +1400.0 1600.0 2100.0 2400.0 3100.0 3400.0 +1600.0 1900.0 2200.0 2500.0 2800.0 3100.0 +1500.0 1800.0 2200.0 2300.0 3000.0 3200.0 +1600.0 1700.0 2200.0 2400.0 3000.0 3200.0 +1700.0 1800.0 2300.0 2400.0 2900.0 3200.0 +1800.0 1900.0 2400.0 2500.0 2800.0 3100.0 +2000.0 2100.0 2500.0 2600.0 3100.0 3300.0 +2000.0 2100.0 2400.0 2500.0 3000.0 3300.0 +1800.0 2100.0 2400.0 2600.0 3200.0 3400.0 +1600.0 1900.0 2300.0 2500.0 3000.0 3300.0 +1400.0 1700.0 2200.0 2300.0 3000.0 3300.0 +1400.0 1700.0 2100.0 2200.0 3200.0 3300.0 +1700.0 1800.0 2200.0 2300.0 3100.0 3200.0 +1900.0 2200.0 2400.0 2500.0 2900.0 3100.0 +1400.0 1600.0 2200.0 2600.0 3100.0 3300.0 +1400.0 1700.0 2300.0 2700.0 3100.0 3300.0 +1500.0 1900.0 2300.0 2600.0 3200.0 3400.0 +1200.0 1600.0 2400.0 2500.0 3100.0 3200.0 +1200.0 2000.0 2400.0 2600.0 3300.0 3400.0 +1700.0 1800.0 2100.0 2300.0 2900.0 3000.0 +1800.0 1900.0 2200.0 2300.0 2900.0 3000.0 +1900.0 2000.0 2500.0 2600.0 3100.0 3200.0 +1700.0 1900.0 2300.0 2600.0 3200.0 3300.0 +1800.0 2100.0 2500.0 2600.0 3300.0 3400.0 +1700.0 2300.0 2500.0 2900.0 3200.0 3300.0 +1900.0 2400.0 2800.0 3000.0 3300.0 3400.0 +1600.0 1800.0 2400.0 2500.0 3000.0 3400.0 +1700.0 1800.0 2400.0 2500.0 3100.0 3400.0 +1600.0 2000.0 2200.0 2600.0 3200.0 3300.0 +1500.0 2100.0 2500.0 2800.0 3200.0 3300.0 +1500.0 2000.0 2500.0 2800.0 3300.0 3400.0 +1800.0 2000.0 2500.0 2900.0 3300.0 3400.0 +1500.0 2100.0 2400.0 2800.0 3300.0 3400.0 +1300.0 2000.0 2400.0 2500.0 3300.0 3400.0 +1600.0 1700.0 2200.0 2400.0 3200.0 3300.0 +1600.0 1700.0 2200.0 2300.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2400.0 3200.0 3300.0 +1600.0 1700.0 2200.0 2400.0 2900.0 3300.0 +1500.0 1700.0 2300.0 2400.0 2900.0 3100.0 +1400.0 1800.0 2500.0 2600.0 3000.0 3200.0 +1300.0 1600.0 2400.0 2500.0 3100.0 3300.0 +1300.0 1500.0 2400.0 2500.0 3000.0 3400.0 +1300.0 1500.0 2500.0 2600.0 3000.0 3300.0 +1300.0 1500.0 2400.0 2500.0 2800.0 3300.0 +1400.0 1500.0 2500.0 2600.0 2900.0 3300.0 +1800.0 2200.0 2700.0 2900.0 3200.0 3300.0 +1600.0 1700.0 2400.0 2500.0 2900.0 3300.0 +1600.0 1700.0 2300.0 2500.0 2800.0 3300.0 +1700.0 1800.0 2200.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2200.0 2300.0 3100.0 3200.0 +1600.0 1800.0 2200.0 2400.0 3100.0 3200.0 +1500.0 1800.0 2100.0 2300.0 3100.0 3200.0 +1400.0 1800.0 2200.0 2400.0 2900.0 3200.0 +1500.0 2000.0 2200.0 2400.0 2700.0 3200.0 +1600.0 1900.0 2200.0 2400.0 2800.0 3200.0 +1700.0 1800.0 2400.0 2500.0 3300.0 3500.0 +1500.0 1800.0 2300.0 2600.0 3200.0 3400.0 +1300.0 1600.0 2200.0 2400.0 3200.0 3400.0 +1200.0 1600.0 2200.0 2400.0 3100.0 3300.0 +1100.0 1500.0 2100.0 2300.0 3100.0 3200.0 +1400.0 1700.0 2100.0 2400.0 3100.0 3200.0 +1500.0 1600.0 2100.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2100.0 2300.0 2900.0 3000.0 +1600.0 1700.0 2100.0 2400.0 2900.0 3100.0 +1600.0 1700.0 2100.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2100.0 2300.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2300.0 3200.0 3300.0 +1700.0 1900.0 2100.0 2300.0 3200.0 3400.0 +1800.0 1900.0 2100.0 2300.0 3200.0 3400.0 +1700.0 1900.0 2200.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2200.0 2300.0 3000.0 3200.0 +1600.0 1700.0 2200.0 2300.0 2700.0 3100.0 +1600.0 1700.0 2100.0 2300.0 2500.0 3000.0 +1500.0 1800.0 2300.0 2500.0 2900.0 3100.0 +1500.0 2000.0 2300.0 2600.0 3100.0 3200.0 +1500.0 2000.0 2500.0 2900.0 3200.0 3300.0 +1700.0 2400.0 2900.0 3100.0 3300.0 3400.0 +1700.0 2100.0 2400.0 2800.0 3300.0 3400.0 +1800.0 2400.0 2600.0 2800.0 3100.0 3300.0 +1200.0 1600.0 2400.0 2500.0 3100.0 3400.0 +1300.0 1500.0 2400.0 2500.0 3100.0 3400.0 +1400.0 1500.0 2400.0 2500.0 3000.0 3200.0 +1400.0 1600.0 2400.0 2500.0 3000.0 3200.0 +1800.0 2100.0 2500.0 2600.0 3000.0 3200.0 +1700.0 2200.0 2500.0 2800.0 3100.0 3300.0 +1600.0 1700.0 2300.0 2500.0 3100.0 3300.0 +1600.0 1700.0 2300.0 2500.0 3000.0 3200.0 +1400.0 2000.0 2400.0 2500.0 3200.0 3400.0 +1800.0 2100.0 2400.0 2500.0 3200.0 3400.0 +1800.0 1900.0 2200.0 2400.0 3100.0 3300.0 +1700.0 2000.0 2400.0 2600.0 3200.0 3400.0 +1600.0 1700.0 2300.0 2400.0 3100.0 3400.0 +1600.0 1700.0 2300.0 2400.0 3200.0 3400.0 +1200.0 1700.0 2400.0 2500.0 3200.0 3400.0 +1700.0 2200.0 2800.0 3100.0 3400.0 3500.0 +1600.0 2000.0 2400.0 2800.0 3300.0 3400.0 +1300.0 1600.0 2100.0 2300.0 3100.0 3200.0 +1300.0 1600.0 2100.0 2200.0 3100.0 3200.0 +1300.0 1500.0 1800.0 2000.0 3000.0 3100.0 +1300.0 1500.0 1800.0 1900.0 3100.0 3200.0 +1400.0 1500.0 1700.0 1800.0 3100.0 3200.0 +1400.0 1600.0 1700.0 2000.0 2800.0 2900.0 +1500.0 1700.0 2200.0 2400.0 2800.0 3200.0 +1500.0 1700.0 2200.0 2300.0 3100.0 3200.0 +1500.0 1700.0 2000.0 2200.0 3100.0 3200.0 +1300.0 1500.0 1800.0 2200.0 3100.0 3200.0 +1400.0 1800.0 2300.0 2500.0 2900.0 3200.0 +1400.0 1800.0 2300.0 2400.0 2700.0 3200.0 +1500.0 1600.0 2000.0 2500.0 2900.0 3200.0 +1500.0 1600.0 2000.0 2400.0 3100.0 3300.0 +1500.0 1700.0 2200.0 2500.0 2800.0 3200.0 +1700.0 1800.0 2200.0 2500.0 2800.0 3100.0 +1600.0 1700.0 2200.0 2500.0 2800.0 3100.0 +1700.0 1800.0 2200.0 2500.0 2900.0 3100.0 +1900.0 2000.0 2400.0 2600.0 3000.0 3200.0 +1500.0 1700.0 2200.0 2500.0 3000.0 3300.0 +1300.0 1500.0 2200.0 2400.0 3000.0 3400.0 +1200.0 1400.0 2200.0 2500.0 3200.0 3400.0 +1300.0 1600.0 2000.0 2200.0 3100.0 3200.0 +1400.0 1600.0 1900.0 2000.0 3000.0 3100.0 +1700.0 1800.0 2200.0 2400.0 2900.0 3100.0 +1500.0 1600.0 2200.0 2300.0 2800.0 3100.0 +1400.0 1600.0 2200.0 2300.0 2800.0 3100.0 +1300.0 1600.0 2300.0 2400.0 2900.0 3300.0 +1700.0 2200.0 2800.0 3100.0 3300.0 3400.0 +1700.0 2200.0 2600.0 3000.0 3300.0 3500.0 +1100.0 1500.0 2400.0 2500.0 3200.0 3300.0 +1500.0 2000.0 2300.0 2500.0 2700.0 3100.0 +1900.0 2100.0 2500.0 2600.0 3100.0 3300.0 +1900.0 2000.0 2300.0 2400.0 3000.0 3300.0 +1500.0 2100.0 2500.0 2800.0 3300.0 3400.0 +1600.0 2100.0 2500.0 2900.0 3300.0 3400.0 +1200.0 1600.0 2400.0 2500.0 2900.0 3400.0 +1300.0 1500.0 2300.0 2500.0 2700.0 3200.0 +1400.0 1600.0 2500.0 2600.0 3000.0 3300.0 +1300.0 1600.0 2400.0 2500.0 3100.0 3400.0 +1300.0 1800.0 2300.0 2500.0 3100.0 3300.0 +1300.0 1600.0 2300.0 2400.0 3100.0 3300.0 +1200.0 1600.0 2300.0 2400.0 3000.0 3300.0 +1100.0 1700.0 2200.0 2500.0 3100.0 3300.0 +1500.0 1600.0 2200.0 2600.0 3000.0 3300.0 +1500.0 1600.0 2200.0 2600.0 2900.0 3300.0 +1500.0 1700.0 2400.0 2600.0 2900.0 3300.0 +1500.0 1600.0 2300.0 2500.0 2900.0 3200.0 +1700.0 2100.0 2600.0 3000.0 3300.0 3400.0 +1600.0 1800.0 2400.0 2500.0 3100.0 3500.0 +1500.0 1600.0 2400.0 2500.0 3100.0 3400.0 +1500.0 1600.0 2500.0 2600.0 3100.0 3300.0 +1200.0 1500.0 1600.0 2000.0 3200.0 3400.0 +1900.0 2000.0 2300.0 2500.0 2900.0 3200.0 +2000.0 2500.0 2700.0 2800.0 3200.0 3300.0 +2000.0 2200.0 2500.0 2800.0 3100.0 3200.0 +1700.0 1800.0 2300.0 2700.0 2900.0 3100.0 +1700.0 1800.0 2400.0 2800.0 2900.0 3100.0 +1700.0 1800.0 2400.0 2800.0 3000.0 3100.0 +1700.0 1800.0 2300.0 2800.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2800.0 3100.0 3200.0 +1400.0 1900.0 2200.0 2400.0 3000.0 3200.0 +2100.0 2300.0 2800.0 3000.0 3200.0 3300.0 +2100.0 2400.0 2900.0 3000.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2600.0 3000.0 3100.0 +1700.0 1800.0 2300.0 2600.0 2900.0 3100.0 +1600.0 1700.0 2100.0 2600.0 2900.0 3100.0 +1700.0 1800.0 2100.0 2700.0 2900.0 3100.0 +1800.0 1900.0 2200.0 2700.0 3000.0 3100.0 +1900.0 2100.0 2300.0 2800.0 3100.0 3200.0 +2000.0 2400.0 2600.0 2900.0 3200.0 3300.0 +1300.0 1700.0 2400.0 2700.0 3100.0 3200.0 +1200.0 1500.0 2300.0 2400.0 3000.0 3200.0 +1100.0 1500.0 2300.0 2500.0 3100.0 3200.0 +2000.0 2300.0 2800.0 3000.0 3200.0 3300.0 +2100.0 2400.0 2900.0 3000.0 3300.0 3400.0 +2200.0 2500.0 2900.0 3100.0 3300.0 3400.0 +2300.0 2500.0 2900.0 3100.0 3300.0 3400.0 +2200.0 2500.0 2900.0 3100.0 3200.0 3300.0 +1900.0 2000.0 2400.0 2600.0 3200.0 3400.0 +1500.0 1800.0 2000.0 2300.0 3200.0 3400.0 +1700.0 1800.0 2000.0 2100.0 3200.0 3400.0 +1800.0 1900.0 2200.0 2300.0 3200.0 3400.0 +1900.0 2000.0 2500.0 2800.0 3000.0 3200.0 +1800.0 1900.0 2400.0 2800.0 3000.0 3200.0 +1800.0 1900.0 2500.0 2800.0 3200.0 3400.0 +1800.0 2300.0 2600.0 2800.0 3200.0 3400.0 +1500.0 1900.0 2600.0 2800.0 3100.0 3300.0 +1400.0 1500.0 2400.0 2700.0 2800.0 3100.0 +1400.0 1500.0 2300.0 2700.0 2800.0 3100.0 +1400.0 1500.0 2400.0 2800.0 2900.0 3100.0 +1300.0 1500.0 2300.0 2900.0 3100.0 3200.0 +1300.0 1500.0 2200.0 2900.0 3100.0 3300.0 +1500.0 1600.0 2000.0 2700.0 3200.0 3300.0 +1500.0 1600.0 2000.0 2400.0 3100.0 3200.0 +1700.0 1800.0 2200.0 2400.0 3000.0 3100.0 +1700.0 1800.0 2200.0 2400.0 2900.0 3200.0 +1700.0 1900.0 2100.0 2400.0 2900.0 3200.0 +2000.0 2400.0 2700.0 2900.0 3100.0 3200.0 +1900.0 2000.0 2400.0 2800.0 3100.0 3200.0 +1700.0 1900.0 2500.0 2800.0 3000.0 3200.0 +1100.0 1400.0 2500.0 2900.0 3100.0 3200.0 +2200.0 2500.0 2900.0 3000.0 3200.0 3400.0 +2100.0 2500.0 2900.0 3000.0 3200.0 3400.0 +1900.0 2100.0 2500.0 2900.0 3000.0 3200.0 +1900.0 2000.0 2400.0 2800.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2800.0 3000.0 3100.0 +1700.0 1900.0 2200.0 2800.0 3000.0 3100.0 +1600.0 1900.0 2000.0 2500.0 2800.0 3000.0 +1300.0 1900.0 2100.0 2500.0 2900.0 3100.0 +1500.0 1900.0 2100.0 2600.0 2900.0 3100.0 +1100.0 1400.0 2500.0 2700.0 3000.0 3300.0 +1300.0 1600.0 2500.0 2700.0 2900.0 3300.0 +1500.0 1700.0 2500.0 2700.0 2900.0 3200.0 +1700.0 1900.0 2600.0 2700.0 3000.0 3200.0 +1800.0 1900.0 2500.0 2800.0 3000.0 3200.0 +1800.0 1900.0 2500.0 2800.0 2900.0 3200.0 +1900.0 2000.0 2400.0 2800.0 2900.0 3200.0 +1900.0 2000.0 2400.0 2800.0 3000.0 3100.0 +1900.0 2100.0 2500.0 2900.0 3100.0 3200.0 +1800.0 2100.0 2500.0 2800.0 3000.0 3200.0 +1500.0 1700.0 2100.0 2600.0 2900.0 3100.0 +1500.0 1700.0 2400.0 2800.0 3000.0 3200.0 +1500.0 1700.0 2400.0 2900.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2600.0 3000.0 3300.0 +1200.0 1700.0 2500.0 2700.0 3000.0 3300.0 +1200.0 1500.0 2600.0 2700.0 3000.0 3300.0 +1300.0 1600.0 2600.0 2700.0 3000.0 3300.0 +1600.0 1800.0 2400.0 2600.0 2900.0 3200.0 +1700.0 1800.0 2500.0 2600.0 2800.0 3200.0 +1900.0 2000.0 2400.0 2700.0 2800.0 3100.0 +2000.0 2100.0 2500.0 2700.0 2800.0 3100.0 +1800.0 1900.0 2400.0 2700.0 2800.0 3100.0 +1700.0 1800.0 2400.0 2700.0 2800.0 3100.0 +1600.0 1700.0 2400.0 2700.0 2800.0 3100.0 +1500.0 1600.0 2400.0 2700.0 2800.0 3200.0 +1400.0 1600.0 2300.0 2600.0 2900.0 3200.0 +1300.0 1500.0 2400.0 2600.0 2800.0 3200.0 +1200.0 1400.0 2500.0 2600.0 2900.0 3200.0 +1300.0 1400.0 2200.0 2600.0 2800.0 3100.0 +1900.0 2100.0 2600.0 2800.0 3200.0 3400.0 +1900.0 2000.0 2500.0 2800.0 3200.0 3300.0 +1800.0 2100.0 2500.0 2700.0 2900.0 3100.0 +1600.0 2000.0 2400.0 2800.0 3000.0 3200.0 +1600.0 1900.0 2400.0 2800.0 3000.0 3300.0 +1800.0 1900.0 2300.0 2700.0 3000.0 3100.0 +1800.0 1900.0 2300.0 2700.0 2900.0 3000.0 +1700.0 1900.0 2200.0 2500.0 2900.0 3000.0 +1400.0 1900.0 2200.0 2500.0 2900.0 3100.0 +1500.0 1800.0 2200.0 2400.0 2900.0 3100.0 +1600.0 1900.0 2300.0 2500.0 3000.0 3200.0 +1800.0 2100.0 2300.0 2700.0 3100.0 3200.0 +1900.0 2300.0 2600.0 2800.0 3000.0 3200.0 +1500.0 1700.0 2300.0 2700.0 2900.0 3100.0 +1700.0 1800.0 2300.0 2800.0 3000.0 3100.0 +2000.0 2100.0 2400.0 2800.0 3100.0 3200.0 +2100.0 2400.0 2500.0 2800.0 3100.0 3200.0 +1900.0 2100.0 2500.0 2800.0 3000.0 3200.0 +1700.0 1800.0 2400.0 2800.0 3000.0 3200.0 +1300.0 1500.0 2200.0 2800.0 3100.0 3200.0 +1400.0 1500.0 2400.0 2800.0 2900.0 3200.0 +1400.0 1600.0 2500.0 2700.0 3000.0 3200.0 +1500.0 1600.0 2400.0 2700.0 3000.0 3200.0 +1600.0 1800.0 2400.0 2700.0 2900.0 3200.0 +1400.0 1600.0 2500.0 2600.0 3100.0 3300.0 +1200.0 1600.0 2600.0 2700.0 3100.0 3300.0 +1000.0 1800.0 2700.0 2800.0 3200.0 3400.0 +1100.0 1700.0 2400.0 2500.0 3200.0 3400.0 +1600.0 1800.0 2000.0 2200.0 3200.0 3400.0 +1800.0 1900.0 2200.0 2400.0 3000.0 3300.0 +1800.0 1900.0 2200.0 2600.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2700.0 3000.0 3200.0 +1300.0 1500.0 2500.0 2800.0 3000.0 3300.0 +1700.0 2000.0 2500.0 2700.0 2900.0 3200.0 +2000.0 2200.0 2500.0 2700.0 2900.0 3200.0 +2200.0 2600.0 2700.0 2800.0 3100.0 3300.0 +2100.0 2600.0 2700.0 2900.0 3300.0 3400.0 +2200.0 2300.0 2600.0 2800.0 3000.0 3200.0 +1600.0 2200.0 2500.0 2700.0 3100.0 3200.0 +1600.0 2100.0 2400.0 2700.0 3100.0 3200.0 +1800.0 2000.0 2500.0 2900.0 3100.0 3200.0 +2200.0 2400.0 2600.0 2900.0 3100.0 3200.0 +2200.0 2500.0 2600.0 2800.0 3100.0 3200.0 +2300.0 2500.0 2600.0 2800.0 3200.0 3300.0 +2200.0 2500.0 2700.0 2800.0 3200.0 3300.0 +2200.0 2500.0 2700.0 2800.0 3100.0 3200.0 +2200.0 2400.0 2600.0 2800.0 3100.0 3200.0 +2000.0 2200.0 2400.0 2800.0 3000.0 3100.0 +1900.0 2000.0 2300.0 2800.0 3000.0 3200.0 +1700.0 2100.0 2300.0 2600.0 3000.0 3200.0 +1900.0 2200.0 2300.0 2600.0 3000.0 3100.0 +1800.0 2000.0 2200.0 2600.0 3000.0 3100.0 +1600.0 1900.0 2300.0 2500.0 2800.0 3000.0 +1700.0 1800.0 2300.0 2500.0 2800.0 2900.0 +1700.0 2100.0 2400.0 2700.0 3100.0 3200.0 +1400.0 1600.0 1700.0 2100.0 3200.0 3400.0 +1500.0 1800.0 2200.0 2300.0 3200.0 3500.0 +1300.0 1700.0 2300.0 2500.0 2900.0 3200.0 +1300.0 1500.0 2100.0 2500.0 2900.0 3200.0 +1700.0 2000.0 2200.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2500.0 2700.0 2900.0 3200.0 +1700.0 1900.0 2400.0 2700.0 2900.0 3200.0 +1600.0 1700.0 2300.0 2600.0 2900.0 3200.0 +1400.0 1600.0 2300.0 2400.0 2800.0 3300.0 +1600.0 1700.0 2400.0 2700.0 3000.0 3300.0 +1600.0 1800.0 2400.0 2700.0 2900.0 3300.0 +1600.0 1800.0 2400.0 2800.0 3000.0 3200.0 +1600.0 1700.0 2100.0 2600.0 2900.0 3200.0 +1500.0 1700.0 2200.0 2500.0 2700.0 3200.0 +1700.0 2000.0 2400.0 2700.0 3000.0 3300.0 +1600.0 1700.0 2400.0 2700.0 3000.0 3200.0 +1500.0 1600.0 2300.0 2700.0 3100.0 3300.0 +1400.0 1600.0 2300.0 2700.0 3100.0 3300.0 +1400.0 1600.0 2200.0 2800.0 3100.0 3200.0 +1500.0 1600.0 2200.0 2800.0 3100.0 3200.0 +1500.0 1600.0 2100.0 2800.0 3100.0 3200.0 +1500.0 1600.0 2000.0 2600.0 3100.0 3200.0 +1600.0 1700.0 2200.0 2800.0 3100.0 3200.0 +1700.0 1900.0 2500.0 2900.0 3100.0 3300.0 +2300.0 2400.0 2600.0 2900.0 3200.0 3300.0 +2200.0 2300.0 2500.0 2800.0 3100.0 3300.0 +2000.0 2200.0 2400.0 2600.0 3000.0 3300.0 +1300.0 1800.0 2200.0 2400.0 3000.0 3300.0 +1500.0 1800.0 2300.0 2400.0 3100.0 3400.0 +1800.0 2100.0 2300.0 2600.0 3000.0 3200.0 +1900.0 2100.0 2300.0 2700.0 3000.0 3200.0 +1600.0 1900.0 2500.0 2600.0 3000.0 3300.0 +1600.0 1800.0 2500.0 2600.0 3000.0 3400.0 +1600.0 1900.0 2400.0 2500.0 3100.0 3400.0 +1600.0 1800.0 2300.0 2400.0 3100.0 3400.0 +1600.0 1800.0 2200.0 2300.0 3100.0 3400.0 +1600.0 1800.0 2000.0 2200.0 3100.0 3400.0 +1700.0 1800.0 2300.0 2600.0 3100.0 3200.0 +2200.0 2300.0 2500.0 2800.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2500.0 3000.0 3200.0 +1300.0 1700.0 2300.0 2400.0 3000.0 3200.0 +1400.0 1800.0 2300.0 2400.0 3000.0 3100.0 +1200.0 1500.0 2600.0 2800.0 3000.0 3300.0 +2200.0 2400.0 2600.0 2800.0 3000.0 3200.0 +2000.0 2500.0 2600.0 2800.0 3100.0 3200.0 +1900.0 2400.0 2600.0 2700.0 3100.0 3200.0 +2000.0 2300.0 2400.0 2600.0 3000.0 3200.0 +1900.0 2200.0 2400.0 2800.0 3100.0 3300.0 +1800.0 2100.0 2300.0 2800.0 3100.0 3300.0 +1900.0 2100.0 2400.0 2600.0 3100.0 3200.0 +2000.0 2300.0 2500.0 2600.0 2900.0 3200.0 +1600.0 2100.0 2400.0 2600.0 2900.0 3300.0 +1400.0 1700.0 2400.0 2800.0 3000.0 3200.0 +1100.0 1700.0 2900.0 3000.0 3200.0 3400.0 +1100.0 1700.0 2300.0 2900.0 3300.0 3400.0 +1100.0 1500.0 2300.0 2400.0 3300.0 3500.0 +1400.0 1700.0 2200.0 2400.0 3000.0 3300.0 +1600.0 1800.0 2300.0 2600.0 2900.0 3300.0 +2000.0 2100.0 2400.0 2800.0 3000.0 3100.0 +1900.0 2000.0 2300.0 2700.0 3000.0 3100.0 +1600.0 1900.0 2100.0 2600.0 3000.0 3100.0 +1700.0 1800.0 2200.0 2600.0 3000.0 3300.0 +1500.0 1700.0 1900.0 2200.0 3200.0 3400.0 +1400.0 1600.0 1800.0 2100.0 3200.0 3400.0 +1300.0 1500.0 1600.0 2200.0 3300.0 3400.0 +1800.0 2000.0 2200.0 2400.0 3000.0 3300.0 +2100.0 2500.0 2700.0 2800.0 3100.0 3200.0 +2100.0 2400.0 2600.0 2800.0 3100.0 3200.0 +1300.0 1800.0 2200.0 2600.0 3000.0 3200.0 +1800.0 2200.0 2400.0 2800.0 3200.0 3300.0 +1700.0 2100.0 2300.0 2700.0 3100.0 3300.0 +1400.0 1600.0 2100.0 2200.0 3000.0 3300.0 +1500.0 1700.0 2100.0 2200.0 3100.0 3400.0 +1500.0 1700.0 2000.0 2200.0 3100.0 3400.0 +1700.0 1800.0 2100.0 2300.0 3100.0 3400.0 +1900.0 2000.0 2400.0 2600.0 3000.0 3100.0 +2100.0 2500.0 2800.0 2900.0 3200.0 3300.0 +1800.0 2200.0 2400.0 2700.0 3100.0 3200.0 +1700.0 2100.0 2300.0 2600.0 3000.0 3100.0 +1900.0 2100.0 2300.0 2700.0 3000.0 3100.0 +2000.0 2200.0 2500.0 2700.0 2900.0 3100.0 +1400.0 1700.0 2000.0 2600.0 3200.0 3300.0 +1400.0 1700.0 2200.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2900.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2600.0 3000.0 3100.0 +1600.0 1900.0 2200.0 2500.0 2900.0 3000.0 +1600.0 1800.0 2000.0 2600.0 3000.0 3100.0 +1600.0 1800.0 2300.0 2700.0 2900.0 3100.0 +1500.0 1900.0 2200.0 2500.0 2600.0 3200.0 +1800.0 1900.0 2400.0 2800.0 2900.0 3200.0 +2000.0 2100.0 2400.0 2800.0 3000.0 3200.0 +2000.0 2300.0 2400.0 2700.0 3200.0 3300.0 +1900.0 2200.0 2400.0 2800.0 3200.0 3300.0 +1300.0 1800.0 2200.0 2600.0 3100.0 3300.0 +2000.0 2400.0 2800.0 3000.0 3200.0 3400.0 +2200.0 2300.0 2800.0 3000.0 3200.0 3300.0 +2100.0 2300.0 2600.0 3000.0 3200.0 3300.0 +2100.0 2200.0 2600.0 2900.0 3100.0 3200.0 +2100.0 2200.0 2500.0 2900.0 3100.0 3200.0 +1800.0 2100.0 2300.0 2800.0 3100.0 3200.0 +1800.0 2000.0 2200.0 2600.0 3100.0 3200.0 +2000.0 2100.0 2400.0 2900.0 3100.0 3200.0 +2200.0 2500.0 2800.0 3000.0 3200.0 3300.0 +2100.0 2400.0 2800.0 3000.0 3200.0 3400.0 +2000.0 2100.0 2500.0 2800.0 3100.0 3200.0 +2000.0 2100.0 2500.0 2900.0 3000.0 3200.0 +1800.0 1900.0 2200.0 2800.0 2900.0 3100.0 +1600.0 1900.0 2100.0 2500.0 2800.0 3000.0 +1700.0 1900.0 2200.0 2500.0 2800.0 3000.0 +2100.0 2400.0 2700.0 3000.0 3200.0 3400.0 +1700.0 1800.0 2300.0 2700.0 3000.0 3200.0 +1600.0 1700.0 2300.0 2800.0 3000.0 3200.0 +1600.0 1900.0 2300.0 2800.0 3100.0 3300.0 +1400.0 1600.0 1700.0 2100.0 3300.0 3400.0 +1600.0 1700.0 2000.0 2300.0 3200.0 3400.0 +1600.0 1800.0 2300.0 2700.0 2900.0 3200.0 +1600.0 1700.0 2300.0 2800.0 2900.0 3200.0 +1600.0 1800.0 2300.0 2800.0 3000.0 3100.0 +1700.0 1800.0 2200.0 2800.0 3000.0 3100.0 +1800.0 1900.0 2300.0 2600.0 2900.0 3300.0 +1700.0 1800.0 2300.0 2500.0 3000.0 3400.0 +1600.0 1700.0 2200.0 2400.0 3000.0 3400.0 +1600.0 1700.0 2200.0 2300.0 3000.0 3400.0 +2000.0 2100.0 2300.0 2400.0 3000.0 3300.0 +2200.0 2500.0 2700.0 2900.0 3200.0 3400.0 +2000.0 2500.0 2600.0 2800.0 3200.0 3300.0 +2100.0 2500.0 2600.0 2900.0 3200.0 3300.0 +1700.0 1900.0 2200.0 2700.0 3000.0 3100.0 +1900.0 2000.0 2300.0 2800.0 3000.0 3100.0 +1700.0 2000.0 2300.0 2700.0 3000.0 3200.0 +2000.0 2100.0 2500.0 2800.0 3000.0 3100.0 +1400.0 1600.0 1800.0 2100.0 3300.0 3400.0 +1500.0 1800.0 2100.0 2300.0 3200.0 3300.0 +1600.0 1700.0 2200.0 2500.0 3000.0 3300.0 +1600.0 1700.0 2200.0 2600.0 3000.0 3200.0 +1600.0 1700.0 2200.0 2700.0 3000.0 3200.0 +1700.0 1800.0 2200.0 2700.0 3000.0 3100.0 +1800.0 2000.0 2200.0 2800.0 3000.0 3100.0 +1300.0 1900.0 2200.0 2500.0 3100.0 3200.0 +1300.0 2000.0 2200.0 2600.0 3100.0 3200.0 +2100.0 2500.0 2800.0 2900.0 3200.0 3400.0 +2200.0 2600.0 2800.0 3000.0 3300.0 3400.0 +1600.0 1900.0 2500.0 2600.0 3100.0 3400.0 +1400.0 1800.0 2500.0 2600.0 3100.0 3400.0 +1100.0 1800.0 2600.0 2700.0 3200.0 3400.0 +1000.0 1800.0 2500.0 2600.0 3300.0 3400.0 +1200.0 1500.0 1700.0 1900.0 3000.0 3400.0 +1700.0 2100.0 2300.0 2700.0 3200.0 3300.0 +2000.0 2100.0 2600.0 2800.0 3100.0 3300.0 +2000.0 2100.0 2500.0 2900.0 3100.0 3200.0 +1700.0 2000.0 2300.0 2800.0 3100.0 3200.0 +1600.0 2000.0 2100.0 2700.0 3000.0 3100.0 +1600.0 2000.0 2100.0 2700.0 3100.0 3200.0 +1800.0 1900.0 2200.0 2500.0 2900.0 3100.0 +1700.0 2000.0 2200.0 2500.0 2900.0 3100.0 +1500.0 2000.0 2200.0 2400.0 2900.0 3100.0 +1600.0 1900.0 2200.0 2600.0 3000.0 3100.0 +1600.0 1900.0 2300.0 2700.0 2900.0 3100.0 +1700.0 2000.0 2200.0 2700.0 2900.0 3000.0 +1700.0 2000.0 2300.0 2700.0 2900.0 3100.0 +1700.0 2000.0 2300.0 2600.0 2900.0 3100.0 +1700.0 1900.0 2400.0 2600.0 2800.0 3000.0 +1700.0 1800.0 2300.0 2600.0 2800.0 3000.0 +1700.0 1900.0 2400.0 2600.0 2900.0 3100.0 +1700.0 1900.0 2300.0 2500.0 2800.0 3100.0 +1700.0 2100.0 2400.0 2600.0 2800.0 3100.0 +2000.0 2200.0 2500.0 2700.0 2800.0 3100.0 +1900.0 2200.0 2400.0 2700.0 2900.0 3000.0 +1800.0 2000.0 2300.0 2700.0 2900.0 3000.0 +1800.0 2300.0 2500.0 2700.0 3000.0 3100.0 +2000.0 2400.0 2600.0 2800.0 3100.0 3200.0 +1900.0 2300.0 2700.0 2800.0 3200.0 3300.0 +1800.0 2400.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2300.0 2600.0 2800.0 3200.0 3300.0 +1700.0 2000.0 2300.0 2500.0 2900.0 3000.0 +1700.0 1800.0 2100.0 2500.0 2900.0 3000.0 +1600.0 1700.0 2000.0 2400.0 2900.0 3100.0 +1600.0 1700.0 2100.0 2400.0 2700.0 2900.0 +1500.0 1600.0 2000.0 2600.0 2800.0 3100.0 +1400.0 1500.0 2000.0 2700.0 3200.0 3300.0 +1500.0 1600.0 2100.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2100.0 2600.0 3100.0 3200.0 +1800.0 1900.0 2200.0 2800.0 3100.0 3300.0 +2000.0 2200.0 2800.0 2900.0 3200.0 3400.0 +2000.0 2200.0 2800.0 2900.0 3100.0 3400.0 +2000.0 2100.0 2700.0 2900.0 3100.0 3400.0 +1800.0 2200.0 2500.0 2800.0 3100.0 3200.0 +1800.0 2200.0 2600.0 2800.0 3100.0 3200.0 +1900.0 2200.0 2500.0 2800.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2500.0 2900.0 3100.0 +1800.0 1900.0 2200.0 2500.0 2800.0 3100.0 +1600.0 1700.0 2100.0 2500.0 2800.0 3000.0 +1500.0 1700.0 2100.0 2400.0 2700.0 3100.0 +1400.0 1500.0 1900.0 2400.0 3000.0 3100.0 +1400.0 1600.0 2000.0 2400.0 3100.0 3200.0 +1500.0 1700.0 2100.0 2400.0 3000.0 3200.0 +1600.0 1800.0 2100.0 2400.0 2900.0 3100.0 +1600.0 1800.0 2100.0 2300.0 3000.0 3200.0 +1600.0 1800.0 2100.0 2300.0 3100.0 3300.0 +1600.0 1700.0 2000.0 2200.0 3200.0 3300.0 +1600.0 1700.0 1900.0 2100.0 3000.0 3300.0 +1700.0 1800.0 2100.0 2400.0 3100.0 3200.0 +2000.0 2300.0 2500.0 2700.0 2900.0 3100.0 +2000.0 2300.0 2600.0 2700.0 3000.0 3200.0 +1900.0 2100.0 2400.0 2600.0 2900.0 3200.0 +1700.0 1900.0 2200.0 2600.0 2800.0 3100.0 +1700.0 1800.0 2200.0 2600.0 2700.0 3100.0 +1600.0 1700.0 2200.0 2600.0 2800.0 3000.0 +1500.0 1600.0 2100.0 2700.0 2800.0 3000.0 +1300.0 1500.0 2000.0 2700.0 3000.0 3200.0 +1200.0 1500.0 2100.0 2800.0 3000.0 3200.0 +1300.0 1500.0 2100.0 2800.0 3000.0 3100.0 +1600.0 1900.0 2100.0 2600.0 3200.0 3300.0 +1600.0 1900.0 2200.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2100.0 2500.0 3200.0 3300.0 +1500.0 1900.0 2400.0 2500.0 2900.0 3200.0 +1600.0 1700.0 2200.0 2500.0 2900.0 3100.0 +1600.0 1700.0 2200.0 2700.0 2800.0 3000.0 +1600.0 1700.0 2200.0 2700.0 2900.0 3100.0 +1500.0 1700.0 2400.0 2700.0 2900.0 3100.0 +1500.0 1800.0 2400.0 2700.0 2900.0 3200.0 +1700.0 2100.0 2500.0 2700.0 3100.0 3200.0 +1700.0 2100.0 2500.0 2600.0 2900.0 3100.0 +1900.0 2300.0 2600.0 2700.0 3000.0 3100.0 +1800.0 2200.0 2600.0 2700.0 3000.0 3100.0 +1900.0 2200.0 2500.0 2700.0 3000.0 3100.0 +1900.0 2100.0 2400.0 2800.0 3000.0 3100.0 +1800.0 2000.0 2300.0 2500.0 3000.0 3300.0 +1600.0 2000.0 2200.0 2600.0 2800.0 3000.0 +1700.0 1800.0 2100.0 2600.0 3000.0 3200.0 +1600.0 1800.0 2100.0 2600.0 2900.0 3200.0 +1500.0 1700.0 2100.0 2400.0 2900.0 3200.0 +1400.0 1600.0 2100.0 2300.0 3000.0 3200.0 +1400.0 1800.0 2100.0 2500.0 3100.0 3200.0 +1700.0 1900.0 2300.0 2500.0 2700.0 3100.0 +1800.0 1900.0 2200.0 2500.0 2800.0 3200.0 +1700.0 1900.0 2100.0 2500.0 2800.0 3100.0 +1700.0 1900.0 2200.0 2500.0 2800.0 3200.0 +1600.0 1800.0 2100.0 2600.0 2800.0 3100.0 +1600.0 1800.0 2200.0 2600.0 2900.0 3200.0 +1500.0 1700.0 2200.0 2600.0 2800.0 3100.0 +1400.0 1600.0 2200.0 2600.0 2900.0 3100.0 +1400.0 1600.0 2300.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2200.0 2700.0 2900.0 3200.0 +1500.0 1700.0 2100.0 2600.0 3000.0 3100.0 +1600.0 1700.0 2100.0 2600.0 3000.0 3100.0 +1600.0 1800.0 2300.0 2500.0 2900.0 3100.0 +1700.0 1900.0 2300.0 2500.0 2900.0 3100.0 +1600.0 1800.0 2300.0 2500.0 2900.0 3000.0 +1500.0 1700.0 2000.0 2700.0 3000.0 3100.0 +1500.0 1600.0 2000.0 2600.0 2900.0 3100.0 +1500.0 1600.0 1900.0 2500.0 2900.0 3000.0 +1500.0 1600.0 1900.0 2600.0 2900.0 3100.0 +1700.0 1900.0 2500.0 2700.0 3100.0 3200.0 +1600.0 1700.0 2300.0 2700.0 2900.0 3200.0 +1600.0 1700.0 2200.0 2700.0 2800.0 3100.0 +1600.0 1700.0 2300.0 2700.0 2800.0 3100.0 +1500.0 1600.0 2200.0 2700.0 2900.0 3200.0 +1500.0 1600.0 2100.0 2700.0 3000.0 3200.0 +1400.0 1500.0 2100.0 2700.0 3000.0 3100.0 +1600.0 1800.0 2200.0 2500.0 3200.0 3300.0 +1900.0 2200.0 2400.0 2700.0 3100.0 3300.0 +1900.0 2100.0 2500.0 2800.0 3100.0 3200.0 +1800.0 2100.0 2400.0 2800.0 3000.0 3200.0 +1600.0 1800.0 2300.0 2700.0 3000.0 3200.0 +1600.0 1800.0 2200.0 2400.0 3000.0 3300.0 +1700.0 1900.0 2100.0 2500.0 3100.0 3300.0 +1600.0 1800.0 2200.0 2500.0 3200.0 3400.0 +1700.0 1900.0 2200.0 2500.0 3200.0 3400.0 +1600.0 1800.0 2200.0 2600.0 3200.0 3300.0 +1900.0 2100.0 2500.0 2700.0 2900.0 3100.0 +1900.0 2200.0 2400.0 2600.0 2800.0 3100.0 +1600.0 1700.0 2100.0 2500.0 2700.0 3000.0 +1600.0 1700.0 2100.0 2500.0 2600.0 3000.0 +1600.0 1700.0 2200.0 2400.0 2700.0 2900.0 +1700.0 1800.0 2300.0 2500.0 2800.0 3000.0 +1700.0 1800.0 2300.0 2500.0 2800.0 3100.0 +1700.0 1800.0 2200.0 2400.0 2800.0 3100.0 +1700.0 1900.0 2200.0 2400.0 2800.0 3100.0 +1500.0 2000.0 2300.0 2700.0 2900.0 3100.0 +1500.0 1900.0 2300.0 2500.0 3000.0 3300.0 +1700.0 2000.0 2400.0 2900.0 3200.0 3300.0 +2000.0 2100.0 2400.0 2700.0 3000.0 3100.0 +1900.0 2200.0 2400.0 2600.0 2900.0 3000.0 +1700.0 2100.0 2300.0 2700.0 2900.0 3000.0 +1600.0 2000.0 2200.0 2600.0 3000.0 3100.0 +1600.0 2100.0 2200.0 2600.0 3000.0 3100.0 +1600.0 2100.0 2300.0 2600.0 3000.0 3100.0 +1700.0 2100.0 2300.0 2600.0 2900.0 3100.0 +1800.0 2300.0 2400.0 2700.0 3000.0 3200.0 +1900.0 2300.0 2500.0 2700.0 3000.0 3100.0 +1900.0 2400.0 2500.0 2700.0 3000.0 3100.0 +1900.0 2400.0 2600.0 2800.0 3000.0 3200.0 +1800.0 2400.0 2600.0 2800.0 3000.0 3200.0 +1800.0 2300.0 2600.0 2700.0 3000.0 3100.0 +1600.0 1800.0 2300.0 2500.0 2800.0 3100.0 +1500.0 1800.0 2200.0 2500.0 2800.0 3000.0 +1500.0 1800.0 2300.0 2500.0 2800.0 3100.0 +1400.0 1900.0 2300.0 2500.0 2800.0 3000.0 +2000.0 2100.0 2500.0 2700.0 3100.0 3200.0 +2000.0 2100.0 2600.0 2800.0 3000.0 3200.0 +1800.0 2100.0 2400.0 2700.0 2900.0 3100.0 +1800.0 2100.0 2400.0 2600.0 2900.0 3200.0 +1800.0 2000.0 2400.0 2600.0 2900.0 3200.0 +1700.0 1900.0 2400.0 2600.0 2900.0 3200.0 +1500.0 1700.0 2100.0 2500.0 2900.0 3200.0 +1200.0 1700.0 2200.0 2400.0 2900.0 3200.0 +1500.0 1600.0 1900.0 2500.0 2800.0 3000.0 +1500.0 1600.0 2000.0 2500.0 2800.0 3000.0 +1600.0 1700.0 2100.0 2500.0 2800.0 3200.0 +1700.0 1800.0 2100.0 2400.0 2800.0 3100.0 +1700.0 1800.0 2100.0 2400.0 2900.0 3100.0 +1700.0 1800.0 2300.0 2700.0 3100.0 3300.0 +1300.0 1700.0 2300.0 2600.0 3100.0 3300.0 +1400.0 1800.0 2300.0 2700.0 3100.0 3300.0 +1500.0 1600.0 1900.0 2100.0 2800.0 3300.0 +1600.0 1700.0 2000.0 2100.0 2700.0 3300.0 +1800.0 2200.0 2400.0 2500.0 3000.0 3300.0 +1700.0 2300.0 2400.0 2600.0 3100.0 3200.0 +1700.0 2200.0 2400.0 2600.0 3000.0 3100.0 +1800.0 2000.0 2300.0 2500.0 2800.0 3100.0 +1800.0 2000.0 2200.0 2500.0 2900.0 3100.0 +1800.0 2100.0 2200.0 2700.0 3000.0 3100.0 +1800.0 2000.0 2200.0 2600.0 2900.0 3000.0 +1700.0 2000.0 2100.0 2600.0 3000.0 3100.0 +1700.0 2000.0 2100.0 2500.0 3000.0 3100.0 +1700.0 1900.0 2300.0 2500.0 2800.0 3200.0 +1600.0 1900.0 2300.0 2500.0 2900.0 3200.0 +1500.0 1800.0 2200.0 2500.0 3100.0 3300.0 +1600.0 1700.0 2300.0 2700.0 3100.0 3200.0 +1500.0 1700.0 2000.0 2600.0 2900.0 3000.0 +1400.0 1600.0 2000.0 2600.0 2900.0 3200.0 +1500.0 1600.0 2000.0 2600.0 2900.0 3200.0 +1600.0 1700.0 2100.0 2500.0 2900.0 3200.0 +1500.0 1900.0 2300.0 2400.0 3000.0 3300.0 +1600.0 1800.0 2300.0 2500.0 3000.0 3300.0 +1800.0 2200.0 2500.0 2700.0 2900.0 3100.0 +1500.0 1900.0 2200.0 2600.0 3000.0 3200.0 +1600.0 1800.0 2200.0 2700.0 2900.0 3100.0 +1400.0 1600.0 2000.0 2700.0 2800.0 3000.0 +1400.0 1600.0 1900.0 2600.0 2800.0 3000.0 +1400.0 1600.0 2100.0 2600.0 2900.0 3200.0 +1500.0 1600.0 2100.0 2600.0 3000.0 3200.0 +1500.0 1600.0 2100.0 2600.0 2900.0 3100.0 +1600.0 1700.0 2000.0 2600.0 2900.0 3000.0 +1700.0 1900.0 2100.0 2600.0 2800.0 3100.0 +1800.0 2000.0 2400.0 2700.0 2900.0 3200.0 +1900.0 2000.0 2400.0 2700.0 3000.0 3200.0 +1800.0 2200.0 2600.0 2900.0 3100.0 3300.0 +1800.0 1900.0 2100.0 2500.0 3100.0 3200.0 +1800.0 1900.0 2100.0 2400.0 3000.0 3200.0 +1700.0 1900.0 2100.0 2500.0 3000.0 3200.0 +1600.0 1700.0 2300.0 2500.0 2800.0 3200.0 +1600.0 1700.0 2200.0 2600.0 2800.0 3200.0 +1600.0 1700.0 2100.0 2600.0 2800.0 3200.0 +1600.0 1700.0 2000.0 2600.0 2800.0 3100.0 +1400.0 1700.0 2000.0 2600.0 2900.0 3100.0 +1800.0 2200.0 2500.0 2900.0 3100.0 3300.0 +1700.0 2100.0 2500.0 2900.0 3100.0 3200.0 +1500.0 1700.0 2400.0 2700.0 2900.0 3200.0 +1400.0 1500.0 2300.0 2500.0 2800.0 3100.0 +1300.0 1500.0 2300.0 2500.0 2800.0 3100.0 +1300.0 1500.0 2200.0 2600.0 2700.0 3100.0 +1200.0 1600.0 2400.0 2600.0 3000.0 3200.0 +1600.0 2000.0 2500.0 2700.0 3000.0 3300.0 +1500.0 1700.0 2500.0 2700.0 3000.0 3200.0 +1400.0 1500.0 2000.0 2700.0 3000.0 3100.0 +1400.0 1500.0 1900.0 2600.0 3000.0 3100.0 +2000.0 2300.0 2800.0 2900.0 3200.0 3400.0 +2100.0 2500.0 2700.0 2800.0 3200.0 3400.0 +1900.0 2300.0 2500.0 2700.0 3100.0 3400.0 +1800.0 1900.0 2200.0 2500.0 3000.0 3300.0 +1900.0 2200.0 2500.0 2600.0 2900.0 3200.0 +1900.0 2100.0 2300.0 2700.0 2800.0 3100.0 +1900.0 2000.0 2200.0 2600.0 3000.0 3200.0 +1900.0 2000.0 2500.0 2800.0 3100.0 3300.0 +1800.0 1900.0 2200.0 2700.0 2800.0 3100.0 +1700.0 1800.0 2400.0 2600.0 2800.0 3200.0 +1700.0 1900.0 2400.0 2500.0 2900.0 3300.0 +1400.0 1700.0 2300.0 2400.0 2600.0 3000.0 +1600.0 1700.0 2000.0 2200.0 2900.0 3200.0 +1600.0 1700.0 2000.0 2300.0 2900.0 3200.0 +1800.0 1900.0 2100.0 2600.0 2800.0 3100.0 +1800.0 1900.0 2300.0 2600.0 2900.0 3100.0 +1100.0 1800.0 2200.0 2400.0 2900.0 3200.0 +1200.0 1700.0 2300.0 2500.0 3000.0 3200.0 +1500.0 1600.0 2200.0 2600.0 2700.0 3100.0 +1700.0 1800.0 2100.0 2500.0 3000.0 3100.0 +1300.0 1700.0 2000.0 2400.0 3000.0 3200.0 +1300.0 1600.0 2000.0 2300.0 3100.0 3200.0 +1300.0 1600.0 1900.0 2300.0 3100.0 3200.0 +1400.0 1600.0 1900.0 2300.0 3100.0 3200.0 +1400.0 1600.0 1900.0 2400.0 3100.0 3200.0 +1500.0 1700.0 1900.0 2400.0 3100.0 3200.0 +1800.0 2100.0 2200.0 2700.0 3100.0 3200.0 +1700.0 2100.0 2200.0 2700.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2700.0 3000.0 3200.0 +1700.0 1900.0 2300.0 2600.0 3200.0 3400.0 +1900.0 2200.0 2600.0 3000.0 3300.0 3400.0 +1400.0 1800.0 2200.0 2600.0 3000.0 3300.0 +1000.0 1400.0 2400.0 2600.0 2900.0 3200.0 +1200.0 1500.0 2500.0 2600.0 3000.0 3300.0 +1200.0 1500.0 2400.0 2600.0 3000.0 3300.0 +1200.0 1500.0 2400.0 2600.0 2900.0 3300.0 +1200.0 1500.0 2400.0 2500.0 2900.0 3300.0 +1200.0 1500.0 2300.0 2500.0 3000.0 3300.0 +1200.0 1500.0 2300.0 2400.0 3000.0 3300.0 +1300.0 2000.0 2300.0 2700.0 3100.0 3200.0 +1700.0 1800.0 2200.0 2500.0 2800.0 3200.0 +1800.0 1900.0 2300.0 2500.0 2700.0 3200.0 +1800.0 1900.0 2300.0 2600.0 2700.0 3100.0 +1800.0 1900.0 2400.0 2600.0 2800.0 3200.0 +1900.0 2000.0 2700.0 2800.0 3100.0 3300.0 +1900.0 2000.0 2600.0 2800.0 3000.0 3300.0 +1900.0 2000.0 2500.0 2800.0 3000.0 3300.0 +1900.0 2100.0 2700.0 2800.0 3100.0 3300.0 +1900.0 2000.0 2700.0 2800.0 3000.0 3300.0 +1900.0 2000.0 2600.0 2800.0 3000.0 3200.0 +1200.0 1500.0 2200.0 2500.0 3100.0 3300.0 +1600.0 1900.0 2200.0 2600.0 3000.0 3200.0 +1300.0 1700.0 2300.0 2500.0 3100.0 3200.0 +1400.0 1500.0 2100.0 2400.0 2600.0 3100.0 +1500.0 1600.0 2000.0 2400.0 2700.0 3100.0 +1600.0 1700.0 2000.0 2500.0 2700.0 3100.0 +1900.0 2100.0 2300.0 2600.0 2900.0 3200.0 +1900.0 2100.0 2400.0 2600.0 2900.0 3100.0 +1700.0 2000.0 2200.0 2700.0 2900.0 3100.0 +1800.0 2000.0 2100.0 2700.0 3000.0 3100.0 +1800.0 1900.0 2100.0 2700.0 3000.0 3200.0 +1900.0 2100.0 2700.0 2800.0 3000.0 3300.0 +1900.0 2300.0 2700.0 2800.0 3100.0 3300.0 +2000.0 2400.0 2700.0 2800.0 3200.0 3400.0 +1600.0 2000.0 2300.0 2600.0 3000.0 3100.0 +1000.0 1400.0 2200.0 2400.0 3100.0 3300.0 +1400.0 1500.0 2000.0 2100.0 2900.0 3300.0 +1800.0 1900.0 2100.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2200.0 2700.0 3000.0 3300.0 +1800.0 2000.0 2300.0 2700.0 3100.0 3300.0 +1800.0 2100.0 2500.0 2700.0 3000.0 3100.0 +1900.0 2200.0 2800.0 2900.0 3200.0 3300.0 +2000.0 2200.0 2500.0 2900.0 3200.0 3300.0 +1800.0 2000.0 2300.0 2400.0 3100.0 3200.0 +1800.0 2000.0 2300.0 2400.0 3000.0 3200.0 +1800.0 1900.0 2200.0 2400.0 3000.0 3200.0 +1600.0 1800.0 2100.0 2600.0 2800.0 3000.0 +1500.0 1600.0 2200.0 2600.0 2900.0 3100.0 +1600.0 1700.0 2000.0 2600.0 3200.0 3300.0 +1700.0 1800.0 2000.0 2500.0 3100.0 3200.0 +1600.0 1900.0 2000.0 2500.0 3000.0 3100.0 +1900.0 2300.0 2800.0 2900.0 3200.0 3400.0 +2000.0 2200.0 2700.0 3000.0 3200.0 3300.0 +1900.0 2400.0 2800.0 2900.0 3200.0 3300.0 +2000.0 2400.0 2700.0 2900.0 3100.0 3300.0 +1800.0 2200.0 2400.0 2800.0 3000.0 3200.0 +1900.0 2200.0 2700.0 3000.0 3200.0 3400.0 +1900.0 2200.0 2600.0 2800.0 3000.0 3300.0 +1600.0 1700.0 2400.0 2600.0 2800.0 3200.0 +1600.0 1700.0 2300.0 2700.0 2800.0 3200.0 +1600.0 1700.0 2200.0 2700.0 2800.0 3200.0 +1600.0 1700.0 2000.0 2400.0 2900.0 3200.0 +1600.0 1900.0 2200.0 2500.0 2800.0 3000.0 +1600.0 2000.0 2400.0 2800.0 3200.0 3300.0 +1900.0 2000.0 2300.0 2700.0 3000.0 3200.0 +1600.0 1800.0 2000.0 2700.0 3000.0 3100.0 +1400.0 1600.0 2100.0 2700.0 2900.0 3100.0 +1900.0 2200.0 2800.0 3000.0 3300.0 3500.0 +1700.0 2000.0 2700.0 2800.0 3100.0 3300.0 +1600.0 1800.0 2200.0 2500.0 2800.0 3100.0 +1600.0 1800.0 2100.0 2400.0 2800.0 3000.0 +1600.0 2000.0 2300.0 2600.0 2800.0 3000.0 +1600.0 1900.0 2300.0 2600.0 2800.0 3000.0 +1800.0 2200.0 2500.0 2900.0 3200.0 3400.0 +1700.0 1900.0 2200.0 2800.0 3100.0 3200.0 +1600.0 2000.0 2300.0 2700.0 3000.0 3300.0 +1600.0 2000.0 2200.0 2600.0 3000.0 3200.0 +1800.0 2100.0 2300.0 2600.0 3000.0 3100.0 +1800.0 2100.0 2300.0 2600.0 3100.0 3200.0 +1900.0 2200.0 2400.0 2600.0 3100.0 3200.0 +1800.0 1900.0 2400.0 2600.0 2900.0 3200.0 +1300.0 2000.0 2300.0 2400.0 2800.0 3300.0 +1800.0 2000.0 2400.0 2600.0 2900.0 3300.0 +1900.0 2200.0 2300.0 2700.0 3000.0 3100.0 +1900.0 2200.0 2300.0 2700.0 3000.0 3200.0 +1800.0 2200.0 2400.0 2800.0 3100.0 3200.0 +1600.0 2100.0 2200.0 2700.0 3000.0 3100.0 +1700.0 2000.0 2300.0 2500.0 2900.0 3200.0 +1800.0 2200.0 2400.0 2700.0 3100.0 3300.0 +1200.0 2000.0 2500.0 2600.0 3100.0 3200.0 +1000.0 1600.0 2700.0 2900.0 3200.0 3300.0 +1000.0 1500.0 2700.0 2900.0 3200.0 3300.0 +1500.0 1700.0 2600.0 2800.0 3100.0 3300.0 +1500.0 1700.0 2600.0 2800.0 3000.0 3300.0 +1600.0 1700.0 2500.0 2800.0 3000.0 3300.0 +1600.0 1700.0 2400.0 2800.0 3000.0 3300.0 +1700.0 1800.0 2000.0 2400.0 3000.0 3200.0 +1700.0 1900.0 2100.0 2500.0 3000.0 3100.0 +1700.0 1900.0 2200.0 2500.0 2900.0 3100.0 +1700.0 1800.0 2200.0 2500.0 2800.0 3000.0 +1700.0 1800.0 2400.0 2600.0 2800.0 3100.0 +1200.0 1600.0 2200.0 2400.0 2900.0 3100.0 +1300.0 1800.0 2400.0 2600.0 2900.0 3200.0 +1300.0 1500.0 2000.0 2600.0 3000.0 3200.0 +1500.0 1800.0 2400.0 2700.0 3100.0 3200.0 +1800.0 2100.0 2400.0 2700.0 3100.0 3400.0 +1500.0 1600.0 2000.0 2200.0 3000.0 3300.0 +1600.0 1700.0 2100.0 2200.0 3000.0 3300.0 +1700.0 1800.0 2100.0 2300.0 3100.0 3300.0 +1800.0 1900.0 2200.0 2400.0 2900.0 3100.0 +1800.0 2000.0 2300.0 2700.0 3100.0 3200.0 +1500.0 1900.0 2200.0 2500.0 3000.0 3200.0 +1500.0 2100.0 2300.0 2500.0 3100.0 3300.0 +1700.0 1900.0 2400.0 2700.0 2900.0 3100.0 +1400.0 1800.0 2200.0 2300.0 3100.0 3400.0 +1300.0 1800.0 2300.0 2400.0 3000.0 3300.0 +1800.0 2200.0 2400.0 2600.0 3100.0 3300.0 +1800.0 2100.0 2300.0 2500.0 3100.0 3200.0 +1100.0 1700.0 2200.0 2300.0 3000.0 3200.0 +1100.0 1600.0 2200.0 2400.0 3100.0 3200.0 +1200.0 2000.0 2300.0 2500.0 3000.0 3100.0 +1700.0 2300.0 2500.0 2800.0 3200.0 3300.0 +1500.0 1900.0 2200.0 2400.0 2900.0 3100.0 +1400.0 1900.0 2200.0 2500.0 3000.0 3200.0 +1400.0 2000.0 2200.0 2600.0 3100.0 3200.0 +1700.0 2000.0 2300.0 2600.0 3000.0 3200.0 +1600.0 1800.0 2500.0 2800.0 2900.0 3200.0 +1700.0 1800.0 2500.0 2700.0 2900.0 3200.0 +1600.0 1800.0 2400.0 2600.0 2800.0 3200.0 +1400.0 1700.0 2100.0 2500.0 3000.0 3300.0 +1400.0 1600.0 1900.0 2000.0 3100.0 3300.0 +1400.0 1600.0 2000.0 2100.0 3100.0 3300.0 +1900.0 2000.0 2300.0 2400.0 2900.0 3300.0 +2100.0 2300.0 2600.0 2900.0 3100.0 3300.0 +1200.0 1800.0 2200.0 2400.0 3000.0 3200.0 +1700.0 2000.0 2300.0 2600.0 3000.0 3300.0 +1900.0 2400.0 2700.0 2900.0 3300.0 3400.0 +1400.0 1600.0 2100.0 2500.0 3100.0 3200.0 +1400.0 1700.0 2300.0 2500.0 3200.0 3400.0 +1400.0 1600.0 2300.0 2500.0 3200.0 3400.0 +1400.0 1600.0 2300.0 2500.0 3100.0 3400.0 +1500.0 1700.0 2200.0 2800.0 3100.0 3200.0 +1500.0 1600.0 2300.0 2800.0 3000.0 3200.0 +1400.0 1600.0 2300.0 2800.0 3000.0 3200.0 +1200.0 1400.0 2400.0 2900.0 3100.0 3200.0 +1200.0 1400.0 2400.0 2900.0 3200.0 3300.0 +1100.0 1400.0 2400.0 2900.0 3200.0 3300.0 +1600.0 1800.0 2400.0 2700.0 3000.0 3100.0 +1700.0 2000.0 2400.0 2800.0 3000.0 3200.0 +1900.0 2300.0 2700.0 3000.0 3300.0 3400.0 +1800.0 2300.0 2800.0 3000.0 3200.0 3400.0 +1800.0 1900.0 2400.0 2800.0 3100.0 3300.0 +1700.0 1800.0 2100.0 2600.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2700.0 3100.0 3200.0 +1600.0 1700.0 2000.0 2500.0 3100.0 3200.0 +1400.0 1700.0 2200.0 2700.0 3200.0 3300.0 +1500.0 1700.0 2200.0 2600.0 3100.0 3200.0 +1700.0 1900.0 2200.0 2700.0 3100.0 3200.0 +1900.0 2200.0 2500.0 2800.0 3000.0 3100.0 +2000.0 2200.0 2500.0 2700.0 3200.0 3300.0 +1700.0 1800.0 2300.0 2800.0 2900.0 3200.0 +1700.0 1800.0 2400.0 2800.0 2900.0 3200.0 +1600.0 1800.0 2600.0 2800.0 3000.0 3300.0 +2100.0 2300.0 2500.0 2800.0 3000.0 3300.0 +2100.0 2200.0 2500.0 2600.0 2900.0 3200.0 +1900.0 2100.0 2400.0 2600.0 2800.0 3200.0 +1800.0 2000.0 2700.0 2800.0 3000.0 3300.0 +1700.0 2100.0 2400.0 2600.0 3000.0 3200.0 +1800.0 2000.0 2400.0 2500.0 3100.0 3400.0 +1900.0 2200.0 2500.0 2600.0 3100.0 3200.0 +1900.0 2200.0 2500.0 2600.0 3000.0 3200.0 +1800.0 2200.0 2500.0 2600.0 3000.0 3100.0 +2000.0 2200.0 2600.0 2700.0 3100.0 3200.0 +2000.0 2300.0 2600.0 2700.0 3100.0 3200.0 +1800.0 2100.0 2300.0 2500.0 2900.0 3100.0 +1800.0 2100.0 2700.0 3000.0 3300.0 3400.0 +1800.0 2000.0 2700.0 2900.0 3200.0 3300.0 +1900.0 2100.0 2400.0 2700.0 3000.0 3300.0 +1900.0 2100.0 2400.0 2700.0 2900.0 3100.0 +2000.0 2200.0 2400.0 2700.0 2900.0 3100.0 +2000.0 2400.0 2600.0 2700.0 2900.0 3100.0 +1500.0 1700.0 2200.0 2300.0 3100.0 3300.0 +1400.0 1600.0 2300.0 2600.0 2900.0 3300.0 +1600.0 1700.0 2500.0 2700.0 2900.0 3200.0 +1600.0 1700.0 2500.0 2600.0 2900.0 3200.0 +1500.0 1700.0 2300.0 2400.0 3000.0 3400.0 +1500.0 1700.0 2100.0 2300.0 2900.0 3300.0 +1600.0 1700.0 2100.0 2300.0 3000.0 3300.0 +1500.0 2000.0 2300.0 2600.0 3100.0 3300.0 +1500.0 2100.0 2500.0 2600.0 3000.0 3200.0 +1500.0 2000.0 2500.0 2600.0 3100.0 3200.0 +1600.0 1700.0 2000.0 2500.0 3000.0 3100.0 +1700.0 1800.0 2200.0 2600.0 3000.0 3100.0 +1700.0 1800.0 2200.0 2500.0 3000.0 3100.0 +1800.0 1900.0 2200.0 2600.0 3000.0 3100.0 +1700.0 2100.0 2600.0 2900.0 3100.0 3400.0 +1700.0 2000.0 2600.0 2900.0 3200.0 3300.0 +1800.0 1900.0 2300.0 2800.0 2900.0 3100.0 +1800.0 1900.0 2600.0 2800.0 3200.0 3300.0 +1800.0 2000.0 2500.0 2900.0 3200.0 3400.0 +1800.0 2400.0 2800.0 2900.0 3300.0 3400.0 +1500.0 1800.0 2300.0 2700.0 3200.0 3300.0 +1600.0 1700.0 2400.0 2800.0 3000.0 3200.0 +1200.0 1600.0 2200.0 2600.0 2900.0 3200.0 +1400.0 1800.0 2400.0 2800.0 3200.0 3300.0 +1700.0 1900.0 2300.0 2800.0 3100.0 3300.0 +1300.0 1700.0 2300.0 2600.0 3000.0 3200.0 +1500.0 1600.0 2400.0 2600.0 3000.0 3300.0 +1700.0 1800.0 2300.0 2600.0 3000.0 3100.0 +1800.0 2000.0 2600.0 2900.0 3200.0 3400.0 +1900.0 2000.0 2700.0 2900.0 3200.0 3400.0 +1200.0 1800.0 2400.0 2500.0 3000.0 3300.0 +1300.0 1900.0 2400.0 2500.0 3100.0 3300.0 +1700.0 2000.0 2500.0 2900.0 3200.0 3300.0 +1100.0 1400.0 2400.0 2900.0 3100.0 3200.0 +1700.0 1800.0 2200.0 2700.0 3100.0 3200.0 +2000.0 2200.0 2400.0 2600.0 3000.0 3100.0 +1900.0 2100.0 2300.0 2600.0 3000.0 3100.0 +1700.0 1900.0 2500.0 2800.0 3100.0 3200.0 +1400.0 1600.0 2400.0 2800.0 3000.0 3200.0 +1200.0 1500.0 2200.0 2600.0 3100.0 3300.0 +1400.0 1600.0 2100.0 2700.0 3100.0 3200.0 +1500.0 1700.0 2200.0 2400.0 2900.0 3100.0 +1500.0 1800.0 2200.0 2300.0 2800.0 2900.0 +1500.0 1800.0 2200.0 2500.0 2900.0 3100.0 +1600.0 1800.0 2200.0 2500.0 2900.0 3100.0 +1700.0 1800.0 2200.0 2700.0 2900.0 3000.0 +1600.0 1800.0 2100.0 2800.0 3000.0 3100.0 +1800.0 1900.0 2300.0 2800.0 3100.0 3300.0 +1800.0 2000.0 2400.0 2800.0 3200.0 3400.0 +1900.0 2000.0 2500.0 2800.0 3200.0 3400.0 +1900.0 2000.0 2300.0 2700.0 3200.0 3300.0 +1500.0 1600.0 2300.0 2600.0 3000.0 3200.0 +1400.0 1700.0 2200.0 2500.0 3100.0 3300.0 +1900.0 2300.0 2500.0 2800.0 3100.0 3300.0 +1300.0 2000.0 2200.0 2400.0 2800.0 3100.0 +1400.0 1700.0 2300.0 2600.0 3000.0 3300.0 +1500.0 1600.0 2300.0 2700.0 2800.0 3100.0 +1600.0 1800.0 2300.0 2600.0 2800.0 3100.0 +1900.0 2000.0 2400.0 2600.0 2900.0 3100.0 +2000.0 2500.0 2600.0 2700.0 3200.0 3300.0 +2200.0 2500.0 2600.0 2900.0 3100.0 3300.0 +2100.0 2400.0 2600.0 2700.0 3200.0 3300.0 +2100.0 2400.0 2600.0 2700.0 3200.0 3400.0 +1700.0 1900.0 2500.0 2700.0 2900.0 3100.0 +1900.0 2300.0 2400.0 2700.0 3000.0 3200.0 +2000.0 2300.0 2500.0 2700.0 3000.0 3100.0 +2000.0 2400.0 2500.0 2800.0 3200.0 3300.0 +2000.0 2400.0 2600.0 2800.0 3200.0 3300.0 +1500.0 1600.0 2300.0 2600.0 3100.0 3300.0 +1400.0 1600.0 2200.0 2400.0 3000.0 3300.0 +1400.0 1600.0 2100.0 2400.0 2900.0 3200.0 +1600.0 1700.0 2200.0 2300.0 2700.0 3200.0 +1700.0 1800.0 2100.0 2300.0 2800.0 3300.0 +1700.0 1800.0 2200.0 2400.0 2800.0 3300.0 +1900.0 2000.0 2200.0 2500.0 3000.0 3200.0 +1300.0 2000.0 2300.0 2400.0 2900.0 3200.0 +1900.0 2200.0 2400.0 2500.0 2900.0 3200.0 +1600.0 1800.0 2200.0 2500.0 2700.0 3100.0 +1600.0 1700.0 2300.0 2500.0 3000.0 3400.0 +1900.0 2000.0 2400.0 2700.0 2900.0 3300.0 +1800.0 2200.0 2400.0 2600.0 2900.0 3100.0 +1700.0 2000.0 2300.0 2600.0 2800.0 3100.0 +1700.0 1800.0 2200.0 2600.0 2800.0 3000.0 +1600.0 1700.0 2100.0 2700.0 2900.0 3000.0 +1400.0 1600.0 2000.0 2200.0 2800.0 3200.0 +1200.0 1600.0 2000.0 2400.0 3000.0 3200.0 +1200.0 1700.0 2200.0 2500.0 3000.0 3100.0 +1600.0 1900.0 2600.0 2800.0 3000.0 3200.0 +1500.0 1900.0 2300.0 2700.0 2900.0 3200.0 +1200.0 1900.0 2300.0 2400.0 3000.0 3300.0 +1400.0 1600.0 2300.0 2600.0 3200.0 3300.0 +1300.0 1900.0 2300.0 2500.0 3000.0 3200.0 +1500.0 1600.0 2100.0 2400.0 3000.0 3200.0 +1600.0 1700.0 2200.0 2300.0 3000.0 3300.0 +1600.0 1700.0 2100.0 2200.0 2900.0 3300.0 +1500.0 1600.0 2000.0 2100.0 2800.0 3200.0 +1500.0 1600.0 2000.0 2200.0 2800.0 3200.0 +1500.0 1600.0 2000.0 2200.0 2900.0 3200.0 +1500.0 1800.0 2100.0 2200.0 2900.0 3300.0 +2100.0 2300.0 2500.0 2700.0 2900.0 3100.0 +2000.0 2200.0 2400.0 2600.0 2800.0 3100.0 +1800.0 2100.0 2300.0 2600.0 2800.0 3000.0 +1600.0 1800.0 2400.0 2600.0 2800.0 3000.0 +1200.0 1300.0 2100.0 2700.0 2800.0 3000.0 +1100.0 1300.0 2300.0 2700.0 2900.0 3100.0 +1100.0 1300.0 2300.0 2700.0 2800.0 3100.0 +1100.0 1300.0 2300.0 2800.0 2900.0 3100.0 +1500.0 1800.0 2300.0 2700.0 3100.0 3200.0 +1200.0 1800.0 2300.0 2600.0 3000.0 3200.0 +1700.0 1800.0 2300.0 2600.0 2800.0 3200.0 +1900.0 2000.0 2400.0 2600.0 2800.0 3200.0 +2100.0 2200.0 2400.0 2600.0 3100.0 3300.0 +2000.0 2200.0 2400.0 2600.0 3100.0 3300.0 +2300.0 2500.0 2800.0 3000.0 3200.0 3300.0 +1900.0 2200.0 2700.0 2800.0 3100.0 3300.0 +1600.0 1700.0 2200.0 2600.0 3000.0 3300.0 +1500.0 1700.0 2100.0 2400.0 3100.0 3300.0 +1300.0 1600.0 2100.0 2400.0 3200.0 3400.0 +1400.0 2000.0 2300.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2300.0 2500.0 3000.0 3300.0 +1400.0 1600.0 2300.0 2400.0 2800.0 3200.0 +1400.0 1600.0 2300.0 2500.0 2800.0 3200.0 +1400.0 1500.0 2300.0 2500.0 2800.0 3200.0 +1400.0 1500.0 2200.0 2600.0 3000.0 3300.0 +1500.0 1600.0 2000.0 2500.0 3100.0 3200.0 +1600.0 1800.0 2200.0 2700.0 3000.0 3200.0 +1500.0 1600.0 2300.0 2700.0 3000.0 3200.0 +1800.0 2000.0 2500.0 2800.0 2900.0 3200.0 +1700.0 1900.0 2500.0 2700.0 2900.0 3200.0 +1900.0 2200.0 2600.0 2800.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2200.0 2700.0 3100.0 3200.0 +1300.0 1500.0 2100.0 2800.0 3100.0 3200.0 +1500.0 1600.0 2400.0 2800.0 3000.0 3300.0 +1400.0 1500.0 2500.0 2600.0 2900.0 3200.0 +1500.0 1600.0 2400.0 2600.0 2800.0 3300.0 +1600.0 1700.0 2400.0 2600.0 2800.0 3300.0 +1800.0 2000.0 2300.0 2600.0 3000.0 3100.0 +1800.0 2000.0 2300.0 2700.0 3000.0 3100.0 +1900.0 2100.0 2400.0 2800.0 3100.0 3300.0 +1900.0 2100.0 2400.0 2800.0 3000.0 3300.0 +1800.0 1900.0 2300.0 2700.0 2900.0 3100.0 +1800.0 2100.0 2300.0 2700.0 3000.0 3100.0 +1900.0 2100.0 2300.0 2800.0 3000.0 3100.0 +1400.0 2000.0 2200.0 2500.0 3000.0 3200.0 +1900.0 2200.0 2600.0 3000.0 3200.0 3300.0 +1800.0 2200.0 2600.0 3000.0 3200.0 3300.0 +1500.0 1600.0 2400.0 2600.0 2800.0 3200.0 +1400.0 1600.0 2500.0 2700.0 2900.0 3200.0 +1500.0 1600.0 2400.0 2700.0 2900.0 3100.0 +1500.0 2100.0 2400.0 2700.0 3100.0 3300.0 +1900.0 2000.0 2300.0 2600.0 3000.0 3100.0 +1900.0 2000.0 2300.0 2600.0 2900.0 3100.0 +1700.0 2000.0 2200.0 2600.0 2900.0 3100.0 +1700.0 2200.0 2400.0 2700.0 3000.0 3200.0 +1700.0 1900.0 2500.0 2600.0 2900.0 3100.0 +1500.0 1700.0 2500.0 2600.0 2900.0 3100.0 +1400.0 1600.0 2300.0 2600.0 2900.0 3100.0 +1200.0 1400.0 2200.0 2600.0 2900.0 3200.0 +1600.0 1700.0 2200.0 2600.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2500.0 3100.0 3200.0 +1600.0 1900.0 2200.0 2700.0 3000.0 3200.0 +1700.0 1900.0 2300.0 2800.0 3100.0 3200.0 +1900.0 2100.0 2500.0 2700.0 3100.0 3400.0 +2100.0 2300.0 2600.0 2800.0 3000.0 3200.0 +2000.0 2300.0 2600.0 2800.0 3000.0 3200.0 +2100.0 2400.0 2700.0 2800.0 3000.0 3200.0 +1600.0 2300.0 2600.0 2800.0 3000.0 3100.0 +1700.0 2300.0 2600.0 2800.0 3000.0 3100.0 +1600.0 1700.0 2400.0 2600.0 3000.0 3300.0 +1500.0 1700.0 2400.0 2500.0 2900.0 3300.0 +1600.0 1900.0 2300.0 2600.0 2700.0 3300.0 +1600.0 1900.0 2300.0 2500.0 3300.0 3400.0 +1600.0 1800.0 2300.0 2500.0 3200.0 3400.0 +1800.0 2200.0 2700.0 2900.0 3300.0 3500.0 +1700.0 2000.0 2400.0 2600.0 3300.0 3400.0 +1800.0 2200.0 2800.0 3000.0 3200.0 3300.0 +2100.0 2400.0 2800.0 3100.0 3400.0 3500.0 +2100.0 2500.0 2800.0 3100.0 3400.0 3500.0 +1900.0 2300.0 2900.0 3000.0 3300.0 3400.0 +1900.0 2000.0 2300.0 2400.0 3200.0 3400.0 +1400.0 1700.0 2000.0 2300.0 3000.0 3100.0 +1400.0 1600.0 1900.0 2100.0 3000.0 3100.0 +1400.0 1600.0 1800.0 2100.0 3100.0 3200.0 +1400.0 1600.0 1800.0 2000.0 3200.0 3300.0 +1500.0 1700.0 2200.0 2300.0 2900.0 3300.0 +1600.0 1800.0 2400.0 2500.0 2900.0 3300.0 +1900.0 2000.0 2200.0 2400.0 3100.0 3300.0 +1900.0 2000.0 2200.0 2400.0 3200.0 3400.0 +1300.0 1500.0 2000.0 2500.0 3000.0 3200.0 +1300.0 1600.0 2100.0 2500.0 3000.0 3200.0 +1300.0 1600.0 2300.0 2600.0 3200.0 3300.0 +1400.0 1800.0 2200.0 2600.0 3200.0 3400.0 +1600.0 1800.0 2100.0 2400.0 3300.0 3400.0 +1700.0 1900.0 2200.0 2400.0 3200.0 3400.0 +1800.0 2000.0 2400.0 2700.0 3200.0 3400.0 +1900.0 2200.0 2600.0 2700.0 3000.0 3200.0 +1800.0 2100.0 2300.0 2600.0 3200.0 3300.0 +1600.0 1800.0 2000.0 2400.0 3100.0 3200.0 +1400.0 1600.0 1800.0 2000.0 3000.0 3100.0 +1400.0 1600.0 1800.0 2000.0 2900.0 3000.0 +1400.0 1600.0 1800.0 2100.0 2800.0 3000.0 +1500.0 1700.0 2100.0 2400.0 3000.0 3300.0 +1400.0 1600.0 2200.0 2500.0 3200.0 3300.0 +1100.0 1700.0 2400.0 2600.0 3100.0 3300.0 +1200.0 1800.0 2400.0 2500.0 3100.0 3200.0 +1600.0 2100.0 2400.0 2800.0 3300.0 3400.0 +1600.0 2300.0 2500.0 2800.0 3300.0 3400.0 +1800.0 2200.0 2700.0 3100.0 3400.0 3500.0 +1800.0 2200.0 2800.0 3000.0 3400.0 3500.0 +1900.0 2300.0 2800.0 3100.0 3400.0 3500.0 +1900.0 2400.0 2800.0 3100.0 3300.0 3400.0 +1800.0 2200.0 2600.0 2900.0 3400.0 3500.0 +1600.0 1800.0 2400.0 2800.0 3200.0 3300.0 +2000.0 2500.0 2600.0 2900.0 3200.0 3300.0 +2100.0 2400.0 2600.0 3000.0 3200.0 3300.0 +2200.0 2500.0 2700.0 3100.0 3200.0 3300.0 +2100.0 2500.0 2600.0 2800.0 3300.0 3400.0 +2000.0 2100.0 2700.0 2900.0 3300.0 3400.0 +1900.0 2000.0 2300.0 2500.0 3100.0 3400.0 +1700.0 1900.0 2300.0 2400.0 3100.0 3400.0 +1600.0 1900.0 2300.0 2500.0 3200.0 3400.0 +1600.0 2200.0 2700.0 3000.0 3300.0 3400.0 +1800.0 2300.0 2700.0 3000.0 3400.0 3500.0 +1700.0 2300.0 2500.0 2800.0 3300.0 3400.0 +1500.0 1900.0 2500.0 2700.0 3300.0 3400.0 +1700.0 2200.0 2500.0 2800.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2500.0 3200.0 3300.0 +1100.0 2000.0 2400.0 2500.0 3200.0 3300.0 +1400.0 1800.0 2400.0 2700.0 3100.0 3300.0 +1500.0 1900.0 2500.0 2700.0 3100.0 3300.0 +1500.0 1900.0 2300.0 2500.0 2700.0 2900.0 +1400.0 1800.0 2200.0 2500.0 2700.0 2900.0 +1400.0 1800.0 2400.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2400.0 2600.0 3000.0 3300.0 +1500.0 1900.0 2100.0 2300.0 3200.0 3300.0 +1400.0 1800.0 2300.0 2400.0 3000.0 3300.0 +2000.0 2300.0 2800.0 3000.0 3400.0 3500.0 +1600.0 1900.0 2200.0 2300.0 3100.0 3400.0 +1600.0 1800.0 2000.0 2500.0 3000.0 3100.0 +1500.0 1700.0 1800.0 2400.0 3100.0 3200.0 +1500.0 1600.0 1800.0 2400.0 3200.0 3300.0 +1700.0 1900.0 2300.0 2600.0 3100.0 3200.0 +1700.0 1900.0 2300.0 2500.0 2900.0 3300.0 +1900.0 2300.0 2700.0 2900.0 3100.0 3300.0 +1400.0 1700.0 2300.0 2500.0 3100.0 3200.0 +1200.0 1700.0 2300.0 2500.0 3100.0 3200.0 +1300.0 2200.0 2600.0 2800.0 3100.0 3300.0 +1100.0 1700.0 2500.0 2600.0 3200.0 3400.0 +1300.0 1600.0 2500.0 2600.0 3200.0 3300.0 +1400.0 1500.0 2500.0 2600.0 3100.0 3300.0 +1700.0 1800.0 2300.0 2500.0 2700.0 3300.0 +1800.0 2000.0 2500.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2400.0 2500.0 2900.0 3200.0 +1800.0 1900.0 2400.0 2500.0 2800.0 3200.0 +1900.0 2000.0 2300.0 2500.0 2800.0 3300.0 +1800.0 2000.0 2200.0 2500.0 2800.0 3300.0 +1900.0 2300.0 2700.0 3000.0 3300.0 3500.0 +2100.0 2300.0 2900.0 3000.0 3200.0 3300.0 +1900.0 2100.0 2800.0 2900.0 3100.0 3300.0 +1700.0 2000.0 2600.0 2700.0 2900.0 3100.0 +1700.0 2100.0 2600.0 2800.0 3000.0 3200.0 +1700.0 2100.0 2600.0 2900.0 3100.0 3300.0 +1400.0 1500.0 1700.0 2900.0 3300.0 3400.0 +1400.0 1700.0 1800.0 2600.0 3300.0 3400.0 +1400.0 1700.0 2000.0 2700.0 3100.0 3200.0 +1500.0 1700.0 1900.0 2300.0 2900.0 3000.0 +1400.0 1700.0 1800.0 2200.0 3000.0 3100.0 +1500.0 1600.0 2000.0 2100.0 3000.0 3200.0 +1300.0 1600.0 1800.0 2000.0 3000.0 3100.0 +1300.0 1600.0 1800.0 2000.0 3100.0 3200.0 +1300.0 1500.0 1700.0 2200.0 3200.0 3300.0 +1300.0 1600.0 1700.0 2200.0 3200.0 3300.0 +1300.0 1500.0 1600.0 2100.0 3200.0 3300.0 +1600.0 1700.0 2100.0 2300.0 3100.0 3300.0 +1500.0 1600.0 2300.0 2400.0 3100.0 3400.0 +1900.0 2400.0 2800.0 3100.0 3400.0 3500.0 +2000.0 2400.0 2800.0 3000.0 3400.0 3500.0 +1600.0 1800.0 2200.0 2600.0 2900.0 3100.0 +1300.0 1600.0 1800.0 2400.0 3100.0 3200.0 +1200.0 1600.0 1800.0 2100.0 3000.0 3100.0 +1400.0 1900.0 2100.0 2400.0 3000.0 3100.0 +1300.0 1900.0 2100.0 2300.0 3000.0 3200.0 +1300.0 1800.0 2100.0 2300.0 3000.0 3200.0 +1400.0 1800.0 2500.0 2700.0 3100.0 3400.0 +1100.0 1800.0 2200.0 2300.0 3100.0 3200.0 +1100.0 1800.0 2200.0 2300.0 3200.0 3300.0 +1200.0 1700.0 2300.0 2400.0 3200.0 3300.0 +1400.0 1700.0 2300.0 2400.0 3000.0 3300.0 +1400.0 1700.0 2400.0 2500.0 3000.0 3300.0 +1900.0 2200.0 2400.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2400.0 3200.0 3400.0 +1300.0 1700.0 2200.0 2400.0 2900.0 3100.0 +1100.0 1600.0 1800.0 2100.0 2900.0 3000.0 +1500.0 1700.0 1900.0 2100.0 3000.0 3100.0 +1600.0 1700.0 1900.0 2100.0 3000.0 3100.0 +1700.0 1900.0 2300.0 2500.0 2900.0 3200.0 +1400.0 1800.0 2200.0 2300.0 3300.0 3400.0 +2100.0 2400.0 2800.0 2900.0 3200.0 3300.0 +2200.0 2500.0 2700.0 2900.0 3100.0 3300.0 +2300.0 2500.0 2700.0 3000.0 3100.0 3300.0 +1700.0 2200.0 2400.0 2800.0 3300.0 3400.0 +1800.0 2300.0 2800.0 3100.0 3400.0 3500.0 +1800.0 2300.0 2600.0 3100.0 3400.0 3500.0 +1800.0 2300.0 2600.0 3100.0 3300.0 3400.0 +1500.0 1700.0 2400.0 2600.0 3000.0 3300.0 +1400.0 1600.0 2400.0 2500.0 2900.0 3300.0 +1200.0 1700.0 2200.0 2400.0 3100.0 3200.0 +1500.0 2000.0 2400.0 2700.0 3200.0 3300.0 +1400.0 1900.0 2300.0 2700.0 3000.0 3200.0 +1300.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1600.0 1900.0 2400.0 2500.0 3000.0 3200.0 +2000.0 2300.0 2600.0 2700.0 3000.0 3100.0 +1800.0 2000.0 2500.0 2800.0 3000.0 3300.0 +2000.0 2400.0 2600.0 2700.0 3100.0 3200.0 +1700.0 2400.0 2600.0 2800.0 3100.0 3200.0 +1200.0 1800.0 2200.0 2300.0 3300.0 3400.0 +1100.0 1600.0 2200.0 2400.0 3200.0 3300.0 +1100.0 1800.0 1900.0 2500.0 3000.0 3100.0 +1200.0 1700.0 1900.0 2500.0 3100.0 3200.0 +1400.0 1800.0 2300.0 2500.0 3200.0 3400.0 +1500.0 1700.0 2400.0 2500.0 3100.0 3400.0 +1500.0 1700.0 2300.0 2400.0 2900.0 3300.0 +1500.0 1900.0 2200.0 2600.0 3000.0 3100.0 +1300.0 1600.0 2100.0 2300.0 3000.0 3100.0 +1400.0 1700.0 2200.0 2300.0 3000.0 3100.0 +1400.0 1700.0 2200.0 2400.0 3000.0 3100.0 +1400.0 1600.0 2200.0 2300.0 3000.0 3100.0 +1500.0 1700.0 2200.0 2400.0 3100.0 3300.0 +1500.0 1700.0 2100.0 2300.0 3200.0 3300.0 +1400.0 1700.0 2000.0 2300.0 3200.0 3300.0 +1300.0 1700.0 2100.0 2500.0 3100.0 3200.0 +1500.0 1800.0 2200.0 2700.0 3000.0 3200.0 +1500.0 1700.0 2300.0 2400.0 3200.0 3400.0 +1500.0 1600.0 2200.0 2400.0 3100.0 3400.0 +1400.0 1600.0 2200.0 2400.0 3100.0 3400.0 +1100.0 1700.0 2300.0 2400.0 3200.0 3300.0 +1100.0 1900.0 2300.0 2500.0 3100.0 3200.0 +1500.0 1700.0 2300.0 2600.0 3100.0 3400.0 +1500.0 1700.0 2300.0 2500.0 3000.0 3400.0 +1500.0 1900.0 2200.0 2600.0 2800.0 3000.0 +1500.0 1800.0 2200.0 2500.0 2900.0 3000.0 +1500.0 1700.0 2200.0 2500.0 3100.0 3400.0 +1300.0 1800.0 2100.0 2300.0 3300.0 3400.0 +1100.0 1600.0 2200.0 2500.0 3000.0 3300.0 +1400.0 1600.0 2100.0 2500.0 2900.0 3200.0 +1500.0 1800.0 2400.0 2600.0 3300.0 3400.0 +1500.0 1900.0 2500.0 2700.0 3100.0 3200.0 +1800.0 2000.0 2100.0 2600.0 3000.0 3200.0 +1500.0 1700.0 2100.0 2600.0 3100.0 3300.0 +1500.0 1600.0 1800.0 2200.0 3200.0 3300.0 +1600.0 1800.0 1900.0 2300.0 3300.0 3400.0 +1500.0 1800.0 2100.0 2200.0 3200.0 3400.0 +1500.0 2000.0 2200.0 2600.0 3200.0 3300.0 +1300.0 1700.0 2100.0 2300.0 3100.0 3300.0 +1400.0 1500.0 2100.0 2300.0 3000.0 3300.0 +1500.0 1600.0 2100.0 2300.0 3000.0 3300.0 +1500.0 1600.0 2200.0 2300.0 3000.0 3300.0 +1400.0 1900.0 2100.0 2200.0 3000.0 3100.0 +1400.0 1800.0 2100.0 2400.0 3100.0 3200.0 +1500.0 1700.0 2300.0 2600.0 3100.0 3300.0 +1600.0 1900.0 2500.0 2700.0 3200.0 3300.0 +1500.0 1700.0 2200.0 2300.0 3200.0 3400.0 +1500.0 1900.0 2200.0 2400.0 2600.0 3300.0 +1500.0 1900.0 2300.0 2400.0 2800.0 3300.0 +1400.0 1600.0 2400.0 2600.0 3100.0 3300.0 +1400.0 1600.0 2400.0 2500.0 3100.0 3300.0 +1500.0 1600.0 2400.0 2500.0 3100.0 3200.0 +1600.0 1800.0 2100.0 2300.0 2800.0 3300.0 +1800.0 2100.0 2600.0 3000.0 3400.0 3500.0 +2100.0 2500.0 2900.0 3100.0 3400.0 3500.0 +1700.0 2100.0 2600.0 2700.0 3100.0 3200.0 +1600.0 1900.0 2300.0 2400.0 3200.0 3400.0 +1500.0 1800.0 2400.0 2500.0 3100.0 3400.0 +1600.0 2300.0 2700.0 3000.0 3300.0 3400.0 +1400.0 1600.0 1700.0 2100.0 3100.0 3200.0 +1400.0 1600.0 1700.0 2000.0 3100.0 3200.0 +1600.0 1700.0 1900.0 2200.0 3100.0 3300.0 +1800.0 1900.0 2500.0 2600.0 3000.0 3300.0 +1800.0 2100.0 2600.0 2900.0 3400.0 3500.0 +1800.0 2000.0 2300.0 2900.0 3200.0 3300.0 +1700.0 1800.0 2300.0 2400.0 2900.0 3100.0 +1100.0 1600.0 2500.0 2700.0 3100.0 3400.0 +1200.0 1700.0 2600.0 2700.0 3200.0 3300.0 +1400.0 2000.0 2600.0 2900.0 3300.0 3400.0 +1800.0 2200.0 2700.0 3000.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2600.0 3100.0 3300.0 +1300.0 1900.0 2600.0 2700.0 3200.0 3300.0 +1800.0 2100.0 2800.0 2900.0 3300.0 3400.0 +1700.0 1800.0 2000.0 2400.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2500.0 3100.0 3300.0 +1800.0 2100.0 2300.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2600.0 2700.0 3000.0 3200.0 +1800.0 2000.0 2600.0 2700.0 3000.0 3200.0 +1900.0 2000.0 2500.0 2700.0 3000.0 3200.0 +2000.0 2100.0 2500.0 2600.0 2900.0 3200.0 +1800.0 1900.0 2500.0 2700.0 2900.0 3300.0 +1700.0 1800.0 2500.0 2700.0 3000.0 3300.0 +1800.0 2200.0 2700.0 2800.0 3200.0 3300.0 +1400.0 1600.0 2400.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2300.0 2700.0 2900.0 3100.0 +1400.0 1600.0 2400.0 2700.0 2900.0 3200.0 +1700.0 2300.0 2700.0 3000.0 3300.0 3400.0 +1400.0 1700.0 2400.0 2700.0 3100.0 3300.0 +1400.0 1700.0 2400.0 2700.0 3000.0 3300.0 +1400.0 1700.0 1800.0 2500.0 3000.0 3100.0 +1300.0 1700.0 1900.0 2300.0 3000.0 3100.0 +1400.0 1800.0 1900.0 2400.0 3000.0 3100.0 +1900.0 2100.0 2500.0 2700.0 3100.0 3200.0 +1200.0 1700.0 2200.0 2300.0 2900.0 3100.0 +1300.0 1700.0 2200.0 2400.0 2800.0 3100.0 +1400.0 1700.0 2200.0 2300.0 2800.0 3100.0 +1500.0 1700.0 2200.0 2300.0 2900.0 3200.0 +1500.0 1700.0 2100.0 2300.0 2900.0 3200.0 +1500.0 1700.0 2000.0 2200.0 2900.0 3100.0 +1500.0 1700.0 1900.0 2200.0 3000.0 3200.0 +1500.0 1700.0 1900.0 2300.0 3100.0 3200.0 +1500.0 1700.0 2000.0 2300.0 3100.0 3200.0 +1600.0 1800.0 2300.0 2600.0 3000.0 3100.0 +2000.0 2500.0 2700.0 2900.0 3200.0 3300.0 +2300.0 2500.0 2800.0 3100.0 3200.0 3300.0 +2300.0 2500.0 2600.0 2900.0 3200.0 3300.0 +1500.0 1700.0 2000.0 2400.0 3100.0 3200.0 +1500.0 1700.0 1900.0 2200.0 3100.0 3300.0 +1600.0 1700.0 1800.0 2100.0 3200.0 3300.0 +1300.0 1600.0 2300.0 2500.0 3000.0 3100.0 +1200.0 1800.0 2300.0 2500.0 3000.0 3200.0 +1400.0 1800.0 2300.0 2400.0 2800.0 3200.0 +1400.0 1700.0 2300.0 2400.0 2900.0 3300.0 +1500.0 2000.0 2500.0 2600.0 2800.0 3100.0 +1800.0 2000.0 2200.0 2600.0 3000.0 3200.0 +1400.0 1700.0 1900.0 2100.0 3000.0 3100.0 +1300.0 1600.0 2300.0 2400.0 2900.0 3100.0 +1400.0 1700.0 2300.0 2500.0 3000.0 3200.0 +1500.0 1700.0 2300.0 2600.0 3100.0 3200.0 +1500.0 1800.0 2400.0 2600.0 3100.0 3200.0 +1600.0 1800.0 2000.0 2600.0 2900.0 3100.0 +1500.0 1700.0 1900.0 2600.0 2900.0 3100.0 +1400.0 1600.0 1700.0 2200.0 3100.0 3200.0 +1300.0 1500.0 1700.0 2100.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2700.0 3100.0 3300.0 +1400.0 1700.0 1900.0 2200.0 3000.0 3100.0 +1400.0 1800.0 2000.0 2200.0 3000.0 3100.0 +2100.0 2300.0 2500.0 2700.0 3100.0 3200.0 +1500.0 1900.0 2300.0 2500.0 3000.0 3100.0 +1500.0 1900.0 2200.0 2500.0 2900.0 3100.0 +1500.0 1800.0 2100.0 2500.0 2900.0 3100.0 +1500.0 1700.0 2300.0 2600.0 2800.0 3200.0 +1500.0 1700.0 2300.0 2500.0 3000.0 3100.0 +1400.0 1900.0 2500.0 2700.0 3200.0 3300.0 +1200.0 1500.0 2600.0 2700.0 2900.0 3000.0 +1300.0 1600.0 2500.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2500.0 2600.0 3000.0 3200.0 +1400.0 1700.0 2500.0 2600.0 3000.0 3200.0 +1500.0 1800.0 2500.0 2600.0 3100.0 3200.0 +1400.0 1600.0 2400.0 2600.0 2900.0 3200.0 +1400.0 1600.0 2400.0 2700.0 3000.0 3300.0 +1400.0 1500.0 2200.0 2600.0 2900.0 3200.0 +1300.0 1700.0 2400.0 2600.0 3000.0 3300.0 +1800.0 2000.0 2500.0 2600.0 3100.0 3400.0 +1100.0 1800.0 2500.0 2600.0 3100.0 3200.0 +1100.0 1800.0 2400.0 2500.0 3100.0 3300.0 +1100.0 1800.0 2400.0 2600.0 3100.0 3300.0 +1000.0 1800.0 2500.0 2700.0 3200.0 3300.0 +1100.0 1900.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2000.0 2400.0 2500.0 2900.0 3300.0 +1700.0 1900.0 2300.0 2500.0 3000.0 3300.0 +1300.0 1700.0 2100.0 2300.0 3000.0 3200.0 +1300.0 1600.0 2000.0 2200.0 3000.0 3100.0 +1300.0 1600.0 1900.0 2100.0 3000.0 3100.0 +1500.0 1700.0 2400.0 2600.0 2900.0 3100.0 +1500.0 1900.0 2600.0 2700.0 3100.0 3200.0 +2100.0 2400.0 2900.0 3100.0 3300.0 3400.0 +2000.0 2500.0 2900.0 3100.0 3400.0 3500.0 +2000.0 2500.0 2700.0 3000.0 3300.0 3400.0 +1600.0 1900.0 2600.0 2700.0 3100.0 3300.0 +1600.0 1900.0 2600.0 2700.0 3200.0 3300.0 +1100.0 1500.0 1600.0 2200.0 2900.0 3000.0 +1200.0 1500.0 1600.0 2100.0 3000.0 3100.0 +2300.0 2500.0 2900.0 3100.0 3400.0 3500.0 +1500.0 1900.0 2300.0 2400.0 2900.0 3200.0 +1500.0 2000.0 2500.0 2600.0 3100.0 3300.0 +1500.0 1900.0 2400.0 2800.0 3200.0 3300.0 +1100.0 1800.0 2200.0 2500.0 3100.0 3200.0 +1200.0 1800.0 2200.0 2400.0 3200.0 3300.0 +1300.0 1700.0 2400.0 2500.0 3100.0 3200.0 +1600.0 2100.0 2300.0 2600.0 3100.0 3200.0 +1300.0 1800.0 2100.0 2300.0 3200.0 3300.0 +1200.0 1800.0 2100.0 2300.0 3100.0 3200.0 +2100.0 2200.0 2700.0 2800.0 3300.0 3400.0 +2000.0 2300.0 2600.0 2900.0 3200.0 3400.0 +2100.0 2400.0 2700.0 2800.0 3200.0 3300.0 +1900.0 2200.0 2600.0 2700.0 3100.0 3300.0 +2100.0 2400.0 2600.0 3000.0 3300.0 3400.0 +1400.0 1800.0 2300.0 2400.0 3000.0 3200.0 +1500.0 1700.0 1900.0 2400.0 2900.0 3000.0 +1500.0 1600.0 1800.0 2300.0 3100.0 3200.0 +1500.0 1700.0 1800.0 2300.0 3100.0 3200.0 +2100.0 2500.0 2700.0 3000.0 3400.0 3500.0 +2000.0 2400.0 2700.0 2900.0 3400.0 3500.0 +1400.0 1800.0 1900.0 2600.0 3100.0 3200.0 +1400.0 1800.0 2100.0 2300.0 3200.0 3300.0 +1600.0 1800.0 2300.0 2500.0 3000.0 3100.0 +1400.0 2000.0 2400.0 2700.0 3100.0 3200.0 +1400.0 1900.0 2300.0 2600.0 3100.0 3200.0 +1700.0 1800.0 2500.0 2800.0 3100.0 3300.0 +1400.0 1800.0 2400.0 2500.0 2900.0 3300.0 +1400.0 2000.0 2400.0 2500.0 3100.0 3300.0 +1300.0 1600.0 2400.0 2600.0 3200.0 3300.0 +1900.0 2400.0 2900.0 3100.0 3400.0 3500.0 +2000.0 2400.0 2900.0 3100.0 3400.0 3500.0 +900.0 1800.0 2500.0 2600.0 3200.0 3300.0 +900.0 1800.0 2600.0 2700.0 3200.0 3300.0 +1000.0 1700.0 2800.0 2900.0 3200.0 3300.0 +1500.0 1600.0 2200.0 2600.0 2900.0 3200.0 +1600.0 1800.0 2100.0 2500.0 2800.0 3000.0 +1800.0 1900.0 2400.0 2600.0 2900.0 3100.0 +1900.0 2100.0 2600.0 2900.0 3100.0 3300.0 +1800.0 1900.0 2600.0 2800.0 3000.0 3200.0 +1900.0 2100.0 2500.0 2900.0 3200.0 3400.0 +1300.0 1500.0 2400.0 2700.0 2900.0 3100.0 +1300.0 1600.0 2500.0 2600.0 2900.0 3100.0 +1400.0 1600.0 2400.0 2600.0 2900.0 3100.0 +1600.0 1700.0 2500.0 2800.0 2900.0 3200.0 +1700.0 2000.0 2600.0 3000.0 3300.0 3400.0 +1900.0 2200.0 2700.0 2800.0 3200.0 3400.0 +2000.0 2100.0 2700.0 2800.0 3100.0 3300.0 +2000.0 2100.0 2600.0 2800.0 3100.0 3200.0 +1700.0 2000.0 2500.0 2600.0 3100.0 3300.0 +1900.0 2100.0 2300.0 2500.0 3200.0 3300.0 +1300.0 1900.0 2300.0 2500.0 3200.0 3400.0 +1300.0 1800.0 2300.0 2400.0 3200.0 3400.0 +1300.0 1900.0 2300.0 2500.0 3200.0 3300.0 +2000.0 2300.0 2600.0 2700.0 3000.0 3300.0 +1800.0 2000.0 2300.0 2600.0 3100.0 3300.0 +1400.0 1800.0 2500.0 2700.0 3100.0 3300.0 +1200.0 1500.0 2500.0 2900.0 3100.0 3200.0 +1400.0 1600.0 2500.0 2700.0 2900.0 3100.0 +2100.0 2400.0 2700.0 2800.0 3100.0 3300.0 +1600.0 2100.0 2400.0 2800.0 3100.0 3300.0 +1400.0 1600.0 2100.0 2600.0 3100.0 3200.0 +1300.0 1500.0 2300.0 2600.0 3100.0 3300.0 +2000.0 2200.0 2700.0 2800.0 3200.0 3300.0 +1900.0 2200.0 2700.0 2800.0 3300.0 3400.0 +1800.0 2400.0 2700.0 3000.0 3400.0 3500.0 +1900.0 2400.0 2800.0 3000.0 3400.0 3500.0 +2000.0 2100.0 2600.0 2800.0 3000.0 3300.0 +2100.0 2200.0 2700.0 2800.0 3000.0 3300.0 +1500.0 2000.0 2400.0 2600.0 3100.0 3300.0 +1300.0 2000.0 2200.0 2500.0 3000.0 3100.0 +1800.0 2100.0 2300.0 2500.0 3100.0 3300.0 +1500.0 1800.0 2500.0 2800.0 3200.0 3300.0 +1500.0 1700.0 2100.0 2600.0 3200.0 3300.0 +1700.0 1800.0 2200.0 2600.0 3200.0 3400.0 +1400.0 1700.0 2300.0 2400.0 3200.0 3400.0 +1100.0 1800.0 2300.0 2400.0 3300.0 3400.0 +1000.0 1900.0 2400.0 2500.0 3100.0 3400.0 +1600.0 1800.0 2200.0 2300.0 3100.0 3300.0 +1500.0 1600.0 2300.0 2400.0 3100.0 3300.0 +1500.0 1600.0 2200.0 2300.0 3200.0 3400.0 +1400.0 1800.0 2300.0 2700.0 3000.0 3300.0 +1400.0 1800.0 2100.0 2300.0 2800.0 3200.0 +1400.0 1800.0 2100.0 2500.0 2900.0 3200.0 +1200.0 1600.0 1700.0 2100.0 3000.0 3100.0 +1200.0 1600.0 1900.0 2400.0 3000.0 3200.0 +1100.0 2000.0 2300.0 2500.0 3100.0 3200.0 +1100.0 2000.0 2400.0 2700.0 3100.0 3200.0 +1200.0 1400.0 2400.0 2600.0 2900.0 3200.0 +1300.0 1400.0 2300.0 2400.0 2800.0 3300.0 +1300.0 1500.0 2300.0 2400.0 2900.0 3200.0 +1300.0 1600.0 2400.0 2500.0 2800.0 3200.0 +1300.0 1600.0 2300.0 2500.0 2900.0 3200.0 +1300.0 1500.0 1600.0 2100.0 2800.0 2900.0 +1500.0 1800.0 2500.0 2700.0 3200.0 3400.0 +1400.0 1700.0 2300.0 2500.0 2900.0 3100.0 +1300.0 1700.0 2400.0 2500.0 3000.0 3200.0 +1200.0 1600.0 2500.0 2600.0 3100.0 3400.0 +1100.0 1700.0 2500.0 2600.0 3100.0 3400.0 +1400.0 1800.0 2200.0 2300.0 2600.0 3000.0 +1300.0 1800.0 2200.0 2300.0 2500.0 3000.0 +1400.0 1800.0 2300.0 2700.0 3000.0 3200.0 +1300.0 1500.0 2300.0 2400.0 2900.0 3100.0 +1300.0 1600.0 2400.0 2500.0 3000.0 3200.0 +1200.0 1600.0 2400.0 2600.0 3100.0 3300.0 +1200.0 1500.0 2600.0 2700.0 3100.0 3300.0 +1200.0 1500.0 2500.0 2700.0 2900.0 3200.0 +1400.0 1600.0 2300.0 2500.0 3100.0 3300.0 +1400.0 1600.0 2000.0 2200.0 2900.0 3000.0 +1300.0 1500.0 1800.0 1900.0 2800.0 2900.0 +1200.0 1600.0 1700.0 2200.0 2900.0 3000.0 +1300.0 1700.0 1800.0 2100.0 2900.0 3000.0 +1500.0 1700.0 2100.0 2400.0 2600.0 3100.0 +1500.0 2000.0 2500.0 2600.0 3000.0 3200.0 +1700.0 2000.0 2200.0 2600.0 2900.0 3200.0 +1700.0 2200.0 2600.0 2700.0 3100.0 3300.0 +1600.0 1700.0 2400.0 2500.0 3000.0 3400.0 +1900.0 2000.0 2100.0 2300.0 3300.0 3400.0 +1700.0 1900.0 2400.0 2500.0 3100.0 3300.0 +1500.0 1800.0 2200.0 2300.0 3100.0 3400.0 +1900.0 2300.0 2500.0 3000.0 3300.0 3400.0 +1500.0 1700.0 2100.0 2300.0 3000.0 3300.0 +1700.0 1900.0 2200.0 2400.0 2700.0 3200.0 +1800.0 1900.0 2200.0 2300.0 2700.0 3100.0 +1700.0 1900.0 2100.0 2300.0 2700.0 3100.0 +1700.0 2000.0 2600.0 2800.0 3100.0 3300.0 +1200.0 1800.0 2200.0 2400.0 3000.0 3100.0 +1300.0 1900.0 2200.0 2500.0 3000.0 3100.0 +1500.0 1600.0 2300.0 2500.0 3000.0 3200.0 +1400.0 1500.0 2300.0 2500.0 3000.0 3200.0 +1300.0 1700.0 2100.0 2400.0 3100.0 3200.0 +1500.0 1600.0 2200.0 2500.0 3100.0 3200.0 +1600.0 1700.0 2200.0 2300.0 3100.0 3400.0 +1400.0 1600.0 2100.0 2300.0 2900.0 3000.0 +1400.0 1600.0 2000.0 2200.0 2800.0 2900.0 +1400.0 1800.0 2200.0 2500.0 3100.0 3300.0 +1400.0 1800.0 2100.0 2400.0 3100.0 3300.0 +1400.0 1700.0 2000.0 2400.0 3000.0 3200.0 +1900.0 2100.0 2300.0 2500.0 2800.0 3100.0 +1900.0 2100.0 2300.0 2500.0 2900.0 3100.0 +1400.0 1600.0 2100.0 2400.0 3000.0 3200.0 +1400.0 1600.0 2000.0 2300.0 3000.0 3200.0 +1600.0 2000.0 2200.0 2600.0 2900.0 3200.0 +1600.0 2000.0 2200.0 2600.0 3000.0 3300.0 +1300.0 1900.0 2200.0 2400.0 3000.0 3200.0 +1700.0 2000.0 2300.0 2700.0 3000.0 3300.0 +1000.0 1600.0 2600.0 2700.0 3200.0 3300.0 +1100.0 1700.0 2600.0 2700.0 3200.0 3300.0 +1500.0 1800.0 2300.0 2400.0 3300.0 3400.0 +1900.0 2100.0 2300.0 2500.0 3100.0 3200.0 +1400.0 1700.0 2200.0 2500.0 3300.0 3400.0 +1400.0 1900.0 2200.0 2700.0 3200.0 3300.0 +1400.0 2000.0 2300.0 2700.0 3100.0 3200.0 +1600.0 2100.0 2400.0 2700.0 3000.0 3200.0 +1600.0 1800.0 2100.0 2400.0 3000.0 3200.0 +1700.0 1800.0 2100.0 2400.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2500.0 2900.0 3300.0 +1800.0 1900.0 2200.0 2500.0 2900.0 3300.0 +1800.0 1900.0 2200.0 2500.0 2900.0 3200.0 +1700.0 1900.0 2200.0 2400.0 3000.0 3300.0 +1700.0 1900.0 2200.0 2400.0 2600.0 3000.0 +1500.0 1800.0 2500.0 2600.0 3200.0 3300.0 +1600.0 1700.0 2500.0 2600.0 3000.0 3200.0 +1600.0 1700.0 2400.0 2500.0 3100.0 3200.0 +1600.0 1700.0 2500.0 2600.0 3100.0 3200.0 +1600.0 1800.0 2500.0 2600.0 3100.0 3200.0 +1800.0 1900.0 2500.0 2600.0 3000.0 3200.0 +1900.0 2400.0 2700.0 3000.0 3300.0 3500.0 +1900.0 2400.0 2700.0 3100.0 3300.0 3400.0 +2000.0 2400.0 2600.0 3000.0 3300.0 3400.0 +1800.0 2500.0 2700.0 2900.0 3300.0 3400.0 +1800.0 2400.0 2700.0 2900.0 3400.0 3500.0 +1900.0 2400.0 2700.0 3000.0 3200.0 3300.0 +1600.0 1800.0 2400.0 2500.0 3000.0 3300.0 +1700.0 1800.0 2400.0 2600.0 3200.0 3300.0 +1300.0 1800.0 2000.0 2500.0 3100.0 3200.0 +1500.0 1800.0 2300.0 2400.0 3000.0 3100.0 +2100.0 2500.0 2700.0 2900.0 3100.0 3300.0 +1800.0 2000.0 2200.0 2500.0 2800.0 3100.0 +1400.0 1700.0 1900.0 2300.0 2800.0 2900.0 +1800.0 2000.0 2300.0 2700.0 3000.0 3300.0 +1800.0 1900.0 2300.0 2700.0 3200.0 3300.0 +1700.0 1800.0 2400.0 2800.0 3100.0 3300.0 +1500.0 1700.0 2500.0 2600.0 2900.0 3300.0 +1400.0 1500.0 2300.0 2500.0 2900.0 3300.0 +1500.0 1700.0 2200.0 2500.0 2900.0 3200.0 +1700.0 1900.0 2100.0 2300.0 3100.0 3300.0 +1400.0 1800.0 2200.0 2400.0 2700.0 3100.0 +1300.0 1500.0 1700.0 1900.0 2800.0 3000.0 +1300.0 1500.0 1700.0 1900.0 2900.0 3000.0 +1100.0 1600.0 2300.0 2500.0 3100.0 3200.0 +1000.0 1600.0 2300.0 2500.0 3200.0 3300.0 +1000.0 1700.0 2300.0 2400.0 3200.0 3300.0 +900.0 1700.0 2300.0 2400.0 3200.0 3300.0 +900.0 1800.0 2300.0 2400.0 3200.0 3300.0 +1100.0 1900.0 2200.0 2500.0 3100.0 3200.0 +1200.0 1900.0 2200.0 2400.0 3100.0 3200.0 +1200.0 1700.0 2200.0 2300.0 3100.0 3200.0 +1300.0 1700.0 2200.0 2300.0 3100.0 3200.0 +1400.0 1800.0 2200.0 2300.0 3100.0 3200.0 +1500.0 1700.0 2200.0 2300.0 3000.0 3200.0 +1500.0 1600.0 2200.0 2300.0 2900.0 3200.0 +1600.0 2000.0 2300.0 2400.0 3100.0 3300.0 +1600.0 2100.0 2300.0 2400.0 2700.0 3300.0 +1600.0 1800.0 2100.0 2300.0 2900.0 3000.0 +1400.0 1600.0 1700.0 2300.0 2900.0 3000.0 +1600.0 1800.0 2100.0 2300.0 3000.0 3100.0 +1600.0 1700.0 2000.0 2200.0 3000.0 3100.0 +1500.0 1600.0 2300.0 2400.0 2900.0 3100.0 +1500.0 1600.0 2400.0 2500.0 3000.0 3200.0 +1800.0 2100.0 2600.0 2700.0 3100.0 3200.0 +1500.0 1600.0 1900.0 2300.0 2900.0 3100.0 +1500.0 1700.0 2300.0 2700.0 3100.0 3200.0 +1500.0 2100.0 2500.0 2700.0 3100.0 3300.0 +1000.0 1500.0 2400.0 2500.0 3100.0 3300.0 +1200.0 1400.0 2400.0 2500.0 2900.0 3300.0 +1300.0 1700.0 2200.0 2400.0 2900.0 3000.0 +1200.0 2000.0 2400.0 2500.0 3000.0 3200.0 +1200.0 1900.0 2400.0 2500.0 3100.0 3300.0 +1300.0 1800.0 2400.0 2500.0 3100.0 3400.0 +1500.0 1800.0 2300.0 2400.0 3000.0 3300.0 +1700.0 1800.0 2300.0 2400.0 3000.0 3200.0 +1600.0 1900.0 2100.0 2400.0 2900.0 3200.0 +1400.0 1600.0 2200.0 2400.0 2900.0 3100.0 +1500.0 1700.0 2200.0 2400.0 3000.0 3100.0 +1400.0 1600.0 2300.0 2400.0 3000.0 3200.0 +1400.0 1600.0 2200.0 2300.0 2900.0 3200.0 +1600.0 1700.0 2000.0 2200.0 3000.0 3200.0 +1600.0 1800.0 2100.0 2400.0 2900.0 3200.0 +1600.0 1700.0 2100.0 2300.0 2900.0 3200.0 +1400.0 1600.0 2100.0 2400.0 3200.0 3300.0 +1200.0 1600.0 2100.0 2300.0 3100.0 3200.0 +1600.0 2100.0 2300.0 2500.0 3000.0 3200.0 +1800.0 2100.0 2400.0 2600.0 3100.0 3300.0 +1400.0 1600.0 2300.0 2400.0 2900.0 3200.0 +1400.0 1500.0 2100.0 2400.0 2700.0 3100.0 +1200.0 1400.0 2100.0 2200.0 3000.0 3300.0 +1300.0 1800.0 2200.0 2300.0 2800.0 3200.0 +1300.0 1700.0 2200.0 2300.0 2800.0 3300.0 +1400.0 1800.0 2200.0 2300.0 2800.0 3200.0 +1800.0 2100.0 2500.0 3000.0 3200.0 3400.0 +1700.0 1900.0 2200.0 2500.0 3100.0 3300.0 +1800.0 1900.0 2100.0 2400.0 3200.0 3300.0 +1500.0 1600.0 2200.0 2300.0 3200.0 3300.0 +1400.0 1700.0 2200.0 2300.0 3100.0 3300.0 +1400.0 1900.0 2200.0 2600.0 3100.0 3300.0 +1600.0 1900.0 2500.0 2900.0 3200.0 3300.0 +1400.0 1900.0 2400.0 2700.0 3100.0 3200.0 +1400.0 1600.0 2200.0 2300.0 2900.0 3100.0 +1600.0 1800.0 2200.0 2400.0 3000.0 3100.0 +1800.0 2000.0 2400.0 2900.0 3100.0 3200.0 +1900.0 2000.0 2500.0 2900.0 3100.0 3300.0 +1500.0 1600.0 2100.0 2200.0 3000.0 3300.0 +1500.0 1600.0 2100.0 2300.0 2900.0 3200.0 +1300.0 1500.0 2200.0 2300.0 2800.0 3100.0 +1100.0 1900.0 2500.0 2700.0 3100.0 3200.0 +1300.0 1800.0 2300.0 2700.0 3100.0 3200.0 +1100.0 1700.0 2200.0 2600.0 3000.0 3200.0 +1300.0 1600.0 1900.0 2100.0 3000.0 3200.0 +1300.0 1500.0 1800.0 1900.0 3000.0 3100.0 +1100.0 1400.0 2500.0 2600.0 3000.0 3300.0 +1300.0 1500.0 2400.0 2600.0 2900.0 3300.0 +1700.0 1900.0 2300.0 2400.0 3000.0 3300.0 +1600.0 1800.0 2100.0 2400.0 2800.0 3100.0 +1500.0 1700.0 2000.0 2500.0 2800.0 3000.0 +1400.0 1700.0 2200.0 2500.0 2900.0 3100.0 +1300.0 1500.0 2300.0 2600.0 3000.0 3300.0 +1000.0 1600.0 2200.0 2500.0 3000.0 3100.0 +1000.0 1500.0 2500.0 2600.0 3100.0 3300.0 +1000.0 1600.0 2500.0 2600.0 3200.0 3300.0 +1000.0 1700.0 2600.0 2700.0 3200.0 3300.0 +2000.0 2400.0 2800.0 3000.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2700.0 3100.0 3200.0 +1800.0 1900.0 2400.0 2700.0 3000.0 3300.0 +1700.0 2100.0 2300.0 2500.0 3000.0 3200.0 +1200.0 1400.0 1500.0 2100.0 3100.0 3200.0 +1400.0 1600.0 1700.0 2200.0 3000.0 3200.0 +1600.0 1800.0 1900.0 2200.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2300.0 3000.0 3200.0 +1900.0 2000.0 2400.0 2500.0 3000.0 3300.0 +1800.0 1900.0 2400.0 2500.0 2900.0 3300.0 +1800.0 1900.0 2300.0 2500.0 3100.0 3400.0 +1800.0 2000.0 2400.0 2600.0 3200.0 3400.0 +1400.0 1600.0 2100.0 2200.0 3100.0 3400.0 +1500.0 1700.0 1900.0 2500.0 3000.0 3200.0 +1300.0 1400.0 2200.0 2500.0 2900.0 3200.0 +1300.0 1700.0 2100.0 2600.0 3100.0 3300.0 +1900.0 2100.0 2400.0 2700.0 3200.0 3400.0 +1700.0 2000.0 2300.0 2500.0 3000.0 3300.0 +1600.0 1700.0 2100.0 2600.0 3000.0 3200.0 +1400.0 1600.0 1700.0 2000.0 3000.0 3100.0 +1300.0 1500.0 1600.0 2000.0 3000.0 3100.0 +1400.0 1600.0 2100.0 2200.0 2700.0 3200.0 +1300.0 1600.0 1700.0 2300.0 3100.0 3300.0 +1500.0 1700.0 2200.0 2500.0 3100.0 3200.0 +2100.0 2200.0 2600.0 2900.0 3200.0 3400.0 +2100.0 2300.0 2700.0 3000.0 3300.0 3400.0 +1900.0 2300.0 2800.0 3100.0 3300.0 3500.0 +1900.0 2300.0 2700.0 3100.0 3400.0 3500.0 +1900.0 2300.0 2700.0 3100.0 3300.0 3400.0 +1400.0 1800.0 2200.0 2300.0 2900.0 3200.0 +1400.0 1600.0 2100.0 2300.0 2800.0 3300.0 +1300.0 1700.0 2200.0 2300.0 2800.0 3200.0 +1300.0 1600.0 2200.0 2300.0 2900.0 3300.0 +1400.0 1800.0 2200.0 2600.0 3100.0 3300.0 +1700.0 2100.0 2400.0 2700.0 3000.0 3200.0 +1300.0 1800.0 2200.0 2500.0 3000.0 3300.0 +1900.0 2000.0 2500.0 2600.0 2900.0 3300.0 +2100.0 2200.0 2400.0 2600.0 2900.0 3200.0 +2100.0 2200.0 2400.0 2600.0 3000.0 3200.0 +2000.0 2100.0 2400.0 2500.0 3000.0 3200.0 +1800.0 2000.0 2200.0 2400.0 3100.0 3200.0 +1400.0 2000.0 2300.0 2400.0 3000.0 3100.0 +1300.0 1600.0 2100.0 2300.0 2700.0 3200.0 +1200.0 1800.0 2200.0 2400.0 3200.0 3400.0 +1200.0 1800.0 2300.0 2400.0 3200.0 3400.0 +1200.0 1900.0 2300.0 2400.0 3100.0 3400.0 +1700.0 1800.0 2100.0 2300.0 2800.0 3200.0 +1500.0 1600.0 2200.0 2300.0 2900.0 3300.0 +1500.0 1600.0 2100.0 2300.0 2800.0 3200.0 +1500.0 1600.0 2000.0 2200.0 2700.0 3200.0 +1400.0 1900.0 2200.0 2600.0 3200.0 3300.0 +1400.0 1600.0 2100.0 2200.0 2800.0 3200.0 +1900.0 2100.0 2300.0 2600.0 3100.0 3300.0 +2000.0 2300.0 2600.0 2800.0 3200.0 3400.0 +1700.0 1800.0 2300.0 2500.0 2700.0 3200.0 +1700.0 1800.0 2300.0 2500.0 2700.0 3100.0 +1800.0 1900.0 2400.0 2500.0 2700.0 3100.0 +1700.0 1800.0 2400.0 2500.0 2800.0 3200.0 +1600.0 1800.0 2500.0 2600.0 2900.0 3100.0 +1500.0 1800.0 2500.0 2600.0 3200.0 3400.0 +1400.0 1500.0 2100.0 2300.0 2900.0 3300.0 +1400.0 1600.0 2100.0 2300.0 3000.0 3300.0 +1600.0 1700.0 2200.0 2500.0 3100.0 3400.0 +1600.0 2000.0 2200.0 2400.0 2900.0 3100.0 +2000.0 2200.0 2600.0 2900.0 3200.0 3400.0 +1200.0 1400.0 2200.0 2300.0 3100.0 3300.0 +1300.0 1500.0 2200.0 2300.0 3100.0 3300.0 +1700.0 1800.0 2200.0 2300.0 3100.0 3400.0 +1800.0 1900.0 2200.0 2300.0 2900.0 3300.0 +1800.0 2000.0 2400.0 2700.0 3100.0 3400.0 +1600.0 1700.0 2000.0 2100.0 2700.0 3100.0 +1700.0 1900.0 2200.0 2300.0 2900.0 3200.0 +2200.0 2500.0 2700.0 2800.0 3100.0 3300.0 +1600.0 1700.0 2200.0 2300.0 2900.0 3100.0 +1400.0 1500.0 1600.0 2000.0 3000.0 3200.0 +1500.0 1700.0 1900.0 2400.0 3000.0 3200.0 +1900.0 2200.0 2500.0 2900.0 3200.0 3300.0 +1900.0 2400.0 2600.0 2900.0 3300.0 3400.0 +1800.0 2100.0 2200.0 2400.0 3000.0 3300.0 +1400.0 1600.0 1700.0 2300.0 3200.0 3300.0 +1400.0 1600.0 1900.0 2500.0 3200.0 3300.0 +1700.0 2100.0 2700.0 3000.0 3300.0 3400.0 +1400.0 1800.0 2300.0 2700.0 3100.0 3200.0 +1400.0 1600.0 2300.0 2700.0 3000.0 3200.0 +1400.0 2000.0 2200.0 2500.0 3100.0 3300.0 +1600.0 2100.0 2400.0 2900.0 3200.0 3400.0 +1400.0 1600.0 1800.0 2600.0 3300.0 3400.0 +1400.0 1500.0 1700.0 2200.0 3200.0 3300.0 +1400.0 1500.0 1700.0 2100.0 3100.0 3200.0 +1300.0 1500.0 2200.0 2400.0 2800.0 3100.0 +1300.0 1600.0 1800.0 2400.0 3000.0 3100.0 +1400.0 1600.0 2000.0 2200.0 3000.0 3300.0 +1500.0 1600.0 2100.0 2400.0 3100.0 3300.0 +1500.0 1700.0 2100.0 2300.0 2700.0 3100.0 +1500.0 1600.0 2000.0 2200.0 2600.0 3100.0 +1400.0 1500.0 2000.0 2300.0 3100.0 3300.0 +1400.0 1500.0 2000.0 2200.0 3100.0 3300.0 +1600.0 1800.0 2200.0 2300.0 3000.0 3200.0 +1400.0 1700.0 2100.0 2500.0 2900.0 3100.0 +1400.0 1800.0 2200.0 2400.0 2900.0 3000.0 +1500.0 1800.0 2300.0 2500.0 3000.0 3200.0 +2000.0 2300.0 2800.0 3100.0 3400.0 3500.0 +2000.0 2500.0 2800.0 2900.0 3200.0 3300.0 +1400.0 2000.0 2300.0 2600.0 3000.0 3300.0 +1600.0 1900.0 2300.0 2700.0 3200.0 3400.0 +2000.0 2400.0 2800.0 2900.0 3300.0 3400.0 +1200.0 1400.0 2000.0 2200.0 3200.0 3400.0 +1200.0 1600.0 2400.0 2500.0 2900.0 3200.0 +1500.0 1600.0 2300.0 2400.0 2800.0 3200.0 +1100.0 1600.0 2200.0 2300.0 3300.0 3400.0 +1300.0 1600.0 2200.0 2400.0 3000.0 3300.0 +1300.0 1600.0 2200.0 2400.0 2700.0 3200.0 +1400.0 1700.0 2300.0 2500.0 2700.0 3100.0 +1500.0 1700.0 2400.0 2500.0 2800.0 3100.0 +1800.0 2000.0 2200.0 2300.0 3000.0 3200.0 +1700.0 1900.0 2300.0 2400.0 2900.0 3200.0 +1700.0 1900.0 2200.0 2400.0 2900.0 3300.0 +1300.0 1700.0 2200.0 2300.0 3200.0 3400.0 +1500.0 1600.0 2300.0 2400.0 3000.0 3400.0 +1600.0 1900.0 2400.0 2800.0 3200.0 3400.0 +1500.0 1600.0 2300.0 2400.0 2900.0 3300.0 +1600.0 1700.0 2300.0 2400.0 2800.0 3300.0 +1800.0 2000.0 2200.0 2500.0 3000.0 3300.0 +1900.0 2000.0 2300.0 2500.0 2800.0 3100.0 +1600.0 1700.0 2400.0 2600.0 3100.0 3400.0 +1600.0 1800.0 2400.0 2700.0 3200.0 3300.0 +1600.0 1900.0 2400.0 2700.0 3200.0 3400.0 +1500.0 1800.0 2200.0 2500.0 3200.0 3400.0 +1200.0 1800.0 2300.0 2600.0 3100.0 3300.0 +1900.0 2000.0 2400.0 2600.0 3100.0 3400.0 +1700.0 1800.0 2400.0 2500.0 3000.0 3400.0 +1400.0 2000.0 2300.0 2400.0 2600.0 3100.0 +1800.0 1900.0 2100.0 2200.0 3300.0 3400.0 +1400.0 1600.0 1700.0 2300.0 3300.0 3400.0 +1400.0 1600.0 1700.0 2200.0 3300.0 3400.0 +1400.0 1600.0 1700.0 2300.0 3200.0 3400.0 +1600.0 1800.0 2000.0 2300.0 2900.0 3100.0 +1700.0 1800.0 2000.0 2300.0 2900.0 3100.0 +1600.0 1800.0 2100.0 2300.0 2800.0 3100.0 +1500.0 1700.0 2100.0 2300.0 2800.0 3100.0 +1500.0 1600.0 2100.0 2300.0 2700.0 3100.0 +1500.0 1600.0 2100.0 2200.0 2700.0 3100.0 +1400.0 1800.0 2300.0 2400.0 2800.0 3100.0 +1400.0 1600.0 2300.0 2400.0 2900.0 3300.0 +1200.0 1700.0 2200.0 2300.0 2900.0 3200.0 +1400.0 1500.0 2100.0 2400.0 3200.0 3400.0 +1700.0 2100.0 2400.0 2500.0 2900.0 3100.0 +1500.0 1700.0 2000.0 2400.0 3000.0 3200.0 +1400.0 1900.0 2200.0 2600.0 3000.0 3200.0 +1600.0 1800.0 2200.0 2700.0 3000.0 3100.0 +1600.0 1800.0 2100.0 2500.0 2800.0 3100.0 +2000.0 2300.0 2500.0 2800.0 3000.0 3100.0 +1900.0 2400.0 2700.0 2800.0 3100.0 3200.0 +1800.0 2300.0 2700.0 2800.0 3100.0 3200.0 +1700.0 2400.0 2700.0 2800.0 3200.0 3300.0 +1700.0 2400.0 2700.0 2800.0 3100.0 3200.0 +1600.0 2400.0 2700.0 2800.0 3100.0 3200.0 +1600.0 2000.0 2200.0 2700.0 3100.0 3200.0 +1800.0 2200.0 2600.0 2800.0 3100.0 3400.0 +1800.0 2200.0 2600.0 3000.0 3200.0 3400.0 +1800.0 2200.0 2300.0 2700.0 3200.0 3300.0 +1600.0 2100.0 2300.0 2600.0 3200.0 3300.0 +1700.0 1900.0 2200.0 2600.0 3000.0 3100.0 +1600.0 1800.0 2200.0 2500.0 2800.0 3000.0 +2000.0 2400.0 2800.0 3100.0 3200.0 3300.0 +1500.0 1700.0 1900.0 2000.0 2600.0 3100.0 +1400.0 1600.0 1900.0 2000.0 2500.0 3100.0 +1400.0 1600.0 1800.0 2000.0 2500.0 3100.0 +1400.0 1500.0 1800.0 1900.0 2500.0 3100.0 +1400.0 1500.0 1800.0 1900.0 2600.0 3200.0 +1400.0 1500.0 1700.0 2000.0 2900.0 3200.0 +1300.0 1700.0 2100.0 2600.0 3100.0 3200.0 +1200.0 1700.0 2200.0 2500.0 3100.0 3200.0 +1800.0 2000.0 2500.0 2600.0 3000.0 3200.0 +1700.0 1900.0 2200.0 2700.0 2900.0 3200.0 +1500.0 1700.0 2100.0 2600.0 3000.0 3200.0 +1600.0 1800.0 2200.0 2400.0 2700.0 3100.0 +1600.0 1900.0 2200.0 2600.0 2800.0 3100.0 +1600.0 1800.0 2100.0 2500.0 3000.0 3100.0 +1600.0 1800.0 2000.0 2200.0 2600.0 3100.0 +1200.0 1400.0 2300.0 2700.0 2800.0 3100.0 +1300.0 1600.0 2100.0 2600.0 3100.0 3300.0 +1400.0 1600.0 2100.0 2500.0 2700.0 3000.0 +1300.0 1600.0 2300.0 2600.0 3000.0 3300.0 +1300.0 1700.0 2300.0 2700.0 3000.0 3300.0 +1400.0 1600.0 2000.0 2500.0 2800.0 3000.0 +1800.0 2000.0 2200.0 2600.0 2800.0 3100.0 +1800.0 1900.0 2400.0 2600.0 2800.0 3100.0 +1500.0 1700.0 2200.0 2700.0 2900.0 3100.0 +1400.0 1700.0 2300.0 2700.0 3000.0 3100.0 +1700.0 2200.0 2500.0 2900.0 3200.0 3300.0 +1500.0 1700.0 2100.0 2700.0 3000.0 3200.0 +1700.0 2000.0 2600.0 2700.0 3100.0 3200.0 +1500.0 1700.0 1900.0 2500.0 3100.0 3200.0 +1500.0 2000.0 2200.0 2600.0 3000.0 3100.0 +1500.0 1800.0 2000.0 2800.0 3200.0 3300.0 +1700.0 1900.0 2500.0 2600.0 2900.0 3200.0 +1800.0 2000.0 2400.0 2600.0 3000.0 3100.0 +1400.0 1700.0 2100.0 2500.0 2700.0 3000.0 +1500.0 1900.0 2200.0 2400.0 2800.0 3200.0 +1300.0 1500.0 2100.0 2400.0 3100.0 3300.0 +1200.0 1600.0 2200.0 2500.0 3200.0 3300.0 +1300.0 1800.0 2300.0 2600.0 3200.0 3300.0 +1300.0 1900.0 2200.0 2400.0 3100.0 3200.0 +1300.0 1800.0 2200.0 2400.0 3000.0 3100.0 +1500.0 1700.0 2100.0 2700.0 3100.0 3200.0 +1500.0 1700.0 2100.0 2800.0 3100.0 3200.0 +1700.0 2000.0 2200.0 2500.0 3100.0 3200.0 +1800.0 1900.0 2100.0 2300.0 2600.0 3100.0 +1500.0 1600.0 1800.0 2000.0 2500.0 3100.0 +1700.0 2000.0 2200.0 2400.0 3100.0 3300.0 +1600.0 1800.0 2000.0 2400.0 2900.0 3200.0 +1400.0 1500.0 1700.0 1900.0 3000.0 3200.0 +1600.0 1700.0 2000.0 2600.0 3000.0 3200.0 +1700.0 1900.0 2100.0 2500.0 3100.0 3200.0 +1700.0 2200.0 2600.0 2800.0 3100.0 3200.0 +1600.0 2200.0 2500.0 2700.0 3000.0 3100.0 +1700.0 2000.0 2200.0 2500.0 3000.0 3100.0 +1600.0 2000.0 2500.0 2800.0 3100.0 3300.0 +1700.0 2100.0 2400.0 2900.0 3200.0 3300.0 +1800.0 2000.0 2400.0 2700.0 3000.0 3100.0 +1800.0 2000.0 2500.0 2700.0 3000.0 3100.0 +1600.0 1900.0 2300.0 2600.0 3000.0 3100.0 +1500.0 1900.0 2100.0 2500.0 3000.0 3200.0 +1900.0 2300.0 2500.0 2600.0 2900.0 3100.0 +2000.0 2200.0 2500.0 2800.0 3300.0 3400.0 +2100.0 2300.0 2600.0 2800.0 3200.0 3400.0 +2200.0 2400.0 2800.0 2900.0 3200.0 3300.0 +2100.0 2500.0 2700.0 2900.0 3200.0 3300.0 +1800.0 2300.0 2500.0 2700.0 3100.0 3200.0 +1800.0 2300.0 2500.0 2700.0 3000.0 3200.0 +1400.0 1800.0 2500.0 2700.0 3200.0 3300.0 +1400.0 1600.0 2500.0 2700.0 3200.0 3300.0 +1400.0 1700.0 2200.0 2700.0 3100.0 3300.0 +1500.0 1700.0 2200.0 2700.0 3000.0 3200.0 +1500.0 1700.0 2100.0 2700.0 2900.0 3100.0 +1800.0 2300.0 2600.0 2700.0 3200.0 3300.0 +1800.0 2400.0 2700.0 2800.0 3300.0 3400.0 +1800.0 2500.0 2700.0 2900.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2400.0 2800.0 3000.0 +1600.0 1800.0 2200.0 2400.0 2800.0 3100.0 +1900.0 2000.0 2200.0 2700.0 3000.0 3100.0 +1900.0 2000.0 2300.0 2700.0 3100.0 3300.0 +2000.0 2200.0 2500.0 2600.0 2900.0 3100.0 +1400.0 1900.0 2400.0 2700.0 3000.0 3300.0 +1500.0 1900.0 2300.0 2700.0 3000.0 3300.0 +1300.0 1800.0 2100.0 2400.0 3100.0 3200.0 +1500.0 1800.0 2200.0 2500.0 2700.0 3100.0 +1600.0 2000.0 2200.0 2600.0 2900.0 3100.0 +1700.0 2100.0 2700.0 3000.0 3200.0 3300.0 +1600.0 1800.0 2600.0 2800.0 3200.0 3300.0 +1200.0 1600.0 2200.0 2600.0 3000.0 3300.0 +1800.0 2300.0 2600.0 2800.0 3100.0 3200.0 +1800.0 2400.0 2700.0 2800.0 3100.0 3200.0 +1700.0 2300.0 2700.0 2800.0 3100.0 3200.0 +1900.0 2200.0 2700.0 2900.0 3100.0 3300.0 +1600.0 2200.0 2500.0 2700.0 3000.0 3200.0 +1600.0 2000.0 2500.0 2700.0 3000.0 3100.0 +1800.0 2200.0 2500.0 2600.0 3100.0 3200.0 +1800.0 2500.0 2700.0 2800.0 3200.0 3300.0 +1700.0 2300.0 2600.0 2700.0 3100.0 3200.0 +1400.0 1600.0 2000.0 2500.0 2900.0 3100.0 +1700.0 2000.0 2300.0 2600.0 3200.0 3300.0 +1200.0 1400.0 1700.0 1800.0 2700.0 3200.0 +1500.0 1700.0 2000.0 2400.0 2700.0 3000.0 +1600.0 1800.0 2300.0 2400.0 2800.0 3100.0 +1800.0 2000.0 2400.0 2500.0 2900.0 3100.0 +1700.0 2000.0 2400.0 2600.0 2900.0 3000.0 +1500.0 1900.0 2300.0 2600.0 2900.0 3100.0 +1500.0 1900.0 2200.0 2600.0 2900.0 3100.0 +1500.0 1900.0 2100.0 2400.0 2900.0 3100.0 +1700.0 2300.0 2500.0 2800.0 3100.0 3200.0 +1600.0 2400.0 2700.0 2800.0 3200.0 3300.0 +1500.0 2400.0 2800.0 2900.0 3200.0 3300.0 +1200.0 1700.0 2300.0 2400.0 3000.0 3200.0 +1300.0 1900.0 2400.0 2600.0 3200.0 3300.0 +1500.0 2100.0 2300.0 2700.0 3100.0 3300.0 +1700.0 2200.0 2500.0 2700.0 3100.0 3300.0 +1400.0 1600.0 2000.0 2500.0 3000.0 3300.0 +1600.0 2000.0 2400.0 2500.0 3100.0 3300.0 +1400.0 1900.0 2300.0 2500.0 3200.0 3400.0 +1100.0 2100.0 2300.0 2600.0 3200.0 3300.0 +1100.0 2200.0 2400.0 2700.0 3200.0 3300.0 +1200.0 2000.0 2300.0 2600.0 3100.0 3200.0 +1400.0 1900.0 2200.0 2500.0 3100.0 3200.0 +1500.0 1700.0 1900.0 2500.0 2900.0 3000.0 +1500.0 1900.0 2200.0 2400.0 2600.0 3100.0 +1800.0 2000.0 2500.0 2600.0 2900.0 3200.0 +2000.0 2100.0 2500.0 2700.0 3100.0 3300.0 +1800.0 2100.0 2400.0 2600.0 3000.0 3400.0 +1600.0 1800.0 2200.0 2400.0 3300.0 3400.0 +1400.0 1800.0 2200.0 2400.0 3200.0 3300.0 +1600.0 1900.0 2200.0 2700.0 3200.0 3300.0 +1500.0 1900.0 2300.0 2400.0 3000.0 3200.0 +1500.0 1900.0 2300.0 2500.0 2900.0 3200.0 +2200.0 2500.0 2900.0 3000.0 3300.0 3400.0 +1500.0 1800.0 2400.0 2700.0 3300.0 3400.0 +1400.0 1800.0 2100.0 2700.0 3100.0 3200.0 +1400.0 1600.0 2000.0 2700.0 3100.0 3200.0 +1900.0 2000.0 2300.0 2800.0 3100.0 3200.0 +2100.0 2200.0 2400.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2400.0 2500.0 2900.0 3100.0 +1800.0 1900.0 2200.0 2700.0 3200.0 3300.0 +1800.0 2200.0 2800.0 3000.0 3300.0 3500.0 +1800.0 2300.0 2600.0 2900.0 3300.0 3500.0 +2100.0 2400.0 2700.0 3000.0 3300.0 3500.0 +1600.0 1800.0 2200.0 2400.0 2900.0 3300.0 +1500.0 1900.0 2500.0 2600.0 2900.0 3100.0 +1600.0 2100.0 2400.0 2600.0 2800.0 3100.0 +1500.0 1600.0 2100.0 2400.0 2900.0 3300.0 +1500.0 1700.0 2200.0 2400.0 2900.0 3300.0 +1400.0 1500.0 2300.0 2500.0 3200.0 3300.0 +1400.0 1700.0 2400.0 2600.0 3200.0 3300.0 +1800.0 2000.0 2400.0 2500.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2400.0 2900.0 3200.0 +1700.0 2400.0 2600.0 2900.0 3300.0 3400.0 +1600.0 1700.0 2100.0 2300.0 2700.0 3200.0 +1800.0 2300.0 2600.0 2900.0 3100.0 3300.0 +1800.0 2400.0 2600.0 2900.0 3300.0 3400.0 +1900.0 2300.0 2700.0 2900.0 3200.0 3400.0 +1400.0 1800.0 2200.0 2500.0 3300.0 3400.0 +1300.0 1900.0 2300.0 2700.0 3100.0 3300.0 +1500.0 1800.0 2300.0 2600.0 3200.0 3300.0 +1800.0 2000.0 2400.0 2500.0 3000.0 3300.0 +1900.0 2300.0 2600.0 2700.0 3200.0 3300.0 +1900.0 2100.0 2700.0 2900.0 3100.0 3300.0 +1600.0 1800.0 2000.0 2500.0 2900.0 3000.0 +1800.0 2100.0 2400.0 2500.0 2900.0 3100.0 +1500.0 1700.0 2400.0 2500.0 2700.0 3000.0 +1400.0 1600.0 2200.0 2500.0 2600.0 3000.0 +1300.0 2100.0 2300.0 2800.0 3100.0 3200.0 +1300.0 2100.0 2200.0 2700.0 3100.0 3200.0 +1500.0 2000.0 2300.0 2500.0 3000.0 3100.0 +1900.0 2000.0 2300.0 2400.0 2800.0 3200.0 +1900.0 2000.0 2300.0 2500.0 2900.0 3300.0 +1600.0 1900.0 2500.0 2800.0 3100.0 3200.0 +1400.0 2000.0 2400.0 2600.0 3000.0 3100.0 +1200.0 1900.0 2000.0 2400.0 3100.0 3200.0 +1300.0 1600.0 1700.0 2000.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2600.0 2900.0 3000.0 +1700.0 1900.0 2300.0 2600.0 3000.0 3100.0 +1800.0 2200.0 2800.0 3000.0 3200.0 3400.0 +2000.0 2300.0 2900.0 3100.0 3300.0 3400.0 +1500.0 2000.0 2300.0 2700.0 3300.0 3400.0 +1200.0 1700.0 2300.0 2500.0 3100.0 3300.0 +1300.0 1800.0 2200.0 2600.0 3200.0 3300.0 +1200.0 2000.0 2200.0 2600.0 3100.0 3200.0 +2000.0 2300.0 2500.0 2900.0 3200.0 3300.0 +2200.0 2300.0 2700.0 3000.0 3200.0 3300.0 +1500.0 2000.0 2300.0 2500.0 2800.0 3000.0 +1200.0 1800.0 2300.0 2400.0 3200.0 3300.0 +1200.0 1800.0 2200.0 2300.0 3200.0 3300.0 +1200.0 1900.0 2300.0 2400.0 3100.0 3200.0 +1600.0 2100.0 2500.0 2700.0 3200.0 3300.0 +1500.0 1700.0 1900.0 2400.0 2800.0 3000.0 +1500.0 1700.0 1900.0 2500.0 2800.0 3000.0 +1500.0 1800.0 2100.0 2700.0 3000.0 3200.0 +2000.0 2200.0 2700.0 3000.0 3300.0 3400.0 +2100.0 2400.0 2800.0 3000.0 3400.0 3500.0 +2000.0 2200.0 2700.0 2900.0 3200.0 3300.0 +2100.0 2500.0 2800.0 3000.0 3400.0 3500.0 +2000.0 2300.0 2600.0 2700.0 3200.0 3300.0 +1900.0 2300.0 2600.0 2700.0 3200.0 3400.0 +1500.0 1800.0 2300.0 2600.0 3000.0 3300.0 +1400.0 1900.0 2400.0 2500.0 2700.0 3000.0 +2200.0 2300.0 2700.0 2900.0 3200.0 3300.0 +2100.0 2300.0 2700.0 2800.0 3200.0 3300.0 +2000.0 2300.0 2500.0 2700.0 3300.0 3400.0 +2300.0 2500.0 2800.0 3100.0 3400.0 3500.0 +2200.0 2600.0 2800.0 3100.0 3300.0 3400.0 +2200.0 2600.0 2700.0 3000.0 3300.0 3400.0 +1900.0 2200.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2000.0 2400.0 2600.0 2900.0 3100.0 +1700.0 1800.0 2300.0 2500.0 2700.0 3000.0 +1500.0 1800.0 2200.0 2400.0 2800.0 3200.0 +1300.0 2100.0 2400.0 2700.0 3300.0 3400.0 +1200.0 1900.0 2400.0 2600.0 3100.0 3300.0 +1200.0 1500.0 2400.0 2500.0 3100.0 3400.0 +1400.0 1500.0 2400.0 2600.0 3000.0 3400.0 +1500.0 1600.0 2500.0 2600.0 3100.0 3400.0 +1600.0 2100.0 2400.0 2500.0 3100.0 3300.0 +1600.0 2200.0 2400.0 2600.0 3100.0 3300.0 +1800.0 2300.0 2600.0 2900.0 3200.0 3400.0 +2100.0 2200.0 2500.0 2700.0 2900.0 3200.0 +1700.0 2000.0 2300.0 2400.0 2700.0 3000.0 +2000.0 2200.0 2400.0 2700.0 3300.0 3400.0 +1500.0 2000.0 2300.0 2500.0 3300.0 3400.0 +1200.0 1700.0 2200.0 2400.0 3300.0 3400.0 +1400.0 1900.0 2000.0 2600.0 3200.0 3300.0 +1800.0 2000.0 2200.0 2600.0 3200.0 3300.0 +1200.0 2100.0 2300.0 2600.0 3300.0 3400.0 +1100.0 2100.0 2300.0 2600.0 3300.0 3400.0 +1900.0 2100.0 2600.0 2700.0 3100.0 3300.0 +1200.0 1600.0 2100.0 2400.0 3000.0 3300.0 +1200.0 1700.0 2100.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2100.0 2300.0 2600.0 3000.0 +1900.0 2200.0 2300.0 2700.0 3200.0 3300.0 +1900.0 2000.0 2400.0 2500.0 2900.0 3200.0 +1500.0 1900.0 2100.0 2500.0 2900.0 3100.0 +1300.0 1900.0 2100.0 2400.0 3000.0 3100.0 +1800.0 2400.0 2800.0 3000.0 3400.0 3500.0 +1600.0 2000.0 2300.0 2800.0 3200.0 3300.0 +1500.0 1700.0 2200.0 2400.0 3000.0 3300.0 +1400.0 2100.0 2300.0 2500.0 3200.0 3400.0 +1700.0 2000.0 2500.0 2700.0 3000.0 3300.0 +1800.0 1900.0 2500.0 2700.0 3200.0 3300.0 +1400.0 1700.0 1900.0 2800.0 3100.0 3200.0 +1300.0 1600.0 1800.0 2600.0 3100.0 3200.0 +1300.0 1500.0 1600.0 2400.0 3100.0 3200.0 +1400.0 1600.0 1700.0 2200.0 3000.0 3100.0 +1700.0 1800.0 2200.0 2500.0 2900.0 3200.0 +1500.0 1900.0 2100.0 2400.0 3200.0 3300.0 +1800.0 2000.0 2100.0 2500.0 3200.0 3300.0 +1400.0 2000.0 2400.0 2500.0 3100.0 3200.0 +1200.0 1800.0 2500.0 2600.0 3100.0 3300.0 +1100.0 1800.0 2300.0 2600.0 3100.0 3300.0 +1400.0 1700.0 2300.0 2600.0 3100.0 3200.0 +1400.0 1600.0 2300.0 2600.0 3100.0 3200.0 +1500.0 1800.0 2500.0 2700.0 3100.0 3300.0 +1500.0 1900.0 2500.0 2700.0 3000.0 3200.0 +1600.0 1900.0 2500.0 2800.0 3200.0 3400.0 +1600.0 1700.0 2400.0 2700.0 2900.0 3200.0 +1500.0 1600.0 2100.0 2600.0 2800.0 3100.0 +1300.0 1500.0 1700.0 1900.0 3000.0 3100.0 +1400.0 1500.0 2200.0 2400.0 3100.0 3300.0 +1100.0 1400.0 2200.0 2500.0 3200.0 3300.0 +1200.0 1500.0 1700.0 1900.0 3200.0 3300.0 +1500.0 1700.0 2300.0 2700.0 3000.0 3300.0 +1900.0 2200.0 2700.0 2800.0 3100.0 3400.0 +1900.0 2200.0 2700.0 2900.0 3300.0 3500.0 +1400.0 1900.0 2300.0 2400.0 3000.0 3200.0 +1500.0 1600.0 2300.0 2600.0 2900.0 3200.0 +1800.0 2100.0 2700.0 2800.0 3200.0 3300.0 +1500.0 1700.0 2400.0 2800.0 3100.0 3300.0 +1700.0 1900.0 2700.0 2800.0 3300.0 3400.0 +1700.0 2100.0 2600.0 2800.0 3100.0 3400.0 +1700.0 2200.0 2700.0 2900.0 3200.0 3400.0 +1900.0 2100.0 2400.0 2800.0 3200.0 3400.0 +1800.0 2100.0 2300.0 2600.0 3000.0 3300.0 +1800.0 2000.0 2200.0 2500.0 3100.0 3300.0 +1400.0 1600.0 2300.0 2400.0 3200.0 3300.0 +1600.0 1800.0 2300.0 2400.0 2900.0 3100.0 +1800.0 2200.0 2700.0 2800.0 3100.0 3300.0 +1800.0 2100.0 2700.0 2800.0 3000.0 3300.0 +1800.0 2100.0 2700.0 2800.0 3100.0 3300.0 +1500.0 1900.0 2200.0 2500.0 3200.0 3300.0 +1200.0 1800.0 2200.0 2400.0 3100.0 3300.0 +1000.0 1400.0 2300.0 2400.0 3200.0 3300.0 +1100.0 1500.0 2200.0 2400.0 3200.0 3300.0 +1200.0 1500.0 2100.0 2200.0 3200.0 3300.0 +1900.0 2000.0 2300.0 2600.0 3200.0 3400.0 +1100.0 1500.0 2100.0 2200.0 3200.0 3300.0 +1500.0 2000.0 2600.0 2800.0 3200.0 3400.0 +1400.0 1600.0 2500.0 2800.0 3000.0 3300.0 +1500.0 1600.0 2500.0 2700.0 3100.0 3300.0 +1400.0 1700.0 2600.0 2800.0 3000.0 3300.0 +1100.0 1900.0 2200.0 2400.0 3100.0 3300.0 +1000.0 1800.0 2200.0 2400.0 3200.0 3300.0 +1000.0 1900.0 2200.0 2400.0 3200.0 3300.0 +1300.0 1600.0 1800.0 2000.0 3200.0 3300.0 +1300.0 1500.0 1800.0 1900.0 3200.0 3300.0 +1500.0 1700.0 2100.0 2500.0 3000.0 3300.0 +1700.0 1800.0 2400.0 2600.0 3100.0 3400.0 +1500.0 1600.0 2100.0 2600.0 2800.0 3200.0 +1500.0 1600.0 2200.0 2600.0 2800.0 3000.0 +1600.0 1700.0 2100.0 2500.0 2900.0 3100.0 +1500.0 1600.0 2100.0 2500.0 2800.0 3200.0 +1500.0 1600.0 2100.0 2500.0 2700.0 3100.0 +1500.0 1600.0 2100.0 2400.0 2800.0 3100.0 +1500.0 1700.0 2200.0 2400.0 2800.0 3100.0 +2000.0 2300.0 2600.0 2700.0 3200.0 3400.0 +1600.0 1800.0 2100.0 2600.0 3100.0 3300.0 +1600.0 1700.0 2200.0 2700.0 3100.0 3300.0 +1300.0 1800.0 2400.0 2600.0 3100.0 3300.0 +1300.0 1500.0 2400.0 2700.0 3000.0 3300.0 +1500.0 1600.0 1900.0 2600.0 2900.0 3000.0 +1800.0 1900.0 2200.0 2700.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2700.0 3000.0 3300.0 +1800.0 1900.0 2400.0 2700.0 2900.0 3300.0 +1900.0 2000.0 2600.0 2700.0 3000.0 3200.0 +1900.0 2200.0 2700.0 2800.0 3000.0 3200.0 +1500.0 1600.0 2100.0 2500.0 2800.0 3100.0 +1100.0 1300.0 2400.0 2600.0 2800.0 3200.0 +1200.0 1500.0 2300.0 2600.0 3100.0 3300.0 +1200.0 1600.0 1800.0 2000.0 3200.0 3300.0 +1400.0 1600.0 1900.0 2000.0 3200.0 3300.0 +1300.0 1500.0 1700.0 1900.0 3200.0 3300.0 +2000.0 2200.0 2700.0 2800.0 3200.0 3400.0 +1500.0 1600.0 2400.0 2500.0 2900.0 3300.0 +1100.0 1700.0 2100.0 2300.0 3100.0 3200.0 +1500.0 1600.0 2100.0 2700.0 2900.0 3000.0 +1500.0 1900.0 2300.0 2600.0 2900.0 3000.0 +1600.0 2000.0 2200.0 2600.0 3100.0 3300.0 +1400.0 1600.0 1800.0 2000.0 3100.0 3200.0 +1900.0 2000.0 2300.0 2500.0 3000.0 3300.0 +1900.0 2100.0 2500.0 2700.0 3000.0 3100.0 +1900.0 2400.0 2700.0 2800.0 3200.0 3400.0 +1900.0 2500.0 2700.0 2800.0 3300.0 3400.0 +2000.0 2500.0 2800.0 2900.0 3300.0 3500.0 +2100.0 2600.0 2800.0 3000.0 3400.0 3500.0 +1500.0 1600.0 2300.0 2600.0 2900.0 3300.0 +1600.0 2100.0 2600.0 2800.0 3200.0 3300.0 +1300.0 1500.0 2300.0 2700.0 3000.0 3300.0 +1400.0 1800.0 2300.0 2500.0 2700.0 3100.0 +1400.0 1600.0 2400.0 2700.0 3200.0 3300.0 +1400.0 1500.0 2300.0 2600.0 3200.0 3300.0 +1400.0 1600.0 2200.0 2600.0 3200.0 3300.0 +1700.0 1800.0 2100.0 2300.0 3200.0 3400.0 +2100.0 2400.0 2700.0 2800.0 3100.0 3400.0 +2100.0 2400.0 2700.0 2800.0 3200.0 3400.0 +1600.0 1800.0 2600.0 2700.0 3000.0 3400.0 +1500.0 1700.0 2600.0 2700.0 2900.0 3300.0 +1600.0 1800.0 2600.0 2700.0 3000.0 3200.0 +1900.0 2500.0 2700.0 3000.0 3400.0 3500.0 +2000.0 2500.0 2600.0 3100.0 3300.0 3400.0 +2100.0 2300.0 2700.0 3000.0 3200.0 3400.0 +1600.0 1700.0 2100.0 2500.0 3100.0 3300.0 +1600.0 1700.0 2000.0 2400.0 3200.0 3300.0 +1600.0 1700.0 2000.0 2500.0 3200.0 3300.0 +2200.0 2500.0 2700.0 2900.0 3300.0 3400.0 +1200.0 1400.0 2100.0 2500.0 3000.0 3100.0 +1400.0 1700.0 2200.0 2400.0 3100.0 3300.0 +1300.0 1700.0 2000.0 2200.0 3100.0 3200.0 +1200.0 1600.0 1700.0 2100.0 3100.0 3200.0 +1800.0 2100.0 2700.0 2900.0 3100.0 3200.0 +1700.0 1800.0 2300.0 2800.0 2900.0 3100.0 +1900.0 2000.0 2300.0 2700.0 2900.0 3200.0 +2000.0 2100.0 2400.0 2700.0 3000.0 3200.0 +1800.0 1900.0 2400.0 2700.0 3100.0 3400.0 +1700.0 1800.0 2500.0 2800.0 3000.0 3300.0 +2200.0 2600.0 2800.0 2900.0 3300.0 3400.0 +1500.0 1700.0 2200.0 2500.0 3200.0 3300.0 +1300.0 1600.0 2200.0 2500.0 3100.0 3200.0 +1700.0 1900.0 2300.0 2700.0 3100.0 3200.0 +1700.0 1900.0 2400.0 2800.0 3000.0 3200.0 +1300.0 1800.0 2200.0 2600.0 3000.0 3300.0 +1200.0 1500.0 2300.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2400.0 3100.0 3400.0 +1300.0 1700.0 2200.0 2300.0 3100.0 3300.0 +1500.0 1700.0 2300.0 2500.0 3200.0 3300.0 +1500.0 1600.0 2400.0 2600.0 3200.0 3300.0 +1600.0 1700.0 2400.0 2700.0 3100.0 3400.0 +1600.0 1700.0 2300.0 2800.0 3000.0 3300.0 +1300.0 1700.0 2300.0 2600.0 2700.0 2900.0 +1500.0 1600.0 2200.0 2600.0 2800.0 3200.0 +1300.0 1700.0 2200.0 2400.0 3000.0 3200.0 +1400.0 1900.0 2300.0 2600.0 2900.0 3300.0 +1200.0 1400.0 2500.0 2600.0 3100.0 3400.0 +1500.0 1600.0 2200.0 2500.0 2700.0 3200.0 +1600.0 1700.0 2300.0 2500.0 2700.0 3300.0 +1100.0 1300.0 2200.0 2700.0 3000.0 3200.0 +1200.0 1300.0 2000.0 2700.0 2900.0 3100.0 +1800.0 2000.0 2700.0 2900.0 3100.0 3300.0 +1800.0 1900.0 2400.0 2800.0 3000.0 3300.0 +1900.0 2000.0 2400.0 2800.0 3000.0 3300.0 +2000.0 2100.0 2400.0 2700.0 2900.0 3100.0 +1700.0 1800.0 2300.0 2600.0 2700.0 3100.0 +1500.0 1700.0 2100.0 2500.0 2700.0 2900.0 +1400.0 1800.0 2400.0 2600.0 2800.0 3200.0 +2000.0 2100.0 2500.0 2900.0 3100.0 3300.0 +2000.0 2100.0 2600.0 2900.0 3100.0 3300.0 +2100.0 2200.0 2500.0 2800.0 3100.0 3300.0 +1900.0 2000.0 2500.0 2600.0 2900.0 3100.0 +1800.0 1900.0 2500.0 2700.0 2800.0 3100.0 +1900.0 2300.0 2800.0 2900.0 3300.0 3400.0 +1700.0 1800.0 2100.0 2200.0 3100.0 3200.0 +1800.0 1900.0 2200.0 2300.0 3100.0 3200.0 +1200.0 1700.0 2100.0 2300.0 3200.0 3300.0 +1400.0 1600.0 2000.0 2200.0 3000.0 3100.0 +1500.0 1600.0 2200.0 2500.0 2900.0 3100.0 +1900.0 2200.0 2400.0 2600.0 2800.0 3000.0 +1900.0 2100.0 2400.0 2700.0 2800.0 3000.0 +1900.0 2100.0 2300.0 2700.0 2900.0 3000.0 +1800.0 2000.0 2400.0 2900.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2800.0 3200.0 3300.0 +1600.0 1700.0 2300.0 2500.0 2800.0 3100.0 +1600.0 1700.0 2100.0 2200.0 2700.0 3100.0 +1600.0 1700.0 2100.0 2200.0 2600.0 3100.0 +1900.0 2200.0 2400.0 2900.0 3300.0 3400.0 +1600.0 1800.0 2400.0 2500.0 2900.0 3200.0 +2000.0 2200.0 2400.0 2500.0 2800.0 3200.0 +2000.0 2400.0 2500.0 2700.0 2900.0 3100.0 +1900.0 2000.0 2200.0 2300.0 3100.0 3400.0 +2000.0 2100.0 2300.0 2600.0 3000.0 3200.0 +2000.0 2100.0 2500.0 2700.0 3000.0 3100.0 +1900.0 2000.0 2300.0 2600.0 2900.0 3000.0 +1300.0 1500.0 2300.0 2500.0 3000.0 3200.0 +1700.0 1800.0 2100.0 2600.0 2900.0 3000.0 +1700.0 1800.0 2200.0 2500.0 2700.0 3100.0 +1900.0 2400.0 2600.0 2700.0 3000.0 3100.0 +2000.0 2400.0 2500.0 2900.0 3200.0 3300.0 +1600.0 1700.0 2300.0 2600.0 2800.0 3100.0 +1900.0 2100.0 2600.0 3000.0 3200.0 3300.0 +1800.0 2300.0 2400.0 2600.0 3200.0 3300.0 +1900.0 2200.0 2300.0 2600.0 3200.0 3300.0 +1900.0 2400.0 2800.0 2900.0 3200.0 3400.0 +1800.0 2400.0 2700.0 2800.0 3200.0 3400.0 +1700.0 2100.0 2200.0 2600.0 3000.0 3100.0 +1900.0 2200.0 2500.0 2900.0 3200.0 3400.0 +1800.0 2400.0 2600.0 2700.0 3300.0 3400.0 +1900.0 2500.0 2700.0 2900.0 3300.0 3400.0 +1900.0 2400.0 2800.0 2900.0 3300.0 3400.0 +1800.0 2400.0 2800.0 2900.0 3200.0 3400.0 +1200.0 1300.0 2400.0 2800.0 2900.0 3100.0 +1600.0 1800.0 2000.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2300.0 2700.0 3200.0 3300.0 +1800.0 2100.0 2300.0 2800.0 3200.0 3300.0 +1500.0 1600.0 2100.0 2200.0 2800.0 3100.0 +1500.0 1600.0 2000.0 2200.0 2500.0 3100.0 +1400.0 1500.0 2200.0 2500.0 2700.0 3000.0 +1200.0 1400.0 2300.0 2600.0 2800.0 3100.0 +1700.0 1800.0 2100.0 2400.0 2800.0 3000.0 +1700.0 2100.0 2200.0 2600.0 2800.0 2900.0 +2000.0 2200.0 2400.0 2700.0 3000.0 3100.0 +1500.0 2100.0 2500.0 2600.0 3100.0 3200.0 +1800.0 2400.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2400.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2300.0 2400.0 2600.0 3200.0 3300.0 +1900.0 2000.0 2400.0 2700.0 3000.0 3100.0 +2000.0 2200.0 2700.0 2900.0 3100.0 3200.0 +1800.0 1900.0 2300.0 2800.0 3200.0 3300.0 +1900.0 2000.0 2200.0 2700.0 3200.0 3300.0 +1900.0 2100.0 2200.0 2700.0 3200.0 3300.0 +1600.0 2000.0 2200.0 2700.0 3200.0 3300.0 +1800.0 2000.0 2300.0 2800.0 3200.0 3300.0 +2000.0 2200.0 2500.0 2800.0 3200.0 3400.0 +1800.0 2100.0 2400.0 2900.0 3100.0 3200.0 +1700.0 1800.0 2300.0 2700.0 3000.0 3100.0 +1500.0 1700.0 2100.0 2300.0 2600.0 3100.0 +1400.0 1500.0 1800.0 1900.0 2400.0 3000.0 +1400.0 1500.0 1800.0 1900.0 2300.0 3000.0 +1400.0 1600.0 1900.0 2000.0 2600.0 3200.0 +1700.0 1800.0 2200.0 2300.0 2700.0 3100.0 +1500.0 1600.0 2100.0 2700.0 3100.0 3200.0 +1400.0 1500.0 2100.0 2700.0 3100.0 3200.0 +1700.0 1800.0 2200.0 2600.0 2900.0 3000.0 +1800.0 1900.0 2200.0 2600.0 2900.0 3000.0 +1400.0 1600.0 2100.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2000.0 2500.0 2900.0 3100.0 +1600.0 1800.0 2400.0 2800.0 3100.0 3200.0 +1400.0 1900.0 2300.0 2700.0 3100.0 3200.0 +1900.0 2200.0 2500.0 2900.0 3300.0 3400.0 +1500.0 1600.0 2100.0 2800.0 3200.0 3300.0 +1400.0 1500.0 1700.0 1900.0 2800.0 3100.0 +1400.0 1600.0 2100.0 2600.0 2800.0 3100.0 +1500.0 1700.0 2300.0 2600.0 2800.0 3000.0 +1600.0 1700.0 2500.0 2700.0 3100.0 3200.0 +1600.0 1900.0 2400.0 2800.0 3000.0 3200.0 +1800.0 2300.0 2600.0 2700.0 3100.0 3300.0 +1900.0 2300.0 2500.0 2700.0 3100.0 3300.0 +1700.0 2000.0 2200.0 2600.0 3000.0 3100.0 +1600.0 1900.0 2100.0 2700.0 2900.0 3100.0 +1600.0 2200.0 2400.0 2700.0 3200.0 3300.0 +1700.0 2300.0 2500.0 2700.0 3200.0 3300.0 +1600.0 2100.0 2300.0 2500.0 3100.0 3200.0 +1700.0 2100.0 2300.0 2500.0 3100.0 3200.0 +1800.0 2200.0 2300.0 2600.0 3200.0 3300.0 +1700.0 2200.0 2400.0 2600.0 3300.0 3400.0 +1700.0 2200.0 2300.0 2600.0 3200.0 3300.0 +1800.0 1900.0 2300.0 2600.0 2900.0 3200.0 +1700.0 1800.0 2200.0 2400.0 2700.0 3000.0 +1800.0 1900.0 2200.0 2500.0 2700.0 3100.0 +1700.0 1900.0 2100.0 2600.0 3100.0 3200.0 +1900.0 2000.0 2300.0 2800.0 3200.0 3300.0 +1800.0 2000.0 2200.0 2700.0 3200.0 3300.0 +1700.0 1800.0 2100.0 2400.0 3200.0 3300.0 +1200.0 1500.0 2400.0 2700.0 2900.0 3000.0 +1700.0 1800.0 2100.0 2200.0 2500.0 3000.0 +1700.0 1800.0 2100.0 2200.0 2400.0 3000.0 +1600.0 1700.0 2000.0 2100.0 2400.0 3000.0 +1600.0 1700.0 1900.0 2000.0 2500.0 3000.0 +1700.0 1900.0 2100.0 2400.0 2600.0 2900.0 +1800.0 2000.0 2200.0 2400.0 2600.0 3000.0 +1600.0 1900.0 2400.0 2500.0 2900.0 3200.0 +1900.0 2100.0 2300.0 2700.0 3200.0 3300.0 +1900.0 2000.0 2300.0 2700.0 2800.0 3000.0 +1900.0 2000.0 2300.0 2700.0 2800.0 3100.0 +1500.0 1600.0 2300.0 2700.0 2900.0 3100.0 +1700.0 2200.0 2700.0 2800.0 3100.0 3300.0 +1600.0 2000.0 2600.0 2800.0 3200.0 3300.0 +1800.0 2200.0 2400.0 2600.0 3100.0 3200.0 +1600.0 2200.0 2600.0 2700.0 3000.0 3100.0 +2000.0 2200.0 2400.0 2600.0 2900.0 3100.0 +1400.0 1600.0 2000.0 2600.0 2800.0 3000.0 +1500.0 1600.0 2500.0 2700.0 3000.0 3100.0 +1300.0 1500.0 2200.0 2600.0 3100.0 3300.0 +1100.0 1600.0 2200.0 2500.0 3000.0 3200.0 +1200.0 1400.0 2200.0 2700.0 2800.0 3000.0 +1200.0 1400.0 2300.0 2600.0 2700.0 3000.0 +1600.0 1700.0 2000.0 2100.0 2600.0 3100.0 +1800.0 2300.0 2400.0 2600.0 2800.0 3100.0 +1700.0 2300.0 2700.0 2800.0 3200.0 3300.0 +1300.0 1600.0 2300.0 2700.0 2900.0 3000.0 +1500.0 1600.0 2200.0 2700.0 3000.0 3200.0 +1600.0 1700.0 2200.0 2700.0 3000.0 3100.0 +1900.0 2000.0 2300.0 2600.0 2800.0 3000.0 +1900.0 2100.0 2300.0 2600.0 2800.0 3000.0 +1500.0 1900.0 2500.0 2700.0 3000.0 3100.0 +1900.0 2400.0 2700.0 2900.0 3100.0 3300.0 +1300.0 1600.0 1800.0 2100.0 2900.0 3200.0 +1700.0 1800.0 2000.0 2200.0 3100.0 3200.0 +2000.0 2300.0 2700.0 3100.0 3300.0 3400.0 +1900.0 2200.0 2300.0 2600.0 3000.0 3200.0 +1900.0 2300.0 2800.0 3000.0 3200.0 3300.0 +2100.0 2300.0 2800.0 2900.0 3200.0 3300.0 +2000.0 2200.0 2800.0 2900.0 3200.0 3300.0 +1700.0 1900.0 2400.0 2800.0 3200.0 3300.0 +1500.0 1600.0 2200.0 2800.0 3200.0 3300.0 +1400.0 1500.0 2200.0 2500.0 2900.0 3200.0 +1300.0 1800.0 2200.0 2500.0 3100.0 3200.0 +1200.0 1800.0 2300.0 2700.0 3100.0 3200.0 +1500.0 1800.0 2500.0 2700.0 3200.0 3300.0 +1900.0 2300.0 2400.0 2700.0 2900.0 3100.0 +1900.0 2200.0 2400.0 2600.0 3000.0 3100.0 +1600.0 1800.0 2100.0 2800.0 3100.0 3200.0 +1800.0 2400.0 2600.0 2700.0 3000.0 3100.0 +1600.0 1700.0 1900.0 2000.0 2500.0 3100.0 +1800.0 1900.0 2100.0 2300.0 2900.0 3300.0 +1300.0 1700.0 2400.0 2700.0 3200.0 3300.0 +1500.0 2000.0 2500.0 2800.0 3100.0 3300.0 +1900.0 2300.0 2400.0 2600.0 3300.0 3400.0 +1900.0 2300.0 2500.0 2700.0 3200.0 3300.0 +1400.0 1600.0 2100.0 2800.0 3100.0 3200.0 +1500.0 1600.0 2100.0 2200.0 2700.0 3200.0 +1500.0 1600.0 1900.0 2000.0 2600.0 3100.0 +1400.0 1500.0 1900.0 2000.0 2600.0 3100.0 +1400.0 1600.0 1900.0 2000.0 2700.0 3200.0 +1700.0 1900.0 2100.0 2400.0 3000.0 3100.0 +1800.0 2000.0 2200.0 2400.0 2900.0 3200.0 +1700.0 2000.0 2200.0 2400.0 2800.0 3100.0 +1800.0 2000.0 2300.0 2700.0 2900.0 3200.0 +1700.0 2000.0 2200.0 2400.0 3000.0 3200.0 +1600.0 1900.0 2100.0 2300.0 3000.0 3200.0 +1700.0 1900.0 2100.0 2300.0 3000.0 3200.0 +1600.0 1900.0 2100.0 2400.0 3000.0 3200.0 +1700.0 1900.0 2200.0 2600.0 2900.0 3100.0 +1500.0 1800.0 1900.0 2400.0 2800.0 3000.0 +1700.0 2000.0 2400.0 2900.0 3100.0 3300.0 +1800.0 2000.0 2700.0 2900.0 3200.0 3400.0 +2000.0 2200.0 2600.0 2900.0 3100.0 3200.0 +1600.0 2200.0 2500.0 2700.0 3200.0 3300.0 +1800.0 2000.0 2200.0 2400.0 2600.0 3100.0 +1700.0 1800.0 2000.0 2100.0 2600.0 3100.0 +1600.0 1700.0 1900.0 2000.0 2700.0 3200.0 +1700.0 1900.0 2100.0 2300.0 2600.0 3100.0 +2000.0 2300.0 2500.0 2600.0 3200.0 3300.0 +1500.0 2100.0 2500.0 2700.0 3100.0 3200.0 +1500.0 2200.0 2500.0 2800.0 3200.0 3300.0 +1600.0 2200.0 2500.0 2800.0 3100.0 3200.0 +1500.0 2100.0 2400.0 2700.0 3100.0 3200.0 +1600.0 2100.0 2400.0 2700.0 3000.0 3100.0 +1800.0 2100.0 2400.0 2700.0 3000.0 3100.0 +1500.0 1600.0 2000.0 2600.0 3000.0 3200.0 +1400.0 1900.0 2400.0 2600.0 3000.0 3300.0 +1400.0 1500.0 2100.0 2600.0 3000.0 3100.0 +1300.0 1500.0 2300.0 2600.0 2800.0 3200.0 +1400.0 1600.0 2200.0 2600.0 3000.0 3200.0 +1700.0 1800.0 2200.0 2600.0 2900.0 3200.0 +1700.0 1800.0 2000.0 2600.0 2900.0 3100.0 +1600.0 1800.0 2000.0 2500.0 3000.0 3200.0 +1300.0 1500.0 2300.0 2700.0 3200.0 3300.0 +1500.0 1700.0 2300.0 2800.0 3200.0 3300.0 +1900.0 2000.0 2300.0 2400.0 3000.0 3200.0 +1700.0 1900.0 2200.0 2600.0 3000.0 3300.0 +1700.0 1800.0 2300.0 2600.0 2800.0 2900.0 +1600.0 1700.0 2000.0 2300.0 3100.0 3200.0 +1600.0 1700.0 2100.0 2400.0 3000.0 3200.0 +2000.0 2100.0 2400.0 2800.0 3100.0 3300.0 +1700.0 2200.0 2300.0 2700.0 3000.0 3100.0 +1700.0 2200.0 2400.0 2600.0 3000.0 3200.0 +1900.0 2300.0 2400.0 2600.0 3000.0 3200.0 +2100.0 2200.0 2600.0 2800.0 3200.0 3400.0 +2100.0 2200.0 2700.0 2900.0 3200.0 3400.0 +2000.0 2200.0 2800.0 3000.0 3200.0 3400.0 +2000.0 2200.0 2700.0 3000.0 3200.0 3400.0 +2000.0 2200.0 2700.0 2900.0 3200.0 3400.0 +1700.0 2100.0 2400.0 2900.0 3100.0 3200.0 +1500.0 1800.0 1900.0 2500.0 3000.0 3100.0 +1700.0 1800.0 2100.0 2400.0 2900.0 3300.0 +1800.0 2000.0 2300.0 2400.0 2700.0 3100.0 +1800.0 2100.0 2300.0 2800.0 3000.0 3200.0 +1600.0 2300.0 2500.0 2800.0 3100.0 3200.0 +1600.0 2100.0 2500.0 2600.0 3200.0 3300.0 +1700.0 1800.0 2100.0 2800.0 3000.0 3100.0 +1800.0 2300.0 2600.0 2700.0 3100.0 3200.0 +2000.0 2200.0 2800.0 3000.0 3300.0 3400.0 +2000.0 2200.0 2600.0 2800.0 3200.0 3400.0 +1700.0 1800.0 2200.0 2600.0 2800.0 3200.0 +1600.0 1800.0 2200.0 2500.0 2800.0 3200.0 +1600.0 1700.0 1900.0 2000.0 2600.0 3100.0 +1600.0 1700.0 2200.0 2800.0 3000.0 3200.0 +1700.0 1800.0 2400.0 2900.0 3100.0 3300.0 +1900.0 2200.0 2700.0 2900.0 3400.0 3500.0 +1700.0 1800.0 2000.0 2200.0 2900.0 3200.0 +1700.0 1900.0 2100.0 2300.0 2900.0 3200.0 +1200.0 1400.0 2200.0 2900.0 3100.0 3200.0 +1800.0 1900.0 2300.0 2600.0 2800.0 3200.0 +1600.0 1700.0 2000.0 2200.0 2700.0 3200.0 +1600.0 1700.0 2000.0 2200.0 2800.0 3200.0 +1600.0 1700.0 2000.0 2100.0 2800.0 3200.0 +1600.0 1800.0 2000.0 2100.0 2800.0 3200.0 +1700.0 1800.0 2000.0 2300.0 2900.0 3200.0 +1800.0 1900.0 2200.0 2600.0 3200.0 3300.0 +1800.0 2000.0 2200.0 2500.0 3200.0 3300.0 +1300.0 1500.0 1900.0 2600.0 3100.0 3200.0 +1300.0 1400.0 2000.0 2600.0 3200.0 3300.0 +1600.0 1700.0 2100.0 2700.0 3000.0 3200.0 +1400.0 1500.0 2000.0 2600.0 3100.0 3200.0 +1400.0 1500.0 2000.0 2700.0 3100.0 3200.0 +1500.0 1800.0 2400.0 2700.0 3000.0 3300.0 +1500.0 1600.0 2200.0 2300.0 2700.0 3300.0 +1400.0 1500.0 2200.0 2400.0 2700.0 3200.0 +1300.0 1500.0 2300.0 2600.0 2900.0 3200.0 +1400.0 1700.0 2400.0 2600.0 3000.0 3200.0 +1300.0 1600.0 2400.0 2500.0 2900.0 3200.0 +1400.0 1500.0 2200.0 2400.0 2900.0 3300.0 +1400.0 1600.0 2100.0 2200.0 3200.0 3300.0 +1400.0 1800.0 2200.0 2700.0 3200.0 3300.0 +1700.0 2000.0 2500.0 2600.0 3100.0 3200.0 +1500.0 1700.0 1900.0 2600.0 3200.0 3300.0 +1500.0 1600.0 1800.0 2000.0 2800.0 3200.0 +1500.0 1600.0 1900.0 2000.0 2700.0 3200.0 +1500.0 1600.0 1900.0 2000.0 2800.0 3200.0 +1600.0 1700.0 2000.0 2500.0 3000.0 3200.0 +1600.0 1700.0 2200.0 2700.0 2900.0 3200.0 +1300.0 1500.0 2300.0 2700.0 2900.0 3200.0 +1600.0 1700.0 2600.0 2800.0 2900.0 3200.0 +1300.0 1500.0 2300.0 2500.0 2800.0 3200.0 +1300.0 1400.0 2300.0 2500.0 2800.0 3200.0 +1500.0 1700.0 2200.0 2600.0 2700.0 3100.0 +1500.0 1700.0 2200.0 2600.0 2800.0 3000.0 +1500.0 1700.0 2000.0 2600.0 2700.0 3000.0 +1100.0 1300.0 2300.0 2800.0 3100.0 3200.0 +1600.0 1700.0 2100.0 2500.0 3200.0 3300.0 +1700.0 1800.0 2300.0 2700.0 3100.0 3200.0 +1900.0 2100.0 2300.0 2700.0 2900.0 3200.0 +1800.0 2000.0 2500.0 2800.0 3100.0 3400.0 +1900.0 2000.0 2800.0 2900.0 3300.0 3400.0 +1800.0 2000.0 2700.0 2800.0 3300.0 3400.0 +1700.0 1800.0 2100.0 2200.0 2600.0 3100.0 +1500.0 1600.0 1800.0 1900.0 2600.0 3200.0 +1600.0 1700.0 1900.0 2000.0 2600.0 3200.0 +1600.0 1700.0 2000.0 2100.0 2600.0 3200.0 +1700.0 1800.0 2000.0 2100.0 2800.0 3300.0 +1600.0 1900.0 2100.0 2400.0 3000.0 3100.0 +1600.0 1800.0 2300.0 2600.0 2900.0 3000.0 +1400.0 1500.0 2100.0 2600.0 2900.0 3100.0 +1400.0 1500.0 2200.0 2600.0 2900.0 3100.0 +1000.0 1200.0 2300.0 2900.0 3100.0 3200.0 +1300.0 1700.0 2400.0 2600.0 3000.0 3200.0 +1100.0 1600.0 2300.0 2600.0 3200.0 3300.0 +1200.0 1600.0 2300.0 2600.0 3100.0 3300.0 +1100.0 1600.0 2200.0 2600.0 3100.0 3300.0 +1600.0 2200.0 2400.0 2700.0 3100.0 3200.0 +1700.0 1800.0 2300.0 2700.0 2800.0 3000.0 +1400.0 1700.0 1900.0 2500.0 3200.0 3300.0 +1700.0 1900.0 2200.0 2400.0 2800.0 3000.0 +1400.0 1600.0 2100.0 2200.0 2700.0 3000.0 +1500.0 1700.0 2200.0 2400.0 2700.0 3100.0 +1500.0 1600.0 2200.0 2400.0 2800.0 3100.0 +1000.0 1900.0 2200.0 2500.0 3200.0 3300.0 +1200.0 1700.0 2100.0 2400.0 3200.0 3300.0 +1700.0 2000.0 2500.0 2600.0 3100.0 3400.0 +1600.0 2200.0 2400.0 2600.0 3200.0 3300.0 +2000.0 2500.0 2600.0 3000.0 3300.0 3400.0 +1400.0 1500.0 2100.0 2300.0 3200.0 3300.0 +1500.0 1700.0 2100.0 2400.0 3200.0 3300.0 +1500.0 1700.0 2200.0 2300.0 3300.0 3400.0 +1800.0 2200.0 2500.0 2700.0 3100.0 3400.0 +1500.0 1900.0 2300.0 2600.0 3200.0 3300.0 +2100.0 2200.0 2600.0 2900.0 3100.0 3300.0 +1500.0 1600.0 1800.0 2600.0 3200.0 3300.0 +1300.0 1500.0 1600.0 2200.0 3100.0 3200.0 +1200.0 1800.0 2300.0 2400.0 3000.0 3200.0 +1100.0 1900.0 2100.0 2500.0 3200.0 3300.0 +1400.0 1700.0 2200.0 2500.0 3100.0 3200.0 +1900.0 2100.0 2300.0 2600.0 3000.0 3300.0 +1900.0 2100.0 2500.0 2800.0 3300.0 3400.0 +1700.0 1900.0 2300.0 2500.0 3100.0 3400.0 +1500.0 1900.0 2200.0 2500.0 2900.0 3200.0 +1200.0 2000.0 2300.0 2400.0 2500.0 3100.0 +1200.0 2000.0 2300.0 2400.0 2600.0 3100.0 +1900.0 2200.0 2500.0 2600.0 3100.0 3300.0 +1900.0 2200.0 2500.0 2700.0 3200.0 3400.0 +1800.0 2100.0 2400.0 2500.0 3200.0 3300.0 +1800.0 2100.0 2300.0 2500.0 3300.0 3400.0 +1500.0 1700.0 1800.0 2500.0 3200.0 3300.0 +1400.0 1600.0 1800.0 2300.0 3200.0 3300.0 +1300.0 1600.0 2300.0 2400.0 3200.0 3400.0 +1200.0 1500.0 1700.0 2100.0 3100.0 3200.0 +2100.0 2300.0 2400.0 2800.0 3200.0 3300.0 +1500.0 2000.0 2300.0 2400.0 3100.0 3300.0 +1400.0 1600.0 2000.0 2100.0 3000.0 3300.0 +1900.0 2000.0 2200.0 2400.0 3000.0 3300.0 +1500.0 1800.0 2200.0 2300.0 3000.0 3300.0 +1300.0 1500.0 2100.0 2200.0 2800.0 3300.0 +1500.0 1800.0 2200.0 2400.0 3000.0 3300.0 +1600.0 1900.0 2300.0 2600.0 3200.0 3400.0 +1300.0 1800.0 2200.0 2500.0 3000.0 3200.0 +1100.0 1600.0 2200.0 2300.0 3100.0 3200.0 +1300.0 1500.0 2000.0 2200.0 3100.0 3300.0 +2300.0 2500.0 2900.0 3100.0 3200.0 3300.0 +2300.0 2400.0 2700.0 2800.0 3100.0 3300.0 +2000.0 2100.0 2400.0 2700.0 3200.0 3300.0 +1600.0 1700.0 1900.0 2100.0 3200.0 3300.0 +1600.0 1800.0 1900.0 2300.0 3200.0 3300.0 +1500.0 1600.0 1900.0 2600.0 3100.0 3200.0 +1300.0 1500.0 1900.0 2300.0 3000.0 3100.0 +1200.0 1600.0 2000.0 2100.0 3200.0 3300.0 +1300.0 2000.0 2200.0 2400.0 2700.0 3100.0 +1100.0 1900.0 2300.0 2400.0 3000.0 3100.0 +1200.0 1500.0 2300.0 2600.0 3100.0 3200.0 +1400.0 1600.0 1900.0 2500.0 3000.0 3100.0 +1300.0 1500.0 1600.0 2300.0 3200.0 3300.0 +1500.0 1800.0 2100.0 2400.0 3100.0 3200.0 +1900.0 2200.0 2500.0 2600.0 3200.0 3400.0 +1400.0 1500.0 2100.0 2300.0 2900.0 3200.0 +1100.0 1600.0 2100.0 2300.0 3100.0 3200.0 +1100.0 1600.0 2100.0 2300.0 3200.0 3300.0 +1000.0 1600.0 2200.0 2300.0 3100.0 3300.0 +1100.0 1600.0 2100.0 2300.0 3000.0 3100.0 +1100.0 1400.0 2300.0 2500.0 3200.0 3300.0 +1700.0 2100.0 2500.0 2800.0 3100.0 3400.0 +1300.0 1600.0 2300.0 2400.0 3200.0 3300.0 +1400.0 1700.0 2300.0 2400.0 3200.0 3300.0 +1500.0 1600.0 2300.0 2400.0 3000.0 3300.0 +1700.0 1900.0 2500.0 2600.0 3000.0 3200.0 +1100.0 1500.0 2400.0 2500.0 3100.0 3200.0 +1700.0 1900.0 2100.0 2400.0 3100.0 3300.0 +1300.0 1700.0 2200.0 2600.0 3100.0 3300.0 +1600.0 1700.0 2000.0 2200.0 3100.0 3300.0 +1800.0 2000.0 2200.0 2400.0 3200.0 3400.0 +1900.0 2100.0 2600.0 2800.0 3000.0 3200.0 +1900.0 2100.0 2600.0 2800.0 3100.0 3200.0 +1400.0 1900.0 2400.0 2500.0 3100.0 3300.0 +1100.0 2100.0 2300.0 2700.0 3100.0 3200.0 +1100.0 1800.0 2200.0 2500.0 3000.0 3100.0 +1100.0 1800.0 2200.0 2400.0 3000.0 3100.0 +1500.0 1800.0 2400.0 2500.0 3100.0 3300.0 +1500.0 2000.0 2400.0 2500.0 3200.0 3400.0 +1800.0 2000.0 2500.0 2600.0 3000.0 3300.0 +1900.0 2400.0 2600.0 2900.0 3200.0 3400.0 +1500.0 2100.0 2500.0 2700.0 3200.0 3300.0 +1400.0 2100.0 2400.0 2700.0 3100.0 3200.0 +1500.0 2100.0 2500.0 2700.0 3000.0 3200.0 +1600.0 2100.0 2500.0 2600.0 3100.0 3300.0 +1500.0 1800.0 2100.0 2700.0 3100.0 3300.0 +1300.0 1600.0 1800.0 2500.0 3200.0 3300.0 +1300.0 1500.0 1600.0 2800.0 3300.0 3400.0 +1300.0 1400.0 2200.0 2300.0 3100.0 3300.0 +1300.0 1600.0 2400.0 2500.0 3000.0 3300.0 +1700.0 1800.0 2300.0 2500.0 3200.0 3400.0 +1400.0 2000.0 2100.0 2400.0 3000.0 3100.0 +1300.0 1900.0 2100.0 2400.0 3100.0 3200.0 +1600.0 1700.0 2200.0 2600.0 3200.0 3300.0 +1400.0 1800.0 2300.0 2400.0 2900.0 3200.0 +1300.0 1600.0 2200.0 2400.0 3000.0 3200.0 +1200.0 1900.0 2200.0 2500.0 3100.0 3200.0 +1500.0 1600.0 2200.0 2400.0 3100.0 3300.0 +1000.0 1600.0 2500.0 2600.0 3100.0 3200.0 +900.0 1600.0 2500.0 2600.0 3200.0 3300.0 +1400.0 1700.0 2500.0 2700.0 3100.0 3300.0 +1300.0 1900.0 2500.0 2700.0 3200.0 3300.0 +1600.0 2000.0 2400.0 2500.0 2900.0 3100.0 +1400.0 1600.0 2500.0 2600.0 3200.0 3400.0 +1400.0 1600.0 2600.0 2700.0 3100.0 3300.0 +1400.0 1600.0 2600.0 2700.0 3100.0 3400.0 +1600.0 2100.0 2600.0 2900.0 3300.0 3400.0 +1800.0 2100.0 2800.0 3000.0 3300.0 3400.0 +1800.0 2300.0 2700.0 2900.0 3400.0 3500.0 +1800.0 2400.0 2900.0 3100.0 3300.0 3400.0 +1200.0 1800.0 2300.0 2400.0 3000.0 3100.0 +1300.0 1600.0 2400.0 2500.0 3100.0 3200.0 +1400.0 1800.0 2400.0 2500.0 3200.0 3400.0 +2000.0 2500.0 2700.0 3100.0 3300.0 3400.0 +1900.0 2000.0 2400.0 2800.0 3100.0 3300.0 +1500.0 1800.0 1900.0 2500.0 3100.0 3200.0 +1600.0 1800.0 2000.0 2600.0 3100.0 3200.0 +1700.0 2000.0 2200.0 2700.0 3000.0 3100.0 +1700.0 2000.0 2300.0 2600.0 2900.0 3000.0 +2300.0 2400.0 2700.0 2900.0 3200.0 3300.0 +1200.0 1600.0 2200.0 2300.0 3000.0 3100.0 +1400.0 2000.0 2300.0 2500.0 3100.0 3200.0 +1500.0 1900.0 2300.0 2400.0 3100.0 3200.0 +1300.0 1700.0 1800.0 2400.0 2900.0 3000.0 +1300.0 1500.0 1600.0 2200.0 2800.0 2900.0 +1900.0 2100.0 2500.0 2700.0 3000.0 3300.0 +1500.0 1900.0 2400.0 2600.0 2900.0 3300.0 +1400.0 1800.0 2300.0 2500.0 3100.0 3300.0 +1300.0 1800.0 2500.0 2700.0 3100.0 3300.0 +1300.0 1800.0 2400.0 2600.0 3100.0 3200.0 +1200.0 1700.0 2400.0 2500.0 2900.0 3100.0 +1100.0 1800.0 2000.0 2200.0 3000.0 3100.0 +1300.0 1600.0 1700.0 2600.0 3100.0 3200.0 +1700.0 1900.0 2200.0 2400.0 3000.0 3200.0 +1700.0 1900.0 2300.0 2400.0 3000.0 3100.0 +1800.0 1900.0 2400.0 2500.0 3000.0 3100.0 +1500.0 2200.0 2500.0 2700.0 3300.0 3400.0 +1900.0 2500.0 2700.0 3000.0 3300.0 3400.0 +1400.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1400.0 1800.0 2100.0 2500.0 3000.0 3100.0 +1200.0 1500.0 1600.0 2600.0 3100.0 3200.0 +1300.0 1600.0 1700.0 2300.0 3100.0 3200.0 +1300.0 1600.0 1700.0 2200.0 3100.0 3200.0 +1200.0 1500.0 1600.0 2200.0 3100.0 3200.0 +1200.0 1500.0 1600.0 2300.0 3000.0 3100.0 +1300.0 1800.0 2400.0 2600.0 3000.0 3200.0 +1300.0 1800.0 2200.0 2400.0 3100.0 3300.0 +1400.0 1800.0 2200.0 2400.0 3100.0 3300.0 +1600.0 1700.0 2100.0 2300.0 2700.0 3100.0 +1700.0 1800.0 2100.0 2300.0 2700.0 3200.0 +1700.0 1800.0 2200.0 2300.0 2800.0 3200.0 +1700.0 2200.0 2400.0 2800.0 3100.0 3200.0 +1100.0 2000.0 2200.0 2400.0 3000.0 3100.0 +1100.0 1900.0 2000.0 2400.0 3000.0 3100.0 +1300.0 1500.0 1600.0 2700.0 3200.0 3300.0 +1300.0 1500.0 1600.0 2600.0 3300.0 3400.0 +1600.0 1700.0 2000.0 2600.0 3100.0 3200.0 +1700.0 2200.0 2500.0 2700.0 2900.0 3200.0 +1100.0 1700.0 2200.0 2300.0 3100.0 3200.0 +1100.0 1800.0 2100.0 2200.0 3100.0 3200.0 +1100.0 1600.0 2000.0 2100.0 3100.0 3200.0 +1100.0 1600.0 1900.0 2100.0 3100.0 3200.0 +1200.0 1600.0 1800.0 2000.0 3100.0 3200.0 +1300.0 1600.0 1700.0 2000.0 3100.0 3200.0 +1300.0 1600.0 1700.0 2000.0 3000.0 3100.0 +1200.0 1500.0 1600.0 2000.0 3000.0 3100.0 +1500.0 1700.0 1900.0 2400.0 2800.0 2900.0 +1600.0 2000.0 2300.0 2600.0 2900.0 3100.0 +2200.0 2400.0 2700.0 2800.0 3100.0 3300.0 +1700.0 2100.0 2300.0 2400.0 2800.0 3200.0 +1600.0 1800.0 2300.0 2400.0 2800.0 3200.0 +1000.0 2000.0 2600.0 2700.0 3200.0 3300.0 +1000.0 1900.0 2800.0 2900.0 3300.0 3400.0 +1400.0 1600.0 1800.0 2400.0 2700.0 3000.0 +1800.0 2000.0 2300.0 2500.0 2900.0 3100.0 +1200.0 1800.0 2600.0 2700.0 3200.0 3300.0 +1300.0 1800.0 2400.0 2500.0 3000.0 3300.0 +1500.0 1900.0 2500.0 2700.0 3200.0 3400.0 +1400.0 1800.0 2500.0 2600.0 3100.0 3300.0 +1600.0 1800.0 2200.0 2300.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2400.0 2700.0 3100.0 +1700.0 1900.0 2200.0 2500.0 2700.0 3100.0 +1300.0 1400.0 2200.0 2800.0 3100.0 3200.0 +1700.0 2100.0 2300.0 2500.0 2800.0 3100.0 +1500.0 1600.0 2200.0 2700.0 2900.0 3100.0 +1200.0 1400.0 2200.0 2800.0 3000.0 3200.0 +1200.0 1400.0 2300.0 2800.0 3100.0 3200.0 +1900.0 2000.0 2600.0 2800.0 3100.0 3300.0 +1900.0 2100.0 2500.0 2800.0 3000.0 3300.0 +2100.0 2300.0 2500.0 2700.0 2900.0 3200.0 +1900.0 2000.0 2700.0 2900.0 3100.0 3400.0 +1900.0 2000.0 2600.0 2900.0 3200.0 3300.0 +1900.0 2000.0 2600.0 2900.0 3200.0 3400.0 +900.0 1500.0 2500.0 2600.0 3200.0 3400.0 +1800.0 1900.0 2400.0 2800.0 2900.0 3100.0 +1600.0 1900.0 2300.0 2600.0 2900.0 3100.0 +1400.0 1500.0 2000.0 2400.0 2900.0 3100.0 +1500.0 1800.0 2200.0 2400.0 2600.0 2800.0 +2000.0 2400.0 2800.0 2900.0 3100.0 3400.0 +1900.0 2300.0 2800.0 2900.0 3100.0 3300.0 +1200.0 1400.0 1900.0 2600.0 3100.0 3200.0 +2100.0 2300.0 2800.0 2900.0 3100.0 3200.0 +2000.0 2400.0 2600.0 2700.0 3100.0 3300.0 +2000.0 2400.0 2600.0 2700.0 3000.0 3200.0 +2000.0 2300.0 2600.0 2700.0 2900.0 3200.0 +1800.0 1900.0 2300.0 2600.0 2800.0 3000.0 +2000.0 2300.0 2500.0 2800.0 3000.0 3200.0 +1700.0 2000.0 2200.0 2600.0 2800.0 3000.0 +1900.0 2000.0 2400.0 2800.0 2900.0 3100.0 +2200.0 2600.0 2800.0 2900.0 3200.0 3400.0 +1600.0 1700.0 2200.0 2400.0 2700.0 3200.0 +1500.0 1600.0 2300.0 2400.0 2700.0 3200.0 +1300.0 1500.0 2200.0 2500.0 2700.0 3100.0 +1700.0 1800.0 2100.0 2200.0 2700.0 3200.0 +1900.0 2000.0 2600.0 2900.0 3000.0 3200.0 +1800.0 2100.0 2400.0 2500.0 2800.0 3100.0 +1400.0 1500.0 2200.0 2500.0 2700.0 3100.0 +1500.0 1600.0 2200.0 2400.0 2700.0 3100.0 +1700.0 1800.0 2300.0 2400.0 2700.0 3100.0 +1900.0 2000.0 2300.0 2500.0 2700.0 3100.0 +1900.0 2200.0 2400.0 2700.0 2800.0 3100.0 +1600.0 1700.0 2200.0 2600.0 2700.0 3100.0 +2100.0 2400.0 2600.0 2800.0 3000.0 3200.0 +2100.0 2300.0 2700.0 2800.0 3200.0 3400.0 +1800.0 2300.0 2600.0 2800.0 3000.0 3200.0 +2000.0 2200.0 2400.0 2700.0 3000.0 3300.0 +1900.0 2200.0 2400.0 2600.0 3000.0 3300.0 +1700.0 2000.0 2300.0 2600.0 2800.0 3000.0 +1600.0 1800.0 2100.0 2500.0 2700.0 3000.0 +1600.0 1700.0 2300.0 2600.0 2800.0 3000.0 +1600.0 1700.0 2400.0 2600.0 2800.0 3000.0 +2000.0 2300.0 2600.0 2700.0 3300.0 3400.0 +1700.0 1800.0 2100.0 2500.0 3000.0 3300.0 +1300.0 1500.0 2300.0 2400.0 3000.0 3300.0 +1500.0 1600.0 1900.0 2100.0 3000.0 3100.0 +1900.0 2000.0 2500.0 2800.0 3100.0 3200.0 +2000.0 2400.0 2900.0 3000.0 3200.0 3400.0 +1700.0 1800.0 2100.0 2500.0 2700.0 3100.0 +1500.0 2000.0 2400.0 2500.0 3000.0 3300.0 +1500.0 1600.0 2300.0 2400.0 2700.0 3100.0 +1600.0 1700.0 2300.0 2400.0 2700.0 3200.0 +1700.0 1800.0 2200.0 2500.0 2600.0 3000.0 +1800.0 1900.0 2200.0 2500.0 2700.0 3000.0 +1800.0 1900.0 2200.0 2600.0 2700.0 3000.0 +1800.0 2200.0 2500.0 2700.0 2900.0 3200.0 +1200.0 1600.0 2500.0 2600.0 3000.0 3300.0 +1000.0 1300.0 2400.0 2900.0 3100.0 3200.0 +1300.0 1600.0 2500.0 2800.0 3000.0 3200.0 +1800.0 2100.0 2600.0 2800.0 3000.0 3300.0 +1300.0 1600.0 2500.0 2800.0 2900.0 3200.0 +1200.0 1500.0 2300.0 2700.0 2900.0 3200.0 +1200.0 1400.0 2300.0 2700.0 2900.0 3200.0 +1400.0 1600.0 2100.0 2500.0 3100.0 3300.0 +1700.0 2300.0 2600.0 2800.0 3100.0 3200.0 +2000.0 2200.0 2400.0 2700.0 2800.0 3100.0 +1400.0 1500.0 2300.0 2800.0 3000.0 3100.0 +1500.0 1600.0 2300.0 2800.0 2900.0 3100.0 +1500.0 1600.0 2400.0 2800.0 2900.0 3100.0 +1700.0 1800.0 2200.0 2700.0 2800.0 3000.0 +1800.0 1900.0 2600.0 2700.0 2900.0 3200.0 +1800.0 2000.0 2700.0 2800.0 3200.0 3400.0 +1800.0 2000.0 2600.0 2800.0 3000.0 3300.0 +1700.0 1800.0 2400.0 2600.0 2900.0 3100.0 +2000.0 2200.0 2500.0 2600.0 3000.0 3100.0 +2000.0 2100.0 2500.0 2900.0 3200.0 3300.0 +1800.0 2000.0 2600.0 2900.0 3100.0 3300.0 +1700.0 1900.0 2200.0 2700.0 2800.0 3000.0 +1700.0 2000.0 2500.0 2600.0 3200.0 3300.0 +1400.0 1600.0 2300.0 2500.0 2700.0 3100.0 +1900.0 2300.0 2800.0 3000.0 3400.0 3500.0 +1600.0 1800.0 2300.0 2400.0 2800.0 3300.0 +1600.0 1700.0 2200.0 2400.0 2800.0 3000.0 +1600.0 1700.0 2300.0 2600.0 3000.0 3100.0 +1800.0 2100.0 2700.0 2900.0 3300.0 3500.0 +1600.0 1700.0 2300.0 2800.0 2900.0 3100.0 +1300.0 1500.0 2200.0 2700.0 2900.0 3100.0 +1200.0 1400.0 2500.0 2900.0 3000.0 3200.0 +1900.0 2200.0 2400.0 2700.0 3200.0 3400.0 +1800.0 2000.0 2600.0 2900.0 3100.0 3400.0 +1600.0 1700.0 2100.0 2600.0 2700.0 3100.0 +1500.0 1600.0 2300.0 2500.0 2700.0 3100.0 +1500.0 1600.0 2200.0 2800.0 3100.0 3300.0 +1300.0 1500.0 2000.0 2700.0 3100.0 3200.0 +1300.0 1500.0 1900.0 2600.0 3200.0 3300.0 +1300.0 1400.0 2000.0 2400.0 3200.0 3300.0 +1300.0 1400.0 2000.0 2300.0 3100.0 3300.0 +1300.0 1500.0 2000.0 2300.0 3100.0 3200.0 +1800.0 2000.0 2200.0 2400.0 3100.0 3300.0 +1700.0 1900.0 2300.0 2400.0 2800.0 3300.0 +1200.0 2200.0 2500.0 2700.0 3200.0 3300.0 +1300.0 2100.0 2300.0 2700.0 3200.0 3300.0 +1400.0 2200.0 2400.0 2900.0 3300.0 3400.0 +1500.0 2100.0 2400.0 2600.0 3200.0 3300.0 +1200.0 1900.0 2400.0 2500.0 3000.0 3200.0 +1200.0 2000.0 2400.0 2600.0 3000.0 3200.0 +1200.0 1900.0 2400.0 2500.0 3200.0 3300.0 +2000.0 2300.0 2700.0 3000.0 3200.0 3400.0 +1900.0 2100.0 2600.0 3000.0 3300.0 3400.0 +1500.0 1900.0 2200.0 2600.0 3000.0 3300.0 +1400.0 1800.0 2200.0 2500.0 3000.0 3300.0 +1800.0 2000.0 2300.0 2400.0 3300.0 3400.0 +1600.0 2100.0 2300.0 2400.0 3100.0 3300.0 +1900.0 2300.0 2800.0 3000.0 3200.0 3400.0 +1700.0 2100.0 2400.0 2700.0 3100.0 3400.0 +1400.0 1800.0 2300.0 2600.0 3200.0 3400.0 +1700.0 2000.0 2200.0 2400.0 3100.0 3200.0 +1500.0 1800.0 2200.0 2500.0 3000.0 3300.0 +1700.0 1900.0 2200.0 2600.0 2900.0 3200.0 +1400.0 1900.0 2200.0 2400.0 3100.0 3200.0 +1500.0 1900.0 2200.0 2400.0 3100.0 3200.0 +1600.0 2100.0 2300.0 2700.0 3100.0 3200.0 +1600.0 1700.0 1900.0 2800.0 3000.0 3100.0 +1500.0 1700.0 1900.0 2600.0 3000.0 3100.0 +1500.0 1600.0 2100.0 2600.0 3200.0 3300.0 +2200.0 2300.0 2600.0 2900.0 3100.0 3300.0 +1900.0 2200.0 2400.0 2700.0 3000.0 3300.0 +1400.0 1700.0 2300.0 2400.0 3000.0 3100.0 +1900.0 2000.0 2400.0 2500.0 3100.0 3200.0 +2000.0 2500.0 2600.0 2800.0 3300.0 3400.0 +2000.0 2400.0 2600.0 3000.0 3200.0 3300.0 +1500.0 1800.0 2300.0 2500.0 2900.0 3200.0 +1300.0 1900.0 2200.0 2300.0 3000.0 3200.0 +1600.0 1700.0 2500.0 2800.0 3200.0 3400.0 +1500.0 1900.0 2500.0 2600.0 3300.0 3400.0 +1900.0 2200.0 2500.0 2700.0 3000.0 3300.0 +1300.0 1600.0 1800.0 2100.0 3000.0 3100.0 +1000.0 1900.0 2200.0 2500.0 3100.0 3200.0 +1200.0 2000.0 2300.0 2600.0 3300.0 3400.0 +1400.0 1600.0 1800.0 2600.0 2900.0 3100.0 +1400.0 1700.0 2000.0 2600.0 3100.0 3200.0 +1300.0 1800.0 2000.0 2700.0 3200.0 3300.0 +1700.0 2000.0 2300.0 2400.0 2700.0 3100.0 +1700.0 1800.0 2000.0 2400.0 3100.0 3200.0 +1800.0 1900.0 2100.0 2500.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2500.0 2800.0 3100.0 +1600.0 1800.0 2100.0 2400.0 2700.0 2800.0 +1300.0 1700.0 2100.0 2200.0 3100.0 3300.0 +1300.0 1700.0 2100.0 2200.0 3000.0 3200.0 +1500.0 1800.0 2200.0 2400.0 2700.0 3200.0 +1600.0 1800.0 2200.0 2300.0 2900.0 3200.0 +1500.0 1800.0 2100.0 2400.0 2900.0 3200.0 +1400.0 1700.0 1900.0 2200.0 2800.0 2900.0 +1500.0 1800.0 2100.0 2500.0 3000.0 3100.0 +1500.0 1900.0 2100.0 2500.0 3000.0 3100.0 +1500.0 2000.0 2200.0 2700.0 3200.0 3300.0 +1400.0 1800.0 2200.0 2500.0 3200.0 3300.0 +1500.0 2000.0 2200.0 2400.0 2900.0 3200.0 +1800.0 2000.0 2700.0 2900.0 3300.0 3400.0 +1500.0 1800.0 2100.0 2500.0 3200.0 3300.0 +1400.0 1700.0 1800.0 2200.0 3100.0 3200.0 +1400.0 1600.0 1700.0 2300.0 3000.0 3100.0 +1300.0 2000.0 2100.0 2700.0 3100.0 3200.0 +1400.0 1800.0 2200.0 2500.0 3100.0 3200.0 +1400.0 1700.0 1800.0 2300.0 3000.0 3100.0 +1600.0 1700.0 1900.0 2600.0 3000.0 3100.0 +1800.0 2100.0 2300.0 2700.0 3300.0 3400.0 +1700.0 2100.0 2300.0 2700.0 3300.0 3400.0 +1800.0 2100.0 2300.0 2400.0 2700.0 3100.0 +1500.0 1700.0 1900.0 2600.0 3100.0 3200.0 +1300.0 2000.0 2200.0 2800.0 3200.0 3300.0 +1700.0 1900.0 2600.0 2900.0 3200.0 3400.0 +1200.0 1800.0 2600.0 2700.0 3100.0 3200.0 +1900.0 2000.0 2200.0 2500.0 3200.0 3400.0 +1300.0 1700.0 2300.0 2400.0 2900.0 3200.0 +1200.0 1600.0 2200.0 2400.0 2800.0 3100.0 +1200.0 1800.0 2200.0 2600.0 3200.0 3300.0 +1300.0 1800.0 2300.0 2700.0 3300.0 3400.0 +1700.0 2000.0 2400.0 2500.0 3000.0 3200.0 +1600.0 1900.0 2200.0 2300.0 2900.0 3100.0 +1400.0 1700.0 1900.0 2400.0 3000.0 3100.0 +1600.0 1900.0 2400.0 2700.0 3300.0 3400.0 +1800.0 2300.0 2700.0 3000.0 3200.0 3400.0 +1300.0 1700.0 2300.0 2600.0 3000.0 3300.0 +1200.0 1800.0 2200.0 2600.0 3100.0 3300.0 +1700.0 2000.0 2400.0 2800.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2400.0 2600.0 3000.0 +1600.0 1700.0 2100.0 2400.0 2600.0 3000.0 +1700.0 1900.0 2200.0 2400.0 2800.0 3200.0 +1700.0 2100.0 2300.0 2700.0 2800.0 3000.0 +1600.0 1900.0 2100.0 2600.0 2900.0 3000.0 +1800.0 2000.0 2700.0 2800.0 3100.0 3400.0 +1500.0 1600.0 2200.0 2800.0 3000.0 3100.0 +1300.0 1500.0 2100.0 2700.0 3000.0 3100.0 +1500.0 1800.0 2300.0 2600.0 3000.0 3100.0 +1600.0 1700.0 2300.0 2700.0 2900.0 3000.0 +1600.0 1800.0 2200.0 2600.0 2800.0 3100.0 +1500.0 1600.0 2300.0 2600.0 2900.0 3100.0 +1600.0 1800.0 2200.0 2700.0 3000.0 3300.0 +2100.0 2200.0 2600.0 2700.0 2900.0 3100.0 +1800.0 1900.0 2300.0 2700.0 2800.0 3000.0 +1800.0 1900.0 2200.0 2700.0 2800.0 3000.0 +1500.0 1800.0 2000.0 2600.0 3000.0 3100.0 +1500.0 1700.0 2100.0 2500.0 2700.0 3000.0 +1500.0 1600.0 1900.0 2000.0 2400.0 3100.0 +1200.0 1500.0 2100.0 2200.0 2700.0 3200.0 +1300.0 1700.0 2400.0 2700.0 3000.0 3200.0 +1600.0 1700.0 2400.0 2800.0 2900.0 3200.0 +1500.0 1800.0 2000.0 2500.0 2900.0 3200.0 +1800.0 2000.0 2200.0 2500.0 2700.0 3000.0 +1800.0 1900.0 2300.0 2600.0 2700.0 3200.0 +1500.0 1700.0 2200.0 2700.0 2900.0 3200.0 +1300.0 1400.0 2100.0 2600.0 3000.0 3200.0 +1400.0 1500.0 2100.0 2700.0 3000.0 3200.0 +1500.0 1600.0 2300.0 2800.0 3000.0 3300.0 +1700.0 1800.0 2300.0 2600.0 2900.0 3300.0 +1600.0 1700.0 2100.0 2400.0 2900.0 3300.0 +1500.0 1600.0 1900.0 2100.0 2500.0 3100.0 +1700.0 1900.0 2100.0 2400.0 2700.0 3100.0 +1400.0 1500.0 2100.0 2800.0 3100.0 3200.0 +1400.0 1600.0 2100.0 2800.0 3000.0 3200.0 +1700.0 1800.0 2100.0 2700.0 2800.0 3100.0 +1600.0 1700.0 2100.0 2600.0 2700.0 3000.0 +1500.0 1600.0 2100.0 2600.0 2700.0 3100.0 +1600.0 1700.0 2000.0 2500.0 2900.0 3200.0 +1900.0 2000.0 2300.0 2400.0 2700.0 3100.0 +1900.0 2100.0 2300.0 2500.0 2700.0 3100.0 +1900.0 2100.0 2400.0 2600.0 2800.0 3100.0 +1700.0 2200.0 2400.0 2700.0 3100.0 3200.0 +1600.0 2000.0 2600.0 2900.0 3200.0 3300.0 +2000.0 2100.0 2300.0 2500.0 2800.0 3100.0 +1800.0 1900.0 2200.0 2400.0 2800.0 3200.0 +1900.0 2100.0 2700.0 2900.0 3200.0 3400.0 +1800.0 2100.0 2300.0 2800.0 2900.0 3100.0 +1800.0 2000.0 2200.0 2700.0 2900.0 3000.0 +1800.0 1900.0 2200.0 2700.0 2900.0 3000.0 +2100.0 2200.0 2600.0 2800.0 3000.0 3200.0 +1600.0 1700.0 2100.0 2400.0 2700.0 3100.0 +1800.0 2000.0 2200.0 2300.0 2600.0 3100.0 +1700.0 1900.0 2300.0 2600.0 2700.0 3000.0 +1800.0 2000.0 2300.0 2500.0 2900.0 3200.0 +1200.0 1400.0 2300.0 2700.0 3100.0 3300.0 +1600.0 1800.0 2300.0 2800.0 3000.0 3200.0 +1600.0 1800.0 2300.0 2700.0 3000.0 3100.0 +1700.0 1800.0 2300.0 2700.0 2900.0 3000.0 +1400.0 1500.0 2000.0 2200.0 2900.0 3200.0 +2000.0 2300.0 2400.0 2700.0 2900.0 3100.0 +1400.0 2100.0 2400.0 2800.0 3100.0 3200.0 +1500.0 1600.0 1900.0 2100.0 2900.0 3200.0 +1500.0 1700.0 2400.0 2600.0 3000.0 3200.0 +1300.0 1500.0 2300.0 2700.0 3100.0 3300.0 +1600.0 2100.0 2300.0 2600.0 3000.0 3200.0 +1900.0 2300.0 2400.0 2700.0 3000.0 3100.0 +1700.0 2300.0 2600.0 2900.0 3200.0 3300.0 +1700.0 2000.0 2200.0 2600.0 2800.0 3100.0 +1800.0 1900.0 2200.0 2600.0 2800.0 3100.0 +2000.0 2100.0 2500.0 2800.0 3000.0 3300.0 +2000.0 2100.0 2700.0 2900.0 3100.0 3300.0 +2100.0 2300.0 2800.0 2900.0 3100.0 3300.0 +1800.0 1900.0 2100.0 2500.0 2800.0 3200.0 +1700.0 1800.0 2200.0 2500.0 2700.0 3000.0 +1500.0 1700.0 2100.0 2500.0 2800.0 3100.0 +1800.0 2100.0 2400.0 2900.0 3200.0 3300.0 +1800.0 2100.0 2700.0 2900.0 3100.0 3300.0 +1700.0 2000.0 2200.0 2500.0 2800.0 3100.0 +1300.0 1900.0 2200.0 2600.0 2800.0 3000.0 +1400.0 1900.0 2300.0 2700.0 2900.0 3200.0 +1800.0 2200.0 2500.0 2800.0 3000.0 3100.0 +1800.0 2300.0 2600.0 2700.0 3000.0 3200.0 +1500.0 1700.0 2200.0 2500.0 2800.0 3100.0 +1500.0 1700.0 2100.0 2600.0 2800.0 3100.0 +1400.0 1500.0 1900.0 2700.0 3100.0 3200.0 +2000.0 2500.0 2900.0 3100.0 3300.0 3400.0 +1200.0 1800.0 2400.0 2700.0 3100.0 3300.0 +1700.0 1900.0 2100.0 2500.0 2700.0 3100.0 +1500.0 2300.0 2500.0 2700.0 2900.0 3100.0 +1700.0 1800.0 2200.0 2600.0 2700.0 3000.0 +1800.0 1900.0 2300.0 2500.0 2700.0 3100.0 +1900.0 2000.0 2300.0 2600.0 3000.0 3300.0 +1400.0 1600.0 2200.0 2600.0 2800.0 3200.0 +1400.0 1700.0 2300.0 2600.0 3000.0 3100.0 +1500.0 1700.0 2100.0 2500.0 2800.0 3200.0 +2200.0 2600.0 2900.0 3100.0 3400.0 3500.0 +2200.0 2500.0 2900.0 3100.0 3300.0 3500.0 +1800.0 2100.0 2400.0 2900.0 3100.0 3300.0 +1600.0 1800.0 2300.0 2600.0 2900.0 3100.0 +1200.0 1400.0 2200.0 2400.0 3000.0 3200.0 +1300.0 1700.0 2100.0 2400.0 2900.0 3100.0 +1600.0 1700.0 2100.0 2200.0 3000.0 3200.0 +1500.0 1600.0 2500.0 2800.0 3100.0 3300.0 +1400.0 1600.0 2300.0 2700.0 3000.0 3300.0 +1400.0 1600.0 2200.0 2500.0 2900.0 3100.0 +1300.0 1600.0 2300.0 2600.0 3100.0 3300.0 +1600.0 1700.0 2200.0 2400.0 2900.0 3200.0 +1700.0 1800.0 2100.0 2300.0 3000.0 3300.0 +1300.0 1400.0 2300.0 2600.0 2900.0 3200.0 +1300.0 1500.0 2300.0 2500.0 2900.0 3200.0 +1800.0 1900.0 2200.0 2400.0 2700.0 3100.0 +1800.0 1900.0 2200.0 2400.0 2800.0 3100.0 +1600.0 1700.0 2200.0 2400.0 2700.0 3100.0 +1400.0 1600.0 2200.0 2500.0 3000.0 3300.0 +1500.0 1700.0 2200.0 2400.0 3000.0 3400.0 +1600.0 1700.0 2200.0 2500.0 2700.0 3200.0 +1700.0 1800.0 2100.0 2200.0 2800.0 3200.0 +1600.0 1700.0 2100.0 2200.0 3100.0 3300.0 +1500.0 1600.0 2100.0 2200.0 3100.0 3300.0 +1000.0 1800.0 2200.0 2500.0 3100.0 3300.0 +1100.0 1700.0 2200.0 2500.0 3000.0 3200.0 +1400.0 1800.0 2100.0 2400.0 2800.0 3000.0 +1500.0 1800.0 2500.0 2700.0 3000.0 3200.0 +1900.0 2500.0 2800.0 3000.0 3400.0 3500.0 +2000.0 2500.0 2900.0 3200.0 3400.0 3500.0 +1400.0 1700.0 2300.0 2500.0 3000.0 3300.0 +1400.0 1900.0 2300.0 2500.0 3000.0 3200.0 +1400.0 2000.0 2300.0 2600.0 2900.0 3100.0 +1400.0 1900.0 2200.0 2500.0 2700.0 3100.0 +1600.0 1800.0 2000.0 2400.0 3000.0 3200.0 +1300.0 1800.0 2400.0 2700.0 3100.0 3300.0 +1400.0 1600.0 2400.0 2600.0 3100.0 3200.0 +1400.0 1500.0 1600.0 2400.0 3200.0 3300.0 +1900.0 2300.0 2600.0 2900.0 3100.0 3200.0 +1100.0 1700.0 2500.0 2600.0 3100.0 3300.0 +1300.0 1700.0 2400.0 2500.0 3000.0 3300.0 +1400.0 1700.0 2400.0 2500.0 3000.0 3400.0 +1400.0 1600.0 2400.0 2500.0 2900.0 3400.0 +1400.0 1700.0 2400.0 2500.0 3100.0 3400.0 +1500.0 1600.0 2300.0 2600.0 3200.0 3300.0 +1500.0 1600.0 2300.0 2400.0 3000.0 3200.0 +1600.0 1800.0 2200.0 2300.0 3000.0 3100.0 +1500.0 1900.0 2400.0 2700.0 3000.0 3200.0 +1300.0 1800.0 2400.0 2700.0 3300.0 3400.0 +1400.0 1700.0 2200.0 2500.0 2900.0 3200.0 +1800.0 2100.0 2500.0 2700.0 3100.0 3400.0 +1000.0 1500.0 1800.0 2200.0 3000.0 3100.0 +2100.0 2600.0 2900.0 3100.0 3300.0 3400.0 +1900.0 2000.0 2200.0 2500.0 3100.0 3300.0 +1700.0 1900.0 2300.0 2600.0 2900.0 3300.0 +1600.0 1800.0 2000.0 2200.0 3100.0 3300.0 +1300.0 1700.0 2300.0 2600.0 3100.0 3200.0 +1400.0 2100.0 2400.0 2700.0 3100.0 3300.0 +1200.0 1500.0 2200.0 2600.0 3200.0 3300.0 +1500.0 1600.0 2300.0 2500.0 3000.0 3100.0 +1600.0 1900.0 2300.0 2500.0 3000.0 3100.0 +1500.0 1800.0 2600.0 2800.0 3200.0 3400.0 +1600.0 1700.0 2300.0 2500.0 3100.0 3400.0 +1500.0 1600.0 2300.0 2600.0 3100.0 3400.0 +1200.0 1500.0 2500.0 2600.0 3100.0 3400.0 +1200.0 1500.0 2500.0 2600.0 3100.0 3300.0 +1200.0 1600.0 2500.0 2600.0 3100.0 3300.0 +1900.0 2300.0 2600.0 2900.0 3400.0 3500.0 +900.0 1500.0 2600.0 2700.0 3100.0 3200.0 +2100.0 2500.0 2900.0 3100.0 3300.0 3400.0 +1400.0 2100.0 2300.0 2500.0 3000.0 3300.0 +1200.0 1600.0 1700.0 2300.0 3100.0 3200.0 +1100.0 1800.0 2200.0 2600.0 3000.0 3200.0 +1500.0 2000.0 2400.0 2700.0 3100.0 3200.0 +2000.0 2100.0 2400.0 2600.0 2900.0 3300.0 +1400.0 2100.0 2500.0 2700.0 3100.0 3200.0 +1200.0 1600.0 2300.0 2500.0 3000.0 3200.0 +1500.0 1600.0 2300.0 2500.0 3100.0 3200.0 +2300.0 2500.0 2700.0 2800.0 3100.0 3300.0 +2200.0 2300.0 2500.0 2700.0 3100.0 3200.0 +1300.0 1900.0 2300.0 2500.0 2800.0 3000.0 +1200.0 1800.0 2300.0 2500.0 3000.0 3300.0 +1400.0 1600.0 2400.0 2600.0 3200.0 3400.0 +1500.0 1600.0 2300.0 2500.0 3100.0 3400.0 +1400.0 1900.0 2400.0 2500.0 2700.0 3100.0 +1200.0 1600.0 2200.0 2600.0 3100.0 3300.0 +1300.0 1600.0 2300.0 2600.0 3100.0 3400.0 +1500.0 1600.0 2200.0 2500.0 3100.0 3400.0 +1600.0 2000.0 2500.0 2700.0 3000.0 3200.0 +1600.0 1700.0 2000.0 2300.0 3000.0 3200.0 +1400.0 1700.0 1800.0 2300.0 3100.0 3200.0 +2100.0 2200.0 2400.0 2600.0 3200.0 3300.0 +1600.0 1900.0 2400.0 2500.0 2700.0 3200.0 +2200.0 2300.0 2500.0 2700.0 3100.0 3300.0 +2200.0 2300.0 2600.0 2700.0 3100.0 3300.0 +1400.0 1800.0 2300.0 2500.0 2800.0 3200.0 +1600.0 1800.0 2300.0 2500.0 2700.0 3100.0 +1400.0 1600.0 1800.0 2500.0 2900.0 3000.0 +1400.0 1600.0 1900.0 2600.0 3000.0 3200.0 +1500.0 1700.0 2000.0 2600.0 3000.0 3200.0 +1400.0 1700.0 2400.0 2500.0 3100.0 3300.0 +2300.0 2400.0 2700.0 3000.0 3200.0 3400.0 +1300.0 1700.0 2100.0 2300.0 3100.0 3200.0 +1300.0 1700.0 2100.0 2300.0 3000.0 3100.0 +1300.0 1700.0 2000.0 2200.0 3000.0 3100.0 +1400.0 1700.0 1900.0 2300.0 3000.0 3100.0 +1400.0 1600.0 1800.0 2300.0 2900.0 3000.0 +1300.0 1800.0 2400.0 2600.0 3000.0 3300.0 +2200.0 2300.0 2500.0 2800.0 3000.0 3200.0 +1900.0 2200.0 2400.0 2600.0 2900.0 3300.0 +1900.0 2100.0 2400.0 2600.0 3200.0 3400.0 +1900.0 2400.0 2600.0 2800.0 3200.0 3400.0 +1800.0 2100.0 2500.0 2600.0 3200.0 3400.0 +1500.0 1900.0 2400.0 2600.0 2900.0 3100.0 +1200.0 1600.0 2300.0 2500.0 3200.0 3300.0 +1100.0 1400.0 2300.0 2400.0 3000.0 3300.0 +1000.0 1800.0 2400.0 2500.0 3300.0 3400.0 +1000.0 1700.0 2400.0 2500.0 3300.0 3400.0 +2000.0 2400.0 2800.0 3000.0 3300.0 3500.0 +1400.0 2100.0 2500.0 2700.0 3300.0 3400.0 +1200.0 1900.0 2500.0 2600.0 3200.0 3300.0 +1400.0 2000.0 2500.0 2600.0 3100.0 3300.0 +1800.0 2200.0 2700.0 3000.0 3300.0 3500.0 +1700.0 2200.0 2400.0 2700.0 3100.0 3300.0 +1000.0 2000.0 2300.0 2400.0 3300.0 3400.0 +1400.0 1900.0 2400.0 2600.0 3300.0 3400.0 +1300.0 1800.0 2400.0 2500.0 3100.0 3300.0 +1600.0 2000.0 2500.0 2600.0 3200.0 3300.0 +2100.0 2500.0 2700.0 3000.0 3200.0 3400.0 +1600.0 2000.0 2300.0 2400.0 3200.0 3300.0 +1400.0 1700.0 1900.0 2100.0 3300.0 3400.0 +1500.0 1700.0 2000.0 2200.0 3200.0 3300.0 +1500.0 1800.0 2200.0 2300.0 2600.0 2900.0 +1600.0 1700.0 2300.0 2500.0 2800.0 3000.0 +1600.0 1700.0 2200.0 2300.0 2900.0 3200.0 +1300.0 1500.0 2300.0 2400.0 2800.0 3200.0 +1400.0 1700.0 2300.0 2400.0 3000.0 3200.0 +1600.0 1700.0 2100.0 2300.0 2900.0 3300.0 +1500.0 2100.0 2300.0 2600.0 3100.0 3300.0 +1100.0 1500.0 2200.0 2300.0 3100.0 3300.0 +1000.0 1800.0 2300.0 2400.0 3100.0 3200.0 +900.0 1800.0 2400.0 2500.0 3100.0 3200.0 +1000.0 1800.0 2400.0 2500.0 3100.0 3200.0 +1700.0 2200.0 2500.0 2900.0 3400.0 3500.0 +1300.0 1900.0 2300.0 2400.0 3300.0 3400.0 +1100.0 1900.0 2300.0 2400.0 3200.0 3300.0 +1200.0 1700.0 2300.0 2400.0 3200.0 3400.0 +1300.0 1700.0 2300.0 2500.0 3200.0 3300.0 +1200.0 1500.0 2200.0 2300.0 3000.0 3200.0 +1200.0 1800.0 2200.0 2300.0 3000.0 3200.0 +1000.0 1800.0 2400.0 2500.0 3100.0 3300.0 +900.0 1800.0 2600.0 2700.0 3300.0 3400.0 +900.0 1900.0 2700.0 2800.0 3300.0 3400.0 +1800.0 2400.0 2700.0 3100.0 3400.0 3500.0 +1400.0 1600.0 2200.0 2400.0 2900.0 3200.0 +1700.0 2300.0 2500.0 2700.0 3300.0 3400.0 +1400.0 1900.0 2400.0 2600.0 3200.0 3400.0 +1300.0 1500.0 2200.0 2400.0 2700.0 3100.0 +1500.0 1600.0 2000.0 2200.0 2900.0 3100.0 +1500.0 1600.0 1800.0 1900.0 2800.0 3300.0 +1700.0 1800.0 2000.0 2300.0 3000.0 3300.0 +2200.0 2400.0 2600.0 2700.0 3300.0 3400.0 +1700.0 1900.0 2300.0 2400.0 3200.0 3300.0 +1300.0 1900.0 2200.0 2400.0 2700.0 3100.0 +1700.0 2300.0 2600.0 3000.0 3300.0 3400.0 +2200.0 2300.0 2500.0 2700.0 3100.0 3400.0 +1600.0 1800.0 2000.0 2200.0 3200.0 3300.0 +2100.0 2500.0 2700.0 2900.0 3400.0 3500.0 +2100.0 2400.0 2600.0 2700.0 3100.0 3300.0 +2100.0 2400.0 2700.0 3100.0 3300.0 3400.0 +1400.0 1700.0 2200.0 2600.0 2900.0 3200.0 +1000.0 1900.0 2200.0 2400.0 3100.0 3200.0 +1100.0 1600.0 2500.0 2600.0 3100.0 3300.0 +1300.0 1600.0 2200.0 2300.0 2800.0 3300.0 +1000.0 2000.0 2500.0 2600.0 3300.0 3400.0 +1700.0 2200.0 2400.0 2700.0 3200.0 3400.0 +1200.0 2000.0 2400.0 2500.0 3100.0 3200.0 +1100.0 1700.0 2100.0 2200.0 3000.0 3200.0 +1100.0 1600.0 2100.0 2200.0 3100.0 3300.0 +1100.0 1600.0 2200.0 2300.0 3200.0 3300.0 +1300.0 1700.0 2300.0 2400.0 3300.0 3400.0 +1300.0 1800.0 2300.0 2400.0 3300.0 3400.0 +1000.0 1800.0 2300.0 2400.0 3100.0 3300.0 +1400.0 2000.0 2300.0 2500.0 2900.0 3200.0 +1100.0 1900.0 2400.0 2500.0 3100.0 3200.0 +1000.0 2000.0 2600.0 2700.0 3300.0 3400.0 +1200.0 1600.0 2200.0 2300.0 3100.0 3300.0 +1300.0 1800.0 2200.0 2300.0 3200.0 3300.0 +1000.0 1700.0 2400.0 2600.0 3300.0 3400.0 +1000.0 1700.0 2400.0 2600.0 3200.0 3300.0 +2000.0 2400.0 2700.0 3100.0 3300.0 3400.0 +1500.0 1900.0 2200.0 2400.0 3200.0 3300.0 +1400.0 1700.0 2100.0 2200.0 3100.0 3300.0 +2200.0 2400.0 2600.0 2900.0 3300.0 3400.0 +1300.0 1900.0 2100.0 2500.0 3000.0 3200.0 +1900.0 2100.0 2300.0 2400.0 3000.0 3300.0 +1100.0 2200.0 2600.0 2700.0 3300.0 3400.0 +1700.0 1900.0 2400.0 2500.0 3000.0 3400.0 +1800.0 2100.0 2600.0 2900.0 3100.0 3400.0 +1900.0 2300.0 2900.0 3100.0 3300.0 3400.0 +1900.0 2400.0 2600.0 3000.0 3300.0 3500.0 +1400.0 2100.0 2400.0 2500.0 2700.0 3000.0 +1300.0 1600.0 1900.0 2100.0 2900.0 3000.0 +1900.0 2000.0 2200.0 2300.0 3000.0 3300.0 +1300.0 1600.0 2200.0 2500.0 3000.0 3300.0 +1100.0 1800.0 2300.0 2500.0 3100.0 3300.0 +1100.0 1700.0 2300.0 2500.0 3000.0 3200.0 +1200.0 1600.0 2300.0 2400.0 3000.0 3200.0 +1300.0 1600.0 2200.0 2400.0 2900.0 3200.0 +1800.0 2300.0 2600.0 3000.0 3300.0 3500.0 +1500.0 2000.0 2400.0 2700.0 3200.0 3400.0 +1800.0 2000.0 2200.0 2500.0 2800.0 3000.0 +1800.0 2100.0 2300.0 2400.0 2700.0 3000.0 +1800.0 2100.0 2300.0 2500.0 2900.0 3200.0 +1700.0 1900.0 2100.0 2700.0 2900.0 3200.0 +1800.0 2100.0 2300.0 2600.0 2900.0 3000.0 +1600.0 1800.0 2100.0 2400.0 2600.0 2900.0 +1800.0 1900.0 2400.0 2800.0 3000.0 3100.0 +2000.0 2400.0 2700.0 2900.0 3200.0 3400.0 +1900.0 2100.0 2800.0 2900.0 3200.0 3400.0 +2000.0 2100.0 2500.0 2800.0 2900.0 3100.0 +1800.0 1900.0 2500.0 2600.0 2900.0 3300.0 +1600.0 1700.0 2000.0 2100.0 3000.0 3200.0 +1600.0 1700.0 2000.0 2100.0 2900.0 3200.0 +2000.0 2200.0 2400.0 2800.0 3100.0 3300.0 +2100.0 2300.0 2800.0 2900.0 3300.0 3400.0 +1900.0 2000.0 2300.0 2400.0 2900.0 3100.0 +1500.0 1800.0 2300.0 2500.0 3000.0 3300.0 +1200.0 1800.0 2500.0 2600.0 2900.0 3000.0 +1400.0 1700.0 2200.0 2600.0 2900.0 3000.0 +1500.0 1700.0 2200.0 2600.0 3000.0 3100.0 +1700.0 1800.0 2100.0 2400.0 2900.0 3200.0 +1800.0 1900.0 2200.0 2600.0 2900.0 3200.0 +1800.0 2000.0 2200.0 2400.0 2800.0 3100.0 +1400.0 1600.0 1900.0 2100.0 2700.0 3200.0 +1500.0 2000.0 2200.0 2500.0 3000.0 3200.0 +1700.0 1800.0 2000.0 2200.0 3100.0 3300.0 +1800.0 1900.0 2100.0 2400.0 3000.0 3100.0 +1800.0 2100.0 2400.0 2600.0 3000.0 3100.0 +2000.0 2300.0 2600.0 2800.0 3000.0 3300.0 +2100.0 2300.0 2800.0 2900.0 3200.0 3400.0 +1800.0 1900.0 2500.0 2800.0 3100.0 3200.0 +1800.0 2000.0 2200.0 2500.0 2900.0 3000.0 +1700.0 1800.0 2100.0 2700.0 2900.0 3000.0 +1700.0 1800.0 2600.0 2800.0 3100.0 3300.0 +1600.0 2000.0 2300.0 2800.0 3100.0 3300.0 +1500.0 1600.0 1900.0 2000.0 2900.0 3200.0 +2100.0 2300.0 2700.0 2800.0 3000.0 3200.0 +2000.0 2200.0 2400.0 2600.0 3100.0 3200.0 +1800.0 2100.0 2400.0 2500.0 3000.0 3200.0 +1800.0 2100.0 2500.0 2600.0 2900.0 3200.0 +2100.0 2400.0 2800.0 2900.0 3300.0 3400.0 +1800.0 2000.0 2300.0 2600.0 3100.0 3400.0 +1700.0 2000.0 2300.0 2600.0 2900.0 3300.0 +1800.0 1900.0 2300.0 2500.0 2800.0 3000.0 +1400.0 1600.0 2200.0 2500.0 2900.0 3300.0 +1600.0 1700.0 2100.0 2300.0 2600.0 3100.0 +1700.0 1800.0 2100.0 2500.0 2800.0 3200.0 +1500.0 1600.0 2200.0 2700.0 2800.0 3200.0 +2100.0 2300.0 2700.0 2800.0 3100.0 3300.0 +1600.0 1700.0 2000.0 2400.0 3000.0 3300.0 +1500.0 1600.0 2600.0 2800.0 3100.0 3300.0 +1800.0 2000.0 2400.0 2600.0 2900.0 3100.0 +1700.0 1800.0 2300.0 2500.0 2600.0 3100.0 +1500.0 1800.0 2100.0 2500.0 2900.0 3300.0 +1600.0 1800.0 2100.0 2500.0 3000.0 3300.0 +1700.0 1800.0 2300.0 2400.0 2800.0 3100.0 +1600.0 1700.0 2000.0 2300.0 2800.0 3100.0 +1700.0 1800.0 2200.0 2400.0 2700.0 3100.0 +2000.0 2500.0 2800.0 3000.0 3400.0 3500.0 +1900.0 2400.0 2800.0 2900.0 3400.0 3500.0 +1600.0 1700.0 2400.0 2700.0 2900.0 3100.0 +1600.0 1700.0 2500.0 2600.0 2900.0 3100.0 +1500.0 1700.0 2200.0 2600.0 2900.0 3100.0 +1700.0 2000.0 2200.0 2500.0 2900.0 3200.0 +1500.0 1700.0 2200.0 2700.0 3200.0 3300.0 +1400.0 1500.0 2100.0 2500.0 3000.0 3200.0 +1200.0 1500.0 2200.0 2400.0 2800.0 3200.0 +1500.0 1600.0 2000.0 2100.0 2900.0 3200.0 +1800.0 1900.0 2100.0 2500.0 2900.0 3200.0 +1500.0 1800.0 2300.0 2500.0 2800.0 3200.0 +1500.0 1800.0 2500.0 2800.0 3100.0 3300.0 +1300.0 1800.0 2500.0 2600.0 3000.0 3100.0 +1600.0 1800.0 2300.0 2700.0 2900.0 3000.0 +1500.0 1600.0 2200.0 2400.0 2600.0 3100.0 +1600.0 2000.0 2500.0 2600.0 3000.0 3300.0 +1500.0 1600.0 2000.0 2600.0 2800.0 3000.0 +1500.0 1600.0 2200.0 2600.0 2700.0 3000.0 +1200.0 1600.0 2200.0 2400.0 3000.0 3200.0 +1800.0 2300.0 2500.0 2800.0 3000.0 3100.0 +1500.0 1600.0 2500.0 2800.0 2900.0 3200.0 +1300.0 1500.0 2300.0 2800.0 3100.0 3200.0 +1700.0 1800.0 2100.0 2500.0 2800.0 3000.0 +1400.0 1800.0 2200.0 2600.0 3000.0 3200.0 +1500.0 1700.0 2000.0 2700.0 3100.0 3200.0 +1400.0 1600.0 2300.0 2600.0 3000.0 3300.0 +1700.0 2100.0 2700.0 2900.0 3300.0 3500.0 +1700.0 1800.0 2300.0 2700.0 2800.0 3100.0 +1600.0 1800.0 2200.0 2600.0 2700.0 3000.0 +1900.0 2300.0 2400.0 2600.0 2800.0 3100.0 +1300.0 1600.0 2100.0 2200.0 3100.0 3300.0 +1500.0 1800.0 2400.0 2700.0 3000.0 3100.0 +1600.0 1800.0 2000.0 2600.0 2900.0 3000.0 +1600.0 1800.0 2100.0 2700.0 2900.0 3000.0 +1600.0 1700.0 2300.0 2700.0 3000.0 3100.0 +1700.0 1800.0 2400.0 2700.0 2900.0 3100.0 +1800.0 1900.0 2500.0 2600.0 3000.0 3100.0 +1700.0 1800.0 2100.0 2400.0 2700.0 3200.0 +1700.0 2000.0 2200.0 2500.0 2800.0 3000.0 +2000.0 2400.0 2500.0 2700.0 3000.0 3100.0 +1800.0 2000.0 2600.0 2700.0 3100.0 3200.0 +2200.0 2400.0 2700.0 2900.0 3100.0 3300.0 +2300.0 2500.0 2700.0 2900.0 3100.0 3300.0 +1800.0 2200.0 2300.0 2600.0 3000.0 3100.0 +1700.0 2100.0 2300.0 2800.0 3100.0 3200.0 +2000.0 2400.0 2600.0 2800.0 3000.0 3200.0 +1500.0 2000.0 2200.0 2600.0 3100.0 3300.0 +1100.0 1600.0 2200.0 2600.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2500.0 2700.0 3000.0 +1900.0 2300.0 2400.0 2600.0 2800.0 3000.0 +1700.0 2100.0 2300.0 2600.0 2900.0 3000.0 +1600.0 1700.0 2000.0 2200.0 2600.0 3100.0 +1600.0 1900.0 2200.0 2400.0 3000.0 3100.0 +1300.0 2000.0 2300.0 2600.0 3100.0 3300.0 +1600.0 2100.0 2300.0 2600.0 2900.0 3000.0 +1700.0 2100.0 2300.0 2500.0 2800.0 3000.0 +1600.0 2100.0 2300.0 2500.0 2800.0 3000.0 +1500.0 1800.0 2000.0 2300.0 2800.0 2900.0 +1300.0 1600.0 2300.0 2600.0 2900.0 3200.0 +1200.0 1700.0 2100.0 2600.0 3100.0 3300.0 +1800.0 2200.0 2600.0 2700.0 3200.0 3300.0 +1600.0 1700.0 1900.0 2100.0 3100.0 3200.0 +1500.0 2000.0 2300.0 2500.0 3000.0 3300.0 +1600.0 1700.0 2000.0 2500.0 2700.0 2900.0 +1600.0 1800.0 2100.0 2500.0 2900.0 3000.0 +1600.0 1700.0 2100.0 2500.0 2700.0 2900.0 +1600.0 1700.0 2200.0 2500.0 2700.0 2900.0 +1500.0 1700.0 2000.0 2600.0 2800.0 3000.0 +1200.0 1600.0 2200.0 2400.0 2800.0 3000.0 +1800.0 2200.0 2400.0 2600.0 2800.0 3000.0 +1700.0 2000.0 2200.0 2500.0 2700.0 3100.0 +1700.0 2000.0 2200.0 2500.0 2700.0 3000.0 +1600.0 1900.0 2300.0 2600.0 2800.0 3200.0 +1200.0 1400.0 2000.0 2600.0 2800.0 3000.0 +1400.0 1600.0 2200.0 2600.0 3000.0 3300.0 +1500.0 1700.0 2200.0 2400.0 2700.0 2900.0 +1600.0 1700.0 2200.0 2500.0 2800.0 3000.0 +1600.0 1700.0 2100.0 2400.0 2700.0 3000.0 +1900.0 2100.0 2400.0 2600.0 3000.0 3100.0 +1900.0 2500.0 2700.0 2800.0 3100.0 3200.0 +1800.0 2200.0 2500.0 2600.0 3000.0 3200.0 +1900.0 2200.0 2400.0 2500.0 2800.0 3100.0 +1800.0 2100.0 2300.0 2500.0 2700.0 3000.0 +2000.0 2300.0 2400.0 2600.0 2900.0 3100.0 +1400.0 1600.0 1800.0 1900.0 2700.0 3200.0 +1400.0 1600.0 1700.0 1900.0 2800.0 3100.0 +2100.0 2200.0 2600.0 3000.0 3200.0 3300.0 +1700.0 2000.0 2200.0 2400.0 2700.0 2900.0 +1500.0 1600.0 1900.0 2400.0 2600.0 2700.0 +1600.0 1700.0 2000.0 2400.0 2600.0 2800.0 +1900.0 2000.0 2500.0 2800.0 2900.0 3200.0 +1500.0 1600.0 1900.0 2100.0 2700.0 3200.0 +1500.0 1700.0 2000.0 2200.0 2900.0 3300.0 +1800.0 2000.0 2700.0 2800.0 3200.0 3300.0 +1700.0 1800.0 2400.0 2700.0 3300.0 3400.0 +1600.0 1900.0 2500.0 2700.0 3300.0 3400.0 +1200.0 1800.0 2100.0 2400.0 3100.0 3200.0 +1200.0 1800.0 2100.0 2500.0 3200.0 3300.0 +1600.0 1700.0 2200.0 2600.0 2900.0 3200.0 +1800.0 2200.0 2500.0 2600.0 3200.0 3400.0 +1000.0 1900.0 2600.0 2700.0 3200.0 3300.0 +1100.0 2000.0 2600.0 2700.0 3200.0 3300.0 +1300.0 1800.0 2500.0 2700.0 3200.0 3300.0 +1400.0 1700.0 1800.0 2400.0 3000.0 3100.0 +1500.0 1800.0 2000.0 2400.0 3100.0 3200.0 +1200.0 1400.0 1500.0 2300.0 3100.0 3200.0 +2100.0 2200.0 2500.0 2600.0 3100.0 3200.0 +1400.0 1600.0 2100.0 2400.0 2900.0 3100.0 +1400.0 1500.0 2100.0 2400.0 2800.0 3200.0 +1100.0 2000.0 2300.0 2500.0 3200.0 3300.0 +1200.0 2000.0 2300.0 2700.0 3100.0 3200.0 +1300.0 1700.0 2200.0 2500.0 2900.0 3000.0 +1400.0 1700.0 1900.0 2600.0 2900.0 3100.0 +1200.0 2000.0 2300.0 2700.0 3200.0 3300.0 +1500.0 2200.0 2400.0 2600.0 3200.0 3300.0 +1400.0 1800.0 2000.0 2500.0 3000.0 3100.0 +1400.0 2000.0 2300.0 2500.0 3200.0 3300.0 +1900.0 2400.0 2600.0 2700.0 3100.0 3300.0 +1300.0 1600.0 1700.0 2200.0 3000.0 3100.0 +1300.0 1600.0 2500.0 2600.0 3100.0 3300.0 +1500.0 1700.0 2500.0 2600.0 3200.0 3300.0 +1300.0 1600.0 2400.0 2600.0 3200.0 3400.0 +1400.0 2000.0 2300.0 2500.0 2700.0 3000.0 +1500.0 1900.0 2300.0 2500.0 2700.0 3100.0 +1500.0 1600.0 1800.0 2500.0 2800.0 3000.0 +1300.0 1800.0 2200.0 2600.0 3100.0 3200.0 +1300.0 1900.0 2100.0 2500.0 3100.0 3200.0 +1300.0 1700.0 2100.0 2400.0 3100.0 3300.0 +1300.0 1900.0 2300.0 2600.0 3000.0 3200.0 +1200.0 1900.0 2500.0 2600.0 3300.0 3400.0 +1700.0 2200.0 2500.0 2600.0 3200.0 3400.0 +1600.0 2000.0 2200.0 2300.0 3100.0 3200.0 +1800.0 1900.0 2300.0 2600.0 3200.0 3300.0 +1800.0 1900.0 2100.0 2500.0 3200.0 3300.0 +1900.0 2000.0 2100.0 2500.0 3300.0 3400.0 +1700.0 2100.0 2600.0 2800.0 3300.0 3500.0 +1600.0 1800.0 2200.0 2700.0 3200.0 3300.0 +1400.0 2000.0 2300.0 2400.0 2600.0 3000.0 +1400.0 1600.0 2100.0 2300.0 3100.0 3200.0 +1100.0 1900.0 2500.0 2600.0 3300.0 3400.0 +1200.0 1600.0 2300.0 2600.0 3100.0 3400.0 +1400.0 1600.0 2100.0 2400.0 3000.0 3300.0 +1400.0 1700.0 2100.0 2500.0 3100.0 3300.0 +1200.0 2000.0 2700.0 2800.0 3300.0 3400.0 +1700.0 1800.0 2000.0 2300.0 3300.0 3400.0 +1300.0 1600.0 1800.0 2100.0 3100.0 3200.0 +1800.0 1900.0 2100.0 2200.0 3200.0 3400.0 +1800.0 1900.0 2100.0 2300.0 3300.0 3400.0 +1800.0 1900.0 2200.0 2300.0 3100.0 3300.0 +1800.0 2300.0 2800.0 2900.0 3200.0 3300.0 +1900.0 2200.0 2500.0 2600.0 3200.0 3300.0 +1300.0 1600.0 2300.0 2500.0 2900.0 3300.0 +1400.0 1600.0 2300.0 2500.0 2900.0 3300.0 +1400.0 1700.0 2400.0 2500.0 2900.0 3200.0 +1500.0 1700.0 2100.0 2200.0 3100.0 3200.0 +1500.0 1700.0 2100.0 2200.0 3100.0 3300.0 +1500.0 1600.0 2100.0 2300.0 2900.0 3300.0 +1300.0 1900.0 2200.0 2500.0 3000.0 3200.0 +1200.0 1900.0 2200.0 2500.0 3000.0 3200.0 +1000.0 1300.0 2100.0 2200.0 2900.0 3200.0 +1400.0 1600.0 1700.0 2000.0 3300.0 3400.0 +1300.0 1500.0 1600.0 2000.0 3300.0 3400.0 +1300.0 1500.0 1700.0 1900.0 3300.0 3400.0 +1500.0 1600.0 2100.0 2300.0 3100.0 3400.0 +1500.0 1600.0 2300.0 2500.0 2700.0 3200.0 +1400.0 2000.0 2300.0 2400.0 2700.0 3200.0 +1200.0 1500.0 2400.0 2600.0 2900.0 3200.0 +1500.0 1600.0 2300.0 2400.0 2700.0 3300.0 +1500.0 1700.0 2200.0 2400.0 2600.0 3100.0 +1500.0 1700.0 2300.0 2500.0 3100.0 3400.0 +1600.0 1700.0 2400.0 2600.0 3000.0 3400.0 +1600.0 1700.0 2500.0 2700.0 3100.0 3400.0 +1400.0 1500.0 2300.0 2400.0 3000.0 3300.0 +1500.0 1600.0 2100.0 2300.0 3000.0 3200.0 +1500.0 1600.0 2200.0 2400.0 2900.0 3200.0 +1500.0 1700.0 2400.0 2500.0 2900.0 3200.0 +1400.0 1900.0 2200.0 2300.0 2800.0 3200.0 +1500.0 1800.0 2100.0 2200.0 3000.0 3300.0 +2000.0 2100.0 2500.0 2600.0 3000.0 3400.0 +1000.0 1600.0 2200.0 2300.0 3200.0 3400.0 +1300.0 1500.0 2300.0 2600.0 2900.0 3300.0 +1400.0 1600.0 2500.0 2600.0 2900.0 3200.0 +1400.0 1600.0 2100.0 2400.0 3100.0 3300.0 +1500.0 2000.0 2300.0 2500.0 3100.0 3300.0 +1000.0 1700.0 2100.0 2200.0 3200.0 3300.0 +1500.0 1700.0 2200.0 2400.0 3200.0 3400.0 +1600.0 1800.0 2300.0 2400.0 3000.0 3100.0 +1300.0 1500.0 2100.0 2200.0 3000.0 3300.0 +1200.0 1400.0 2200.0 2300.0 3000.0 3300.0 +1600.0 1700.0 1900.0 2200.0 3200.0 3300.0 +1700.0 1800.0 2200.0 2300.0 3000.0 3400.0 +1400.0 1500.0 2200.0 2500.0 2800.0 3100.0 +1800.0 1900.0 2300.0 2500.0 3000.0 3400.0 +1500.0 1700.0 2100.0 2500.0 2700.0 3100.0 +1600.0 1900.0 2400.0 2700.0 2900.0 3100.0 +1700.0 1800.0 2200.0 2500.0 2700.0 3300.0 +1800.0 1900.0 2400.0 2500.0 2800.0 3300.0 +1300.0 1600.0 2100.0 2300.0 3000.0 3300.0 +1300.0 2100.0 2300.0 2600.0 3200.0 3300.0 +1100.0 1500.0 2500.0 2600.0 3100.0 3400.0 +1600.0 1700.0 2200.0 2500.0 2600.0 3100.0 +1500.0 1600.0 2200.0 2500.0 2600.0 3100.0 +1600.0 2200.0 2600.0 2800.0 3100.0 3300.0 +2000.0 2200.0 2600.0 2700.0 3300.0 3400.0 +1500.0 2000.0 2200.0 2400.0 2600.0 2900.0 +1500.0 1800.0 2200.0 2400.0 3100.0 3400.0 +1800.0 2200.0 2600.0 2800.0 3400.0 3500.0 +1600.0 1700.0 2200.0 2600.0 3200.0 3400.0 +1800.0 2000.0 2300.0 2600.0 3200.0 3400.0 +1600.0 1800.0 2200.0 2600.0 3200.0 3400.0 +1500.0 1600.0 2100.0 2400.0 2800.0 3200.0 +1500.0 1800.0 2000.0 2600.0 3200.0 3300.0 +1200.0 1800.0 1900.0 2200.0 3100.0 3200.0 +1500.0 1600.0 2200.0 2400.0 3200.0 3300.0 +1800.0 1900.0 2600.0 2800.0 3000.0 3300.0 +1300.0 1600.0 2300.0 2400.0 3000.0 3100.0 +2000.0 2100.0 2400.0 2600.0 3000.0 3100.0 +2000.0 2100.0 2500.0 2600.0 2900.0 3100.0 +1800.0 2000.0 2500.0 2600.0 3000.0 3100.0 +1800.0 2300.0 2700.0 2800.0 3400.0 3500.0 +1200.0 1900.0 2200.0 2600.0 3100.0 3200.0 +1600.0 2000.0 2500.0 2700.0 3100.0 3400.0 +1900.0 2100.0 2600.0 2700.0 3000.0 3200.0 +1500.0 1900.0 2600.0 2800.0 3200.0 3300.0 +1600.0 1800.0 2200.0 2700.0 3200.0 3400.0 +1400.0 1800.0 2400.0 2600.0 2900.0 3200.0 +1500.0 1700.0 2500.0 2600.0 3000.0 3200.0 +1800.0 2100.0 2600.0 2800.0 3400.0 3500.0 +1700.0 2000.0 2600.0 2800.0 3000.0 3300.0 +1800.0 2100.0 2700.0 2900.0 3400.0 3500.0 +1600.0 1700.0 2600.0 2700.0 3100.0 3400.0 +1800.0 1900.0 2400.0 2600.0 2800.0 3000.0 +1600.0 2000.0 2500.0 2600.0 2900.0 3200.0 +1400.0 1800.0 2400.0 2500.0 2900.0 3100.0 +1500.0 1800.0 2400.0 2500.0 2900.0 3200.0 +1200.0 1400.0 2300.0 2500.0 2900.0 3200.0 +1400.0 1600.0 2500.0 2700.0 3000.0 3300.0 +1500.0 1900.0 2500.0 2700.0 3000.0 3300.0 +1000.0 1400.0 2600.0 2700.0 3100.0 3300.0 +1400.0 1700.0 2100.0 2300.0 2900.0 3000.0 +1700.0 1800.0 2400.0 2600.0 2800.0 3000.0 +1500.0 2000.0 2100.0 2500.0 3000.0 3100.0 +2000.0 2100.0 2300.0 2400.0 3100.0 3300.0 +2100.0 2200.0 2600.0 2800.0 3100.0 3200.0 +2100.0 2200.0 2600.0 2700.0 3000.0 3200.0 +1800.0 2000.0 2600.0 2800.0 3100.0 3400.0 +1700.0 2000.0 2500.0 2900.0 3100.0 3300.0 +1700.0 2000.0 2500.0 2900.0 3100.0 3400.0 +1600.0 1800.0 2500.0 2800.0 3000.0 3200.0 +1500.0 1800.0 2200.0 2700.0 3200.0 3300.0 +1500.0 1700.0 2300.0 2600.0 3200.0 3300.0 +1500.0 1600.0 2400.0 2600.0 2800.0 3100.0 +1200.0 1600.0 2200.0 2600.0 3000.0 3200.0 +1500.0 1600.0 2000.0 2300.0 2900.0 3200.0 +1900.0 2000.0 2400.0 2700.0 3200.0 3400.0 +1900.0 2000.0 2400.0 2700.0 2800.0 3200.0 +1500.0 1700.0 2300.0 2600.0 3200.0 3400.0 +1700.0 1800.0 2400.0 2500.0 2800.0 3100.0 +1500.0 1600.0 2200.0 2400.0 2900.0 3100.0 +1500.0 1600.0 2200.0 2500.0 3100.0 3300.0 +1600.0 2000.0 2200.0 2400.0 2700.0 3100.0 +1500.0 1700.0 2300.0 2600.0 2900.0 3300.0 +1700.0 1800.0 2100.0 2300.0 2900.0 3100.0 +1400.0 1500.0 2000.0 2500.0 2700.0 3000.0 +1800.0 1900.0 2300.0 2400.0 2800.0 3100.0 +1300.0 1800.0 2200.0 2500.0 2900.0 3100.0 +1300.0 1900.0 2300.0 2700.0 3200.0 3300.0 +1600.0 1700.0 2300.0 2500.0 2700.0 3100.0 +1600.0 1700.0 2200.0 2600.0 3100.0 3300.0 +1400.0 1500.0 2300.0 2500.0 2800.0 3000.0 +1300.0 1700.0 2100.0 2500.0 3000.0 3300.0 +1600.0 1800.0 2200.0 2400.0 2800.0 3200.0 +1400.0 1500.0 2200.0 2500.0 3200.0 3300.0 +1800.0 1900.0 2200.0 2500.0 3000.0 3100.0 +1300.0 1500.0 2200.0 2400.0 2900.0 3100.0 +1300.0 1500.0 2300.0 2500.0 3100.0 3300.0 +1100.0 1500.0 2400.0 2500.0 3000.0 3200.0 +1600.0 1700.0 2400.0 2600.0 2800.0 3100.0 +1500.0 1600.0 2400.0 2500.0 2800.0 3100.0 +1500.0 1600.0 2000.0 2500.0 2800.0 3100.0 +1200.0 1700.0 2400.0 2600.0 3200.0 3300.0 +1100.0 1600.0 2400.0 2500.0 3200.0 3400.0 +1100.0 1500.0 2400.0 2500.0 3000.0 3400.0 +1100.0 1600.0 2400.0 2500.0 3100.0 3300.0 +1900.0 2000.0 2400.0 2500.0 2900.0 3100.0 +1300.0 1500.0 2200.0 2300.0 2700.0 3100.0 +1600.0 1900.0 2500.0 2800.0 3200.0 3300.0 +1900.0 2100.0 2600.0 2900.0 3300.0 3400.0 +1700.0 2100.0 2500.0 2600.0 3000.0 3300.0 +1800.0 1900.0 2400.0 2500.0 2900.0 3000.0 +1300.0 1500.0 2300.0 2400.0 2900.0 3000.0 +1200.0 1700.0 1800.0 2300.0 2900.0 3000.0 +1200.0 1600.0 1800.0 2200.0 2900.0 3000.0 +1200.0 1700.0 2100.0 2300.0 3100.0 3200.0 +1400.0 1900.0 2100.0 2400.0 3000.0 3200.0 +1100.0 1500.0 2500.0 2600.0 3000.0 3300.0 +1300.0 1400.0 2400.0 2500.0 2800.0 3300.0 +1300.0 1500.0 2300.0 2500.0 3200.0 3400.0 +1300.0 1900.0 2300.0 2700.0 3100.0 3200.0 +1700.0 1900.0 2200.0 2400.0 2700.0 3100.0 +1400.0 1500.0 2000.0 2500.0 2600.0 3000.0 +1500.0 1600.0 2000.0 2400.0 2600.0 3000.0 +1400.0 1700.0 2400.0 2600.0 3000.0 3300.0 +2000.0 2100.0 2300.0 2500.0 2900.0 3100.0 +1900.0 2000.0 2400.0 2500.0 2800.0 3000.0 +1800.0 1900.0 2200.0 2400.0 2700.0 3000.0 +1400.0 1600.0 1900.0 2300.0 2600.0 3000.0 +1600.0 2000.0 2600.0 2800.0 3300.0 3400.0 +1200.0 1600.0 1800.0 2100.0 3200.0 3300.0 +1900.0 2300.0 2700.0 2800.0 3400.0 3500.0 +1500.0 1600.0 2200.0 2500.0 2700.0 3100.0 +1700.0 2100.0 2300.0 2500.0 2900.0 3200.0 +1300.0 1500.0 2200.0 2500.0 3000.0 3300.0 +1400.0 1500.0 2100.0 2500.0 2600.0 2900.0 +1500.0 1600.0 2200.0 2300.0 2800.0 3300.0 +1500.0 1600.0 1800.0 2100.0 2800.0 2900.0 +1700.0 1800.0 2200.0 2400.0 2600.0 3100.0 +1600.0 1900.0 2600.0 2700.0 3200.0 3400.0 +1500.0 1700.0 2400.0 2600.0 3000.0 3400.0 +1200.0 1500.0 2300.0 2400.0 2900.0 3300.0 +1600.0 2100.0 2500.0 2700.0 3200.0 3400.0 +1500.0 1700.0 2300.0 2500.0 2600.0 2900.0 +1500.0 1600.0 2400.0 2600.0 3000.0 3100.0 +1600.0 1800.0 2600.0 2800.0 3000.0 3200.0 +1400.0 1700.0 2200.0 2500.0 3100.0 3400.0 +1600.0 1700.0 2300.0 2600.0 2700.0 3100.0 +1600.0 1700.0 2100.0 2500.0 2700.0 3100.0 +2000.0 2200.0 2500.0 2700.0 3100.0 3400.0 +1900.0 2100.0 2400.0 2600.0 3000.0 3400.0 +1400.0 1800.0 2100.0 2600.0 2900.0 3100.0 +1000.0 1800.0 2100.0 2300.0 3100.0 3200.0 +1400.0 1500.0 2200.0 2400.0 3000.0 3300.0 +1300.0 1800.0 2200.0 2300.0 3000.0 3200.0 +1100.0 1500.0 2300.0 2400.0 3000.0 3200.0 +1400.0 1500.0 2300.0 2400.0 2900.0 3300.0 +1400.0 1500.0 2200.0 2400.0 2800.0 3300.0 +1200.0 1600.0 2100.0 2200.0 3200.0 3300.0 +1600.0 1800.0 2100.0 2300.0 2500.0 3100.0 +1500.0 1600.0 2400.0 2600.0 3000.0 3400.0 +1500.0 1800.0 2500.0 2600.0 3300.0 3400.0 +1900.0 2500.0 2600.0 2900.0 3200.0 3300.0 +1300.0 1500.0 2100.0 2500.0 2700.0 3100.0 +1200.0 1400.0 2400.0 2500.0 2800.0 3200.0 +1600.0 1700.0 2300.0 2400.0 2900.0 3400.0 +1100.0 1800.0 2200.0 2300.0 3300.0 3400.0 +1800.0 2200.0 2500.0 2800.0 3100.0 3400.0 +1200.0 1700.0 2100.0 2700.0 3100.0 3200.0 +1300.0 1600.0 2100.0 2600.0 3000.0 3200.0 +2000.0 2200.0 2300.0 2400.0 3100.0 3300.0 +1700.0 1900.0 2400.0 2600.0 3100.0 3400.0 +1300.0 1700.0 2000.0 2600.0 3200.0 3300.0 +1100.0 1700.0 2300.0 2400.0 3200.0 3400.0 +1100.0 1600.0 2300.0 2400.0 3200.0 3400.0 +1700.0 2300.0 2800.0 3000.0 3300.0 3400.0 +1700.0 2000.0 2300.0 2800.0 3200.0 3300.0 +1800.0 1900.0 2100.0 2600.0 3000.0 3200.0 +1300.0 2000.0 2200.0 2600.0 3000.0 3200.0 +1300.0 1500.0 2300.0 2400.0 3000.0 3400.0 +1600.0 1700.0 2100.0 2300.0 2800.0 3200.0 +1700.0 1800.0 2400.0 2700.0 2800.0 3200.0 +1800.0 1900.0 2500.0 2700.0 2800.0 3200.0 +1700.0 1800.0 2100.0 2300.0 2900.0 3300.0 +1500.0 1700.0 2300.0 2400.0 2700.0 3200.0 +1600.0 2100.0 2500.0 2800.0 3100.0 3200.0 +1400.0 1700.0 2300.0 2700.0 3000.0 3300.0 +900.0 1400.0 2300.0 2500.0 3100.0 3300.0 +1700.0 1800.0 2300.0 2400.0 3000.0 3400.0 +2000.0 2100.0 2400.0 2600.0 2900.0 3100.0 +1900.0 2500.0 2600.0 2800.0 3300.0 3400.0 +1400.0 1500.0 2200.0 2300.0 2900.0 3300.0 +1600.0 1700.0 2000.0 2500.0 2600.0 3100.0 +1700.0 1800.0 2200.0 2300.0 2900.0 3200.0 +2100.0 2500.0 2800.0 3100.0 3300.0 3500.0 +1900.0 2400.0 2600.0 2700.0 3300.0 3400.0 +1700.0 2100.0 2500.0 2600.0 3300.0 3400.0 +1100.0 1500.0 2300.0 2400.0 3100.0 3400.0 +1200.0 1500.0 2300.0 2400.0 3300.0 3400.0 +1200.0 1800.0 2200.0 2400.0 3300.0 3400.0 +1500.0 1900.0 2200.0 2300.0 3100.0 3300.0 +1300.0 1600.0 1800.0 2100.0 3200.0 3300.0 +1600.0 1800.0 2400.0 2600.0 2900.0 3300.0 +1700.0 1900.0 2400.0 2600.0 3000.0 3400.0 +1300.0 1800.0 2200.0 2300.0 2900.0 3200.0 +1400.0 1700.0 2200.0 2300.0 3200.0 3400.0 +1400.0 1600.0 2200.0 2400.0 3200.0 3400.0 +1700.0 1800.0 2400.0 2500.0 3200.0 3500.0 +1600.0 1700.0 2500.0 2600.0 3200.0 3400.0 +1500.0 1700.0 2400.0 2500.0 2900.0 3400.0 +1700.0 1800.0 2300.0 2400.0 2900.0 3500.0 +1700.0 1800.0 2300.0 2400.0 3000.0 3500.0 +1600.0 1700.0 2300.0 2500.0 2700.0 3400.0 +1800.0 1900.0 2400.0 2500.0 3000.0 3500.0 +1300.0 1600.0 1800.0 2500.0 3100.0 3300.0 +1200.0 1700.0 2000.0 2200.0 3200.0 3300.0 +1200.0 1600.0 2200.0 2300.0 3200.0 3400.0 +1200.0 1600.0 2200.0 2400.0 3200.0 3400.0 +1600.0 2300.0 2600.0 2900.0 3300.0 3400.0 +1300.0 1600.0 2200.0 2300.0 3000.0 3400.0 +1900.0 2100.0 2400.0 2500.0 2800.0 3100.0 +1400.0 2000.0 2500.0 2700.0 3100.0 3200.0 +1700.0 1800.0 2400.0 2500.0 2800.0 3300.0 +1900.0 2000.0 2400.0 2600.0 2800.0 3400.0 +1600.0 2200.0 2500.0 2800.0 3200.0 3300.0 +1200.0 1700.0 2300.0 2400.0 3000.0 3300.0 +1200.0 1400.0 2200.0 2300.0 2900.0 3200.0 +1600.0 1800.0 2400.0 2700.0 3200.0 3400.0 +1600.0 1900.0 2400.0 2600.0 3100.0 3400.0 +1500.0 1800.0 2400.0 2600.0 3000.0 3400.0 +1600.0 1700.0 2400.0 2500.0 3100.0 3500.0 +1500.0 1600.0 2100.0 2300.0 2700.0 3200.0 +1500.0 1600.0 2100.0 2200.0 2600.0 3100.0 +1700.0 1900.0 2400.0 2700.0 3300.0 3400.0 +1200.0 1500.0 2200.0 2300.0 3300.0 3400.0 +1300.0 1600.0 2100.0 2200.0 3300.0 3400.0 +1400.0 1500.0 2100.0 2200.0 3200.0 3400.0 +1800.0 1900.0 2300.0 2400.0 2800.0 3300.0 +1900.0 2000.0 2400.0 2500.0 2800.0 3200.0 +2000.0 2100.0 2400.0 2600.0 2800.0 3200.0 +1500.0 2100.0 2300.0 2500.0 2800.0 3200.0 +1500.0 1800.0 2300.0 2400.0 3000.0 3200.0 +1700.0 1800.0 2600.0 2800.0 3000.0 3200.0 +1900.0 2500.0 2800.0 2900.0 3200.0 3300.0 +1100.0 1400.0 2500.0 2800.0 3000.0 3200.0 +1200.0 1400.0 2700.0 2900.0 3100.0 3300.0 +1200.0 1400.0 2600.0 2900.0 3000.0 3300.0 +1200.0 1400.0 2700.0 2900.0 3000.0 3400.0 +1200.0 1600.0 2600.0 2800.0 3100.0 3400.0 +1300.0 1800.0 2400.0 2500.0 2900.0 3200.0 +1400.0 1700.0 2500.0 2600.0 3200.0 3400.0 +1400.0 1900.0 2300.0 2400.0 2900.0 3300.0 +1800.0 1900.0 2600.0 2700.0 3100.0 3400.0 +1800.0 2000.0 2600.0 2700.0 3100.0 3400.0 +1800.0 1900.0 2600.0 2700.0 3000.0 3400.0 +1400.0 1800.0 2300.0 2500.0 2700.0 3000.0 +1600.0 1700.0 2500.0 2700.0 3200.0 3400.0 +1500.0 1700.0 2400.0 2700.0 3000.0 3200.0 +1500.0 1900.0 2400.0 2700.0 3100.0 3200.0 +1900.0 2100.0 2700.0 2800.0 3200.0 3300.0 +1600.0 2000.0 2300.0 2400.0 3200.0 3400.0 +1500.0 1700.0 2500.0 2700.0 3200.0 3300.0 +1700.0 1800.0 2500.0 2700.0 3200.0 3300.0 +1800.0 1900.0 2600.0 2800.0 3100.0 3400.0 +1700.0 1800.0 2500.0 2800.0 2900.0 3200.0 +1600.0 1700.0 2500.0 2700.0 3000.0 3300.0 +1200.0 1700.0 2700.0 2800.0 3100.0 3300.0 +1200.0 1500.0 2700.0 2900.0 3100.0 3300.0 +1500.0 1800.0 2400.0 2700.0 3100.0 3400.0 +1400.0 1600.0 2600.0 2800.0 3000.0 3300.0 +1600.0 1800.0 2500.0 2700.0 3000.0 3400.0 +1500.0 1800.0 2300.0 2600.0 3100.0 3400.0 +1500.0 1700.0 2300.0 2500.0 2700.0 3300.0 +2000.0 2100.0 2500.0 2700.0 2900.0 3300.0 +2200.0 2300.0 2600.0 2700.0 3200.0 3400.0 +1400.0 1800.0 2300.0 2700.0 3200.0 3300.0 +1500.0 1700.0 2600.0 2700.0 3100.0 3400.0 +1300.0 1700.0 2100.0 2500.0 3100.0 3300.0 +2100.0 2200.0 2600.0 2800.0 3300.0 3400.0 +2100.0 2300.0 2700.0 2800.0 3300.0 3400.0 +1600.0 1700.0 2500.0 2700.0 3100.0 3300.0 +1400.0 1700.0 2600.0 2700.0 3200.0 3400.0 +1200.0 1500.0 2600.0 2800.0 3100.0 3300.0 +1800.0 1900.0 2500.0 2600.0 3000.0 3400.0 +1700.0 1800.0 2400.0 2600.0 2900.0 3000.0 +1200.0 1600.0 2800.0 3000.0 3200.0 3300.0 +1600.0 1700.0 2300.0 2600.0 3200.0 3400.0 +1700.0 1800.0 2200.0 2500.0 2800.0 3300.0 +1700.0 1800.0 2600.0 2700.0 3000.0 3400.0 +1500.0 1600.0 2600.0 2800.0 3000.0 3300.0 +1100.0 1300.0 2400.0 2900.0 3000.0 3200.0 +1100.0 1500.0 2700.0 2800.0 3100.0 3300.0 +1600.0 1800.0 2000.0 2300.0 3300.0 3400.0 +1800.0 2000.0 2100.0 2400.0 3300.0 3400.0 +1800.0 2000.0 2500.0 2600.0 2900.0 3300.0 +1600.0 1700.0 2400.0 2700.0 2900.0 3300.0 +1600.0 1700.0 2600.0 2800.0 3100.0 3300.0 +1500.0 1700.0 1900.0 2100.0 3000.0 3300.0 +1900.0 2000.0 2100.0 2300.0 3200.0 3400.0 +2100.0 2200.0 2500.0 2600.0 2900.0 3300.0 +1800.0 2000.0 2200.0 2400.0 3300.0 3400.0 +1700.0 1800.0 2100.0 2300.0 3300.0 3400.0 +2000.0 2200.0 2500.0 2600.0 3200.0 3400.0 +1700.0 1900.0 2100.0 2800.0 3100.0 3200.0 +1800.0 1900.0 2500.0 2900.0 3100.0 3200.0 +1800.0 1900.0 2500.0 2900.0 3000.0 3200.0 +1300.0 1500.0 1800.0 1900.0 2700.0 3200.0 +1000.0 1300.0 2400.0 3000.0 3300.0 3400.0 +1400.0 1600.0 1800.0 1900.0 2900.0 3300.0 +1500.0 1700.0 1900.0 2000.0 2800.0 3200.0 +1800.0 2000.0 2300.0 2500.0 2700.0 3100.0 +1800.0 1900.0 2200.0 2300.0 2800.0 3200.0 +1200.0 1900.0 2500.0 2600.0 2900.0 3000.0 +1200.0 1900.0 2400.0 2600.0 2900.0 3000.0 +1800.0 2000.0 2100.0 2400.0 3000.0 3200.0 +1900.0 2200.0 2600.0 2900.0 3100.0 3200.0 +1600.0 1700.0 2000.0 2100.0 2700.0 3200.0 +1600.0 1800.0 2300.0 2800.0 3100.0 3200.0 +1700.0 1900.0 2400.0 2700.0 2900.0 3300.0 +1900.0 2000.0 2400.0 2800.0 3200.0 3300.0 +1400.0 1600.0 2300.0 2500.0 2800.0 3100.0 +1600.0 1700.0 2100.0 2200.0 2700.0 3200.0 +2000.0 2100.0 2600.0 2900.0 3300.0 3400.0 +1200.0 1500.0 2300.0 2500.0 2900.0 3200.0 +1200.0 1400.0 2200.0 2400.0 2900.0 3200.0 +1600.0 2200.0 2400.0 2600.0 3200.0 3400.0 +1700.0 1800.0 2400.0 2500.0 3000.0 3100.0 +1700.0 1800.0 2200.0 2600.0 3100.0 3200.0 +1200.0 1900.0 2300.0 2600.0 3100.0 3200.0 +1400.0 1600.0 2000.0 2800.0 3200.0 3300.0 +1500.0 1700.0 2400.0 2500.0 3000.0 3100.0 +1400.0 2000.0 2400.0 2600.0 3000.0 3300.0 +1200.0 1400.0 2400.0 2800.0 3000.0 3100.0 +1500.0 1600.0 2000.0 2100.0 2900.0 3300.0 +1500.0 1600.0 2000.0 2200.0 2800.0 3300.0 +1200.0 1500.0 2100.0 2200.0 3000.0 3300.0 +1400.0 2000.0 2300.0 2700.0 3100.0 3300.0 +1600.0 1700.0 2000.0 2700.0 3200.0 3300.0 +1700.0 1900.0 2300.0 2600.0 2800.0 3200.0 +2100.0 2300.0 2600.0 2800.0 3100.0 3200.0 +1400.0 1800.0 2400.0 2500.0 3000.0 3200.0 +1500.0 2100.0 2400.0 2700.0 3000.0 3300.0 +1600.0 1700.0 2100.0 2700.0 3000.0 3100.0 +1500.0 1800.0 2200.0 2700.0 3100.0 3300.0 +1300.0 1500.0 2400.0 2500.0 2900.0 3200.0 +1200.0 1500.0 2500.0 2600.0 3000.0 3200.0 +1100.0 1500.0 2400.0 2500.0 2900.0 3300.0 +1800.0 1900.0 2400.0 2500.0 2800.0 3000.0 +1700.0 1800.0 2100.0 2800.0 3100.0 3200.0 +1900.0 2200.0 2400.0 2900.0 3100.0 3200.0 +1500.0 1700.0 2300.0 2600.0 2800.0 3100.0 +1300.0 1500.0 1900.0 2500.0 3000.0 3100.0 +1700.0 1800.0 2400.0 2700.0 3100.0 3200.0 +1900.0 2500.0 2900.0 3100.0 3300.0 3400.0 +1500.0 1800.0 2000.0 2600.0 2900.0 3100.0 +1900.0 2300.0 2500.0 2800.0 3200.0 3400.0 +1500.0 2100.0 2500.0 2700.0 3200.0 3400.0 +1500.0 2100.0 2500.0 2700.0 2900.0 3200.0 +1800.0 2300.0 2800.0 2900.0 3300.0 3400.0 +1600.0 1900.0 2200.0 2600.0 3000.0 3300.0 +1400.0 1900.0 2400.0 2600.0 2800.0 3100.0 +1300.0 1700.0 2500.0 2600.0 3000.0 3200.0 +1400.0 1800.0 2100.0 2500.0 2800.0 3100.0 +1700.0 2400.0 2600.0 3000.0 3300.0 3400.0 +2200.0 2400.0 2700.0 3000.0 3200.0 3300.0 +1400.0 1800.0 2400.0 2700.0 3000.0 3200.0 +1300.0 1700.0 2300.0 2600.0 2900.0 3200.0 +1400.0 1900.0 2200.0 2500.0 2700.0 3000.0 +1500.0 1900.0 2200.0 2800.0 3100.0 3300.0 +1400.0 1600.0 1800.0 2200.0 3200.0 3400.0 +1700.0 2000.0 2200.0 2700.0 3200.0 3300.0 +1400.0 1900.0 2500.0 2700.0 3300.0 3400.0 +1500.0 2100.0 2300.0 2500.0 2800.0 3100.0 +1500.0 2000.0 2300.0 2500.0 2800.0 3100.0 +1500.0 1600.0 2400.0 2800.0 3000.0 3200.0 +1400.0 1600.0 2200.0 2700.0 3000.0 3100.0 +1200.0 1800.0 2000.0 2300.0 2900.0 3100.0 +1300.0 1900.0 2400.0 2700.0 3200.0 3300.0 +2200.0 2500.0 2800.0 3100.0 3400.0 3500.0 +2100.0 2400.0 2900.0 3000.0 3100.0 3300.0 +1200.0 1500.0 1700.0 2300.0 2900.0 3000.0 +1600.0 2200.0 2600.0 2800.0 3200.0 3300.0 +1700.0 2300.0 2500.0 2800.0 3100.0 3300.0 +1400.0 1900.0 2500.0 2600.0 3100.0 3200.0 +1400.0 1700.0 2500.0 2600.0 3100.0 3400.0 +1300.0 1700.0 2500.0 2600.0 3100.0 3400.0 +1400.0 2100.0 2300.0 2600.0 3200.0 3300.0 +1300.0 1900.0 2200.0 2600.0 3100.0 3200.0 +1100.0 1900.0 2100.0 2500.0 3100.0 3200.0 +1300.0 1400.0 2500.0 2600.0 3000.0 3300.0 +1300.0 2000.0 2400.0 2600.0 3100.0 3300.0 +1500.0 2000.0 2300.0 2600.0 3200.0 3400.0 +1400.0 1900.0 2200.0 2700.0 3000.0 3200.0 +1600.0 2100.0 2500.0 2600.0 3000.0 3200.0 +1600.0 2100.0 2500.0 2700.0 3000.0 3200.0 +1500.0 2000.0 2500.0 2700.0 3000.0 3200.0 +1900.0 2400.0 2600.0 2900.0 3400.0 3500.0 +1400.0 1700.0 2300.0 2700.0 3000.0 3200.0 +1800.0 2300.0 2900.0 3100.0 3400.0 3500.0 +1700.0 2100.0 2300.0 2500.0 3000.0 3100.0 +1900.0 2100.0 2500.0 3000.0 3300.0 3400.0 +1300.0 1500.0 1800.0 2500.0 2800.0 3000.0 +1300.0 1400.0 2000.0 2400.0 2800.0 3200.0 +1300.0 2100.0 2400.0 2600.0 3200.0 3300.0 +1300.0 1900.0 2200.0 2600.0 3000.0 3200.0 +1400.0 1900.0 2400.0 2600.0 3100.0 3200.0 +1300.0 1800.0 2500.0 2600.0 3100.0 3200.0 +1500.0 2100.0 2400.0 2500.0 3200.0 3300.0 +1500.0 1700.0 2000.0 2700.0 2900.0 3100.0 +1400.0 2000.0 2200.0 2400.0 2700.0 3100.0 +1200.0 1400.0 2600.0 2700.0 2900.0 3100.0 +1500.0 2100.0 2300.0 2500.0 2700.0 3100.0 +1800.0 2100.0 2500.0 2600.0 3100.0 3200.0 +1200.0 1700.0 2100.0 2500.0 3200.0 3300.0 +1400.0 2100.0 2300.0 2700.0 3200.0 3300.0 +1700.0 2000.0 2600.0 2800.0 3100.0 3200.0 +1400.0 1700.0 2300.0 2700.0 3200.0 3300.0 +1300.0 1600.0 2200.0 2400.0 3100.0 3200.0 +1400.0 1500.0 2200.0 2500.0 3000.0 3200.0 +1400.0 1700.0 2300.0 2500.0 2800.0 3100.0 +1500.0 1700.0 2200.0 2500.0 2700.0 3100.0 +1500.0 1700.0 2200.0 2500.0 2900.0 3100.0 +1800.0 2000.0 2700.0 2900.0 3100.0 3400.0 +1300.0 1700.0 2100.0 2200.0 3200.0 3300.0 +1500.0 1600.0 2300.0 2700.0 2900.0 3300.0 +1500.0 1600.0 2700.0 2800.0 3000.0 3300.0 +1400.0 1500.0 2500.0 2700.0 2900.0 3200.0 +1100.0 1600.0 2400.0 2600.0 3000.0 3200.0 +1600.0 2000.0 2700.0 2900.0 3300.0 3400.0 +1400.0 1500.0 2600.0 2800.0 3000.0 3300.0 +1400.0 1500.0 2600.0 2700.0 3000.0 3300.0 +1400.0 1500.0 2500.0 2700.0 2900.0 3300.0 +1700.0 1900.0 2600.0 2900.0 3100.0 3300.0 +1500.0 1600.0 2300.0 2700.0 3100.0 3200.0 +1200.0 1700.0 2300.0 2700.0 3000.0 3200.0 +1500.0 1600.0 2500.0 2800.0 3000.0 3300.0 +1500.0 1600.0 1700.0 1800.0 3100.0 3400.0 +1500.0 1600.0 2300.0 2700.0 3000.0 3300.0 +1300.0 1500.0 2600.0 2700.0 3200.0 3300.0 +2100.0 2200.0 2500.0 2700.0 3100.0 3200.0 +2100.0 2200.0 2800.0 3000.0 3200.0 3300.0 +1500.0 1700.0 2400.0 2600.0 2800.0 3100.0 +1500.0 1800.0 2400.0 2700.0 3000.0 3200.0 +1400.0 1700.0 2400.0 2700.0 3100.0 3200.0 +900.0 1500.0 2800.0 2900.0 3100.0 3300.0 +1400.0 1700.0 2500.0 2700.0 3100.0 3400.0 +1800.0 2000.0 2300.0 2800.0 3100.0 3300.0 +1200.0 1600.0 2300.0 2400.0 2900.0 3200.0 +1800.0 1900.0 2300.0 2600.0 3000.0 3100.0 +1300.0 1600.0 1900.0 2400.0 2900.0 3200.0 +1400.0 1600.0 2500.0 2700.0 2900.0 3300.0 +900.0 1600.0 2200.0 2300.0 3200.0 3300.0 +1300.0 1900.0 2200.0 2300.0 3100.0 3300.0 +1700.0 1900.0 2500.0 2900.0 3200.0 3300.0 +1400.0 1900.0 2500.0 2700.0 3200.0 3400.0 +1700.0 2000.0 2200.0 2500.0 2900.0 3000.0 +1200.0 1500.0 2600.0 2800.0 3100.0 3400.0 +1400.0 1700.0 2100.0 2600.0 3000.0 3300.0 +1400.0 1700.0 2500.0 2800.0 3200.0 3300.0 +1800.0 2400.0 2600.0 2900.0 3400.0 3500.0 +1900.0 2100.0 2500.0 2600.0 3100.0 3200.0 +2200.0 2500.0 2800.0 3000.0 3400.0 3500.0 +1600.0 1800.0 1900.0 2500.0 3100.0 3200.0 +1100.0 1600.0 2500.0 2600.0 3200.0 3400.0 +1700.0 2200.0 2500.0 2700.0 3100.0 3400.0 +1000.0 1700.0 2200.0 2300.0 3200.0 3300.0 +1100.0 1700.0 2200.0 2600.0 3100.0 3300.0 +1100.0 1700.0 2300.0 2700.0 3200.0 3300.0 +1500.0 1800.0 2100.0 2600.0 3200.0 3300.0 +1300.0 2100.0 2400.0 2600.0 2800.0 3200.0 +1800.0 1900.0 2200.0 2600.0 2800.0 3200.0 +1800.0 1900.0 2500.0 2600.0 3100.0 3200.0 +1400.0 2100.0 2300.0 2500.0 2700.0 3100.0 +1300.0 2000.0 2400.0 2500.0 2800.0 3200.0 +1600.0 2100.0 2600.0 2800.0 3200.0 3400.0 +1400.0 1800.0 2200.0 2400.0 3300.0 3400.0 +1300.0 1700.0 2200.0 2300.0 3300.0 3400.0 +1300.0 1600.0 2200.0 2300.0 3300.0 3400.0 +1300.0 1600.0 2300.0 2400.0 3300.0 3400.0 +1100.0 1700.0 2200.0 2300.0 3300.0 3400.0 +1500.0 1900.0 2200.0 2500.0 2700.0 3100.0 +1300.0 1700.0 1900.0 2200.0 3000.0 3100.0 +1400.0 1600.0 2500.0 2600.0 3300.0 3400.0 +1500.0 1600.0 2500.0 2600.0 3200.0 3400.0 +1000.0 1700.0 2600.0 2700.0 3300.0 3400.0 +1000.0 1600.0 2600.0 2700.0 3300.0 3400.0 +1400.0 1700.0 2500.0 2600.0 3000.0 3400.0 +1400.0 1800.0 2500.0 2600.0 3300.0 3400.0 +1500.0 1600.0 2400.0 2600.0 3200.0 3400.0 +1600.0 2200.0 2500.0 2600.0 3200.0 3300.0 +1000.0 1900.0 2400.0 2500.0 3300.0 3400.0 +1200.0 1700.0 2200.0 2400.0 3200.0 3400.0 +2000.0 2200.0 2600.0 2900.0 3300.0 3400.0 +2200.0 2300.0 2700.0 2800.0 3300.0 3400.0 +2200.0 2300.0 2700.0 2800.0 3200.0 3300.0 +2000.0 2300.0 2400.0 2700.0 3100.0 3300.0 +2200.0 2300.0 2600.0 2800.0 3200.0 3300.0 +1500.0 2000.0 2300.0 2400.0 3200.0 3300.0 +1500.0 1600.0 1800.0 2500.0 3200.0 3300.0 +1100.0 1900.0 2200.0 2400.0 3000.0 3300.0 +1500.0 2100.0 2600.0 2700.0 3200.0 3400.0 +1400.0 1900.0 2400.0 2600.0 3000.0 3200.0 +1200.0 1800.0 2400.0 2600.0 3200.0 3300.0 +1200.0 1700.0 2700.0 2800.0 3200.0 3300.0 +1200.0 1600.0 2600.0 2700.0 3200.0 3300.0 +1300.0 1600.0 2500.0 2600.0 3000.0 3300.0 +1500.0 1600.0 2500.0 2700.0 2900.0 3300.0 +1500.0 1700.0 1800.0 2500.0 3100.0 3200.0 +1400.0 1700.0 1900.0 2600.0 3100.0 3200.0 +1300.0 1700.0 2500.0 2600.0 3200.0 3300.0 +1100.0 1400.0 2600.0 3000.0 3200.0 3300.0 +1100.0 1400.0 2600.0 2900.0 3100.0 3300.0 +1600.0 1800.0 1900.0 2600.0 3200.0 3300.0 +2000.0 2100.0 2600.0 2700.0 3100.0 3200.0 +1300.0 1700.0 2100.0 2300.0 3200.0 3300.0 +1100.0 1700.0 2800.0 2900.0 3200.0 3300.0 +1500.0 1700.0 2500.0 2600.0 2900.0 3200.0 +1400.0 1800.0 2600.0 2700.0 3200.0 3300.0 +1600.0 1700.0 2100.0 2400.0 3000.0 3300.0 +1300.0 1500.0 1600.0 2200.0 3000.0 3100.0 +1300.0 2000.0 2500.0 2700.0 3100.0 3200.0 +1800.0 2200.0 2500.0 2600.0 3200.0 3300.0 +1700.0 2200.0 2400.0 2600.0 2800.0 3100.0 +2000.0 2200.0 2600.0 2800.0 3000.0 3300.0 +1300.0 1400.0 2400.0 2700.0 3100.0 3300.0 +1500.0 1600.0 1900.0 2000.0 2900.0 3300.0 +1000.0 1200.0 2400.0 2500.0 3100.0 3400.0 +1800.0 1900.0 2200.0 2400.0 2600.0 3000.0 +1900.0 2000.0 2200.0 2600.0 2800.0 3000.0 +1300.0 1800.0 2200.0 2400.0 2900.0 3200.0 +1800.0 2100.0 2300.0 2500.0 2800.0 3000.0 +1500.0 2000.0 2300.0 2600.0 2800.0 3100.0 +1000.0 1400.0 2400.0 2500.0 3100.0 3300.0 +1300.0 1900.0 2700.0 2800.0 3200.0 3300.0 +1900.0 2200.0 2300.0 2500.0 2800.0 3100.0 +1900.0 2000.0 2200.0 2600.0 2800.0 3100.0 +1600.0 1700.0 2100.0 2200.0 2900.0 3200.0 +1500.0 1900.0 2200.0 2500.0 3000.0 3300.0 +1400.0 1900.0 2400.0 2800.0 3100.0 3300.0 +1900.0 2000.0 2300.0 2600.0 2800.0 3200.0 +1900.0 2100.0 2300.0 2600.0 2800.0 3200.0 +1600.0 1700.0 2300.0 2700.0 3100.0 3300.0 +1600.0 1800.0 2100.0 2300.0 2600.0 3000.0 +1600.0 1800.0 2100.0 2400.0 2600.0 3000.0 +1700.0 2000.0 2200.0 2500.0 3100.0 3300.0 +1600.0 1700.0 2000.0 2400.0 2600.0 3000.0 +1300.0 1500.0 2200.0 2400.0 2800.0 3200.0 +1300.0 1700.0 2200.0 2400.0 2900.0 3200.0 +1700.0 1900.0 2100.0 2300.0 2800.0 3100.0 +1200.0 1400.0 2300.0 2400.0 2900.0 3300.0 +1400.0 1500.0 2000.0 2200.0 2700.0 3000.0 +1200.0 1900.0 2400.0 2600.0 3000.0 3300.0 +1700.0 1800.0 2100.0 2300.0 2600.0 3100.0 +1900.0 2000.0 2200.0 2400.0 2700.0 3000.0 +1900.0 2100.0 2300.0 2400.0 2700.0 3000.0 +1400.0 1800.0 2200.0 2400.0 2700.0 3200.0 +1700.0 1800.0 2200.0 2300.0 2900.0 3300.0 +1700.0 2000.0 2500.0 2800.0 3400.0 3500.0 +1300.0 1500.0 2200.0 2300.0 3100.0 3200.0 +1400.0 1800.0 2100.0 2600.0 3000.0 3200.0 +1300.0 1900.0 2200.0 2500.0 3100.0 3300.0 +1500.0 2100.0 2600.0 2700.0 3200.0 3300.0 +1300.0 1800.0 2600.0 2700.0 3200.0 3300.0 +1000.0 1500.0 2700.0 2800.0 3100.0 3300.0 +2200.0 2300.0 2500.0 2900.0 3200.0 3400.0 +2100.0 2200.0 2500.0 2900.0 3100.0 3300.0 +1500.0 1600.0 2400.0 2700.0 3000.0 3300.0 +1300.0 1500.0 1600.0 2000.0 3200.0 3400.0 +1400.0 1600.0 1700.0 2000.0 3200.0 3400.0 +1700.0 1900.0 2700.0 2800.0 3200.0 3300.0 +1700.0 1900.0 2700.0 2800.0 3100.0 3300.0 +1500.0 1600.0 2300.0 2700.0 2800.0 3200.0 +1500.0 1600.0 2200.0 2500.0 2900.0 3300.0 +1200.0 1500.0 2100.0 2600.0 3000.0 3300.0 +1800.0 2300.0 2700.0 2800.0 3200.0 3400.0 +1000.0 1400.0 2400.0 2500.0 2900.0 3300.0 +1000.0 1500.0 2500.0 2600.0 2900.0 3200.0 +1900.0 2400.0 2700.0 3000.0 3200.0 3400.0 +1700.0 1900.0 2300.0 2400.0 3000.0 3400.0 +1300.0 1600.0 1700.0 2200.0 3100.0 3300.0 +1800.0 1900.0 2600.0 2900.0 3100.0 3300.0 +2300.0 2600.0 2800.0 2900.0 3300.0 3400.0 +1000.0 1500.0 2400.0 2500.0 3200.0 3300.0 +1400.0 1600.0 2100.0 2300.0 2900.0 3200.0 +1500.0 2000.0 2400.0 2600.0 2800.0 3000.0 +1400.0 1900.0 2300.0 2600.0 2800.0 3100.0 +1600.0 1700.0 2500.0 2600.0 2800.0 3200.0 +2000.0 2200.0 2800.0 3000.0 3300.0 3500.0 +2000.0 2400.0 2700.0 2800.0 3200.0 3300.0 +1400.0 1600.0 1700.0 1900.0 3200.0 3400.0 +2100.0 2200.0 2400.0 2700.0 3000.0 3300.0 +2100.0 2400.0 2800.0 3000.0 3100.0 3300.0 +1800.0 2000.0 2300.0 2400.0 3100.0 3400.0 +1400.0 1700.0 2600.0 2700.0 3000.0 3300.0 +1300.0 1700.0 2200.0 2500.0 3200.0 3400.0 +1500.0 1900.0 2300.0 2600.0 2800.0 3100.0 +2200.0 2500.0 2700.0 2800.0 3200.0 3400.0 +2100.0 2200.0 2500.0 2800.0 3000.0 3200.0 +1700.0 1900.0 2300.0 2600.0 2800.0 3000.0 +1800.0 2000.0 2400.0 2700.0 2900.0 3300.0 +1500.0 1800.0 2000.0 2400.0 3000.0 3100.0 +1500.0 1700.0 1800.0 2600.0 3100.0 3200.0 +1200.0 1700.0 2300.0 2600.0 3000.0 3200.0 +1400.0 1500.0 1900.0 2700.0 3000.0 3100.0 +1600.0 2100.0 2300.0 2700.0 3000.0 3100.0 +1700.0 2300.0 2400.0 2700.0 3100.0 3200.0 +1800.0 2300.0 2400.0 2700.0 2900.0 3100.0 +1400.0 1500.0 1900.0 2500.0 2800.0 3000.0 +1300.0 1500.0 1900.0 2600.0 3000.0 3100.0 +1500.0 1600.0 2000.0 2500.0 2900.0 3100.0 +1500.0 1900.0 2300.0 2800.0 3200.0 3300.0 +1900.0 2000.0 2500.0 2700.0 3000.0 3100.0 +1400.0 1500.0 2000.0 2500.0 2800.0 3000.0 +1400.0 1500.0 2000.0 2600.0 3000.0 3100.0 +1700.0 2000.0 2200.0 2600.0 2700.0 3000.0 +1400.0 1700.0 2000.0 2500.0 3100.0 3200.0 +1700.0 1900.0 2400.0 2700.0 2800.0 3100.0 +1700.0 2000.0 2300.0 2500.0 2800.0 3100.0 +1400.0 1600.0 1900.0 2400.0 2700.0 3000.0 +1500.0 1700.0 1900.0 2400.0 2700.0 3000.0 +1400.0 1500.0 1900.0 2800.0 3100.0 3200.0 +1400.0 1900.0 2200.0 2600.0 3100.0 3200.0 +1200.0 1600.0 2200.0 2500.0 3000.0 3100.0 +1500.0 1800.0 2500.0 2800.0 3000.0 3200.0 +1200.0 1900.0 2600.0 2700.0 3200.0 3300.0 +1700.0 2100.0 2300.0 2500.0 2700.0 3200.0 +1300.0 1600.0 2100.0 2300.0 2800.0 3200.0 +1800.0 2000.0 2200.0 2800.0 3100.0 3200.0 +2100.0 2400.0 2900.0 3000.0 3300.0 3500.0 +1700.0 1900.0 2600.0 2900.0 3200.0 3300.0 +2100.0 2500.0 2900.0 3000.0 3200.0 3300.0 +2000.0 2300.0 2800.0 2900.0 3100.0 3400.0 +1300.0 1500.0 2100.0 2400.0 2800.0 3200.0 +1600.0 1700.0 2000.0 2700.0 3000.0 3100.0 +1500.0 1800.0 2000.0 2500.0 3000.0 3100.0 +1500.0 1800.0 2200.0 2700.0 2900.0 3100.0 +1600.0 1700.0 2100.0 2400.0 2600.0 3100.0 +1500.0 1900.0 2300.0 2400.0 2900.0 3300.0 +1300.0 2000.0 2400.0 2700.0 3100.0 3200.0 +1300.0 2000.0 2300.0 2700.0 3300.0 3400.0 +1700.0 2200.0 2400.0 2800.0 3200.0 3300.0 +1400.0 1900.0 2600.0 2900.0 3200.0 3300.0 +1400.0 1700.0 2000.0 2400.0 3100.0 3200.0 +1400.0 1600.0 2300.0 2500.0 2700.0 3000.0 +1500.0 1600.0 2300.0 2600.0 3100.0 3200.0 +1500.0 1900.0 2200.0 2400.0 3300.0 3400.0 +1200.0 1900.0 2100.0 2400.0 2900.0 3100.0 +1000.0 2300.0 2600.0 2800.0 3200.0 3300.0 +2200.0 2300.0 2600.0 2900.0 3300.0 3400.0 +1400.0 1600.0 2600.0 2700.0 3200.0 3300.0 +1300.0 2100.0 2500.0 2700.0 3100.0 3200.0 +1400.0 1600.0 2500.0 2600.0 3000.0 3400.0 +1200.0 1800.0 2700.0 2800.0 3000.0 3100.0 +1100.0 2000.0 2600.0 2700.0 3100.0 3200.0 +1000.0 1900.0 2700.0 2800.0 3100.0 3200.0 +1100.0 1900.0 2700.0 2800.0 3200.0 3300.0 +1200.0 1800.0 2500.0 2600.0 3000.0 3200.0 +2000.0 2100.0 2500.0 2600.0 3100.0 3200.0 +1400.0 2000.0 2500.0 2700.0 3200.0 3300.0 +2300.0 2400.0 2900.0 3100.0 3300.0 3400.0 +1600.0 1900.0 2300.0 2500.0 2900.0 3100.0 +1300.0 2200.0 2400.0 2900.0 3300.0 3400.0 +1300.0 2100.0 2200.0 2500.0 3200.0 3300.0 +1300.0 1900.0 2500.0 2600.0 3000.0 3100.0 +1300.0 1900.0 2500.0 2600.0 3100.0 3200.0 +1300.0 2000.0 2500.0 2600.0 3100.0 3200.0 +1400.0 1600.0 2500.0 2600.0 3200.0 3300.0 +1700.0 1800.0 2300.0 2600.0 3000.0 3400.0 +1600.0 1800.0 2300.0 2700.0 3200.0 3400.0 +1300.0 1500.0 1600.0 2600.0 3200.0 3300.0 +1300.0 1500.0 1600.0 2500.0 3300.0 3400.0 +1300.0 1500.0 1600.0 2700.0 3300.0 3400.0 +2100.0 2500.0 3000.0 3100.0 3300.0 3400.0 +1400.0 1900.0 2300.0 2400.0 3100.0 3200.0 +1600.0 2200.0 2300.0 2600.0 3300.0 3400.0 +1300.0 1600.0 1700.0 2700.0 3100.0 3200.0 +1800.0 2300.0 2500.0 2800.0 3100.0 3300.0 +1500.0 1600.0 2400.0 2600.0 3100.0 3400.0 +1200.0 1900.0 2200.0 2400.0 3000.0 3100.0 +1400.0 1900.0 2200.0 2700.0 3100.0 3200.0 +1300.0 1700.0 2300.0 2600.0 2900.0 3100.0 +1300.0 2000.0 2300.0 2600.0 3200.0 3300.0 +1800.0 1900.0 2400.0 2600.0 3200.0 3500.0 +1700.0 1800.0 2400.0 2700.0 2900.0 3300.0 +1400.0 2000.0 2400.0 2500.0 2700.0 2900.0 +1400.0 2100.0 2400.0 2500.0 2700.0 3100.0 +1500.0 1700.0 2300.0 2700.0 2900.0 3200.0 +1200.0 1300.0 2300.0 2800.0 3000.0 3200.0 +1200.0 1400.0 2100.0 2600.0 3000.0 3300.0 +1600.0 1700.0 2500.0 2700.0 2800.0 3200.0 +1700.0 2100.0 2200.0 2700.0 3000.0 3100.0 +1400.0 1500.0 2100.0 2400.0 2900.0 3200.0 +1700.0 2100.0 2200.0 2600.0 3100.0 3200.0 +1600.0 1900.0 2300.0 2500.0 2900.0 3000.0 +1300.0 1500.0 2000.0 2600.0 2900.0 3000.0 +1800.0 1900.0 2100.0 2300.0 3000.0 3200.0 +1100.0 1500.0 2500.0 2800.0 3000.0 3200.0 +1900.0 2000.0 2200.0 2400.0 2800.0 3200.0 +1800.0 1900.0 2700.0 2800.0 3100.0 3300.0 +1200.0 1400.0 2000.0 2700.0 3000.0 3100.0 +1300.0 1400.0 1900.0 2000.0 2600.0 3200.0 +1000.0 1300.0 2400.0 2600.0 2800.0 3200.0 +1700.0 1800.0 2200.0 2400.0 2600.0 3000.0 +2000.0 2300.0 2400.0 2700.0 2900.0 3000.0 +1600.0 1700.0 2000.0 2200.0 2500.0 3100.0 +1700.0 2300.0 2700.0 2800.0 3200.0 3400.0 +1600.0 1700.0 2300.0 2600.0 2700.0 3000.0 +1400.0 1500.0 2000.0 2700.0 2900.0 3100.0 +1100.0 1400.0 2200.0 2600.0 2800.0 3000.0 +1700.0 2100.0 2300.0 2600.0 3000.0 3300.0 +1400.0 1500.0 1700.0 1800.0 2700.0 3200.0 +1500.0 1600.0 1900.0 2000.0 2600.0 3200.0 +1000.0 1300.0 2400.0 2600.0 2900.0 3300.0 +1300.0 1500.0 1900.0 2500.0 2700.0 3000.0 +1800.0 1900.0 2200.0 2600.0 2900.0 3300.0 +1300.0 1400.0 1700.0 1800.0 2700.0 3200.0 +1700.0 1800.0 2000.0 2500.0 2700.0 2900.0 +1800.0 2000.0 2300.0 2700.0 2800.0 3100.0 +1600.0 1700.0 2200.0 2800.0 2900.0 3100.0 +1800.0 2100.0 2800.0 2900.0 3200.0 3400.0 +1700.0 2100.0 2800.0 2900.0 3100.0 3400.0 +1900.0 2400.0 2700.0 2800.0 3400.0 3500.0 +1600.0 1700.0 2400.0 2700.0 2800.0 3200.0 +1600.0 1900.0 2200.0 2500.0 3000.0 3300.0 +1400.0 1500.0 2000.0 2500.0 2800.0 3100.0 +1200.0 1300.0 2100.0 2500.0 2700.0 3000.0 +1900.0 2200.0 2600.0 2800.0 3400.0 3500.0 +1500.0 1900.0 2600.0 2700.0 2900.0 3300.0 +1400.0 1500.0 2000.0 2100.0 2700.0 3100.0 +1600.0 1700.0 2100.0 2200.0 2600.0 3200.0 +1700.0 2200.0 2500.0 2700.0 3000.0 3100.0 +1800.0 2300.0 2500.0 2600.0 2900.0 3100.0 +1100.0 1300.0 2500.0 2700.0 2900.0 3200.0 +1400.0 1500.0 1900.0 2000.0 2600.0 3200.0 +1600.0 1700.0 2000.0 2100.0 2800.0 3300.0 +1300.0 1900.0 2300.0 2600.0 2700.0 3000.0 +1800.0 1900.0 2500.0 2700.0 2900.0 3100.0 +2100.0 2200.0 2700.0 3000.0 3100.0 3300.0 +2000.0 2100.0 2700.0 2900.0 3200.0 3400.0 +1500.0 1700.0 1800.0 2200.0 3200.0 3300.0 +1500.0 1800.0 2000.0 2700.0 3200.0 3300.0 +1800.0 1900.0 2100.0 2400.0 3100.0 3200.0 +1500.0 1600.0 2400.0 2500.0 3200.0 3300.0 +1400.0 1800.0 2400.0 2600.0 3300.0 3400.0 +1400.0 1800.0 2400.0 2600.0 3200.0 3400.0 +2300.0 2600.0 2800.0 3100.0 3300.0 3400.0 +2000.0 2100.0 2800.0 2900.0 3300.0 3400.0 +1400.0 1700.0 2600.0 2700.0 3200.0 3300.0 +1300.0 1700.0 2500.0 2700.0 3200.0 3300.0 +1500.0 1800.0 2200.0 2700.0 3000.0 3300.0 +1800.0 2000.0 2300.0 2500.0 2900.0 3300.0 +1300.0 1800.0 2400.0 2500.0 3200.0 3400.0 +1500.0 1900.0 2500.0 2600.0 3000.0 3300.0 +1700.0 1800.0 2700.0 2800.0 3200.0 3400.0 +1500.0 1800.0 2700.0 2800.0 3200.0 3400.0 +1500.0 1800.0 2700.0 2800.0 3300.0 3400.0 +1400.0 1600.0 2400.0 2500.0 3200.0 3300.0 +1600.0 1800.0 2400.0 2800.0 3100.0 3300.0 +1500.0 2100.0 2500.0 2600.0 3100.0 3300.0 +1500.0 1600.0 2500.0 2600.0 3000.0 3400.0 +1200.0 1900.0 2300.0 2500.0 3100.0 3300.0 +1500.0 1600.0 2300.0 2500.0 3200.0 3300.0 +1600.0 2300.0 2600.0 2800.0 3300.0 3400.0 +2100.0 2400.0 2500.0 2700.0 3200.0 3300.0 +1100.0 1800.0 2500.0 2600.0 2900.0 3200.0 +1400.0 1700.0 2100.0 2600.0 3000.0 3200.0 +1700.0 2000.0 2500.0 2600.0 3000.0 3100.0 +1100.0 1500.0 2500.0 2600.0 3100.0 3300.0 +1500.0 1600.0 2200.0 2400.0 2600.0 3200.0 +1600.0 1800.0 2300.0 2500.0 2900.0 3300.0 +1600.0 1700.0 2100.0 2300.0 3000.0 3200.0 +2000.0 2200.0 2600.0 2800.0 3300.0 3400.0 +1600.0 1700.0 1900.0 2400.0 3100.0 3300.0 +1200.0 1700.0 2300.0 2500.0 3100.0 3400.0 +1100.0 1600.0 1900.0 2200.0 3000.0 3100.0 +1400.0 1900.0 2300.0 2600.0 2900.0 3000.0 +1900.0 2200.0 2800.0 3000.0 3200.0 3400.0 +1400.0 1500.0 2200.0 2300.0 2700.0 3100.0 +1800.0 1900.0 2200.0 2600.0 3000.0 3300.0 +1700.0 1900.0 2200.0 2500.0 2700.0 3000.0 +1600.0 1800.0 2000.0 2400.0 2700.0 2800.0 +1900.0 2300.0 2700.0 2900.0 3100.0 3200.0 +1400.0 1500.0 2000.0 2400.0 2900.0 3000.0 +1800.0 2100.0 2200.0 2500.0 2700.0 3000.0 +1200.0 1300.0 1900.0 2500.0 3000.0 3100.0 +1100.0 1200.0 2500.0 2900.0 3000.0 3200.0 +1400.0 1500.0 1900.0 2000.0 2500.0 3100.0 +1400.0 1600.0 2000.0 2200.0 2500.0 3100.0 +1200.0 1700.0 2300.0 2700.0 3100.0 3300.0 +1900.0 2200.0 2300.0 2500.0 2700.0 3100.0 +1500.0 1600.0 2000.0 2100.0 2800.0 3300.0 +1500.0 1800.0 2000.0 2300.0 2600.0 2900.0 +2100.0 2200.0 2600.0 2700.0 3000.0 3100.0 +2100.0 2300.0 2700.0 2900.0 3200.0 3400.0 +1600.0 1700.0 1900.0 2000.0 2700.0 3100.0 +1300.0 1500.0 1800.0 1900.0 2500.0 3100.0 +1900.0 2500.0 2700.0 2900.0 3200.0 3300.0 +1200.0 1400.0 2000.0 2700.0 3200.0 3300.0 +1900.0 2500.0 2700.0 2800.0 3200.0 3300.0 +1200.0 1600.0 2200.0 2400.0 2900.0 3200.0 +2000.0 2200.0 2600.0 2700.0 3100.0 3400.0 +1500.0 1700.0 2000.0 2300.0 2600.0 3000.0 +1700.0 2100.0 2500.0 2700.0 3000.0 3100.0 +1800.0 2200.0 2500.0 2700.0 3000.0 3100.0 +2000.0 2400.0 2600.0 2900.0 3100.0 3200.0 +1700.0 2400.0 2500.0 2700.0 3100.0 3200.0 +1600.0 2000.0 2100.0 2600.0 3000.0 3100.0 +1500.0 2100.0 2400.0 2600.0 3000.0 3200.0 +1400.0 1600.0 2000.0 2600.0 3100.0 3200.0 +1500.0 1700.0 2000.0 2800.0 3100.0 3200.0 +1600.0 1700.0 2000.0 2700.0 3100.0 3200.0 +1400.0 2000.0 2300.0 2500.0 3000.0 3200.0 +1600.0 1800.0 2000.0 2300.0 3100.0 3300.0 +1500.0 1800.0 2300.0 2700.0 2900.0 3200.0 +1100.0 1400.0 2200.0 2300.0 3200.0 3300.0 +1800.0 2400.0 2800.0 2900.0 3200.0 3300.0 +1700.0 2400.0 2800.0 2900.0 3200.0 3300.0 +2000.0 2200.0 2800.0 3000.0 3400.0 3500.0 +1300.0 1400.0 2200.0 2900.0 3100.0 3200.0 +1200.0 1400.0 2300.0 2900.0 3100.0 3200.0 +1600.0 1900.0 2300.0 2600.0 2900.0 3300.0 +1700.0 2200.0 2300.0 2700.0 3100.0 3200.0 +1200.0 1700.0 2400.0 2700.0 3000.0 3300.0 +1500.0 1700.0 1900.0 2500.0 2900.0 3100.0 +1700.0 1800.0 2200.0 2600.0 2900.0 3300.0 +1300.0 1400.0 1900.0 2600.0 3000.0 3100.0 +1200.0 1400.0 2200.0 2500.0 2900.0 3300.0 +1500.0 1800.0 2000.0 2500.0 2900.0 3000.0 +1300.0 1400.0 2300.0 2500.0 2900.0 3300.0 +1700.0 2100.0 2300.0 2700.0 3000.0 3100.0 +1700.0 2100.0 2300.0 2800.0 3000.0 3100.0 +1200.0 1300.0 2100.0 2800.0 3200.0 3300.0 +1300.0 1600.0 2100.0 2600.0 2900.0 3100.0 +1300.0 1400.0 1800.0 2500.0 2800.0 3000.0 +1500.0 1700.0 2400.0 2600.0 2900.0 3000.0 +2100.0 2200.0 2500.0 2600.0 3000.0 3100.0 +2200.0 2300.0 2500.0 2700.0 3000.0 3200.0 +1400.0 1800.0 2000.0 2300.0 3200.0 3300.0 +1600.0 1700.0 2400.0 2700.0 3100.0 3200.0 +1600.0 1700.0 2500.0 2700.0 3000.0 3200.0 +1900.0 2500.0 2600.0 2800.0 3200.0 3300.0 +1200.0 1400.0 2600.0 2800.0 3000.0 3300.0 +1800.0 2300.0 2500.0 3000.0 3300.0 3400.0 +1200.0 1400.0 2200.0 2700.0 3200.0 3300.0 +1100.0 1400.0 2400.0 2500.0 3100.0 3400.0 +1100.0 1300.0 2400.0 2500.0 3200.0 3400.0 +1000.0 1400.0 2400.0 2500.0 3000.0 3300.0 +1800.0 1900.0 2400.0 2700.0 3200.0 3400.0 +1600.0 1700.0 2200.0 2500.0 2800.0 3300.0 +2000.0 2200.0 2400.0 2800.0 2900.0 3100.0 +1300.0 1800.0 2700.0 2800.0 3200.0 3400.0 +1800.0 2200.0 2700.0 3000.0 3400.0 3500.0 +1800.0 1900.0 2300.0 2600.0 2700.0 3000.0 +1900.0 2000.0 2400.0 2600.0 2900.0 3400.0 +1600.0 1700.0 2300.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2500.0 2700.0 3200.0 3300.0 +2100.0 2500.0 2800.0 3000.0 3200.0 3400.0 +1800.0 2000.0 2300.0 2400.0 3000.0 3100.0 +2300.0 2400.0 2600.0 2900.0 3100.0 3300.0 +1600.0 1800.0 2400.0 2500.0 3000.0 3100.0 +2100.0 2500.0 2900.0 3100.0 3200.0 3300.0 +1600.0 1900.0 2500.0 2900.0 3100.0 3300.0 +1500.0 1800.0 2300.0 2400.0 3200.0 3400.0 +1300.0 1500.0 2700.0 2800.0 3100.0 3300.0 +1200.0 1500.0 2600.0 2700.0 3200.0 3300.0 +1000.0 1500.0 2700.0 2800.0 3200.0 3300.0 +1100.0 1600.0 2600.0 2700.0 3200.0 3300.0 +1500.0 1700.0 2600.0 2700.0 3000.0 3300.0 +1100.0 1700.0 2800.0 2900.0 3200.0 3400.0 +1300.0 1700.0 2300.0 2500.0 3300.0 3400.0 +1700.0 2100.0 2400.0 2500.0 3200.0 3300.0 +1500.0 1800.0 2100.0 2400.0 3300.0 3400.0 +2000.0 2100.0 2400.0 2600.0 2800.0 3100.0 +1600.0 1700.0 2300.0 2800.0 3100.0 3300.0 +1900.0 2100.0 2800.0 3000.0 3300.0 3400.0 +2000.0 2100.0 2300.0 2600.0 2900.0 3200.0 +1100.0 1500.0 2500.0 2700.0 2900.0 3300.0 +1600.0 1800.0 2200.0 2500.0 2700.0 2800.0 +2000.0 2200.0 2500.0 2600.0 3100.0 3200.0 +1400.0 1600.0 2100.0 2900.0 3100.0 3200.0 +1900.0 2400.0 2800.0 3000.0 3200.0 3300.0 +2000.0 2300.0 2500.0 2700.0 2900.0 3200.0 +1700.0 2100.0 2300.0 2800.0 3200.0 3300.0 +1400.0 2000.0 2300.0 2500.0 3100.0 3300.0 +2000.0 2500.0 2600.0 3000.0 3200.0 3300.0 +1500.0 1700.0 2500.0 2600.0 3000.0 3400.0 +1100.0 2000.0 2500.0 2700.0 3200.0 3300.0 +1400.0 1600.0 2600.0 2900.0 3100.0 3400.0 +1800.0 2300.0 2800.0 3000.0 3200.0 3300.0 +1700.0 2000.0 2100.0 2300.0 3300.0 3400.0 +1400.0 1700.0 1800.0 2300.0 3300.0 3400.0 +1400.0 1500.0 2300.0 2500.0 3000.0 3400.0 +1400.0 1700.0 2600.0 2700.0 3100.0 3200.0 +1500.0 1700.0 2600.0 2700.0 3200.0 3300.0 +1600.0 1800.0 2600.0 2700.0 3100.0 3300.0 +1200.0 1400.0 1500.0 2200.0 3100.0 3200.0 +1500.0 1600.0 2100.0 2400.0 2700.0 3200.0 +1000.0 1500.0 2600.0 2700.0 3000.0 3300.0 +1200.0 1500.0 1600.0 2100.0 3100.0 3200.0 +1800.0 2200.0 2600.0 3000.0 3400.0 3500.0 +1000.0 2300.0 2600.0 2700.0 3200.0 3300.0 +1400.0 1600.0 2100.0 2500.0 2800.0 3200.0 +1300.0 1900.0 2300.0 2500.0 2900.0 3300.0 +1500.0 1600.0 2400.0 2500.0 3300.0 3400.0 +1600.0 2000.0 2500.0 2800.0 3100.0 3200.0 +1000.0 2100.0 2500.0 2600.0 3100.0 3400.0 +1700.0 1800.0 2100.0 2400.0 3000.0 3100.0 +2200.0 2300.0 2600.0 2700.0 3000.0 3300.0 +1900.0 2000.0 2700.0 2800.0 3300.0 3400.0 +1500.0 1700.0 2400.0 2500.0 2900.0 3100.0 +1100.0 1600.0 2800.0 2900.0 3200.0 3300.0 +2000.0 2600.0 2800.0 3000.0 3400.0 3500.0 +1900.0 2500.0 2800.0 3100.0 3400.0 3500.0 +1200.0 1700.0 2700.0 2800.0 3200.0 3400.0 +1300.0 1600.0 2700.0 2800.0 3100.0 3400.0 +1500.0 1700.0 2700.0 2800.0 3100.0 3400.0 +1300.0 1400.0 2500.0 2800.0 3200.0 3400.0 +1700.0 2000.0 2700.0 2800.0 3300.0 3400.0 +1800.0 1900.0 2600.0 2700.0 3300.0 3400.0 +1100.0 1800.0 2700.0 2800.0 3200.0 3300.0 +2100.0 2600.0 2700.0 3000.0 3300.0 3400.0 +1300.0 1600.0 1800.0 2100.0 2900.0 3000.0 +1300.0 1500.0 2200.0 2400.0 3100.0 3400.0 +1200.0 1500.0 1700.0 2000.0 3000.0 3100.0 +1200.0 1500.0 1700.0 2100.0 3000.0 3100.0 +1300.0 2000.0 2200.0 2400.0 2700.0 3000.0 +1500.0 1800.0 2100.0 2300.0 3300.0 3400.0 +1100.0 1600.0 1800.0 2200.0 3000.0 3100.0 +1000.0 1800.0 2100.0 2400.0 3000.0 3100.0 +1500.0 1600.0 2300.0 2400.0 2900.0 3400.0 +1400.0 1600.0 1800.0 2100.0 2900.0 3000.0 +1100.0 1500.0 2100.0 2200.0 3100.0 3200.0 +1300.0 1700.0 1800.0 2200.0 3000.0 3100.0 +1500.0 1700.0 2100.0 2300.0 2700.0 2900.0 +1100.0 1700.0 1900.0 2100.0 2900.0 3000.0 +1400.0 1700.0 2100.0 2400.0 2900.0 3200.0 +1300.0 1600.0 1800.0 2300.0 3000.0 3100.0 +1200.0 1500.0 1700.0 2300.0 3000.0 3100.0 +1600.0 1800.0 1900.0 2300.0 3000.0 3100.0 +1700.0 2200.0 2600.0 2900.0 3100.0 3300.0 +1900.0 2400.0 2500.0 2700.0 2900.0 3100.0 +1800.0 2000.0 2100.0 2400.0 3100.0 3200.0 +1700.0 2400.0 2700.0 2800.0 3000.0 3200.0 +1800.0 1900.0 2300.0 2600.0 2800.0 3300.0 +1300.0 1900.0 2500.0 2600.0 3200.0 3400.0 +1400.0 1600.0 2300.0 2400.0 2800.0 3100.0 +1900.0 2000.0 2300.0 2700.0 3000.0 3300.0 +1700.0 1800.0 2400.0 2700.0 3200.0 3400.0 +1800.0 2000.0 2300.0 2600.0 2900.0 3300.0 +2100.0 2300.0 2600.0 2700.0 3300.0 3400.0 +1400.0 1600.0 2200.0 2400.0 3200.0 3300.0 +1300.0 1600.0 1800.0 2200.0 2800.0 2900.0 +1500.0 1700.0 1900.0 2600.0 2800.0 3000.0 +1700.0 2200.0 2500.0 2600.0 3100.0 3300.0 +1200.0 1700.0 1800.0 2100.0 3000.0 3100.0 +1100.0 1800.0 2500.0 2600.0 3300.0 3400.0 +1100.0 1900.0 2100.0 2300.0 2900.0 3000.0 +1200.0 1700.0 2400.0 2600.0 3100.0 3400.0 +1100.0 1700.0 2600.0 2700.0 3000.0 3300.0 +1000.0 1700.0 2700.0 2800.0 3200.0 3400.0 +1100.0 1900.0 2200.0 2300.0 3200.0 3300.0 +1300.0 1900.0 2300.0 2500.0 3000.0 3300.0 +1200.0 1600.0 2600.0 2700.0 3100.0 3400.0 +1300.0 1600.0 1800.0 2400.0 3000.0 3200.0 +1400.0 1700.0 1800.0 2100.0 3200.0 3400.0 +1000.0 1500.0 2300.0 2400.0 3200.0 3400.0 +900.0 1700.0 2600.0 2700.0 3300.0 3400.0 +1100.0 1400.0 2500.0 2700.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2500.0 2800.0 2900.0 +2100.0 2300.0 2700.0 2900.0 3400.0 3500.0 +2100.0 2200.0 2300.0 2400.0 3000.0 3300.0 +1800.0 2000.0 2400.0 2500.0 2800.0 3000.0 +1700.0 1900.0 2300.0 2500.0 2700.0 3000.0 +1300.0 1400.0 2300.0 2900.0 3100.0 3200.0 +2100.0 2300.0 2600.0 2900.0 3100.0 3200.0 +1400.0 1800.0 2200.0 2300.0 3200.0 3400.0 +2100.0 2500.0 2900.0 3200.0 3400.0 3500.0 +1700.0 1900.0 2100.0 2400.0 3200.0 3400.0 +1600.0 1700.0 2300.0 2600.0 2800.0 2900.0 +1800.0 2000.0 2300.0 2700.0 2800.0 3000.0 +1900.0 2300.0 2600.0 2800.0 3000.0 3100.0 +1300.0 1600.0 2200.0 2600.0 3100.0 3200.0 +1500.0 1600.0 2400.0 2500.0 2900.0 3400.0 +1600.0 1800.0 2000.0 2700.0 3100.0 3200.0 +1000.0 1800.0 2600.0 2700.0 3200.0 3400.0 +900.0 1800.0 2500.0 2600.0 3300.0 3400.0 +1300.0 2200.0 2300.0 2700.0 3200.0 3300.0 +1200.0 2000.0 2300.0 2500.0 3300.0 3400.0 +1100.0 1500.0 2400.0 2500.0 3100.0 3400.0 +1300.0 1700.0 1900.0 2100.0 3000.0 3100.0 +2000.0 2100.0 2500.0 2600.0 3300.0 3500.0 +1500.0 1800.0 2000.0 2500.0 3300.0 3400.0 +2000.0 2100.0 2800.0 2900.0 3100.0 3300.0 +2300.0 2400.0 2600.0 2800.0 3200.0 3300.0 +1400.0 1900.0 2200.0 2300.0 3100.0 3200.0 +1500.0 1900.0 2600.0 2700.0 3200.0 3300.0 +1500.0 1600.0 2200.0 2600.0 3100.0 3400.0 +1700.0 1800.0 2500.0 2700.0 3300.0 3400.0 +1100.0 1600.0 2400.0 2500.0 3300.0 3400.0 +900.0 1600.0 2600.0 2700.0 3300.0 3400.0 +1400.0 1500.0 2200.0 2600.0 3200.0 3400.0 +1200.0 2000.0 2400.0 2500.0 2700.0 3200.0 +1300.0 1500.0 2500.0 2600.0 3200.0 3300.0 +1500.0 1600.0 2300.0 2600.0 3200.0 3400.0 +1300.0 2000.0 2300.0 2800.0 3000.0 3200.0 +2000.0 2100.0 2600.0 2700.0 3000.0 3100.0 +2000.0 2200.0 2600.0 2700.0 3000.0 3100.0 +2100.0 2200.0 2800.0 2900.0 3100.0 3200.0 +1900.0 2100.0 2500.0 2600.0 3000.0 3100.0 +1900.0 2100.0 2300.0 2500.0 2800.0 2900.0 +1800.0 2000.0 2600.0 2700.0 3000.0 3400.0 +1400.0 1700.0 1800.0 2500.0 2800.0 3200.0 +1300.0 1800.0 2200.0 2300.0 3200.0 3400.0 +1400.0 1600.0 1700.0 2200.0 3200.0 3400.0 +1400.0 1500.0 1600.0 2100.0 3200.0 3400.0 +1700.0 2100.0 2300.0 2500.0 3300.0 3400.0 +1600.0 2000.0 2600.0 2800.0 3200.0 3400.0 +1400.0 1600.0 2700.0 2800.0 3000.0 3300.0 +1400.0 1500.0 1600.0 2200.0 3300.0 3400.0 +1600.0 1700.0 2500.0 2600.0 3300.0 3400.0 +1000.0 1500.0 2300.0 2400.0 3000.0 3100.0 +1400.0 1500.0 1700.0 1800.0 3200.0 3300.0 +1600.0 2000.0 2300.0 2500.0 2800.0 3100.0 +1900.0 2500.0 2600.0 2900.0 3400.0 3500.0 +1800.0 1900.0 2500.0 2600.0 3300.0 3500.0 +1500.0 1900.0 2200.0 2300.0 3200.0 3300.0 +1900.0 2200.0 2500.0 2600.0 3300.0 3400.0 +1400.0 2000.0 2300.0 2600.0 3100.0 3300.0 +1800.0 1900.0 2300.0 2400.0 3200.0 3500.0 +1100.0 1900.0 2500.0 2600.0 2900.0 3000.0 +1600.0 1700.0 2300.0 2400.0 2900.0 3000.0 +1700.0 2300.0 2500.0 2700.0 3000.0 3100.0 +2100.0 2200.0 2700.0 2900.0 3100.0 3400.0 +1400.0 1900.0 2300.0 2600.0 2800.0 2900.0 +1800.0 2000.0 2200.0 2400.0 2600.0 2900.0 +1400.0 2100.0 2500.0 2600.0 2900.0 3100.0 +1700.0 1900.0 2400.0 2800.0 3200.0 3400.0 +1000.0 1500.0 2300.0 2400.0 3000.0 3300.0 +1500.0 2000.0 2300.0 2800.0 3200.0 3300.0 +1900.0 2000.0 2300.0 2600.0 3100.0 3400.0 +1300.0 1500.0 2400.0 2600.0 3300.0 3400.0 +2100.0 2500.0 2900.0 3100.0 3200.0 3400.0 +1400.0 1700.0 1800.0 2400.0 3200.0 3300.0 +1400.0 1500.0 2300.0 2600.0 3100.0 3400.0 +1000.0 1900.0 2600.0 2700.0 3000.0 3100.0 +1100.0 1800.0 2500.0 2700.0 3200.0 3300.0 +1700.0 1800.0 2200.0 2700.0 2800.0 3200.0 +2000.0 2200.0 2700.0 2800.0 3100.0 3200.0 +1300.0 2100.0 2400.0 2500.0 2900.0 3100.0 +1300.0 2000.0 2400.0 2500.0 2800.0 3000.0 +1500.0 2100.0 2500.0 2600.0 2900.0 3100.0 +1700.0 2200.0 2500.0 2700.0 3000.0 3200.0 +1600.0 2100.0 2500.0 2600.0 3000.0 3100.0 +1700.0 2200.0 2500.0 2600.0 3000.0 3200.0 +1800.0 2200.0 2300.0 2600.0 3000.0 3200.0 +1300.0 1500.0 1700.0 2100.0 3300.0 3400.0 +1300.0 1500.0 1700.0 2000.0 3300.0 3400.0 +1300.0 1900.0 2700.0 2800.0 3200.0 3400.0 +1700.0 2500.0 2700.0 2900.0 3300.0 3400.0 +1100.0 1700.0 2100.0 2200.0 3300.0 3400.0 +1000.0 1800.0 2700.0 2900.0 3300.0 3400.0 +1500.0 1600.0 2500.0 2600.0 3200.0 3300.0 +1100.0 1900.0 2600.0 2800.0 3000.0 3100.0 +1300.0 1500.0 2400.0 2500.0 3200.0 3300.0 +1700.0 2100.0 2300.0 2400.0 2800.0 3300.0 +1300.0 1500.0 1700.0 1800.0 3200.0 3400.0 +2000.0 2100.0 2400.0 2700.0 2900.0 3300.0 +1400.0 1500.0 2500.0 2600.0 3000.0 3200.0 +1400.0 1500.0 2000.0 2900.0 3300.0 3400.0 +1300.0 1500.0 2600.0 2700.0 3100.0 3200.0 +1100.0 1300.0 2700.0 2800.0 3200.0 3300.0 +1100.0 1300.0 2500.0 2600.0 2900.0 3100.0 +1900.0 2300.0 2400.0 2600.0 2700.0 3100.0 +1300.0 2100.0 2200.0 2600.0 3200.0 3300.0 +1100.0 1800.0 2400.0 2500.0 2900.0 3100.0 +1000.0 1800.0 2200.0 2300.0 3200.0 3300.0 +1500.0 1700.0 1800.0 2600.0 3200.0 3400.0 +1500.0 2000.0 2400.0 2600.0 2700.0 3100.0 +2000.0 2100.0 2300.0 2500.0 2700.0 3300.0 +1000.0 1500.0 2700.0 2800.0 3300.0 3400.0 diff --git a/gr-vocoder/lib/codec2/codebook/lspjvm1.txt b/gr-vocoder/lib/codec2/codebook/lspjvm1.txt new file mode 100644 index 0000000000..9cd10ed35c --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspjvm1.txt @@ -0,0 +1,513 @@ +10 512 +0.435217 0.668864 1.010296 1.220420 1.503978 1.784675 2.135458 2.357467 2.618905 2.738042 +0.179285 0.333160 0.500638 0.796950 1.039987 1.234969 1.652301 1.848233 2.625555 2.804968 +0.268785 0.356576 0.595753 1.044339 1.249382 1.428680 1.686986 1.864689 2.339905 2.513801 +0.120070 0.165585 0.484694 0.959160 1.237528 1.529146 1.837513 2.107730 2.487495 2.766846 +0.150214 0.229487 0.628240 0.961255 1.337065 1.598306 1.919745 2.217861 2.537318 2.759560 +0.268624 0.345980 0.569637 0.754737 0.916538 1.508543 1.786354 1.954418 2.369530 2.501822 +0.246064 0.468874 0.662711 0.890015 1.147153 1.510431 1.781056 2.095943 2.655391 2.800369 +0.191631 0.280628 0.393229 0.611761 1.420170 1.707741 1.873032 2.101553 2.280348 2.499488 +0.361668 0.507047 0.789974 1.045992 1.502378 1.677032 1.905337 2.162555 2.432259 2.590873 +0.208160 0.294285 0.448634 0.694229 0.872517 1.070315 1.703352 2.168742 2.426189 2.603657 +0.316939 0.513618 0.705487 0.917036 1.175989 1.311140 1.618599 2.037840 2.450523 2.579395 +0.241068 0.377728 0.521595 0.717203 1.310414 1.539991 1.736431 2.098926 2.297917 2.587348 +0.234937 0.281875 0.780422 1.440733 1.609428 1.756430 1.977206 2.148605 2.602032 2.722501 +0.178679 0.242672 0.416988 0.708348 0.955620 1.176671 1.781798 2.054488 2.281591 2.448112 +0.345036 0.421080 0.740887 1.165442 1.324944 1.488798 1.763463 1.906174 2.395050 2.649158 +0.249586 0.357494 0.520747 0.847195 1.428408 1.597779 1.778194 2.178502 2.413437 2.564662 +0.295235 0.574231 1.249097 1.464097 1.727559 1.926790 2.095363 2.284830 2.567065 2.722480 +0.341930 0.427307 0.634001 0.804212 0.905629 1.333373 1.790329 1.892756 2.445823 2.602828 +0.363948 0.508985 0.667357 0.946354 1.437562 1.626545 1.811141 2.039091 2.291882 2.435493 +0.163514 0.277407 0.409207 0.902065 1.189070 1.339636 1.802411 1.960770 2.652930 2.818987 +0.302643 0.359753 0.651207 1.208021 1.423702 1.548149 1.882130 2.015591 2.260535 2.578896 +0.155928 0.216908 0.381812 0.654803 1.112373 1.589935 1.847562 1.976716 2.224078 2.725337 +0.274981 0.347675 0.572000 0.736046 0.894248 1.632373 1.891391 2.056890 2.602900 2.721779 +0.154496 0.243461 0.348174 0.689505 1.573807 1.700306 1.943182 2.101580 2.564661 2.773169 +0.292612 0.466612 0.795936 1.047468 1.413693 1.750848 2.062894 2.340073 2.613612 2.769493 +0.242896 0.361500 0.555859 0.793597 0.932291 1.409467 1.863863 2.009534 2.464500 2.677491 +0.221646 0.344724 0.554564 0.729403 1.136575 1.301772 1.529181 2.163590 2.395821 2.610805 +0.160969 0.224467 0.371545 0.626879 1.160953 1.444229 1.675966 1.879779 2.478590 2.672023 +0.214172 0.341585 0.676575 0.977397 1.325429 1.720096 2.072595 2.369539 2.635285 2.778792 +0.203311 0.289438 0.458739 0.914153 1.122885 1.302925 1.583844 1.886828 2.187869 2.427039 +0.280383 0.371600 0.824827 1.100246 1.236225 1.398923 1.578041 2.016000 2.368973 2.506732 +0.170627 0.251778 0.393686 0.608347 1.287599 1.446665 1.793278 2.036554 2.310153 2.752439 +0.180580 0.288746 0.987854 1.431706 1.677216 1.915661 2.124939 2.289452 2.589612 2.754264 +0.176335 0.266263 0.445421 0.706403 0.875402 1.422918 1.758670 1.960910 2.410676 2.601751 +0.216173 0.287404 0.480696 1.009765 1.291304 1.476644 1.895584 2.064286 2.284064 2.483108 +0.176523 0.273934 0.403407 0.966139 1.304724 1.436612 1.944728 2.084836 2.544458 2.762416 +0.311836 0.550501 0.879591 1.096228 1.276661 1.477859 1.817706 2.154340 2.560467 2.779841 +0.179765 0.250560 0.455939 1.023886 1.225132 1.475662 1.734617 1.918713 2.147342 2.438235 +0.271033 0.457235 0.599622 0.821049 0.940125 1.200937 1.849716 1.986656 2.548168 2.751578 +0.179326 0.248002 0.426405 0.817060 1.285888 1.565019 2.117359 2.298712 2.572404 2.752701 +0.374409 0.535936 0.897009 1.185070 1.591569 1.757202 1.967944 2.179985 2.457394 2.622641 +0.185472 0.282752 0.409439 0.657499 0.856446 1.029396 1.879933 2.069323 2.344742 2.753103 +0.375964 0.578457 0.758945 0.929339 1.127475 1.259437 1.704109 2.122973 2.336031 2.498298 +0.225641 0.361030 0.501679 0.783379 1.314851 1.452621 1.714150 1.987157 2.225703 2.724361 +0.144996 0.252919 0.632145 1.226038 1.575343 1.901549 2.171481 2.390554 2.682293 2.809834 +0.172022 0.263338 0.448634 0.729435 0.984007 1.171597 1.757049 1.990232 2.321305 2.771210 +0.235731 0.351117 0.796871 1.055711 1.300224 1.591818 1.895875 2.122918 2.417888 2.599817 +0.254053 0.319371 0.455623 1.086141 1.664667 1.915882 2.059084 2.233416 2.452037 2.586788 +0.375538 0.742993 1.139911 1.337758 1.735562 2.013906 2.315012 2.483433 2.651575 2.755211 +0.247245 0.481131 0.710366 0.897602 1.121094 1.271709 1.787346 2.199502 2.429663 2.740668 +0.226103 0.311441 0.501648 0.844424 1.362818 1.531338 1.777474 1.989925 2.187493 2.358501 +0.195862 0.296224 0.609554 0.783241 1.243472 1.445477 1.637032 2.022645 2.483557 2.646137 +0.233302 0.299441 0.472792 1.249457 1.457875 1.601860 1.831433 1.993719 2.597193 2.755433 +0.168096 0.224183 0.382700 0.596214 1.060587 1.294418 1.605760 1.848489 2.357695 2.569186 +0.330050 0.445912 0.661713 0.874446 1.000792 1.452973 1.943987 2.076916 2.423883 2.612359 +0.226382 0.287303 0.517631 0.806229 1.309009 1.885280 2.160514 2.286410 2.526377 2.660822 +0.203170 0.499314 0.887358 1.235074 1.462922 1.698260 1.999316 2.229225 2.571613 2.766691 +0.307531 0.378353 0.573606 0.712218 0.850169 1.308996 2.059092 2.263816 2.497943 2.676815 +0.276203 0.510250 0.686800 0.902844 1.205197 1.327979 1.718894 2.038947 2.256393 2.697149 +0.161948 0.229115 0.393619 0.683613 1.137811 1.322692 1.783723 1.961584 2.389073 2.636082 +0.201334 0.276773 0.468994 0.967017 1.475971 1.632424 1.965774 2.197278 2.480593 2.701553 +0.214587 0.315421 0.469498 0.733397 1.146003 1.277911 1.727839 2.227135 2.440264 2.681122 +0.255602 0.394609 0.743393 0.977796 1.199085 1.405972 1.918336 2.224828 2.479187 2.663394 +0.245989 0.352625 0.517055 0.802830 1.558712 1.795653 1.944055 2.133640 2.333267 2.479982 +0.337423 0.480433 0.869036 1.139571 1.630764 1.822959 2.074843 2.292613 2.479130 2.625317 +0.220974 0.358850 0.571640 0.752791 0.937013 1.151721 1.674398 2.062466 2.558717 2.784838 +0.267518 0.331708 0.541111 1.116547 1.411121 1.532868 1.792949 1.933520 2.248940 2.628644 +0.084613 0.105083 0.297424 0.916949 1.256301 1.567029 1.885388 2.189875 2.522795 2.792102 +0.205328 0.287223 0.724462 1.032395 1.457708 1.642169 1.925628 2.175524 2.429638 2.605488 +0.232554 0.338724 0.502115 0.859975 1.044090 1.245652 1.806555 1.999641 2.261164 2.459984 +0.291638 0.379172 0.626072 0.792796 0.959124 1.504886 1.734465 1.919612 2.614359 2.722709 +0.191554 0.263114 0.426797 0.610628 1.077406 1.829543 2.021948 2.210572 2.427652 2.613828 +0.389151 0.679476 0.915414 1.036635 1.250846 1.586610 2.040972 2.281500 2.567941 2.718815 +0.203200 0.301280 0.470357 0.668716 0.851737 0.980327 1.570862 2.037617 2.289067 2.693877 +0.304064 0.405934 0.710274 0.962705 1.128820 1.341667 1.635050 1.845382 2.079916 2.507510 +0.171777 0.240705 0.409371 0.786432 1.223202 1.375689 1.691760 1.866080 2.350406 2.493942 +0.231251 0.277994 0.557867 1.325822 1.660352 1.779477 2.007138 2.172322 2.440457 2.652308 +0.188101 0.259494 0.412543 0.624843 0.839549 1.033700 1.634128 1.931944 2.246076 2.425773 +0.361304 0.419465 0.795676 1.184605 1.296796 1.578447 1.841746 1.997361 2.540538 2.687139 +0.274372 0.338938 0.492443 0.963516 1.509514 1.706378 1.869885 2.077166 2.261281 2.444183 +0.415990 0.652103 1.031293 1.269551 1.572746 1.772975 2.004659 2.175272 2.430606 2.596553 +0.242045 0.370942 0.534392 0.763529 1.001165 1.129764 1.682192 2.144644 2.324478 2.715697 +0.377438 0.588168 0.765394 0.976873 1.356652 1.490088 1.737970 2.006774 2.213691 2.389973 +0.191625 0.284123 0.405342 1.016777 1.432730 1.547592 1.813930 1.958317 2.470765 2.649257 +0.272672 0.349555 0.633911 1.152234 1.303938 1.547640 1.919504 2.047696 2.562779 2.730575 +0.168423 0.236330 0.421468 0.831345 1.083543 1.553448 1.880726 2.064701 2.370864 2.632945 +0.219318 0.301481 0.513617 0.765086 1.026019 1.514647 2.048203 2.248568 2.499810 2.657069 +0.232695 0.347947 0.495203 0.718830 1.423013 1.722493 1.879584 2.165044 2.420251 2.589658 +0.270284 0.336865 0.684929 1.155789 1.690421 1.876744 2.027359 2.226178 2.446748 2.582000 +0.149701 0.193747 0.352019 0.520123 0.823974 1.434753 1.686592 1.961148 2.370914 2.693067 +0.254818 0.412303 0.601514 0.771438 1.175450 1.376569 1.539029 1.937039 2.408576 2.563621 +0.233713 0.355886 0.593725 0.762880 1.271479 1.563900 1.797523 2.094688 2.538627 2.711734 +0.179028 0.237103 0.396818 1.042021 1.633539 1.762676 2.123935 2.322391 2.588193 2.751345 +0.182027 0.251039 0.434581 0.714302 0.950997 1.437895 1.813570 1.969103 2.145882 2.353968 +0.501538 0.692148 0.848860 1.071308 1.350543 1.489476 1.841643 2.104284 2.341536 2.515294 +0.274530 0.381470 0.526682 0.922143 1.444946 1.573605 1.858767 2.066747 2.284796 2.626819 +0.360617 0.583131 0.979491 1.254083 1.488351 1.797557 2.219518 2.482176 2.742366 2.862025 +0.140913 0.220301 0.619552 0.818307 1.052429 1.339972 1.830726 2.133953 2.536378 2.751128 +0.293514 0.391691 0.790080 0.962740 1.160319 1.526602 1.805491 2.041462 2.361619 2.564962 +0.199542 0.290571 0.452891 0.689515 1.258530 1.409879 1.886242 2.228126 2.465677 2.726646 +0.296920 0.356356 0.784287 0.996540 1.146175 1.623865 1.815498 2.038297 2.600627 2.705700 +0.206451 0.276025 0.537547 0.802572 1.220407 1.642060 1.863625 2.001978 2.215339 2.585384 +0.333650 0.464751 0.653772 0.966306 1.103865 1.340203 1.784701 1.914591 2.470171 2.686916 +0.181861 0.244870 0.376456 0.554383 1.329897 1.810440 2.047836 2.202318 2.660855 2.817057 +0.450565 0.647291 0.951172 1.229431 1.519644 1.686812 2.049107 2.267169 2.501284 2.650596 +0.219996 0.320591 0.427747 0.601183 0.753448 0.929578 1.741979 2.285789 2.472633 2.749566 +0.333848 0.423373 0.658791 1.031299 1.222625 1.365771 1.901889 2.121101 2.290306 2.531185 +0.166064 0.233902 0.383355 0.661806 1.226567 1.399684 1.771269 1.974537 2.173487 2.566344 +0.189286 0.243602 0.390584 1.387930 1.588719 1.763237 2.091118 2.316314 2.593526 2.755080 +0.158404 0.224878 0.385000 0.668463 0.942954 1.411967 1.700313 1.828069 2.059396 2.692546 +0.325989 0.461263 0.851471 1.045709 1.284028 1.516199 1.797341 2.088387 2.437669 2.627215 +0.223709 0.289190 0.632812 0.858738 1.541903 1.746766 1.935738 2.184816 2.404330 2.583013 +0.545842 0.952420 1.340820 1.516838 1.838879 2.012890 2.244968 2.403170 2.592285 2.691119 +0.238526 0.349079 0.494582 0.987665 1.170746 1.348229 1.468645 2.296964 2.644160 2.787381 +0.270857 0.442003 0.655998 0.881913 1.259254 1.428358 1.769867 1.998528 2.395589 2.652840 +0.154384 0.211806 0.489481 0.997257 1.249817 1.541232 1.778865 1.949397 2.319136 2.623391 +0.268258 0.312888 0.589114 1.258625 1.572705 1.675430 1.912780 2.070458 2.279933 2.564230 +0.170715 0.224965 0.374011 0.540197 1.161887 1.499072 1.925865 2.082569 2.246619 2.469724 +0.324358 0.391989 0.706816 0.833614 1.015725 1.568995 1.735976 2.127068 2.558411 2.653871 +0.178059 0.258575 0.374125 0.536831 1.334827 1.798628 1.986978 2.189252 2.432266 2.626696 +0.198857 0.420955 0.817664 1.178363 1.466742 1.821295 2.207327 2.474411 2.738275 2.851185 +0.188344 0.324302 0.470468 0.790033 0.934101 1.188722 1.887171 2.052833 2.448325 2.630236 +0.201295 0.365646 0.526513 0.758388 1.140096 1.267331 1.650173 1.879342 2.102889 2.600286 +0.135058 0.169428 0.307348 0.503160 1.018083 1.447946 1.810984 2.134002 2.480277 2.759846 +0.178006 0.266610 0.390327 0.928681 1.501613 1.621327 1.871356 2.025864 2.580442 2.770801 +0.246182 0.424290 0.644023 0.801168 1.114876 1.277757 1.503317 2.074888 2.295695 2.501380 +0.322996 0.430355 0.631600 1.047698 1.221840 1.426726 1.903081 2.032223 2.516726 2.708452 +0.292994 0.430599 0.619178 0.794567 1.283029 1.652817 1.840836 2.069946 2.385375 2.528246 +0.525494 0.787797 1.121816 1.387482 1.674574 1.936221 2.224042 2.390624 2.634276 2.743234 +0.299504 0.409196 0.602235 0.892336 1.056426 1.253766 1.489136 1.639876 2.427480 2.650368 +0.423758 0.520480 0.758987 1.041257 1.173655 1.423676 1.818235 1.936407 2.363001 2.626644 +0.155042 0.247496 0.641445 0.954509 1.224970 1.465850 1.837841 2.090456 2.451501 2.716155 +0.251949 0.421094 0.706797 0.975659 1.259906 1.520067 1.816310 2.122017 2.474913 2.716671 +0.215220 0.302248 0.730598 0.896343 1.145567 1.370192 1.700685 2.022563 2.283265 2.489220 +0.285230 0.453559 0.663670 0.861526 1.011602 1.247419 1.655985 1.861291 2.578936 2.731333 +0.162067 0.219409 0.373433 0.544669 1.103298 1.597178 1.921040 2.143402 2.406499 2.660484 +0.342367 0.511499 0.931350 1.163219 1.393645 1.611146 1.972769 2.194416 2.470766 2.649264 +0.251010 0.364125 0.560956 0.746545 1.019837 1.170725 1.532945 2.288671 2.577088 2.723074 +0.315001 0.489412 0.720682 0.877607 1.090466 1.253848 1.448221 1.922954 2.255887 2.408634 +0.174666 0.235793 0.387644 0.554402 1.231089 1.456137 1.688034 2.127450 2.367035 2.597270 +0.215113 0.341915 1.043717 1.322751 1.495414 1.741895 1.961164 2.239824 2.544905 2.703945 +0.219852 0.301770 0.513912 0.705474 0.877540 1.295896 1.699002 1.987057 2.287968 2.496966 +0.290638 0.366442 0.655155 1.044990 1.172154 1.532536 1.800791 1.948931 2.509679 2.660055 +0.232252 0.313770 0.658552 0.941977 1.463174 1.665488 1.862461 2.027843 2.534016 2.701236 +0.326539 0.552681 1.121731 1.331381 1.520072 1.867084 2.082861 2.332474 2.606039 2.737092 +0.190254 0.340428 0.492777 0.739738 0.895461 1.079371 1.643156 1.795290 2.491822 2.729382 +0.283586 0.418440 0.587306 0.870866 1.418553 1.577030 1.799498 2.069398 2.274484 2.438103 +0.235752 0.357650 0.502891 1.012434 1.258853 1.407789 1.820057 1.955830 2.505903 2.734330 +0.278412 0.343137 0.849977 1.232895 1.350504 1.590626 1.787519 2.091578 2.541360 2.663856 +0.162966 0.243159 0.439238 0.684821 0.887783 1.462899 1.881739 2.044253 2.289393 2.705002 +0.235063 0.371799 0.578210 0.752199 1.008546 1.476284 1.804912 2.271399 2.655042 2.789653 +0.154939 0.223696 0.344718 0.667555 1.495659 1.669436 2.069883 2.307215 2.627692 2.811343 +0.239702 0.335917 0.716616 1.131805 1.452514 1.639133 2.105515 2.279822 2.502030 2.669220 +0.226818 0.331261 0.472705 0.651974 0.781639 1.219798 1.822904 2.082732 2.439327 2.610900 +0.223413 0.359594 0.534704 0.741518 1.225894 1.389874 1.618191 2.009911 2.207000 2.459844 +0.171308 0.268378 0.383799 0.858926 1.376293 1.519165 1.780601 1.922915 2.623094 2.802402 +0.140134 0.212320 0.443224 0.967457 1.264241 1.562153 1.929148 2.217388 2.668341 2.830751 +0.221323 0.322124 0.485563 0.818589 1.011837 1.198984 1.423616 1.669403 2.157523 2.363190 +0.369687 0.525655 0.719213 0.939654 1.137631 1.312217 1.599935 1.826813 2.355221 2.580680 +0.211975 0.314411 0.489148 0.739213 1.377801 1.554504 1.824373 2.158875 2.352992 2.722621 +0.170698 0.296368 0.934285 1.243133 1.555900 1.866544 2.159940 2.363436 2.585032 2.738530 +0.189263 0.305887 0.439912 0.784610 1.227264 1.342508 1.587650 1.754907 2.439893 2.721315 +0.296339 0.385169 0.612012 1.081322 1.276361 1.437178 1.871470 2.001718 2.339094 2.640217 +0.229588 0.320544 0.517278 0.969137 1.142560 1.626089 1.877916 2.115461 2.546741 2.708025 +0.248869 0.420193 0.732388 1.049015 1.303410 1.601458 1.949210 2.239464 2.648223 2.822614 +0.207600 0.292320 0.496539 0.857149 1.182294 1.399849 1.714165 1.868238 2.027936 2.200737 +0.225558 0.396897 0.541783 0.873366 1.178972 1.299579 1.677191 1.849602 2.330475 2.752717 +0.176821 0.231377 0.372767 0.508565 1.152819 1.808050 2.112679 2.250073 2.571342 2.748550 +0.352149 0.515765 1.023238 1.260221 1.443565 1.622067 1.872804 2.100177 2.489280 2.671043 +0.166138 0.263444 0.370151 0.590066 0.754819 0.940533 1.761870 1.946611 2.445015 2.758191 +0.342082 0.476411 0.656223 0.851774 1.003992 1.153372 1.694401 2.065625 2.255642 2.440148 +0.227237 0.376514 0.514329 0.894887 1.141673 1.283052 1.831377 1.985902 2.334470 2.784878 +0.215891 0.269548 0.684111 1.405658 1.674813 1.800925 2.172085 2.339395 2.591569 2.730100 +0.236240 0.400377 0.533684 0.750343 0.910405 1.089112 1.737729 1.912807 2.192519 2.688733 +0.169242 0.284879 0.916252 1.169769 1.433683 1.644376 1.919124 2.161625 2.482664 2.682591 +0.270731 0.336506 0.477594 1.042714 1.605840 1.796859 1.945909 2.160039 2.354913 2.520950 +0.420586 0.652563 1.117162 1.406006 1.747537 1.947424 2.203094 2.359970 2.547902 2.682168 +0.281552 0.395037 0.640181 0.944531 1.193959 1.330492 1.718657 2.188389 2.444591 2.578673 +0.311824 0.476892 0.633431 0.845825 1.332518 1.491656 1.693614 2.041082 2.289317 2.439399 +0.133945 0.200790 0.647237 0.927687 1.188883 1.369658 1.699557 1.972777 2.295259 2.678185 +0.204796 0.278215 0.443465 1.270484 1.405209 1.640920 1.824252 2.327085 2.599637 2.772533 +0.183970 0.244116 0.410594 0.639103 1.221589 1.404867 1.628358 1.902439 2.168632 2.306804 +0.343622 0.434735 0.666599 0.868069 1.048942 1.532778 1.819835 1.971884 2.288701 2.448745 +0.238017 0.320361 0.657255 0.917611 1.303306 1.727361 1.988909 2.181455 2.442965 2.613322 +0.323613 0.545056 0.930173 1.226059 1.440181 1.772300 2.056890 2.347811 2.689382 2.820616 +0.288930 0.401387 0.617124 0.836453 0.990306 1.261227 1.913283 2.110049 2.324584 2.557162 +0.332670 0.480804 0.656147 0.880536 1.029566 1.230493 1.769063 1.932296 2.200370 2.585210 +0.185551 0.265352 0.409432 0.608847 1.034698 1.222821 1.876965 2.171647 2.403502 2.666441 +0.155026 0.223348 0.401684 1.079141 1.415789 1.620021 2.045515 2.258512 2.631625 2.802291 +0.183461 0.263081 0.425694 0.635685 1.188664 1.357556 1.574991 2.085982 2.288725 2.511108 +0.314738 0.463011 0.648733 0.877651 1.002890 1.265811 2.005414 2.198095 2.481535 2.714178 +0.244411 0.318444 0.546578 0.793615 1.326150 1.735479 1.945598 2.114662 2.315350 2.478535 +0.326237 0.543540 0.987361 1.304413 1.684932 1.902147 2.207172 2.374273 2.557527 2.716216 +0.157795 0.283302 0.430398 0.660379 0.811060 1.142539 1.479298 1.718714 2.670264 2.847556 +0.220856 0.283872 0.779935 1.074940 1.312211 1.626329 1.837609 1.968885 2.155988 2.602381 +0.140763 0.205719 0.406561 0.762459 1.041266 1.486993 1.838306 2.114606 2.552810 2.772285 +0.140451 0.395920 0.792110 1.108001 1.402642 1.623079 1.943151 2.227952 2.546163 2.773998 +0.229862 0.336462 0.546590 0.810150 1.201906 1.346787 1.825323 2.092925 2.285730 2.473359 +0.224913 0.328246 0.517269 0.874793 1.012587 1.452178 1.695778 2.014930 2.511447 2.672574 +0.247745 0.335741 0.546558 0.710177 1.170556 1.727789 1.970678 2.158532 2.482819 2.628913 +0.398252 0.555087 0.890367 1.121205 1.381533 1.601228 1.866647 2.066612 2.405164 2.588016 +0.198563 0.288867 0.478054 0.658477 0.851841 1.027105 1.539739 2.021106 2.579462 2.784184 +0.304271 0.371642 0.661590 1.068976 1.224249 1.411927 1.680524 1.869770 2.100073 2.308554 +0.188223 0.257939 0.432402 0.735050 1.318038 1.485528 1.828110 2.046435 2.307018 2.457237 +0.246723 0.297276 0.604475 1.310901 1.570442 1.688851 1.913658 2.051334 2.556011 2.714965 +0.158309 0.234509 0.435792 0.667900 0.957567 1.235918 1.592945 1.818158 2.307389 2.768973 +0.419843 0.501412 0.766892 1.073173 1.189374 1.480225 1.766597 1.922151 2.537937 2.694771 +0.275140 0.335563 0.678421 1.081521 1.592379 1.772635 1.931245 2.140699 2.333804 2.490857 +0.372056 0.856814 1.239538 1.409989 1.690297 1.863018 2.072702 2.273547 2.532657 2.690517 +0.321254 0.422981 0.604856 0.793437 0.912112 1.128454 1.795979 2.173232 2.360146 2.536137 +0.395214 0.598779 0.771997 0.946713 1.213777 1.330433 1.660335 1.977154 2.165056 2.344018 +0.225286 0.317828 0.464801 1.112329 1.369512 1.511999 1.921954 2.053407 2.593519 2.777285 +0.330612 0.407807 0.730129 1.259731 1.459811 1.605671 1.981307 2.137009 2.465971 2.679722 +0.213145 0.305305 0.507016 0.662299 1.056848 1.479862 1.671904 2.102707 2.369871 2.581994 +0.219658 0.296096 0.443507 0.610973 0.799691 1.676579 1.965487 2.153235 2.502228 2.692999 +0.174947 0.257739 0.373547 0.552567 1.405316 1.614249 1.848917 2.117795 2.317884 2.711904 +0.209667 0.297529 0.756195 1.095304 1.564196 1.844775 2.103697 2.292657 2.520051 2.679489 +0.170138 0.240310 0.452247 0.684414 0.880102 1.366921 1.741648 2.131295 2.505730 2.732611 +0.278164 0.468635 0.707518 0.853693 1.054780 1.210458 1.540941 2.174562 2.410662 2.612138 +0.155738 0.238890 0.352836 0.621012 1.441438 1.619698 1.825165 1.975331 2.525373 2.748574 +0.223776 0.274424 0.479048 0.797871 1.694190 1.878135 2.135285 2.373726 2.595422 2.729787 +0.151088 0.198286 0.326558 0.536276 0.845893 1.141653 1.460565 1.762868 2.025851 2.177303 +0.434445 0.614208 0.887657 1.028446 1.191359 1.392204 1.786886 2.062481 2.423405 2.619356 +0.180755 0.275311 0.397787 0.859366 1.409762 1.523325 1.908846 2.082319 2.389720 2.743887 +0.275975 0.508416 0.889894 1.318925 1.633314 1.904728 2.169012 2.374655 2.726973 2.847666 +0.156239 0.262624 0.406657 0.739074 1.044495 1.201234 1.810887 2.005600 2.581700 2.804889 +0.195391 0.258771 0.654924 0.824371 1.315259 1.500728 1.765938 2.063992 2.341176 2.513659 +0.178034 0.301047 0.463020 0.716172 1.198868 1.340454 1.834558 2.022132 2.400750 2.776294 +0.340368 0.404236 0.843747 1.039238 1.202107 1.708051 1.914952 2.169509 2.521521 2.623348 +0.218465 0.289694 0.528045 0.817051 1.132337 1.580464 1.838891 1.983392 2.147493 2.348131 +0.322509 0.458058 0.654679 0.958976 1.118211 1.321565 1.901390 2.046409 2.360931 2.664215 +0.191821 0.252321 0.389176 0.581111 1.529667 1.931689 2.083614 2.270465 2.566855 2.713879 +0.493961 0.710827 0.982260 1.196274 1.419327 1.620910 1.928015 2.145652 2.429769 2.601973 +0.213148 0.311589 0.424636 0.602664 0.736895 1.022165 1.992278 2.218533 2.611628 2.850324 +0.288129 0.434441 0.629313 0.856153 1.289667 1.424520 1.875795 2.150240 2.351814 2.536843 +0.160031 0.230716 0.406654 0.870424 1.156517 1.392317 1.804098 1.951437 2.210479 2.735164 +0.229340 0.293962 0.503222 1.242097 1.475824 1.624647 1.998680 2.144499 2.578549 2.753270 +0.158770 0.220035 0.363386 0.577761 0.963090 1.174939 1.738169 1.979202 2.162436 2.661916 +0.346062 0.444816 0.716985 1.180717 1.370580 1.522996 1.892173 2.066682 2.395796 2.627659 +0.307495 0.389330 0.612607 0.969283 1.557708 1.839939 1.996737 2.172382 2.420627 2.539195 +0.437804 0.726957 1.291168 1.503297 1.765428 1.962121 2.163647 2.336227 2.579616 2.708524 +0.232184 0.333678 0.528368 0.706749 1.203280 1.379018 1.611161 2.154678 2.592903 2.750319 +0.272652 0.461710 0.625777 0.839609 1.342021 1.496726 1.715376 2.137572 2.370040 2.597390 +0.184908 0.302324 0.454883 0.880307 1.104383 1.292526 1.777203 1.943364 2.444174 2.622726 +0.265644 0.341261 0.553228 1.139475 1.427148 1.560441 1.933941 2.084129 2.393307 2.654135 +0.167920 0.207301 0.370331 0.525538 1.030891 1.368163 1.782474 2.062404 2.332762 2.526299 +0.343172 0.433912 0.717501 0.889734 1.052060 1.695278 2.053156 2.208456 2.608869 2.718320 +0.216527 0.305247 0.445890 0.729271 1.639736 1.903284 2.053351 2.221254 2.432253 2.568018 +0.110545 0.209955 0.844788 1.174205 1.492201 1.810243 2.177274 2.440496 2.697294 2.835232 +0.217384 0.337412 0.488999 0.761842 0.879715 1.209528 1.970747 2.120795 2.611654 2.791762 +0.190459 0.296484 0.469967 0.800649 1.105561 1.278527 1.516938 1.693066 2.114420 2.716739 +0.134814 0.175978 0.300425 0.496817 1.244295 1.485308 1.861721 2.131233 2.485046 2.773884 +0.210174 0.278266 0.435508 0.927538 1.606908 1.753898 1.957554 2.166283 2.398518 2.749609 +0.213766 0.315300 0.509924 0.709930 0.964724 1.106776 1.382615 2.001070 2.323214 2.565314 +0.400615 0.524954 0.798552 1.012852 1.135488 1.474850 1.989029 2.130909 2.507971 2.679460 +0.249400 0.377023 0.519635 0.754227 1.459559 1.642762 1.828961 2.077882 2.298228 2.467534 +0.473365 0.683973 1.052341 1.375830 1.548106 1.747589 2.139299 2.318768 2.609977 2.739255 +0.203877 0.341791 0.485180 0.884069 1.097592 1.269532 1.479924 1.757879 2.648399 2.822387 +0.273046 0.404254 0.555403 0.954547 1.291233 1.399022 1.722890 1.903441 2.171984 2.645312 +0.040369 0.117266 0.617136 0.892043 1.260331 1.541653 1.859383 2.153096 2.498232 2.761886 +0.132414 0.211358 0.742445 1.066857 1.331084 1.570793 1.867458 2.132535 2.479624 2.731076 +0.237329 0.326529 0.612538 0.790663 0.990133 1.413736 1.738235 1.936914 2.167728 2.451626 +0.273960 0.405794 0.572530 0.933672 1.057816 1.397952 1.856531 1.997548 2.599486 2.760042 +0.199334 0.298380 0.442931 0.628638 1.303213 1.640138 1.804023 2.113020 2.375455 2.548946 +0.350188 0.502010 0.821298 1.038639 1.369294 1.592404 1.910815 2.156486 2.460508 2.653260 +0.281558 0.399892 0.573105 0.753299 0.900613 1.054574 1.581987 2.178437 2.430354 2.616044 +0.344653 0.543532 0.703715 0.862285 1.198215 1.338208 1.579080 2.060769 2.306749 2.485749 +0.220701 0.326795 0.520618 0.755133 1.295552 1.451886 1.690502 2.200045 2.414271 2.615909 +0.279478 0.332193 0.801527 1.345966 1.487477 1.678499 1.922202 2.100025 2.585571 2.713387 +0.163502 0.212169 0.365096 0.525464 0.869846 1.208807 1.793988 2.040314 2.297180 2.469797 +0.285531 0.341488 0.754059 1.170016 1.300835 1.513696 1.699861 1.889918 2.581459 2.706874 +0.249595 0.366997 0.626427 0.945219 1.407043 1.560558 1.831657 2.231149 2.466354 2.654518 +0.271671 0.443136 1.156412 1.406456 1.676521 1.856481 2.063218 2.230498 2.475840 2.639575 +0.286620 0.427806 0.637320 0.803409 0.996161 1.266383 1.681751 2.003968 2.394651 2.588547 +0.314906 0.440519 0.612129 0.896126 1.472415 1.717693 1.881351 2.099437 2.369166 2.495466 +0.170277 0.251270 0.405477 0.915641 1.126887 1.436630 1.714771 1.893198 2.552995 2.738519 +0.279410 0.337137 0.734563 1.281046 1.480602 1.611880 1.853215 1.994883 2.416054 2.654827 +0.165776 0.226083 0.417544 0.744574 1.044468 1.534891 1.808494 1.944946 2.138491 2.601790 +0.264579 0.336652 0.542033 0.710190 0.913338 1.655751 1.817762 2.231956 2.524436 2.658519 +0.158194 0.235588 0.338347 0.541657 1.583377 1.766293 2.009135 2.243336 2.503941 2.775158 +0.332612 0.509620 0.822935 1.075876 1.454286 1.650788 1.974450 2.251279 2.537342 2.745115 +0.262817 0.359709 0.520893 0.707667 0.818364 1.438849 1.971249 2.087666 2.497014 2.646442 +0.233200 0.399599 0.612456 0.775547 1.199192 1.355765 1.646901 2.136245 2.342490 2.695742 +0.149687 0.238538 0.372248 0.634520 1.255813 1.433790 1.770041 1.928752 2.611905 2.824930 +0.137016 0.210297 0.591489 1.125451 1.375648 1.685296 2.089612 2.390888 2.704458 2.844434 +0.213490 0.341024 0.541716 0.750061 1.088199 1.244576 1.555338 1.965568 2.187900 2.383714 +0.300159 0.489291 0.825022 1.037100 1.194088 1.347375 1.684747 2.024936 2.465611 2.740973 +0.170029 0.255033 0.392758 0.727117 1.382065 1.579676 1.800912 1.959072 2.282335 2.728796 +0.175883 0.365509 1.112175 1.385866 1.720391 1.977810 2.245295 2.421614 2.629567 2.754004 +0.162590 0.248164 0.454630 0.763209 0.966031 1.282338 1.730743 1.938052 2.479376 2.667563 +0.258043 0.345866 0.556520 0.981312 1.361528 1.482377 1.872244 2.158226 2.362269 2.555030 +0.234139 0.348843 0.528234 0.987884 1.195217 1.422145 1.960028 2.127365 2.603321 2.793004 +0.179699 0.559209 0.867682 1.088835 1.316888 1.571498 1.922198 2.197391 2.501118 2.728679 +0.216784 0.310791 0.487492 0.932903 1.201954 1.366554 1.800398 1.977499 2.174265 2.537065 +0.186878 0.400655 0.580952 0.846287 1.103872 1.266778 1.842772 2.019592 2.488005 2.717222 +0.164641 0.248712 0.389358 0.772822 1.212561 1.369916 2.025869 2.277615 2.617524 2.809527 +0.351899 0.520326 0.926597 1.219651 1.509839 1.676837 1.921744 2.111253 2.356380 2.545934 +0.242182 0.365285 0.506156 0.716020 0.865221 1.011688 1.786917 2.122981 2.350877 2.767729 +0.413776 0.559566 0.735800 0.928997 1.079117 1.267179 1.880069 2.152492 2.324834 2.539856 +0.210597 0.329568 0.469735 0.788590 1.215495 1.319810 1.711456 2.058991 2.245438 2.653727 +0.197937 0.254148 0.477985 1.227090 1.629920 1.767432 2.186975 2.385104 2.594869 2.725544 +0.205489 0.333855 0.523915 0.706275 1.102152 1.246608 1.648901 2.026835 2.281695 2.759313 +0.230328 0.322431 0.861834 1.145614 1.347211 1.576111 1.807275 2.004824 2.354365 2.572251 +0.224898 0.282022 0.506636 1.152298 1.626560 1.752095 2.028178 2.218821 2.488955 2.670460 +0.313732 0.625469 1.164472 1.499077 1.749612 2.018528 2.262230 2.429601 2.692165 2.822502 +0.375623 0.575307 0.791200 0.935770 1.096937 1.343393 1.807992 2.187306 2.519720 2.694803 +0.236981 0.332412 0.479270 0.844461 1.347641 1.490733 1.683942 2.039143 2.297619 2.458431 +0.129047 0.206250 0.636751 0.865101 1.136893 1.356610 1.704798 1.916685 2.518358 2.756320 +0.195171 0.266517 0.414793 1.239561 1.452906 1.608357 1.833045 2.047802 2.473522 2.621994 +0.165853 0.212720 0.372757 0.536136 1.013938 1.339627 1.555122 1.945745 2.236281 2.440949 +0.256981 0.368868 0.635878 0.802543 1.084757 1.439120 1.814729 2.120519 2.458154 2.621456 +0.214382 0.297135 0.445091 0.702050 1.365102 1.851262 2.067026 2.207298 2.470728 2.612432 +0.340710 0.532103 0.935278 1.171022 1.377886 1.638598 1.965274 2.246164 2.631266 2.806341 +0.310524 0.412051 0.582478 0.768755 0.871594 1.119854 1.926346 2.207508 2.407091 2.636633 +0.249349 0.443517 0.631532 0.810096 1.205129 1.357206 1.607396 1.984157 2.208016 2.645111 +0.143090 0.185312 0.325214 0.504000 1.134467 1.327913 1.673654 2.006903 2.389284 2.746094 +0.226575 0.298946 0.453938 0.998061 1.394600 1.597283 2.064183 2.223246 2.425469 2.569458 +0.183924 0.255181 0.415834 0.624247 1.042338 1.203077 1.555240 2.125309 2.400352 2.661916 +0.275610 0.365968 0.654909 0.990108 1.170799 1.455333 2.077561 2.252672 2.502315 2.685945 +0.204334 0.287844 0.394810 0.761295 1.501200 1.784709 1.935569 2.152830 2.349263 2.545639 +0.342976 0.527539 0.917466 1.160585 1.499531 1.761830 2.095272 2.301872 2.540570 2.694692 +0.202374 0.333367 0.480179 0.708677 0.819505 1.105285 1.806641 1.953348 2.610844 2.797497 +0.307033 0.368471 0.602486 1.108611 1.413347 1.528636 1.798519 1.986138 2.169052 2.437256 +0.144073 0.196932 0.386988 0.819061 1.289767 1.625073 1.901924 2.136105 2.483019 2.707970 +0.176760 0.268627 0.662082 1.056866 1.547973 1.711386 1.972939 2.249909 2.544471 2.761094 +0.191409 0.292985 0.492193 0.800526 1.041836 1.278546 1.836626 2.028677 2.249387 2.627785 +0.324102 0.399146 0.687435 0.868704 1.022957 1.582084 1.853847 1.981885 2.554914 2.677057 +0.229172 0.302836 0.481418 0.704363 0.967567 1.828269 2.097295 2.258467 2.549112 2.704652 +0.467124 0.696788 0.939500 1.094987 1.277543 1.488496 1.896279 2.158470 2.474182 2.659994 +0.175418 0.234039 0.367674 0.513586 0.747619 1.008405 1.583161 2.053114 2.363292 2.681153 +0.410273 0.561949 0.736215 0.956685 1.135688 1.288424 1.750612 1.937714 2.151318 2.489336 +0.204541 0.277613 0.529607 0.722971 1.199975 1.447336 1.715634 1.921054 2.357781 2.507488 +0.253116 0.311907 0.696982 1.320082 1.575418 1.705324 2.005068 2.168666 2.461879 2.665053 +0.163657 0.237902 0.393374 0.609490 0.854272 1.089980 1.526387 1.842337 2.126252 2.679051 +0.448627 0.530664 0.812719 1.095201 1.207641 1.575411 1.884209 2.034297 2.553007 2.688355 +0.262717 0.338748 0.512685 1.003543 1.480178 1.622083 1.828518 2.142415 2.356457 2.511530 +0.417111 0.636688 1.036571 1.319877 1.679924 1.873389 2.073722 2.249396 2.507732 2.651054 +0.263698 0.461151 0.618737 0.830471 1.004041 1.158874 1.801566 2.020222 2.306558 2.743041 +0.387779 0.575108 0.729791 0.932981 1.361163 1.505161 1.751183 2.068466 2.338260 2.487637 +0.181510 0.265666 0.454631 1.082382 1.287303 1.579202 1.851178 2.096963 2.467237 2.646930 +0.277668 0.345119 0.602341 1.179200 1.378990 1.545625 1.813861 1.962590 2.491799 2.664453 +0.179320 0.248080 0.456925 0.722589 1.126932 1.579450 1.799397 1.950668 2.484125 2.707238 +0.314322 0.381145 0.608651 0.727613 0.890472 1.610280 2.136172 2.258358 2.596376 2.709780 +0.189539 0.266068 0.419729 0.651693 1.410161 1.643106 1.854810 2.275582 2.492054 2.722009 +0.254466 0.313038 0.594149 1.012536 1.688813 1.935465 2.119184 2.287869 2.535543 2.667926 +0.134691 0.171906 0.302740 0.492936 0.899551 1.229188 1.733940 2.012878 2.446339 2.742762 +0.231556 0.365068 0.680761 0.889142 1.111338 1.295904 1.542636 1.971784 2.427562 2.631912 +0.222525 0.305606 0.527193 0.687519 1.181381 1.671764 1.863683 2.072023 2.634517 2.779272 +0.178770 0.237415 0.375160 0.856692 1.673680 1.813743 2.016791 2.272421 2.522601 2.735959 +0.193532 0.268731 0.451328 0.753471 0.984854 1.285349 1.685647 1.884123 2.091677 2.243418 +0.476037 0.651610 0.801054 1.010162 1.241374 1.355840 1.775976 2.086152 2.272907 2.454351 +0.211657 0.308331 0.421366 0.865966 1.418774 1.556743 1.786149 2.020332 2.198585 2.631981 +0.203789 0.490794 1.010137 1.275006 1.472213 1.810140 2.170639 2.437660 2.662122 2.788061 +0.174355 0.252095 0.674715 0.842194 1.055087 1.278000 1.698680 2.070561 2.399385 2.657430 +0.245109 0.324049 0.628822 0.927910 1.123601 1.580066 1.878640 2.054601 2.358721 2.546838 +0.182644 0.253804 0.386248 0.614056 1.364821 1.545877 2.040174 2.218827 2.419010 2.624609 +0.295605 0.367794 0.690701 1.055162 1.186600 1.644453 1.944154 2.101444 2.562120 2.691268 +0.220878 0.289573 0.640307 0.822072 1.144055 1.567797 1.766410 1.908109 2.103459 2.560489 +0.403453 0.526298 0.732204 0.901150 1.035869 1.339383 1.783990 1.941961 2.371032 2.626653 +0.212825 0.258570 0.471588 0.685549 1.263740 1.821051 2.163822 2.288398 2.628063 2.788155 +0.401181 0.642053 1.032473 1.236110 1.444450 1.686678 2.006722 2.228515 2.572112 2.723964 +0.239433 0.341091 0.492629 0.707630 0.881426 1.030816 1.719255 2.344056 2.579063 2.756942 +0.294093 0.382770 0.577412 1.009281 1.313036 1.419303 1.744673 2.094230 2.289039 2.475843 +0.169805 0.236922 0.403314 0.638995 1.176446 1.352145 1.665573 1.909756 2.150120 2.716243 +0.210447 0.277913 0.452474 1.402686 1.513430 1.720944 1.903938 2.278499 2.583756 2.743179 +0.159574 0.225382 0.374008 0.714137 1.011253 1.371713 1.699162 1.871587 2.027056 2.491194 +0.258602 0.557253 0.819720 1.038856 1.301470 1.445358 1.830613 2.098171 2.320809 2.541075 +0.232756 0.282242 0.631974 0.898694 1.537444 1.869217 2.063967 2.234463 2.498226 2.633517 +0.580133 0.997946 1.320956 1.481874 1.731605 1.898579 2.120712 2.290128 2.530088 2.651657 +0.211840 0.307093 0.453360 0.945579 1.250815 1.490290 1.724135 2.281097 2.562699 2.752602 +0.314276 0.493555 0.667782 0.896500 1.323006 1.482618 1.667487 1.974415 2.427345 2.555679 +0.182455 0.261592 0.418011 1.050927 1.261387 1.443370 1.665467 1.939030 2.444695 2.638451 +0.241570 0.306934 0.491293 1.105950 1.554827 1.666520 1.923917 2.087652 2.367600 2.654889 +0.190084 0.254850 0.454062 0.724519 1.083362 1.393887 1.892335 2.088856 2.321764 2.484299 +0.306497 0.389831 0.721793 0.839714 1.124754 1.652401 1.822919 2.273310 2.569195 2.669599 +0.186200 0.273460 0.383201 0.564758 1.511073 1.845018 1.998284 2.194096 2.388693 2.587923 +0.300722 0.478218 0.823364 1.127490 1.591141 1.871349 2.174720 2.403181 2.624785 2.782405 +0.228884 0.358342 0.504622 0.795874 1.005622 1.152613 1.908053 2.124794 2.372473 2.797584 +0.171885 0.248234 0.432842 0.833143 1.040892 1.269289 1.661635 1.918629 2.158962 2.653403 +0.140943 0.193684 0.343025 0.562303 1.069552 1.543330 1.824473 1.961637 2.463513 2.770537 +0.173053 0.245656 0.360656 0.960618 1.589535 1.689906 1.984141 2.142998 2.588389 2.759403 +0.240180 0.429951 0.637440 0.786596 1.069147 1.226573 1.470883 1.952052 2.195064 2.615973 +0.367862 0.471897 0.730834 1.082320 1.226293 1.462927 1.928169 2.052466 2.406737 2.662458 +0.247175 0.358209 0.535946 0.781876 1.363697 1.635239 1.807233 1.993776 2.452769 2.601039 +0.445578 0.687898 1.114108 1.301027 1.577397 1.886042 2.224903 2.436534 2.659695 2.761031 +0.214389 0.336025 0.487794 0.759534 0.970518 1.141100 1.457335 1.624644 2.306922 2.715265 +0.377300 0.466775 0.716121 1.083781 1.256543 1.411238 1.789433 1.936372 2.205572 2.562355 +0.148362 0.214593 0.545023 0.840437 1.193325 1.480659 1.791868 2.083419 2.410537 2.676129 +0.150403 0.278398 0.792676 0.976680 1.218845 1.405245 1.775056 2.162458 2.547861 2.746383 +0.236301 0.328633 0.630867 0.839915 1.042349 1.298870 1.627752 1.839491 2.298928 2.493962 +0.337889 0.497920 0.711277 0.850420 0.992027 1.246884 1.710746 2.086682 2.527158 2.707162 +0.172215 0.236540 0.372897 0.525146 1.182577 1.735727 1.927035 2.114619 2.319170 2.542782 +0.415304 0.624807 0.906616 1.117841 1.446155 1.669417 1.948413 2.172815 2.504530 2.670754 +0.265417 0.407241 0.613894 0.816534 0.980063 1.156061 1.756747 2.274851 2.497193 2.712242 +0.276440 0.468209 0.649518 0.816686 1.195171 1.355517 1.549226 1.935272 2.217871 2.426979 +0.188925 0.277012 0.412665 0.672627 1.354807 1.514523 1.699988 2.144554 2.382186 2.586077 +0.242630 0.352485 0.912974 1.343781 1.604428 1.801867 2.014791 2.193072 2.460809 2.631999 +0.190903 0.285841 0.449070 0.760328 0.954285 1.182936 1.692638 1.878163 2.276840 2.465963 +0.220659 0.300374 0.721694 0.947306 1.298330 1.562980 1.760618 1.888247 2.506445 2.689675 +0.213168 0.290928 0.695227 0.918179 1.378186 1.631987 1.847886 2.003072 2.358358 2.619347 +0.328586 0.517244 0.937320 1.376238 1.574840 1.764347 2.058630 2.224334 2.584444 2.756653 +0.248486 0.367007 0.562147 0.750632 0.902785 1.147563 1.637415 1.912062 2.413993 2.605696 +0.310691 0.477895 0.670796 0.940507 1.418293 1.563497 1.805141 2.114076 2.376358 2.535155 +0.256555 0.414210 0.559427 0.981289 1.191646 1.378307 1.678398 1.849306 2.576704 2.756630 +0.291424 0.335003 0.750149 1.289655 1.437209 1.599989 1.803177 1.967415 2.601748 2.733761 +0.195254 0.279513 0.451755 0.649111 0.828694 1.609509 1.914906 2.091219 2.319589 2.534899 +0.222304 0.332624 0.475678 0.685205 1.030332 1.737223 1.920979 2.378290 2.706719 2.817726 +0.164833 0.240093 0.359862 0.801929 1.513677 1.641713 2.040524 2.248843 2.488659 2.714025 +0.214777 0.287322 0.572644 1.145070 1.367112 1.752687 2.042424 2.222067 2.543047 2.697885 +0.226099 0.330382 0.474439 0.687757 0.799187 1.319837 1.944566 2.078099 2.367800 2.508460 +0.244540 0.392163 0.553692 0.729765 1.247865 1.448376 1.617590 2.074636 2.340052 2.518064 +0.175381 0.314231 0.446023 0.797404 1.328458 1.439727 1.793346 1.939571 2.468800 2.721651 +0.205808 0.293670 0.452447 1.074268 1.288235 1.655635 1.857504 2.364687 2.639812 2.798144 +0.253926 0.392653 0.587584 0.800134 0.976310 1.185587 1.570687 1.821414 2.090893 2.349021 +0.322461 0.410912 0.723569 1.060644 1.201524 1.400360 1.579189 1.788759 2.460242 2.616602 +0.211266 0.304981 0.436011 0.771978 1.490623 1.677748 1.886227 2.113497 2.326353 2.727265 +0.235012 0.406911 0.864785 1.291485 1.708295 1.938554 2.179896 2.352404 2.563792 2.711446 +0.176814 0.268620 0.445837 0.823113 1.029776 1.271571 1.623388 1.811215 2.402140 2.614165 +0.241865 0.339268 0.507509 1.003677 1.204347 1.372561 1.940795 2.101371 2.385606 2.669975 +0.230878 0.334743 0.500370 0.879929 1.021894 1.533770 1.970789 2.128971 2.567262 2.717288 +0.297505 0.451574 0.748848 0.988527 1.366237 1.606668 1.894660 2.174481 2.521427 2.759168 +0.199265 0.271145 0.498160 0.854679 1.172103 1.364148 1.762079 1.969095 2.173538 2.311630 +0.222173 0.424864 0.564942 0.829809 1.038172 1.194055 1.720601 1.858086 2.431760 2.741461 +0.181961 0.226819 0.390513 0.556339 1.056596 1.553065 2.128349 2.258018 2.602497 2.802121 +0.357600 0.565047 1.153012 1.350312 1.533576 1.718542 1.957892 2.175347 2.505650 2.678495 +0.162257 0.236808 0.374039 0.570569 0.748034 1.172262 1.823392 2.053032 2.513769 2.772072 +0.305794 0.465870 0.645121 0.882650 1.141294 1.266856 1.701581 2.002881 2.184124 2.411254 +0.231652 0.380738 0.549642 0.837410 1.225266 1.332971 1.851582 2.119371 2.315077 2.732108 +0.235449 0.286771 0.684809 1.346663 1.526630 1.703476 2.101486 2.254546 2.577181 2.718994 +0.233870 0.446515 0.605080 0.814654 1.054963 1.178801 1.633158 1.849743 2.139379 2.732772 +0.271706 0.335152 0.857227 1.253741 1.387189 1.702170 1.896767 2.191114 2.479999 2.601359 +0.237386 0.314549 0.438339 0.912164 1.577764 1.877791 2.032790 2.197037 2.412322 2.536484 +0.361168 0.574093 1.023843 1.468517 1.690562 1.917374 2.187368 2.334035 2.669095 2.806291 +0.278480 0.398742 0.573342 0.839212 1.073888 1.222093 1.691681 2.165258 2.377410 2.536882 +0.286018 0.447947 0.615060 0.849446 1.319465 1.463583 1.769948 2.001035 2.189431 2.450384 +0.219440 0.301601 0.668534 0.861094 1.210001 1.498673 1.745120 1.877765 2.314377 2.619597 +0.223591 0.352153 0.598841 1.217893 1.359082 1.591744 1.771089 2.213856 2.561538 2.735416 +0.176857 0.236601 0.395107 0.634632 1.133495 1.335116 1.770374 1.981313 2.206556 2.339716 +0.334735 0.402265 0.659168 0.781639 0.975228 1.664999 1.872069 2.047533 2.476961 2.573979 +0.215968 0.284755 0.524241 0.781460 1.334811 1.772379 1.953878 2.194209 2.578250 2.741939 +0.298193 0.489879 0.812985 1.183691 1.496418 1.679975 2.108792 2.316557 2.673779 2.851610 +0.312989 0.415446 0.618011 0.899096 1.083683 1.263384 1.887396 2.243064 2.419448 2.570481 +0.244471 0.431115 0.601512 0.813139 1.102163 1.221061 1.692440 2.033163 2.221795 2.619838 +0.150949 0.219060 0.349217 0.611327 1.077112 1.250547 1.915518 2.083980 2.449999 2.792543 +0.161611 0.218964 0.445377 0.927863 1.451151 1.768464 2.130012 2.366724 2.666003 2.814049 +0.196000 0.297256 0.497266 0.691900 1.089877 1.273685 1.513723 2.006472 2.273782 2.572221 +0.335268 0.460795 0.685187 0.867664 1.013807 1.479554 2.011994 2.168476 2.572643 2.717564 +0.257604 0.340872 0.499757 0.843052 1.396548 1.831688 2.034226 2.170332 2.422618 2.540496 +0.417663 0.631718 0.955424 1.197319 1.659797 1.879883 2.168797 2.359053 2.578087 2.698249 +0.162052 0.251583 0.439900 0.660911 0.903902 1.320296 1.624758 1.778577 2.530531 2.799705 +0.256861 0.322803 0.685370 1.086437 1.263276 1.569879 1.851654 2.014946 2.264711 2.447006 +0.125192 0.176171 0.336135 0.781600 1.200220 1.439966 1.805419 2.077525 2.462470 2.738186 +0.102286 0.191322 0.774556 1.076151 1.369456 1.627146 1.973015 2.236001 2.609367 2.812985 +0.173442 0.232622 0.491622 0.844157 1.095241 1.370797 1.696966 2.051411 2.316061 2.502053 +0.257531 0.343598 0.654071 0.838985 1.048102 1.487473 1.725385 1.897417 2.430505 2.585998 +0.197900 0.276312 0.440283 0.705103 1.267341 1.740297 1.934483 2.154007 2.400200 2.624136 +0.409590 0.596785 0.983751 1.181770 1.371153 1.502380 1.758280 2.018571 2.380053 2.592151 +0.231819 0.332890 0.483514 0.644585 0.816808 0.926308 1.403298 2.233007 2.467857 2.678461 +0.258610 0.340064 0.670485 0.908467 1.107611 1.456243 1.759580 1.932179 2.113118 2.310135 +0.184377 0.249203 0.410806 0.587907 1.302501 1.510319 1.724432 1.981890 2.282904 2.422125 +0.254110 0.313328 0.659859 1.265819 1.412949 1.665930 1.927154 2.101984 2.551446 2.673030 +0.161592 0.237480 0.376535 0.637094 0.823028 1.137613 1.696425 1.875770 2.403632 2.639617 +0.384501 0.466812 0.740791 0.938093 1.062352 1.509284 1.749143 1.917797 2.548157 2.671506 +0.333872 0.419367 0.638994 1.092624 1.520550 1.649447 1.866619 2.148941 2.346723 2.506140 +0.426216 0.686997 1.235881 1.428854 1.611591 1.792860 2.017593 2.233715 2.547773 2.696609 +0.262949 0.367509 0.530429 0.741867 0.872474 1.069602 1.745566 2.061187 2.283843 2.494178 +0.335782 0.547236 0.716211 0.919077 1.275686 1.408437 1.685118 1.967394 2.217639 2.446679 +0.227629 0.330991 0.486068 1.117571 1.304983 1.510130 1.757258 1.946972 2.625557 2.782597 +0.359850 0.436633 0.750634 1.201513 1.337571 1.594835 1.970273 2.113840 2.573808 2.729963 +0.211871 0.304028 0.512758 0.663762 1.086354 1.633335 1.818017 2.129577 2.391080 2.600766 +0.196092 0.279726 0.434488 0.624802 0.772358 1.404377 1.948777 2.160918 2.629996 2.775175 +0.176304 0.262521 0.373719 0.581101 1.520108 1.736172 1.933230 2.140172 2.358130 2.753524 +0.254932 0.381411 0.806187 1.102292 1.534523 1.750280 1.970904 2.159871 2.455922 2.658405 +0.190385 0.288656 0.449066 0.678174 0.812376 1.449326 1.728657 1.966320 2.638812 2.789546 +0.251178 0.386509 0.609363 0.797102 1.024159 1.181726 1.454661 2.012630 2.493092 2.698933 +0.166654 0.266226 0.385171 0.711990 1.397897 1.532347 1.915974 2.088003 2.565270 2.789532 +0.238453 0.306036 0.449309 0.876277 1.521437 1.933982 2.134420 2.267986 2.537601 2.658253 +0.161634 0.219919 0.353206 0.524346 0.961806 1.207713 1.687918 1.916939 2.161870 2.320657 +0.413612 0.597095 0.793763 0.986290 1.281786 1.412660 1.652465 2.016091 2.384164 2.528578 +0.228655 0.341562 0.480989 0.988605 1.371003 1.477423 1.861026 2.015852 2.339752 2.773153 +0.259092 0.597012 0.985224 1.321740 1.643354 1.957367 2.288682 2.497474 2.716492 2.844467 +0.185652 0.304664 0.446232 0.864434 1.091795 1.273770 1.942575 2.095543 2.524648 2.768245 +0.176687 0.256678 0.745652 0.934909 1.283760 1.440062 1.765242 2.122092 2.388099 2.590551 +0.189805 0.275637 0.440995 0.821356 1.256020 1.410985 1.929781 2.120144 2.396030 2.604643 +0.266823 0.337688 0.819408 1.134754 1.289204 1.777028 1.982886 2.221748 2.590286 2.698098 +0.205348 0.276512 0.527305 0.727412 1.024647 1.653979 1.904178 2.046613 2.217922 2.455661 +0.293498 0.424494 0.613795 0.956130 1.133981 1.324804 1.809031 1.953922 2.293854 2.575884 +0.183120 0.249650 0.376204 0.543914 1.350827 1.907220 2.092551 2.255705 2.514391 2.687901 +0.541205 0.789796 1.058955 1.269415 1.503899 1.702191 1.970176 2.175444 2.496810 2.652238 +0.229326 0.339475 0.451881 0.661210 0.795832 1.073796 2.027104 2.206371 2.478903 2.726784 +0.330006 0.506868 0.673076 0.887406 1.228765 1.349226 1.781290 2.086583 2.277762 2.480029 +0.138389 0.200001 0.396259 0.811975 1.090712 1.460413 1.745493 1.904269 2.348250 2.699886 +0.176584 0.242161 0.378270 1.177848 1.564718 1.678166 1.951618 2.121413 2.580109 2.737132 +0.145852 0.198423 0.335644 0.550505 1.019727 1.371188 1.797635 1.943825 2.207490 2.746470 +0.385078 0.503696 0.703239 1.069987 1.365736 1.472054 1.825827 2.159636 2.371283 2.520972 +0.284950 0.388050 0.507352 0.879125 1.523530 1.776238 1.929597 2.157558 2.447986 2.586398 +0.491116 0.756155 1.255200 1.522460 1.776579 2.028121 2.286059 2.429774 2.679106 2.776164 +0.252477 0.396081 0.713022 0.861502 1.152223 1.370802 1.614010 2.144798 2.574072 2.712530 +0.282756 0.438437 0.613566 0.847746 1.260772 1.379059 1.642202 2.137540 2.368369 2.522163 +0.203971 0.322195 0.479842 0.953133 1.211278 1.397635 1.800812 1.954516 2.403478 2.573713 +0.264533 0.358424 0.628768 1.111242 1.340246 1.506485 1.999590 2.194109 2.461411 2.667361 +0.177730 0.223680 0.394553 0.556177 0.947415 1.500640 1.733528 1.926046 2.261466 2.436054 +0.314223 0.363636 0.727886 0.851880 1.053844 1.798132 1.974354 2.182595 2.537995 2.629683 +0.201778 0.275500 0.404891 0.747466 1.500050 1.841184 1.998843 2.226807 2.481989 2.669506 +0.132164 0.314955 0.821473 1.196038 1.426590 1.699934 2.036856 2.323497 2.685471 2.828965 +0.223374 0.347335 0.507730 0.773547 0.967916 1.134129 1.991403 2.306567 2.521364 2.788746 +0.312742 0.449784 0.583287 0.934234 1.268567 1.365063 1.569295 1.687046 2.077299 2.595022 +0.124286 0.162126 0.290730 0.654031 1.231658 1.538458 1.893070 2.184784 2.562637 2.798224 +0.177049 0.251654 0.367891 0.912504 1.557576 1.693045 1.898991 2.072136 2.350163 2.646045 +0.240517 0.378333 0.547809 0.754272 0.973321 1.103670 1.574418 2.028049 2.211127 2.562709 +0.427795 0.519003 0.771284 0.937240 1.086617 1.609879 1.878750 2.052791 2.534118 2.657149 +0.224370 0.317969 0.439666 0.812931 1.398497 1.626632 1.794178 2.114000 2.309157 2.496836 diff --git a/gr-vocoder/lib/codec2/codebook/lspjvm2.txt b/gr-vocoder/lib/codec2/codebook/lspjvm2.txt new file mode 100644 index 0000000000..2b7cabf940 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspjvm2.txt @@ -0,0 +1,513 @@ +5 512 +0.005167 -0.037310 -0.002159 0.016849 0.130396 +0.039445 0.031680 -0.074412 -0.031499 0.060536 +0.019479 -0.030564 -0.048137 -0.056279 -0.027829 +0.020585 -0.011270 0.023913 -0.005706 0.011407 +-0.023217 0.107455 -0.037777 0.004070 -0.017279 +-0.090444 0.007641 0.099001 -0.047913 -0.017199 +0.022700 -0.063865 0.047213 0.043843 -0.036225 +0.001312 -0.123861 -0.038988 0.058666 0.074541 +0.039508 0.110300 0.013954 -0.119228 -0.035807 +-0.047392 0.027035 -0.004412 -0.032650 -0.037150 +0.002491 -0.045447 0.158260 0.022828 -0.030124 +-0.047856 0.088744 -0.009678 0.106688 0.087690 +-0.027941 0.044084 -0.028500 0.018736 -0.069969 +-0.035358 -0.051568 -0.030459 -0.017899 0.027632 +-0.018607 -0.123557 0.019228 0.057485 -0.028907 +0.019057 0.038151 -0.080220 0.034222 0.023081 +0.021312 0.041905 0.112903 0.024092 0.093974 +-0.116679 0.015344 -0.066059 -0.096437 0.004041 +-0.022464 -0.116260 0.047819 -0.003921 -0.073504 +0.001975 -0.025869 0.028200 0.122690 0.010627 +-0.035672 0.078963 -0.009686 0.000743 -0.147582 +0.016932 -0.020291 -0.096896 -0.237875 -0.029121 +0.017376 -0.040130 -0.053865 0.154060 -0.013215 +0.015215 -0.019023 -0.070604 0.032265 0.040340 +0.102365 -0.022746 0.019895 0.050570 0.008845 +-0.034134 0.044441 -0.049387 -0.140481 0.072570 +0.013023 -0.006079 0.037574 0.004937 -0.081501 +0.003696 0.049908 0.007355 0.000403 0.026006 +-0.008466 0.080680 0.061382 -0.108985 -0.088060 +-0.012275 -0.081061 0.020333 -0.079001 0.068724 +-0.014081 -0.042609 0.093365 0.044120 0.000303 +0.063391 0.096574 -0.105424 0.039041 0.010412 +-0.054031 -0.084948 0.080406 -0.035883 0.137428 +0.063037 0.050562 0.024690 -0.031394 0.130320 +-0.015501 -0.078884 -0.076886 -0.013864 -0.073587 +0.048778 0.003814 -0.031125 0.046897 0.028304 +0.048692 0.132795 0.065450 0.059487 -0.042396 +-0.176999 0.056943 -0.004135 -0.049378 -0.041083 +-0.039445 -0.016292 -0.004550 0.062010 -0.079613 +-0.054566 -0.008476 -0.016710 0.049202 0.025758 +-0.078723 0.092091 0.096536 -0.065079 0.021161 +0.076657 0.009203 -0.036866 -0.016559 0.012823 +0.008225 -0.003006 0.108033 0.043120 -0.060870 +-0.019346 0.022790 -0.001728 0.062304 -0.016965 +-0.001302 -0.014490 -0.041803 -0.034058 -0.197066 +-0.033655 -0.127217 -0.108681 -0.010571 -0.004705 +-0.015553 -0.086069 0.034109 -0.101379 0.002068 +-0.004003 -0.044637 -0.068617 0.052228 -0.047812 +-0.043307 0.035681 0.042207 -0.055946 0.055944 +-0.026792 -0.012601 -0.056710 -0.021094 0.105842 +-0.025598 -0.078858 -0.013487 0.030728 -0.031956 +0.031444 0.022763 0.025364 0.121366 0.070736 +-0.084556 0.098118 -0.024301 -0.058655 -0.043194 +-0.011752 -0.043781 0.091051 -0.071201 -0.020980 +0.082904 -0.031657 -0.088247 0.066709 -0.079182 +-0.012151 0.011796 -0.010589 0.100656 0.094539 +0.035967 0.025338 0.071826 0.009741 -0.040209 +0.006866 -0.015095 -0.168469 -0.056133 0.060145 +0.045830 -0.068969 0.034551 0.015842 -0.092809 +0.054699 0.138744 0.001726 0.006927 0.005167 +0.016978 0.046384 -0.060183 -0.040742 -0.072692 +-0.022489 -0.029728 -0.065018 -0.124741 0.044927 +-0.029057 -0.037154 0.031068 0.060086 0.009984 +0.009311 -0.006957 -0.105508 0.059637 -0.019564 +-0.068154 -0.066443 0.000799 0.028579 0.097063 +0.096936 0.030230 -0.034623 -0.088918 0.040334 +0.019439 -0.050707 -0.003294 -0.028505 -0.053599 +0.062460 -0.070688 -0.016465 -0.035680 0.017378 +0.009363 0.048761 0.043374 0.039587 -0.023232 +-0.067033 0.042663 0.054070 -0.042797 -0.089391 +-0.030497 -0.050249 0.059528 0.089089 -0.029633 +0.064125 -0.086614 -0.002005 0.080620 0.000502 +-0.003490 0.097336 0.099565 0.015648 0.006691 +0.077668 0.016572 0.035404 -0.046026 0.017237 +-0.048631 0.009314 0.141479 0.017079 0.043796 +-0.106474 0.145951 0.057740 0.011250 -0.059443 +0.027572 0.026650 0.008527 0.002949 -0.037680 +-0.077991 -0.090617 0.003420 -0.046010 0.007354 +0.019056 -0.128651 0.016464 0.004584 -0.030883 +-0.092069 0.038976 -0.081840 0.066695 -0.047340 +0.003513 0.040613 0.046815 -0.023406 0.062389 +0.021759 0.024928 -0.018922 -0.048006 0.063800 +-0.014416 -0.050333 0.042628 -0.114934 -0.101450 +0.062139 0.029295 -0.065908 0.111463 0.050781 +-0.022707 0.135414 0.003548 0.134535 -0.048259 +-0.092344 -0.027727 0.016343 -0.060786 -0.081502 +-0.005412 -0.026229 -0.143331 0.052404 -0.077298 +-0.035919 -0.041968 -0.106108 -0.004369 0.065028 +0.096370 -0.053299 0.043317 -0.049735 0.049815 +0.032324 0.051309 -0.009607 -0.205917 0.005023 +-0.054316 -0.022895 0.099327 -0.006927 -0.076574 +-0.111024 0.111026 0.038381 -0.060368 0.064238 +-0.034316 0.026846 0.025740 -0.076162 -0.163904 +0.055955 -0.056885 0.014831 -0.120715 0.090938 +0.035289 -0.036439 0.060012 0.080302 0.036215 +0.065250 0.083030 -0.058784 0.104826 -0.051805 +-0.011099 -0.006420 0.053042 0.024127 0.092534 +0.058569 -0.033442 0.025186 -0.018222 0.117744 +0.044345 -0.042456 -0.043767 -0.021378 -0.121965 +0.027371 0.052731 -0.020316 0.036912 0.115357 +0.031150 0.041547 0.059267 -0.039672 -0.086918 +-0.162369 0.024801 0.031725 0.083400 -0.034463 +0.000272 -0.008147 -0.002016 0.131953 -0.092911 +-0.091944 -0.062864 -0.005221 0.063647 -0.012658 +0.042685 0.067952 0.038644 -0.153221 0.096841 +0.108299 0.089446 -0.047164 0.004196 -0.043268 +-0.035456 0.050838 0.070444 0.084465 -0.079980 +-0.048916 0.057726 0.023894 0.027653 0.017775 +0.015461 -0.030287 -0.022245 0.052081 -0.150947 +-0.002682 -0.056774 -0.123366 -0.091754 0.006536 +0.006473 -0.143025 0.054690 -0.043189 0.032970 +0.027446 0.033127 -0.132722 -0.010417 -0.080097 +-0.018187 0.001858 0.111290 -0.090749 0.059434 +-0.068738 0.090679 -0.145070 -0.065277 0.063514 +-0.003982 -0.056382 -0.003673 0.015845 -0.073396 +0.043688 0.002836 0.069211 0.124852 -0.053313 +-0.040946 0.070440 -0.107024 -0.019199 -0.033672 +-0.001440 0.021680 0.110595 -0.053452 -0.052426 +0.035461 -0.028179 -0.049041 0.022580 -0.010989 +-0.002913 -0.051691 -0.075881 0.037241 0.076377 +0.034735 -0.031556 0.073516 -0.001427 0.016296 +-0.017537 0.003346 -0.099774 -0.067624 -0.044257 +-0.018202 0.030622 0.012773 0.046475 -0.121785 +-0.057265 0.116179 -0.079916 0.066396 0.050104 +-0.013177 0.057766 -0.047879 -0.109526 -0.146491 +0.032675 -0.049318 -0.057045 -0.080068 0.089621 +-0.046564 -0.029992 0.040828 0.029281 -0.037369 +-0.009731 -0.082145 -0.117622 0.117077 0.037369 +0.000820 -0.106634 -0.007967 0.000812 0.140637 +0.036530 0.062121 -0.065504 -0.094930 0.121336 +0.017530 -0.017330 -0.040402 -0.018255 0.010992 +0.019746 -0.027564 0.033588 0.042466 -0.003143 +0.013767 0.084179 0.033753 -0.017279 -0.009676 +-0.006452 0.032645 0.031852 -0.030975 -0.043384 +-0.005433 -0.015258 0.053273 0.054748 -0.064736 +0.008959 -0.141223 -0.032957 -0.015079 0.018198 +-0.001681 0.143079 0.076000 0.001037 -0.048744 +0.022062 0.026030 -0.008263 -0.050353 -0.023037 +-0.036477 -0.051733 0.137823 -0.034438 -0.007573 +-0.004256 0.064218 0.075183 0.095106 0.026497 +0.026360 0.009791 -0.058039 0.053315 -0.077817 +-0.033283 -0.081151 -0.055220 0.004268 0.017539 +-0.007329 -0.117200 0.093220 0.037359 0.002718 +0.010749 0.018281 -0.075800 -0.024889 0.005720 +0.022129 0.035613 0.036187 0.032246 0.105439 +-0.073766 0.016887 -0.059934 -0.049471 0.073520 +-0.024041 -0.104642 0.023557 -0.059746 -0.043871 +0.022311 -0.000250 -0.074027 0.198593 0.102732 +0.024478 0.077658 -0.060042 -0.018229 -0.149648 +-0.009871 -0.105822 0.007585 -0.161459 -0.041121 +-0.021460 0.009020 -0.065018 0.111801 -0.024953 +0.074594 -0.026041 -0.062859 0.009199 0.069609 +0.078672 -0.033414 0.054128 0.005408 -0.016273 +0.052076 0.107610 -0.067518 -0.096400 0.033703 +-0.014350 -0.024676 0.056254 -0.043770 -0.060847 +-0.004185 0.073550 -0.057830 -0.016644 0.029096 +0.005755 0.026472 0.040449 -0.091950 -0.048538 +-0.034439 -0.107938 0.090712 -0.117001 0.043170 +-0.006505 -0.035277 0.117316 0.127002 0.047906 +-0.001441 0.118379 -0.132165 0.007380 0.023823 +-0.020120 -0.083725 0.047284 0.023795 0.074123 +-0.013439 0.024994 0.060254 -0.069120 0.166373 +-0.024228 -0.063150 -0.046506 -0.077202 -0.054592 +-0.006571 0.010335 -0.006568 0.003982 0.075837 +0.008643 0.136339 -0.005502 0.033910 -0.066379 +-0.127371 -0.006954 0.039770 -0.070123 0.060925 +-0.046386 -0.026420 -0.005280 0.103509 -0.022310 +-0.003740 -0.014999 -0.037770 0.080005 0.025231 +-0.054995 0.071017 0.009442 -0.075737 0.013441 +0.051947 0.027097 -0.070351 -0.055705 -0.021115 +0.021387 0.029232 0.163331 -0.032380 0.010008 +-0.011987 -0.028631 0.002665 0.014770 -0.009558 +-0.034325 0.015830 -0.091253 -0.012677 -0.107378 +-0.034624 -0.047725 -0.102330 0.042525 -0.006869 +0.014048 -0.043127 0.052384 -0.047473 0.055102 +0.009744 -0.033646 -0.081755 -0.001464 -0.016223 +-0.036697 -0.002279 0.023279 -0.036221 0.101478 +-0.058454 0.065074 0.003524 0.005010 0.097182 +-0.038171 -0.037943 -0.009994 -0.033355 -0.044552 +0.041318 0.065041 0.000092 0.100816 0.029007 +-0.031803 0.183537 -0.009617 -0.010544 -0.028465 +0.006900 -0.014988 0.090490 -0.174817 0.027464 +0.063314 -0.049281 -0.001567 0.091421 -0.078603 +-0.004869 -0.063266 -0.001922 0.069338 0.081771 +0.058737 0.073195 0.081676 -0.047808 -0.025797 +-0.004185 0.033203 -0.125472 -0.108148 0.031258 +0.035192 0.029957 0.046675 0.047238 -0.088197 +0.033315 0.114919 -0.049180 0.025707 0.053843 +0.035182 0.140206 -0.058660 -0.025978 -0.019658 +-0.014847 -0.021051 -0.034385 -0.121789 0.173406 +-0.112251 -0.022333 0.071206 0.028998 0.046468 +0.067704 -0.026159 -0.158316 0.014936 0.040216 +-0.010137 -0.053492 0.004935 -0.011277 0.073852 +0.091261 0.114794 -0.014060 -0.051545 0.077316 +0.101258 -0.046137 0.022994 -0.066767 -0.065537 +0.049952 -0.043582 0.012823 0.009313 0.036343 +0.054885 0.037796 0.021940 0.013211 0.006019 +-0.099578 0.058596 -0.045463 -0.015632 -0.087141 +-0.019273 -0.033140 0.043796 0.119057 -0.081813 +-0.021538 -0.070453 -0.052551 0.077213 0.000094 +0.050268 0.092271 0.051688 -0.025224 0.075437 +0.027983 0.069205 0.031787 -0.099975 0.004387 +-0.002747 -0.056567 0.161394 0.000164 0.084189 +-0.124844 0.050329 0.009844 0.055877 0.055701 +0.030479 0.028843 -0.001076 -0.017173 -0.102770 +-0.038426 -0.133841 -0.035840 -0.072046 0.020206 +0.016438 -0.097885 0.041857 0.034601 0.030422 +-0.089192 -0.014112 -0.052276 0.012005 -0.029335 +-0.011331 0.101833 0.063827 0.044288 0.101597 +-0.034689 -0.027434 -0.017801 -0.079224 0.067103 +-0.027456 -0.098034 0.009448 -0.038986 -0.156729 +0.085023 0.033136 -0.021343 0.110701 -0.011901 +-0.006484 0.082023 -0.027094 0.091208 -0.013163 +-0.012223 0.005933 0.010653 -0.098119 -0.005304 +-0.021061 -0.058077 -0.073035 0.097856 -0.102847 +-0.035329 -0.092754 -0.101463 -0.048671 0.055015 +0.102145 0.062017 0.016002 0.036489 0.059000 +0.042861 0.025447 -0.019735 -0.107841 -0.033752 +-0.043982 -0.067059 0.051092 0.025235 -0.147107 +-0.016269 0.123009 0.035894 -0.020453 0.040013 +0.015557 0.015825 0.080712 -0.069630 -0.149739 +0.022006 -0.008848 0.040169 -0.095688 0.059575 +-0.030641 -0.061353 0.046302 0.104489 0.043372 +-0.001579 0.059737 -0.104073 0.042342 -0.048611 +-0.013811 -0.056255 0.107179 0.057433 0.084815 +0.030217 0.022360 -0.040342 -0.028775 0.120588 +0.041270 -0.045775 -0.030195 -0.106859 -0.104349 +0.072418 -0.003603 -0.013072 0.040728 0.086869 +0.091943 0.066517 0.024442 -0.030929 -0.032920 +-0.160336 -0.010347 -0.068458 0.017458 0.044823 +0.050694 0.067625 0.040303 0.113164 -0.038747 +-0.065558 -0.106357 -0.028352 0.121488 0.026548 +-0.007820 0.054872 0.094674 -0.099533 0.005231 +0.118132 0.042780 -0.065079 0.031440 0.043229 +-0.050024 0.015943 0.073917 0.034049 0.010548 +-0.024979 0.022639 0.027795 0.049491 0.048762 +-0.002738 -0.010783 -0.027637 -0.006986 -0.104141 +-0.066719 -0.061742 -0.067028 -0.053057 -0.003478 +-0.050948 -0.122196 0.022082 0.002595 0.015094 +0.006014 0.005784 -0.184537 -0.034872 -0.036104 +0.055412 0.006886 0.103488 -0.063001 0.096665 +-0.035533 0.009847 -0.095114 0.008588 0.023736 +-0.034278 -0.111970 -0.041172 0.039730 -0.102952 +0.063775 0.039273 0.109863 0.091800 0.030306 +-0.082206 0.089449 -0.058478 -0.029341 0.038389 +0.061057 -0.024711 0.111044 -0.035079 -0.027985 +0.014570 0.002046 -0.031545 0.058848 -0.019500 +-0.002475 -0.025589 -0.144358 0.063478 0.124927 +-0.014094 -0.010970 0.031621 -0.040043 0.004389 +0.025003 0.052397 -0.054526 -0.073469 0.026795 +-0.024697 0.024739 0.118299 0.014948 -0.132109 +0.020192 0.037815 -0.090270 0.049313 0.082764 +-0.022642 -0.006053 -0.038073 -0.057363 -0.107347 +0.033166 -0.027556 -0.019765 -0.111958 0.027773 +-0.063001 -0.052998 0.019353 -0.009646 -0.011270 +0.011872 -0.006508 -0.122226 0.059824 0.041779 +0.016445 -0.031890 -0.036310 0.013085 0.091631 +0.062866 0.054501 -0.117523 -0.010907 0.087026 +-0.014974 -0.035920 -0.048565 -0.019246 -0.043405 +-0.006959 0.006211 0.042370 0.014603 -0.006435 +0.019149 0.078038 -0.020556 0.018114 -0.036521 +-0.054036 0.007325 0.056349 -0.033497 -0.025960 +0.050184 -0.066536 0.091501 0.071356 -0.049044 +-0.032263 -0.095268 -0.008784 0.049033 0.036929 +0.020357 0.152151 0.040814 -0.063159 -0.024324 +-0.017084 0.011876 -0.015442 -0.019811 -0.000366 +-0.002700 -0.072981 0.109288 0.007473 -0.049442 +-0.054040 0.051947 0.019359 0.129160 0.021981 +0.002248 0.035262 -0.023141 0.064666 -0.078273 +-0.031663 -0.031343 -0.006058 -0.045421 0.017466 +-0.067122 -0.130784 0.067057 0.052460 -0.041165 +-0.004411 0.046453 -0.055461 0.048162 -0.009687 +0.021530 0.007211 0.104764 0.079849 0.086248 +-0.072791 0.001112 -0.027964 -0.071233 -0.013339 +0.007979 -0.118231 0.076826 -0.060762 -0.084358 +-0.011447 0.009765 0.014163 0.164784 -0.015892 +-0.020756 0.152509 -0.014014 -0.041853 -0.117008 +-0.011755 -0.005766 -0.086896 -0.139650 -0.032342 +0.025651 -0.007843 -0.039073 0.103397 -0.042591 +-0.005971 -0.001324 -0.053945 -0.000716 0.048977 +0.130185 0.028226 0.061179 0.024489 -0.021939 +-0.007019 0.054336 -0.010040 -0.095411 0.082406 +-0.032130 -0.015054 0.033059 0.002802 -0.080159 +-0.022452 0.077426 -0.015314 0.033583 0.028479 +0.023293 0.035078 0.006442 -0.110541 -0.106244 +-0.034737 -0.104140 -0.034570 -0.114316 0.079382 +0.006009 0.003901 0.080081 0.055082 0.012896 +0.064981 0.057219 -0.112986 0.003906 -0.028414 +-0.012383 -0.054541 0.077483 0.004267 0.123567 +0.007369 0.099856 0.023273 -0.028194 0.122030 +-0.036635 -0.126589 -0.034567 -0.028288 -0.065040 +0.014280 0.011435 -0.004867 0.043901 0.035395 +0.028599 0.075858 0.118460 0.070581 -0.051903 +-0.170905 0.050352 0.053514 -0.017139 0.021748 +-0.096610 0.008904 -0.001049 0.078787 -0.101201 +-0.026229 -0.019757 -0.035771 0.054142 0.068041 +-0.020328 0.099979 0.096623 -0.046957 -0.001733 +0.049586 0.052458 -0.031724 -0.028332 -0.005418 +0.046710 0.014238 0.133125 -0.005428 -0.080055 +-0.033226 0.034007 0.025272 0.033924 -0.044662 +-0.034690 -0.079173 -0.160689 -0.153893 -0.228771 +-0.002450 -0.083966 -0.168294 0.010694 -0.012167 +0.000004 -0.044377 0.023373 -0.077437 0.012178 +-0.015899 -0.010828 -0.062847 0.029927 -0.074557 +-0.053306 0.049688 0.057017 -0.022571 0.015337 +-0.046545 0.018895 -0.024848 -0.004424 0.165442 +-0.060201 -0.098629 -0.065190 0.036582 -0.038566 +0.051453 0.093478 0.039619 0.117535 0.090386 +-0.029366 0.108075 -0.016568 -0.093576 -0.048799 +-0.045599 -0.023619 0.070072 -0.109294 0.001548 +0.076285 -0.091274 -0.068829 0.000215 -0.046519 +-0.022512 -0.027067 0.014905 0.079017 0.140699 +0.061141 0.009178 0.097811 0.033468 -0.006666 +0.007163 -0.007578 -0.124238 -0.025271 0.017581 +0.042405 -0.034252 0.064890 0.002500 -0.139083 +0.009733 0.158179 0.014474 0.038913 0.056290 +-0.004998 0.075401 -0.030557 -0.038595 -0.049070 +-0.014680 -0.076306 -0.132365 -0.177693 0.091760 +-0.057238 -0.072379 0.050877 0.051489 0.028125 +0.004991 0.032621 -0.167359 0.041002 -0.007072 +-0.086405 -0.042263 -0.019757 -0.011524 0.066004 +0.085670 0.008071 -0.013614 -0.062142 0.083280 +0.000887 -0.075820 0.008295 -0.020136 -0.016886 +0.089657 -0.106260 -0.051491 -0.012687 0.054778 +0.011535 0.086613 0.053803 0.027164 -0.023825 +-0.040009 0.080987 0.026309 -0.000334 -0.085288 +-0.024208 -0.085040 0.096077 0.120527 -0.044181 +0.003034 -0.091142 0.006471 0.115971 -0.026358 +0.003489 0.083633 0.109975 -0.029425 0.061726 +0.056115 -0.006711 0.013158 -0.062917 -0.015029 +0.003354 0.031574 0.119045 0.022859 0.023777 +-0.068292 0.115604 0.031617 0.008953 0.006943 +0.014420 0.008569 -0.031547 -0.006857 -0.051690 +-0.086683 -0.108339 0.005093 -0.108646 -0.034720 +0.054273 -0.096753 0.050806 -0.021115 -0.025278 +-0.079997 0.027008 -0.034211 0.090949 0.005678 +0.019288 0.042083 0.062119 0.019301 0.040859 +-0.009113 0.022427 -0.004019 -0.060890 0.032884 +-0.012373 -0.037976 0.017625 -0.079369 -0.050788 +0.079720 -0.039347 -0.085324 0.091044 0.026653 +-0.063122 0.099371 -0.024736 0.084631 -0.100421 +-0.073313 0.014317 0.022555 -0.116051 -0.063966 +-0.009688 -0.063666 -0.131709 0.016744 -0.135028 +-0.003708 -0.043685 -0.121631 -0.036930 0.125776 +0.084333 0.010114 0.071231 -0.010395 0.059391 +0.017760 0.033034 -0.018996 -0.130540 0.025758 +-0.018261 -0.060044 0.127025 -0.032724 -0.107299 +-0.064538 0.090073 -0.010186 -0.066127 0.107025 +-0.010940 0.003083 0.019030 -0.023935 -0.140176 +0.003549 -0.042402 -0.010695 -0.185915 0.060835 +0.005405 -0.013822 0.029205 0.079338 0.068155 +0.071485 0.030282 -0.087207 0.073480 -0.027940 +0.004896 -0.033246 0.072637 0.018017 0.054712 +0.026184 -0.005287 0.034456 -0.036753 0.079232 +0.072707 0.004506 -0.039353 -0.015560 -0.071466 +0.010257 0.067446 -0.006598 0.047396 0.072218 +0.023405 0.082663 0.015319 -0.035436 -0.075461 +-0.124036 -0.032046 0.060837 0.010231 -0.053024 +0.022800 0.042891 -0.041549 0.132395 -0.095330 +-0.077091 -0.058554 -0.070632 0.047570 0.031856 +0.000127 0.114996 0.058660 -0.092472 0.064503 +0.096450 0.066200 -0.001059 0.039487 -0.032859 +-0.065721 0.001601 0.088037 0.059828 -0.047411 +-0.077714 0.010275 0.013629 0.003304 0.005407 +0.000665 0.012927 -0.077525 0.069202 -0.157417 +0.014547 -0.095965 -0.087546 -0.067375 -0.027867 +0.005458 -0.095839 0.105294 -0.044892 0.045151 +-0.001349 0.038356 -0.127152 -0.080503 -0.105423 +-0.018484 0.008439 0.104398 -0.027959 0.082086 +-0.020605 0.042785 -0.109139 -0.025958 0.079733 +0.036289 -0.083773 -0.033819 0.032566 -0.065556 +0.006659 0.002090 0.097027 0.115715 -0.013271 +-0.067514 0.128365 -0.089129 0.026160 -0.040584 +-0.002443 -0.017254 0.129204 -0.110078 -0.064943 +0.089215 -0.022299 -0.034959 0.022446 -0.019254 +-0.038900 -0.069862 -0.070540 0.069949 0.111993 +-0.006311 -0.009057 0.094278 -0.014932 0.003657 +-0.019323 0.026145 -0.062611 -0.073753 -0.007182 +0.014101 0.015776 0.052537 0.064728 -0.160187 +-0.005122 0.076356 -0.104763 0.091493 0.020225 +-0.000433 0.062698 -0.060457 -0.147540 -0.066168 +0.007195 -0.061498 -0.037801 -0.039763 0.059551 +-0.028410 -0.074510 0.057667 0.020584 -0.042510 +-0.025311 -0.037825 -0.188010 0.077423 0.030749 +-0.025465 -0.067541 0.003073 -0.049778 0.127789 +0.002786 0.120009 -0.067812 -0.026565 0.111272 +0.023219 -0.024403 -0.014507 -0.048624 0.022163 +0.014596 -0.052136 0.001580 0.064595 0.017963 +0.021330 0.098862 -0.009253 -0.041062 0.008903 +-0.013829 0.031967 0.076571 -0.005348 -0.044010 +0.031252 0.000369 0.036818 0.072854 -0.038569 +0.004161 -0.128017 -0.053152 0.050896 -0.015212 +-0.036159 0.097995 0.068397 -0.048472 -0.056131 +-0.011920 0.059188 0.010215 -0.061152 -0.011717 +-0.035949 -0.057039 0.090859 -0.029682 0.041466 +-0.025106 0.131191 0.059327 0.085383 0.021699 +0.049230 0.036630 -0.077086 0.017806 -0.088790 +0.004040 -0.069533 -0.026785 0.009666 0.014017 +-0.055897 -0.096299 0.120693 0.029995 0.032602 +-0.001365 0.034015 -0.053512 0.001573 -0.019170 +0.003956 0.006452 0.067313 0.028301 0.160615 +-0.053111 0.013990 -0.027060 -0.013638 0.039376 +-0.054462 -0.096553 0.079994 -0.043791 -0.025051 +-0.003222 0.019418 -0.049525 0.151136 0.034123 +0.055117 0.058918 -0.017393 0.026169 -0.126380 +-0.019008 -0.028939 -0.014027 -0.173373 -0.032841 +-0.003370 0.039680 -0.118311 0.114094 -0.041869 +0.041121 -0.038391 -0.096074 -0.032479 0.060222 +0.063968 -0.024528 0.018158 -0.009892 -0.043882 +-0.005004 0.129800 -0.025438 -0.121186 0.049860 +0.010448 -0.040388 0.061853 -0.017304 -0.035088 +-0.008678 0.061476 -0.039493 -0.005055 0.079169 +0.046134 0.009770 0.068294 -0.078965 -0.043792 +-0.030529 -0.053845 0.053853 -0.140682 0.111461 +0.003549 -0.014939 0.148955 0.072861 0.004332 +0.015386 0.062006 -0.122325 -0.032529 0.010241 +-0.047982 -0.126440 0.055840 0.067128 0.101189 +-0.002630 0.031969 0.046076 -0.080194 0.104740 +-0.033486 -0.077818 -0.058697 -0.095258 -0.111074 +0.037236 0.011711 0.001113 -0.005664 0.048588 +0.041131 0.098257 0.033126 0.029317 -0.095311 +-0.071555 -0.039999 0.026678 -0.072182 0.035031 +-0.007997 -0.048174 -0.006796 0.075959 -0.052060 +-0.007645 0.037076 -0.035574 0.085576 0.034126 +-0.050676 0.051430 0.031999 -0.134308 -0.001489 +0.084564 -0.018394 -0.097410 -0.042931 -0.025608 +-0.025489 0.041919 0.142482 0.004617 -0.041085 +-0.028816 -0.015527 -0.031005 0.028405 -0.022240 +-0.067737 -0.025241 -0.052578 0.012322 -0.120556 +0.016278 -0.081744 -0.099160 0.025144 0.025441 +0.003176 -0.073871 0.031718 -0.028622 0.029031 +0.017910 -0.030693 -0.104215 -0.015422 -0.065738 +-0.048346 -0.012847 0.046849 -0.008621 0.058771 +-0.054495 0.031597 -0.038844 0.043138 0.092588 +-0.071371 -0.059093 -0.001197 0.001766 -0.074762 +0.029470 0.089616 0.005009 0.052977 0.015899 +-0.045424 0.158466 -0.038717 -0.032506 0.028687 +0.011435 -0.006772 0.047605 -0.144659 -0.031229 +0.073577 0.011530 -0.008172 0.058883 -0.088412 +0.033615 -0.034120 -0.030701 0.101215 0.096645 +0.027368 0.041249 0.081502 -0.025440 0.007592 +0.059893 0.012106 -0.112009 -0.114692 0.016397 +0.087068 0.016199 0.051263 0.011915 -0.085364 +0.026046 0.145258 -0.047521 0.077134 -0.000345 +0.034532 0.099801 -0.087591 -0.059719 -0.058671 +0.022737 -0.001887 -0.107049 -0.116757 0.134115 +-0.055403 0.005157 0.067618 0.081074 0.071787 +0.063802 -0.003430 -0.106491 0.017543 0.002214 +-0.013785 -0.032962 0.010084 0.024325 0.045963 +0.059883 0.072282 -0.008608 -0.015127 0.048225 +0.041752 -0.068845 0.012227 -0.090748 -0.035309 +0.045353 -0.078624 -0.019489 0.035531 0.058571 +0.045414 0.039032 -0.011106 0.048787 -0.025336 +-0.084893 0.031896 0.010850 0.012526 -0.053205 +0.016952 -0.044041 0.068766 0.097328 -0.122229 +0.027016 -0.051759 -0.057246 0.074566 0.006201 +0.069904 0.100068 0.076124 0.004278 0.029466 +0.045229 0.055683 0.018790 -0.067806 0.039373 +0.029179 -0.036787 0.129921 -0.028993 0.037711 +-0.105011 0.138747 -0.004370 0.052080 0.050835 +0.025511 -0.002962 0.007852 -0.055234 -0.075055 +0.000460 -0.089231 -0.030467 -0.080347 0.007488 +0.067460 -0.076368 0.084991 0.039544 0.033391 +-0.044318 0.006390 -0.079387 -0.002909 -0.029708 +-0.047882 0.063040 0.065719 0.021811 0.070945 +-0.007571 -0.001302 -0.064119 -0.068005 0.051040 +-0.017747 -0.063938 0.018673 -0.038391 -0.099966 +0.057475 -0.007669 0.009384 0.109283 0.012248 +-0.048858 0.092498 0.011967 0.061525 -0.028819 +-0.015131 -0.024160 -0.033220 -0.101648 -0.017980 +-0.003342 -0.049829 -0.125096 0.128241 -0.047377 +-0.028943 -0.109072 -0.066133 -0.015454 0.098334 +0.053371 0.011324 0.042781 0.044313 0.062510 +0.098408 0.065410 -0.040693 -0.116351 -0.032327 +-0.013634 -0.058591 0.081507 0.042019 -0.099770 +-0.018275 0.084624 -0.007512 -0.041113 0.054203 +0.017879 -0.029747 0.059865 -0.048281 -0.111513 +-0.022478 0.002059 0.022383 -0.125360 0.058216 +0.002386 -0.081600 0.049288 0.157428 0.057724 +0.005046 0.102125 -0.083473 0.044059 -0.094864 +0.039120 -0.063306 0.057341 0.060519 0.107383 +0.007076 -0.009373 -0.012555 -0.066630 0.117121 +0.025254 -0.008796 -0.062102 -0.083164 -0.079007 +0.084839 0.042308 -0.055353 0.036386 0.132641 +0.084464 0.056288 -0.011636 -0.059554 -0.087748 +-0.147377 -0.052414 -0.010203 -0.009159 -0.018829 +0.009621 0.061633 0.015716 0.086332 -0.061465 +-0.011833 -0.062998 -0.021168 0.125194 0.045025 +0.052316 0.025720 0.095155 -0.093252 0.028720 +0.056113 0.063321 -0.045315 0.025199 0.023591 +-0.070481 0.072350 0.092458 0.047973 -0.025439 +-0.001281 0.021028 0.034576 0.084779 0.006867 +-0.010323 -0.046330 -0.009172 0.030485 -0.117679 +-0.021782 -0.034737 -0.086292 -0.045885 0.009655 +-0.037167 -0.123331 0.017291 -0.028319 0.071447 +-0.057180 -0.032912 -0.139418 -0.025966 -0.039305 +0.009411 -0.054017 0.076307 -0.060252 0.110087 +-0.061366 0.038897 -0.098107 0.046119 0.043021 +-0.029130 -0.096885 0.007623 0.090513 -0.097416 +0.053264 0.058296 0.054372 0.060769 0.015586 +-0.067956 0.059996 -0.037850 0.005986 0.000778 +0.045873 -0.065546 0.077900 -0.085638 0.000698 +0.027694 -0.021241 -0.002777 0.034509 -0.048173 +0.009988 0.001008 -0.077434 0.026002 0.139490 +0.008910 0.007791 0.059292 -0.057047 0.014127 +-0.022959 0.085710 -0.068087 -0.081561 0.005935 +0.007577 0.061544 0.076542 0.001660 -0.113279 +0.024973 0.086750 -0.061674 0.095059 0.089352 +-0.024436 0.024181 -0.016117 -0.073634 -0.067986 +0.074701 -0.046868 -0.054634 -0.092485 0.006662 +-0.033256 -0.053774 0.049001 -0.002339 0.013545 +-0.006432 -0.012089 -0.086842 0.104105 0.061991 diff --git a/gr-vocoder/lib/codec2/codebook/lspjvm3.txt b/gr-vocoder/lib/codec2/codebook/lspjvm3.txt new file mode 100644 index 0000000000..72767df8ea --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspjvm3.txt @@ -0,0 +1,513 @@ +5 512 +0.007066 0.075781 -0.070082 -0.092014 -0.066477 +0.090510 0.106622 0.025911 -0.016760 0.003724 +-0.024628 0.058332 0.012876 0.059557 -0.002092 +-0.065092 -0.096975 -0.041837 -0.002432 0.058918 +0.014358 0.080049 -0.008803 -0.002091 -0.097584 +0.085323 -0.026053 -0.086585 -0.009541 0.130555 +0.045391 0.037557 0.074726 -0.050453 0.033517 +-0.035576 -0.084211 -0.086430 0.008910 -0.072674 +-0.098699 -0.024540 -0.048972 -0.066975 -0.048791 +0.032184 0.070992 -0.014416 0.141892 -0.044249 +-0.108921 -0.020450 0.115988 0.011287 -0.026273 +0.024341 0.138519 -0.036467 0.020684 0.074258 +-0.053563 0.077463 0.072166 0.032112 -0.079303 +-0.025039 0.079675 0.094211 -0.115754 0.038892 +0.050897 -0.024639 0.057826 -0.110429 0.071184 +0.015309 -0.034027 -0.055726 0.043179 -0.063089 +0.043359 -0.011698 0.006637 0.002751 0.030110 +-0.001261 0.111470 0.043277 -0.004205 -0.021599 +-0.005698 0.058842 0.168422 0.059313 -0.007971 +-0.087599 0.073891 -0.083238 0.099279 -0.017364 +-0.018429 0.014040 -0.014864 -0.111512 0.089450 +-0.028498 -0.087983 -0.077320 -0.062602 0.000328 +-0.027152 -0.093796 0.111381 -0.018603 0.092394 +-0.007256 0.025391 0.011454 0.012802 -0.041680 +0.008078 0.020905 -0.105401 -0.083265 0.027756 +-0.049630 -0.044085 -0.051424 0.104125 -0.000779 +-0.063079 -0.130699 0.070500 0.033468 -0.019802 +-0.061011 0.094839 -0.040122 0.118409 0.056950 +0.086391 -0.006615 0.045337 -0.044190 -0.106474 +-0.081912 0.067557 -0.031649 -0.014437 0.057585 +-0.121755 -0.049113 0.057109 -0.049872 0.044104 +0.064705 -0.091589 0.037286 -0.048606 -0.045398 +0.003456 0.057230 0.006262 -0.055206 -0.063871 +-0.005249 0.081783 0.134969 -0.002331 0.052643 +-0.093346 0.072093 0.116025 -0.031453 -0.006012 +-0.038574 -0.030841 0.010288 0.024420 0.051657 +-0.086584 0.046381 0.005410 0.052622 -0.072741 +0.079023 0.078099 -0.093912 0.005477 -0.006721 +0.100232 -0.017587 0.044819 0.036655 0.021580 +-0.006829 -0.050076 -0.003020 0.088246 0.013560 +-0.015690 0.012477 -0.052595 -0.048861 -0.033688 +0.055615 0.092298 -0.066194 0.016416 -0.066059 +0.046976 0.003023 0.104646 0.109136 0.018293 +-0.016507 -0.006859 0.004326 0.070843 0.140750 +0.025774 0.034730 -0.079590 0.050054 -0.107950 +0.002378 0.097498 0.027111 -0.122953 -0.002423 +-0.020539 -0.063263 -0.095493 -0.157361 -0.039183 +0.025721 0.026897 -0.001200 0.033997 -0.001749 +0.061593 -0.013053 -0.106317 -0.068190 0.046352 +-0.056060 0.157084 -0.049365 0.053959 -0.051065 +-0.047672 0.081570 0.064342 -0.030705 -0.070806 +-0.076503 -0.059471 0.012419 0.073968 -0.026179 +-0.038473 0.059013 -0.035783 -0.030057 -0.036346 +-0.052692 -0.015346 -0.022687 -0.035279 0.013314 +0.068397 -0.046609 -0.009593 -0.040796 0.157438 +-0.075360 -0.110464 0.031839 -0.029035 -0.015222 +0.041013 -0.099212 -0.108920 -0.008627 0.012095 +0.020855 0.009935 -0.086917 0.058827 -0.006536 +0.022104 -0.005013 0.003496 0.046663 -0.051061 +-0.036803 -0.067317 -0.007075 0.180870 -0.027434 +-0.025056 -0.039341 -0.073918 -0.003180 -0.110930 +-0.042711 0.005519 -0.035005 -0.088419 0.170942 +0.001503 -0.121485 0.066383 -0.067346 0.005643 +0.080088 -0.042562 -0.006668 -0.036538 0.020683 +0.042848 0.027852 -0.029088 -0.156468 0.006503 +0.037716 0.032082 0.038416 0.021835 -0.106963 +-0.043017 0.018166 0.070409 -0.005426 -0.035585 +-0.111071 -0.039986 0.050430 0.035157 0.066902 +-0.040684 0.060527 0.036225 0.002527 -0.015087 +0.059243 0.021268 -0.010682 -0.018434 0.059128 +0.111314 -0.054070 0.105744 -0.051476 -0.012970 +-0.000358 -0.099249 -0.077385 0.069924 -0.039101 +-0.072139 -0.049069 -0.088018 0.006144 0.000712 +0.081030 0.021987 -0.046031 0.058087 -0.001320 +-0.046851 -0.011062 0.108321 -0.001146 -0.071193 +0.044973 -0.002915 -0.003323 0.041735 0.094566 +0.053530 0.035927 0.100282 0.059082 -0.054059 +-0.012158 -0.035417 0.020412 -0.073193 0.059296 +-0.040489 -0.095250 -0.003821 -0.084904 0.053925 +0.109183 -0.005862 -0.036538 0.080962 -0.040647 +0.020070 0.057778 -0.020197 -0.079626 -0.003186 +-0.050855 0.128185 0.034731 0.057460 -0.035236 +-0.057096 -0.001238 0.122018 -0.071204 -0.047253 +-0.051767 0.048301 -0.052678 0.025990 -0.017481 +-0.029379 0.030738 0.047207 -0.047864 -0.033561 +0.029884 -0.091175 -0.085446 -0.026140 0.092628 +0.067706 -0.085617 0.081433 0.047305 0.031945 +-0.048728 -0.040387 0.046206 0.010578 -0.037639 +0.011328 -0.042458 -0.149597 0.033882 -0.061869 +0.008800 0.057754 -0.095876 0.038230 0.096876 +-0.033487 -0.141669 -0.014172 0.028439 -0.092764 +-0.053714 0.086926 0.034786 0.136053 -0.005569 +0.028753 0.009630 0.044114 -0.050365 -0.066224 +0.006017 0.014348 0.024471 0.000489 0.067234 +-0.021678 -0.118760 0.036349 -0.040295 0.076358 +-0.008444 -0.086082 -0.044018 -0.025804 0.028971 +-0.009233 0.053026 -0.035341 -0.182193 -0.102515 +0.089210 0.066812 0.032417 0.046882 -0.034815 +-0.052293 0.022814 0.129622 0.128232 -0.012105 +-0.087084 0.004762 0.086538 0.046566 0.098359 +-0.018713 0.039204 -0.021707 -0.060110 -0.117527 +-0.005459 0.060994 -0.057718 -0.021783 0.035154 +0.100557 -0.015470 -0.025818 0.008450 0.051535 +-0.001388 -0.114610 -0.057903 0.041862 0.061778 +0.045701 -0.078563 -0.070166 -0.048450 -0.088530 +0.021375 -0.004598 -0.090710 -0.009399 -0.073952 +-0.035575 -0.050280 0.114780 0.137866 0.065234 +0.003594 -0.066802 -0.144989 0.166201 0.039564 +-0.022457 -0.030090 0.016187 0.115443 -0.097331 +-0.019139 0.099440 0.002198 -0.030953 0.021099 +-0.045399 -0.046871 0.022533 -0.064657 0.005776 +0.049063 -0.028478 0.019268 0.054265 0.028042 +0.045559 -0.005541 -0.014410 -0.024165 -0.054976 +-0.073258 0.084205 0.036077 -0.068683 0.004708 +-0.085228 0.001234 0.046261 -0.050496 -0.028227 +-0.086828 -0.001218 0.021865 0.003791 -0.000568 +-0.088733 -0.040041 -0.035891 -0.054915 0.073463 +-0.132031 -0.012844 -0.068544 0.013052 0.087335 +0.038603 -0.115382 -0.010433 -0.007113 0.095126 +-0.047378 -0.081353 0.018021 -0.021156 -0.120774 +0.040038 0.007633 -0.088728 -0.009928 0.020142 +0.052024 -0.021063 -0.118121 0.102739 -0.055837 +0.005253 -0.061924 0.063680 -0.014512 -0.020259 +0.029493 -0.013435 -0.020638 0.089342 0.001092 +-0.046491 -0.145634 -0.083159 -0.158142 -0.279281 +0.003611 0.055863 -0.064655 -0.088773 0.089283 +-0.029619 -0.089949 0.017197 -0.066633 -0.052347 +0.090828 -0.087551 0.000338 0.085238 -0.005313 +0.096211 0.071381 -0.076546 -0.077927 -0.040864 +0.062936 0.041559 0.016235 -0.017513 0.014773 +-0.025734 0.028586 0.070292 0.055794 -0.026131 +-0.076954 -0.082228 0.043947 -0.035921 0.152668 +-0.049510 0.023159 0.008506 -0.044773 -0.160358 +0.024984 -0.025587 -0.071627 -0.038376 0.088478 +0.120568 0.046723 0.086731 0.000695 -0.015751 +-0.027837 -0.160937 -0.095031 0.036271 -0.009061 +-0.015078 -0.036281 -0.103665 -0.058258 -0.049573 +0.022021 0.108296 -0.002586 0.065655 -0.018584 +-0.046441 -0.031018 0.067350 0.014328 0.008860 +-0.000245 0.063400 -0.001810 0.043515 0.090344 +-0.063845 0.020485 0.079401 0.070558 -0.116428 +0.032628 0.068949 0.052238 -0.044530 0.096813 +0.029911 -0.008814 0.044352 -0.168172 0.009604 +0.055828 -0.100739 -0.026013 0.021193 -0.051425 +0.035891 -0.004085 0.030216 -0.060801 0.037202 +0.007262 0.120686 0.026846 0.058464 -0.100792 +-0.009176 0.027589 0.123957 -0.011283 -0.025744 +-0.105081 0.118244 -0.042122 -0.025404 0.000873 +-0.012703 0.084159 -0.067539 -0.140536 0.041637 +-0.014485 -0.043382 -0.048004 -0.075416 0.054401 +-0.018651 -0.032908 0.164231 -0.053236 0.033946 +-0.021681 -0.012655 -0.037049 -0.001613 -0.053393 +-0.014635 0.017954 -0.116115 -0.027232 0.034005 +-0.035376 0.026492 -0.037250 0.070733 0.074835 +-0.021378 -0.142980 0.123195 0.003699 0.025398 +0.015629 0.077370 0.032623 0.121580 0.097100 +0.000946 -0.056355 0.042065 0.008184 -0.081824 +-0.101937 0.065473 0.003360 0.069241 0.073002 +-0.053844 -0.044301 0.080351 -0.091833 0.044288 +0.007447 -0.120723 -0.013806 -0.023636 -0.064616 +0.030556 0.072630 0.074428 -0.087759 -0.026440 +0.064840 0.049162 0.091053 0.023891 0.033811 +-0.027746 0.116392 0.106126 -0.056644 -0.014781 +0.036137 -0.002632 0.055512 0.070077 0.067819 +-0.030625 0.053772 -0.078457 -0.021351 -0.113011 +0.052797 0.044875 -0.077269 -0.009867 0.101493 +0.073477 -0.024103 0.049145 -0.004706 -0.025211 +-0.053731 -0.049009 -0.035786 0.054430 0.046515 +0.025154 -0.043569 -0.034789 -0.058610 0.006931 +0.012049 0.046809 -0.129441 0.025541 -0.030933 +0.000297 -0.054058 0.179837 0.081515 0.004932 +-0.028445 -0.073753 0.010629 0.080042 0.098710 +-0.014017 0.057597 0.001010 0.071658 -0.067570 +0.074384 0.110366 -0.018121 -0.108754 0.037793 +0.028041 -0.047508 -0.031359 -0.098913 -0.036486 +-0.017311 -0.001279 -0.013694 0.051968 0.036512 +0.088201 0.031155 -0.043442 -0.065045 0.023486 +0.027000 0.104768 -0.015176 -0.038754 -0.004178 +0.003732 0.062166 0.085438 -0.077368 -0.101645 +-0.118347 0.007589 -0.056489 0.082268 0.020253 +-0.035623 0.034235 -0.099354 -0.061237 -0.024285 +0.005441 -0.039694 -0.025957 -0.004411 0.049903 +0.003040 0.036243 0.023552 -0.007334 0.128963 +-0.077727 -0.059175 -0.019437 -0.024872 0.004339 +0.084006 -0.076605 -0.102261 0.036714 -0.035205 +-0.007642 -0.005125 -0.030525 0.096390 -0.053138 +-0.002192 -0.024851 0.050645 0.041490 -0.043183 +0.046796 -0.050894 0.055023 0.133834 -0.024013 +0.000872 -0.057072 -0.000630 0.042070 -0.129339 +-0.064283 0.037836 -0.066393 0.004438 0.125379 +-0.062213 -0.067468 0.090177 -0.046094 -0.025725 +0.079101 -0.074909 -0.043730 -0.073483 0.069672 +-0.020413 -0.000079 -0.049725 -0.120751 -0.046980 +0.039894 0.072305 0.009798 0.005613 -0.045217 +0.006862 0.036285 0.074819 -0.006747 0.015144 +-0.071562 0.012324 -0.001082 0.014835 0.079960 +-0.027804 0.103358 -0.017203 0.014914 -0.056687 +0.030827 0.028076 0.003395 -0.073255 0.110310 +0.056498 -0.044893 0.110122 -0.109058 -0.052302 +-0.001604 -0.089977 -0.060548 0.107808 0.025463 +-0.070203 -0.000513 -0.123913 0.046247 -0.085392 +0.096343 0.095890 -0.064950 0.070363 0.034272 +0.037773 -0.076950 0.124858 -0.009008 -0.010115 +0.083868 0.051242 0.039149 0.015185 0.083375 +0.029773 -0.045961 0.100395 0.003743 -0.138294 +-0.041755 0.010806 0.057797 -0.147374 0.095858 +-0.009929 -0.103347 -0.032310 -0.110560 0.121377 +0.145244 0.017079 -0.080587 0.020516 -0.044939 +-0.010477 0.038347 -0.003466 -0.001618 0.019600 +-0.021762 0.125482 0.011074 0.065815 0.040298 +0.009202 -0.051686 0.129684 -0.131135 0.044536 +0.009313 0.102518 -0.075351 0.054338 0.020273 +-0.045753 0.031345 0.000407 -0.097294 -0.000416 +-0.007466 -0.044972 -0.078744 0.042414 0.066624 +0.030318 -0.067852 0.061416 -0.028992 0.056606 +0.004038 -0.036253 -0.014279 0.023123 -0.007832 +-0.000137 -0.027684 -0.127648 -0.007713 -0.008746 +-0.026500 0.049032 -0.183319 0.059107 0.066500 +0.016902 -0.093331 0.090129 0.016648 -0.083492 +-0.023669 -0.010473 0.027614 0.145068 0.000681 +0.044133 -0.035809 0.005668 -0.090461 -0.090732 +-0.033927 0.042997 0.021700 -0.046955 0.044487 +-0.026444 -0.061011 0.010110 -0.023804 0.030427 +-0.015195 -0.155603 -0.016584 0.021461 -0.003528 +-0.059784 0.032214 0.000847 -0.098859 -0.078980 +0.043188 0.066433 0.062309 0.144507 0.006865 +-0.068953 0.046698 0.099369 0.043354 -0.014309 +-0.033202 -0.002950 0.040734 0.083454 0.039319 +0.051358 0.006074 -0.073465 -0.090554 -0.120787 +-0.040676 0.092412 -0.085151 -0.021699 0.005813 +0.103135 0.024964 0.025832 -0.075982 0.035699 +-0.027310 -0.153007 0.036420 0.057600 0.081630 +0.001605 -0.054191 -0.033043 -0.014390 -0.071383 +0.036180 0.035860 -0.046980 0.038541 -0.044757 +-0.078032 -0.029878 0.078183 0.082251 0.010549 +0.053317 -0.038231 -0.065610 0.055798 0.037504 +0.076317 -0.027605 0.010349 0.095361 -0.088636 +0.049089 0.113316 0.051084 0.038589 0.034330 +-0.055948 -0.037217 -0.015418 -0.139976 0.036306 +0.039306 -0.009889 -0.044910 0.016559 -0.000050 +0.106073 0.015280 -0.002563 -0.109085 -0.048475 +-0.035319 0.163860 0.032981 -0.044932 0.003227 +-0.123233 -0.010638 0.055479 -0.003666 -0.072249 +-0.111158 0.065365 0.010691 0.039119 -0.001837 +-0.118729 0.061470 -0.002077 -0.033335 -0.060165 +-0.026081 -0.001806 -0.079616 -0.000075 0.080598 +0.032908 -0.035140 -0.003136 -0.029024 0.094622 +-0.075773 -0.022898 -0.014817 0.058393 -0.111505 +0.036794 -0.015760 -0.112602 0.030323 0.085897 +-0.020834 0.056079 -0.103762 0.117671 -0.041205 +0.041684 -0.084336 0.034186 0.011973 -0.006313 +0.040836 -0.035709 0.034170 0.122672 0.090973 +-0.053182 -0.059371 0.091017 -0.090998 -0.116986 +0.001405 0.138364 0.017107 -0.064076 0.103486 +-0.031142 -0.030068 0.046547 -0.133471 -0.042055 +0.140418 -0.125084 0.035218 -0.001162 -0.021130 +-0.012034 0.097413 -0.079006 -0.039030 -0.054011 +0.143887 0.078835 -0.000601 -0.021173 -0.039895 +-0.025050 0.075865 0.039221 0.032458 0.038206 +-0.038873 -0.085003 -0.032736 -0.026956 0.113525 +-0.023933 0.120794 -0.003862 -0.026459 -0.138724 +0.089559 0.029002 -0.052098 -0.085692 0.115174 +0.083497 0.024179 0.119021 -0.067541 0.019047 +-0.027720 -0.086083 -0.055329 0.020087 -0.027086 +-0.047858 -0.051975 -0.035205 -0.059342 -0.068582 +0.058936 0.044141 -0.080315 0.119744 -0.046518 +-0.064588 -0.027212 0.147823 0.032404 0.016690 +0.024302 0.085560 -0.001525 0.016469 0.038891 +-0.020146 0.019943 0.045067 0.038070 -0.086274 +-0.025769 0.044192 0.102141 -0.064765 0.055849 +0.048803 -0.030066 -0.009220 -0.116655 0.068295 +0.047580 -0.076138 -0.070307 0.047582 -0.111342 +0.004656 -0.004452 0.029703 -0.004259 0.011130 +0.014446 0.166086 0.059565 0.000985 -0.052607 +0.013251 0.094476 0.106216 0.016715 -0.025581 +-0.101244 0.072897 -0.114526 0.024681 0.010784 +-0.051759 0.032389 -0.050202 -0.083316 0.052334 +-0.035100 -0.116721 -0.110336 -0.053391 0.065541 +-0.029790 -0.020457 0.135285 -0.004142 0.111508 +-0.030936 0.018549 -0.016034 0.018572 -0.084336 +-0.048615 -0.018739 -0.096815 -0.090162 0.019410 +-0.040821 -0.009925 -0.097427 0.091891 0.031793 +-0.024598 -0.132848 0.078353 0.089339 -0.068562 +-0.020779 0.040974 -0.055675 0.169131 0.029649 +0.078165 -0.050679 -0.005881 -0.004983 -0.104324 +-0.069096 0.127960 0.011392 -0.000769 0.062168 +-0.079842 0.001606 0.089284 -0.035465 0.031075 +0.029519 -0.102956 -0.010902 -0.064030 -0.019669 +0.057492 0.075802 -0.008904 -0.060743 -0.053144 +0.005126 0.062980 0.085674 0.019895 0.104448 +-0.086473 0.056906 0.056795 -0.012940 0.036606 +-0.008604 -0.040450 0.042062 0.041810 0.027680 +-0.092256 0.091237 -0.039500 0.024761 -0.088978 +0.068585 0.088295 -0.048033 -0.017808 0.045370 +0.124600 -0.035320 0.056751 0.092751 0.054025 +-0.015725 -0.061938 0.036806 0.078768 -0.016065 +0.002444 -0.023887 -0.072177 -0.029790 -0.005860 +0.015478 0.129142 -0.091024 0.071482 -0.065445 +0.005867 -0.006051 0.098646 0.054089 0.018713 +0.033837 -0.008355 -0.051959 0.057440 0.160305 +-0.001863 0.016738 -0.033705 0.062233 -0.140759 +0.027342 0.060074 0.030362 -0.117875 0.061020 +-0.028026 -0.088238 -0.003782 -0.146288 -0.080395 +0.050048 0.036136 0.019500 0.066902 0.020355 +0.024817 -0.056254 -0.140918 -0.085803 0.020540 +-0.003730 0.161411 -0.049408 0.000219 -0.002348 +-0.055021 0.067820 0.126483 -0.031063 -0.119299 +-0.102834 0.001133 0.010172 0.107707 -0.029106 +-0.059813 0.036698 -0.021720 -0.043189 -0.002270 +-0.031694 0.009605 -0.022459 -0.036417 0.053675 +0.061561 -0.012723 0.050040 -0.029450 0.131044 +-0.124516 -0.107579 -0.012171 0.011761 0.002599 +0.016327 -0.060854 -0.080910 0.030875 -0.002997 +-0.020970 -0.011880 -0.086096 0.037912 0.012421 +0.055253 -0.007250 0.041740 0.055596 -0.024420 +-0.017564 -0.079202 0.008897 0.180091 0.054490 +0.001772 -0.022151 -0.082048 -0.010559 -0.163377 +-0.020660 -0.017827 -0.030800 -0.045856 0.122405 +-0.052946 -0.130490 0.097383 -0.116737 0.039855 +0.056504 -0.059549 -0.059931 -0.018658 0.034898 +0.054889 0.005373 -0.066796 -0.127360 0.047960 +0.071746 0.027410 -0.006212 0.024132 -0.094062 +0.005369 -0.008926 0.073085 -0.014265 -0.029204 +-0.100025 -0.072076 0.014651 0.069368 0.048275 +-0.066823 0.086074 0.014921 -0.015395 -0.045138 +0.026224 0.000902 -0.038208 -0.035221 0.057397 +0.097606 -0.073195 0.051626 -0.033488 0.027813 +0.002070 -0.097510 -0.057877 0.126680 -0.082194 +-0.072597 0.006014 -0.093185 -0.016853 -0.022790 +0.138461 0.005394 -0.056485 0.102778 0.028918 +-0.045604 -0.060041 0.121251 0.029260 -0.101404 +0.061194 0.033039 -0.016798 0.064263 0.065144 +0.010925 0.023151 0.107623 0.027977 -0.090356 +-0.024863 -0.006440 0.047870 -0.047486 0.088211 +-0.012139 -0.116121 -0.000525 -0.140961 0.016604 +0.063490 -0.022732 -0.046944 0.066970 -0.068838 +0.016143 0.026202 -0.043344 -0.064881 0.024877 +-0.072845 0.120531 0.077901 0.047272 0.011713 +-0.044646 0.040932 0.076164 -0.101233 -0.029615 +-0.065118 0.050966 -0.023273 0.053517 0.023710 +-0.007489 0.035822 0.023439 -0.055528 -0.004033 +-0.007662 -0.096546 -0.081662 0.037141 0.137562 +0.075526 -0.097496 0.123990 0.013996 0.087005 +-0.019788 -0.082043 0.020524 0.007027 -0.021537 +-0.036264 -0.090952 -0.177722 -0.009306 -0.031473 +-0.009287 0.047557 -0.090241 0.089347 0.056375 +-0.005506 -0.112128 0.004356 0.064421 -0.038478 +-0.035674 0.040616 0.007731 0.160236 -0.054199 +-0.007537 0.012434 0.022001 -0.021567 -0.075163 +-0.026053 0.015909 0.041015 0.021832 0.034152 +-0.048539 -0.086655 0.047465 0.000682 0.042640 +0.023697 -0.095971 -0.022874 -0.000369 0.003413 +0.046005 0.064807 0.010131 -0.129517 -0.092254 +0.116469 0.053796 0.038110 0.094470 0.018435 +-0.034803 0.073591 0.108348 0.104096 0.049884 +-0.021274 0.022097 0.065347 0.065555 0.089319 +0.000474 -0.004186 -0.040493 -0.065543 -0.083167 +-0.017425 0.049177 -0.044248 0.008399 0.068180 +0.154778 0.027549 -0.008012 0.014950 0.043254 +0.039599 -0.136415 -0.018716 0.061900 0.031263 +0.058118 -0.037200 -0.114692 -0.080876 -0.053238 +0.077436 0.015015 -0.092517 0.005804 -0.065541 +-0.005653 -0.073184 0.095594 0.082470 0.060989 +-0.000262 -0.035766 -0.083441 0.122634 0.088429 +-0.014397 -0.055434 -0.005659 0.069697 -0.064892 +0.008824 0.082498 0.051866 -0.036070 0.033403 +-0.082855 -0.087376 0.002714 -0.097121 -0.019170 +0.027179 -0.069870 -0.009316 0.047450 0.040657 +0.060527 0.004620 -0.040264 -0.051228 -0.029023 +-0.071384 0.101421 0.009538 -0.099185 0.060100 +-0.048395 -0.024677 0.025125 -0.056043 -0.058045 +-0.054059 0.008107 0.021078 0.045290 -0.018459 +-0.113359 0.014009 -0.006826 -0.052747 0.046922 +-0.075976 0.008538 -0.084411 -0.004369 0.045801 +0.075392 -0.067340 0.014454 0.032407 0.092478 +-0.061859 -0.083458 0.051442 0.031695 -0.080233 +0.054028 0.027000 -0.073549 0.032300 0.036501 +-0.011384 -0.020780 -0.124142 0.093905 -0.028332 +0.039139 -0.030944 0.079952 -0.001717 0.013976 +0.038005 -0.001751 -0.044097 0.129827 0.014385 +-0.001682 -0.063458 -0.002511 -0.078150 -0.141236 +0.021955 0.104851 -0.093246 -0.060019 0.069998 +0.004399 -0.096408 0.059327 -0.062268 -0.074327 +0.108063 -0.090534 -0.045654 0.048119 0.049187 +0.042105 0.043964 -0.091516 -0.047999 -0.028881 +0.070471 0.055401 -0.025605 0.011176 0.008475 +0.022254 0.038266 0.048106 0.047176 -0.017967 +-0.010978 -0.088762 0.034806 0.019311 0.126815 +-0.010571 0.053073 0.032162 -0.000780 -0.152200 +-0.014253 -0.021954 -0.131040 -0.061376 0.113838 +0.060725 0.020201 0.102533 -0.011392 -0.052046 +-0.069625 -0.091011 -0.097954 0.067847 0.017856 +-0.053461 -0.040679 -0.121664 -0.077208 -0.106919 +0.057996 0.069756 -0.012433 0.069569 -0.055159 +-0.024801 -0.060448 0.101700 0.014619 0.036580 +-0.004526 0.093977 -0.028211 0.045261 0.149736 +-0.014691 -0.007959 0.097708 0.107128 -0.079723 +0.029157 0.020116 0.104828 -0.064208 0.119172 +0.039583 -0.029446 0.006628 -0.110398 0.004062 +0.048132 -0.060601 0.009448 0.051777 -0.053127 +0.050551 -0.001924 0.028079 -0.050618 -0.013698 +0.001920 0.088162 0.073078 0.085795 -0.066788 +0.014025 0.042699 0.176241 -0.046674 -0.034822 +-0.051433 0.121729 -0.057076 0.023901 0.045075 +-0.057182 0.054780 -0.017280 -0.146674 0.002090 +-0.016223 -0.044841 -0.084524 -0.152479 0.072688 +-0.006962 0.008711 0.127455 -0.003876 0.053162 +-0.013682 -0.025386 -0.000427 -0.024811 -0.024474 +-0.056267 0.062116 -0.121311 -0.053011 0.065651 +-0.075385 -0.008680 -0.063033 0.083039 0.110577 +-0.000152 -0.127017 0.055904 0.013659 0.005664 +-0.002852 0.047248 0.001128 0.100773 0.037274 +0.026368 -0.042205 0.021887 -0.020247 -0.056678 +-0.077475 0.089799 0.058003 0.039741 0.106663 +-0.016853 -0.015972 0.075741 -0.048829 0.015374 +-0.032657 -0.125677 -0.062060 -0.057409 -0.061287 +0.073151 0.050357 0.053547 -0.059886 -0.051298 +0.057954 -0.003817 0.076028 0.006757 0.061109 +-0.038030 0.143209 0.092207 -0.018493 0.062291 +0.005751 -0.036449 0.067582 0.031449 0.101894 +-0.080754 0.011515 -0.049485 -0.016137 -0.087818 +0.108851 0.038222 -0.099315 -0.003117 0.052278 +0.107517 -0.036233 0.065370 0.040409 -0.057029 +-0.033167 -0.081758 -0.019502 0.033438 0.013365 +-0.017760 -0.025906 -0.020244 -0.078722 -0.011697 +-0.028246 0.068647 -0.106417 0.026956 -0.064914 +0.062711 -0.017857 0.151539 0.044613 -0.017820 +0.009085 -0.032785 -0.025795 0.075790 0.075667 +-0.040398 0.058556 -0.042634 0.093973 -0.099529 +0.057103 0.073562 0.012640 -0.066141 0.029558 +0.060219 -0.083699 -0.054799 -0.120442 -0.000374 +0.006521 0.034512 -0.039558 0.042191 0.033865 +0.103992 -0.014977 -0.077384 -0.051340 0.001873 +0.047451 0.140612 -0.024885 -0.021420 -0.046604 +0.030606 0.100660 0.076356 -0.019288 -0.098570 +-0.114463 -0.010855 -0.034657 0.025618 -0.003356 +-0.087913 0.064346 -0.075540 -0.091569 -0.024965 +-0.021232 -0.017255 -0.056931 -0.003104 0.030219 +-0.020112 -0.012334 0.035298 0.001405 0.161753 +-0.064618 -0.064401 -0.007218 -0.000120 -0.047208 +0.116105 -0.056464 -0.069645 -0.007032 -0.012090 +-0.023237 0.016000 -0.039802 0.074319 -0.012604 +0.014863 -0.058081 0.093219 0.062253 -0.040302 +0.027405 -0.128683 0.039923 0.116808 -0.011706 +0.012483 -0.017698 0.003645 -0.007588 -0.120662 +-0.032868 0.066217 -0.031343 -0.034166 0.146334 +-0.031228 -0.125921 0.117756 -0.042686 -0.062094 +0.049375 -0.112262 0.010166 -0.073599 0.048690 +0.028292 0.020076 -0.062865 -0.106114 -0.025300 +0.066916 0.029279 0.028191 -0.003599 -0.040614 +0.020491 0.060238 0.052747 -0.010390 -0.022389 +-0.063358 -0.028707 0.035907 -0.011898 0.079703 +-0.003758 0.078051 -0.017869 0.009045 -0.018982 +0.034974 0.069405 -0.018909 -0.038613 0.083909 +0.033935 -0.036607 0.088891 -0.052599 -0.059839 +0.052758 -0.068308 -0.063615 0.126093 -0.009460 +-0.042175 -0.011113 -0.073071 0.052086 -0.052619 +0.049226 0.066898 -0.045666 0.117923 0.053656 +-0.010739 -0.043962 0.141903 0.001792 -0.035469 +0.090671 0.043993 -0.013655 0.018989 0.127223 +0.001030 -0.001154 0.081839 -0.024979 -0.103704 +-0.077920 0.036083 0.068220 -0.062210 0.113730 +-0.010501 -0.065801 0.050885 -0.104304 0.121937 +0.111850 0.009680 -0.011791 0.001677 -0.035029 +0.010677 0.024572 -0.012860 -0.030323 -0.010466 +0.011279 0.167752 0.003136 0.109709 0.007292 +0.000987 0.004572 0.108706 -0.113192 -0.012431 +-0.015225 0.073653 -0.051275 0.077928 -0.012752 +-0.011708 0.014172 0.025162 -0.095378 0.026382 +-0.028889 -0.058569 -0.129329 0.011087 0.061452 +0.056893 -0.058004 0.103586 -0.060752 0.081824 +-0.042805 -0.015991 -0.024444 0.028952 -0.013528 +0.042851 0.019988 -0.165741 -0.031012 -0.014713 +-0.026059 0.031698 -0.134343 0.032090 0.020828 +0.051674 -0.128006 0.050856 0.022220 -0.073513 +-0.009340 0.013756 0.036163 0.098407 -0.023495 +0.023858 0.008121 0.022220 -0.103489 -0.046663 +-0.033000 0.063565 0.029224 -0.012693 0.084202 +0.012187 -0.051000 0.026126 -0.043293 0.008675 +-0.019812 -0.165070 -0.014555 -0.047431 0.017990 +-0.040073 0.107192 0.022228 -0.089023 -0.066885 +0.014630 0.073186 0.069902 0.072634 0.019593 +-0.041539 0.031788 0.092310 0.027223 0.034027 +-0.051855 0.000391 0.007869 0.131910 0.069384 +0.046276 0.040440 -0.037093 -0.031393 -0.112828 +0.015709 0.096749 -0.103205 -0.021284 0.011405 +0.158287 -0.021028 0.042219 -0.050759 0.069715 +-0.042907 -0.116980 0.014224 0.094648 0.028395 +0.041535 -0.057033 -0.047607 -0.024419 -0.034905 +0.010125 0.036728 -0.052503 -0.001839 -0.033477 +-0.053414 -0.070394 0.092895 0.100600 -0.026352 +0.080574 -0.028763 -0.059548 0.094571 0.091787 +0.041437 0.014312 0.045792 0.108269 -0.081586 +0.056288 0.137447 0.054718 -0.032474 0.054502 +-0.100144 -0.006460 0.024739 -0.117043 -0.008919 +0.070299 -0.036862 -0.014543 0.024500 -0.015222 +0.114975 -0.043705 0.000421 -0.061872 -0.035148 +-0.022797 0.128575 -0.031798 -0.086718 -0.007172 +-0.071706 -0.006833 0.028645 -0.007011 -0.096745 +-0.142269 0.027996 0.065210 0.061381 0.000741 +-0.140531 0.017480 -0.014986 -0.040893 -0.012718 +-0.012494 -0.021869 -0.032923 0.016456 0.104475 +0.010792 -0.066178 0.019097 -0.001893 0.067513 +-0.092673 -0.059851 -0.045936 0.052642 -0.062500 +0.065013 -0.025659 -0.149301 0.051705 0.035692 +-0.045790 -0.007482 -0.069141 0.149365 -0.042039 +0.018492 -0.081315 0.055880 0.058158 0.019669 +0.063836 -0.012391 0.007057 0.155454 0.033854 +-0.016532 -0.007661 0.043113 -0.080283 -0.108670 +-0.029344 0.093781 -0.015840 -0.068134 0.091804 +0.004148 -0.058507 0.059633 -0.095883 -0.004939 +0.086151 -0.113571 -0.019466 -0.009167 0.003662 diff --git a/gr-vocoder/lib/codec2/codebook/lspvqanssi1.txt b/gr-vocoder/lib/codec2/codebook/lspvqanssi1.txt new file mode 100644 index 0000000000..0b9dd90205 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspvqanssi1.txt @@ -0,0 +1,257 @@ +10 256 +0.5862 0.7213 0.9146 1.0909 1.2910 1.4954 1.8370 2.0840 2.3771 2.5518 +0.0871 0.2049 0.5849 0.8552 1.2096 1.4686 1.8210 2.0926 2.4508 2.7389 +0.2274 0.3126 0.6088 0.8338 1.1824 1.5948 1.8228 1.9856 2.1832 2.4793 +0.1827 0.2706 0.5842 0.7761 1.0301 1.2462 1.6313 1.9786 2.3479 2.6790 +0.3055 0.3863 0.7194 1.1609 1.3303 1.5017 1.7265 1.9412 2.4659 2.6315 +0.1794 0.2522 0.5477 0.7892 1.3887 1.7101 1.9471 2.1667 2.4361 2.6310 +0.1825 0.2729 0.4185 0.6024 1.2531 1.7291 1.9937 2.1849 2.5865 2.7748 +0.3219 0.4045 0.7357 1.2708 1.4626 1.6439 1.9388 2.1212 2.5005 2.6749 +0.2234 0.3496 0.5054 0.6981 0.8672 1.0431 1.7091 2.0690 2.3290 2.6195 +0.3009 0.3957 0.7576 0.9751 1.1955 1.7727 2.0383 2.2474 2.5612 2.7188 +0.3841 0.5544 0.9209 1.1811 1.5441 1.8126 2.1175 2.3192 2.5486 2.6935 +0.2153 0.3105 0.5597 0.8313 1.2168 1.4512 1.7012 1.8962 2.3893 2.5852 +0.3196 0.4814 0.7629 1.0869 1.5517 1.7780 2.0462 2.2547 2.5023 2.6706 +0.1964 0.3055 0.4307 0.7178 1.4260 1.6240 1.8392 2.0576 2.2976 2.5492 +0.4260 0.6888 1.2019 1.4194 1.6437 1.8221 2.0469 2.2508 2.5142 2.6795 +0.3004 0.3944 0.5847 1.0050 1.1812 1.3559 1.5479 1.7847 2.4924 2.6703 +0.1595 0.2398 0.4336 0.9228 1.2602 1.5064 1.7915 1.9840 2.2320 2.5692 +0.1832 0.2985 0.4205 0.5980 0.7620 0.9894 1.7499 2.1151 2.4814 2.7214 +0.2234 0.3207 0.5457 0.9799 1.2074 1.7079 1.9734 2.1742 2.4575 2.6366 +0.3598 0.4819 0.6385 0.8878 1.3226 1.4910 1.7257 1.9456 2.2061 2.4579 +0.4671 0.5911 0.8513 1.0923 1.5104 1.7043 1.9727 2.1839 2.4484 2.6111 +0.2418 0.3937 0.5420 0.8971 1.1152 1.3054 1.7928 1.9796 2.5441 2.7572 +0.3541 0.4730 0.6546 0.9063 1.0792 1.2743 1.8545 2.0555 2.3083 2.5404 +0.3121 0.4016 0.7137 0.8835 1.0736 1.5907 1.8624 2.0857 2.5075 2.6668 +0.2232 0.3631 0.5273 0.7438 1.0492 1.2235 1.5449 2.2198 2.5160 2.6852 +0.2557 0.3528 0.5051 0.6528 0.8351 1.5688 1.8838 2.1056 2.4401 2.6111 +0.4342 0.5318 0.9234 1.1146 1.3015 1.5198 1.8211 2.0340 2.3694 2.5506 +0.4310 0.5269 0.7431 0.9018 1.0734 1.5196 1.8267 2.0244 2.4508 2.6177 +0.2150 0.3249 0.4966 0.9434 1.1627 1.3497 1.8003 2.0045 2.3567 2.5909 +0.2798 0.4111 0.5786 0.7971 1.0414 1.2142 1.6947 2.0866 2.3351 2.5545 +0.1688 0.2693 0.4004 0.6337 1.3058 1.5064 1.7535 1.9689 2.5542 2.7424 +0.4419 0.6209 1.0127 1.2135 1.4104 1.6111 1.8820 2.1005 2.4238 2.5966 +0.3645 0.5120 0.8977 1.2209 1.5286 1.7204 1.9787 2.1779 2.4390 2.6114 +0.2897 0.4136 0.5504 0.8515 1.2641 1.4334 1.8079 2.0656 2.3509 2.7593 +0.1611 0.4723 0.7420 1.0071 1.2571 1.5891 1.9224 2.2345 2.5647 2.7991 +0.2528 0.4178 0.8909 1.3117 1.6622 1.8641 2.1017 2.2974 2.5299 2.6982 +0.1749 0.2700 0.4116 0.6036 1.1430 1.7776 2.0394 2.2220 2.4667 2.6598 +0.3451 0.4325 0.6194 0.7406 0.9176 1.5540 1.8426 2.0479 2.4401 2.5965 +0.3672 0.5164 0.6558 0.8441 1.2332 1.4114 1.6955 2.0875 2.3674 2.5471 +0.2194 0.3467 0.7384 1.1079 1.5398 1.8437 2.1212 2.3296 2.5800 2.7403 +0.1525 0.2343 0.3915 0.6843 1.0517 1.5020 1.7905 1.9667 2.2027 2.6725 +0.3531 0.5908 0.7462 0.9441 1.2774 1.4743 1.8268 2.1059 2.4478 2.6484 +0.3611 0.4981 0.7598 0.9676 1.4024 1.6330 1.9094 2.1433 2.4408 2.6130 +0.2153 0.3366 0.4974 0.6693 1.1944 1.6791 1.9002 2.1105 2.4100 2.5922 +0.2421 0.3392 0.5123 0.9818 1.5411 1.7092 1.9989 2.1981 2.5659 2.7656 +0.2116 0.3250 0.4845 0.8021 1.0088 1.2158 1.8038 2.0223 2.2975 2.5810 +0.1902 0.2942 0.8003 1.1086 1.3606 1.6008 1.8956 2.1328 2.4481 2.6405 +0.2772 0.3914 0.5826 0.7654 0.9495 1.1240 1.3949 2.0411 2.3891 2.5959 +0.2678 0.5220 0.7630 1.1000 1.3747 1.6432 1.9391 2.2237 2.5511 2.7893 +0.3200 0.4245 0.6174 0.9904 1.1662 1.3882 1.7601 1.9524 2.3998 2.5819 +0.1702 0.4871 0.8370 1.0989 1.3593 1.5830 1.8750 2.1277 2.4666 2.6885 +0.2280 0.3748 0.6554 0.9113 1.2081 1.4619 1.8181 2.0541 2.3791 2.5701 +0.1752 0.4363 0.6454 0.8798 1.1079 1.5367 1.8667 2.1716 2.4804 2.7249 +0.3804 0.4700 0.8224 1.0099 1.1892 1.5906 1.8879 2.0907 2.4544 2.6238 +0.1808 0.2910 0.4683 0.7059 0.8980 1.4031 1.7063 1.9444 2.4658 2.6776 +0.2418 0.3803 0.5443 0.7589 1.1496 1.3185 1.5451 1.7433 2.1310 2.6523 +0.2698 0.3690 0.5362 1.0732 1.2921 1.4696 1.7440 1.9470 2.5051 2.6841 +0.4099 0.5102 0.6983 1.0468 1.2459 1.4185 1.8851 2.0815 2.3464 2.5605 +0.0669 0.1354 0.3764 0.8433 1.1719 1.4834 1.8181 2.1312 2.4626 2.8044 +0.1614 0.2372 0.3878 0.5708 1.2759 1.4950 1.8052 2.0807 2.3485 2.6293 +0.1688 0.2875 0.4301 0.9059 1.2361 1.4054 1.8057 1.9924 2.5589 2.7495 +0.2864 0.3783 0.7032 1.0817 1.2382 1.5741 1.8619 2.0656 2.5139 2.6848 +0.3829 0.4781 0.6766 0.8340 1.0056 1.4147 1.6650 1.8840 2.3922 2.5619 +0.3259 0.4187 0.6139 0.7338 1.1831 1.6497 1.9000 2.1278 2.4322 2.5930 +0.2569 0.3790 0.5426 0.8390 0.9871 1.4850 1.8652 2.0732 2.4314 2.6005 +0.1408 0.2283 0.4024 0.8784 1.1485 1.4003 1.7004 1.9205 2.3723 2.6522 +0.2971 0.5039 0.8005 1.1212 1.4232 1.7801 2.1255 2.3907 2.6795 2.8487 +0.1515 0.2344 0.4684 0.8040 1.0401 1.3774 1.8329 2.1235 2.5555 2.7770 +0.5778 0.7157 0.8910 1.0966 1.4235 1.6482 1.9551 2.1831 2.4572 2.6234 +0.3017 0.4161 0.8088 0.9971 1.2000 1.4419 1.7867 2.0224 2.3473 2.5400 +0.1208 0.2814 0.6564 0.9448 1.2377 1.5663 1.9084 2.2112 2.5583 2.8155 +0.2127 0.3127 0.4635 0.6416 0.8449 1.6652 2.0577 2.2656 2.5811 2.7434 +0.1942 0.3011 0.4212 0.6901 1.5369 1.7639 1.9608 2.1766 2.4435 2.6663 +0.3510 0.4345 0.7146 0.9086 1.0678 1.2579 1.4425 2.0265 2.4574 2.6252 +0.3225 0.4323 0.6168 0.8580 1.5388 1.7910 1.9927 2.2013 2.4494 2.6160 +0.2271 0.4488 0.6287 0.7857 1.2086 1.3830 1.6194 2.1955 2.5236 2.6945 +0.2568 0.3510 0.5613 1.0500 1.2521 1.4359 1.6995 1.9187 2.2148 2.4275 +0.2933 0.3941 0.6128 0.8899 1.0720 1.2862 1.5331 1.8301 2.1553 2.3865 +0.3480 0.4626 0.6009 0.7630 0.9044 1.1225 1.8539 2.1845 2.5035 2.7091 +0.1337 0.4722 0.8099 1.1273 1.4252 1.6990 2.0188 2.2922 2.6018 2.8168 +0.1138 0.3263 0.8059 1.0473 1.3262 1.6202 1.9439 2.2007 2.5347 2.7702 +0.1979 0.3130 0.4635 0.8504 1.1143 1.3221 2.0371 2.2421 2.5406 2.7491 +0.3321 0.4194 0.8239 1.0458 1.1981 1.3733 1.5661 1.9985 2.3747 2.5416 +0.3729 0.5958 0.9551 1.2650 1.5484 1.9255 2.2256 2.4809 2.7276 2.8935 +0.1664 0.2516 0.5347 0.7545 1.1971 1.4089 1.7400 2.0871 2.4098 2.6795 +0.2370 0.3178 0.6123 1.3315 1.5470 1.7257 2.0063 2.1977 2.5449 2.7252 +0.2030 0.3328 0.4766 0.7357 1.2780 1.4439 1.7229 1.9405 2.2278 2.6816 +0.1702 0.2919 0.4598 0.7123 0.9077 1.1450 1.8632 2.0806 2.4990 2.7100 +0.2421 0.3578 0.5400 0.7217 0.8971 1.4898 1.8518 2.1205 2.6077 2.7894 +0.3030 0.3935 0.5812 0.7404 0.9425 1.8342 2.0887 2.2811 2.5596 2.7118 +0.1322 0.1997 0.3466 0.6981 1.1811 1.4849 1.8594 2.1114 2.4708 2.7804 +0.2317 0.3069 0.6860 1.4306 1.7121 1.8671 2.1249 2.2995 2.5705 2.7456 +0.3778 0.4863 0.6639 0.9163 1.1560 1.3186 1.5389 1.7169 2.1603 2.5797 +0.2118 0.3499 0.5259 0.7200 1.1348 1.3140 1.5657 2.0241 2.2873 2.5184 +0.2902 0.4368 0.6331 0.8971 1.3102 1.5219 1.8674 2.1512 2.4708 2.6809 +0.1418 0.3988 0.6251 0.8544 1.1268 1.3964 1.7585 2.0322 2.3964 2.6928 +0.2314 0.3462 0.7282 0.9211 1.1766 1.4941 1.7368 1.9546 2.5170 2.7066 +0.2076 0.3251 0.7423 0.9590 1.1936 1.5329 1.8887 2.1588 2.4667 2.6709 +0.2058 0.4139 0.5745 0.7832 0.9595 1.1688 1.7561 1.9562 2.4840 2.7001 +0.1834 0.2971 0.4643 0.6625 0.8802 1.1137 1.5183 1.8417 2.3842 2.7042 +0.1688 0.4218 0.7070 1.0465 1.4496 1.6953 1.9560 2.2174 2.5172 2.7404 +0.2323 0.3981 0.5489 0.7227 1.2886 1.5221 1.7158 2.1184 2.4066 2.5898 +0.3470 0.5265 0.8140 1.0152 1.3206 1.5411 1.8490 2.0588 2.3556 2.5393 +0.1707 0.2595 0.6762 0.9037 1.2781 1.4903 1.7946 2.0610 2.3741 2.5771 +0.1457 0.2318 0.6039 1.0078 1.3461 1.5908 1.8818 2.1248 2.4432 2.6714 +0.6574 0.8086 1.0243 1.2183 1.4837 1.7129 2.0197 2.2464 2.5059 2.6716 +0.2546 0.4983 0.8674 1.2536 1.6704 1.9529 2.2134 2.4319 2.6532 2.8109 +0.2455 0.3379 0.4632 0.8635 1.5286 1.8047 1.9909 2.1806 2.4031 2.5729 +0.4772 0.6742 1.0000 1.2474 1.5288 1.7415 2.0102 2.2168 2.4770 2.6449 +0.3357 0.4382 0.6033 1.1317 1.3681 1.5576 1.9251 2.1119 2.5548 2.7395 +0.2588 0.7015 0.8953 1.0830 1.2828 1.5160 1.8965 2.1921 2.5150 2.7258 +0.2466 0.3512 0.5047 0.6646 0.8161 1.2577 1.8046 2.0214 2.4447 2.6491 +0.1631 0.2283 0.4070 0.5955 1.1126 1.3894 1.8978 2.1849 2.5384 2.7382 +0.3424 0.4748 0.6222 0.8020 0.9706 1.1568 1.7044 1.9297 2.2127 2.5627 +0.2088 0.5143 0.7400 0.9277 1.1032 1.3561 1.8841 2.2004 2.5882 2.7993 +0.2016 0.3488 0.5894 0.7419 1.1488 1.3626 1.5566 1.9694 2.5488 2.7209 +0.2558 0.3914 0.5360 0.7521 1.4330 1.6955 1.8886 2.1428 2.4190 2.5966 +0.4021 0.5034 0.6653 0.8123 0.9586 1.2825 1.9184 2.1120 2.4090 2.5970 +0.2343 0.4800 0.6934 0.8523 1.2786 1.4763 1.7235 2.0400 2.3602 2.5562 +0.2460 0.3687 0.5325 0.7044 1.1488 1.3608 1.8112 2.0757 2.4183 2.6630 +0.1616 0.3644 0.5725 0.9166 1.2481 1.4938 1.8388 2.1175 2.4712 2.7464 +0.3760 0.4841 0.6350 1.0082 1.2110 1.4003 1.8127 2.0018 2.5199 2.7238 +0.1988 0.2824 0.6553 1.0337 1.5413 1.7369 1.9751 2.1751 2.4372 2.6265 +0.2728 0.4094 0.7498 1.0645 1.3516 1.5946 1.9910 2.2172 2.4830 2.6614 +0.1657 0.5327 0.7281 0.9966 1.2385 1.4629 1.8119 2.0973 2.4469 2.6979 +0.1413 0.2098 0.3540 0.5492 0.8486 1.1288 1.6320 1.9056 2.2805 2.5438 +0.2856 0.3666 0.6259 1.1424 1.6605 1.8197 2.0147 2.1986 2.4121 2.5919 +0.2725 0.4829 0.7650 1.0119 1.2977 1.5488 1.8755 2.1155 2.4383 2.6377 +0.2736 0.3804 0.5537 1.0258 1.2269 1.4186 1.9718 2.1468 2.5665 2.7689 +0.2341 0.5953 1.1030 1.4549 1.7361 1.9758 2.2126 2.4213 2.6405 2.8181 +0.2273 0.4638 0.6228 0.8500 1.1016 1.2823 1.7094 1.9523 2.2669 2.7029 +0.2438 0.3798 0.7299 0.9600 1.3765 1.6104 1.8644 2.1161 2.5073 2.7137 +0.1551 0.4869 0.8676 1.2274 1.5069 1.8857 2.1868 2.4411 2.7106 2.8767 +0.2746 0.5454 0.7589 0.9458 1.1597 1.3349 1.6653 2.1142 2.4356 2.6239 +0.1793 0.2646 0.4344 0.7482 1.1502 1.3733 1.8558 2.0817 2.3248 2.5171 +0.2698 0.4202 0.5765 0.8301 1.0073 1.2101 1.9714 2.2051 2.5138 2.7395 +0.1929 0.3091 0.4460 0.6266 1.1805 1.3672 1.5990 2.1514 2.4729 2.6468 +0.1901 0.3047 0.4607 1.1019 1.3168 1.5343 1.9234 2.1365 2.5924 2.7807 +0.3139 0.5009 0.6700 0.8268 1.0117 1.1810 1.6539 2.1984 2.4828 2.6576 +0.1403 0.2173 0.4117 0.7302 1.0038 1.2732 1.7392 2.0337 2.3809 2.7386 +0.4166 0.5101 0.7449 1.1663 1.3492 1.5543 1.9000 2.0941 2.4588 2.6365 +0.3342 0.4335 0.6160 0.8559 1.0112 1.2097 1.4029 1.6361 2.4129 2.6324 +0.4543 0.6159 0.7932 0.9843 1.2562 1.4308 1.7116 1.9919 2.2671 2.4631 +0.2153 0.3609 0.5302 0.7089 0.8756 1.0376 1.6496 2.2826 2.5680 2.7441 +0.4380 0.6439 0.8282 1.0651 1.3650 1.5829 1.8838 2.1005 2.4006 2.5771 +0.2523 0.3636 0.5879 1.1628 1.3542 1.6756 2.0488 2.2543 2.6093 2.7953 +0.4179 0.5426 0.7065 0.8996 1.0684 1.3146 1.9705 2.2021 2.5051 2.7061 +0.1659 0.2860 0.6693 0.9229 1.3959 1.6544 1.9709 2.2257 2.5236 2.7460 +0.2540 0.4356 0.5946 0.7627 1.2274 1.4222 1.6573 1.9601 2.2514 2.4711 +0.1633 0.2337 0.3698 0.5421 1.1757 1.5916 2.1561 2.3371 2.5534 2.7737 +0.1953 0.2730 0.4521 1.2005 1.7062 1.8627 2.1313 2.3266 2.5906 2.7667 +0.3053 0.4054 0.5651 0.7470 0.8910 1.1720 1.8864 2.1074 2.3705 2.5744 +0.1761 0.3033 0.6501 0.8268 1.0369 1.2687 1.8534 2.1889 2.5074 2.7339 +0.2265 0.3990 1.1359 1.4137 1.6839 1.8912 2.0948 2.3042 2.5489 2.7234 +0.3326 0.5400 0.8711 1.0948 1.3752 1.6155 1.9360 2.1537 2.4451 2.6133 +0.2162 0.3522 0.5309 0.7470 0.9677 1.1747 1.5056 1.7942 2.1615 2.4800 +0.1872 0.2761 0.4053 0.7469 1.5858 1.8945 2.1198 2.3197 2.5819 2.7758 +0.5381 0.8651 1.2695 1.4918 1.7774 1.9696 2.1865 2.3687 2.5739 2.7158 +0.2663 0.3422 0.6098 1.2120 1.4516 1.6092 1.8506 2.0376 2.2929 2.5088 +0.1904 0.3051 0.5663 0.7391 1.1589 1.5705 1.8756 2.1653 2.5518 2.7693 +0.1543 0.3519 0.6976 1.0664 1.3696 1.7817 2.1308 2.4259 2.7070 2.8753 +0.3304 0.4283 0.5942 0.7425 0.8906 1.4067 2.0676 2.2460 2.5394 2.7006 +0.2080 0.3215 0.6278 0.7882 1.3123 1.5592 1.8048 2.0831 2.4303 2.6266 +0.1188 0.2481 0.8270 1.2420 1.5824 1.8976 2.1816 2.4248 2.6645 2.8459 +0.0635 0.1528 0.5973 0.9377 1.2653 1.5465 1.8818 2.1681 2.5089 2.7924 +0.3249 0.5179 0.9143 1.2973 1.4966 1.7550 2.0715 2.3166 2.6500 2.8305 +0.1918 0.3107 0.4506 0.6994 1.3463 1.5348 1.8447 2.1903 2.4480 2.6877 +0.3405 0.4644 0.7232 0.9199 1.2611 1.5175 1.8446 2.0652 2.3915 2.5781 +0.3289 0.5152 0.6602 1.0213 1.1886 1.5496 1.9553 2.1883 2.5394 2.7362 +0.3000 0.4097 0.8372 1.0793 1.3095 1.5684 1.8746 2.0783 2.3643 2.5490 +0.2421 0.3280 0.5288 0.9261 1.6911 1.8959 2.1013 2.2823 2.5238 2.6960 +0.1070 0.3131 0.6226 0.8881 1.1808 1.4867 1.8146 2.1088 2.4594 2.7186 +0.4400 0.5533 0.7025 0.9206 1.4089 1.5820 1.8080 2.0832 2.3577 2.5300 +0.2250 0.3434 0.4808 0.6721 0.8198 1.1446 2.0201 2.2625 2.5520 2.7604 +0.1671 0.2551 0.4603 0.6777 0.9661 1.5579 1.8659 2.1196 2.4425 2.6551 +0.3910 0.5877 1.0287 1.3547 1.6899 1.9166 2.1451 2.3337 2.5519 2.7071 +0.1435 0.2165 0.3968 0.8376 1.2572 1.5298 1.8791 2.1352 2.4636 2.7011 +0.1756 0.2799 0.4120 0.5808 0.7573 1.3340 1.8235 2.1200 2.4993 2.7365 +0.1332 0.2174 0.4716 0.9483 1.2723 1.6028 1.9272 2.2190 2.5588 2.7990 +0.2122 0.3143 0.7042 0.8849 1.1312 1.3711 1.6832 1.9633 2.2685 2.5156 +0.2089 0.3339 0.4817 0.8526 1.0657 1.2741 1.5747 1.8000 2.4860 2.6843 +0.1636 0.2617 0.4400 0.7357 1.0355 1.2638 1.5672 1.8504 2.1904 2.6588 +0.1945 0.2934 0.4869 0.8567 1.1262 1.3604 1.6898 1.9143 2.1475 2.3503 +0.1606 0.2442 0.3931 0.9237 1.5811 1.7529 2.0133 2.2272 2.5250 2.7265 +0.4866 0.7045 1.0593 1.2795 1.5326 1.8221 2.1461 2.3665 2.6041 2.7599 +0.4012 0.4911 0.7103 0.8585 1.0495 1.7244 2.0116 2.2041 2.5189 2.6643 +0.4365 0.6694 0.8644 1.1330 1.4510 1.7627 2.1032 2.3690 2.6280 2.8306 +0.2072 0.4018 0.6227 0.8913 1.3038 1.6056 1.9704 2.2816 2.6135 2.8182 +0.3302 0.4968 0.8713 1.0761 1.2576 1.4654 1.8152 2.1400 2.5404 2.7493 +0.1385 0.2292 0.3530 0.6006 1.4699 1.6571 1.9438 2.1663 2.5027 2.7308 +0.1894 0.2915 0.4345 0.6341 1.0024 1.1896 1.6896 2.0966 2.4086 2.6768 +0.3841 0.5197 0.8889 1.1480 1.4383 1.6285 1.8642 2.0669 2.3466 2.5325 +0.2008 0.3097 0.4664 0.6638 1.2798 1.4940 1.7270 2.0264 2.2915 2.4750 +0.1864 0.2857 0.4481 1.1025 1.3096 1.5035 1.7614 1.9891 2.4255 2.6031 +0.4081 0.6134 0.9514 1.1818 1.3943 1.6361 1.9891 2.2395 2.5547 2.7287 +0.2964 0.3876 0.9450 1.2247 1.3906 1.5882 1.8241 2.0589 2.4188 2.5871 +0.3127 0.4038 0.6168 1.0810 1.3067 1.4759 1.8817 2.0781 2.3394 2.5539 +0.2066 0.3059 0.4989 0.7132 0.9066 1.4460 1.7584 1.9755 2.2210 2.4741 +0.2634 0.3956 0.5667 0.8777 1.0517 1.6029 2.0590 2.2607 2.6064 2.7647 +0.4331 0.5315 0.7764 1.0444 1.2269 1.4311 1.7093 1.9187 2.4337 2.6149 +0.2161 0.4429 0.6851 0.8336 1.1037 1.2966 1.5283 2.0299 2.3407 2.5384 +0.2814 0.3637 0.5416 0.9475 1.5137 1.6945 1.8892 2.1017 2.3190 2.5007 +0.4454 0.6883 1.1402 1.4098 1.7435 2.0014 2.2521 2.4457 2.6495 2.7985 +0.1641 0.4083 0.6426 1.0592 1.3258 1.5754 1.8666 2.1381 2.4572 2.7177 +0.3391 0.4607 0.6072 0.8463 1.4207 1.6062 1.8303 2.0887 2.3615 2.5348 +0.2414 0.3396 0.5100 0.7470 1.3329 1.8618 2.0751 2.2564 2.5147 2.6874 +0.1694 0.2535 0.4156 0.8302 1.2853 1.5838 2.0907 2.3085 2.5929 2.7951 +0.2047 0.3652 0.6500 0.8068 1.0178 1.1865 1.4889 2.0671 2.5966 2.7634 +0.2425 0.3247 0.6020 1.2226 1.4272 1.5996 1.8377 2.0413 2.5333 2.7021 +0.3842 0.5030 0.6541 0.8771 1.0576 1.2612 1.6744 1.8735 2.4781 2.6803 +0.2042 0.3280 0.7283 0.8985 1.1444 1.3299 1.6032 2.1539 2.4739 2.6547 +0.1268 0.1924 0.3208 0.5153 1.1304 1.4443 1.8047 2.0552 2.4385 2.7572 +0.2713 0.3659 0.5395 1.0705 1.4228 1.5836 1.9763 2.1641 2.4459 2.6301 +0.3047 0.4043 0.5727 0.7368 0.8997 1.3242 1.6473 1.8879 2.4330 2.6295 +0.1224 0.3948 0.6903 0.9199 1.2852 1.5516 1.8645 2.1231 2.4657 2.7044 +0.2157 0.3281 0.5036 0.9272 1.0975 1.5285 1.8080 2.0569 2.5448 2.7221 +0.1670 0.2490 0.3696 0.5921 1.3019 1.8398 2.2165 2.3725 2.6142 2.8338 +0.3899 0.5573 0.8100 1.0732 1.3966 1.6598 2.0001 2.2517 2.5548 2.7403 +0.4905 0.6064 0.8222 0.9966 1.1912 1.5714 1.9628 2.1727 2.5300 2.7055 +0.1309 0.2342 0.6232 0.8795 1.1283 1.3655 1.7371 2.0251 2.3992 2.6885 +0.1805 0.2672 0.4297 1.2440 1.4967 1.6796 1.9592 2.1784 2.5439 2.7289 +0.2280 0.5429 0.6967 0.8732 1.4074 1.6074 1.9516 2.2124 2.5486 2.7722 +0.2339 0.3379 0.4924 0.9061 1.3074 1.4719 1.8884 2.1110 2.3618 2.5545 +0.1384 0.2291 0.5127 1.0450 1.4017 1.7884 2.1134 2.3664 2.6588 2.8435 +0.2196 0.6359 0.9100 1.2007 1.4589 1.7053 2.0128 2.2722 2.5520 2.7643 +0.1698 0.2615 0.3810 0.5706 1.4297 1.8686 2.0728 2.2559 2.4860 2.6701 +0.1445 0.2158 0.3658 0.5451 0.9389 1.3669 1.7900 2.0846 2.3924 2.7161 +0.2789 0.3816 0.5277 0.8487 1.3751 1.5461 1.7832 2.0264 2.2695 2.4665 +0.1733 0.3023 0.9216 1.2368 1.4776 1.7229 1.9952 2.2471 2.5390 2.7265 +0.3374 0.5033 1.0951 1.3262 1.5284 1.7336 1.9733 2.2009 2.4992 2.6751 +0.1293 0.2743 0.7533 1.0166 1.2416 1.4444 1.7962 2.0851 2.4770 2.7204 +0.3106 0.4176 0.6358 0.9434 1.1419 1.3458 1.9638 2.1678 2.4390 2.6235 +0.4533 0.5760 0.7392 0.9136 1.0829 1.2759 1.7903 2.0360 2.3124 2.5325 +0.3702 0.5218 0.6977 0.8776 1.1096 1.2855 1.5612 1.9480 2.2170 2.4361 +0.1637 0.2647 0.4185 0.6666 1.1584 1.3270 1.7829 1.9821 2.4361 2.7094 +0.1769 0.2767 0.3942 0.5746 1.3595 1.7110 1.9176 2.1405 2.3722 2.5705 +0.2712 0.3820 0.6524 0.8317 1.0341 1.3972 1.7312 1.9918 2.3854 2.5886 +0.1003 0.2046 0.7261 1.1004 1.4057 1.6697 1.9903 2.2603 2.5813 2.8009 +0.2534 0.3752 0.7192 0.9323 1.3698 1.5955 1.8653 2.0656 2.3368 2.5340 +0.3589 0.4508 0.6631 1.0521 1.5065 1.6697 1.8929 2.1074 2.3466 2.5242 +0.1955 0.2862 0.6111 0.8053 1.0501 1.5218 1.7996 2.0303 2.3788 2.5973 +0.2982 0.4033 0.5660 0.8924 1.1933 1.3465 1.7895 2.0173 2.2606 2.5069 +0.3356 0.4711 0.6310 0.8491 1.0049 1.4364 1.8176 2.0292 2.5710 2.7525 +0.2016 0.2912 0.4363 0.9800 1.4897 1.6494 1.8862 2.0819 2.3636 2.6091 +0.4549 0.6491 0.8450 1.0209 1.1747 1.3745 1.8824 2.1130 2.3760 2.5768 +0.2510 0.3524 0.5171 0.8931 1.4094 1.5710 1.8536 2.0478 2.4766 2.7320 +0.1576 0.2547 0.3891 0.8551 1.4282 1.5880 1.8583 2.0521 2.5359 2.7340 +0.3481 0.4382 0.7720 1.1289 1.3203 1.5019 1.7665 1.9570 2.2231 2.4465 +0.3116 0.4068 0.6991 0.8894 1.0912 1.5356 1.8084 2.0006 2.2323 2.4367 +0.2706 0.4033 0.8272 1.0851 1.4820 1.6927 1.9292 2.1267 2.4049 2.5857 +0.2745 0.3550 0.8663 1.3742 1.5545 1.7324 1.9664 2.1538 2.4581 2.6245 +0.1736 0.2553 0.5357 0.9009 1.1888 1.5132 1.8579 2.1181 2.4273 2.6847 +0.3026 0.4148 0.9044 1.1695 1.3657 1.7036 1.9891 2.2226 2.5441 2.7085 +0.3998 0.5108 0.7205 0.9848 1.1828 1.3716 1.7154 1.9191 2.1875 2.4257 +0.2141 0.3095 0.7428 1.0426 1.2851 1.5571 1.7901 1.9804 2.2462 2.5265 +0.1574 0.2290 0.3869 0.5735 1.0925 1.3383 1.6598 1.9364 2.2095 2.4195 diff --git a/gr-vocoder/lib/codec2/codebook/lspvqanssi2.txt b/gr-vocoder/lib/codec2/codebook/lspvqanssi2.txt new file mode 100644 index 0000000000..607cb47a9f --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspvqanssi2.txt @@ -0,0 +1,129 @@ +10 128 +0.0120 0.0022 0.0068 -0.0112 -0.0508 -0.0490 0.2249 0.1476 0.0133 -0.0379 +0.0598 0.0477 0.0380 0.0660 0.0517 0.0150 0.0617 0.0081 -0.0768 -0.1007 +-0.0087 -0.0440 0.0873 0.0882 0.0391 -0.0060 0.1100 0.0569 -0.0241 -0.0468 +0.0146 -0.0005 0.0322 -0.0650 -0.0778 -0.0780 -0.0255 -0.0527 -0.0301 -0.0401 +-0.0240 -0.0560 -0.0374 0.0274 0.0484 -0.0227 0.0328 0.1135 0.0117 -0.0300 +-0.0324 -0.0574 0.0302 0.0137 -0.0603 -0.1194 -0.0105 -0.0513 0.0698 0.0538 +0.0635 0.0382 0.0531 0.0897 0.0495 0.0039 -0.0421 -0.0919 0.0407 0.0167 +0.0954 0.0854 0.0360 -0.0025 -0.0252 -0.0528 -0.0435 -0.0561 -0.0405 -0.0432 +0.0110 -0.0010 -0.0433 -0.0167 0.1402 0.0738 0.0423 -0.0024 -0.0920 -0.1099 +0.0179 0.0184 -0.0041 -0.0640 0.1004 0.0608 -0.0023 -0.0357 0.1509 0.1262 +-0.0145 -0.0240 -0.0595 -0.1063 0.0597 -0.0040 -0.0886 0.1184 0.0380 0.0126 +-0.0072 0.0172 0.0076 0.0288 0.0810 0.0278 0.0709 0.0051 0.0214 -0.0301 +0.0127 -0.0126 -0.0434 0.1610 0.1178 0.0704 0.0257 -0.0073 -0.0425 -0.0610 +-0.0165 -0.0369 -0.0785 0.1007 0.0309 -0.0651 0.0142 -0.0614 0.0426 0.0289 +-0.0374 -0.0712 0.0049 -0.0382 0.0472 0.0095 -0.0268 -0.0747 -0.0457 -0.0758 +-0.0211 -0.0432 -0.0547 -0.0446 -0.1078 0.0090 -0.0565 -0.1298 0.0721 0.0351 +-0.0014 -0.0072 -0.0283 -0.0324 -0.0208 -0.0703 0.0979 0.0865 -0.0007 0.1881 +-0.0077 -0.0302 0.1231 0.0905 0.0786 0.0432 -0.0286 -0.0661 -0.0055 -0.0275 +0.0010 0.0043 0.0044 0.0380 -0.1201 -0.0098 -0.0166 0.0105 0.0153 0.0134 +0.0843 0.0636 0.0416 -0.0004 -0.0570 -0.0592 0.1158 0.0590 0.0126 0.0034 +0.0346 0.0290 -0.0037 -0.0026 -0.0457 0.1824 0.1469 0.0870 0.0291 -0.0074 +0.0066 0.0682 -0.0148 0.0287 0.0095 -0.0563 0.1296 0.0426 0.1215 0.0886 +-0.0132 -0.0399 0.0960 0.0474 0.0140 0.0306 -0.0192 -0.0703 -0.1559 -0.1556 +-0.0600 0.0482 0.1257 0.0521 0.0229 -0.0031 0.0817 0.0571 -0.0138 -0.0277 +0.0013 -0.0103 -0.0470 -0.0687 -0.1444 0.0181 0.1350 0.0559 -0.0177 -0.0598 +-0.0215 -0.0318 -0.0689 -0.0268 0.0917 0.0307 0.0135 -0.0184 -0.0857 0.1231 +0.0137 -0.0152 0.0199 -0.0291 -0.0685 0.0438 -0.1137 0.0231 -0.0632 -0.0802 +-0.0011 0.0314 0.0535 -0.0135 -0.0291 -0.0579 -0.1049 0.0288 -0.0628 0.1355 +-0.0901 0.0041 -0.0170 0.0351 0.0144 -0.0505 0.0396 0.0638 -0.0145 0.0141 +-0.0400 -0.0603 -0.0714 0.0329 -0.0049 -0.0529 -0.1251 0.0022 -0.0449 -0.0778 +0.0247 0.0296 0.0239 0.0122 -0.0348 -0.1224 -0.0033 0.1237 -0.0016 -0.0436 +0.0246 0.0050 0.0322 0.0818 0.0203 0.0846 0.0022 0.0876 0.0149 -0.0184 +-0.0204 -0.0228 0.0365 -0.0164 0.1087 0.0374 -0.0550 0.0330 -0.0582 -0.0736 +-0.0305 -0.0485 -0.0572 0.0275 -0.0271 -0.0436 0.1217 0.0700 0.1253 0.0990 +-0.0079 -0.0204 -0.0325 0.0491 0.0158 -0.0365 -0.1309 -0.1812 0.1428 0.1148 +0.0680 0.0547 0.0309 0.0079 -0.0332 0.0391 -0.0287 0.1258 0.1123 0.1016 +-0.0264 -0.0409 -0.0538 -0.0192 -0.0393 -0.0713 -0.0618 -0.1078 -0.1850 0.0532 +0.0081 -0.0115 -0.0090 0.1201 -0.0413 -0.0995 0.0445 -0.0032 -0.0286 -0.0497 +-0.0023 -0.0184 -0.0358 0.1279 0.0847 0.0530 0.0230 -0.0212 0.1245 0.0965 +0.0111 0.1038 0.0597 0.0413 0.0533 0.0011 0.0031 0.0705 0.0242 0.0198 +0.0020 -0.0071 -0.0262 -0.0496 -0.0750 -0.1273 -0.1785 0.0606 -0.0223 -0.0583 +-0.0202 0.0669 0.0081 0.0335 -0.0218 -0.1073 -0.0146 -0.0673 0.0490 0.0210 +-0.0108 -0.0230 -0.0614 -0.0986 0.0629 0.0006 0.1496 0.1099 0.0316 0.0098 +-0.0368 -0.0685 0.0138 -0.0213 -0.0009 0.0344 -0.0249 0.0311 0.0803 0.0759 +0.0038 -0.0158 0.0142 0.0254 0.0970 0.0021 -0.1029 0.0006 0.0576 0.0261 +-0.0083 0.0698 0.0406 -0.0348 0.0200 0.0833 0.0186 -0.0145 -0.0725 -0.0872 +-0.0506 -0.0673 0.0776 -0.0172 -0.0444 -0.0531 -0.0799 0.0005 -0.0359 -0.0446 +0.0368 0.0376 -0.0407 -0.0190 0.0987 0.0212 -0.0349 -0.0951 -0.0084 -0.0342 +-0.0309 -0.0561 0.0950 -0.0125 -0.1028 -0.0133 0.0920 0.0965 0.0668 0.0409 +-0.0898 0.0036 -0.0353 -0.0024 -0.0365 -0.0259 -0.0485 -0.0843 -0.0063 -0.0167 +-0.0255 -0.0407 -0.0456 -0.0931 -0.0892 -0.0293 -0.0510 0.0183 -0.0104 0.0472 +-0.0172 -0.0399 -0.0731 0.0546 0.0320 -0.0283 0.0415 -0.0107 -0.1237 -0.1102 +0.0210 0.0294 -0.0038 -0.0090 -0.0551 -0.0922 0.0261 -0.0334 -0.1181 -0.1536 +0.0092 0.0032 -0.0162 0.0398 0.0205 0.1266 -0.0107 -0.0858 0.0392 0.0032 +-0.0038 -0.0269 -0.0737 0.1138 0.0263 -0.0031 -0.1188 0.1621 0.0831 0.0526 +0.0023 -0.0149 -0.0497 0.0898 0.0456 -0.0145 -0.0928 -0.1507 -0.0611 -0.0938 +0.0120 0.0124 -0.0286 -0.1319 0.0219 0.0311 -0.0398 -0.0465 -0.0008 -0.0375 +0.0138 0.0023 0.0024 0.1072 0.0531 0.0006 0.0292 -0.0115 -0.0620 0.1650 +0.0070 -0.0251 0.0715 0.0380 -0.0404 0.1230 0.0629 0.0096 0.0973 0.0641 +-0.0586 0.0772 0.0128 0.1060 0.0715 0.0374 -0.0074 -0.0365 -0.0543 -0.0489 +-0.0392 0.0871 -0.0069 -0.1084 0.0264 -0.0495 0.0396 0.0005 -0.0293 -0.0240 +-0.0327 0.0605 0.0662 0.0100 -0.0007 -0.0525 -0.0812 -0.0686 -0.0873 -0.0830 +0.0119 0.0058 0.0030 -0.0307 0.0650 0.0175 -0.0741 -0.1500 -0.1947 0.0881 +0.0572 0.0411 0.0152 -0.0127 -0.0589 -0.0510 -0.0212 -0.0834 0.1434 0.1318 +0.0518 0.0417 -0.0430 0.0963 -0.0014 0.0173 0.0234 -0.0273 0.0359 -0.0118 +0.0652 0.0587 0.0013 -0.0700 0.1262 0.0975 0.0680 0.0598 0.0048 -0.0305 +-0.0185 -0.0440 0.1178 0.0656 0.0052 -0.0534 -0.1151 0.1116 0.0659 0.0344 +0.0788 0.0577 0.0452 0.0283 -0.0278 0.0911 0.0280 -0.0254 0.0029 -0.0361 +-0.0165 -0.0322 -0.0526 -0.1057 0.0927 0.0293 -0.1026 -0.1671 0.0470 0.0355 +0.0100 0.0001 -0.0221 -0.0775 -0.1109 -0.1416 0.0884 0.0441 0.0632 0.0409 +0.0204 0.0432 0.0141 -0.0296 0.1073 0.0580 0.0383 0.0270 -0.0857 0.1246 +0.0488 0.0231 0.0648 -0.0179 0.0747 0.0156 -0.0384 -0.0733 -0.0732 -0.0970 +0.0005 -0.0199 -0.0260 -0.0511 -0.1110 0.0670 -0.0413 0.1571 0.0498 0.0191 +0.0037 -0.0085 -0.0796 0.0086 -0.0852 0.0850 0.0115 -0.0065 0.1161 0.0727 +0.0023 0.0483 0.0285 -0.0642 -0.0477 0.0175 0.0346 0.0452 0.0655 0.0284 +-0.0986 0.0463 0.0326 -0.0055 0.0702 0.0194 -0.0423 -0.0107 0.0338 0.0619 +0.0126 -0.0138 -0.1115 0.0159 -0.0331 0.0217 -0.0376 -0.0407 -0.0222 -0.0503 +0.0222 0.0071 -0.0490 0.1017 0.0551 -0.0164 0.1578 0.1059 0.0025 -0.0107 +0.0124 -0.0090 0.0322 0.0930 0.0281 -0.0403 -0.0781 0.0125 -0.0670 -0.1058 +0.0363 0.0077 0.1052 0.0039 0.0676 0.0891 0.0433 0.0252 0.0224 -0.0043 +-0.0045 -0.0194 -0.0193 -0.0480 -0.0640 -0.0695 -0.1597 -0.0030 0.1728 0.1231 +0.0297 0.0025 0.0619 -0.0347 -0.1171 0.1043 0.0868 0.0191 -0.0739 -0.1075 +0.0073 0.0914 0.0367 -0.0236 0.0232 0.0304 -0.0787 -0.1099 0.0460 0.0082 +0.0296 0.0297 -0.0444 0.0184 0.0602 -0.0295 -0.0934 0.0636 -0.0347 -0.0722 +-0.0290 -0.0629 0.0598 0.0013 0.0064 0.1431 0.0920 0.0468 -0.0311 -0.0614 +-0.0152 -0.0311 -0.0500 -0.0672 -0.1257 -0.0134 -0.0220 -0.0612 -0.1131 -0.1417 +0.0371 0.0153 -0.0817 -0.0007 0.0837 0.0481 0.0460 0.0678 0.0524 0.0432 +0.0126 -0.0069 -0.0092 -0.0693 -0.0250 0.1510 0.0098 -0.0683 -0.0566 -0.0769 +-0.0199 -0.0423 0.0806 0.0562 0.0009 -0.0563 -0.1358 -0.1578 -0.0456 0.0032 +0.0091 0.0101 -0.0090 -0.0279 -0.0489 -0.1038 -0.0815 0.2184 0.1172 0.0902 +-0.0024 -0.0135 0.0392 0.0028 0.0792 0.0404 0.0867 0.1610 0.0954 0.0846 +-0.0004 -0.0220 -0.0282 -0.1022 -0.0799 0.1278 0.0765 0.0402 0.0850 0.0611 +0.0443 0.0320 -0.0384 -0.0964 0.0030 -0.0398 -0.0730 -0.0052 -0.0267 0.1209 +-0.0706 0.1151 0.0722 -0.0175 -0.0927 -0.0559 0.0316 0.0186 0.0105 0.0314 +-0.0145 -0.0263 -0.0564 0.0248 -0.0181 -0.0817 -0.0938 0.0366 -0.0315 0.1253 +0.0307 0.0039 0.1290 0.0402 -0.0439 -0.0384 0.0044 -0.0177 -0.0172 -0.0310 +0.0447 0.0298 0.0287 0.0273 -0.0350 -0.0708 -0.1829 -0.0317 0.0643 0.0057 +-0.0820 -0.0326 0.0209 -0.0711 0.0084 0.0111 0.0426 0.0262 -0.0061 0.0005 +0.0545 0.0377 -0.0417 -0.0625 0.0114 -0.0405 0.0573 0.0191 -0.0263 -0.0472 +-0.0053 -0.0049 -0.0255 -0.0578 -0.0237 -0.0721 -0.1487 -0.1636 0.0046 -0.0355 +0.0309 0.0107 0.0163 0.0132 -0.0536 -0.0009 -0.0706 -0.1350 -0.0514 -0.0960 +0.0306 0.0003 0.0494 0.0701 0.0027 -0.0458 0.0780 0.0327 0.0937 0.0605 +-0.0017 -0.0275 0.0797 -0.0268 -0.1014 0.0593 -0.0528 -0.1103 0.0682 0.0322 +-0.0507 -0.0806 -0.0646 -0.0052 -0.0576 0.0451 0.0489 0.0150 0.0029 -0.0189 +0.0270 0.0143 -0.0375 -0.0071 -0.0607 -0.1157 -0.0345 -0.1115 0.0201 -0.0104 +-0.0807 -0.1088 0.0845 0.0720 0.0441 0.0301 0.0043 0.0052 0.0016 0.0201 +-0.0290 -0.0532 0.0036 -0.0201 -0.0723 -0.1321 0.0867 0.0479 -0.0556 -0.0850 +-0.0271 0.0126 0.1283 0.0533 -0.0030 -0.0352 -0.0326 -0.0553 0.1402 0.1121 +-0.0358 -0.0518 -0.1080 0.0134 0.0950 0.0384 -0.0040 -0.0254 0.0026 -0.0217 +-0.0152 -0.0375 -0.0827 0.0916 0.0188 0.1306 0.0983 0.0606 0.0381 0.0080 +-0.0107 -0.0269 -0.0573 -0.1189 0.0258 0.1009 0.0565 0.0270 -0.0557 -0.0778 +-0.0193 -0.0242 -0.0784 -0.0816 0.0287 -0.0484 0.0292 -0.0414 0.1124 0.0767 +0.0177 -0.0148 0.0472 -0.0808 0.0623 -0.0636 0.0750 -0.0107 0.0673 0.0425 +-0.0220 0.0577 -0.0769 -0.0247 -0.0321 0.0341 -0.0108 0.0109 -0.0142 0.0122 +0.0194 0.0248 -0.0096 -0.0205 -0.0460 -0.1160 0.0492 -0.0188 -0.1535 0.0816 +0.0301 -0.0286 -0.0077 -0.0117 -0.0036 -0.0026 0.0133 -0.0032 0.0007 -0.0160 +0.0115 -0.0111 0.0246 -0.0639 0.0325 -0.0313 0.0808 0.0435 -0.0777 -0.1108 +-0.0079 -0.0334 -0.0144 -0.0539 0.1564 0.1175 0.0549 0.0340 0.0319 0.0027 +-0.0155 -0.0275 -0.0739 -0.0932 0.0108 -0.0698 0.0036 -0.0213 -0.0486 -0.0670 +-0.0234 -0.0567 0.0020 0.0908 -0.0151 0.0460 -0.0175 -0.0523 0.0098 -0.0237 +0.0057 -0.0066 -0.0418 0.0418 -0.0449 0.1069 0.0629 -0.0016 -0.1068 -0.1492 +-0.0791 0.0403 -0.0009 0.0285 -0.0065 0.0963 0.0550 0.0634 0.0693 0.0694 +-0.0068 -0.0197 -0.0919 0.0071 -0.0551 -0.1173 0.0926 0.0413 0.0127 -0.0158 +0.0540 0.0389 -0.0195 -0.0800 -0.1383 0.0440 -0.0139 -0.0405 0.0147 -0.0183 +0.0380 0.0248 0.0520 -0.0609 0.0339 -0.0070 -0.0974 0.1182 0.0221 -0.0310 +0.0043 0.0046 -0.0274 -0.0502 0.0326 -0.0143 -0.0586 -0.0866 -0.1673 -0.1624 +0.0428 0.0385 -0.0228 0.0704 0.0069 -0.0145 -0.0623 -0.0639 -0.1479 0.0212 +-0.0078 -0.0297 0.0025 -0.0239 -0.0793 0.0896 0.0315 -0.0546 -0.1309 0.1080 diff --git a/gr-vocoder/lib/codec2/codebook/lspvqanssi3.txt b/gr-vocoder/lib/codec2/codebook/lspvqanssi3.txt new file mode 100644 index 0000000000..a28c3e7fba --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspvqanssi3.txt @@ -0,0 +1,65 @@ +10 64 +-0.0291 0.0272 -0.0364 -0.0313 -0.0487 -0.0205 0.0501 0.0225 0.0178 0.0080 +-0.0406 -0.0383 0.0013 -0.0155 -0.0261 -0.0598 0.0003 -0.0242 0.0151 -0.0140 +-0.0445 0.0356 0.0180 -0.0272 -0.0018 -0.0177 -0.0703 0.0471 0.0128 -0.0068 +-0.0033 -0.0285 -0.0560 -0.0186 -0.0499 -0.0070 0.0068 -0.0126 0.0388 -0.0097 +-0.0071 -0.0114 -0.0308 -0.0094 -0.0541 -0.0272 -0.0756 0.0477 -0.0234 0.0678 +0.0048 0.0307 -0.0174 -0.0593 0.0097 -0.0134 0.0034 -0.0212 -0.0418 0.0869 +-0.0189 0.0165 -0.0269 0.0744 0.0344 -0.0177 -0.0603 0.0212 -0.0104 0.0345 +-0.0130 -0.0352 -0.0086 -0.0257 -0.0286 0.0409 0.0656 0.0106 -0.0598 0.0252 +0.0041 0.0097 -0.0032 -0.0154 -0.0405 0.0670 -0.0164 0.0451 0.0774 0.0504 +0.0010 -0.0091 -0.0345 0.0511 0.0016 0.0011 0.0684 0.0167 0.0601 0.0512 +0.0204 -0.0038 -0.0426 0.0185 -0.0191 -0.0630 0.0295 -0.0153 -0.0559 0.0560 +-0.0461 -0.0041 0.0515 0.0219 0.0322 0.0093 0.0044 0.0106 -0.0329 -0.0521 +0.0304 0.0017 0.0209 -0.0002 0.0689 0.0136 0.0216 -0.0268 -0.0682 0.0333 +-0.0175 -0.0425 0.0153 -0.0050 -0.0113 0.0297 -0.0659 -0.0344 0.0302 -0.0272 +-0.0217 -0.0362 0.0426 0.0233 -0.0393 0.0052 0.0138 0.0657 0.0427 0.0220 +-0.0039 -0.0011 -0.0002 -0.0453 -0.0835 0.0144 -0.0268 -0.0589 -0.0185 0.0133 +0.0081 -0.0032 0.0638 0.0032 0.0060 0.0002 -0.0303 -0.0823 0.0124 -0.0308 +0.0108 0.0011 0.0059 0.0396 0.0392 0.0351 -0.0045 -0.0323 -0.0512 -0.0975 +-0.0144 -0.0306 -0.0302 -0.0070 0.0123 -0.0042 -0.0083 -0.0514 0.0120 0.1116 +-0.0046 -0.0131 0.0472 0.0144 -0.0296 -0.0518 0.0337 -0.0145 -0.0733 0.0793 +-0.0064 -0.0162 -0.0327 -0.0711 0.0108 -0.0131 0.0025 -0.0254 -0.0277 -0.0680 +-0.0306 0.0055 0.0272 -0.0189 -0.0173 0.0221 0.0773 0.0043 0.0458 -0.0169 +-0.0006 0.0299 0.0259 0.0227 -0.0530 -0.0596 -0.0271 -0.0091 0.0181 -0.0233 +-0.0116 -0.0398 0.0089 0.0708 -0.0028 -0.0084 -0.0206 -0.0354 -0.0275 -0.0037 +0.0259 -0.0064 -0.0380 0.0572 0.0083 0.0286 -0.0565 0.0158 0.0396 -0.0123 +0.0552 0.0331 -0.0052 -0.0346 -0.0180 -0.0194 -0.0237 0.0184 0.0056 -0.0199 +0.0143 0.0131 -0.0166 0.0196 0.0154 0.0310 -0.0048 0.0901 -0.0333 0.0761 +0.0118 -0.0107 0.0099 0.0078 0.0002 -0.0716 -0.0233 0.0793 0.0516 0.0300 +0.0204 0.0243 0.0192 0.0181 0.0001 -0.0243 -0.0764 -0.0622 -0.0324 0.0640 +0.0132 0.0016 -0.0187 -0.0425 0.0627 0.0094 -0.0786 0.0304 0.0294 -0.0146 +-0.0221 -0.0154 0.0285 -0.0709 0.0406 0.0114 0.0073 -0.0199 0.0081 0.0268 +0.0227 0.0055 0.0163 -0.0447 0.0246 0.0795 0.0239 0.0211 -0.0145 -0.0576 +-0.0119 0.0637 0.0278 0.0202 -0.0086 0.0389 0.0320 -0.0049 -0.0272 -0.0274 +0.0040 -0.0211 0.0426 0.0480 0.0415 0.0659 0.0408 0.0198 0.0327 0.0029 +0.0430 0.0311 0.0083 0.0353 0.0250 0.0143 0.0106 -0.0305 0.0633 0.0227 +-0.0277 0.0302 0.0337 0.0176 0.0191 -0.0156 0.0231 0.0118 0.0465 0.0875 +0.0221 0.0146 0.0147 -0.0211 -0.0317 -0.0179 -0.0049 -0.0297 -0.1078 -0.0413 +-0.0531 0.0180 -0.0066 0.0365 -0.0033 0.0090 -0.0158 -0.0698 0.0315 -0.0048 +0.0289 0.0053 0.0082 0.0077 -0.0664 0.0474 0.0407 -0.0096 0.0028 -0.0526 +-0.0106 -0.0129 -0.0315 0.0335 -0.0217 -0.0427 0.0582 0.0193 -0.0288 -0.0777 +-0.0003 -0.0141 -0.0102 0.0007 -0.0077 -0.0517 -0.0909 0.0128 -0.0349 -0.0769 +-0.0227 -0.0159 -0.0327 0.0011 0.0312 0.0100 -0.0180 -0.0537 -0.0997 0.0122 +0.0190 -0.0139 0.0341 -0.0131 -0.0368 -0.0138 -0.0074 -0.0415 0.0791 0.0503 +0.0182 0.0027 0.0032 -0.0325 -0.0309 -0.0898 0.0509 -0.0170 0.0301 -0.0137 +0.0233 0.0100 0.0231 0.0730 0.0212 -0.0299 0.0440 0.0041 -0.0101 -0.0251 +0.0074 -0.0033 -0.0285 -0.0350 0.0101 0.0735 0.0036 -0.0659 0.0429 -0.0052 +0.0148 -0.0035 -0.0233 0.0079 -0.0142 -0.0402 -0.0358 -0.0985 -0.0080 -0.0549 +0.0203 0.0057 -0.0604 0.0098 0.0402 0.0151 0.0500 0.0058 -0.0086 -0.0401 +0.0056 -0.0381 0.0420 -0.0125 0.0157 -0.0268 0.0433 0.0123 -0.0176 -0.0685 +0.0030 0.0502 0.0067 -0.0222 0.0405 -0.0226 0.0020 -0.0401 -0.0026 -0.0521 +0.0317 0.0089 0.0620 0.0251 0.0066 0.0089 -0.0565 0.0414 0.0005 -0.0365 +-0.0058 0.0086 -0.0291 -0.0164 -0.0134 -0.0490 -0.0427 -0.0451 0.0869 0.0334 +0.0024 0.0328 -0.0415 0.0003 -0.0287 0.0193 -0.0547 -0.0222 -0.0196 -0.0571 +-0.0271 -0.0397 -0.0431 -0.0043 0.0332 0.0093 0.0082 0.0585 0.0282 0.0004 +-0.0251 -0.0167 -0.0289 0.0196 -0.0363 0.0850 0.0028 0.0319 -0.0202 -0.0512 +0.0389 0.0226 0.0401 -0.0091 -0.0152 0.0001 0.0738 0.0402 0.0097 0.0310 +-0.0126 0.0130 -0.0046 -0.0216 0.0298 -0.0344 0.0713 0.0547 -0.0470 -0.0294 +0.0125 0.0044 -0.0028 0.0209 -0.0200 0.0854 0.0018 -0.0386 -0.0703 0.0778 +-0.0036 -0.0347 0.0309 -0.0184 0.0290 -0.0025 -0.0644 0.0347 -0.0523 0.0644 +0.0064 0.0295 -0.0017 0.0282 0.0176 0.0027 0.0246 0.0967 0.0401 -0.0231 +0.0054 -0.0109 0.0055 -0.0479 -0.0490 -0.0136 -0.0245 0.0839 0.0026 -0.0493 +0.0128 -0.0050 -0.0219 -0.0621 0.0313 0.0019 0.0696 0.0459 0.0574 0.0299 +-0.0091 -0.0290 -0.0068 0.0276 0.0645 -0.0150 0.0015 -0.0374 0.0415 -0.0124 +-0.0171 0.0177 -0.0138 0.0034 0.0840 0.0584 0.0233 0.0100 0.0122 0.0047 diff --git a/gr-vocoder/lib/codec2/codebook/lspvqanssi4.txt b/gr-vocoder/lib/codec2/codebook/lspvqanssi4.txt new file mode 100644 index 0000000000..01867d40f6 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lspvqanssi4.txt @@ -0,0 +1,65 @@ +10 64 +0.0221 -0.0035 -0.0032 -0.0177 -0.0327 0.0518 -0.0110 -0.0150 -0.0136 -0.0327 +0.0099 -0.0059 0.0031 -0.0174 0.0464 -0.0240 0.0251 -0.0270 0.0454 -0.0082 +-0.0029 0.0025 -0.0267 -0.0318 -0.0157 0.0173 0.0253 0.0063 -0.0481 0.0419 +-0.0332 -0.0179 -0.0042 0.0241 0.0044 -0.0098 -0.0081 0.0024 -0.0414 0.0339 +-0.0060 0.0182 -0.0051 -0.0479 0.0016 -0.0179 0.0316 0.0222 -0.0029 -0.0351 +0.0074 0.0015 0.0337 -0.0082 -0.0008 0.0129 0.0001 0.0650 0.0175 0.0309 +-0.0212 -0.0261 0.0196 -0.0309 0.0093 -0.0272 0.0260 0.0169 0.0132 0.0116 +-0.0010 0.0202 0.0228 -0.0227 -0.0141 0.0192 -0.0423 -0.0097 -0.0342 0.0338 +-0.0149 -0.0110 -0.0156 0.0290 0.0028 0.0123 -0.0350 -0.0501 0.0272 -0.0245 +-0.0005 -0.0194 0.0460 -0.0001 -0.0280 0.0216 -0.0028 -0.0162 0.0177 -0.0254 +-0.0109 -0.0026 0.0038 -0.0150 -0.0421 -0.0422 0.0164 -0.0436 0.0054 -0.0098 +0.0061 -0.0106 0.0062 0.0207 -0.0329 0.0177 -0.0578 0.0408 0.0077 -0.0260 +0.0001 -0.0098 0.0106 -0.0003 -0.0292 0.0032 0.0560 0.0311 -0.0282 -0.0445 +0.0033 0.0345 -0.0022 -0.0029 -0.0228 0.0242 0.0197 -0.0286 0.0194 -0.0328 +0.0094 -0.0010 0.0121 0.0229 0.0161 0.0363 -0.0124 0.0179 -0.0626 0.0020 +-0.0070 -0.0272 -0.0171 -0.0249 -0.0039 0.0254 0.0317 -0.0324 0.0276 -0.0090 +-0.0002 0.0057 -0.0204 0.0512 -0.0170 0.0113 0.0157 0.0427 -0.0024 0.0162 +-0.0064 -0.0144 0.0216 0.0053 -0.0361 0.0287 0.0230 -0.0161 -0.0189 0.0589 +0.0091 -0.0059 -0.0308 0.0171 -0.0137 -0.0033 -0.0505 -0.0155 -0.0527 0.0133 +-0.0121 -0.0051 0.0219 0.0136 0.0476 -0.0090 -0.0460 0.0208 0.0072 -0.0076 +0.0098 -0.0328 -0.0211 0.0054 -0.0146 -0.0263 0.0248 0.0045 -0.0183 0.0301 +0.0101 0.0139 -0.0073 0.0234 0.0083 -0.0194 -0.0365 0.0307 0.0580 0.0153 +-0.0111 0.0019 0.0265 -0.0150 0.0311 0.0362 0.0244 -0.0213 -0.0224 -0.0299 +0.0061 0.0082 -0.0181 0.0081 -0.0344 0.0133 -0.0095 -0.0411 0.0462 0.0371 +0.0089 -0.0157 0.0179 -0.0256 -0.0118 -0.0302 -0.0329 0.0212 -0.0463 -0.0162 +-0.0313 0.0096 -0.0040 0.0186 0.0248 -0.0126 0.0472 -0.0079 0.0115 -0.0270 +0.0055 0.0044 0.0172 0.0079 -0.0089 -0.0202 -0.0233 -0.0397 -0.0305 -0.0620 +-0.0282 -0.0104 -0.0071 -0.0242 -0.0255 0.0204 -0.0187 -0.0103 -0.0227 -0.0424 +-0.0056 0.0065 0.0151 -0.0376 0.0039 0.0009 -0.0507 -0.0040 0.0393 -0.0201 +0.0128 -0.0228 0.0115 -0.0446 0.0316 0.0266 -0.0036 0.0117 -0.0009 0.0048 +-0.0088 0.0226 0.0125 0.0090 0.0008 -0.0341 0.0243 -0.0178 -0.0589 0.0278 +0.0151 0.0021 -0.0349 -0.0365 -0.0098 -0.0179 -0.0212 -0.0313 0.0109 -0.0164 +-0.0211 -0.0112 -0.0446 0.0014 -0.0034 -0.0179 0.0110 0.0176 0.0286 0.0045 +0.0034 -0.0151 0.0380 0.0331 -0.0034 -0.0439 0.0145 0.0120 0.0036 0.0017 +-0.0348 0.0192 0.0167 0.0069 -0.0266 -0.0085 -0.0076 0.0260 0.0234 0.0075 +-0.0237 0.0150 -0.0094 -0.0201 0.0234 -0.0041 -0.0160 -0.0549 -0.0021 0.0239 +-0.0019 0.0173 0.0295 0.0443 0.0081 0.0181 -0.0039 -0.0270 0.0155 0.0107 +0.0065 -0.0055 -0.0368 0.0232 0.0370 0.0367 0.0046 -0.0167 0.0047 0.0173 +0.0116 0.0053 -0.0229 0.0382 0.0160 -0.0453 0.0057 -0.0267 0.0020 -0.0051 +-0.0140 0.0302 -0.0208 0.0106 0.0101 -0.0049 -0.0319 0.0227 -0.0206 -0.0371 +-0.0007 -0.0109 -0.0053 0.0078 0.0410 -0.0001 0.0543 0.0328 -0.0196 0.0332 +-0.0043 -0.0028 -0.0246 0.0285 -0.0248 0.0153 0.0303 -0.0310 -0.0335 -0.0315 +-0.0417 0.1029 0.0377 0.0069 0.0012 0.0065 0.0007 -0.0144 -0.0083 0.0004 +0.0295 0.0099 -0.0144 -0.0145 0.0141 -0.0013 0.0362 -0.0142 -0.0428 -0.0161 +-0.0095 -0.0206 0.0116 0.0132 0.0164 0.0158 0.0012 -0.0024 0.0640 0.0364 +0.0005 -0.0022 -0.0165 -0.0057 0.0263 0.0339 0.0014 0.0541 0.0164 -0.0411 +0.0039 -0.0143 -0.0107 0.0032 -0.0160 -0.0502 0.0010 0.0272 0.0161 -0.0500 +0.0083 0.0292 -0.0076 -0.0201 0.0313 0.0213 0.0120 0.0087 0.0285 0.0332 +0.0170 0.0018 0.0001 0.0205 0.0106 -0.0064 -0.0082 -0.0083 -0.0082 0.0886 +0.0075 -0.0078 -0.0038 -0.0337 -0.0491 0.0048 0.0069 0.0300 0.0369 0.0088 +-0.0091 -0.0327 0.0041 0.0376 0.0170 0.0154 0.0126 0.0153 -0.0024 -0.0353 +0.0289 -0.0080 0.0063 0.0274 -0.0061 0.0208 0.0390 -0.0060 0.0294 -0.0088 +-0.0037 -0.0195 0.0058 0.0023 -0.0149 -0.0360 -0.0587 -0.0248 0.0288 0.0203 +-0.0031 0.0081 -0.0112 -0.0221 0.0067 -0.0505 -0.0233 0.0353 -0.0131 0.0417 +0.0243 0.0231 -0.0013 0.0049 -0.0423 -0.0245 -0.0029 0.0184 -0.0162 -0.0010 +0.0045 0.0101 -0.0042 0.0014 -0.0133 -0.0321 0.0642 0.0153 0.0377 0.0277 +0.0275 0.0083 0.0286 -0.0243 -0.0084 -0.0236 0.0027 -0.0289 0.0201 0.0235 +0.0281 0.0078 0.0038 0.0069 0.0302 0.0170 -0.0423 -0.0340 0.0104 -0.0181 +0.0334 -0.0034 -0.0257 -0.0061 0.0140 -0.0099 -0.0195 0.0529 0.0019 0.0010 +-0.0114 0.0012 -0.0038 -0.0016 -0.0140 0.0697 0.0372 0.0243 0.0172 0.0066 +0.0192 0.0149 0.0285 0.0077 0.0246 -0.0135 0.0145 0.0317 -0.0074 -0.0438 +-0.0034 -0.0175 -0.0245 -0.0153 0.0357 -0.0102 -0.0062 -0.0053 -0.0308 -0.0499 +0.0025 -0.0253 0.0148 0.0031 0.0189 -0.0023 -0.0085 -0.0596 -0.0337 0.0175 +-0.0091 -0.0171 -0.0217 -0.0189 0.0056 0.0249 -0.0499 0.0236 0.0042 0.0449 diff --git a/gr-vocoder/lib/codec2/codec2.c b/gr-vocoder/lib/codec2/codec2.c index 93ea9208c1..bc4a084839 100644 --- a/gr-vocoder/lib/codec2/codec2.c +++ b/gr-vocoder/lib/codec2/codec2.c @@ -42,7 +42,32 @@ #include "interp.h" #include "postfilter.h" #include "codec2.h" +#include "lsp.h" #include "codec2_internal.h" +#include "machdep.h" + +/*---------------------------------------------------------------------------*\ + + FUNCTION HEADERS + +\*---------------------------------------------------------------------------*/ + +void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]); +void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, + float ak[]); +void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]); +void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits); +void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]); +void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * bits); +void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]); +void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * bits); +void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]); +void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits); +void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]); +void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est); +void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]); +void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits); +static void ear_protection(float in_out[], int n); /*---------------------------------------------------------------------------*\ @@ -64,50 +89,68 @@ \*---------------------------------------------------------------------------*/ -void *codec2_create() +struct CODEC2 * CODEC2_WIN32SUPPORT codec2_create(int mode) { - CODEC2 *c2; - int i,l; + struct CODEC2 *c2; + int i,l; - c2 = (CODEC2*)malloc(sizeof(CODEC2)); + c2 = (struct CODEC2*)malloc(sizeof(struct CODEC2)); if (c2 == NULL) return NULL; + assert( + (mode == CODEC2_MODE_3200) || + (mode == CODEC2_MODE_2400) || + (mode == CODEC2_MODE_1600) || + (mode == CODEC2_MODE_1400) || + (mode == CODEC2_MODE_1300) || + (mode == CODEC2_MODE_1200) + ); + c2->mode = mode; for(i=0; i<M; i++) c2->Sn[i] = 1.0; c2->hpf_states[0] = c2->hpf_states[1] = 0.0; for(i=0; i<2*N; i++) c2->Sn_[i] = 0; - make_analysis_window(c2->w,c2->W); + c2->fft_fwd_cfg = kiss_fft_alloc(FFT_ENC, 0, NULL, NULL); + make_analysis_window(c2->fft_fwd_cfg, c2->w,c2->W); make_synthesis_window(c2->Pn); + c2->fft_inv_cfg = kiss_fft_alloc(FFT_DEC, 1, NULL, NULL); quantise_init(); - c2->prev_Wo = 0.0; + c2->prev_Wo_enc = 0.0; c2->bg_est = 0.0; c2->ex_phase = 0.0; - for(l=1; l<MAX_AMP; l++) - c2->prev_model.A[l] = 0.0; - c2->prev_model.Wo = TWO_PI/P_MAX; - c2->prev_model.L = PI/c2->prev_model.Wo; - c2->prev_model.voiced = 0; + for(l=1; l<=MAX_AMP; l++) + c2->prev_model_dec.A[l] = 0.0; + c2->prev_model_dec.Wo = TWO_PI/P_MAX; + c2->prev_model_dec.L = PI/c2->prev_model_dec.Wo; + c2->prev_model_dec.voiced = 0; for(i=0; i<LPC_ORD; i++) { - c2->prev_lsps[i] = i*PI/(LPC_ORD+1); + c2->prev_lsps_dec[i] = i*PI/(LPC_ORD+1); } - c2->prev_energy = 1; + c2->prev_e_dec = 1; - c2->nlp = nlp_create(); + c2->nlp = nlp_create(M); if (c2->nlp == NULL) { free (c2); return NULL; } - return (void*)c2; + c2->lpc_pf = 1; c2->bass_boost = 1; c2->beta = LPCPF_BETA; c2->gamma = LPCPF_GAMMA; + + c2->xq_enc[0] = c2->xq_enc[1] = 0.0; + c2->xq_dec[0] = c2->xq_dec[1] = 0.0; + + c2->smoothing = 0; + + return c2; } /*---------------------------------------------------------------------------*\ - FUNCTION....: codec2_create + FUNCTION....: codec2_destroy AUTHOR......: David Rowe DATE CREATED: 21/8/2010 @@ -115,27 +158,282 @@ void *codec2_create() \*---------------------------------------------------------------------------*/ -void codec2_destroy(void *codec2_state) +void CODEC2_WIN32SUPPORT codec2_destroy(struct CODEC2 *c2) { - CODEC2 *c2; - - assert(codec2_state != NULL); - c2 = (CODEC2*)codec2_state; + assert(c2 != NULL); nlp_destroy(c2->nlp); - free(codec2_state); + KISS_FFT_FREE(c2->fft_fwd_cfg); + KISS_FFT_FREE(c2->fft_inv_cfg); + free(c2); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_bits_per_frame + AUTHOR......: David Rowe + DATE CREATED: Nov 14 2011 + + Returns the number of bits per frame. + +\*---------------------------------------------------------------------------*/ + +int CODEC2_WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *c2) { + if (c2->mode == CODEC2_MODE_3200) + return 64; + if (c2->mode == CODEC2_MODE_2400) + return 48; + if (c2->mode == CODEC2_MODE_1600) + return 64; + if (c2->mode == CODEC2_MODE_1400) + return 56; + if (c2->mode == CODEC2_MODE_1300) + return 52; + if (c2->mode == CODEC2_MODE_1200) + return 48; + + return 0; /* shouldn't get here */ +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_samples_per_frame + AUTHOR......: David Rowe + DATE CREATED: Nov 14 2011 + + Returns the number of bits per frame. + +\*---------------------------------------------------------------------------*/ + +int CODEC2_WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *c2) { + if (c2->mode == CODEC2_MODE_3200) + return 160; + if (c2->mode == CODEC2_MODE_2400) + return 160; + if (c2->mode == CODEC2_MODE_1600) + return 320; + if (c2->mode == CODEC2_MODE_1400) + return 320; + if (c2->mode == CODEC2_MODE_1300) + return 320; + if (c2->mode == CODEC2_MODE_1200) + return 320; + + return 0; /* shouldnt get here */ +} + +void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[]) +{ + assert(c2 != NULL); + assert( + (c2->mode == CODEC2_MODE_3200) || + (c2->mode == CODEC2_MODE_2400) || + (c2->mode == CODEC2_MODE_1600) || + (c2->mode == CODEC2_MODE_1400) || + (c2->mode == CODEC2_MODE_1300) || + (c2->mode == CODEC2_MODE_1200) + ); + + if (c2->mode == CODEC2_MODE_3200) + codec2_encode_3200(c2, bits, speech); + if (c2->mode == CODEC2_MODE_2400) + codec2_encode_2400(c2, bits, speech); + if (c2->mode == CODEC2_MODE_1600) + codec2_encode_1600(c2, bits, speech); + if (c2->mode == CODEC2_MODE_1400) + codec2_encode_1400(c2, bits, speech); + if (c2->mode == CODEC2_MODE_1300) + codec2_encode_1300(c2, bits, speech); + if (c2->mode == CODEC2_MODE_1200) + codec2_encode_1200(c2, bits, speech); +} + +void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits, float ber_est) +{ + assert(c2 != NULL); + assert( + (c2->mode == CODEC2_MODE_3200) || + (c2->mode == CODEC2_MODE_2400) || + (c2->mode == CODEC2_MODE_1600) || + (c2->mode == CODEC2_MODE_1400) || + (c2->mode == CODEC2_MODE_1300) || + (c2->mode == CODEC2_MODE_1200) + ); + + if (c2->mode == CODEC2_MODE_3200) + codec2_decode_3200(c2, speech, bits); + if (c2->mode == CODEC2_MODE_2400) + codec2_decode_2400(c2, speech, bits); + if (c2->mode == CODEC2_MODE_1600) + codec2_decode_1600(c2, speech, bits); + if (c2->mode == CODEC2_MODE_1400) + codec2_decode_1400(c2, speech, bits); + if (c2->mode == CODEC2_MODE_1300) + codec2_decode_1300(c2, speech, bits, ber_est); + if (c2->mode == CODEC2_MODE_1200) + codec2_decode_1200(c2, speech, bits); } + /*---------------------------------------------------------------------------*\ - FUNCTION....: codec2_encode + FUNCTION....: codec2_encode_3200 + AUTHOR......: David Rowe + DATE CREATED: 13 Sep 2012 + + Encodes 160 speech samples (20ms of speech) into 64 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm twice. On the + first frame we just send the voicing bits. On the second frame we + send all model parameters. Compared to 2400 we use a larger number + of bits for the LSPs and non-VQ pitch and energy. + + The bit allocation is: + + Parameter bits/frame + -------------------------------------- + Harmonic magnitudes (LSPs) 50 + Pitch (Wo) 7 + Energy 5 + Voicing (10ms update) 2 + TOTAL 64 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]) +{ + MODEL model; + float ak[LPC_ORD+1]; + float lsps[LPC_ORD]; + float e; + int Wo_index, e_index; + int lspd_indexes[LPC_ORD]; + int i; + unsigned int nbit = 0; + + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + + /* first 10ms analysis frame - we just want voicing */ + + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); + + /* second 10ms analysis frame */ + + analyse_one_frame(c2, &model, &speech[N]); + pack(bits, &nbit, model.voiced, 1); + Wo_index = encode_Wo(model.Wo); + pack(bits, &nbit, Wo_index, WO_BITS); + + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + e_index = encode_energy(e); + pack(bits, &nbit, e_index, E_BITS); + + encode_lspds_scalar(lspd_indexes, lsps, LPC_ORD); + for(i=0; i<LSPD_SCALAR_INDEXES; i++) { + pack(bits, &nbit, lspd_indexes[i], lspd_bits(i)); + } + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_decode_3200 + AUTHOR......: David Rowe + DATE CREATED: 13 Sep 2012 + + Decodes a frame of 64 bits into 160 samples (20ms) of speech. + +\*---------------------------------------------------------------------------*/ + +void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits) +{ + MODEL model[2]; + int lspd_indexes[LPC_ORD]; + float lsps[2][LPC_ORD]; + int Wo_index, e_index; + float e[2]; + float snr; + float ak[2][LPC_ORD+1]; + int i,j; + unsigned int nbit = 0; + + assert(c2 != NULL); + + /* only need to zero these out due to (unused) snr calculation */ + + for(i=0; i<2; i++) + for(j=1; j<=MAX_AMP; j++) + model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 2 x 10ms + frames */ + + model[0].voiced = unpack(bits, &nbit, 1); + model[1].voiced = unpack(bits, &nbit, 1); + + Wo_index = unpack(bits, &nbit, WO_BITS); + model[1].Wo = decode_Wo(Wo_index); + model[1].L = PI/model[1].Wo; + + e_index = unpack(bits, &nbit, E_BITS); + e[1] = decode_energy(e_index); + + for(i=0; i<LSPD_SCALAR_INDEXES; i++) { + lspd_indexes[i] = unpack(bits, &nbit, lspd_bits(i)); + } + decode_lspds_scalar(&lsps[1][0], lspd_indexes, LPC_ORD); + + /* interpolate ------------------------------------------------*/ + + /* Wo and energy are sampled every 20ms, so we interpolate just 1 + 10ms frame between 20ms samples */ + + interp_Wo(&model[0], &c2->prev_model_dec, &model[1]); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + + /* LSPs are sampled every 20ms so we interpolate the frame in + between, then recover spectral amplitudes */ + + interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5); + for(i=0; i<2; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); + aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, + c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); + apply_lpc_correction(&model[i]); + } + + /* synthesise ------------------------------------------------*/ + + for(i=0; i<2; i++) + synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]); + + /* update memories for next frame ----------------------------*/ + + c2->prev_model_dec = model[1]; + c2->prev_e_dec = e[1]; + for(i=0; i<LPC_ORD; i++) + c2->prev_lsps_dec[i] = lsps[1][i]; +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode_2400 AUTHOR......: David Rowe DATE CREATED: 21/8/2010 - Encodes 160 speech samples (20ms of speech) into 51 bits. + Encodes 160 speech samples (20ms of speech) into 48 bits. The codec2 algorithm actually operates internally on 10ms (80 sample) frames, so we run the encoding algorithm twice. On the - first frame we just send the voicing bit. One the second frame we + first frame we just send the voicing bit. On the second frame we send all model parameters. The bit allocation is: @@ -143,132 +441,859 @@ void codec2_destroy(void *codec2_state) Parameter bits/frame -------------------------------------- Harmonic magnitudes (LSPs) 36 - Low frequency LPC correction 1 - Energy 5 - Wo (fundamental frequnecy) 7 + Joint VQ of Energy and Wo 8 Voicing (10ms update) 2 - TOTAL 51 + Spare 2 + TOTAL 48 \*---------------------------------------------------------------------------*/ -void codec2_encode(void *codec2_state, unsigned char * bits, short speech[]) +void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]) { - CODEC2 *c2; MODEL model; - int voiced1, voiced2; + float ak[LPC_ORD+1]; + float lsps[LPC_ORD]; + float e; + int WoE_index; int lsp_indexes[LPC_ORD]; - int energy_index; - int Wo_index; int i; + int spare = 0; unsigned int nbit = 0; - assert(codec2_state != NULL); - c2 = (CODEC2*)codec2_state; + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); /* first 10ms analysis frame - we just want voicing */ analyse_one_frame(c2, &model, speech); - voiced1 = model.voiced; + pack(bits, &nbit, model.voiced, 1); /* second 10ms analysis frame */ analyse_one_frame(c2, &model, &speech[N]); - voiced2 = model.voiced; + pack(bits, &nbit, model.voiced, 1); + + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); + + encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); + for(i=0; i<LSP_SCALAR_INDEXES; i++) { + pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); + } + pack(bits, &nbit, spare, 2); + + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_decode_2400 + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Decodes frames of 48 bits into 160 samples (20ms) of speech. + +\*---------------------------------------------------------------------------*/ + +void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * bits) +{ + MODEL model[2]; + int lsp_indexes[LPC_ORD]; + float lsps[2][LPC_ORD]; + int WoE_index; + float e[2]; + float snr; + float ak[2][LPC_ORD+1]; + int i,j; + unsigned int nbit = 0; + + assert(c2 != NULL); + + /* only need to zero these out due to (unused) snr calculation */ + + for(i=0; i<2; i++) + for(j=1; j<=MAX_AMP; j++) + model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 2 x 10ms + frames */ + + model[0].voiced = unpack(bits, &nbit, 1); + + model[1].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&model[1], &e[1], c2->xq_dec, WoE_index); + + for(i=0; i<LSP_SCALAR_INDEXES; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); + } + decode_lsps_scalar(&lsps[1][0], lsp_indexes, LPC_ORD); + check_lsp_order(&lsps[1][0], LPC_ORD); + bw_expand_lsps(&lsps[1][0], LPC_ORD, 50.0, 100.0); + + /* interpolate ------------------------------------------------*/ + + /* Wo and energy are sampled every 20ms, so we interpolate just 1 + 10ms frame between 20ms samples */ + + interp_Wo(&model[0], &c2->prev_model_dec, &model[1]); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + + /* LSPs are sampled every 20ms so we interpolate the frame in + between, then recover spectral amplitudes */ + + interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5); + for(i=0; i<2; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); + aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, + c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); + apply_lpc_correction(&model[i]); + } + + /* synthesise ------------------------------------------------*/ + + for(i=0; i<2; i++) + synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]); + + /* update memories for next frame ----------------------------*/ + + c2->prev_model_dec = model[1]; + c2->prev_e_dec = e[1]; + for(i=0; i<LPC_ORD; i++) + c2->prev_lsps_dec[i] = lsps[1][i]; +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode_1600 + AUTHOR......: David Rowe + DATE CREATED: Feb 28 2013 + + Encodes 320 speech samples (40ms of speech) into 64 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm 4 times: + + frame 0: voicing bit + frame 1: voicing bit, Wo and E + frame 2: voicing bit + frame 3: voicing bit, Wo and E, scalar LSPs + + The bit allocation is: + + Parameter frame 2 frame 4 Total + ------------------------------------------------------- + Harmonic magnitudes (LSPs) 0 36 36 + Pitch (Wo) 7 7 14 + Energy 5 5 10 + Voicing (10ms update) 2 2 4 + TOTAL 14 50 64 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]) +{ + MODEL model; + float lsps[LPC_ORD]; + float ak[LPC_ORD+1]; + float e; + int lsp_indexes[LPC_ORD]; + int Wo_index, e_index; + int i; + unsigned int nbit = 0; + + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + + /* frame 1: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); + + /* frame 2: - voicing, scalar Wo & E -------------------------------*/ + + analyse_one_frame(c2, &model, &speech[N]); + pack(bits, &nbit, model.voiced, 1); Wo_index = encode_Wo(model.Wo); - encode_amplitudes(lsp_indexes, - &energy_index, - &model, - c2->Sn, - c2->w); - memset(bits, '\0', ((CODEC2_BITS_PER_FRAME + 7) / 8)); pack(bits, &nbit, Wo_index, WO_BITS); - for(i=0; i<LPC_ORD; i++) { + + /* need to run this just to get LPC energy */ + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + e_index = encode_energy(e); + pack(bits, &nbit, e_index, E_BITS); + + /* frame 3: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, &speech[2*N]); + pack(bits, &nbit, model.voiced, 1); + + /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ + + analyse_one_frame(c2, &model, &speech[3*N]); + pack(bits, &nbit, model.voiced, 1); + + Wo_index = encode_Wo(model.Wo); + pack(bits, &nbit, Wo_index, WO_BITS); + + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + e_index = encode_energy(e); + pack(bits, &nbit, e_index, E_BITS); + + encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); + for(i=0; i<LSP_SCALAR_INDEXES; i++) { pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); } - pack(bits, &nbit, energy_index, E_BITS); - pack(bits, &nbit, voiced1, 1); - pack(bits, &nbit, voiced2, 1); - assert(nbit == CODEC2_BITS_PER_FRAME); + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); } + /*---------------------------------------------------------------------------*\ - FUNCTION....: codec2_decode + FUNCTION....: codec2_decode_1600 AUTHOR......: David Rowe - DATE CREATED: 21/8/2010 + DATE CREATED: 11 May 2012 - Decodes frames of 51 bits into 160 samples (20ms) of speech. + Decodes frames of 64 bits into 320 samples (40ms) of speech. \*---------------------------------------------------------------------------*/ -void codec2_decode(void *codec2_state, short speech[], - const unsigned char * bits) +void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * bits) +{ + MODEL model[4]; + int lsp_indexes[LPC_ORD]; + float lsps[4][LPC_ORD]; + int Wo_index, e_index; + float e[4]; + float snr; + float ak[4][LPC_ORD+1]; + int i,j; + unsigned int nbit = 0; + float weight; + + assert(c2 != NULL); + + /* only need to zero these out due to (unused) snr calculation */ + + for(i=0; i<4; i++) + for(j=1; j<=MAX_AMP; j++) + model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 4 x 10ms + frames */ + + model[0].voiced = unpack(bits, &nbit, 1); + + model[1].voiced = unpack(bits, &nbit, 1); + Wo_index = unpack(bits, &nbit, WO_BITS); + model[1].Wo = decode_Wo(Wo_index); + model[1].L = PI/model[1].Wo; + + e_index = unpack(bits, &nbit, E_BITS); + e[1] = decode_energy(e_index); + + model[2].voiced = unpack(bits, &nbit, 1); + + model[3].voiced = unpack(bits, &nbit, 1); + Wo_index = unpack(bits, &nbit, WO_BITS); + model[3].Wo = decode_Wo(Wo_index); + model[3].L = PI/model[3].Wo; + + e_index = unpack(bits, &nbit, E_BITS); + e[3] = decode_energy(e_index); + + for(i=0; i<LSP_SCALAR_INDEXES; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); + } + decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); + check_lsp_order(&lsps[3][0], LPC_ORD); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); + + /* interpolate ------------------------------------------------*/ + + /* Wo and energy are sampled every 20ms, so we interpolate just 1 + 10ms frame between 20ms samples */ + + interp_Wo(&model[0], &c2->prev_model_dec, &model[1]); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + interp_Wo(&model[2], &model[1], &model[3]); + e[2] = interp_energy(e[1], e[3]); + + /* LSPs are sampled every 40ms so we interpolate the 3 frames in + between, then recover spectral amplitudes */ + + for(i=0, weight=0.25; i<3; i++, weight += 0.25) { + interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight); + } + for(i=0; i<4; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); + aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, + c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); + apply_lpc_correction(&model[i]); + } + + /* synthesise ------------------------------------------------*/ + + for(i=0; i<4; i++) + synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]); + + /* update memories for next frame ----------------------------*/ + + c2->prev_model_dec = model[3]; + c2->prev_e_dec = e[3]; + for(i=0; i<LPC_ORD; i++) + c2->prev_lsps_dec[i] = lsps[3][i]; + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode_1400 + AUTHOR......: David Rowe + DATE CREATED: May 11 2012 + + Encodes 320 speech samples (40ms of speech) into 56 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm 4 times: + + frame 0: voicing bit + frame 1: voicing bit, joint VQ of Wo and E + frame 2: voicing bit + frame 3: voicing bit, joint VQ of Wo and E, scalar LSPs + + The bit allocation is: + + Parameter frame 2 frame 4 Total + ------------------------------------------------------- + Harmonic magnitudes (LSPs) 0 36 36 + Energy+Wo 8 8 16 + Voicing (10ms update) 2 2 4 + TOTAL 10 46 56 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]) { - CODEC2 *c2; MODEL model; - int voiced1, voiced2; + float lsps[LPC_ORD]; + float ak[LPC_ORD+1]; + float e; int lsp_indexes[LPC_ORD]; + int WoE_index; + int i; + unsigned int nbit = 0; + + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + + /* frame 1: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); + + /* frame 2: - voicing, joint Wo & E -------------------------------*/ + + analyse_one_frame(c2, &model, &speech[N]); + pack(bits, &nbit, model.voiced, 1); + + /* need to run this just to get LPC energy */ + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); + + /* frame 3: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, &speech[2*N]); + pack(bits, &nbit, model.voiced, 1); + + /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ + + analyse_one_frame(c2, &model, &speech[3*N]); + pack(bits, &nbit, model.voiced, 1); + + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); + + encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); + for(i=0; i<LSP_SCALAR_INDEXES; i++) { + pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); + } + + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_decode_1400 + AUTHOR......: David Rowe + DATE CREATED: 11 May 2012 + + Decodes frames of 56 bits into 320 samples (40ms) of speech. + +\*---------------------------------------------------------------------------*/ + +void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits) +{ + MODEL model[4]; + int lsp_indexes[LPC_ORD]; + float lsps[4][LPC_ORD]; + int WoE_index; + float e[4]; + float snr; + float ak[4][LPC_ORD+1]; + int i,j; + unsigned int nbit = 0; + float weight; + + assert(c2 != NULL); + + /* only need to zero these out due to (unused) snr calculation */ + + for(i=0; i<4; i++) + for(j=1; j<=MAX_AMP; j++) + model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 4 x 10ms + frames */ + + model[0].voiced = unpack(bits, &nbit, 1); + + model[1].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&model[1], &e[1], c2->xq_dec, WoE_index); + + model[2].voiced = unpack(bits, &nbit, 1); + + model[3].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&model[3], &e[3], c2->xq_dec, WoE_index); + + for(i=0; i<LSP_SCALAR_INDEXES; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); + } + decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); + check_lsp_order(&lsps[3][0], LPC_ORD); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); + + /* interpolate ------------------------------------------------*/ + + /* Wo and energy are sampled every 20ms, so we interpolate just 1 + 10ms frame between 20ms samples */ + + interp_Wo(&model[0], &c2->prev_model_dec, &model[1]); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + interp_Wo(&model[2], &model[1], &model[3]); + e[2] = interp_energy(e[1], e[3]); + + /* LSPs are sampled every 40ms so we interpolate the 3 frames in + between, then recover spectral amplitudes */ + + for(i=0, weight=0.25; i<3; i++, weight += 0.25) { + interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight); + } + for(i=0; i<4; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); + aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, + c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); + apply_lpc_correction(&model[i]); + } + + /* synthesise ------------------------------------------------*/ + + for(i=0; i<4; i++) + synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]); + + /* update memories for next frame ----------------------------*/ + + c2->prev_model_dec = model[3]; + c2->prev_e_dec = e[3]; + for(i=0; i<LPC_ORD; i++) + c2->prev_lsps_dec[i] = lsps[3][i]; + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode_1300 + AUTHOR......: David Rowe + DATE CREATED: March 14 2013 + + Encodes 320 speech samples (40ms of speech) into 52 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm 4 times: + + frame 0: voicing bit + frame 1: voicing bit, + frame 2: voicing bit + frame 3: voicing bit, Wo and E, scalar LSPs + + The bit allocation is: + + Parameter frame 2 frame 4 Total + ------------------------------------------------------- + Harmonic magnitudes (LSPs) 0 36 36 + Pitch (Wo) 0 7 7 + Energy 0 5 5 + Voicing (10ms update) 2 2 4 + TOTAL 2 50 52 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]) +{ + MODEL model; float lsps[LPC_ORD]; - int energy_index; - float energy; - int Wo_index; float ak[LPC_ORD+1]; - float ak_interp[LPC_ORD+1]; + float e; + int lsp_indexes[LPC_ORD]; + int Wo_index, e_index; int i; unsigned int nbit = 0; - MODEL model_interp; + #ifdef TIMER + unsigned int quant_start; + #endif + + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + + /* frame 1: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); + + /* frame 2: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, &speech[N]); + pack(bits, &nbit, model.voiced, 1); + + /* frame 3: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, &speech[2*N]); + pack(bits, &nbit, model.voiced, 1); - assert(codec2_state != NULL); - c2 = (CODEC2*)codec2_state; + /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ - /* unpack bit stream to integer codes */ + analyse_one_frame(c2, &model, &speech[3*N]); + pack(bits, &nbit, model.voiced, 1); + + Wo_index = encode_Wo(model.Wo); + pack(bits, &nbit, Wo_index, WO_BITS); + + #ifdef TIMER + quant_start = machdep_timer_sample(); + #endif + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + e_index = encode_energy(e); + pack(bits, &nbit, e_index, E_BITS); + + encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); + for(i=0; i<LSP_SCALAR_INDEXES; i++) { + pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); + } + #ifdef TIMER + machdep_timer_sample_and_log(quant_start, " quant/packing"); + #endif + + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_decode_1300 + AUTHOR......: David Rowe + DATE CREATED: 11 May 2012 + + Decodes frames of 52 bits into 320 samples (40ms) of speech. + +\*---------------------------------------------------------------------------*/ + +void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est) +{ + MODEL model[4]; + int lsp_indexes[LPC_ORD]; + float lsps[4][LPC_ORD]; + int Wo_index, e_index; + float e[4]; + float snr; + float ak[4][LPC_ORD+1]; + int i,j; + unsigned int nbit = 0; + float weight; + TIMER_VAR(recover_start); + + assert(c2 != NULL); + + /* only need to zero these out due to (unused) snr calculation */ + + for(i=0; i<4; i++) + for(j=1; j<=MAX_AMP; j++) + model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 4 x 10ms + frames */ + + model[0].voiced = unpack(bits, &nbit, 1); + model[1].voiced = unpack(bits, &nbit, 1); + model[2].voiced = unpack(bits, &nbit, 1); + model[3].voiced = unpack(bits, &nbit, 1); Wo_index = unpack(bits, &nbit, WO_BITS); - for(i=0; i<LPC_ORD; i++) { + model[3].Wo = decode_Wo(Wo_index); + model[3].L = PI/model[3].Wo; + + e_index = unpack(bits, &nbit, E_BITS); + e[3] = decode_energy(e_index); + + for(i=0; i<LSP_SCALAR_INDEXES; i++) { lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); } - energy_index = unpack(bits, &nbit, E_BITS); - voiced1 = unpack(bits, &nbit, 1); - voiced2 = unpack(bits, &nbit, 1); - assert(nbit == CODEC2_BITS_PER_FRAME); + decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); + check_lsp_order(&lsps[3][0], LPC_ORD); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); + + if (ber_est > 0.15) { + model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced = 0; + e[3] = decode_energy(10); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 200.0, 200.0); + fprintf(stderr, "soft mute\n"); + } + + /* interpolate ------------------------------------------------*/ + + /* Wo, energy, and LSPs are sampled every 40ms so we interpolate + the 3 frames in between */ + + TIMER_SAMPLE(recover_start); + for(i=0, weight=0.25; i<3; i++, weight += 0.25) { + interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight); + interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight); + e[i] = interp_energy2(c2->prev_e_dec, e[3],weight); + } + + /* then recover spectral amplitudes */ + + for(i=0; i<4; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); + aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, + c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); + apply_lpc_correction(&model[i]); + } + TIMER_SAMPLE_AND_LOG2(recover_start, " recover"); + + /* synthesise ------------------------------------------------*/ + + for(i=0; i<4; i++) + synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]); + + /* update memories for next frame ----------------------------*/ + + c2->prev_model_dec = model[3]; + c2->prev_e_dec = e[3]; + for(i=0; i<LPC_ORD; i++) + c2->prev_lsps_dec[i] = lsps[3][i]; + +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode_1200 + AUTHOR......: David Rowe + DATE CREATED: Nov 14 2011 + + Encodes 320 speech samples (40ms of speech) into 48 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm four times: + + frame 0: voicing bit + frame 1: voicing bit, joint VQ of Wo and E + frame 2: voicing bit + frame 3: voicing bit, joint VQ of Wo and E, VQ LSPs + + The bit allocation is: + + Parameter frame 2 frame 4 Total + ------------------------------------------------------- + Harmonic magnitudes (LSPs) 0 27 27 + Energy+Wo 8 8 16 + Voicing (10ms update) 2 2 4 + Spare 0 1 1 + TOTAL 10 38 48 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]) +{ + MODEL model; + float lsps[LPC_ORD]; + float lsps_[LPC_ORD]; + float ak[LPC_ORD+1]; + float e; + int lsp_indexes[LPC_ORD]; + int WoE_index; + int i; + int spare = 0; + unsigned int nbit = 0; + + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + + /* frame 1: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); + + /* frame 2: - voicing, joint Wo & E -------------------------------*/ + + analyse_one_frame(c2, &model, &speech[N]); + pack(bits, &nbit, model.voiced, 1); + + /* need to run this just to get LPC energy */ + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); + + /* frame 3: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, &speech[2*N]); + pack(bits, &nbit, model.voiced, 1); + + /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ + + analyse_one_frame(c2, &model, &speech[3*N]); + pack(bits, &nbit, model.voiced, 1); + + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + WoE_index = encode_WoE(&model, e, c2->xq_enc); + pack(bits, &nbit, WoE_index, WO_E_BITS); + + encode_lsps_vq(lsp_indexes, lsps, lsps_, LPC_ORD); + for(i=0; i<LSP_PRED_VQ_INDEXES; i++) { + pack(bits, &nbit, lsp_indexes[i], lsp_pred_vq_bits(i)); + } + pack(bits, &nbit, spare, 1); + + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_decode_1200 + AUTHOR......: David Rowe + DATE CREATED: 14 Feb 2012 + + Decodes frames of 48 bits into 320 samples (40ms) of speech. - /* decode integer codes to model parameters */ +\*---------------------------------------------------------------------------*/ - model.Wo = decode_Wo(Wo_index); - model.L = PI/model.Wo; - memset(&model.A, 0, (model.L+1)*sizeof(model.A[0])); - decode_amplitudes(&model, - ak, - lsp_indexes, - energy_index, - lsps, - &energy); +void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits) +{ + MODEL model[4]; + int lsp_indexes[LPC_ORD]; + float lsps[4][LPC_ORD]; + int WoE_index; + float e[4]; + float snr; + float ak[4][LPC_ORD+1]; + int i,j; + unsigned int nbit = 0; + float weight; - model.voiced = voiced2; - model_interp.voiced = voiced1; - model_interp.Wo = P_MAX/2; - memset(&model_interp.A, 0, MAX_AMP*sizeof(model_interp.A[0])); + assert(c2 != NULL); - /* interpolate middle frame's model parameters for adjacent frames */ + /* only need to zero these out due to (unused) snr calculation */ - interpolate_lsp(&model_interp, &c2->prev_model, &model, - c2->prev_lsps, c2->prev_energy, lsps, energy, ak_interp); - apply_lpc_correction(&model_interp); + for(i=0; i<4; i++) + for(j=1; j<=MAX_AMP; j++) + model[i].A[j] = 0.0; + + /* unpack bits from channel ------------------------------------*/ + + /* this will partially fill the model params for the 4 x 10ms + frames */ + + model[0].voiced = unpack(bits, &nbit, 1); + + model[1].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&model[1], &e[1], c2->xq_dec, WoE_index); + + model[2].voiced = unpack(bits, &nbit, 1); + + model[3].voiced = unpack(bits, &nbit, 1); + WoE_index = unpack(bits, &nbit, WO_E_BITS); + decode_WoE(&model[3], &e[3], c2->xq_dec, WoE_index); + + for(i=0; i<LSP_PRED_VQ_INDEXES; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_pred_vq_bits(i)); + } + decode_lsps_vq(lsp_indexes, &lsps[3][0], LPC_ORD); + check_lsp_order(&lsps[3][0], LPC_ORD); + bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); + + /* interpolate ------------------------------------------------*/ + + /* Wo and energy are sampled every 20ms, so we interpolate just 1 + 10ms frame between 20ms samples */ + + interp_Wo(&model[0], &c2->prev_model_dec, &model[1]); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + interp_Wo(&model[2], &model[1], &model[3]); + e[2] = interp_energy(e[1], e[3]); + + /* LSPs are sampled every 40ms so we interpolate the 3 frames in + between, then recover spectral amplitudes */ + + for(i=0, weight=0.25; i<3; i++, weight += 0.25) { + interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight); + } + for(i=0; i<4; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); + aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, + c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); + apply_lpc_correction(&model[i]); + } - /* synthesis two 10ms frames */ + /* synthesise ------------------------------------------------*/ - synthesise_one_frame(c2, speech, &model_interp, ak_interp); - synthesise_one_frame(c2, &speech[N], &model, ak); + for(i=0; i<4; i++) + synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]); - /* update memories (decode states) for next time */ + /* update memories for next frame ----------------------------*/ - memcpy(&c2->prev_model, &model, sizeof(MODEL)); - memcpy(c2->prev_lsps, lsps, sizeof(lsps)); - c2->prev_energy = energy; + c2->prev_model_dec = model[3]; + c2->prev_e_dec = e[3]; + for(i=0; i<LPC_ORD; i++) + c2->prev_lsps_dec[i] = lsps[3][i]; } + /*---------------------------------------------------------------------------*\ FUNCTION....: synthesise_one_frame() @@ -279,13 +1304,30 @@ void codec2_decode(void *codec2_state, short speech[], \*---------------------------------------------------------------------------*/ -void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model, float ak[]) +void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, float ak[]) { int i; + TIMER_VAR(phase_start, pf_start, synth_start); + + #ifdef DUMP + dump_quantised_model(model); + #endif + + TIMER_SAMPLE(phase_start); + + phase_synth_zero_order(c2->fft_fwd_cfg, model, ak, &c2->ex_phase, LPC_ORD); + + TIMER_SAMPLE_AND_LOG(pf_start,phase_start, " phase_synth"); - phase_synth_zero_order(model, ak, &c2->ex_phase, LPC_ORD); postfilter(model, &c2->bg_est); - synthesise(c2->Sn_, model, c2->Pn, 1); + + TIMER_SAMPLE_AND_LOG(synth_start, pf_start, " postfilter"); + + synthesise(c2->fft_inv_cfg, c2->Sn_, model, c2->Pn, 1); + + TIMER_SAMPLE_AND_LOG2(synth_start, " synth"); + + ear_protection(c2->Sn_, N); for(i=0; i<N; i++) { if (c2->Sn_[i] > 32767.0) @@ -309,13 +1351,14 @@ void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model, float ak[]) \*---------------------------------------------------------------------------*/ -void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]) +void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) { COMP Sw[FFT_ENC]; COMP Sw_[FFT_ENC]; COMP Ew[FFT_ENC]; float pitch; int i; + TIMER_VAR(dft_start, nlp_start, model_start, two_stage, estamps); /* Read input speech */ @@ -324,19 +1367,155 @@ void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]) for(i=0; i<N; i++) c2->Sn[i+M-N] = speech[i]; - dft_speech(Sw, c2->Sn, c2->w); + TIMER_SAMPLE(dft_start); + dft_speech(c2->fft_fwd_cfg, Sw, c2->Sn, c2->w); + TIMER_SAMPLE_AND_LOG(nlp_start, dft_start, " dft_speech"); /* Estimate pitch */ - nlp(c2->nlp,c2->Sn,N,M,P_MIN,P_MAX,&pitch,Sw,&c2->prev_Wo); + nlp(c2->nlp,c2->Sn,N,P_MIN,P_MAX,&pitch,Sw, c2->W, &c2->prev_Wo_enc); + TIMER_SAMPLE_AND_LOG(model_start, nlp_start, " nlp"); + model->Wo = TWO_PI/pitch; model->L = PI/model->Wo; /* estimate model parameters */ two_stage_pitch_refinement(model, Sw); - estimate_amplitudes(model, Sw, c2->W); - est_voicing_mbe(model, Sw, c2->W, Sw_, Ew, c2->prev_Wo); + TIMER_SAMPLE_AND_LOG(two_stage, model_start, " two_stage"); + estimate_amplitudes(model, Sw, c2->W, 0); + TIMER_SAMPLE_AND_LOG(estamps, two_stage, " est_amps"); + est_voicing_mbe(model, Sw, c2->W, Sw_, Ew, c2->prev_Wo_enc); + c2->prev_Wo_enc = model->Wo; + TIMER_SAMPLE_AND_LOG2(estamps, " est_voicing"); + #ifdef DUMP + dump_model(model); + #endif +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: ear_protection() + AUTHOR......: David Rowe + DATE CREATED: Nov 7 2012 + + Limits output level to protect ears when there are bit errors or the input + is overdriven. This doesn't correct or mask bit erros, just reduces the + worst of their damage. + +\*---------------------------------------------------------------------------*/ + +static void ear_protection(float in_out[], int n) { + float max_sample, over, gain; + int i; + + /* find maximum sample in frame */ + + max_sample = 0.0; + for(i=0; i<n; i++) + if (in_out[i] > max_sample) + max_sample = in_out[i]; + + /* determine how far above set point */ + + over = max_sample/30000.0; + + /* If we are x dB over set point we reduce level by 2x dB, this + attenuates major excursions in amplitude (likely to be caused + by bit errors) more than smaller ones */ + + if (over > 1.0) { + gain = 1.0/(over*over); + //fprintf(stderr, "gain: %f\n", gain); + for(i=0; i<n; i++) + in_out[i] *= gain; + } +} + +void CODEC2_WIN32SUPPORT codec2_set_lpc_post_filter(struct CODEC2 *c2, int enable, int bass_boost, float beta, float gamma) +{ + assert((beta >= 0.0) && (beta <= 1.0)); + assert((gamma >= 0.0) && (gamma <= 1.0)); + c2->lpc_pf = enable; + c2->bass_boost = bass_boost; + c2->beta = beta; + c2->gamma = gamma; +} + +/* + Allows optional stealing of one of the voicing bits for use as a + spare bit, only 1300 & 1400 & 1600 bit/s supported for now. + Experimental method of sending voice/data frames for FreeDV. +*/ + +int CODEC2_WIN32SUPPORT codec2_get_spare_bit_index(struct CODEC2 *c2) +{ + assert(c2 != NULL); + + switch(c2->mode) { + case CODEC2_MODE_1300: + return 2; // bit 2 (3th bit) is v2 (third voicing bit) + break; + case CODEC2_MODE_1400: + return 10; // bit 10 (11th bit) is v2 (third voicing bit) + break; + case CODEC2_MODE_1600: + return 15; // bit 15 (16th bit) is v2 (third voicing bit) + break; + } + + return -1; +} + +/* + Reconstructs the spare voicing bit. Note works on unpacked bits + for convenience. +*/ + +int CODEC2_WIN32SUPPORT codec2_rebuild_spare_bit(struct CODEC2 *c2, int unpacked_bits[]) +{ + int v1,v3; + + assert(c2 != NULL); + + v1 = unpacked_bits[1]; + + switch(c2->mode) { + case CODEC2_MODE_1300: + + v3 = unpacked_bits[1+1+1]; + + /* if either adjacent frame is voiced, make this one voiced */ + + unpacked_bits[2] = (v1 || v3); + + return 0; + + break; + + case CODEC2_MODE_1400: + + v3 = unpacked_bits[1+1+8+1]; + + /* if either adjacent frame is voiced, make this one voiced */ + + unpacked_bits[10] = (v1 || v3); + + return 0; + + break; + + case CODEC2_MODE_1600: + v3 = unpacked_bits[1+1+8+5+1]; + + /* if either adjacent frame is voiced, make this one voiced */ + + unpacked_bits[15] = (v1 || v3); + + return 0; + + break; + } - c2->prev_Wo = model->Wo; + return -1; } diff --git a/gr-vocoder/lib/codec2/codec2.h b/gr-vocoder/lib/codec2/codec2.h index f812a05983..2f0c2b1246 100644 --- a/gr-vocoder/lib/codec2/codec2.h +++ b/gr-vocoder/lib/codec2/codec2.h @@ -2,10 +2,10 @@ FILE........: codec2.h AUTHOR......: David Rowe - DATE CREATED: 21/8/2010 + DATE CREATED: 21 August 2010 - Codec2 fully quantised encoder and decoder functions. If you want use - codec2, these are the functions you need to call. + Codec 2 fully quantised encoder and decoder functions. If you want use + Codec 2, these are the functions you need to call. \*---------------------------------------------------------------------------*/ @@ -26,17 +26,49 @@ along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#ifdef __cplusplus + extern "C" { +#endif + #ifndef __CODEC2__ #define __CODEC2__ -#define CODEC2_SAMPLES_PER_FRAME 160 -#define CODEC2_BITS_PER_FRAME 50 -#define CODEC2_BYTES_PER_FRAME ((CODEC2_BITS_PER_FRAME + 7) / 8) // == 8 bytes when packing the 50 bits +/* set up the calling convention for DLL function import/export for + WIN32 cross compiling */ + +#ifdef __CODEC2_WIN32__ +#ifdef __CODEC2_BUILDING_DLL__ +#define CODEC2_WIN32SUPPORT __declspec(dllexport) __stdcall +#else +#define CODEC2_WIN32SUPPORT __declspec(dllimport) __stdcall +#endif +#else +#define CODEC2_WIN32SUPPORT +#endif + +#define CODEC2_MODE_3200 0 +#define CODEC2_MODE_2400 1 +#define CODEC2_MODE_1600 2 +#define CODEC2_MODE_1400 3 +#define CODEC2_MODE_1300 4 +#define CODEC2_MODE_1200 5 -void *codec2_create(); -void codec2_destroy(void *codec2_state); -void codec2_encode(void *codec2_state, unsigned char * bits, short speech_in[]); -void codec2_decode(void *codec2_state, short speech_out[], - const unsigned char * bits); +struct CODEC2; + +struct CODEC2 * CODEC2_WIN32SUPPORT codec2_create(int mode); +void CODEC2_WIN32SUPPORT codec2_destroy(struct CODEC2 *codec2_state); +void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *codec2_state, unsigned char * bits, short speech_in[]); + void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits, float ber_est); +int CODEC2_WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *codec2_state); +int CODEC2_WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *codec2_state); + +void CODEC2_WIN32SUPPORT codec2_set_lpc_post_filter(struct CODEC2 *codec2_state, int enable, int bass_boost, float beta, float gamma); +int CODEC2_WIN32SUPPORT codec2_get_spare_bit_index(struct CODEC2 *codec2_state); +int CODEC2_WIN32SUPPORT codec2_rebuild_spare_bit(struct CODEC2 *codec2_state, int unpacked_bits[]); #endif + +#ifdef __cplusplus +} +#endif + diff --git a/gr-vocoder/lib/codec2/codec2_fdmdv.h b/gr-vocoder/lib/codec2/codec2_fdmdv.h new file mode 100644 index 0000000000..b7da96f629 --- /dev/null +++ b/gr-vocoder/lib/codec2/codec2_fdmdv.h @@ -0,0 +1,124 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: codec2_fdmdv.h + AUTHOR......: David Rowe + DATE CREATED: April 14 2012 + + A 1400 bit/s (nominal) Frequency Division Multiplexed Digital Voice + (FDMDV) modem. Used for digital audio over HF SSB. See + README_fdmdv.txt for more information, and fdmdv_mod.c and + fdmdv_demod.c for example usage. + + The name codec2_fdmdv.h is used to make it unique when "make + installed". + + References: + + [1] http://n1su.com/fdmdv/FDMDV_Docs_Rel_1_4b.pdf + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2012 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __FDMDV__ +#define __FDMDV__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* set up the calling convention for DLL function import/export for + WIN32 cross compiling */ + +#ifdef __CODEC2_WIN32__ +#ifdef __CODEC2_BUILDING_DLL__ +#define CODEC2_WIN32SUPPORT __declspec(dllexport) __stdcall +#else +#define CODEC2_WIN32SUPPORT __declspec(dllimport) __stdcall +#endif +#else +#define CODEC2_WIN32SUPPORT +#endif + +#include "comp.h" + +#define FDMDV_NC 14 /* default number of data carriers */ +#define FDMDV_NC_MAX 20 /* maximum number of data carriers */ +#define FDMDV_BITS_PER_FRAME 28 /* 20ms frames, for nominal 1400 bit/s */ +#define FDMDV_NOM_SAMPLES_PER_FRAME 160 /* modulator output samples/frame and nominal demod samples/frame */ + /* at 8000 Hz sample rate */ +#define FDMDV_MAX_SAMPLES_PER_FRAME 200 /* max demod samples/frame, use this to allocate storage */ +#define FDMDV_SCALE 1000 /* suggested scaling for 16 bit shorts */ +#define FDMDV_FCENTRE 1500 /* Centre frequency, Nc/2 carriers below this, Nc/2 carriers above (Hz) */ + +/* 8 to 48 kHz sample rate conversion */ + +#define FDMDV_OS 6 /* oversampling rate */ +#define FDMDV_OS_TAPS 48 /* number of OS filter taps */ + +/* FFT points */ + +#define FDMDV_NSPEC 512 +#define FDMDV_MAX_F_HZ 4000 + +/* FDMDV states and stats structures */ + +struct FDMDV; + +struct FDMDV_STATS { + int Nc; + float snr_est; /* estimated SNR of rx signal in dB (3 kHz noise BW) */ + COMP rx_symbols[FDMDV_NC_MAX+1]; /* latest received symbols, for scatter plot */ + int sync; /* demod sync state */ + float foff; /* estimated freq offset in Hz */ + float rx_timing; /* estimated optimum timing offset in samples */ + float clock_offset; /* Estimated tx/rx sample clock offset in ppm */ +}; + +struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc); +void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv_state); +void CODEC2_WIN32SUPPORT fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state); +int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv_state); +float CODEC2_WIN32SUPPORT fdmdv_get_fsep(struct FDMDV *fdmdv_state); +void CODEC2_WIN32SUPPORT fdmdv_set_fsep(struct FDMDV *fdmdv_state, float fsep); + +void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit); +void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin); + +void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]); +int CODEC2_WIN32SUPPORT fdmdv_error_pattern_size(struct FDMDV *fdmdv_state); +void CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], int *bit_errors, int *ntest_bits, int rx_bits[]); + +void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct FDMDV_STATS *fdmdv_stats); +void CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *fdmdv_state, float mag_dB[], COMP rx_fdm[], int nin); + +void CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n); +void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n); + +void CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_rect, COMP *foff_phase_rect, int nin); + +/* debug/development function(s) */ + +void CODEC2_WIN32SUPPORT fdmdv_dump_osc_mags(struct FDMDV *f); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/gr-vocoder/lib/codec2/codec2_fifo.h b/gr-vocoder/lib/codec2/codec2_fifo.h new file mode 100644 index 0000000000..9140fd7f78 --- /dev/null +++ b/gr-vocoder/lib/codec2/codec2_fifo.h @@ -0,0 +1,51 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: codec2_fifo.h + AUTHOR......: David Rowe + DATE CREATED: Oct 15 2012 + + A FIFO design useful in gluing the FDMDV modem and codec together in + integrated applications. + + The name codec2_fifo.h is used to make it unique when "make + installed". + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2012 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __FIFO__ +#define __FIFO__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct FIFO; + +struct FIFO *fifo_create(int nshort); +void fifo_destroy(struct FIFO *fifo); +int fifo_write(struct FIFO *fifo, short data[], int n); +int fifo_read(struct FIFO *fifo, short data[], int n); +int fifo_used(struct FIFO *fifo); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/gr-vocoder/lib/codec2/codec2_internal.h b/gr-vocoder/lib/codec2/codec2_internal.h index 3aa5300b10..246d1ae6af 100644 --- a/gr-vocoder/lib/codec2/codec2_internal.h +++ b/gr-vocoder/lib/codec2/codec2_internal.h @@ -2,15 +2,15 @@ FILE........: codec2_internal.h AUTHOR......: David Rowe - DATE CREATED: 22 March 2011 + DATE CREATED: April 16 2012 - Some internal structures and states broken out here as they are useful for - testing and development. + Header file for Codec2 internal states, exposed via this header + file to assist in testing. \*---------------------------------------------------------------------------*/ /* - Copyright (C) 2011 David Rowe + Copyright (C) 2012 David Rowe All rights reserved. @@ -27,37 +27,36 @@ */ #ifndef __CODEC2_INTERNAL__ -#define __CODEC2_INTERNAL__ - -/*---------------------------------------------------------------------------*\ - - STATES - -\*---------------------------------------------------------------------------*/ - -typedef struct { - float w[M]; /* time domain hamming window */ - COMP W[FFT_ENC]; /* DFT of w[] */ - float Pn[2*N]; /* trapezoidal synthesis window */ - float Sn[M]; /* input speech */ - float hpf_states[2]; /* high pass filter states */ - void *nlp; /* pitch predictor states */ - float Sn_[2*N]; /* synthesised output speech */ - float ex_phase; /* excitation model phase track */ - float bg_est; /* background noise estimate for post filter */ - float prev_Wo; /* previous frame's pitch estimate */ - MODEL prev_model; /* previous frame's model parameters */ - float prev_lsps[LPC_ORD]; /* previous frame's LSPs */ - float prev_energy; /* previous frame's LPC energy */ -} CODEC2; - -/*---------------------------------------------------------------------------*\ - - FUNCTION HEADERS - -\*---------------------------------------------------------------------------*/ - -void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]); -void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model,float ak[]); +#define __CODEC2_INTERNAL__ + +struct CODEC2 { + int mode; + kiss_fft_cfg fft_fwd_cfg; /* forward FFT config */ + float w[M]; /* time domain hamming window */ + COMP W[FFT_ENC]; /* DFT of w[] */ + float Pn[2*N]; /* trapezoidal synthesis window */ + float Sn[M]; /* input speech */ + float hpf_states[2]; /* high pass filter states */ + void *nlp; /* pitch predictor states */ + + kiss_fft_cfg fft_inv_cfg; /* inverse FFT config */ + float Sn_[2*N]; /* synthesised output speech */ + float ex_phase; /* excitation model phase track */ + float bg_est; /* background noise estimate for post filter */ + float prev_Wo_enc; /* previous frame's pitch estimate */ + MODEL prev_model_dec; /* previous frame's model parameters */ + float prev_lsps_dec[LPC_ORD]; /* previous frame's LSPs */ + float prev_e_dec; /* previous frame's LPC energy */ + + int lpc_pf; /* LPC post filter on */ + int bass_boost; /* LPC post filter bass boost */ + float beta; /* LPC post filter parameters */ + float gamma; + + float xq_enc[2]; /* joint pitch and energy VQ states */ + float xq_dec[2]; + + int smoothing; /* enable smoothing for channels with errors */ +}; #endif diff --git a/gr-vocoder/lib/codec2/defines.h b/gr-vocoder/lib/codec2/defines.h index 75064fae14..4b81357ea6 100644 --- a/gr-vocoder/lib/codec2/defines.h +++ b/gr-vocoder/lib/codec2/defines.h @@ -68,8 +68,8 @@ typedef struct { float Wo; /* fundamental frequency estimate in radians */ int L; /* number of harmonics */ - float A[MAX_AMP]; /* amplitiude of each harmonic */ - float phi[MAX_AMP]; /* phase of each harmonic */ + float A[MAX_AMP+1]; /* amplitiude of each harmonic */ + float phi[MAX_AMP+1]; /* phase of each harmonic */ int voiced; /* non-zero if this frame is voiced */ } MODEL; @@ -81,8 +81,14 @@ struct lsp_codebook { int m; /* elements in codebook */ const float * cb; /* The elements */ }; + extern const struct lsp_codebook lsp_cb[]; extern const struct lsp_codebook lsp_cbd[]; -extern const struct lsp_codebook lsp_cbdvq[]; +extern const struct lsp_codebook lsp_cbvq[]; +extern const struct lsp_codebook lsp_cbjnd[]; +extern const struct lsp_codebook lsp_cbdt[]; +extern const struct lsp_codebook lsp_cbjvm[]; +extern const struct lsp_codebook lsp_cbvqanssi[]; +extern const struct lsp_codebook ge_cb[]; #endif diff --git a/gr-vocoder/lib/codec2/dump.c b/gr-vocoder/lib/codec2/dump.c index 1dc34c858d..cc935d73cf 100644 --- a/gr-vocoder/lib/codec2/dump.c +++ b/gr-vocoder/lib/codec2/dump.c @@ -32,6 +32,13 @@ #include <string.h> #include <math.h> +#ifdef __EMBEDDED__ +#include "gdb_stdio.h" +#define fprintf gdb_stdio_fprintf +#define fopen gdb_stdio_fopen +#define fclose gdb_stdio_fclose +#endif + #ifdef DUMP static int dumpon = 0; @@ -41,8 +48,12 @@ static FILE *few = NULL; static FILE *fsw_ = NULL; static FILE *fmodel = NULL; static FILE *fqmodel = NULL; +static FILE *fpwb = NULL; static FILE *fpw = NULL; +static FILE *frw = NULL; static FILE *flsp = NULL; +static FILE *fweights = NULL; +static FILE *flsp_ = NULL; static FILE *fphase = NULL; static FILE *fphase_ = NULL; static FILE *ffw = NULL; @@ -50,11 +61,13 @@ static FILE *fe = NULL; static FILE *fsq = NULL; static FILE *fdec = NULL; static FILE *fsnr = NULL; +static FILE *flpcsnr = NULL; static FILE *fak = NULL; +static FILE *fak_ = NULL; static FILE *fbg = NULL; static FILE *fE = NULL; static FILE *frk = NULL; -static FILE *fres = NULL; +static FILE *fhephase = NULL; static char prefix[MAX_STR]; @@ -76,10 +89,18 @@ void dump_off(){ fclose(fmodel); if (fqmodel != NULL) fclose(fqmodel); + if (fpwb != NULL) + fclose(fpwb); if (fpw != NULL) fclose(fpw); + if (frw != NULL) + fclose(frw); if (flsp != NULL) fclose(flsp); + if (fweights != NULL) + fclose(fweights); + if (flsp_ != NULL) + fclose(flsp_); if (fphase != NULL) fclose(fphase); if (fphase_ != NULL) @@ -94,16 +115,20 @@ void dump_off(){ fclose(fdec); if (fsnr != NULL) fclose(fsnr); + if (flpcsnr != NULL) + fclose(flpcsnr); if (fak != NULL) fclose(fak); + if (fak_ != NULL) + fclose(fak_); if (fbg != NULL) fclose(fbg); if (fE != NULL) fclose(fE); if (frk != NULL) fclose(frk); - if (fres != NULL) - fclose(fres); + if (fhephase != NULL) + fclose(fhephase); } void dump_Sn(float Sn[]) { @@ -186,6 +211,7 @@ void dump_Ew(COMP Ew[]) { void dump_model(MODEL *model) { int l; char s[MAX_STR]; + char line[2048]; if (!dumpon) return; @@ -195,18 +221,25 @@ void dump_model(MODEL *model) { assert(fmodel != NULL); } - fprintf(fmodel,"%f\t%d\t", model->Wo, model->L); - for(l=1; l<=model->L; l++) - fprintf(fmodel,"%f\t",model->A[l]); - for(l=model->L+1; l<MAX_AMP; l++) - fprintf(fmodel,"0.0\t"); - fprintf(fmodel,"%d\t",model->voiced); - fprintf(fmodel,"\n"); + sprintf(line,"%12f %12d ", model->Wo, model->L); + for(l=1; l<=model->L; l++) { + sprintf(s,"%12f ",model->A[l]); + strcat(line, s); + } + for(l=model->L+1; l<=MAX_AMP; l++) { + sprintf(s,"%12f ", 0.0); + strcat(line,s); + } + + sprintf(s,"%d\n",model->voiced); + strcat(line,s); + fprintf(fmodel,"%s",line); } void dump_quantised_model(MODEL *model) { int l; char s[MAX_STR]; + char line[2048]; if (!dumpon) return; @@ -216,32 +249,19 @@ void dump_quantised_model(MODEL *model) { assert(fqmodel != NULL); } - fprintf(fqmodel,"%f\t%d\t", model->Wo, model->L); - for(l=1; l<=model->L; l++) - fprintf(fqmodel,"%f\t",model->A[l]); - for(l=model->L+1; l<MAX_AMP; l++) - fprintf(fqmodel,"0.0\t"); - fprintf(fqmodel,"\n"); -} - -void dump_resample(float w[], float A[], int n) { - int l; - char s[MAX_STR]; - - if (!dumpon) return; - - if (fres == NULL) { - sprintf(s,"%s_res.txt", prefix); - fres = fopen(s, "wt"); - assert(fres != NULL); + sprintf(line,"%12f %12d ", model->Wo, model->L); + for(l=1; l<=model->L; l++) { + sprintf(s,"%12f ",model->A[l]); + strcat(line, s); + } + for(l=model->L+1; l<=MAX_AMP; l++) { + sprintf(s,"%12f ", 0.0); + strcat(line, s); } - fprintf(fres,"%d\t",n); - for(l=0; l<n; l++) - fprintf(fres,"%f\t",w[l]); - for(l=0; l<n; l++) - fprintf(fres,"%f\t",A[l]); - fprintf(fres,"\n"); + sprintf(s,"%d\n",model->voiced); + strcat(line, s); + fprintf(fqmodel, "%s", line); } void dump_phase(float phase[], int L) { @@ -258,7 +278,7 @@ void dump_phase(float phase[], int L) { for(l=1; l<=L; l++) fprintf(fphase,"%f\t",phase[l]); - for(l=L+1; l<MAX_AMP; l++) + for(l=L+1; l<=MAX_AMP; l++) fprintf(fphase,"%f\t",0.0); fprintf(fphase,"\n"); } @@ -282,6 +302,25 @@ void dump_phase_(float phase_[], int L) { fprintf(fphase_,"\n"); } + +void dump_hephase(int ind[], int dim) { + int m; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fhephase == NULL) { + sprintf(s,"%s_hephase.txt", prefix); + fhephase = fopen(s, "wt"); + assert(fhephase != NULL); + } + + for(m=0; m<dim; m++) + fprintf(fhephase,"%d\t",ind[m]); + fprintf(fhephase,"\n"); +} + + void dump_snr(float snr) { char s[MAX_STR]; @@ -296,6 +335,39 @@ void dump_snr(float snr) { fprintf(fsnr,"%f\n",snr); } +void dump_lpc_snr(float snr) { + char s[MAX_STR]; + + if (!dumpon) return; + + if (flpcsnr == NULL) { + sprintf(s,"%s_lpc_snr.txt", prefix); + flpcsnr = fopen(s, "wt"); + assert(flpcsnr != NULL); + } + + fprintf(flpcsnr,"%f\n",snr); +} + +/* Pw "before" post filter so we can plot before and after */ + +void dump_Pwb(COMP Pwb[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fpwb == NULL) { + sprintf(s,"%s_pwb.txt", prefix); + fpwb = fopen(s, "wt"); + assert(fpwb != NULL); + } + + for(i=0; i<FFT_ENC/2; i++) + fprintf(fpwb,"%f\t",Pwb[i].real); + fprintf(fpwb,"\n"); +} + void dump_Pw(COMP Pw[]) { int i; char s[MAX_STR]; @@ -308,11 +380,45 @@ void dump_Pw(COMP Pw[]) { assert(fpw != NULL); } - for(i=0; i<FFT_DEC/2; i++) + for(i=0; i<FFT_ENC/2; i++) fprintf(fpw,"%f\t",Pw[i].real); fprintf(fpw,"\n"); } +void dump_Rw(float Rw[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (frw == NULL) { + sprintf(s,"%s_rw.txt", prefix); + frw = fopen(s, "wt"); + assert(frw != NULL); + } + + for(i=0; i<FFT_ENC/2; i++) + fprintf(frw,"%f\t",Rw[i]); + fprintf(frw,"\n"); +} + +void dump_weights(float w[], int order) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fweights == NULL) { + sprintf(s,"%s_weights.txt", prefix); + fweights = fopen(s, "wt"); + assert(fweights != NULL); + } + + for(i=0; i<order; i++) + fprintf(fweights,"%f\t", w[i]); + fprintf(fweights,"\n"); +} + void dump_lsp(float lsp[]) { int i; char s[MAX_STR]; @@ -330,6 +436,23 @@ void dump_lsp(float lsp[]) { fprintf(flsp,"\n"); } +void dump_lsp_(float lsp_[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (flsp_ == NULL) { + sprintf(s,"%s_lsp_.txt", prefix); + flsp_ = fopen(s, "wt"); + assert(flsp_ != NULL); + } + + for(i=0; i<10; i++) + fprintf(flsp_,"%f\t",lsp_[i]); + fprintf(flsp_,"\n"); +} + void dump_ak(float ak[], int order) { int i; char s[MAX_STR]; @@ -347,6 +470,23 @@ void dump_ak(float ak[], int order) { fprintf(fak,"\n"); } +void dump_ak_(float ak_[], int order) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fak_ == NULL) { + sprintf(s,"%s_ak_.txt", prefix); + fak_ = fopen(s, "wt"); + assert(fak_ != NULL); + } + + for(i=0; i<=order; i++) + fprintf(fak_,"%f\t",ak_[i]); + fprintf(fak_,"\n"); +} + void dump_Fw(COMP Fw[]) { int i; char s[MAX_STR]; diff --git a/gr-vocoder/lib/codec2/dump.h b/gr-vocoder/lib/codec2/dump.h index 4b92d009d9..a61fdaab69 100644 --- a/gr-vocoder/lib/codec2/dump.h +++ b/gr-vocoder/lib/codec2/dump.h @@ -26,7 +26,10 @@ #ifndef __DUMP__ #define __DUMP__ +#include "defines.h" #include "comp.h" +#include "kiss_fft.h" +#include "codec2_internal.h" void dump_on(char filename_prefix[]); void dump_off(); @@ -40,17 +43,23 @@ void dump_Ew(COMP Ew[]); void dump_model(MODEL *m); void dump_quantised_model(MODEL *m); +void dump_Pwn(COMP Pw[]); void dump_Pw(COMP Pw[]); +void dump_Rw(float Rw[]); void dump_lsp(float lsp[]); +void dump_weights(float w[], int ndim); +void dump_lsp_(float lsp_[]); void dump_ak(float ak[], int order); +void dump_ak_(float ak[], int order); void dump_E(float E); -void dump_resample(float w[], float A[], int n); +void dump_lpc_snr(float snr); /* phase modelling */ void dump_snr(float snr); void dump_phase(float phase[], int L); void dump_phase_(float phase[], int L); +void dump_hephase(int ind[], int dim); /* NLP states */ @@ -63,5 +72,6 @@ void dump_Rk(float Rk[]); /* post filter */ void dump_bg(float e, float bg_est, float percent_uv); +void dump_Pwb(COMP Pwb[]); #endif diff --git a/gr-vocoder/lib/codec2/fdmdv.c b/gr-vocoder/lib/codec2/fdmdv.c new file mode 100644 index 0000000000..6af1cf4c6d --- /dev/null +++ b/gr-vocoder/lib/codec2/fdmdv.c @@ -0,0 +1,1569 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: fdmdv.c + AUTHOR......: David Rowe + DATE CREATED: April 14 2012 + + Functions that implement the FDMDV modem. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2012 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +/*---------------------------------------------------------------------------*\ + + INCLUDES + +\*---------------------------------------------------------------------------*/ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include "fdmdv_internal.h" +#include "codec2_fdmdv.h" +#include "rn.h" +#include "test_bits.h" +#include "pilot_coeff.h" +#include "kiss_fft.h" +#include "hanning.h" +#include "os.h" + +static int sync_uw[] = {1,-1,1,-1,1,-1}; + +/*---------------------------------------------------------------------------* \ + + FUNCTIONS + +\*---------------------------------------------------------------------------*/ + +static COMP cneg(COMP a) +{ + COMP res; + + res.real = -a.real; + res.imag = -a.imag; + + return res; +} + +static COMP cconj(COMP a) +{ + COMP res; + + res.real = a.real; + res.imag = -a.imag; + + return res; +} + +static COMP cmult(COMP a, COMP b) +{ + COMP res; + + res.real = a.real*b.real - a.imag*b.imag; + res.imag = a.real*b.imag + a.imag*b.real; + + return res; +} + +static COMP fcmult(float a, COMP b) +{ + COMP res; + + res.real = a*b.real; + res.imag = a*b.imag; + + return res; +} + +static COMP cadd(COMP a, COMP b) +{ + COMP res; + + res.real = a.real + b.real; + res.imag = a.imag + b.imag; + + return res; +} + +static float cabsolute(COMP a) +{ + return sqrt(pow(a.real, 2.0) + pow(a.imag, 2.0)); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_create + AUTHOR......: David Rowe + DATE CREATED: 16/4/2012 + + Create and initialise an instance of the modem. Returns a pointer + to the modem states or NULL on failure. One set of states is + sufficient for a full duplex modem. + +\*---------------------------------------------------------------------------*/ + +struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc) +{ + struct FDMDV *f; + int c, i, k; + + assert(NC == FDMDV_NC_MAX); /* check public and private #defines match */ + assert(Nc <= NC); + assert(FDMDV_NOM_SAMPLES_PER_FRAME == M); + assert(FDMDV_MAX_SAMPLES_PER_FRAME == (M+M/P)); + + f = (struct FDMDV*)malloc(sizeof(struct FDMDV)); + if (f == NULL) + return NULL; + + f->Nc = Nc; + + f->ntest_bits = Nc*NB*4; + f->current_test_bit = 0; + f->rx_test_bits_mem = (int*)malloc(sizeof(int)*f->ntest_bits); + assert(f->rx_test_bits_mem != NULL); + for(i=0; i<f->ntest_bits; i++) + f->rx_test_bits_mem[i] = 0; + assert((sizeof(test_bits)/sizeof(int)) >= f->ntest_bits); + + f->old_qpsk_mapping = 0; + + f->tx_pilot_bit = 0; + + for(c=0; c<Nc+1; c++) { + f->prev_tx_symbols[c].real = 1.0; + f->prev_tx_symbols[c].imag = 0.0; + f->prev_rx_symbols[c].real = 1.0; + f->prev_rx_symbols[c].imag = 0.0; + + for(k=0; k<NSYM; k++) { + f->tx_filter_memory[c][k].real = 0.0; + f->tx_filter_memory[c][k].imag = 0.0; + } + + for(k=0; k<NFILTER; k++) { + f->rx_filter_memory[c][k].real = 0.0; + f->rx_filter_memory[c][k].imag = 0.0; + } + + /* Spread initial FDM carrier phase out as far as possible. + This helped PAPR for a few dB. We don't need to adjust rx + phase as DQPSK takes care of that. */ + + f->phase_tx[c].real = cos(2.0*PI*c/(Nc+1)); + f->phase_tx[c].imag = sin(2.0*PI*c/(Nc+1)); + + f->phase_rx[c].real = 1.0; + f->phase_rx[c].imag = 0.0; + + for(k=0; k<NT*P; k++) { + f->rx_filter_mem_timing[c][k].real = 0.0; + f->rx_filter_mem_timing[c][k].imag = 0.0; + } + for(k=0; k<NFILTERTIMING; k++) { + f->rx_baseband_mem_timing[c][k].real = 0.0; + f->rx_baseband_mem_timing[c][k].imag = 0.0; + } + } + + fdmdv_set_fsep(f, FSEP); + f->freq[Nc].real = cos(2.0*PI*FDMDV_FCENTRE/FS); + f->freq[Nc].imag = sin(2.0*PI*FDMDV_FCENTRE/FS); + + /* Generate DBPSK pilot Look Up Table (LUT) */ + + generate_pilot_lut(f->pilot_lut, &f->freq[Nc]); + + /* freq Offset estimation states */ + + f->fft_pilot_cfg = kiss_fft_alloc (MPILOTFFT, 0, NULL, NULL); + assert(f->fft_pilot_cfg != NULL); + + for(i=0; i<NPILOTBASEBAND; i++) { + f->pilot_baseband1[i].real = f->pilot_baseband2[i].real = 0.0; + f->pilot_baseband1[i].imag = f->pilot_baseband2[i].imag = 0.0; + } + f->pilot_lut_index = 0; + f->prev_pilot_lut_index = 3*M; + + for(i=0; i<NPILOTLPF; i++) { + f->pilot_lpf1[i].real = f->pilot_lpf2[i].real = 0.0; + f->pilot_lpf1[i].imag = f->pilot_lpf2[i].imag = 0.0; + } + + f->foff = 0.0; + f->foff_rect.real = 1.0; + f->foff_rect.imag = 0.0; + f->foff_phase_rect.real = 1.0; + f->foff_phase_rect.imag = 0.0; + + f->fest_state = 0; + f->sync = 0; + f->timer = 0; + for(i=0; i<NSYNC_MEM; i++) + f->sync_mem[i] = 0; + + for(c=0; c<Nc+1; c++) { + f->sig_est[c] = 0.0; + f->noise_est[c] = 0.0; + } + + for(i=0; i<2*FDMDV_NSPEC; i++) + f->fft_buf[i] = 0.0; + f->fft_cfg = kiss_fft_alloc (2*FDMDV_NSPEC, 0, NULL, NULL); + assert(f->fft_cfg != NULL); + + + return f; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_destroy + AUTHOR......: David Rowe + DATE CREATED: 16/4/2012 + + Destroy an instance of the modem. + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv) +{ + assert(fdmdv != NULL); + KISS_FFT_FREE(fdmdv->fft_pilot_cfg); + KISS_FFT_FREE(fdmdv->fft_cfg); + free(fdmdv->rx_test_bits_mem); + free(fdmdv); +} + + +void CODEC2_WIN32SUPPORT fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv) { + fdmdv->old_qpsk_mapping = 1; +} + + +int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv) +{ + return (fdmdv->Nc * NB); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_get_test_bits() + AUTHOR......: David Rowe + DATE CREATED: 16/4/2012 + + Generate a frame of bits from a repeating sequence of random data. OK so + it's not very random if it repeats but it makes syncing at the demod easier + for test purposes. + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[]) +{ + int i; + int bits_per_frame = fdmdv_bits_per_frame(f); + + for(i=0; i<bits_per_frame; i++) { + tx_bits[i] = test_bits[f->current_test_bit]; + f->current_test_bit++; + if (f->current_test_bit > (f->ntest_bits-1)) + f->current_test_bit = 0; + } + } + +float CODEC2_WIN32SUPPORT fdmdv_get_fsep(struct FDMDV *f) +{ + return f->fsep; +} + +void CODEC2_WIN32SUPPORT fdmdv_set_fsep(struct FDMDV *f, float fsep) { + int c; + float carrier_freq; + + f->fsep = fsep; + /* Set up frequency of each carrier */ + + for(c=0; c<f->Nc/2; c++) { + carrier_freq = (-f->Nc/2 + c)*f->fsep + FDMDV_FCENTRE; + f->freq[c].real = cos(2.0*PI*carrier_freq/FS); + f->freq[c].imag = sin(2.0*PI*carrier_freq/FS); + } + + for(c=f->Nc/2; c<f->Nc; c++) { + carrier_freq = (-f->Nc/2 + c + 1)*f->fsep + FDMDV_FCENTRE; + f->freq[c].real = cos(2.0*PI*carrier_freq/FS); + f->freq[c].imag = sin(2.0*PI*carrier_freq/FS); + } +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: bits_to_dqpsk_symbols() + AUTHOR......: David Rowe + DATE CREATED: 16/4/2012 + + Maps bits to parallel DQPSK symbols. Generate Nc+1 QPSK symbols from + vector of (1,Nc*Nb) input tx_bits. The Nc+1 symbol is the +1 -1 +1 + .... BPSK sync carrier. + +\*---------------------------------------------------------------------------*/ + +void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping) +{ + int c, msb, lsb; + COMP j = {0.0,1.0}; + + /* Map tx_bits to to Nc DQPSK symbols. Note legacy support for + old (suboptimal) V0.91 FreeDV mapping */ + + for(c=0; c<Nc; c++) { + msb = tx_bits[2*c]; + lsb = tx_bits[2*c+1]; + if ((msb == 0) && (lsb == 0)) + tx_symbols[c] = prev_tx_symbols[c]; + if ((msb == 0) && (lsb == 1)) + tx_symbols[c] = cmult(j, prev_tx_symbols[c]); + if ((msb == 1) && (lsb == 0)) { + if (old_qpsk_mapping) + tx_symbols[c] = cneg(prev_tx_symbols[c]); + else + tx_symbols[c] = cmult(cneg(j),prev_tx_symbols[c]); + } + if ((msb == 1) && (lsb == 1)) { + if (old_qpsk_mapping) + tx_symbols[c] = cmult(cneg(j),prev_tx_symbols[c]); + else + tx_symbols[c] = cneg(prev_tx_symbols[c]); + } + } + + /* +1 -1 +1 -1 BPSK sync carrier, once filtered becomes (roughly) + two spectral lines at +/- Rs/2 */ + + if (*pilot_bit) + tx_symbols[Nc] = cneg(prev_tx_symbols[Nc]); + else + tx_symbols[Nc] = prev_tx_symbols[Nc]; + + if (*pilot_bit) + *pilot_bit = 0; + else + *pilot_bit = 1; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: tx_filter() + AUTHOR......: David Rowe + DATE CREATED: 17/4/2012 + + Given Nc*NB bits construct M samples (1 symbol) of Nc+1 filtered + symbols streams. + +\*---------------------------------------------------------------------------*/ + +void tx_filter(COMP tx_baseband[NC+1][M], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]) +{ + int c; + int i,j,k; + float acc; + COMP gain; + + gain.real = sqrt(2.0)/2.0; + gain.imag = 0.0; + + for(c=0; c<Nc+1; c++) + tx_filter_memory[c][NSYM-1] = cmult(tx_symbols[c], gain); + + /* + tx filter each symbol, generate M filtered output samples for each symbol. + Efficient polyphase filter techniques used as tx_filter_memory is sparse + */ + + for(i=0; i<M; i++) { + for(c=0; c<Nc+1; c++) { + + /* filter real sample of symbol for carrier c */ + + acc = 0.0; + for(j=0,k=M-i-1; j<NSYM; j++,k+=M) + acc += M * tx_filter_memory[c][j].real * gt_alpha5_root[k]; + tx_baseband[c][i].real = acc; + + /* filter imag sample of symbol for carrier c */ + + acc = 0.0; + for(j=0,k=M-i-1; j<NSYM; j++,k+=M) + acc += M * tx_filter_memory[c][j].imag * gt_alpha5_root[k]; + tx_baseband[c][i].imag = acc; + + } + } + + /* shift memory, inserting zeros at end */ + + for(i=0; i<NSYM-1; i++) + for(c=0; c<Nc+1; c++) + tx_filter_memory[c][i] = tx_filter_memory[c][i+1]; + + for(c=0; c<Nc+1; c++) { + tx_filter_memory[c][NSYM-1].real = 0.0; + tx_filter_memory[c][NSYM-1].imag = 0.0; + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdm_upconvert() + AUTHOR......: David Rowe + DATE CREATED: 17/4/2012 + + Construct FDM signal by frequency shifting each filtered symbol + stream. Returns complex signal so we can apply frequency offsets + easily. + +\*---------------------------------------------------------------------------*/ + +void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq[]) +{ + int i,c; + COMP two = {2.0, 0.0}; + COMP pilot; + + for(i=0; i<M; i++) { + tx_fdm[i].real = 0.0; + tx_fdm[i].imag = 0.0; + } + + /* Nc/2 tones below centre freq */ + + for (c=0; c<Nc/2; c++) + for (i=0; i<M; i++) { + phase_tx[c] = cmult(phase_tx[c], freq[c]); + tx_fdm[i] = cadd(tx_fdm[i], cmult(tx_baseband[c][i], phase_tx[c])); + } + + /* Nc/2 tones above centre freq */ + + for (c=Nc/2; c<Nc; c++) + for (i=0; i<M; i++) { + phase_tx[c] = cmult(phase_tx[c], freq[c]); + tx_fdm[i] = cadd(tx_fdm[i], cmult(tx_baseband[c][i], phase_tx[c])); + } + + /* add centre pilot tone */ + + c = Nc; + for (i=0; i<M; i++) { + phase_tx[c] = cmult(phase_tx[c], freq[c]); + pilot = cmult(cmult(two, tx_baseband[c][i]), phase_tx[c]); + tx_fdm[i] = cadd(tx_fdm[i], pilot); + } + + /* + Scale such that total Carrier power C of real(tx_fdm) = Nc. This + excludes the power of the pilot tone. + We return the complex (single sided) signal to make frequency + shifting for the purpose of testing easier + */ + + for (i=0; i<M; i++) + tx_fdm[i] = cmult(two, tx_fdm[i]); + + /* normalise digital oscilators as the magnitude can drfift over time */ + + for (c=0; c<Nc+1; c++) { + phase_tx[c].real /= cabsolute(phase_tx[c]); + phase_tx[c].imag /= cabsolute(phase_tx[c]); + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_mod() + AUTHOR......: David Rowe + DATE CREATED: 26/4/2012 + + FDMDV modulator, take a frame of FDMDV_BITS_PER_FRAME bits and + generates a frame of FDMDV_SAMPLES_PER_FRAME modulated symbols. + Sync bit is returned to aid alignment of your next frame. + + The sync_bit value returned will be used for the _next_ frame. + + The output signal is complex to support single sided frequency + shifting, for example when testing frequency offsets in channel + simulation. + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], + int tx_bits[], int *sync_bit) +{ + COMP tx_symbols[NC+1]; + COMP tx_baseband[NC+1][M]; + + bits_to_dqpsk_symbols(tx_symbols, fdmdv->Nc, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit, fdmdv->old_qpsk_mapping); + memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(fdmdv->Nc+1)); + tx_filter(tx_baseband, fdmdv->Nc, tx_symbols, fdmdv->tx_filter_memory); + fdm_upconvert(tx_fdm, fdmdv->Nc, tx_baseband, fdmdv->phase_tx, fdmdv->freq); + + *sync_bit = fdmdv->tx_pilot_bit; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: generate_pilot_fdm() + AUTHOR......: David Rowe + DATE CREATED: 19/4/2012 + + Generate M samples of DBPSK pilot signal for Freq offset estimation. + +\*---------------------------------------------------------------------------*/ + +void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, + float *filter_mem, COMP *phase, COMP *freq) +{ + int i,j,k; + float tx_baseband[M]; + + /* +1 -1 +1 -1 DBPSK sync carrier, once filtered becomes (roughly) + two spectral lines at +/- RS/2 */ + + if (*bit) + *symbol = -*symbol; + else + *symbol = *symbol; + if (*bit) + *bit = 0; + else + *bit = 1; + + /* filter DPSK symbol to create M baseband samples */ + + filter_mem[NFILTER-1] = (sqrt(2)/2) * *symbol; + for(i=0; i<M; i++) { + tx_baseband[i] = 0.0; + for(j=M-1,k=M-i-1; j<NFILTER; j+=M,k+=M) + tx_baseband[i] += M * filter_mem[j] * gt_alpha5_root[k]; + } + + /* shift memory, inserting zeros at end */ + + for(i=0; i<NFILTER-M; i++) + filter_mem[i] = filter_mem[i+M]; + + for(i=NFILTER-M; i<NFILTER; i++) + filter_mem[i] = 0.0; + + /* upconvert */ + + for(i=0; i<M; i++) { + *phase = cmult(*phase, *freq); + pilot_fdm[i].real = sqrt(2)*2*tx_baseband[i] * phase->real; + pilot_fdm[i].imag = sqrt(2)*2*tx_baseband[i] * phase->imag; + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: generate_pilot_lut() + AUTHOR......: David Rowe + DATE CREATED: 19/4/2012 + + Generate a 4M sample vector of DBPSK pilot signal. As the pilot signal + is periodic in 4M samples we can then use this vector as a look up table + for pilot signal generation in the demod. + +\*---------------------------------------------------------------------------*/ + +void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq) +{ + int pilot_rx_bit = 0; + float pilot_symbol = sqrt(2.0); + COMP pilot_phase = {1.0, 0.0}; + float pilot_filter_mem[NFILTER]; + COMP pilot[M]; + int i,f; + + for(i=0; i<NFILTER; i++) + pilot_filter_mem[i] = 0.0; + + /* discard first 4 symbols as filter memory is filling, just keep + last four symbols */ + + for(f=0; f<8; f++) { + generate_pilot_fdm(pilot, &pilot_rx_bit, &pilot_symbol, pilot_filter_mem, &pilot_phase, pilot_freq); + if (f >= 4) + memcpy(&pilot_lut[M*(f-4)], pilot, M*sizeof(COMP)); + } + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: lpf_peak_pick() + AUTHOR......: David Rowe + DATE CREATED: 20/4/2012 + + LPF and peak pick part of freq est, put in a function as we call it twice. + +\*---------------------------------------------------------------------------*/ + +void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], + COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin) +{ + int i,j,k; + int mpilot; + COMP s[MPILOTFFT]; + float mag, imax; + int ix; + float r; + + /* LPF cutoff 200Hz, so we can handle max +/- 200 Hz freq offset */ + + for(i=0; i<NPILOTLPF-nin; i++) + pilot_lpf[i] = pilot_lpf[nin+i]; + for(i=NPILOTLPF-nin, j=0; i<NPILOTLPF; i++,j++) { + pilot_lpf[i].real = 0.0; pilot_lpf[i].imag = 0.0; + for(k=0; k<NPILOTCOEFF; k++) + pilot_lpf[i] = cadd(pilot_lpf[i], fcmult(pilot_coeff[k], pilot_baseband[j+k])); + } + + /* decimate to improve DFT resolution, window and DFT */ + + mpilot = FS/(2*200); /* calc decimation rate given new sample rate is twice LPF freq */ + for(i=0; i<MPILOTFFT; i++) { + s[i].real = 0.0; s[i].imag = 0.0; + } + for(i=0,j=0; i<NPILOTLPF; i+=mpilot,j++) { + s[j] = fcmult(hanning[i], pilot_lpf[i]); + } + + kiss_fft(fft_pilot_cfg, (kiss_fft_cpx *)s, (kiss_fft_cpx *)S); + + /* peak pick and convert to Hz */ + + imax = 0.0; + ix = 0; + for(i=0; i<MPILOTFFT; i++) { + mag = S[i].real*S[i].real + S[i].imag*S[i].imag; + if (mag > imax) { + imax = mag; + ix = i; + } + } + r = 2.0*200.0/MPILOTFFT; /* maps FFT bin to frequency in Hz */ + + if (ix >= MPILOTFFT/2) + *foff = (ix - MPILOTFFT)*r; + else + *foff = (ix)*r; + *max = imax; + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: rx_est_freq_offset() + AUTHOR......: David Rowe + DATE CREATED: 19/4/2012 + + Estimate frequency offset of FDM signal using BPSK pilot. Note that + this algorithm is quite sensitive to pilot tone level wrt other + carriers, so test variations to the pilot amplitude carefully. + +\*---------------------------------------------------------------------------*/ + +float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin) +{ + int i,j; + COMP pilot[M+M/P]; + COMP prev_pilot[M+M/P]; + float foff, foff1, foff2; + float max1, max2; + + assert(nin <= M+M/P); + + /* get pilot samples used for correlation/down conversion of rx signal */ + + for (i=0; i<nin; i++) { + pilot[i] = f->pilot_lut[f->pilot_lut_index]; + f->pilot_lut_index++; + if (f->pilot_lut_index >= 4*M) + f->pilot_lut_index = 0; + + prev_pilot[i] = f->pilot_lut[f->prev_pilot_lut_index]; + f->prev_pilot_lut_index++; + if (f->prev_pilot_lut_index >= 4*M) + f->prev_pilot_lut_index = 0; + } + + /* + Down convert latest M samples of pilot by multiplying by ideal + BPSK pilot signal we have generated locally. The peak of the + resulting signal is sensitive to the time shift between the + received and local version of the pilot, so we do it twice at + different time shifts and choose the maximum. + */ + + for(i=0; i<NPILOTBASEBAND-nin; i++) { + f->pilot_baseband1[i] = f->pilot_baseband1[i+nin]; + f->pilot_baseband2[i] = f->pilot_baseband2[i+nin]; + } + + for(i=0,j=NPILOTBASEBAND-nin; i<nin; i++,j++) { + f->pilot_baseband1[j] = cmult(rx_fdm[i], cconj(pilot[i])); + f->pilot_baseband2[j] = cmult(rx_fdm[i], cconj(prev_pilot[i])); + } + + lpf_peak_pick(&foff1, &max1, f->pilot_baseband1, f->pilot_lpf1, f->fft_pilot_cfg, f->S1, nin); + lpf_peak_pick(&foff2, &max2, f->pilot_baseband2, f->pilot_lpf2, f->fft_pilot_cfg, f->S2, nin); + + if (max1 > max2) + foff = foff1; + else + foff = foff2; + + return foff; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_freq_shift() + AUTHOR......: David Rowe + DATE CREATED: 26/4/2012 + + Frequency shift modem signal. The use of complex input and output allows + single sided frequency shifting (no images). + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, + COMP *foff_rect, COMP *foff_phase_rect, int nin) +{ + int i; + + foff_rect->real = cos(2.0*PI*foff/FS); + foff_rect->imag = sin(2.0*PI*foff/FS); + for(i=0; i<nin; i++) { + *foff_phase_rect = cmult(*foff_phase_rect, *foff_rect); + rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect); + } + + /* normalise digital oscilator as the magnitude can drfift over time */ + + foff_phase_rect->real /= cabsolute(*foff_phase_rect); + foff_phase_rect->imag /= cabsolute(*foff_phase_rect); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdm_downconvert() + AUTHOR......: David Rowe + DATE CREATED: 22/4/2012 + + Frequency shift each modem carrier down to Nc+1 baseband signals. + +\*---------------------------------------------------------------------------*/ + +void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin) +{ + int i,c; + + /* maximum number of input samples to demod */ + + assert(nin <= (M+M/P)); + + /* Nc/2 tones below centre freq */ + + for (c=0; c<Nc/2; c++) + for (i=0; i<nin; i++) { + phase_rx[c] = cmult(phase_rx[c], freq[c]); + rx_baseband[c][i] = cmult(rx_fdm[i], cconj(phase_rx[c])); + } + + /* Nc/2 tones above centre freq */ + + for (c=Nc/2; c<Nc; c++) + for (i=0; i<nin; i++) { + phase_rx[c] = cmult(phase_rx[c], freq[c]); + rx_baseband[c][i] = cmult(rx_fdm[i], cconj(phase_rx[c])); + } + + /* centre pilot tone */ + + c = Nc; + for (i=0; i<nin; i++) { + phase_rx[c] = cmult(phase_rx[c], freq[c]); + rx_baseband[c][i] = cmult(rx_fdm[i], cconj(phase_rx[c])); + } + + /* normalise digital oscilators as the magnitude can drift over time */ + + for (c=0; c<Nc+1; c++) { + phase_rx[c].real /= cabsolute(phase_rx[c]); + phase_rx[c].imag /= cabsolute(phase_rx[c]); + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: rx_filter() + AUTHOR......: David Rowe + DATE CREATED: 22/4/2012 + + Receive filter each baseband signal at oversample rate P. Filtering at + rate P lowers CPU compared to rate M. + + Depending on the number of input samples to the demod nin, we + produce P-1, P (usually), or P+1 filtered samples at rate P. nin is + occasionally adjusted to compensate for timing slips due to + different tx and rx sample clocks. + +\*---------------------------------------------------------------------------*/ + +void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_memory[NC+1][NFILTER], int nin) +{ + int c, i,j,k,l; + int n=M/P; + + /* rx filter each symbol, generate P filtered output samples for + each symbol. Note we keep filter memory at rate M, it's just + the filter output at rate P */ + + for(i=0, j=0; i<nin; i+=n,j++) { + + /* latest input sample */ + + for(c=0; c<Nc+1; c++) + for(k=NFILTER-n,l=i; k<NFILTER; k++,l++) + rx_filter_memory[c][k] = rx_baseband[c][l]; + + /* convolution (filtering) */ + + for(c=0; c<Nc+1; c++) { + rx_filt[c][j].real = 0.0; rx_filt[c][j].imag = 0.0; + for(k=0; k<NFILTER; k++) + rx_filt[c][j] = cadd(rx_filt[c][j], fcmult(gt_alpha5_root[k], rx_filter_memory[c][k])); + } + + /* make room for next input sample */ + + for(c=0; c<Nc+1; c++) + for(k=0,l=n; k<NFILTER-n; k++,l++) + rx_filter_memory[c][k] = rx_filter_memory[c][l]; + } + + assert(j <= (P+1)); /* check for any over runs */ +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: rx_est_timing() + AUTHOR......: David Rowe + DATE CREATED: 23/4/2012 + + Estimate optimum timing offset, re-filter receive symbols at optimum + timing estimate. + +\*---------------------------------------------------------------------------*/ + +float rx_est_timing(COMP rx_symbols[], + int Nc, + COMP rx_filt[NC+1][P+1], + COMP rx_baseband[NC+1][M+M/P], + COMP rx_filter_mem_timing[NC+1][NT*P], + float env[], + COMP rx_baseband_mem_timing[NC+1][NFILTERTIMING], + int nin) +{ + int c,i,j,k; + int adjust, s; + COMP x, phase, freq; + float rx_timing; + + /* + nin adjust + -------------------------------- + 120 -1 (one less rate P sample) + 160 0 (nominal) + 200 1 (one more rate P sample) + */ + + adjust = P - nin*P/M; + + /* update buffer of NT rate P filtered symbols */ + + for(c=0; c<Nc+1; c++) + for(i=0,j=P-adjust; i<(NT-1)*P+adjust; i++,j++) + rx_filter_mem_timing[c][i] = rx_filter_mem_timing[c][j]; + for(c=0; c<Nc+1; c++) + for(i=(NT-1)*P+adjust,j=0; i<NT*P; i++,j++) + rx_filter_mem_timing[c][i] = rx_filt[c][j]; + + /* sum envelopes of all carriers */ + + for(i=0; i<NT*P; i++) { + env[i] = 0.0; + for(c=0; c<Nc+1; c++) + env[i] += cabsolute(rx_filter_mem_timing[c][i]); + } + + /* The envelope has a frequency component at the symbol rate. The + phase of this frequency component indicates the timing. So work + out single DFT at frequency 2*pi/P */ + + x.real = 0.0; x.imag = 0.0; + freq.real = cos(2*PI/P); + freq.imag = sin(2*PI/P); + phase.real = 1.0; + phase.imag = 0.0; + + for(i=0; i<NT*P; i++) { + x = cadd(x, fcmult(env[i], phase)); + phase = cmult(phase, freq); + } + + /* Map phase to estimated optimum timing instant at rate M. The + M/4 part was adjusted by experiment, I know not why.... */ + + rx_timing = atan2(x.imag, x.real)*M/(2*PI) + M/4; + + if (rx_timing > M) + rx_timing -= M; + if (rx_timing < -M) + rx_timing += M; + + /* rx_filt_mem_timing contains M + Nfilter + M samples of the + baseband signal at rate M this enables us to resample the + filtered rx symbol with M sample precision once we have + rx_timing */ + + for(c=0; c<Nc+1; c++) + for(i=0,j=nin; i<NFILTERTIMING-nin; i++,j++) + rx_baseband_mem_timing[c][i] = rx_baseband_mem_timing[c][j]; + for(c=0; c<Nc+1; c++) + for(i=NFILTERTIMING-nin,j=0; i<NFILTERTIMING; i++,j++) + rx_baseband_mem_timing[c][i] = rx_baseband[c][j]; + + /* rx filter to get symbol for each carrier at estimated optimum + timing instant. We use rate M filter memory to get fine timing + resolution. */ + + s = round(rx_timing) + M; + for(c=0; c<Nc+1; c++) { + rx_symbols[c].real = 0.0; + rx_symbols[c].imag = 0.0; + for(k=s,j=0; k<s+NFILTER; k++,j++) + rx_symbols[c] = cadd(rx_symbols[c], fcmult(gt_alpha5_root[j], rx_baseband_mem_timing[c][k])); + } + + return rx_timing; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: qpsk_to_bits() + AUTHOR......: David Rowe + DATE CREATED: 24/4/2012 + + Convert DQPSK symbols back to an array of bits, extracts sync bit + from DBPSK pilot, and also uses pilot to estimate fine frequency + error. + +\*---------------------------------------------------------------------------*/ + +float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], + COMP rx_symbols[], int old_qpsk_mapping) +{ + int c; + COMP pi_on_4; + COMP d; + int msb=0, lsb=0; + float ferr, norm; + + pi_on_4.real = cos(PI/4.0); + pi_on_4.imag = sin(PI/4.0); + + /* Extra 45 degree clockwise lets us use real and imag axis as + decision boundaries. "norm" makes sure the phase subtraction + from the previous symbol doesn't affect the amplitude, which + leads to sensible scatter plots */ + + for(c=0; c<Nc; c++) { + norm = 1.0/(cabsolute(prev_rx_symbols[c])+1E-6); + phase_difference[c] = cmult(cmult(rx_symbols[c], fcmult(norm,cconj(prev_rx_symbols[c]))), pi_on_4); + } + + /* map (Nc,1) DQPSK symbols back into an (1,Nc*Nb) array of bits */ + + for (c=0; c<Nc; c++) { + d = phase_difference[c]; + if ((d.real >= 0) && (d.imag >= 0)) { + msb = 0; lsb = 0; + } + if ((d.real < 0) && (d.imag >= 0)) { + msb = 0; lsb = 1; + } + if ((d.real < 0) && (d.imag < 0)) { + if (old_qpsk_mapping) { + msb = 1; lsb = 0; + } else { + msb = 1; lsb = 1; + } + } + if ((d.real >= 0) && (d.imag < 0)) { + if (old_qpsk_mapping) { + msb = 1; lsb = 1; + } else { + msb = 1; lsb = 0; + } + } + rx_bits[2*c] = msb; + rx_bits[2*c+1] = lsb; + } + + /* Extract DBPSK encoded Sync bit and fine freq offset estimate */ + + norm = 1.0/(cabsolute(prev_rx_symbols[Nc])+1E-6); + phase_difference[Nc] = cmult(rx_symbols[Nc], fcmult(norm, cconj(prev_rx_symbols[Nc]))); + if (phase_difference[Nc].real < 0) { + *sync_bit = 1; + ferr = phase_difference[Nc].imag; + } + else { + *sync_bit = 0; + ferr = -phase_difference[Nc].imag; + } + + /* pilot carrier gets an extra pi/4 rotation to make it consistent + with other carriers, as we need it for snr_update and scatter + diagram */ + + phase_difference[Nc] = cmult(phase_difference[Nc], pi_on_4); + + return ferr; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: snr_update() + AUTHOR......: David Rowe + DATE CREATED: 17 May 2012 + + Given phase differences update estimates of signal and noise levels. + +\*---------------------------------------------------------------------------*/ + +void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]) +{ + float s[NC+1]; + COMP refl_symbols[NC+1]; + float n[NC+1]; + COMP pi_on_4; + int c; + + pi_on_4.real = cos(PI/4.0); + pi_on_4.imag = sin(PI/4.0); + + /* mag of each symbol is distance from origin, this gives us a + vector of mags, one for each carrier. */ + + for(c=0; c<Nc+1; c++) + s[c] = cabsolute(phase_difference[c]); + + /* signal mag estimate for each carrier is a smoothed version of + instantaneous magntitude, this gives us a vector of smoothed + mag estimates, one for each carrier. */ + + for(c=0; c<Nc+1; c++) + sig_est[c] = SNR_COEFF*sig_est[c] + (1.0 - SNR_COEFF)*s[c]; + + /* noise mag estimate is distance of current symbol from average + location of that symbol. We reflect all symbols into the first + quadrant for convenience. */ + + for(c=0; c<Nc+1; c++) { + refl_symbols[c].real = fabs(phase_difference[c].real); + refl_symbols[c].imag = fabs(phase_difference[c].imag); + n[c] = cabsolute(cadd(fcmult(sig_est[c], pi_on_4), cneg(refl_symbols[c]))); + } + + /* noise mag estimate for each carrier is a smoothed version of + instantaneous noise mag, this gives us a vector of smoothed + noise power estimates, one for each carrier. */ + + for(c=0; c<Nc+1; c++) + noise_est[c] = SNR_COEFF*noise_est[c] + (1 - SNR_COEFF)*n[c]; +} + +// returns number of shorts in error_pattern[], one short per error + +int CODEC2_WIN32SUPPORT fdmdv_error_pattern_size(struct FDMDV *f) { + return f->ntest_bits; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_put_test_bits() + AUTHOR......: David Rowe + DATE CREATED: 24/4/2012 + + Accepts nbits from rx and attempts to sync with test_bits sequence. + If sync OK measures bit errors. + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], + int *bit_errors, int *ntest_bits, + int rx_bits[]) +{ + int i,j; + float ber; + int bits_per_frame = fdmdv_bits_per_frame(f); + + /* Append to our memory */ + + for(i=0,j=bits_per_frame; i<f->ntest_bits-bits_per_frame; i++,j++) + f->rx_test_bits_mem[i] = f->rx_test_bits_mem[j]; + for(i=f->ntest_bits-bits_per_frame,j=0; i<f->ntest_bits; i++,j++) + f->rx_test_bits_mem[i] = rx_bits[j]; + + /* see how many bit errors we get when checked against test sequence */ + + *bit_errors = 0; + for(i=0; i<f->ntest_bits; i++) { + error_pattern[i] = test_bits[i] ^ f->rx_test_bits_mem[i]; + *bit_errors += error_pattern[i]; + //printf("%d %d %d %d\n", i, test_bits[i], f->rx_test_bits_mem[i], test_bits[i] ^ f->rx_test_bits_mem[i]); + } + + /* if less than a thresh we are aligned and in sync with test sequence */ + + ber = (float)*bit_errors/f->ntest_bits; + + *sync = 0; + if (ber < 0.2) + *sync = 1; + + *ntest_bits = f->ntest_bits; + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: freq_state(() + AUTHOR......: David Rowe + DATE CREATED: 24/4/2012 + + Freq offset state machine. Moves between coarse and fine states + based on BPSK pilot sequence. Freq offset estimator occasionally + makes mistakes when used continuously. So we use it until we have + acquired the BPSK pilot, then switch to a more robust "fine" + tracking algorithm. If we lose sync we switch back to coarse mode + for fast re-acquisition of large frequency offsets. + + The sync state is also useful for higher layers to determine when + there is valid FDMDV data for decoding. We want to reliably and + quickly get into sync, stay in sync even on fading channels, and + fall out of sync quickly if tx stops or it's a false sync. + + In multipath fading channels the BPSK sync carrier may be pushed + down in the noise, despite other carriers being at full strength. + We want to avoid loss of sync in these cases. + +\*---------------------------------------------------------------------------*/ + +int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem) +{ + int next_state, sync, unique_word, i, corr; + + /* look for 6 symbols (120ms) 101010 of sync sequence */ + + unique_word = 0; + for(i=0; i<NSYNC_MEM-1; i++) + sync_mem[i] = sync_mem[i+1]; + sync_mem[i] = 1 - 2*sync_bit; + corr = 0; + for(i=0; i<NSYNC_MEM; i++) + corr += sync_mem[i]*sync_uw[i]; + if (abs(corr) == NSYNC_MEM) + unique_word = 1; + *reliable_sync_bit = (corr == NSYNC_MEM); + + /* iterate state machine */ + + next_state = *state; + switch(*state) { + case 0: + if (unique_word) { + next_state = 1; + *timer = 0; + } + break; + case 1: /* tentative sync state */ + if (unique_word) { + (*timer)++; + if (*timer == 25) /* sync has been good for 500ms */ + next_state = 2; + } + else + next_state = 0; /* quickly fall out of sync */ + break; + case 2: /* good sync state */ + if (unique_word == 0) { + *timer = 0; + next_state = 3; + } + break; + case 3: /* tentative bad state, but could be a fade */ + if (unique_word) + next_state = 2; + else { + (*timer)++; + if (*timer == 50) /* wait for 1000ms in case sync comes back */ + next_state = 0; + } + break; + } + + //printf("state: %d next_state: %d uw: %d timer: %d\n", *state, next_state, unique_word, *timer); + *state = next_state; + if (*state) + sync = 1; + else + sync = 0; + + return sync; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_demod() + AUTHOR......: David Rowe + DATE CREATED: 26/4/2012 + + FDMDV demodulator, take an array of FDMDV_SAMPLES_PER_FRAME + modulated samples, returns an array of FDMDV_BITS_PER_FRAME bits, + plus the sync bit. + + The input signal is complex to support single sided frequency shifting + before the demod input (e.g. fdmdv2 click to tune feature). + + The number of input samples nin will normally be M == + FDMDV_SAMPLES_PER_FRAME. However to adjust for differences in + transmit and receive sample clocks nin will occasionally be M-M/P, + or M+M/P. + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], + int *reliable_sync_bit, COMP rx_fdm[], int *nin) +{ + float foff_coarse, foff_fine; + COMP rx_fdm_fcorr[M+M/P]; + COMP rx_baseband[NC+1][M+M/P]; + COMP rx_filt[NC+1][P+1]; + COMP rx_symbols[NC+1]; + float env[NT*P]; + int sync_bit; + + /* freq offset estimation and correction */ + + foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, *nin); + + if (fdmdv->sync == 0) + fdmdv->foff = foff_coarse; + fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, -fdmdv->foff, &fdmdv->foff_rect, &fdmdv->foff_phase_rect, *nin); + + /* baseband processing */ + + fdm_downconvert(rx_baseband, fdmdv->Nc, rx_fdm_fcorr, fdmdv->phase_rx, fdmdv->freq, *nin); + rx_filter(rx_filt, fdmdv->Nc, rx_baseband, fdmdv->rx_filter_memory, *nin); + fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, *nin); + + /* Adjust number of input samples to keep timing within bounds */ + + *nin = M; + + if (fdmdv->rx_timing > 2*M/P) + *nin += M/P; + + if (fdmdv->rx_timing < 0) + *nin -= M/P; + + foff_fine = qpsk_to_bits(rx_bits, &sync_bit, fdmdv->Nc, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols, + fdmdv->old_qpsk_mapping); + memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(fdmdv->Nc+1)); + snr_update(fdmdv->sig_est, fdmdv->noise_est, fdmdv->Nc, fdmdv->phase_difference); + + /* freq offset estimation state machine */ + + fdmdv->sync = freq_state(reliable_sync_bit, sync_bit, &fdmdv->fest_state, &fdmdv->timer, fdmdv->sync_mem); + fdmdv->foff -= TRACK_COEFF*foff_fine; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: calc_snr() + AUTHOR......: David Rowe + DATE CREATED: 17 May 2012 + + Calculate current SNR estimate (3000Hz noise BW) + +\*---------------------------------------------------------------------------*/ + +float calc_snr(int Nc, float sig_est[], float noise_est[]) +{ + float S, SdB; + float mean, N50, N50dB, N3000dB; + float snr_dB; + int c; + + S = 0.0; + for(c=0; c<Nc+1; c++) + S += pow(sig_est[c], 2.0); + SdB = 10.0*log10(S+1E-12); + + /* Average noise mag across all carriers and square to get an + average noise power. This is an estimate of the noise power in + Rs = 50Hz of BW (note for raised root cosine filters Rs is the + noise BW of the filter) */ + + mean = 0.0; + for(c=0; c<Nc+1; c++) + mean += noise_est[c]; + mean /= (Nc+1); + N50 = pow(mean, 2.0); + N50dB = 10.0*log10(N50+1E-12); + + /* Now multiply by (3000 Hz)/(50 Hz) to find the total noise power + in 3000 Hz */ + + N3000dB = N50dB + 10.0*log10(3000.0/RS); + + snr_dB = SdB - N3000dB; + + return snr_dB; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_get_demod_stats() + AUTHOR......: David Rowe + DATE CREATED: 1 May 2012 + + Fills stats structure with a bunch of demod information. + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv, + struct FDMDV_STATS *fdmdv_stats) +{ + int c; + + fdmdv_stats->Nc = fdmdv->Nc; + fdmdv_stats->snr_est = calc_snr(fdmdv->Nc, fdmdv->sig_est, fdmdv->noise_est); + fdmdv_stats->sync = fdmdv->sync; + fdmdv_stats->foff = fdmdv->foff; + fdmdv_stats->rx_timing = fdmdv->rx_timing; + fdmdv_stats->clock_offset = 0.0; /* TODO - implement clock offset estimation */ + + for(c=0; c<fdmdv->Nc+1; c++) { + fdmdv_stats->rx_symbols[c] = fdmdv->phase_difference[c]; + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_8_to_48() + AUTHOR......: David Rowe + DATE CREATED: 9 May 2012 + + Changes the sample rate of a signal from 8 to 48 kHz. Experience + with PC based modems has shown that PC sound cards have a more + accurate sample clock when set for 48 kHz than 8 kHz. + + n is the number of samples at the 8 kHz rate, there are FDMDV_OS*n samples + at the 48 kHz rate. A memory of FDMDV_OS_TAPS/FDMDV_OS samples is reqd for + in8k[] (see t48_8.c unit test as example). + + This is a classic polyphase upsampler. We take the 8 kHz samples + and insert (FDMDV_OS-1) zeroes between each sample, then + FDMDV_OS_TAPS FIR low pass filter the signal at 4kHz. As most of + the input samples are zeroes, we only need to multiply non-zero + input samples by filter coefficients. The zero insertion and + filtering are combined in the code below and I'm too lazy to explain + it further right now.... + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n) +{ + int i,j,k,l; + + /* make sure n is an integer multiple of the oversampling rate, ow + this function breaks */ + + assert((n % FDMDV_OS) == 0); + + for(i=0; i<n; i++) { + for(j=0; j<FDMDV_OS; j++) { + out48k[i*FDMDV_OS+j] = 0.0; + for(k=0,l=0; k<FDMDV_OS_TAPS; k+=FDMDV_OS,l++) + out48k[i*FDMDV_OS+j] += fdmdv_os_filter[k+j]*in8k[i-l]; + out48k[i*FDMDV_OS+j] *= FDMDV_OS; + + } + } + + /* update filter memory */ + + for(i=-(FDMDV_OS_TAPS/FDMDV_OS); i<0; i++) + in8k[i] = in8k[i + n]; + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_48_to_8() + AUTHOR......: David Rowe + DATE CREATED: 9 May 2012 + + Changes the sample rate of a signal from 48 to 8 kHz. + + n is the number of samples at the 8 kHz rate, there are FDMDV_OS*n + samples at the 48 kHz rate. As above however a memory of + FDMDV_OS_TAPS samples is reqd for in48k[] (see t48_8.c unit test as example). + + Low pass filter the 48 kHz signal at 4 kHz using the same filter as + the upsampler, then just output every FDMDV_OS-th filtered sample. + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n) +{ + int i,j; + + for(i=0; i<n; i++) { + out8k[i] = 0.0; + for(j=0; j<FDMDV_OS_TAPS; j++) + out8k[i] += fdmdv_os_filter[j]*in48k[i*FDMDV_OS-j]; + } + + /* update filter memory */ + + for(i=-FDMDV_OS_TAPS; i<0; i++) + in48k[i] = in48k[i + n*FDMDV_OS]; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: fdmdv_get_rx_spectrum() + AUTHOR......: David Rowe + DATE CREATED: 9 June 2012 + + Returns the FDMDV_NSPEC point magnitude spectrum of the rx signal in + dB. The spectral samples are scaled so that 0dB is the peak, a good + range for plotting is 0 to -40dB. + + Note only the real part of the complex input signal is used at + present. A complex variable is used for input for compatability + with the other rx signal procesing. + + Successive calls can be used to build up a waterfall or spectrogram + plot, by mapping the received levels to colours. + + The time-frequency resolution of the spectrum can be adjusted by varying + FDMDV_NSPEC. Note that a 2*FDMDV_NSPEC size FFT is reqd to get + FDMDV_NSPEC output points. FDMDV_NSPEC must be a power of 2. + + See octave/tget_spec.m for a demo real time spectral display using + Octave. This demo averages the output over time to get a smoother + display: + + av = 0.9*av + 0.1*mag_dB + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *f, float mag_spec_dB[], + COMP rx_fdm[], int nin) +{ + int i,j; + COMP fft_in[2*FDMDV_NSPEC]; + COMP fft_out[2*FDMDV_NSPEC]; + float full_scale_dB; + + /* update buffer of input samples */ + + for(i=0; i<2*FDMDV_NSPEC-nin; i++) + f->fft_buf[i] = f->fft_buf[i+nin]; + for(j=0; j<nin; j++,i++) + f->fft_buf[i] = rx_fdm[j].real; + assert(i == 2*FDMDV_NSPEC); + + /* window and FFT */ + + for(i=0; i<2*FDMDV_NSPEC; i++) { + fft_in[i].real = f->fft_buf[i] * (0.5 - 0.5*cos((float)i*2.0*PI/(2*FDMDV_NSPEC))); + fft_in[i].imag = 0.0; + } + + kiss_fft(f->fft_cfg, (kiss_fft_cpx *)fft_in, (kiss_fft_cpx *)fft_out); + + /* FFT scales up a signal of level 1 FDMDV_NSPEC */ + + full_scale_dB = 20*log10(FDMDV_NSPEC); + + /* scale and convert to dB */ + + for(i=0; i<FDMDV_NSPEC; i++) { + mag_spec_dB[i] = 10.0*log10(fft_out[i].real*fft_out[i].real + fft_out[i].imag*fft_out[i].imag + 1E-12); + mag_spec_dB[i] -= full_scale_dB; + } +} + +/*---------------------------------------------------------------------------*\ + + Function used during development to test if magnitude of digital + oscillators was drifting. It was! + +\*---------------------------------------------------------------------------*/ + +void CODEC2_WIN32SUPPORT fdmdv_dump_osc_mags(struct FDMDV *f) +{ + int i; + + fprintf(stderr, "phase_tx[]:\n"); + for(i=0; i<=f->Nc; i++) + fprintf(stderr," %1.3f", cabsolute(f->phase_tx[i])); + fprintf(stderr,"\nfreq[]:\n"); + for(i=0; i<=f->Nc; i++) + fprintf(stderr," %1.3f", cabsolute(f->freq[i])); + fprintf(stderr,"\nfoff_rect %1.3f foff_phase_rect: %1.3f", cabsolute(f->foff_rect), cabsolute(f->foff_phase_rect)); + fprintf(stderr,"\nphase_rx[]:\n"); + for(i=0; i<=f->Nc; i++) + fprintf(stderr," %1.3f", cabsolute(f->phase_rx[i])); + fprintf(stderr, "\n\n"); +} diff --git a/gr-vocoder/lib/codec2/fdmdv_internal.h b/gr-vocoder/lib/codec2/fdmdv_internal.h new file mode 100644 index 0000000000..24080e63c8 --- /dev/null +++ b/gr-vocoder/lib/codec2/fdmdv_internal.h @@ -0,0 +1,176 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: fdmdv_internal.h + AUTHOR......: David Rowe + DATE CREATED: April 16 2012 + + Header file for FDMDV internal functions, exposed via this header + file for testing. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2012 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __FDMDV_INTERNAL__ +#define __FDMDV_INTERNAL__ + +#include "comp.h" +#include "codec2_fdmdv.h" +#include "kiss_fft.h" + +/*---------------------------------------------------------------------------*\ + + DEFINES + +\*---------------------------------------------------------------------------*/ + +#define PI 3.141592654 +#define FS 8000 /* sample rate in Hz */ +#define T (1.0/FS) /* sample period in seconds */ +#define RS 50 /* symbol rate in Hz */ +#define NC 20 /* max number of data carriers (plus one pilot in the centre) */ +#define NB 2 /* Bits/symbol for QPSK modulation */ +#define RB (NC*RS*NB) /* bit rate */ +#define M (FS/RS) /* oversampling factor */ +#define NSYM 6 /* number of symbols to filter over */ +#define NFILTER (NSYM*M) /* size of tx/rx filters at sample rate M */ + +#define FSEP 75 /* Default separation between carriers (Hz) */ + +#define NT 5 /* number of symbols we estimate timing over */ +#define P 4 /* oversample factor used for initial rx symbol filtering */ +#define NFILTERTIMING (M+NFILTER+M) /* filter memory used for resampling after timing estimation */ + +#define NPILOT_LUT (4*M) /* number of pilot look up table samples */ +#define NPILOTCOEFF 30 /* number of FIR filter coeffs in LP filter */ +#define NPILOTBASEBAND (NPILOTCOEFF+M+M/P) /* number of pilot baseband samples reqd for pilot LPF */ +#define NPILOTLPF (4*M) /* number of samples we DFT pilot over, pilot est window */ +#define MPILOTFFT 256 + +#define NSYNC_MEM 6 + +/* averaging filter coeffs */ + +#define TRACK_COEFF 0.5 +#define SNR_COEFF 0.9 /* SNR est averaging filter coeff */ + +/*---------------------------------------------------------------------------*\ + + STRUCT for States + +\*---------------------------------------------------------------------------*/ + +struct FDMDV { + + int Nc; + float fsep; + + /* test data (test frame) states */ + + int ntest_bits; + int current_test_bit; + int *rx_test_bits_mem; + + /* Modulator */ + + int old_qpsk_mapping; + int tx_pilot_bit; + COMP prev_tx_symbols[NC+1]; + COMP tx_filter_memory[NC+1][NSYM]; + COMP phase_tx[NC+1]; + COMP freq[NC+1]; + + /* Pilot generation at demodulator */ + + COMP pilot_lut[NPILOT_LUT]; + int pilot_lut_index; + int prev_pilot_lut_index; + + /* freq offset estimation states */ + + kiss_fft_cfg fft_pilot_cfg; + COMP pilot_baseband1[NPILOTBASEBAND]; + COMP pilot_baseband2[NPILOTBASEBAND]; + COMP pilot_lpf1[NPILOTLPF]; + COMP pilot_lpf2[NPILOTLPF]; + COMP S1[MPILOTFFT]; + COMP S2[MPILOTFFT]; + + /* freq offset correction states */ + + float foff; + COMP foff_rect; + COMP foff_phase_rect; + + /* Demodulator */ + + COMP phase_rx[NC+1]; + COMP rx_filter_memory[NC+1][NFILTER]; + COMP rx_filter_mem_timing[NC+1][NT*P]; + COMP rx_baseband_mem_timing[NC+1][NFILTERTIMING]; + float rx_timing; + COMP phase_difference[NC+1]; + COMP prev_rx_symbols[NC+1]; + + /* sync state machine */ + + int sync_mem[NSYNC_MEM]; + int fest_state; + int sync; + int timer; + + /* SNR estimation states */ + + float sig_est[NC+1]; + float noise_est[NC+1]; + + /* Buf for FFT/waterfall */ + + float fft_buf[2*FDMDV_NSPEC]; + kiss_fft_cfg fft_cfg; + }; + +/*---------------------------------------------------------------------------*\ + + FUNCTION PROTOTYPES + +\*---------------------------------------------------------------------------*/ + +void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping); +void tx_filter(COMP tx_baseband[NC+1][M], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]); +void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq_tx[]); +void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, float *filter_mem, COMP *phase, COMP *freq); +void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq); +float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin); +void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin); +void freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_rect, COMP *foff_phase_rect, int nin); +void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin); +void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_memory[NC+1][NFILTER], int nin); +float rx_est_timing(COMP rx_symbols[], int Nc, + COMP rx_filt[NC+1][P+1], + COMP rx_baseband[NC+1][M+M/P], + COMP rx_filter_mem_timing[NC+1][NT*P], + float env[], + COMP rx_baseband_mem_timing[NC+1][NFILTERTIMING], + int nin); +float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[], int old_qpsk_mapping); +void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]); +int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem); +float calc_snr(int Nc, float sig_est[], float noise_est[]); + +#endif diff --git a/gr-vocoder/lib/codec2/fft.c b/gr-vocoder/lib/codec2/fft.c deleted file mode 100644 index 19f3141a80..0000000000 --- a/gr-vocoder/lib/codec2/fft.c +++ /dev/null @@ -1,101 +0,0 @@ -/*---------------------------------------------------------------------------*\ - - FILE........: fft.c - AUTHOR......: Bruce Robertson - DATE CREATED: 20/11/2010 - - Bridging function to the kiss_fft package. - -\*---------------------------------------------------------------------------*/ - -/* - Copyright (C) 2010 Bruce Robertson - - All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 2.1, as - published by the Free Software Foundation. This program 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 Lesser General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. -*/ - -#include <assert.h> -#include "kiss_fft.h" - -/*---------------------------------------------------------------------------*\ - - GLOBALS - -\*---------------------------------------------------------------------------*/ - -kiss_fft_cpx *fin; -kiss_fft_cpx *fout; -kiss_fft_cfg cfg_forward; -kiss_fft_cfg cfg_reverse; - -/*---------------------------------------------------------------------------*\ - - initialize_fft(int n) - - Initialisation function for kiss_fft. This assumes that all calls to fft() - use the same datatypes and are one arrays of the same size. - -\*---------------------------------------------------------------------------*/ - -void -initialize_fft (int n) -{ - fin = KISS_FFT_MALLOC (n * sizeof (kiss_fft_cpx)); - assert(fin != NULL); - fout = KISS_FFT_MALLOC (n * sizeof (kiss_fft_cpx)); - assert(fout != NULL); - cfg_forward = kiss_fft_alloc (n, 0, NULL, NULL); - assert(cfg_forward != NULL); - cfg_reverse = kiss_fft_alloc (n, 1, NULL, NULL); - assert(cfg_reverse != NULL); -} - -/*---------------------------------------------------------------------------*\ - - fft(float x[], int n, int isign) - Function that calls kiss_fft with the signature of four1 from NRC. - -\*---------------------------------------------------------------------------*/ - - -void -fft (float x[], int n, int isign) -{ - //int isReverse = 0; // never used - int c; - kiss_fft_cfg cfg; - if (cfg_forward == NULL) - { - initialize_fft (n); - } - for (c = 0; c < n * 2; c += 2) - { - fin[c / 2].r = x[c]; - fin[c / 2].i = -x[c + 1]; - } - if (isign == -1) - { - cfg = cfg_reverse; - } - else - { - cfg = cfg_forward; - } - kiss_fft (cfg, fin, fout); - for (c = 0; c < n * 2; c += 2) - { - x[c] = fout[(c) / 2].r; - x[c + 1] = -fout[(c) / 2].i; - } -} diff --git a/gr-vocoder/lib/codec2/fft.h b/gr-vocoder/lib/codec2/fft.h deleted file mode 100644 index d5f83045e1..0000000000 --- a/gr-vocoder/lib/codec2/fft.h +++ /dev/null @@ -1,16 +0,0 @@ -/*---------------------------------------------------------------------------*\ - - FILE........: fft.h - AUTHOR......: Bruce Robertson - DATE CREATED: 29/11/2010 - - Bridge between existing code and kiss_fft. - -\*---------------------------------------------------------------------------*/ - -#ifndef __FFT__ -#define __FFT__ -void fft(float x[], int n, int isign); - -#endif /* __FFT__ */ - diff --git a/gr-vocoder/lib/codec2/fifo.c b/gr-vocoder/lib/codec2/fifo.c new file mode 100644 index 0000000000..acac2614f7 --- /dev/null +++ b/gr-vocoder/lib/codec2/fifo.c @@ -0,0 +1,142 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: fifo.c + AUTHOR......: David Rowe + DATE CREATED: Oct 15 2012 + + A FIFO design useful in gluing the FDMDV modem and codec together in + integrated applications. The unittest/tfifo indicates these + routines are thread safe without the need for syncronisation + object, e.g. a different thread can read and write to a fifo at the + same time. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2012 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include "codec2_fifo.h" + +struct FIFO { + short *buf; + short *pin; + short *pout; + int nshort; +}; + +struct FIFO *fifo_create(int nshort) { + struct FIFO *fifo; + + fifo = (struct FIFO *)malloc(sizeof(struct FIFO)); + assert(fifo != NULL); + + fifo->buf = (short*)malloc(sizeof(short)*nshort); + assert(fifo->buf != NULL); + fifo->pin = fifo->buf; + fifo->pout = fifo->buf; + fifo->nshort = nshort; + + return fifo; +} + +void fifo_destroy(struct FIFO *fifo) { + assert(fifo != NULL); + free(fifo->buf); + free(fifo); +} + +int fifo_write(struct FIFO *fifo, short data[], int n) { + int i; + int fifo_free; + short *pdata; + short *pin = fifo->pin; + + assert(fifo != NULL); + assert(data != NULL); + + // available storage is one less than nshort as prd == pwr + // is reserved for empty rather than full + + fifo_free = fifo->nshort - fifo_used(fifo) - 1; + + if (n > fifo_free) { + return -1; + } + else { + + /* This could be made more efficient with block copies + using memcpy */ + + pdata = data; + for(i=0; i<n; i++) { + *pin++ = *pdata++; + if (pin == (fifo->buf + fifo->nshort)) + pin = fifo->buf; + } + fifo->pin = pin; + } + + return 0; +} + +int fifo_read(struct FIFO *fifo, short data[], int n) +{ + int i; + short *pdata; + short *pout = fifo->pout; + + assert(fifo != NULL); + assert(data != NULL); + + if (n > fifo_used(fifo)) { + return -1; + } + else { + + /* This could be made more efficient with block copies + using memcpy */ + + pdata = data; + for(i=0; i<n; i++) { + *pdata++ = *pout++; + if (pout == (fifo->buf + fifo->nshort)) + pout = fifo->buf; + } + fifo->pout = pout; + } + + return 0; +} + +int fifo_used(struct FIFO *fifo) +{ + short *pin = fifo->pin; + short *pout = fifo->pout; + unsigned int used; + + assert(fifo != NULL); + if (pin >= pout) + used = pin - pout; + else + used = fifo->nshort + (unsigned int)(pin - pout); + + return used; +} + diff --git a/gr-vocoder/lib/codec2/fq20.sh b/gr-vocoder/lib/codec2/fq20.sh deleted file mode 100755 index 9ccf739dc2..0000000000 --- a/gr-vocoder/lib/codec2/fq20.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# fq20.shsh -# David Rowe 27 July 2010 -# -# Decode a file with fully quantised codec at 20ms frame rate - -../src/sinedec ../raw/$1.raw $1.mdl -o $1_phase0_lsp_20_EWo2.raw --phase 0 --lpc 10 --lsp --postfilter --dec - diff --git a/gr-vocoder/lib/codec2/hanning.h b/gr-vocoder/lib/codec2/hanning.h new file mode 100644 index 0000000000..81d88dcb35 --- /dev/null +++ b/gr-vocoder/lib/codec2/hanning.h @@ -0,0 +1,644 @@ +/* Generated by hanning_file() Octave function */ + +const float hanning[]={ + 0, + 2.4171e-05, + 9.66816e-05, + 0.000217525, + 0.000386689, + 0.000604158, + 0.00086991, + 0.00118392, + 0.00154616, + 0.00195659, + 0.00241517, + 0.00292186, + 0.00347661, + 0.00407937, + 0.00473008, + 0.00542867, + 0.00617507, + 0.00696922, + 0.00781104, + 0.00870045, + 0.00963736, + 0.0106217, + 0.0116533, + 0.0127322, + 0.0138581, + 0.0150311, + 0.0162509, + 0.0175175, + 0.0188308, + 0.0201906, + 0.0215968, + 0.0230492, + 0.0245478, + 0.0260923, + 0.0276826, + 0.0293186, + 0.0310001, + 0.032727, + 0.034499, + 0.036316, + 0.0381779, + 0.0400844, + 0.0420354, + 0.0440307, + 0.04607, + 0.0481533, + 0.0502802, + 0.0524506, + 0.0546643, + 0.056921, + 0.0592206, + 0.0615627, + 0.0639473, + 0.0663741, + 0.0688427, + 0.0713531, + 0.0739048, + 0.0764978, + 0.0791318, + 0.0818064, + 0.0845214, + 0.0872767, + 0.0900718, + 0.0929066, + 0.0957807, + 0.0986939, + 0.101646, + 0.104636, + 0.107665, + 0.110732, + 0.113836, + 0.116978, + 0.120156, + 0.123372, + 0.126624, + 0.129912, + 0.133235, + 0.136594, + 0.139989, + 0.143418, + 0.146881, + 0.150379, + 0.153911, + 0.157476, + 0.161074, + 0.164705, + 0.168368, + 0.172063, + 0.17579, + 0.179549, + 0.183338, + 0.187158, + 0.191008, + 0.194888, + 0.198798, + 0.202737, + 0.206704, + 0.2107, + 0.214724, + 0.218775, + 0.222854, + 0.226959, + 0.231091, + 0.235249, + 0.239432, + 0.243641, + 0.247874, + 0.252132, + 0.256414, + 0.260719, + 0.265047, + 0.269398, + 0.273772, + 0.278167, + 0.282584, + 0.287021, + 0.29148, + 0.295958, + 0.300456, + 0.304974, + 0.30951, + 0.314065, + 0.318638, + 0.323228, + 0.327835, + 0.332459, + 0.3371, + 0.341756, + 0.346427, + 0.351113, + 0.355814, + 0.360528, + 0.365256, + 0.369997, + 0.374751, + 0.379516, + 0.384293, + 0.389082, + 0.393881, + 0.398691, + 0.40351, + 0.408338, + 0.413176, + 0.418022, + 0.422876, + 0.427737, + 0.432605, + 0.43748, + 0.44236, + 0.447247, + 0.452138, + 0.457034, + 0.461935, + 0.466839, + 0.471746, + 0.476655, + 0.481568, + 0.486481, + 0.491397, + 0.496313, + 0.501229, + 0.506145, + 0.511061, + 0.515976, + 0.520889, + 0.5258, + 0.530708, + 0.535614, + 0.540516, + 0.545414, + 0.550308, + 0.555197, + 0.560081, + 0.564958, + 0.56983, + 0.574695, + 0.579552, + 0.584402, + 0.589244, + 0.594077, + 0.598901, + 0.603715, + 0.60852, + 0.613314, + 0.618097, + 0.622868, + 0.627628, + 0.632375, + 0.63711, + 0.641831, + 0.646538, + 0.651232, + 0.655911, + 0.660574, + 0.665222, + 0.669855, + 0.67447, + 0.679069, + 0.683651, + 0.688215, + 0.69276, + 0.697287, + 0.701795, + 0.706284, + 0.710752, + 0.7152, + 0.719627, + 0.724033, + 0.728418, + 0.73278, + 0.73712, + 0.741437, + 0.74573, + 0.75, + 0.754246, + 0.758467, + 0.762663, + 0.766833, + 0.770978, + 0.775097, + 0.779189, + 0.783254, + 0.787291, + 0.791301, + 0.795283, + 0.799236, + 0.80316, + 0.807055, + 0.810921, + 0.814756, + 0.81856, + 0.822334, + 0.826077, + 0.829788, + 0.833468, + 0.837115, + 0.840729, + 0.844311, + 0.847859, + 0.851374, + 0.854855, + 0.858301, + 0.861713, + 0.86509, + 0.868431, + 0.871737, + 0.875007, + 0.87824, + 0.881437, + 0.884598, + 0.887721, + 0.890806, + 0.893854, + 0.896864, + 0.899835, + 0.902768, + 0.905661, + 0.908516, + 0.911331, + 0.914106, + 0.916841, + 0.919536, + 0.92219, + 0.924804, + 0.927376, + 0.929907, + 0.932397, + 0.934845, + 0.93725, + 0.939614, + 0.941935, + 0.944213, + 0.946448, + 0.94864, + 0.950789, + 0.952894, + 0.954955, + 0.956972, + 0.958946, + 0.960874, + 0.962759, + 0.964598, + 0.966393, + 0.968142, + 0.969846, + 0.971505, + 0.973118, + 0.974686, + 0.976207, + 0.977683, + 0.979112, + 0.980495, + 0.981832, + 0.983122, + 0.984365, + 0.985561, + 0.986711, + 0.987813, + 0.988868, + 0.989876, + 0.990837, + 0.99175, + 0.992616, + 0.993434, + 0.994204, + 0.994927, + 0.995601, + 0.996228, + 0.996807, + 0.997337, + 0.99782, + 0.998255, + 0.998641, + 0.998979, + 0.999269, + 0.999511, + 0.999704, + 0.999849, + 0.999946, + 0.999994, + 0.999994, + 0.999946, + 0.999849, + 0.999704, + 0.999511, + 0.999269, + 0.998979, + 0.998641, + 0.998255, + 0.99782, + 0.997337, + 0.996807, + 0.996228, + 0.995601, + 0.994927, + 0.994204, + 0.993434, + 0.992616, + 0.99175, + 0.990837, + 0.989876, + 0.988868, + 0.987813, + 0.986711, + 0.985561, + 0.984365, + 0.983122, + 0.981832, + 0.980495, + 0.979112, + 0.977683, + 0.976207, + 0.974686, + 0.973118, + 0.971505, + 0.969846, + 0.968142, + 0.966393, + 0.964598, + 0.962759, + 0.960874, + 0.958946, + 0.956972, + 0.954955, + 0.952894, + 0.950789, + 0.94864, + 0.946448, + 0.944213, + 0.941935, + 0.939614, + 0.93725, + 0.934845, + 0.932397, + 0.929907, + 0.927376, + 0.924804, + 0.92219, + 0.919536, + 0.916841, + 0.914106, + 0.911331, + 0.908516, + 0.905661, + 0.902768, + 0.899835, + 0.896864, + 0.893854, + 0.890806, + 0.887721, + 0.884598, + 0.881437, + 0.87824, + 0.875007, + 0.871737, + 0.868431, + 0.86509, + 0.861713, + 0.858301, + 0.854855, + 0.851374, + 0.847859, + 0.844311, + 0.840729, + 0.837115, + 0.833468, + 0.829788, + 0.826077, + 0.822334, + 0.81856, + 0.814756, + 0.810921, + 0.807055, + 0.80316, + 0.799236, + 0.795283, + 0.791301, + 0.787291, + 0.783254, + 0.779189, + 0.775097, + 0.770978, + 0.766833, + 0.762663, + 0.758467, + 0.754246, + 0.75, + 0.74573, + 0.741437, + 0.73712, + 0.73278, + 0.728418, + 0.724033, + 0.719627, + 0.7152, + 0.710752, + 0.706284, + 0.701795, + 0.697287, + 0.69276, + 0.688215, + 0.683651, + 0.679069, + 0.67447, + 0.669855, + 0.665222, + 0.660574, + 0.655911, + 0.651232, + 0.646538, + 0.641831, + 0.63711, + 0.632375, + 0.627628, + 0.622868, + 0.618097, + 0.613314, + 0.60852, + 0.603715, + 0.598901, + 0.594077, + 0.589244, + 0.584402, + 0.579552, + 0.574695, + 0.56983, + 0.564958, + 0.560081, + 0.555197, + 0.550308, + 0.545414, + 0.540516, + 0.535614, + 0.530708, + 0.5258, + 0.520889, + 0.515976, + 0.511061, + 0.506145, + 0.501229, + 0.496313, + 0.491397, + 0.486481, + 0.481568, + 0.476655, + 0.471746, + 0.466839, + 0.461935, + 0.457034, + 0.452138, + 0.447247, + 0.44236, + 0.43748, + 0.432605, + 0.427737, + 0.422876, + 0.418022, + 0.413176, + 0.408338, + 0.40351, + 0.398691, + 0.393881, + 0.389082, + 0.384293, + 0.379516, + 0.374751, + 0.369997, + 0.365256, + 0.360528, + 0.355814, + 0.351113, + 0.346427, + 0.341756, + 0.3371, + 0.332459, + 0.327835, + 0.323228, + 0.318638, + 0.314065, + 0.30951, + 0.304974, + 0.300456, + 0.295958, + 0.29148, + 0.287021, + 0.282584, + 0.278167, + 0.273772, + 0.269398, + 0.265047, + 0.260719, + 0.256414, + 0.252132, + 0.247874, + 0.243641, + 0.239432, + 0.235249, + 0.231091, + 0.226959, + 0.222854, + 0.218775, + 0.214724, + 0.2107, + 0.206704, + 0.202737, + 0.198798, + 0.194888, + 0.191008, + 0.187158, + 0.183338, + 0.179549, + 0.17579, + 0.172063, + 0.168368, + 0.164705, + 0.161074, + 0.157476, + 0.153911, + 0.150379, + 0.146881, + 0.143418, + 0.139989, + 0.136594, + 0.133235, + 0.129912, + 0.126624, + 0.123372, + 0.120156, + 0.116978, + 0.113836, + 0.110732, + 0.107665, + 0.104636, + 0.101646, + 0.0986939, + 0.0957807, + 0.0929066, + 0.0900718, + 0.0872767, + 0.0845214, + 0.0818064, + 0.0791318, + 0.0764978, + 0.0739048, + 0.0713531, + 0.0688427, + 0.0663741, + 0.0639473, + 0.0615627, + 0.0592206, + 0.056921, + 0.0546643, + 0.0524506, + 0.0502802, + 0.0481533, + 0.04607, + 0.0440307, + 0.0420354, + 0.0400844, + 0.0381779, + 0.036316, + 0.034499, + 0.032727, + 0.0310001, + 0.0293186, + 0.0276826, + 0.0260923, + 0.0245478, + 0.0230492, + 0.0215968, + 0.0201906, + 0.0188308, + 0.0175175, + 0.0162509, + 0.0150311, + 0.0138581, + 0.0127322, + 0.0116533, + 0.0106217, + 0.00963736, + 0.00870045, + 0.00781104, + 0.00696922, + 0.00617507, + 0.00542867, + 0.00473008, + 0.00407937, + 0.00347661, + 0.00292186, + 0.00241517, + 0.00195659, + 0.00154616, + 0.00118392, + 0.00086991, + 0.000604158, + 0.000386689, + 0.000217525, + 9.66816e-05, + 2.4171e-05, + 0 +}; diff --git a/gr-vocoder/lib/codec2/interp.c b/gr-vocoder/lib/codec2/interp.c index fad4554f43..be89fc3154 100644 --- a/gr-vocoder/lib/codec2/interp.c +++ b/gr-vocoder/lib/codec2/interp.c @@ -29,13 +29,11 @@ #include <math.h> #include <string.h> #include <stdio.h> -#include <stdlib.h> #include "defines.h" #include "interp.h" #include "lsp.h" #include "quantise.h" -#include "dump.h" float sample_log_amp(MODEL *model, float w); @@ -113,23 +111,19 @@ float sample_log_amp(MODEL *model, float w) assert(w > 0.0); assert (w <= PI); - m = 0; - while ((m+1)*model->Wo < w) m++; - f = (w - m*model->Wo)/model->Wo; + m = floorf(w/model->Wo + 0.5); + f = (w - m*model->Wo)/w; assert(f <= 1.0); if (m < 1) { - log_amp = f*log10(model->A[1] + 1E-6); + log_amp = f*log10f(model->A[1] + 1E-6); } else if ((m+1) > model->L) { - log_amp = (1.0-f)*log10(model->A[model->L] + 1E-6); + log_amp = (1.0-f)*log10f(model->A[model->L] + 1E-6); } else { - log_amp = (1.0-f)*log10(model->A[m] + 1E-6) + - f*log10(model->A[m+1] + 1E-6); - //printf("m=%d A[m] %f A[m+1] %f x %f %f %f\n", m, model->A[m], - // model->A[m+1], pow(10.0, log_amp), - // (1-f), f); + log_amp = (1.0-f)*log10f(model->A[m] + 1E-6) + + f*log10f(model->A[m+1] + 1E-6); } return log_amp; @@ -137,338 +131,193 @@ float sample_log_amp(MODEL *model, float w) /*---------------------------------------------------------------------------*\ - FUNCTION....: sample_log_amp_quad() + FUNCTION....: interp_lsp() AUTHOR......: David Rowe - DATE CREATED: 9 March 2011 - - Samples the amplitude envelope at an arbitrary frequency w. Uses - quadratic interpolation in the log domain to sample between harmonic - amplitudes. - - y(x) = ax*x + bx + c + DATE CREATED: 10 Nov 2010 - We assume three points are x=-1, x=0, x=1, which we map to m-1,m,m+1 + Given two frames decribed by model parameters 20ms apart, determines + the model parameters of the 10ms frame between them. Assumes + voicing is available for middle (interpolated) frame. Outputs are + amplitudes and Wo for the interpolated frame. - c = y(0) - b = (y(1) - y(-1))/2 - a = y(-1) + b - y(0) + This version uses interpolation of LSPs, seems to do a better job + with bg noise. \*---------------------------------------------------------------------------*/ -float sample_log_amp_quad(MODEL *model, float w) +void interpolate_lsp( + kiss_fft_cfg fft_fwd_cfg, + MODEL *interp, /* interpolated model params */ + MODEL *prev, /* previous frames model params */ + MODEL *next, /* next frames model params */ + float *prev_lsps, /* previous frames LSPs */ + float prev_e, /* previous frames LPC energy */ + float *next_lsps, /* next frames LSPs */ + float next_e, /* next frames LPC energy */ + float *ak_interp, /* interpolated aks for this frame */ + float *lsps_interp/* interpolated lsps for this frame */ +) { - int m; - float a,b,c,x, log_amp; + int i; + float e; + float snr; - assert(w > 0.0); assert (w <= PI); + /* trap corner case where V est is probably wrong */ - m = floor(w/model->Wo + 0.5); - if (m < 2) m = 2; - if (m > (model->L-1)) m = model->L-1; - c = log10(model->A[m]+1E-6); - b = (log10(model->A[m+1]+1E-6) - log10(model->A[m-1]+1E-6))/2.0; - a = log10(model->A[m-1]+1E-6) + b - c; - x = (w - m*model->Wo)/model->Wo; - - log_amp = a*x*x + b*x + c; - //printf("m=%d A[m-1] %f A[m] %f A[m+1] %f w %f x %f log_amp %f\n", m, - // model->A[m-1], - // model->A[m], model->A[m+1], w, x, pow(10.0, log_amp)); - return log_amp; -} + if (interp->voiced && !prev->voiced && !next->voiced) { + interp->voiced = 0; + } -/*---------------------------------------------------------------------------*\ + /* Wo depends on voicing of this and adjacent frames */ - FUNCTION....: sample_log_amp_quad_nl() - AUTHOR......: David Rowe - DATE CREATED: 10 March 2011 + if (interp->voiced) { + if (prev->voiced && next->voiced) + interp->Wo = (prev->Wo + next->Wo)/2.0; + if (!prev->voiced && next->voiced) + interp->Wo = next->Wo; + if (prev->voiced && !next->voiced) + interp->Wo = prev->Wo; + } + else { + interp->Wo = TWO_PI/P_MAX; + } + interp->L = PI/interp->Wo; - Samples the amplitude envelope at an arbitrary frequency w. Uses - quadratic interpolation in the log domain to sample between harmonic - amplitudes. This version can handle non-linear steps along a freq - axis defined by arbitrary steps. + //printf(" interp: prev_v: %d next_v: %d prev_Wo: %f next_Wo: %f\n", + // prev->voiced, next->voiced, prev->Wo, next->Wo); + //printf(" interp: Wo: %1.5f L: %d\n", interp->Wo, interp->L); - y(x) = ax*x + bx + c + /* interpolate LSPs */ - We assume three points are (x_1,y_1), (0,y0) and (x1,y1). + for(i=0; i<LPC_ORD; i++) { + lsps_interp[i] = (prev_lsps[i] + next_lsps[i])/2.0; + } -\*---------------------------------------------------------------------------*/ + /* Interpolate LPC energy in log domain */ -float sample_log_amp_quad_nl( - float w[], /* frequency points */ - float A[], /* for these amplitude samples */ - int np, /* number of frequency points */ - float w_sample /* frequency of new samples */ -) -{ - int m,i; - float a,b,c,x, log_amp, best_dist; - float x_1, x1; - float y_1, y0, y1; - - //printf("w_sample %f\n", w_sample); - assert(w_sample >= 0.0); assert (w_sample <= 1.1*PI); - - /* find closest point to centre quadratic interpolator */ - - best_dist = 1E32; - m = 0; - for (i=0; i<np; i++) - if (fabs(w[i] - w_sample) < best_dist) { - best_dist = fabs(w[i] - w_sample); - m = i; - } - - /* stay one point away from edge of array */ - - if (m < 1) m = 1; - if (m > (np-2)) m = np - 2; - - /* find polynomial coeffs */ - - x_1 = w[m-1]- w[m]; x1 = w[m+1] - w[m]; - y_1 = log10(A[m-1]+1E-6); - y0 = log10(A[m]+1E-6); - y1 = log10(A[m+1]+1E-6); - - c = y0; - a = (y_1*x1 - y1*x_1 + c*x_1 - c*x1)/(x_1*x_1*x1 - x1*x1*x_1); - b = (y1 -a*x1*x1 - c)/x1; - x = w_sample - w[m]; - - //printf("%f %f %f\n", w[0], w[1], w[2]); - //printf("%f %f %f %f %f %f\n", x_1, y_1, 0.0, y0, x1, y1); - log_amp = a*x*x + b*x + c; - //printf("a %f b %f c %f\n", a, b, c); - //printf("m=%d A[m-1] %f A[m] %f A[m+1] %f w_sample %f w[m] %f x %f log_amp %f\n", m, - // A[m-1], - // A[m], A[m+1], w_sample, w[m], x, log_amp); - //exit(0); - return log_amp; -} + e = powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0); + //printf(" interp: e: %f\n", e); -#define M_MAX 40 + /* convert back to amplitudes */ + + lsp_to_lpc(lsps_interp, ak_interp, LPC_ORD); + aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA); + //printf(" interp: ak[1]: %f A[1] %f\n", ak_interp[1], interp->A[1]); +} -float fres[] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, - 1200, 1400, 1600, 1850, 2100, 2350, 2600, 2900, 3400, 3800}; /*---------------------------------------------------------------------------*\ - FUNCTION....: resample_amp_nl() + FUNCTION....: interp_Wo() AUTHOR......: David Rowe - DATE CREATED: 7 March 2011 + DATE CREATED: 22 May 2012 - Converts the current model with L {Am} samples spaced Wo apart to - RES_POINTS samples spaced Wo/RES_POINTS apart. Then subtracts - from the previous frames samples to get the delta. + Interpolates centre 10ms sample of Wo and L samples given two + samples 20ms apart. Assumes voicing is available for centre + (interpolated) frame. \*---------------------------------------------------------------------------*/ -void resample_amp_fixed(MODEL *model, - float w[], float A[], - float wres[], float Ares[], - float AresdB_prev[], - float AresdB[], - float deltat[]) +void interp_Wo( + MODEL *interp, /* interpolated model params */ + MODEL *prev, /* previous frames model params */ + MODEL *next /* next frames model params */ + ) { - int i; - - for(i=1; i<=model->L; i++) { - w[i-1] = i*model->Wo; - A[i-1] = model->A[i]; - } - - for(i=0; i<RES_POINTS; i++) { - wres[i] = fres[i]*PI/4000.0; - } - - for(i=0; i<RES_POINTS; i++) { - Ares[i] = pow(10.0,sample_log_amp_quad_nl(w, A, model->L, wres[i])); - } - - /* work out delta T vector for this frame */ - - for(i=0; i<RES_POINTS; i++) { - AresdB[i] = 20.0*log10(Ares[i]); - deltat[i] = AresdB[i] - AresdB_prev[i]; - } - + interp_Wo2(interp, prev, next, 0.5); } /*---------------------------------------------------------------------------*\ - FUNCTION....: resample_amp_nl() + FUNCTION....: interp_Wo2() AUTHOR......: David Rowe - DATE CREATED: 7 March 2011 - - Converts the current model with L {Am} samples spaced Wo apart to M - samples spaced Wo/M apart. Then converts back to L {Am} samples. - used to prototype constant rate Amplitude encoding ideas. + DATE CREATED: 22 May 2012 - Returns the SNR in dB. + Weighted interpolation of two Wo samples. \*---------------------------------------------------------------------------*/ -float resample_amp_nl(MODEL *model, int m, float AresdB_prev[]) +void interp_Wo2( + MODEL *interp, /* interpolated model params */ + MODEL *prev, /* previous frames model params */ + MODEL *next, /* next frames model params */ + float weight +) { - int i; - float w[MAX_AMP], A[MAX_AMP]; - float wres[MAX_AMP], Ares[MAX_AMP], AresdB[MAX_AMP]; - float signal, noise, snr; - float new_A; - float deltat[MAX_AMP], deltat_q[MAX_AMP], AresdB_q[MAX_AMP]; - - resample_amp_fixed(model, w, A, wres, Ares, AresdB_prev, AresdB, deltat); - - /* quantise delta T vector */ - - for(i=0; i<RES_POINTS; i++) { - noise = 3.0*(1.0 - 2.0*rand()/RAND_MAX); - //noise = 0.0; - deltat_q[i] = deltat[i] + noise; - } + /* trap corner case where voicing est is probably wrong */ - /* recover Ares vector */ - - for(i=0; i<RES_POINTS; i++) { - AresdB_q[i] = AresdB_prev[i] + deltat_q[i]; - Ares[i] = pow(10.0, AresdB_q[i]/20.0); - //printf("%d %f %f\n", i, AresdB[i], AresdB_q[i]); + if (interp->voiced && !prev->voiced && !next->voiced) { + interp->voiced = 0; } - /* update memory based on version at decoder */ + /* Wo depends on voicing of this and adjacent frames */ - for(i=0; i<RES_POINTS; i++) { - AresdB_prev[i] = AresdB_q[i]; + if (interp->voiced) { + if (prev->voiced && next->voiced) + interp->Wo = (1.0 - weight)*prev->Wo + weight*next->Wo; + if (!prev->voiced && next->voiced) + interp->Wo = next->Wo; + if (prev->voiced && !next->voiced) + interp->Wo = prev->Wo; } - -#ifdef DUMP - dump_resample(wres,Ares,M_MAX); -#endif - - signal = noise = 0.0; - - for(i=1; i<model->L; i++) { - new_A = pow(10.0,sample_log_amp_quad_nl(wres, Ares, RES_POINTS, model->Wo*i)); - signal += pow(model->A[i], 2.0); - noise += pow(model->A[i] - new_A, 2.0); - //printf("%f %f\n", model->A[i], new_A); - model->A[i] = new_A; + else { + interp->Wo = TWO_PI/P_MAX; } - - snr = 10.0*log10(signal/noise); - printf("snr = %3.2f\n", snr); - //exit(0); - return snr; + interp->L = PI/interp->Wo; } + /*---------------------------------------------------------------------------*\ - FUNCTION....: resample_amp() + FUNCTION....: interp_energy() AUTHOR......: David Rowe - DATE CREATED: 10 March 2011 - - Converts the current model with L {Am} samples spaced Wo apart to M - samples with a non-linear spacing. Then converts back to L {Am} - samples. used to prototype constant rate Amplitude encoding ideas. + DATE CREATED: 22 May 2012 - Returns the SNR in dB. + Interpolates centre 10ms sample of energy given two samples 20ms + apart. \*---------------------------------------------------------------------------*/ -float resample_amp(MODEL *model, int m) +float interp_energy(float prev_e, float next_e) { - int i; - MODEL model_m; - float new_A, signal, noise, snr, log_amp_dB; - float n_db = 0.0; - - model_m.Wo = PI/(float)m; - model_m.L = PI/model_m.Wo; - - for(i=1; i<=model_m.L; i++) { - log_amp_dB = 20.0*sample_log_amp_quad(model, i*model_m.Wo); - log_amp_dB += n_db*(1.0 - 2.0*rand()/RAND_MAX); - model_m.A[i] = pow(10,log_amp_dB/20.0); - } - - //dump_resample(&model_m); - - signal = noise = 0.0; + return powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0); - for(i=1; i<model->L/4; i++) { - new_A = pow(10,sample_log_amp_quad(&model_m, i*model->Wo)); - signal += pow(model->A[i], 2.0); - noise += pow(model->A[i] - new_A, 2.0); - //printf("%f %f\n", model->A[i], new_A); - model->A[i] = new_A; - } - - snr = 10.0*log10(signal/noise); - //printf("snr = %3.2f\n", snr); - //exit(0); - return snr; } + /*---------------------------------------------------------------------------*\ - FUNCTION....: interp_lsp() + FUNCTION....: interp_energy2() AUTHOR......: David Rowe - DATE CREATED: 10 Nov 2010 - - Given two frames decribed by model parameters 20ms apart, determines - the model parameters of the 10ms frame between them. Assumes - voicing is available for middle (interpolated) frame. Outputs are - amplitudes and Wo for the interpolated frame. + DATE CREATED: 22 May 2012 - This version uses interpolation of LSPs, seems to do a better job - with bg noise. + Interpolates centre 10ms sample of energy given two samples 20ms + apart. \*---------------------------------------------------------------------------*/ -void interpolate_lsp( - MODEL *interp, /* interpolated model params */ - MODEL *prev, /* previous frames model params */ - MODEL *next, /* next frames model params */ - float *prev_lsps, /* previous frames LSPs */ - float prev_e, /* previous frames LPC energy */ - float *next_lsps, /* next frames LSPs */ - float next_e, /* next frames LPC energy */ - float *ak_interp /* interpolated aks for this frame */ - ) +float interp_energy2(float prev_e, float next_e, float weight) { - //int l,i; - int i; - float lsps[LPC_ORD],e; - float snr; + return powf(10.0, (1.0 - weight)*log10f(prev_e) + weight*log10f(next_e)); - /* Wo depends on voicing of this and adjacent frames */ +} - if (interp->voiced) { - if (prev->voiced && next->voiced) - interp->Wo = (prev->Wo + next->Wo)/2.0; - if (!prev->voiced && next->voiced) - interp->Wo = next->Wo; - if (prev->voiced && !next->voiced) - interp->Wo = prev->Wo; - } - else { - interp->Wo = TWO_PI/P_MAX; - } - interp->L = PI/interp->Wo; - /* interpolate LSPs */ +/*---------------------------------------------------------------------------*\ - for(i=0; i<LPC_ORD; i++) { - lsps[i] = (prev_lsps[i] + next_lsps[i])/2.0; - } + FUNCTION....: interpolate_lsp_ver2() + AUTHOR......: David Rowe + DATE CREATED: 22 May 2012 - /* Interpolate LPC energy in log domain */ + Weighted interpolation of LSPs. - e = pow(10.0, (log10(prev_e) + log10(next_e))/2.0); +\*---------------------------------------------------------------------------*/ - /* convert back to amplitudes */ +void interpolate_lsp_ver2(float interp[], float prev[], float next[], float weight) +{ + int i; - lsp_to_lpc(lsps, ak_interp, LPC_ORD); - aks_to_M2(ak_interp, LPC_ORD, interp, e, &snr, 0); + for(i=0; i<LPC_ORD; i++) + interp[i] = (1.0 - weight)*prev[i] + weight*next[i]; } + diff --git a/gr-vocoder/lib/codec2/interp.h b/gr-vocoder/lib/codec2/interp.h index d509726140..24cb9462a3 100644 --- a/gr-vocoder/lib/codec2/interp.h +++ b/gr-vocoder/lib/codec2/interp.h @@ -28,14 +28,18 @@ #ifndef __INTERP__ #define __INTERP__ -#define RES_POINTS 20 +#include "kiss_fft.h" void interpolate(MODEL *interp, MODEL *prev, MODEL *next); -void interpolate_lsp(MODEL *interp, MODEL *prev, MODEL *next, +void interpolate_lsp(kiss_fft_cfg fft_dec_cfg, + MODEL *interp, MODEL *prev, MODEL *next, float *prev_lsps, float prev_e, float *next_lsps, float next_e, - float *ak_interp); -float resample_amp(MODEL *model, int m); -float resample_amp_nl(MODEL *model, int m, float Ares_prev[]); + float *ak_interp, float *lsps_interp); +void interp_Wo(MODEL *interp, MODEL *prev, MODEL *next); +void interp_Wo2(MODEL *interp, MODEL *prev, MODEL *next, float weight); +float interp_energy(float prev, float next); +float interp_energy2(float prev, float next, float weight); +void interpolate_lsp_ver2(float interp[], float prev[], float next[], float weight); #endif diff --git a/gr-vocoder/lib/codec2/listensim.sh b/gr-vocoder/lib/codec2/listensim.sh deleted file mode 100755 index 0b27a1b0cb..0000000000 --- a/gr-vocoder/lib/codec2/listensim.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -# listensim.sh -# David Rowe 10 Sep 2009 -# -# Listen to files processed with sim.sh - -../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_lpc10.raw $1_phase0_lpc10.raw $1_phase0_lpc10_dec.raw $1_phase0_lsp_dec.raw $2 $3 - - diff --git a/gr-vocoder/lib/codec2/lpc.c b/gr-vocoder/lib/codec2/lpc.c index 1784f75ca1..9a730eb4ad 100644 --- a/gr-vocoder/lib/codec2/lpc.c +++ b/gr-vocoder/lib/codec2/lpc.c @@ -2,14 +2,14 @@ FILE........: lpc.c AUTHOR......: David Rowe - DATE CREATED: 30/9/90 + DATE CREATED: 30 Sep 1990 (!) Linear Prediction functions written in C. \*---------------------------------------------------------------------------*/ /* - Copyright (C) 2009 David Rowe + Copyright (C) 2009-2012 David Rowe All rights reserved. @@ -28,6 +28,9 @@ #define LPC_MAX_N 512 /* maximum no. of samples in frame */ #define PI 3.141592654 /* mathematical constant */ +#define ALPHA 1.0 +#define BETA 0.94 + #include <assert.h> #include <math.h> #include "defines.h" @@ -35,6 +38,60 @@ /*---------------------------------------------------------------------------*\ + pre_emp() + + Pre-emphasise (high pass filter with zero close to 0 Hz) a frame of + speech samples. Helps reduce dynamic range of LPC spectrum, giving + greater weight and hensea better match to low energy formants. + + Should be balanced by de-emphasis of the output speech. + +\*---------------------------------------------------------------------------*/ + +void pre_emp( + float Sn_pre[], /* output frame of speech samples */ + float Sn[], /* input frame of speech samples */ + float *mem, /* Sn[-1]single sample memory */ + int Nsam /* number of speech samples to use */ +) +{ + int i; + + for(i=0; i<Nsam; i++) { + Sn_pre[i] = Sn[i] - ALPHA * mem[0]; + mem[0] = Sn[i]; + } + +} + + +/*---------------------------------------------------------------------------*\ + + de_emp() + + De-emphasis filter (low pass filter with polse close to 0 Hz). + +\*---------------------------------------------------------------------------*/ + +void de_emp( + float Sn_de[], /* output frame of speech samples */ + float Sn[], /* input frame of speech samples */ + float *mem, /* Sn[-1]single sample memory */ + int Nsam /* number of speech samples to use */ +) +{ + int i; + + for(i=0; i<Nsam; i++) { + Sn_de[i] = Sn[i] + BETA * mem[0]; + mem[0] = Sn_de[i]; + } + +} + + +/*---------------------------------------------------------------------------*\ + hanning_window() Hanning windows a frame of speech samples. @@ -50,7 +107,7 @@ void hanning_window( int i; /* loop variable */ for(i=0; i<Nsam; i++) - Wn[i] = Sn[i]*(0.5 - 0.5*cos(2*PI*(float)i/(Nsam-1))); + Wn[i] = Sn[i]*(0.5 - 0.5*cosf(2*PI*(float)i/(Nsam-1))); } /*---------------------------------------------------------------------------*\ @@ -80,33 +137,6 @@ void autocorrelate( /*---------------------------------------------------------------------------*\ - autocorrelate_freq() - - Finds the first P autocorrelation values from an array of frequency domain - power samples. - -\*---------------------------------------------------------------------------*/ - -void autocorrelate_freq( - float Pw[], /* Nsam frequency domain power spectrum samples */ - float w[], /* frequency of each sample in Pw[] */ - float R[], /* array of order+1 autocorrelation coefficients */ - int Nsam, /* number of windowed samples to use */ - int order /* order of LPC analysis */ -) -{ - int i,j; /* loop variables */ - - for(j=0; j<order+1; j++) { - R[j] = 0.0; - for(i=0; i<Nsam; i++) - R[j] += Pw[i]*cos(j*w[i]); - } - R[j] /= Nsam; -} - -/*---------------------------------------------------------------------------*\ - levinson_durbin() Given P+1 autocorrelation coefficients, finds P Linear Prediction Coeff. @@ -139,7 +169,7 @@ void levinson_durbin( for(j=1; j<=i-1; j++) sum += a[i-1][j]*R[i-j]; k[i] = -1.0*(R[i] + sum)/E[i-1]; /* Equation 38b, Makhoul */ - if (fabs(k[i]) > 1.0) + if (fabsf(k[i]) > 1.0) k[i] = 0.0; a[i][i] = k[i]; @@ -274,6 +304,6 @@ void weight( int i; for(i=1; i<=order; i++) - akw[i] = ak[i]*pow(gamma,(float)i); + akw[i] = ak[i]*powf(gamma,(float)i); } diff --git a/gr-vocoder/lib/codec2/lpc.h b/gr-vocoder/lib/codec2/lpc.h index 9125189d1b..482aa1fff5 100644 --- a/gr-vocoder/lib/codec2/lpc.h +++ b/gr-vocoder/lib/codec2/lpc.h @@ -9,7 +9,7 @@ \*---------------------------------------------------------------------------*/ /* - Copyright (C) 2009 David Rowe + Copyright (C) 2009-2012 David Rowe All rights reserved. @@ -30,9 +30,10 @@ #define LPC_MAX_ORDER 20 +void pre_emp(float Sn_pre[], float Sn[], float *mem, int Nsam); +void de_emp(float Sn_se[], float Sn[], float *mem, int Nsam); void hanning_window(float Sn[], float Wn[], int Nsam); void autocorrelate(float Sn[], float Rn[], int Nsam, int order); -void autocorrelate_freq(float Pw[], float w[], float R[], int Nsam, int order); void levinson_durbin(float R[], float lpcs[], int order); void inverse_filter(float Sn[], float a[], int Nsam, float res[], int order); void synthesis_filter(float res[], float a[], int Nsam, int order, float Sn_[]); diff --git a/gr-vocoder/lib/codec2/lsp.c b/gr-vocoder/lib/codec2/lsp.c index b57507bb42..3f34444e33 100644 --- a/gr-vocoder/lib/codec2/lsp.c +++ b/gr-vocoder/lib/codec2/lsp.c @@ -212,7 +212,7 @@ int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta) interval between xl and xr and repeat till root is located within the specified limits */ - if((psumr*psuml)<0.0){ + if(((psumr*psuml)<0.0) || (psumr == 0.0)){ roots++; psumm=psuml; diff --git a/gr-vocoder/lib/codec2/machdep.h b/gr-vocoder/lib/codec2/machdep.h new file mode 100644 index 0000000000..ef2e64943e --- /dev/null +++ b/gr-vocoder/lib/codec2/machdep.h @@ -0,0 +1,51 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: machdep.h + AUTHOR......: David Rowe + DATE CREATED: May 2 2013 + + Machine dependant functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2013 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __MACHDEP__ +#define __MACHDEP__ + +#ifdef TIMER +#define TIMER_VAR(...) unsigned int __VA_ARGS__ +#define TIMER_SAMPLE(timestamp) timestamp = machdep_timer_sample() +#define TIMER_SAMPLE_AND_LOG(timestamp, prev_timestamp, label) \ + timestamp = machdep_timer_sample_and_log(prev_timestamp, label) +#define TIMER_SAMPLE_AND_LOG2(prev_timestamp, label) \ + machdep_timer_sample_and_log(prev_timestamp, label) +#else +#define TIMER_VAR(...) +#define TIMER_SAMPLE(timestamp) +#define TIMER_SAMPLE_AND_LOG(timestamp, prev_timestamp, label) +#define TIMER_SAMPLE_AND_LOG2(prev_timestamp, label) +#endif + +void machdep_timer_init(void); +void machdep_timer_reset(void); +unsigned int machdep_timer_sample(void); +unsigned int machdep_timer_sample_and_log(unsigned int start, char s[]); +void machdep_timer_print_logged_samples(void); + +#endif diff --git a/gr-vocoder/lib/codec2/nlp.c b/gr-vocoder/lib/codec2/nlp.c index 0d5e530ce6..cca835b46f 100644 --- a/gr-vocoder/lib/codec2/nlp.c +++ b/gr-vocoder/lib/codec2/nlp.c @@ -28,7 +28,9 @@ #include "defines.h" #include "nlp.h" #include "dump.h" -#include "fft.h" +#include "kiss_fft.h" +#undef TIMER +#include "machdep.h" #include <assert.h> #include <math.h> @@ -51,6 +53,8 @@ #define CNLP 0.3 /* post processor constant */ #define NLP_NTAP 48 /* Decimation LPF order */ +#undef DUMP + /*---------------------------------------------------------------------------*\ GLOBALS @@ -111,12 +115,16 @@ const float nlp_fir[] = { }; typedef struct { - float sq[PMAX_M]; /* squared speech samples */ - float mem_x,mem_y; /* memory for notch filter */ - float mem_fir[NLP_NTAP]; /* decimation FIR filter memory */ + int m; + float w[PMAX_M/DEC]; /* DFT window */ + float sq[PMAX_M]; /* squared speech samples */ + float mem_x,mem_y; /* memory for notch filter */ + float mem_fir[NLP_NTAP]; /* decimation FIR filter memory */ + kiss_fft_cfg fft_cfg; /* kiss FFT config */ } NLP; -float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax); +float test_candidate_mbe(COMP Sw[], COMP W[], float f0); +float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax, COMP Sw[], COMP W[], float *prev_Wo); float post_process_sub_multiples(COMP Fw[], int pmin, int pmax, float gmax, int gmax_bin, float *prev_Wo); @@ -129,15 +137,24 @@ float post_process_sub_multiples(COMP Fw[], \*---------------------------------------------------------------------------*/ -void *nlp_create() +void *nlp_create( +int m /* analysis window size */ +) { NLP *nlp; int i; + assert(m <= PMAX_M); + nlp = (NLP*)malloc(sizeof(NLP)); if (nlp == NULL) return NULL; + nlp->m = m; + for(i=0; i<m/DEC; i++) { + nlp->w[i] = 0.5 - 0.5*cosf(2*PI*i/(m/DEC-1)); + } + for(i=0; i<PMAX_M; i++) nlp->sq[i] = 0.0; nlp->mem_x = 0.0; @@ -145,20 +162,27 @@ void *nlp_create() for(i=0; i<NLP_NTAP; i++) nlp->mem_fir[i] = 0.0; + nlp->fft_cfg = kiss_fft_alloc (PE_FFT_SIZE, 0, NULL, NULL); + assert(nlp->fft_cfg != NULL); + return (void*)nlp; } /*---------------------------------------------------------------------------*\ - nlp_destory() + nlp_destroy() - Initialisation function for NLP pitch estimator. + Shut down function for NLP pitch estimator. \*---------------------------------------------------------------------------*/ void nlp_destroy(void *nlp_state) { + NLP *nlp; assert(nlp_state != NULL); + nlp = (NLP*)nlp_state; + + KISS_FFT_FREE(nlp->fft_cfg); free(nlp_state); } @@ -196,28 +220,33 @@ float nlp( void *nlp_state, float Sn[], /* input speech vector */ int n, /* frames shift (no. new samples in Sn[]) */ - int m, /* analysis window size */ - int pmin, /* minimum pitch value */ + int pmin, /* minimum pitch value */ int pmax, /* maximum pitch value */ float *pitch, /* estimated pitch period in samples */ COMP Sw[], /* Freq domain version of Sn[] */ + COMP W[], /* Freq domain window */ float *prev_Wo ) { NLP *nlp; - float notch; /* current notch filter output */ - COMP Fw[PE_FFT_SIZE]; /* DFT of squared signal */ + float notch; /* current notch filter output */ + COMP fw[PE_FFT_SIZE]; /* DFT of squared signal (input) */ + COMP Fw[PE_FFT_SIZE]; /* DFT of squared signal (output) */ float gmax; int gmax_bin; - int i,j; - float best_f0; + int m, i,j; + float best_f0; + TIMER_VAR(start, tnotch, filter, peakpick, window, fft, magsq, shiftmem); assert(nlp_state != NULL); nlp = (NLP*)nlp_state; + m = nlp->m; + + TIMER_SAMPLE(start); /* Square, notch filter at DC, and LP filter vector */ - for(i=m-n; i<M; i++) /* square latest speech samples */ + for(i=m-n; i<m; i++) /* square latest speech samples */ nlp->sq[i] = Sn[i]*Sn[i]; for(i=m-n; i<m; i++) { /* notch filter at DC */ @@ -225,9 +254,18 @@ float nlp( notch += COEFF*nlp->mem_y; nlp->mem_x = nlp->sq[i]; nlp->mem_y = notch; - nlp->sq[i] = notch; + nlp->sq[i] = notch + 1.0; /* With 0 input vectors to codec, + kiss_fft() would take a long + time to execute when running in + real time. Problem was traced + to kiss_fft function call in + this function. Adding this small + constant fixed problem. Not + exactly sure why. */ } + TIMER_SAMPLE_AND_LOG(tnotch, start, " square and notch"); + for(i=m-n; i<m; i++) { /* FIR filter vector */ for(j=0; j<NLP_NTAP-1; j++) @@ -239,26 +277,33 @@ float nlp( nlp->sq[i] += nlp->mem_fir[j]*nlp_fir[j]; } + TIMER_SAMPLE_AND_LOG(filter, tnotch, " filter"); + /* Decimate and DFT */ for(i=0; i<PE_FFT_SIZE; i++) { - Fw[i].real = 0.0; - Fw[i].imag = 0.0; + fw[i].real = 0.0; + fw[i].imag = 0.0; } for(i=0; i<m/DEC; i++) { - Fw[i].real = nlp->sq[i*DEC]*(0.5 - 0.5*cos(2*PI*i/(m/DEC-1))); + fw[i].real = nlp->sq[i*DEC]*nlp->w[i]; } -#ifdef DUMP + TIMER_SAMPLE_AND_LOG(window, filter, " window"); + #ifdef DUMP dump_dec(Fw); -#endif - fft(&Fw[0].real,PE_FFT_SIZE,1); + #endif + + kiss_fft(nlp->fft_cfg, (kiss_fft_cpx *)fw, (kiss_fft_cpx *)Fw); + TIMER_SAMPLE_AND_LOG(fft, window, " fft"); + for(i=0; i<PE_FFT_SIZE; i++) Fw[i].real = Fw[i].real*Fw[i].real + Fw[i].imag*Fw[i].imag; -#ifdef DUMP + TIMER_SAMPLE_AND_LOG(magsq, fft, " mag sq"); + #ifdef DUMP dump_sq(nlp->sq); dump_Fw(Fw); -#endif + #endif /* find global peak */ @@ -271,8 +316,16 @@ float nlp( } } - best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, - prev_Wo); + TIMER_SAMPLE_AND_LOG(peakpick, magsq, " peak pick"); + + //#define POST_PROCESS_MBE + #ifdef POST_PROCESS_MBE + best_f0 = post_process_mbe(Fw, pmin, pmax, gmax, Sw, W, prev_Wo); + #else + best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, prev_Wo); + #endif + + TIMER_SAMPLE_AND_LOG(shiftmem, peakpick, " post process"); /* Shift samples in buffer to make room for new samples */ @@ -282,6 +335,11 @@ float nlp( /* return pitch and F0 estimate */ *pitch = (float)SAMPLE_RATE/best_f0; + + TIMER_SAMPLE_AND_LOG2(shiftmem, " shift mem"); + + TIMER_SAMPLE_AND_LOG2(start, " nlp int"); + return(best_f0); } @@ -289,7 +347,7 @@ float nlp( post_process_sub_multiples() - Given the global maximma of Fw[] we search interger submultiples for + Given the global maximma of Fw[] we search integer submultiples for local maxima. If local maxima exist and they are above an experimentally derived threshold (OK a magic number I pulled out of the air) we choose the submultiple as the F0 estimate. @@ -314,7 +372,7 @@ float post_process_sub_multiples(COMP Fw[], int mult; float thresh, best_f0; int b, bmin, bmax, lmax_bin; - float lmax, cmax; + float lmax; int prev_f0_bin; /* post process estimate by searching submultiples */ @@ -342,7 +400,7 @@ float post_process_sub_multiples(COMP Fw[], lmax = 0; lmax_bin = bmin; - for (b=bmin; b<=bmax; b++) /* look for maximum in interval */ + for (b=bmin; b<=bmax; b++) /* look for maximum in interval */ if (Fw[b].real > lmax) { lmax = Fw[b].real; lmax_bin = b; @@ -350,7 +408,6 @@ float post_process_sub_multiples(COMP Fw[], if (lmax > thresh) if ((lmax > Fw[lmax_bin-1].real) && (lmax > Fw[lmax_bin+1].real)) { - cmax = lmax; cmax_bin = lmax_bin; } @@ -362,3 +419,171 @@ float post_process_sub_multiples(COMP Fw[], return best_f0; } +/*---------------------------------------------------------------------------*\ + + post_process_mbe() + + Use the MBE pitch estimation algorithm to evaluate pitch candidates. This + works OK but the accuracy at low F0 is affected by NW, the analysis window + size used for the DFT of the input speech Sw[]. Also favours high F0 in + the presence of background noise which causes periodic artifacts in the + synthesised speech. + +\*---------------------------------------------------------------------------*/ + +float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax, COMP Sw[], COMP W[], float *prev_Wo) +{ + float candidate_f0; + float f0,best_f0; /* fundamental frequency */ + float e,e_min; /* MBE cost function */ + int i; + #ifdef DUMP + float e_hz[F0_MAX]; + #endif + #if !defined(NDEBUG) || defined(DUMP) + int bin; + #endif + float f0_min, f0_max; + float f0_start, f0_end; + + f0_min = (float)SAMPLE_RATE/pmax; + f0_max = (float)SAMPLE_RATE/pmin; + + /* Now look for local maxima. Each local maxima is a candidate + that we test using the MBE pitch estimation algotithm */ + + #ifdef DUMP + for(i=0; i<F0_MAX; i++) + e_hz[i] = -1; + #endif + e_min = 1E32; + best_f0 = 50; + for(i=PE_FFT_SIZE*DEC/pmax; i<=PE_FFT_SIZE*DEC/pmin; i++) { + if ((Fw[i].real > Fw[i-1].real) && (Fw[i].real > Fw[i+1].real)) { + + /* local maxima found, lets test if it's big enough */ + + if (Fw[i].real > T*gmax) { + + /* OK, sample MBE cost function over +/- 10Hz range in 2.5Hz steps */ + + candidate_f0 = (float)i*SAMPLE_RATE/(PE_FFT_SIZE*DEC); + f0_start = candidate_f0-20; + f0_end = candidate_f0+20; + if (f0_start < f0_min) f0_start = f0_min; + if (f0_end > f0_max) f0_end = f0_max; + + for(f0=f0_start; f0<=f0_end; f0+= 2.5) { + e = test_candidate_mbe(Sw, W, f0); + #if !defined(NDEBUG) || defined(DUMP) + bin = floor(f0); assert((bin > 0) && (bin < F0_MAX)); + #endif + #ifdef DUMP + e_hz[bin] = e; + #endif + if (e < e_min) { + e_min = e; + best_f0 = f0; + } + } + + } + } + } + + /* finally sample MBE cost function around previous pitch estimate + (form of pitch tracking) */ + + candidate_f0 = *prev_Wo * SAMPLE_RATE/TWO_PI; + f0_start = candidate_f0-20; + f0_end = candidate_f0+20; + if (f0_start < f0_min) f0_start = f0_min; + if (f0_end > f0_max) f0_end = f0_max; + + for(f0=f0_start; f0<=f0_end; f0+= 2.5) { + e = test_candidate_mbe(Sw, W, f0); + #if !defined(NDEBUG) || defined(DUMP) + bin = floor(f0); assert((bin > 0) && (bin < F0_MAX)); + #endif + #ifdef DUMP + e_hz[bin] = e; + #endif + if (e < e_min) { + e_min = e; + best_f0 = f0; + } + } + + #ifdef DUMP + dump_e(e_hz); + #endif + + return best_f0; +} + +/*---------------------------------------------------------------------------*\ + + test_candidate_mbe() + + Returns the error of the MBE cost function for the input f0. + + Note: I think a lot of the operations below can be simplified as + W[].imag = 0 and has been normalised such that den always equals 1. + +\*---------------------------------------------------------------------------*/ + +float test_candidate_mbe( + COMP Sw[], + COMP W[], + float f0 +) +{ + COMP Sw_[FFT_ENC]; /* DFT of all voiced synthesised signal */ + int l,al,bl,m; /* loop variables */ + COMP Am; /* amplitude sample for this band */ + int offset; /* centers Hw[] about current harmonic */ + float den; /* denominator of Am expression */ + float error; /* accumulated error between originl and synthesised */ + float Wo; /* current "test" fundamental freq. */ + int L; + + L = floor((SAMPLE_RATE/2.0)/f0); + Wo = f0*(2*PI/SAMPLE_RATE); + + error = 0.0; + + /* Just test across the harmonics in the first 1000 Hz (L/4) */ + + for(l=1; l<L/4; l++) { + Am.real = 0.0; + Am.imag = 0.0; + den = 0.0; + al = ceil((l - 0.5)*Wo*FFT_ENC/TWO_PI); + bl = ceil((l + 0.5)*Wo*FFT_ENC/TWO_PI); + + /* Estimate amplitude of harmonic assuming harmonic is totally voiced */ + + for(m=al; m<bl; m++) { + offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5; + Am.real += Sw[m].real*W[offset].real + Sw[m].imag*W[offset].imag; + Am.imag += Sw[m].imag*W[offset].real - Sw[m].real*W[offset].imag; + den += W[offset].real*W[offset].real + W[offset].imag*W[offset].imag; + } + + Am.real = Am.real/den; + Am.imag = Am.imag/den; + + /* Determine error between estimated harmonic and original */ + + for(m=al; m<bl; m++) { + offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5; + Sw_[m].real = Am.real*W[offset].real - Am.imag*W[offset].imag; + Sw_[m].imag = Am.real*W[offset].imag + Am.imag*W[offset].real; + error += (Sw[m].real - Sw_[m].real)*(Sw[m].real - Sw_[m].real); + error += (Sw[m].imag - Sw_[m].imag)*(Sw[m].imag - Sw_[m].imag); + } + } + + return error; +} + diff --git a/gr-vocoder/lib/codec2/nlp.h b/gr-vocoder/lib/codec2/nlp.h index 5e11f1186e..6e03236c00 100644 --- a/gr-vocoder/lib/codec2/nlp.h +++ b/gr-vocoder/lib/codec2/nlp.h @@ -30,10 +30,9 @@ #include "comp.h" -void *nlp_create(); +void *nlp_create(int m); void nlp_destroy(void *nlp_state); -float nlp(void *nlp_state, float Sn[], int n, int m, int pmin, int pmax, - float *pitch, COMP Sw[], float *prev_Wo); -float test_candidate_mbe(COMP Sw[], float f0, COMP Sw_[]); +float nlp(void *nlp_state, float Sn[], int n, int pmin, int pmax, + float *pitch, COMP Sw[], COMP W[], float *prev_Wo); #endif diff --git a/gr-vocoder/lib/codec2/os.h b/gr-vocoder/lib/codec2/os.h new file mode 100644 index 0000000000..0dae9bfd24 --- /dev/null +++ b/gr-vocoder/lib/codec2/os.h @@ -0,0 +1,53 @@ +/* Generate using fir1(47,1/6) in Octave */ + +const float fdmdv_os_filter[]= { + -3.55606818e-04, + -8.98615286e-04, + -1.40119781e-03, + -1.71713852e-03, + -1.56471179e-03, + -6.28128960e-04, + 1.24522223e-03, + 3.83138676e-03, + 6.41309478e-03, + 7.85893186e-03, + 6.93514929e-03, + 2.79361991e-03, + -4.51051400e-03, + -1.36671853e-02, + -2.21034939e-02, + -2.64084653e-02, + -2.31425052e-02, + -9.84218694e-03, + 1.40648474e-02, + 4.67316298e-02, + 8.39615986e-02, + 1.19925275e-01, + 1.48381174e-01, + 1.64097819e-01, + 1.64097819e-01, + 1.48381174e-01, + 1.19925275e-01, + 8.39615986e-02, + 4.67316298e-02, + 1.40648474e-02, + -9.84218694e-03, + -2.31425052e-02, + -2.64084653e-02, + -2.21034939e-02, + -1.36671853e-02, + -4.51051400e-03, + 2.79361991e-03, + 6.93514929e-03, + 7.85893186e-03, + 6.41309478e-03, + 3.83138676e-03, + 1.24522223e-03, + -6.28128960e-04, + -1.56471179e-03, + -1.71713852e-03, + -1.40119781e-03, + -8.98615286e-04, + -3.55606818e-04 +}; + diff --git a/gr-vocoder/lib/codec2/pack.c b/gr-vocoder/lib/codec2/pack.c index e04c9378cf..3f8f93e422 100644 --- a/gr-vocoder/lib/codec2/pack.c +++ b/gr-vocoder/lib/codec2/pack.c @@ -1,20 +1,20 @@ /* Copyright (C) 2010 Perens LLC <bruce@perens.com> - This program 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 of the License, or - (at your option) any later version. + All rights reserved. - This program 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. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ - */ #include "defines.h" #include "quantise.h" #include <stdio.h> diff --git a/gr-vocoder/lib/codec2/phase.c b/gr-vocoder/lib/codec2/phase.c index 69cc6697fc..a9c1c06b9a 100644 --- a/gr-vocoder/lib/codec2/phase.c +++ b/gr-vocoder/lib/codec2/phase.c @@ -27,17 +27,16 @@ #include "defines.h" #include "phase.h" -#include "fft.h" +#include "kiss_fft.h" #include "comp.h" -#include "glottal.c" +#include "sine.h" #include <assert.h> +#include <ctype.h> #include <math.h> #include <string.h> #include <stdlib.h> -#define GLOTTAL_FFT_SIZE 512 - /*---------------------------------------------------------------------------*\ aks_to_H() @@ -48,6 +47,7 @@ \*---------------------------------------------------------------------------*/ void aks_to_H( + kiss_fft_cfg fft_fwd_cfg, MODEL *model, /* model parameters */ float aks[], /* LPC's */ float G, /* energy term */ @@ -55,7 +55,8 @@ void aks_to_H( int order ) { - COMP Pw[FFT_DEC]; /* power spectrum */ + COMP pw[FFT_ENC]; /* power spectrum (input) */ + COMP Pw[FFT_ENC]; /* power spectrum (output) */ int i,m; /* loop variables */ int am,bm; /* limits of current band */ float r; /* no. rads/bin */ @@ -64,35 +65,35 @@ void aks_to_H( int b; /* centre bin of harmonic */ float phi_; /* phase of LPC spectra */ - r = TWO_PI/(FFT_DEC); + r = TWO_PI/(FFT_ENC); /* Determine DFT of A(exp(jw)) ------------------------------------------*/ - for(i=0; i<FFT_DEC; i++) { - Pw[i].real = 0.0; - Pw[i].imag = 0.0; + for(i=0; i<FFT_ENC; i++) { + pw[i].real = 0.0; + pw[i].imag = 0.0; } for(i=0; i<=order; i++) - Pw[i].real = aks[i]; + pw[i].real = aks[i]; - fft(&Pw[0].real,FFT_DEC,-1); + kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)pw, (kiss_fft_cpx *)Pw); /* Sample magnitude and phase at harmonics */ for(m=1; m<=model->L; m++) { - am = floor((m - 0.5)*model->Wo/r + 0.5); - bm = floor((m + 0.5)*model->Wo/r + 0.5); - b = floor(m*model->Wo/r + 0.5); - - Em = 0.0; - for(i=am; i<bm; i++) - Em += G/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag); - Am = sqrt(fabs(Em/(bm-am))); - - phi_ = -atan2(Pw[b].imag,Pw[b].real); - H[m].real = Am*cos(phi_); - H[m].imag = Am*sin(phi_); + am = (int)((m - 0.5)*model->Wo/r + 0.5); + bm = (int)((m + 0.5)*model->Wo/r + 0.5); + b = (int)(m*model->Wo/r + 0.5); + + Em = 0.0; + for(i=am; i<bm; i++) + Em += G/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag); + Am = sqrtf(fabsf(Em/(bm-am))); + + phi_ = -atan2f(Pw[b].imag,Pw[b].real); + H[m].real = Am*cosf(phi_); + H[m].imag = Am*sinf(phi_); } } @@ -188,6 +189,7 @@ void aks_to_H( \*---------------------------------------------------------------------------*/ void phase_synth_zero_order( + kiss_fft_cfg fft_fwd_cfg, MODEL *model, float aks[], float *ex_phase, /* excitation phase of fundamental */ @@ -196,16 +198,13 @@ void phase_synth_zero_order( { int m; float new_phi; - COMP Ex[MAX_AMP]; /* excitation samples */ - COMP A_[MAX_AMP]; /* synthesised harmonic samples */ - COMP H[MAX_AMP]; /* LPC freq domain samples */ + COMP Ex[MAX_AMP+1]; /* excitation samples */ + COMP A_[MAX_AMP+1]; /* synthesised harmonic samples */ + COMP H[MAX_AMP+1]; /* LPC freq domain samples */ float G; - float jitter = 0.0; - float r; - int b; G = 1.0; - aks_to_H(model, aks, G, H, order); + aks_to_H(fft_fwd_cfg, model, aks, G, H, order); /* Update excitation fundamental phase track, this sets the position @@ -213,50 +212,42 @@ void phase_synth_zero_order( I found that using just this frame's Wo improved quality for UV sounds compared to interpolating two frames Wo like this: - ex_phase[0] += (*prev_Wo+mode->Wo)*N/2; + ex_phase[0] += (*prev_Wo+model->Wo)*N/2; */ ex_phase[0] += (model->Wo)*N; - ex_phase[0] -= TWO_PI*floor(ex_phase[0]/TWO_PI + 0.5); - r = TWO_PI/GLOTTAL_FFT_SIZE; + ex_phase[0] -= TWO_PI*floorf(ex_phase[0]/TWO_PI + 0.5); for(m=1; m<=model->L; m++) { - /* generate excitation */ + /* generate excitation */ if (model->voiced) { - /* I think adding a little jitter helps improve low pitch - males like hts1a. This moves the onset of each harmonic - over at +/- 0.25 of a sample. - */ - jitter = 0.25*(1.0 - 2.0*rand()/RAND_MAX); - b = floor(m*model->Wo/r + 0.5); - if (b > ((GLOTTAL_FFT_SIZE/2)-1)) { - b = (GLOTTAL_FFT_SIZE/2)-1; - } - Ex[m].real = cos(ex_phase[0]*m - jitter*model->Wo*m + glottal[b]); - Ex[m].imag = sin(ex_phase[0]*m - jitter*model->Wo*m + glottal[b]); - } - else { - - /* When a few samples were tested I found that LPC filter - phase is not needed in the unvoiced case, but no harm in - keeping it. - */ - float phi = TWO_PI*(float)rand()/RAND_MAX; - Ex[m].real = cos(phi); - Ex[m].imag = sin(phi); - } - - /* filter using LPC filter */ - - A_[m].real = H[m].real*Ex[m].real - H[m].imag*Ex[m].imag; - A_[m].imag = H[m].imag*Ex[m].real + H[m].real*Ex[m].imag; - - /* modify sinusoidal phase */ - - new_phi = atan2(A_[m].imag, A_[m].real+1E-12); - model->phi[m] = new_phi; + + Ex[m].real = cosf(ex_phase[0]*m); + Ex[m].imag = sinf(ex_phase[0]*m); + } + else { + + /* When a few samples were tested I found that LPC filter + phase is not needed in the unvoiced case, but no harm in + keeping it. + */ + float phi = TWO_PI*(float)codec2_rand()/CODEC2_RAND_MAX; + Ex[m].real = cosf(phi); + Ex[m].imag = sinf(phi); + } + + /* filter using LPC filter */ + + A_[m].real = H[m].real*Ex[m].real - H[m].imag*Ex[m].imag; + A_[m].imag = H[m].imag*Ex[m].real + H[m].real*Ex[m].imag; + + /* modify sinusoidal phase */ + + new_phi = atan2f(A_[m].imag, A_[m].real+1E-12); + model->phi[m] = new_phi; } } + diff --git a/gr-vocoder/lib/codec2/phase.h b/gr-vocoder/lib/codec2/phase.h index 4f1a620899..2927e912d4 100644 --- a/gr-vocoder/lib/codec2/phase.h +++ b/gr-vocoder/lib/codec2/phase.h @@ -28,7 +28,12 @@ #ifndef __PHASE__ #define __PHASE__ -void phase_synth_zero_order(MODEL *model, float aks[], float *ex_phase, +#include "kiss_fft.h" + +void phase_synth_zero_order(kiss_fft_cfg fft_dec_cfg, + MODEL *model, + float aks[], + float *ex_phase, int order); #endif diff --git a/gr-vocoder/lib/codec2/phaseexp.c b/gr-vocoder/lib/codec2/phaseexp.c new file mode 100644 index 0000000000..61b240df49 --- /dev/null +++ b/gr-vocoder/lib/codec2/phaseexp.c @@ -0,0 +1,1455 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: phaseexp.c + AUTHOR......: David Rowe + DATE CREATED: June 2012 + + Experimental functions for quantising, modelling and synthesising phase. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2012 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not,see <http://www.gnu.org/licenses/>. +*/ + +#include "defines.h" +#include "phase.h" +#include "kiss_fft.h" +#include "comp.h" + +#include <assert.h> +#include <ctype.h> +#include <math.h> +#include <string.h> +#include <stdlib.h> + +/* Bruce Perens' funcs to load codebook files */ + +struct codebook { + unsigned int k; + unsigned int log2m; + unsigned int m; + COMP *cb; + unsigned int offset; +}; + +static const char format[] = +"The table format must be:\n" +"\tTwo integers describing the dimensions of the codebook.\n" +"\tThen, enough numbers to fill the specified dimensions.\n"; + +float get_float(FILE * in, const char * name, char * * cursor, char * buffer, int size) +{ + for ( ; ; ) { + char * s = *cursor; + char c; + + while ( (c = *s) != '\0' && !isdigit(c) && c != '-' && c != '.' ) + s++; + + /* Comments start with "#" and continue to the end of the line. */ + if ( c != '\0' && c != '#' ) { + char * end = 0; + float f = 0; + + f = strtod(s, &end); + + if ( end != s ) + *cursor = end; + return f; + } + + if ( fgets(buffer, size, in) == NULL ) { + fprintf(stderr, "%s: Format error. %s\n", name, format); + exit(1); + } + *cursor = buffer; + } +} + +static struct codebook *load(const char * name) +{ + FILE *file; + char line[2048]; + char *cursor = line; + struct codebook *b = malloc(sizeof(struct codebook)); + int i; + int size; + float angle; + + file = fopen(name, "rt"); + assert(file != NULL); + + *cursor = '\0'; + + b->k = (int)get_float(file, name, &cursor, line, sizeof(line)); + b->m = (int)get_float(file, name ,&cursor, line, sizeof(line)); + size = b->k * b->m; + + b->cb = (COMP *)malloc(size * sizeof(COMP)); + + for ( i = 0; i < size; i++ ) { + angle = get_float(file, name, &cursor, line, sizeof(line)); + b->cb[i].real = cos(angle); + b->cb[i].imag = sin(angle); + } + + fclose(file); + + return b; +} + + +/* states for phase experiments */ + +struct PEXP { + float phi1; + float phi_prev[MAX_AMP]; + float Wo_prev; + int frames; + float snr; + float var; + int var_n; + struct codebook *vq1,*vq2,*vq3,*vq4,*vq5; + float vq_var; + int vq_var_n; + MODEL prev_model; + int state; +}; + + +/*---------------------------------------------------------------------------* \ + + phase_experiment_create() + + Inits states for phase quantisation experiments. + +\*---------------------------------------------------------------------------*/ + +struct PEXP * phase_experiment_create() { + struct PEXP *pexp; + int i; + + pexp = (struct PEXP *)malloc(sizeof(struct PEXP)); + assert (pexp != NULL); + + pexp->phi1 = 0; + for(i=0; i<MAX_AMP; i++) + pexp->phi_prev[i] = 0.0; + pexp->Wo_prev = 0.0; + pexp->frames = 0; + pexp->snr = 0.0; + pexp->var = 0.0; + pexp->var_n = 0; + + /* smoothed 10th order for 1st 1 khz */ + //pexp->vq1 = load("../unittest/ph1_10_1024.txt"); + //pexp->vq1->offset = 0; + + /* load experimental phase VQ */ + + //pexp->vq1 = load("../unittest/testn1_20_1024.txt"); + pexp->vq1 = load("../unittest/test.txt"); + //pexp->vq2 = load("../unittest/testn21_40_1024.txt"); + pexp->vq2 = load("../unittest/test11_20_1024.txt"); + pexp->vq3 = load("../unittest/test21_30_1024.txt"); + pexp->vq4 = load("../unittest/test31_40_1024.txt"); + pexp->vq5 = load("../unittest/test41_60_1024.txt"); + pexp->vq1->offset = 0; + pexp->vq2->offset = 10; + pexp->vq3->offset = 20; + pexp->vq4->offset = 30; + pexp->vq5->offset = 40; + + pexp->vq_var = 0.0; + pexp->vq_var_n = 0; + + pexp->state = 0; + + return pexp; +} + + +/*---------------------------------------------------------------------------* \ + + phase_experiment_destroy() + +\*---------------------------------------------------------------------------*/ + +void phase_experiment_destroy(struct PEXP *pexp) { + assert(pexp != NULL); + if (pexp->snr != 0.0) + printf("snr: %4.2f dB\n", pexp->snr/pexp->frames); + if (pexp->var != 0.0) + printf("var...: %4.3f std dev...: %4.3f (%d non zero phases)\n", + pexp->var/pexp->var_n, sqrt(pexp->var/pexp->var_n), pexp->var_n); + if (pexp->vq_var != 0.0) + printf("vq var: %4.3f vq std dev: %4.3f (%d non zero phases)\n", + pexp->vq_var/pexp->vq_var_n, sqrt(pexp->vq_var/pexp->vq_var_n), pexp->vq_var_n); + free(pexp); +} + + +/*---------------------------------------------------------------------------* \ + + Various test and experimental functions ................ + +\*---------------------------------------------------------------------------*/ + +/* Bubblesort to find highest amplitude harmonics */ + +struct AMPINDEX { + float amp; + int index; +}; + +static void bubbleSort(struct AMPINDEX numbers[], int array_size) +{ + int i, j; + struct AMPINDEX temp; + + for (i = (array_size - 1); i > 0; i--) + { + for (j = 1; j <= i; j++) + { + //printf("i %d j %d %f %f \n", i, j, numbers[j-1].amp, numbers[j].amp); + if (numbers[j-1].amp < numbers[j].amp) + { + temp = numbers[j-1]; + numbers[j-1] = numbers[j]; + numbers[j] = temp; + } + } + } +} + + +static void print_pred_error(struct PEXP *pexp, MODEL *model, int start, int end, float mag_thresh) { + int i; + float mag; + + mag = 0.0; + for(i=start; i<=end; i++) + mag += model->A[i]*model->A[i]; + mag = 10*log10(mag/(end-start)); + + if (mag > mag_thresh) { + for(i=start; i<=end; i++) { + float pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0; + float err = pred - model->phi[i]; + err = atan2(sin(err),cos(err)); + printf("%f\n",err); + } + //printf("\n"); + } + +} + + +static void predict_phases(struct PEXP *pexp, MODEL *model, int start, int end) { + int i; + + for(i=start; i<=end; i++) { + model->phi[i] = pexp->phi_prev[i] + N*i*model->Wo; + } + +} +static float refine_Wo(struct PEXP *pexp, + MODEL *model, + int start, + int end); + +/* Fancy state based phase prediction. Actually works OK on most utterances, + but could use some tuning. Breaks down a bit on mmt1. */ + +static void predict_phases_state(struct PEXP *pexp, MODEL *model, int start, int end) { + int i, next_state; + float best_Wo, dWo; + + //best_Wo = refine_Wo(pexp, model, start, end); + //best_Wo = (model->Wo + pexp->Wo_prev)/2.0; + best_Wo = model->Wo; + + dWo = fabs(model->Wo - pexp->Wo_prev)/model->Wo; + next_state = pexp->state; + switch(pexp->state) { + case 0: + if (dWo < 0.1) { + /* UV -> V transition, so start with phases in lock. They will + drift a bit over voiced track which is kinda what we want, so + we don't get clicky speech. + */ + next_state = 1; + for(i=start; i<=end; i++) + pexp->phi_prev[i] = i*pexp->phi1; + } + + break; + case 1: + if (dWo > 0.1) + next_state = 0; + break; + } + pexp->state = next_state; + + if (pexp->state == 0) + for(i=start; i<=end; i++) { + model->phi[i] = PI*(1.0 - 2.0*rand()/RAND_MAX); + } + else + for(i=start; i<=end; i++) { + model->phi[i] = pexp->phi_prev[i] + N*i*best_Wo; + } + printf("state %d\n", pexp->state); +} + +static void struct_phases(struct PEXP *pexp, MODEL *model, int start, int end) { + int i; + + for(i=start; i<=end; i++) + model->phi[i] = pexp->phi1*i; + +} + + +static void predict_phases2(struct PEXP *pexp, MODEL *model, int start, int end) { + int i; + float pred, str, diff; + + for(i=start; i<=end; i++) { + pred = pexp->phi_prev[i] + N*i*model->Wo; + str = pexp->phi1*i; + diff = str - pred; + diff = atan2(sin(diff), cos(diff)); + if (diff > 0) + pred += PI/16; + else + pred -= PI/16; + model->phi[i] = pred; + } + +} + +static void rand_phases(MODEL *model, int start, int end) { + int i; + + for(i=start; i<=end; i++) + model->phi[i] = PI*(1.0 - 2.0*(float)rand()/RAND_MAX); + +} + +static void quant_phase(float *phase, float min, float max, int bits) { + int levels = 1 << bits; + int index; + float norm, step; + + norm = (*phase - min)/(max - min); + index = floor(levels*norm); + + //printf("phase %f norm %f index %d ", *phase, norm, index); + if (index < 0 ) index = 0; + if (index > (levels-1)) index = levels-1; + //printf("index %d ", index); + step = (max - min)/levels; + *phase = min + step*index + 0.5*step; + //printf("step %f phase %f\n", step, *phase); +} + +static void quant_phases(MODEL *model, int start, int end, int bits) { + int i; + + for(i=start; i<=end; i++) { + quant_phase(&model->phi[i], -PI, PI, bits); + } +} + +static void fixed_bits_per_frame(struct PEXP *pexp, MODEL *model, int m, int budget) { + int res, finished; + + res = 3; + finished = 0; + + while(!finished) { + if (m > model->L/2) + res = 2; + if (((budget - res) < 0) || (m > model->L)) + finished = 1; + else { + quant_phase(&model->phi[m], -PI, PI, res); + budget -= res; + m++; + } + } + printf("m: %d L: %d budget: %d\n", m, model->L, budget); + predict_phases(pexp, model, m, model->L); + //rand_phases(model, m, model->L); +} + +/* used to plot histogram of quantisation error, for 3 bits, 8 levels, + should be uniform between +/- PI/8 */ + +static void check_phase_quant(MODEL *model, float tol) +{ + int m; + float phi_before[MAX_AMP]; + + for(m=1; m<=model->L; m++) + phi_before[m] = model->phi[m]; + + quant_phases(model, 1, model->L, 3); + + for(m=1; m<=model->L; m++) { + float err = phi_before[m] - model->phi[m]; + printf("%f\n", err); + if (fabs(err) > tol) + exit(0); + } +} + + +static float est_phi1(MODEL *model, int start, int end) +{ + int m; + float delta, s, c, phi1_est; + + if (end > model->L) + end = model->L; + + s = c = 0.0; + for(m=start; m<end; m++) { + delta = model->phi[m+1] - model->phi[m]; + s += sin(delta); + c += cos(delta); + } + + phi1_est = atan2(s,c); + + return phi1_est; +} + +static void print_phi1_pred_error(MODEL *model, int start, int end) +{ + int m; + float phi1_est; + + phi1_est = est_phi1(model, start, end); + + for(m=start; m<end; m++) { + float err = model->phi[m+1] - model->phi[m] - phi1_est; + err = atan2(sin(err),cos(err)); + printf("%f\n", err); + } +} + + +static void first_order_band(MODEL *model, int start, int end, float phi1_est) +{ + int m; + float pred_err, av_pred_err; + float c,s; + + s = c = 0.0; + for(m=start; m<end; m++) { + pred_err = model->phi[m] - phi1_est*m; + s += sin(pred_err); + c += cos(pred_err); + } + + av_pred_err = atan2(s,c); + for(m=start; m<end; m++) { + model->phi[m] = av_pred_err + phi1_est*m; + model->phi[m] = atan2(sin(model->phi[m]), cos(model->phi[m])); + } + +} + + +static void sub_linear(MODEL *model, int start, int end, float phi1_est) +{ + int m; + + for(m=start; m<end; m++) { + model->phi[m] = m*phi1_est; + } +} + + +static void top_amp(struct PEXP *pexp, MODEL *model, int start, int end, int n_harm, int pred) +{ + int removed = 0, not_removed = 0; + int top, i, j; + struct AMPINDEX sorted[MAX_AMP]; + + /* sort into ascending order of amplitude */ + + printf("\n"); + for(i=start,j=0; i<end; i++,j++) { + sorted[j].amp = model->A[i]; + sorted[j].index = i; + printf("%f ", model->A[i]); + } + bubbleSort(sorted, end-start); + + printf("\n"); + for(j=0; j<n_harm; j++) + printf("%d %f\n", j, sorted[j].amp); + + /* keep phase of top n_harm, predict others */ + + for(i=start; i<end; i++) { + top = 0; + for(j=0; j<n_harm; j++) { + if (model->A[i] == sorted[j].amp) { + top = 1; + assert(i == sorted[j].index); + } + } + + #define ALTTOP + #ifdef ALTTOP + model->phi[i] = 0.0; /* make sure */ + if (top) { + model->phi[i] = i*pexp->phi1; + removed++; + } + else { + model->phi[i] = PI*(1.0 - 2.0*(float)rand()/RAND_MAX); // note: try rand for higher harms + removed++; + } + #else + if (!top) { + model->phi[i] = 0.0; /* make sure */ + if (pred) { + //model->phi[i] = pexp->phi_prev[i] + i*N*(model->Wo + pexp->Wo_prev)/2.0; + model->phi[i] = i*model->phi[1]; + } + else + model->phi[i] = PI*(1.0 - 2.0*(float)rand()/RAND_MAX); // note: try rand for higher harms + removed++; + } + else { + /* need to make this work thru budget of bits */ + quant_phase(&model->phi[i], -PI, PI, 3); + not_removed++; + } + #endif + } + printf("dim: %d rem %d not_rem %d\n", end-start, removed, not_removed); + +} + + +static void limit_prediction_error(struct PEXP *pexp, MODEL *model, int start, int end, float limit) +{ + int i; + float pred, pred_error, error; + + for(i=start; i<=end; i++) { + pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0; + pred_error = pred - model->phi[i]; + pred_error -= TWO_PI*floor((pred_error+PI)/TWO_PI); + quant_phase(&pred_error, -limit, limit, 2); + + error = pred - pred_error - model->phi[i]; + error -= TWO_PI*floor((error+PI)/TWO_PI); + printf("%f\n", pred_error); + model->phi[i] = pred - pred_error; + } +} + + +static void quant_prediction_error(struct PEXP *pexp, MODEL *model, int start, int end, float limit) +{ + int i; + float pred, pred_error; + + for(i=start; i<=end; i++) { + pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0; + pred_error = pred - model->phi[i]; + pred_error -= TWO_PI*floor((pred_error+PI)/TWO_PI); + + printf("%f\n", pred_error); + model->phi[i] = pred - pred_error; + } +} + + +static void print_sparse_pred_error(struct PEXP *pexp, MODEL *model, int start, int end, float mag_thresh) +{ + int i, index; + float mag, pred, error; + float sparse_pe[MAX_AMP]; + + mag = 0.0; + for(i=start; i<=end; i++) + mag += model->A[i]*model->A[i]; + mag = 10*log10(mag/(end-start)); + + if (mag > mag_thresh) { + for(i=0; i<MAX_AMP; i++) { + sparse_pe[i] = 0.0; + } + + for(i=start; i<=end; i++) { + pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0; + error = pred - model->phi[i]; + error = atan2(sin(error),cos(error)); + + index = MAX_AMP*i*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe[index] = error; + } + + /* dump spare phase vector in polar format */ + + for(i=0; i<MAX_AMP; i++) + printf("%f ", sparse_pe[i]); + printf("\n"); + } +} + + +static void update_snr_calc(struct PEXP *pexp, MODEL *model, float before[]) +{ + int m; + float signal, noise, diff; + + signal = 0.0; noise = 0.0; + for(m=1; m<=model->L; m++) { + signal += model->A[m]*model->A[m]; + diff = cos(model->phi[m]) - cos(before[m]); + noise += pow(model->A[m]*diff, 2.0); + diff = sin(model->phi[m]) - sin(before[m]); + noise += pow(model->A[m]*diff, 2.0); + //printf("%f %f\n", before[m], model->phi[m]); + } + //printf("%f %f snr = %f\n", signal, noise, 10.0*log10(signal/noise)); + pexp->snr += 10.0*log10(signal/noise); +} + + +static void update_variance_calc(struct PEXP *pexp, MODEL *model, float before[]) +{ + int m; + float diff; + + for(m=1; m<model->L; m++) { + diff = model->phi[m] - before[m]; + diff = atan2(sin(diff), cos(diff)); + pexp->var += diff*diff; + } + pexp->var_n += model->L; +} + +void print_vec(COMP cb[], int d, int e) +{ + int i,j; + + for(j=0; j<e; j++) { + for(i=0; i<d; i++) + printf("%f %f ", cb[j*d+i].real, cb[j*d+i].imag); + printf("\n"); + } +} + +static COMP cconj(COMP a) +{ + COMP res; + + res.real = a.real; + res.imag = -a.imag; + + return res; +} + +static COMP cadd(COMP a, COMP b) +{ + COMP res; + + res.real = a.real + b.real; + res.imag = a.imag + b.imag; + + return res; +} + +static COMP cmult(COMP a, COMP b) +{ + COMP res; + + res.real = a.real*b.real - a.imag*b.imag; + res.imag = a.real*b.imag + a.imag*b.real; + + return res; +} + +static int vq_phase(COMP cb[], COMP vec[], float weights[], int d, int e, float *se) +{ + float error; /* current error */ + int besti; /* best index so far */ + float best_error; /* best error so far */ + int i,j; + int ignore; + COMP diffr; + float diffp, metric, best_metric; + + besti = 0; + best_metric = best_error = 1E32; + for(j=0; j<e; j++) { + error = 0.0; + metric = 0.0; + for(i=0; i<d; i++) { + ignore = (vec[i].real == 0.0) && (vec[i].imag == 0.0); + if (!ignore) { + diffr = cmult(cb[j*d+i], cconj(vec[i])); + diffp = atan2(diffr.imag, diffr.real); + error += diffp*diffp; + metric += weights[i]*weights[i]*diffp*diffp; + //metric += weights[i]*diffp*diffp; + //metric = log10(weights[i]*fabs(diffp)); + //printf("diffp %f metric %f\n", diffp, metric); + //if (metric < log10(PI/(8.0*sqrt(3.0)))) + // metric = log10(PI/(8.0*sqrt(3.0))); + } + } + if (metric < best_metric) { + best_metric = metric; + best_error = error; + besti = j; + } + } + + *se += best_error; + + return(besti); +} + + +static float refine_Wo(struct PEXP *pexp, + MODEL *model, + int start, + int end) + +{ + int i; + float Wo_est, best_var, Wo, var, pred, error, best_Wo; + + /* test variance over a range of Wo values */ + + Wo_est = (model->Wo + pexp->Wo_prev)/2.0; + best_var = 1E32; + for(Wo=0.97*Wo_est; Wo<=1.03*Wo_est; Wo+=0.001*Wo_est) { + + /* predict phase and sum differences between harmonics */ + + var = 0.0; + for(i=start; i<=end; i++) { + pred = pexp->phi_prev[i] + N*i*Wo; + error = pred - model->phi[i]; + error = atan2(sin(error),cos(error)); + var += error*error; + } + + if (var < best_var) { + best_var = var; + best_Wo = Wo; + } + } + + return best_Wo; +} + + +static void split_vq(COMP sparse_pe_out[], struct PEXP *pexp, struct codebook *vq, float weights[], COMP sparse_pe_in[]) +{ + int i, j, non_zero, vq_ind; + + //printf("\n offset %d k %d m %d j: ", vq->offset, vq->k, vq->m); + vq_ind = vq_phase(vq->cb, &sparse_pe_in[vq->offset], &weights[vq->offset], vq->k, vq->m, &pexp->vq_var); + + non_zero = 0; + for(i=0, j=vq->offset; i<vq->k; i++,j++) { + //printf("%f ", atan2(sparse_pe[i].imag, sparse_pe[i].real)); + if ((sparse_pe_in[j].real != 0.0) && (sparse_pe_in[j].imag != 0.0)) { + //printf("%d ", j); + sparse_pe_out[j] = vq->cb[vq->k * vq_ind + i]; + non_zero++; + } + } + pexp->vq_var_n += non_zero; +} + + +static void sparse_vq_pred_error(struct PEXP *pexp, + MODEL *model +) +{ + int i, index; + float pred, error, error_q_angle, best_Wo; + COMP sparse_pe_in[MAX_AMP], sparse_pe_out[MAX_AMP]; + float weights[MAX_AMP]; + COMP error_q_rect; + + best_Wo = refine_Wo(pexp, model, 1, model->L); + //best_Wo = (model->Wo + pexp->Wo_prev)/2.0; + + /* transform to sparse pred error vector */ + + for(i=0; i<MAX_AMP; i++) { + sparse_pe_in[i].real = 0.0; + sparse_pe_in[i].imag = 0.0; + sparse_pe_out[i].real = 0.0; + sparse_pe_out[i].imag = 0.0; + } + + //printf("\n"); + for(i=1; i<=model->L; i++) { + pred = pexp->phi_prev[i] + N*i*best_Wo; + error = pred - model->phi[i]; + + index = MAX_AMP*i*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe_in[index].real = cos(error); + sparse_pe_in[index].imag = sin(error); + sparse_pe_out[index] = sparse_pe_in[index]; + weights[index] = model->A[i]; + //printf("%d ", index); + } + + /* vector quantise */ + + split_vq(sparse_pe_out, pexp, pexp->vq1, weights, sparse_pe_in); + split_vq(sparse_pe_out, pexp, pexp->vq2, weights, sparse_pe_in); + split_vq(sparse_pe_out, pexp, pexp->vq3, weights, sparse_pe_in); + split_vq(sparse_pe_out, pexp, pexp->vq4, weights, sparse_pe_in); + split_vq(sparse_pe_out, pexp, pexp->vq5, weights, sparse_pe_in); + + /* transform quantised phases back */ + + for(i=1; i<=model->L; i++) { + pred = pexp->phi_prev[i] + N*i*best_Wo; + + index = MAX_AMP*i*model->Wo/PI; + assert(index < MAX_AMP); + error_q_rect = sparse_pe_out[index]; + error_q_angle = atan2(error_q_rect.imag, error_q_rect.real); + model->phi[i] = pred - error_q_angle; + model->phi[i] = atan2(sin(model->phi[i]), cos(model->phi[i])); + } +} + + +static void predict_phases1(struct PEXP *pexp, MODEL *model, int start, int end) { + int i; + float best_Wo; + + best_Wo = refine_Wo(pexp, model, 1, model->L); + + for(i=start; i<=end; i++) { + model->phi[i] = pexp->phi_prev[i] + N*i*best_Wo; + } +} + + +/* + This functions tests theory that some bands can be combined together + due to less frequency resolution at higher frequencies. This will + reduce the amount of information we need to encode. +*/ + +void smooth_phase(struct PEXP *pexp, MODEL *model, int mode) +{ + int m, i, j, index, step, v, en, nav, st; + COMP sparse_pe_in[MAX_AMP], av; + COMP sparse_pe_out[MAX_AMP]; + COMP smoothed[MAX_AMP]; + float best_Wo, pred, err; + float weights[MAX_AMP]; + float avw, smoothed_weights[MAX_AMP]; + COMP smoothed_in[MAX_AMP], smoothed_out[MAX_AMP]; + + best_Wo = refine_Wo(pexp, model, 1, model->L); + + for(m=0; m<MAX_AMP; m++) { + sparse_pe_in[m].real = sparse_pe_in[m].imag = 0.0; + sparse_pe_out[m].real = sparse_pe_out[m].imag = 0.0; + } + + /* set up sparse array */ + + for(m=1; m<=model->L; m++) { + pred = pexp->phi_prev[m] + N*m*best_Wo; + err = model->phi[m] - pred; + err = atan2(sin(err),cos(err)); + + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + sparse_pe_in[index].real = model->A[m]*cos(err); + sparse_pe_in[index].imag = model->A[m]*sin(err); + sparse_pe_out[index] = sparse_pe_in[index]; + weights[index] = model->A[m]; + } + + /* now combine samples at high frequencies to reduce dimension */ + + step = 2; + st = 0; + for(i=st,v=0; i<MAX_AMP; i+=step,v++) { + + /* average over one band */ + + av.real = 0.0; av.imag = 0.0; avw = 0.0; nav = 0; + en = i+step; + if (en > (MAX_AMP-1)) + en = MAX_AMP-1; + for(j=i; j<en; j++) { + if ((sparse_pe_in[j].real != 0.0) &&(sparse_pe_in[j].imag != 0.0) ) { + av = cadd(av, sparse_pe_in[j]); + avw += weights[j]; + nav++; + } + } + if (nav) { + smoothed[v] = av; + smoothed_weights[v] = avw/nav; + } + else + smoothed[v].real = smoothed[v].imag = 0.0; + } + + if (mode == 2) { + for(i=0; i<MAX_AMP; i++) { + smoothed_in[i] = smoothed[i]; + smoothed_out[i] = smoothed_in[i]; + } + split_vq(smoothed_out, pexp, pexp->vq1, smoothed_weights, smoothed_in); + for(i=0; i<MAX_AMP; i++) + smoothed[i] = smoothed_out[i]; + } + + /* set all samples to smoothed average */ + + for(i=st,v=0; i<MAX_AMP; i+=step,v++) { + en = i+step; + if (en > (MAX_AMP-1)) + en = MAX_AMP-1; + for(j=i; j<en; j++) + sparse_pe_out[j] = smoothed[v]; + if (mode == 1) + printf("%f ", atan2(smoothed[v].imag, smoothed[v].real)); + } + if (mode == 1) + printf("\n"); + + /* convert back to Am */ + + for(m=1; m<=model->L; m++) { + index = MAX_AMP*m*model->Wo/PI; + assert(index < MAX_AMP); + pred = pexp->phi_prev[m] + N*m*best_Wo; + err = atan2(sparse_pe_out[index].imag, sparse_pe_out[index].real); + model->phi[m] = pred + err; + } + +} + +/* + Another version of a functions that tests the theory that some bands + can be combined together due to less frequency resolution at higher + frequencies. This will reduce the amount of information we need to + encode. +*/ + +void smooth_phase2(struct PEXP *pexp, MODEL *model) { + float m; + float step; + int a,b,h,i; + float best_Wo, pred, err, s,c, phi1_; + + best_Wo = refine_Wo(pexp, model, 1, model->L); + + step = (float)model->L/30; + printf("\nL: %d step: %3.2f am,bm: ", model->L, step); + for(m=(float)model->L/4; m<=model->L; m+=step) { + a = floor(m); + b = floor(m+step); + if (b > model->L) b = model->L; + h = b-a; + + printf("%d,%d,(%d) ", a, b, h); + c = s = 0.0; + if (h>1) { + for(i=a; i<b; i++) { + pred = pexp->phi_prev[i] + N*i*best_Wo; + err = model->phi[i] - pred; + c += cos(err); s += sin(err); + } + phi1_ = atan2(s,c); + for(i=a; i<b; i++) { + pred = pexp->phi_prev[i] + N*i*best_Wo; + printf("%d: %4.3f -> ", i, model->phi[i]); + model->phi[i] = pred + phi1_; + model->phi[i] = atan2(sin(model->phi[i]),cos(model->phi[i])); + printf("%4.3f ", model->phi[i]); + } + } + } +} + + +#define MAX_BINS 40 +//static float bins[] = {2600.0, 2800.0, 3000.0, 3200.0, 3400.0, 3600.0, 3800.0, 4000.0}; +static float bins[] = {/* + + 1000.0, 1100.0, 1200.0, 1300.0, 1400.0, + 1500.0, 1600.0, 1700.0, 1800.0, 1900.0,*/ + + 2000.0, 2400.0, 2800.0, + 3000.0, 3400.0, 3600.0, 4000.0}; + +void smooth_phase3(struct PEXP *pexp, MODEL *model) { + int m, i; + int nbins; + int b; + float f, best_Wo, pred, err; + COMP av[MAX_BINS]; + + nbins = sizeof(bins)/sizeof(float); + best_Wo = refine_Wo(pexp, model, 1, model->L); + + /* clear all bins */ + + for(i=0; i<MAX_BINS; i++) { + av[i].real = 0.0; + av[i].imag = 0.0; + } + + /* add phases into each bin */ + + for(m=1; m<=model->L; m++) { + f = m*model->Wo*FS/TWO_PI; + if (f > bins[0]) { + + /* find bin */ + + for(i=0; i<nbins; i++) + if ((f > bins[i]) && (f <= bins[i+1])) + b = i; + assert(b < MAX_BINS); + + /* est predicted phase from average */ + + pred = pexp->phi_prev[m] + N*m*best_Wo; + err = model->phi[m] - pred; + av[b].real += cos(err); av[b].imag += sin(err); + } + + } + + /* use averages to est phases */ + + for(m=1; m<=model->L; m++) { + f = m*model->Wo*FS/TWO_PI; + if (f > bins[0]) { + + /* find bin */ + + for(i=0; i<nbins; i++) + if ((f > bins[i]) && (f <= bins[i+1])) + b = i; + assert(b < MAX_BINS); + + /* add predicted phase error to this bin */ + + printf("L %d m %d f %4.f b %d\n", model->L, m, f, b); + + pred = pexp->phi_prev[m] + N*m*best_Wo; + err = atan2(av[b].imag, av[b].real); + printf(" %d: %4.3f -> ", m, model->phi[m]); + model->phi[m] = pred + err; + model->phi[m] = atan2(sin(model->phi[m]),cos(model->phi[m])); + printf("%4.3f\n", model->phi[m]); + } + } + printf("\n"); +} + + +/* + Try to code the phase of the largest amplitude in each band. Randomise the + phase of the other harmonics. The theory is that only the largest harmonic + will be audible. +*/ + +void cb_phase1(struct PEXP *pexp, MODEL *model) { + int m, i; + int nbins; + int b; + float f, best_Wo; + float max_val[MAX_BINS]; + int max_ind[MAX_BINS]; + + nbins = sizeof(bins)/sizeof(float); + best_Wo = refine_Wo(pexp, model, 1, model->L); + + for(i=0; i<nbins; i++) + max_val[i] = 0.0; + + /* determine max amplitude for each bin */ + + for(m=1; m<=model->L; m++) { + f = m*model->Wo*FS/TWO_PI; + if (f > bins[0]) { + + /* find bin */ + + for(i=0; i<nbins; i++) + if ((f > bins[i]) && (f <= bins[i+1])) + b = i; + assert(b < MAX_BINS); + + if (model->A[m] > max_val[b]) { + max_val[b] = model->A[m]; + max_ind[b] = m; + } + } + + } + + /* randomise phase of other harmonics */ + + for(m=1; m<=model->L; m++) { + f = m*model->Wo*FS/TWO_PI; + if (f > bins[0]) { + + /* find bin */ + + for(i=0; i<nbins; i++) + if ((f > bins[i]) && (f <= bins[i+1])) + b = i; + assert(b < MAX_BINS); + + if (m != max_ind[b]) + model->phi[m] = pexp->phi_prev[m] + N*m*best_Wo; + } + } +} + + +/* + Theory is only the phase of the envelope of signal matters within a + Critical Band. So we estimate the position of an impulse that + approximates the envelope of the signal. +*/ + +void cb_phase2(struct PEXP *pexp, MODEL *model) { + int st, m, i, a, b, step; + float diff,w,c,s,phi1_; + float A[MAX_AMP]; + + for(m=1; m<=model->L; m++) { + A[m] = model->A[m]; + model->A[m] = 0; + } + + st = 2*model->L/4; + step = 3; + model->phi[1] = pexp->phi_prev[1] + (pexp->Wo_prev+model->Wo)*N/2.0; + + printf("L=%d ", model->L); + for(m=st; m<st+step*2; m+=step) { + a = m; b=a+step; + if (b > model->L) + b = model->L; + + c = s = 0; + for(i=a; i<b-1; i++) { + printf("diff %d,%d ", i, i+1); + diff = model->phi[i+1] - model->phi[i]; + //w = (model->A[i+1] + model->A[i])/2; + w = 1.0; + c += w*cos(diff); s += w*sin(diff); + } + phi1_ = atan2(s,c); + printf("replacing: "); + for(i=a; i<b; i++) { + //model->phi[i] = i*phi1_; + //model->phi[i] = i*model->phi[1]; + //model->phi[i] = m*(pexp->Wo_prev+model->Wo)*N/2.0; + model->A[m] = A[m]; + printf("%d ", i); + } + printf(" . "); + } + printf("\n"); +} + + +static void smooth_phase4(MODEL *model) { + int m; + float phi_m, phi_m_1; + + if (model->L > 25) { + printf("\nL %d\n", model->L); + for(m=model->L/2; m<=model->L; m+=2) { + if ((m+1) <= model->L) { + phi_m = (model->phi[m] - model->phi[m+1])/2.0; + phi_m_1 = (model->phi[m+1] - model->phi[m])/2.0; + model->phi[m] = phi_m; + model->phi[m+1] = phi_m_1; + printf("%d %4.3f %4.3f ", m, phi_m, phi_m_1); + } + } + } + +} + +/* try repeating last frame, just advance phases to account for time shift */ + +static void repeat_phases(struct PEXP *pexp, MODEL *model) { + int m; + + *model = pexp->prev_model; + for(m=1; m<=model->L; m++) + model->phi[m] += N*m*model->Wo; + +} + +/*---------------------------------------------------------------------------*\ + + phase_experiment() + + Phase quantisation experiments. + +\*---------------------------------------------------------------------------*/ + +void phase_experiment(struct PEXP *pexp, MODEL *model, char *arg) { + int m; + float before[MAX_AMP]; + + assert(pexp != NULL); + memcpy(before, &model->phi[0], sizeof(float)*MAX_AMP); + + if (strcmp(arg,"q3") == 0) { + quant_phases(model, 1, model->L, 3); + update_snr_calc(pexp, model, before); + update_variance_calc(pexp, model, before); + } + + if (strcmp(arg,"dec2") == 0) { + if ((pexp->frames % 2) != 0) { + predict_phases(pexp, model, 1, model->L); + update_snr_calc(pexp, model, before); + update_variance_calc(pexp, model, before); + } + } + + if (strcmp(arg,"repeat") == 0) { + if ((pexp->frames % 2) != 0) { + repeat_phases(pexp, model); + update_snr_calc(pexp, model, before); + update_variance_calc(pexp, model, before); + } + } + + if (strcmp(arg,"vq") == 0) { + sparse_vq_pred_error(pexp, model); + update_snr_calc(pexp, model, before); + update_variance_calc(pexp, model, before); + } + + if (strcmp(arg,"pred") == 0) + predict_phases_state(pexp, model, 1, model->L); + + if (strcmp(arg,"pred1k") == 0) + predict_phases(pexp, model, 1, model->L/4); + + if (strcmp(arg,"smooth") == 0) { + smooth_phase(pexp, model,0); + update_snr_calc(pexp, model, before); + } + if (strcmp(arg,"smoothtrain") == 0) + smooth_phase(pexp, model,1); + if (strcmp(arg,"smoothvq") == 0) { + smooth_phase(pexp, model,2); + update_snr_calc(pexp, model, before); + } + + if (strcmp(arg,"smooth2") == 0) + smooth_phase2(pexp, model); + if (strcmp(arg,"smooth3") == 0) + smooth_phase3(pexp, model); + if (strcmp(arg,"smooth4") == 0) + smooth_phase4(model); + if (strcmp(arg,"vqsmooth3") == 0) { + sparse_vq_pred_error(pexp, model); + smooth_phase3(pexp, model); + } + + if (strcmp(arg,"cb1") == 0) { + cb_phase1(pexp, model); + update_snr_calc(pexp, model, before); + } + + if (strcmp(arg,"top") == 0) { + //top_amp(pexp, model, 1, model->L/4, 4, 1); + //top_amp(pexp, model, model->L/4, model->L/3, 4, 1); + //top_amp(pexp, model, model->L/3+1, model->L/2, 4, 1); + //top_amp(pexp, model, model->L/2, model->L, 6, 1); + //rand_phases(model, model->L/2, 3*model->L/4); + //struct_phases(pexp, model, model->L/2, 3*model->L/4); + //update_snr_calc(pexp, model, before); + } + + if (strcmp(arg,"pred23") == 0) { + predict_phases2(pexp, model, model->L/2, model->L); + update_snr_calc(pexp, model, before); + } + + if (strcmp(arg,"struct23") == 0) { + struct_phases(pexp, model, model->L/2, 3*model->L/4 ); + update_snr_calc(pexp, model, before); + } + + if (strcmp(arg,"addnoise") == 0) { + int m; + float max; + + max = 0; + for(m=1; m<=model->L; m++) + if (model->A[m] > max) + max = model->A[m]; + max = 20.0*log10(max); + for(m=1; m<=model->L; m++) + if (20.0*log10(model->A[m]) < (max-20)) { + model->phi[m] += (PI/4)*(1.0 -2.0*rand()/RAND_MAX); + //printf("m %d\n", m); + } + } + + /* normalise phases */ + + for(m=1; m<=model->L; m++) + model->phi[m] = atan2(sin(model->phi[m]), cos(model->phi[m])); + + /* update states */ + + //best_Wo = refine_Wo(pexp, model, model->L/2, model->L); + pexp->phi1 += N*model->Wo; + + for(m=1; m<=model->L; m++) + pexp->phi_prev[m] = model->phi[m]; + pexp->Wo_prev = model->Wo; + pexp->frames++; + pexp->prev_model = *model; +} + +#ifdef OLD_STUFF + //quant_phases(model, 1, model->L, 3); + //update_variance_calc(pexp, model, before); + //print_sparse_pred_error(pexp, model, 1, model->L, 40.0); + + //sparse_vq_pred_error(pexp, model); + + //quant_phases(model, model->L/4+1, model->L, 3); + + //predict_phases1(pexp, model, 1, model->L/4); + //quant_phases(model, model->L/4+1, model->L, 3); + + //quant_phases(model, 1, model->L/8, 3); + + //update_snr_calc(pexp, model, before); + //update_variance_calc(pexp, model, before); + + //fixed_bits_per_frame(pexp, model, 40); + //struct_phases(pexp, model, 1, model->L/4); + //rand_phases(model, 10, model->L); + //for(m=1; m<=model->L; m++) + // model->A[m] = 0.0; + //model->A[model->L/2] = 1000; + //repeat_phases(model, 20); + //predict_phases(pexp, model, 1, model->L/4); + //quant_phases(model, 1, 10, 3); + //quant_phases(model, 10, 20, 2); + //repeat_phases(model, 20); + //rand_phases(model, 3*model->L/4, model->L); + // print_phi1_pred_error(model, 1, model->L); + //predict_phases(pexp, model, 1, model->L/4); + //first_order_band(model, model->L/4, model->L/2); + //first_order_band(model, model->L/2, 3*model->L/4); + //if (fabs(model->Wo - pexp->Wo_prev)< 0.1*model->Wo) + + //print_pred_error(pexp, model, 1, model->L, 40.0); + //print_sparse_pred_error(pexp, model, 1, model->L, 40.0); + + //phi1_est = est_phi1(model, 1, model->L/4); + //print_phi1_pred_error(model, 1, model->L/4); + + //first_order_band(model, 1, model->L/4, phi1_est); + //sub_linear(model, 1, model->L/4, phi1_est); + + //top_amp(pexp, model, 1, model->L/4, 4); + //top_amp(pexp, model, model->L/4, model->L/2, 4); + + //first_order_band(model, 1, model->L/4, phi1_est); + //first_order_band(model, model->L/4, model->L/2, phi1_est); + + //if (fabs(model->Wo - pexp->Wo_prev) > 0.2*model->Wo) + // rand_phases(model, model->L/2, model->L); + + //top_amp(pexp, model, 1, model->L/4, 4); + //top_amp(pexp, model, model->L/4, model->L/2, 8); + //top_amp(pexp, model, model->L/4+1, model->L/2, 10, 1); + //top_amp(pexp, model, 1, model->L/4, 10, 1); + //top_amp(pexp, model, model->L/4+1, 3*model->L/4, 10, 1); + //top_amp(pexp, model, 1, 3*model->L/4, 20, 1); + + #ifdef REAS_CAND1 + predict_phases(pexp, model, 1, model->L/4); + top_amp(pexp, model, model->L/4+1, 3*model->L/4, 10, 1); + rand_phases(model, 3*model->L/4+1, model->L); + #endif + + #ifdef REAS_CAND2 + if ((pexp->frames % 2) == 0) { + //printf("quant\n"); + predict_phases(pexp, model, 1, model->L/4); + //top_amp(pexp, model, model->L/4+1, 3*model->L/4, 20, 1); + top_amp(pexp, model, model->L/4+1, 7*model->L/8, 20, 1); + rand_phases(model, 7*model->L/8+1, model->L); + } + else { + //printf("predict\n"); + predict_phases(pexp, model, 1, model->L); + } + #endif + + //#define REAS_CAND3 + #ifdef REAS_CAND3 + if ((pexp->frames % 3) != 0) { + printf("pred\n"); + predict_phases(pexp, model, 1, model->L); + } + else { + predict_phases(pexp, model, 1, model->L/4); + fixed_bits_per_frame(pexp, model, model->L/4+1, 60); + } + #endif + //predict_phases(pexp, model, model->L/4, model->L); + + + //print_pred_error(pexp, model, 1, model->L); + //limit_prediction_error(pexp, model, model->L/2, model->L, PI/2); +#endif diff --git a/gr-vocoder/lib/codec2/phaseexp.h b/gr-vocoder/lib/codec2/phaseexp.h new file mode 100644 index 0000000000..865e8aede1 --- /dev/null +++ b/gr-vocoder/lib/codec2/phaseexp.h @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: phaseexp.h + AUTHOR......: David Rowe + DATE CREATED: June 2012 + + Experimental functions for quantising, modelling and synthesising phase. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2012 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __PHASEEXP__ +#define __PHASEEXP__ + +#include "kiss_fft.h" + +struct PEXP; + +struct PEXP * phase_experiment_create(); +void phase_experiment_destroy(struct PEXP *pexp); +void phase_experiment(struct PEXP *pexp, MODEL *model, char *arg); + +#endif diff --git a/gr-vocoder/lib/codec2/pilot_coeff.h b/gr-vocoder/lib/codec2/pilot_coeff.h new file mode 100644 index 0000000000..66e7501d8f --- /dev/null +++ b/gr-vocoder/lib/codec2/pilot_coeff.h @@ -0,0 +1,34 @@ +/* Generated by pilot_coeff_file() Octave function */ + +const float pilot_coeff[]={ + 0.00204705, + 0.00276339, + 0.00432595, + 0.00697042, + 0.0108452, + 0.0159865, + 0.0223035, + 0.029577, + 0.0374709, + 0.045557, + 0.0533491, + 0.0603458, + 0.0660751, + 0.070138, + 0.0722452, + 0.0722452, + 0.070138, + 0.0660751, + 0.0603458, + 0.0533491, + 0.045557, + 0.0374709, + 0.029577, + 0.0223035, + 0.0159865, + 0.0108452, + 0.00697042, + 0.00432595, + 0.00276339, + 0.00204705 +}; diff --git a/gr-vocoder/lib/codec2/postfilter.c b/gr-vocoder/lib/codec2/postfilter.c index 05d77c8450..7c1a6061a0 100644 --- a/gr-vocoder/lib/codec2/postfilter.c +++ b/gr-vocoder/lib/codec2/postfilter.c @@ -27,6 +27,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include <assert.h> #include <stdlib.h> #include <stdio.h> #include <math.h> @@ -34,6 +35,7 @@ #include "defines.h" #include "comp.h" #include "dump.h" +#include "sine.h" #include "postfilter.h" /*---------------------------------------------------------------------------*\ @@ -44,6 +46,11 @@ #define BG_THRESH 40.0 /* only consider low levels signals for bg_est */ #define BG_BETA 0.1 /* averaging filter constant */ +#define BG_MARGIN 6.0 /* harmonics this far above BG noise are + randomised. Helped make bg noise less + spikey (impulsive) for mmt1, but speech was + perhaps a little rougher. + */ /*---------------------------------------------------------------------------*\ @@ -61,7 +68,7 @@ (5-12) are required to transmit the frequency selective voicing information. Mixed excitation also requires accurate voicing estimation (parameter estimators always break occasionally under - exceptional condition). + exceptional conditions). In our case we use a post filter approach which requires no additional bits to be transmitted. The decoder measures the average @@ -97,15 +104,16 @@ void postfilter( ) { int m, uv; - float e; + float e, thresh; /* determine average energy across spectrum */ - e = 0.0; + e = 1E-12; for(m=1; m<=model->L; m++) e += model->A[m]*model->A[m]; - e = 10.0*log10(e/model->L); + assert(e > 0.0); + e = 10.0*log10f(e/model->L); /* If beneath threhold, update bg estimate. The idea of the threshold is to prevent updating during high level @@ -119,10 +127,11 @@ void postfilter( */ uv = 0; + thresh = powf(10.0, (*bg_est + BG_MARGIN)/20.0); if (model->voiced) for(m=1; m<=model->L; m++) - if (20.0*log10(model->A[m]) < *bg_est) { - model->phi[m] = TWO_PI*(float)rand()/RAND_MAX; + if (model->A[m] < thresh) { + model->phi[m] = TWO_PI*(float)codec2_rand()/CODEC2_RAND_MAX; uv++; } diff --git a/gr-vocoder/lib/codec2/quantise.c b/gr-vocoder/lib/codec2/quantise.c index 25f26066ed..6423dc83df 100644 --- a/gr-vocoder/lib/codec2/quantise.c +++ b/gr-vocoder/lib/codec2/quantise.c @@ -36,7 +36,9 @@ #include "quantise.h" #include "lpc.h" #include "lsp.h" -#include "fft.h" +#include "kiss_fft.h" +#undef TIMER +#include "machdep.h" #define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */ @@ -59,38 +61,20 @@ int lsp_bits(int i) { return lsp_cb[i].log2m; } -#if VECTOR_QUANTISATION -/*---------------------------------------------------------------------------*\ - - quantise_uniform - - Simulates uniform quantising of a float. - -\*---------------------------------------------------------------------------*/ - -void quantise_uniform(float *val, float min, float max, int bits) -{ - int levels = 1 << (bits-1); - float norm; - int index; - - /* hard limit to quantiser range */ - - printf("min: %f max: %f val: %f ", min, max, val[0]); - if (val[0] < min) val[0] = min; - if (val[0] > max) val[0] = max; - - norm = (*val - min)/(max-min); - printf("%f norm: %f ", val[0], norm); - index = fabs(levels*norm + 0.5); - - *val = min + index*(max-min)/levels; - - printf("index %d val_: %f\n", index, val[0]); +int lspd_bits(int i) { + return lsp_cbd[i].log2m; } +#ifdef __EXPERIMENTAL__ +int lspdt_bits(int i) { + return lsp_cbdt[i].log2m; +} #endif +int lsp_pred_vq_bits(int i) { + return lsp_cbjvm[i].log2m; +} + /*---------------------------------------------------------------------------*\ quantise_init @@ -127,13 +111,16 @@ long quantise(const float * cb, float vec[], float w[], int k, int m, float *se) float beste; /* best error so far */ long j; int i; + float diff; besti = 0; beste = 1E32; for(j=0; j<m; j++) { e = 0.0; - for(i=0; i<k; i++) - e += pow((cb[j*k+i]-vec[i])*w[i],2.0); + for(i=0; i<k; i++) { + diff = cb[j*k+i]-vec[i]; + e += powf(diff*w[i],2.0); + } if (e < beste) { beste = e; besti = j; @@ -147,16 +134,16 @@ long quantise(const float * cb, float vec[], float w[], int k, int m, float *se) /*---------------------------------------------------------------------------*\ - lspd_quantise + encode_lspds_scalar() - Scalar lsp difference quantiser. + Scalar/VQ LSP difference quantiser. \*---------------------------------------------------------------------------*/ -void lspd_quantise( - float lsp[], - float lsp_[], - int order +void encode_lspds_scalar( + int indexes[], + float lsp[], + int order ) { int i,k,m; @@ -164,10 +151,15 @@ void lspd_quantise( float lsp__hz[LPC_MAX]; float dlsp[LPC_MAX]; float dlsp_[LPC_MAX]; - float wt[1]; + float wt[LPC_MAX]; const float *cb; - float se = 0.0; - int indexes[LPC_MAX]; + float se; + + assert(order == LPC_ORD); + + for(i=0; i<order; i++) { + wt[i] = 1.0; + } /* convert from radians to Hz so we can use human readable frequencies */ @@ -175,14 +167,13 @@ void lspd_quantise( for(i=0; i<order; i++) lsp_hz[i] = (4000.0/PI)*lsp[i]; - dlsp[0] = lsp_hz[0]; - for(i=1; i<order; i++) - dlsp[i] = lsp_hz[i] - lsp_hz[i-1]; - - /* simple uniform scalar quantisers */ + //printf("\n"); wt[0] = 1.0; for(i=0; i<order; i++) { + + /* find difference from previous qunatised lsp */ + if (i) dlsp[i] = lsp_hz[i] - lsp__hz[i-1]; else @@ -194,129 +185,565 @@ void lspd_quantise( indexes[i] = quantise(cb, &dlsp[i], wt, k, m, &se); dlsp_[i] = cb[indexes[i]*k]; + if (i) lsp__hz[i] = lsp__hz[i-1] + dlsp_[i]; else lsp__hz[0] = dlsp_[0]; + + //printf("%d lsp %3.2f dlsp %3.2f dlsp_ %3.2f lsp_ %3.2f\n", i, lsp_hz[i], dlsp[i], dlsp_[i], lsp__hz[i]); } - for(; i<order; i++) - lsp__hz[i] = lsp__hz[i-1] + dlsp[i]; - /* convert back to radians */ +} + +void decode_lspds_scalar( + float lsp_[], + int indexes[], + int order +) +{ + int i,k; + float lsp__hz[LPC_MAX]; + float dlsp_[LPC_MAX]; + const float *cb; + + assert(order == LPC_ORD); + + for(i=0; i<order; i++) { + + k = lsp_cbd[i].k; + cb = lsp_cbd[i].cb; + dlsp_[i] = cb[indexes[i]*k]; + + if (i) + lsp__hz[i] = lsp__hz[i-1] + dlsp_[i]; + else + lsp__hz[0] = dlsp_[0]; - for(i=0; i<order; i++) lsp_[i] = (PI/4000.0)*lsp__hz[i]; + + //printf("%d dlsp_ %3.2f lsp_ %3.2f\n", i, dlsp_[i], lsp__hz[i]); + } + } +#ifdef __EXPERIMENTAL__ /*---------------------------------------------------------------------------*\ - lspd_vq_quantise + lspvq_quantise - Vector lsp difference quantiser. + Vector LSP quantiser. \*---------------------------------------------------------------------------*/ -void lspdvq_quantise( +void lspvq_quantise( float lsp[], float lsp_[], int order ) { int i,k,m,ncb, nlsp; - float dlsp[LPC_MAX]; - float dlsp_[LPC_MAX]; - float wt[LPC_ORD]; + float wt[LPC_ORD], lsp_hz[LPC_ORD]; const float *cb; - float se = 0.0; + float se; int index; - dlsp[0] = lsp[0]; - for(i=1; i<order; i++) - dlsp[i] = lsp[i] - lsp[i-1]; + for(i=0; i<LPC_ORD; i++) { + wt[i] = 1.0; + lsp_hz[i] = 4000.0*lsp[i]/PI; + } - for(i=0; i<order; i++) - dlsp_[i] = dlsp[i]; + /* scalar quantise LSPs 1,2,3,4 */ - for(i=0; i<order; i++) + /* simple uniform scalar quantisers */ + + for(i=0; i<4; i++) { + k = lsp_cb[i].k; + m = lsp_cb[i].m; + cb = lsp_cb[i].cb; + index = quantise(cb, &lsp_hz[i], wt, k, m, &se); + lsp_[i] = cb[index*k]*PI/4000.0; + } + + //#define WGHT +#ifdef WGHT + for(i=4; i<9; i++) { + wt[i] = 1.0/(lsp[i]-lsp[i-1]) + 1.0/(lsp[i+1]-lsp[i]); + //printf("wt[%d] = %f\n", i, wt[i]); + } + wt[9] = 1.0/(lsp[i]-lsp[i-1]); +#endif + + /* VQ LSPs 5,6,7,8,9,10 */ + + ncb = 4; + nlsp = 4; + k = lsp_cbjnd[ncb].k; + m = lsp_cbjnd[ncb].m; + cb = lsp_cbjnd[ncb].cb; + index = quantise(cb, &lsp_hz[nlsp], &wt[nlsp], k, m, &se); + for(i=4; i<LPC_ORD; i++) { + lsp_[i] = cb[index*k+i-4]*(PI/4000.0); + //printf("%4.f (%4.f) ", lsp_hz[i], cb[index*k+i-4]); + } +} + +/*---------------------------------------------------------------------------*\ + + lspjnd_quantise + + Experimental JND LSP quantiser. + +\*---------------------------------------------------------------------------*/ + +void lspjnd_quantise(float lsps[], float lsps_[], int order) +{ + int i,k,m; + float wt[LPC_ORD], lsps_hz[LPC_ORD]; + const float *cb; + float se = 0.0; + int index; + + for(i=0; i<LPC_ORD; i++) { wt[i] = 1.0; + } - /* scalar quantise dLSPs 1,2,3,4,5 */ + /* convert to Hz */ - for(i=0; i<5; i++) { - if (i) - dlsp[i] = (lsp[i] - lsp_[i-1])*4000.0/PI; - else - dlsp[0] = lsp[0]*4000.0/PI; + for(i=0; i<LPC_ORD; i++) { + lsps_hz[i] = lsps[i]*(4000.0/PI); + lsps_[i] = lsps[i]; + } - k = lsp_cbdvq[i].k; - m = lsp_cbdvq[i].m; - cb = lsp_cbdvq[i].cb; - index = quantise(cb, &dlsp[i], wt, k, m, &se); - dlsp_[i] = cb[index*k]*PI/4000.0; + /* simple uniform scalar quantisers */ - if (i) - lsp_[i] = lsp_[i-1] + dlsp_[i]; - else - lsp_[0] = dlsp_[0]; - } - dlsp[i] = lsp[i] - lsp_[i-1]; - dlsp_[i] = dlsp[i]; - - //printf("lsp[0] %f lsp_[0] %f\n", lsp[0], lsp_[0]); - //printf("lsp[1] %f lsp_[1] %f\n", lsp[1], lsp_[1]); - -#ifdef TT - /* VQ dLSPs 3,4,5 */ - - ncb = 2; - nlsp = 2; - k = lsp_cbdvq[ncb].k; - m = lsp_cbdvq[ncb].m; - cb = lsp_cbdvq[ncb].cb; - index = quantise(cb, &dlsp[nlsp], wt, k, m, &se); - dlsp_[nlsp] = cb[index*k]; - dlsp_[nlsp+1] = cb[index*k+1]; - dlsp_[nlsp+2] = cb[index*k+2]; - - lsp_[0] = dlsp_[0]; - for(i=1; i<5; i++) - lsp_[i] = lsp_[i-1] + dlsp_[i]; - dlsp[i] = lsp[i] - lsp_[i-1]; - dlsp_[i] = dlsp[i]; + for(i=0; i<4; i++) { + k = lsp_cbjnd[i].k; + m = lsp_cbjnd[i].m; + cb = lsp_cbjnd[i].cb; + index = quantise(cb, &lsps_hz[i], wt, k, m, &se); + lsps_[i] = cb[index*k]*(PI/4000.0); + } + + /* VQ LSPs 5,6,7,8,9,10 */ + + k = lsp_cbjnd[4].k; + m = lsp_cbjnd[4].m; + cb = lsp_cbjnd[4].cb; + index = quantise(cb, &lsps_hz[4], &wt[4], k, m, &se); + //printf("k = %d m = %d c[0] %f cb[k] %f\n", k,m,cb[0],cb[k]); + //printf("index = %4d: ", index); + for(i=4; i<LPC_ORD; i++) { + lsps_[i] = cb[index*k+i-4]*(PI/4000.0); + //printf("%4.f (%4.f) ", lsps_hz[i], cb[index*k+i-4]); + } + //printf("\n"); +} + +void compute_weights(const float *x, float *w, int ndim); + +/*---------------------------------------------------------------------------*\ + + lspdt_quantise + + LSP difference in time quantiser. Split VQ, encoding LSPs 1-4 with + one VQ, and LSPs 5-10 with a second. Update of previous lsp memory + is done outside of this function to handle dT between 10 or 20ms + frames. + + mode action + ------------------ + + LSPDT_ALL VQ LSPs 1-4 and 5-10 + LSPDT_LOW Just VQ LSPs 1-4, for LSPs 5-10 just copy previous + LSPDT_HIGH Just VQ LSPs 5-10, for LSPs 1-4 just copy previous + +\*---------------------------------------------------------------------------*/ + +void lspdt_quantise(float lsps[], float lsps_[], float lsps__prev[], int mode) +{ + int i; + float wt[LPC_ORD]; + float lsps_dt[LPC_ORD]; +#ifdef TRY_LSPDT_VQ + int k,m; + int index; + const float *cb; + float se = 0.0; +#endif // TRY_LSPDT_VQ + + //compute_weights(lsps, wt, LPC_ORD); + for(i=0; i<LPC_ORD; i++) { + wt[i] = 1.0; + } + + //compute_weights(lsps, wt, LPC_ORD ); + + for(i=0; i<LPC_ORD; i++) { + lsps_dt[i] = lsps[i] - lsps__prev[i]; + lsps_[i] = lsps__prev[i]; + } + + //#define TRY_LSPDT_VQ +#ifdef TRY_LSPDT_VQ + /* this actually improves speech a bit, but 40ms updates works surprsingly well.... */ + k = lsp_cbdt[0].k; + m = lsp_cbdt[0].m; + cb = lsp_cbdt[0].cb; + index = quantise(cb, lsps_dt, wt, k, m, &se); + for(i=0; i<LPC_ORD; i++) { + lsps_[i] += cb[index*k + i]; + } #endif - /* VQ dLSPs 6,7,8,9,10 */ - ncb = 5; - nlsp = 5; - k = lsp_cbdvq[ncb].k; - m = lsp_cbdvq[ncb].m; - cb = lsp_cbdvq[ncb].cb; - index = quantise(cb, &dlsp[nlsp], wt, k, m, &se); - dlsp_[nlsp] = cb[index*k]; - dlsp_[nlsp+1] = cb[index*k+1]; - dlsp_[nlsp+2] = cb[index*k+2]; - dlsp_[nlsp+3] = cb[index*k+3]; - dlsp_[nlsp+4] = cb[index*k+4]; +} +#endif + +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX_ENTRIES 16384 + +void compute_weights(const float *x, float *w, int ndim) +{ + int i; + w[0] = MIN(x[0], x[1]-x[0]); + for (i=1;i<ndim-1;i++) + w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]); + w[ndim-1] = MIN(x[ndim-1]-x[ndim-2], PI-x[ndim-1]); + + for (i=0;i<ndim;i++) + w[i] = 1./(.01+w[i]); + //w[0]*=3; + //w[1]*=2; +} + +/* LSP weight calculation ported from m-file function kindly submitted + by Anssi, OH3GDD */ + +void compute_weights_anssi_mode2(const float *x, float *w, int ndim) +{ + int i; + float d[LPC_ORD]; + + assert(ndim == LPC_ORD); + + for(i=0; i<LPC_ORD; i++) + d[i] = 1.0; + + d[0] = x[1]; + for (i=1; i<LPC_ORD-1; i++) + d[i] = x[i+1] - x[i-1]; + d[LPC_ORD-1] = PI - x[8]; + for (i=0; i<LPC_ORD; i++) { + if (x[i]<((400.0/4000.0)*PI)) + w[i]=5.0/(0.01+d[i]); + else if (x[i]<((700.0/4000.0)*PI)) + w[i]=4.0/(0.01+d[i]); + else if (x[i]<((1200.0/4000.0)*PI)) + w[i]=3.0/(0.01+d[i]); + else if (x[i]<((2000.0/4000.0)*PI)) + w[i]=2.0/(0.01+d[i]); + else + w[i]=1.0/(0.01+d[i]); + + w[i]=pow(w[i]+0.3, 0.66); + } +} + +int find_nearest(const float *codebook, int nb_entries, float *x, int ndim) +{ + int i, j; + float min_dist = 1e15; + int nearest = 0; + + for (i=0;i<nb_entries;i++) + { + float dist=0; + for (j=0;j<ndim;j++) + dist += (x[j]-codebook[i*ndim+j])*(x[j]-codebook[i*ndim+j]); + if (dist<min_dist) + { + min_dist = dist; + nearest = i; + } + } + return nearest; +} + +int find_nearest_weighted(const float *codebook, int nb_entries, float *x, const float *w, int ndim) +{ + int i, j; + float min_dist = 1e15; + int nearest = 0; + + for (i=0;i<nb_entries;i++) + { + float dist=0; + for (j=0;j<ndim;j++) + dist += w[j]*(x[j]-codebook[i*ndim+j])*(x[j]-codebook[i*ndim+j]); + if (dist<min_dist) + { + min_dist = dist; + nearest = i; + } + } + return nearest; +} + +void lspjvm_quantise(float *x, float *xq, int ndim) +{ + int i, n1, n2, n3; + float err[LPC_ORD], err2[LPC_ORD], err3[LPC_ORD]; + float w[LPC_ORD], w2[LPC_ORD], w3[LPC_ORD]; + const float *codebook1 = lsp_cbjvm[0].cb; + const float *codebook2 = lsp_cbjvm[1].cb; + const float *codebook3 = lsp_cbjvm[2].cb; + + w[0] = MIN(x[0], x[1]-x[0]); + for (i=1;i<ndim-1;i++) + w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]); + w[ndim-1] = MIN(x[ndim-1]-x[ndim-2], PI-x[ndim-1]); + + compute_weights(x, w, ndim); + + n1 = find_nearest(codebook1, lsp_cbjvm[0].m, x, ndim); + + for (i=0;i<ndim;i++) + { + xq[i] = codebook1[ndim*n1+i]; + err[i] = x[i] - xq[i]; + } + for (i=0;i<ndim/2;i++) + { + err2[i] = err[2*i]; + err3[i] = err[2*i+1]; + w2[i] = w[2*i]; + w3[i] = w[2*i+1]; + } + n2 = find_nearest_weighted(codebook2, lsp_cbjvm[1].m, err2, w2, ndim/2); + n3 = find_nearest_weighted(codebook3, lsp_cbjvm[2].m, err3, w3, ndim/2); + + for (i=0;i<ndim/2;i++) + { + xq[2*i] += codebook2[ndim*n2/2+i]; + xq[2*i+1] += codebook3[ndim*n3/2+i]; + } +} + +#ifdef __EXPERIMENTAL__ + +#define MBEST_STAGES 4 + +struct MBEST_LIST { + int index[MBEST_STAGES]; /* index of each stage that lead us to this error */ + float error; +}; + +struct MBEST { + int entries; /* number of entries in mbest list */ + struct MBEST_LIST *list; +}; + + +static struct MBEST *mbest_create(int entries) { + int i,j; + struct MBEST *mbest; + + assert(entries > 0); + mbest = (struct MBEST *)malloc(sizeof(struct MBEST)); + assert(mbest != NULL); + + mbest->entries = entries; + mbest->list = (struct MBEST_LIST *)malloc(entries*sizeof(struct MBEST_LIST)); + assert(mbest->list != NULL); + + for(i=0; i<mbest->entries; i++) { + for(j=0; j<MBEST_STAGES; j++) + mbest->list[i].index[j] = 0; + mbest->list[i].error = 1E32; + } + + return mbest; +} + + +static void mbest_destroy(struct MBEST *mbest) { + assert(mbest != NULL); + free(mbest->list); + free(mbest); +} + + +/*---------------------------------------------------------------------------*\ + + mbest_insert + + Insert the results of a vector to codebook entry comparison. The + list is ordered in order or error, so those entries with the + smallest error will be first on the list. + +\*---------------------------------------------------------------------------*/ + +static void mbest_insert(struct MBEST *mbest, int index[], float error) { + int i, j, found; + struct MBEST_LIST *list = mbest->list; + int entries = mbest->entries; + + found = 0; + for(i=0; i<entries && !found; i++) + if (error < list[i].error) { + found = 1; + for(j=entries-1; j>i; j--) + list[j] = list[j-1]; + for(j=0; j<MBEST_STAGES; j++) + list[i].index[j] = index[j]; + list[i].error = error; + } +} + - /* rebuild LSPs for dLSPs */ +static void mbest_print(char title[], struct MBEST *mbest) { + int i,j; - lsp_[0] = dlsp_[0]; - for(i=1; i<order; i++) - lsp_[i] = lsp_[i-1] + dlsp_[i]; + printf("%s\n", title); + for(i=0; i<mbest->entries; i++) { + for(j=0; j<MBEST_STAGES; j++) + printf(" %4d ", mbest->list[i].index[j]); + printf(" %f\n", mbest->list[i].error); + } } -void check_lsp_order(float lsp[], int lpc_order) + +/*---------------------------------------------------------------------------*\ + + mbest_search + + Searches vec[] to a codebbook of vectors, and maintains a list of the mbest + closest matches. + +\*---------------------------------------------------------------------------*/ + +static void mbest_search( + const float *cb, /* VQ codebook to search */ + float vec[], /* target vector */ + float w[], /* weighting vector */ + int k, /* dimension of vector */ + int m, /* number on entries in codebook */ + struct MBEST *mbest, /* list of closest matches */ + int index[] /* indexes that lead us here */ +) +{ + float e; + int i,j; + float diff; + + for(j=0; j<m; j++) { + e = 0.0; + for(i=0; i<k; i++) { + diff = cb[j*k+i]-vec[i]; + e += pow(diff*w[i],2.0); + } + index[0] = j; + mbest_insert(mbest, index, e); + } +} + + +/* 3 stage VQ LSP quantiser. Design and guidance kindly submitted by Anssi, OH3GDD */ + +void lspanssi_quantise(float *x, float *xq, int ndim, int mbest_entries) +{ + int i, j, n1, n2, n3, n4; + float w[LPC_ORD]; + const float *codebook1 = lsp_cbvqanssi[0].cb; + const float *codebook2 = lsp_cbvqanssi[1].cb; + const float *codebook3 = lsp_cbvqanssi[2].cb; + const float *codebook4 = lsp_cbvqanssi[3].cb; + struct MBEST *mbest_stage1, *mbest_stage2, *mbest_stage3, *mbest_stage4; + float target[LPC_ORD]; + int index[MBEST_STAGES]; + + mbest_stage1 = mbest_create(mbest_entries); + mbest_stage2 = mbest_create(mbest_entries); + mbest_stage3 = mbest_create(mbest_entries); + mbest_stage4 = mbest_create(mbest_entries); + for(i=0; i<MBEST_STAGES; i++) + index[i] = 0; + + compute_weights_anssi_mode2(x, w, ndim); + + #ifdef DUMP + dump_weights(w, ndim); + #endif + + /* Stage 1 */ + + mbest_search(codebook1, x, w, ndim, lsp_cbvqanssi[0].m, mbest_stage1, index); + mbest_print("Stage 1:", mbest_stage1); + + /* Stage 2 */ + + for (j=0; j<mbest_entries; j++) { + index[1] = n1 = mbest_stage1->list[j].index[0]; + for(i=0; i<ndim; i++) + target[i] = x[i] - codebook1[ndim*n1+i]; + mbest_search(codebook2, target, w, ndim, lsp_cbvqanssi[1].m, mbest_stage2, index); + } + mbest_print("Stage 2:", mbest_stage2); + + /* Stage 3 */ + + for (j=0; j<mbest_entries; j++) { + index[2] = n1 = mbest_stage2->list[j].index[1]; + index[1] = n2 = mbest_stage2->list[j].index[0]; + for(i=0; i<ndim; i++) + target[i] = x[i] - codebook1[ndim*n1+i] - codebook2[ndim*n2+i]; + mbest_search(codebook3, target, w, ndim, lsp_cbvqanssi[2].m, mbest_stage3, index); + } + mbest_print("Stage 3:", mbest_stage3); + + /* Stage 4 */ + + for (j=0; j<mbest_entries; j++) { + index[3] = n1 = mbest_stage3->list[j].index[2]; + index[2] = n2 = mbest_stage3->list[j].index[1]; + index[1] = n3 = mbest_stage3->list[j].index[0]; + for(i=0; i<ndim; i++) + target[i] = x[i] - codebook1[ndim*n1+i] - codebook2[ndim*n2+i] - codebook3[ndim*n3+i]; + mbest_search(codebook4, target, w, ndim, lsp_cbvqanssi[3].m, mbest_stage4, index); + } + mbest_print("Stage 4:", mbest_stage4); + + n1 = mbest_stage4->list[0].index[3]; + n2 = mbest_stage4->list[0].index[2]; + n3 = mbest_stage4->list[0].index[1]; + n4 = mbest_stage4->list[0].index[0]; + for (i=0;i<ndim;i++) + xq[i] = codebook1[ndim*n1+i] + codebook2[ndim*n2+i] + codebook3[ndim*n3+i] + codebook4[ndim*n4+i]; + + mbest_destroy(mbest_stage1); + mbest_destroy(mbest_stage2); + mbest_destroy(mbest_stage3); + mbest_destroy(mbest_stage4); +} +#endif + +int check_lsp_order(float lsp[], int lpc_order) { int i; float tmp; + int swaps = 0; for(i=1; i<lpc_order; i++) if (lsp[i] < lsp[i-1]) { - printf("swap %d\n",i); + //fprintf(stderr, "swap %d\n",i); + swaps++; tmp = lsp[i-1]; - lsp[i-1] = lsp[i]-0.05; - lsp[i] = tmp+0.05; + lsp[i-1] = lsp[i]-0.1; + lsp[i] = tmp+0.1; + i = 1; /* start check again, as swap may have caused out of order */ } + + return swaps; } void force_min_lsp_dist(float lsp[], int lpc_order) @@ -329,131 +756,159 @@ void force_min_lsp_dist(float lsp[], int lpc_order) } } + /*---------------------------------------------------------------------------*\ - lpc_model_amplitudes + lpc_post_filter() + + Applies a post filter to the LPC synthesis filter power spectrum + Pw, which supresses the inter-formant energy. + + The algorithm is from p267 (Section 8.6) of "Digital Speech", + edited by A.M. Kondoz, 1994 published by Wiley and Sons. Chapter 8 + of this text is on the MBE vocoder, and this is a freq domain + adaptation of post filtering commonly used in CELP. - Derive a LPC model for amplitude samples then estimate amplitude samples - from this model with optional LSP quantisation. + I used the Octave simulation lpcpf.m to get an understaing of the + algorithm. - Returns the spectral distortion for this frame. + Requires two more FFTs which is significantly more MIPs. However + it should be possible to implement this more efficiently in the + time domain. Just not sure how to handle relative time delays + between the synthesis stage and updating these coeffs. A smaller + FFT size might also be accetable to save CPU. + + TODO: + [ ] sync var names between Octave and C version + [ ] doc gain normalisation + [ ] I think the first FFT is not rqd as we do the same + thing in aks_to_M2(). \*---------------------------------------------------------------------------*/ -float lpc_model_amplitudes( - float Sn[], /* Input frame of speech samples */ - float w[], - MODEL *model, /* sinusoidal model parameters */ - int order, /* LPC model order */ - int lsp_quant, /* optional LSP quantisation if non-zero */ - float ak[] /* output aks */ -) +void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, MODEL *model, COMP Pw[], float ak[], + int order, int dump, float beta, float gamma, int bass_boost) { - float Wn[M]; - float R[LPC_MAX+1]; - float E; - int i,j; - float snr; - float lsp[LPC_MAX]; - float lsp_hz[LPC_MAX]; - float lsp_[LPC_MAX]; - int roots; /* number of LSP roots found */ - int index; - float se = 0.0; - int k,m; - const float * cb; - float wt[LPC_MAX]; - - for(i=0; i<M; i++) - Wn[i] = Sn[i]*w[i]; - autocorrelate(Wn,R,M,order); - levinson_durbin(R,ak,order); - - E = 0.0; - for(i=0; i<=order; i++) - E += ak[i]*R[i]; + int i; + COMP x[FFT_ENC]; /* input to FFTs */ + COMP Aw[FFT_ENC]; /* LPC analysis filter spectrum */ + COMP Ww[FFT_ENC]; /* weighting spectrum */ + float Rw[FFT_ENC]; /* R = WA */ + float e_before, e_after, gain; + float Pfw[FFT_ENC]; /* Post filter mag spectrum */ + float max_Rw, min_Rw; + float coeff; + TIMER_VAR(tstart, tfft1, taw, tfft2, tww, tr); + + TIMER_SAMPLE(tstart); + + /* Determine LPC inverse filter spectrum 1/A(exp(jw)) -----------*/ + + /* we actually want the synthesis filter A(exp(jw)) but the + inverse (analysis) filter is easier to find as it's FIR, we + just use the inverse of 1/A to get the synthesis filter + A(exp(jw)) */ + + for(i=0; i<FFT_ENC; i++) { + x[i].real = 0.0; + x[i].imag = 0.0; + } - for(i=0; i<order; i++) - wt[i] = 1.0; + for(i=0; i<=order; i++) + x[i].real = ak[i]; + kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)x, (kiss_fft_cpx *)Aw); - if (lsp_quant) { - roots = lpc_to_lsp(ak, order, lsp, 5, LSP_DELTA1); - if (roots != order) - printf("LSP roots not found\n"); + TIMER_SAMPLE_AND_LOG(tfft1, tstart, " fft1"); - /* convert from radians to Hz to make quantisers more - human readable */ + for(i=0; i<FFT_ENC/2; i++) { + Aw[i].real = 1.0/(Aw[i].real*Aw[i].real + Aw[i].imag*Aw[i].imag); + } - for(i=0; i<order; i++) - lsp_hz[i] = (4000.0/PI)*lsp[i]; + TIMER_SAMPLE_AND_LOG(taw, tfft1, " Aw"); - /* simple uniform scalar quantisers */ + /* Determine weighting filter spectrum W(exp(jw)) ---------------*/ - for(i=0; i<10; i++) { - k = lsp_cb[i].k; - m = lsp_cb[i].m; - cb = lsp_cb[i].cb; - index = quantise(cb, &lsp_hz[i], wt, k, m, &se); - lsp_hz[i] = cb[index*k]; + for(i=0; i<FFT_ENC; i++) { + x[i].real = 0.0; + x[i].imag = 0.0; } - /* experiment: simulating uniform quantisation error - for(i=0; i<order; i++) - lsp[i] += PI*(12.5/4000.0)*(1.0 - 2.0*(float)rand()/RAND_MAX); - */ - - for(i=0; i<order; i++) - lsp[i] = (PI/4000.0)*lsp_hz[i]; + x[0].real = ak[0]; + coeff = gamma; + for(i=1; i<=order; i++) { + x[i].real = ak[i] * coeff; + coeff *= gamma; + } + kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)x, (kiss_fft_cpx *)Ww); - /* Bandwidth Expansion (BW). Prevents any two LSPs getting too - close together after quantisation. We know from experiment - that LSP quantisation errors < 12.5Hz (25Hz setp size) are - inaudible so we use that as the minimum LSP separation. - */ + TIMER_SAMPLE_AND_LOG(tfft2, taw, " fft2"); - for(i=1; i<5; i++) { - if (lsp[i] - lsp[i-1] < PI*(12.5/4000.0)) - lsp[i] = lsp[i-1] + PI*(12.5/4000.0); + for(i=0; i<FFT_ENC/2; i++) { + Ww[i].real = Ww[i].real*Ww[i].real + Ww[i].imag*Ww[i].imag; } - /* as quantiser gaps increased, larger BW expansion was required - to prevent twinkly noises */ + TIMER_SAMPLE_AND_LOG(tww, tfft2, " Ww"); + + /* Determined combined filter R = WA ---------------------------*/ + + max_Rw = 0.0; min_Rw = 1E32; + for(i=0; i<FFT_ENC/2; i++) { + Rw[i] = sqrtf(Ww[i].real * Aw[i].real); + if (Rw[i] > max_Rw) + max_Rw = Rw[i]; + if (Rw[i] < min_Rw) + min_Rw = Rw[i]; - for(i=5; i<8; i++) { - if (lsp[i] - lsp[i-1] < PI*(25.0/4000.0)) - lsp[i] = lsp[i-1] + PI*(25.0/4000.0); } - for(i=8; i<order; i++) { - if (lsp[i] - lsp[i-1] < PI*(75.0/4000.0)) - lsp[i] = lsp[i-1] + PI*(75.0/4000.0); + + TIMER_SAMPLE_AND_LOG(tr, tww, " R"); + + #ifdef DUMP + if (dump) + dump_Rw(Rw); + #endif + + /* create post filter mag spectrum and apply ------------------*/ + + /* measure energy before post filtering */ + + e_before = 1E-4; + for(i=0; i<FFT_ENC/2; i++) + e_before += Pw[i].real; + + /* apply post filter and measure energy */ + + #ifdef DUMP + if (dump) + dump_Pwb(Pw); + #endif + + e_after = 1E-4; + for(i=0; i<FFT_ENC/2; i++) { + Pfw[i] = powf(Rw[i], beta); + Pw[i].real *= Pfw[i] * Pfw[i]; + e_after += Pw[i].real; } + gain = e_before/e_after; - for(j=0; j<order; j++) - lsp_[j] = lsp[j]; + /* apply gain factor to normalise energy */ - lsp_to_lpc(lsp_, ak, order); -#ifdef DUMP - dump_lsp(lsp); -#endif - } + for(i=0; i<FFT_ENC/2; i++) { + Pw[i].real *= gain; + } -#ifdef DUMP - dump_E(E); -#endif - #ifdef SIM_QUANT - /* simulated LPC energy quantisation */ - { - float e = 10.0*log10(E); - e += 2.0*(1.0 - 2.0*(float)rand()/RAND_MAX); - E = pow(10.0,e/10.0); - } - #endif + if (bass_boost) { + /* add 3dB to first 1 kHz to account for LP effect of PF */ - aks_to_M2(ak,order,model,E,&snr, 1); /* {ak} -> {Am} LPC decode */ + for(i=0; i<FFT_ENC/8; i++) { + Pw[i].real *= 1.4*1.4; + } + } - return snr; + TIMER_SAMPLE_AND_LOG2(tr, " filt"); } + /*---------------------------------------------------------------------------*\ aks_to_M2() @@ -465,61 +920,103 @@ float lpc_model_amplitudes( \*---------------------------------------------------------------------------*/ void aks_to_M2( - float ak[], /* LPC's */ - int order, - MODEL *model, /* sinusoidal model parameters for this frame */ - float E, /* energy term */ - float *snr, /* signal to noise ratio for this frame in dB */ - int dump /* true to dump sample to dump file */ + kiss_fft_cfg fft_fwd_cfg, + float ak[], /* LPC's */ + int order, + MODEL *model, /* sinusoidal model parameters for this frame */ + float E, /* energy term */ + float *snr, /* signal to noise ratio for this frame in dB */ + int dump, /* true to dump sample to dump file */ + int sim_pf, /* true to simulate a post filter */ + int pf, /* true to LPC post filter */ + int bass_boost, /* enable LPC filter 0-1khz 3dB boost */ + float beta, + float gamma /* LPC post filter parameters */ ) { - COMP Pw[FFT_DEC]; /* power spectrum */ + COMP pw[FFT_ENC]; /* input to FFT for power spectrum */ + COMP Pw[FFT_ENC]; /* output power spectrum */ int i,m; /* loop variables */ int am,bm; /* limits of current band */ float r; /* no. rads/bin */ float Em; /* energy in band */ float Am; /* spectral amplitude sample */ float signal, noise; + TIMER_VAR(tstart, tfft, tpw, tpf); + + TIMER_SAMPLE(tstart); - r = TWO_PI/(FFT_DEC); + r = TWO_PI/(FFT_ENC); /* Determine DFT of A(exp(jw)) --------------------------------------------*/ - for(i=0; i<FFT_DEC; i++) { - Pw[i].real = 0.0; - Pw[i].imag = 0.0; + for(i=0; i<FFT_ENC; i++) { + pw[i].real = 0.0; + pw[i].imag = 0.0; } for(i=0; i<=order; i++) - Pw[i].real = ak[i]; - fft(&Pw[0].real,FFT_DEC,1); + pw[i].real = ak[i]; + kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)pw, (kiss_fft_cpx *)Pw); + + TIMER_SAMPLE_AND_LOG(tfft, tstart, " fft"); /* Determine power spectrum P(w) = E/(A(exp(jw))^2 ------------------------*/ - for(i=0; i<FFT_DEC/2; i++) + for(i=0; i<FFT_ENC/2; i++) Pw[i].real = E/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag); -#ifdef DUMP + + TIMER_SAMPLE_AND_LOG(tpw, tfft, " Pw"); + + if (pf) + lpc_post_filter(fft_fwd_cfg, model, Pw, ak, order, dump, beta, gamma, bass_boost); + + TIMER_SAMPLE_AND_LOG(tpf, tpw, " LPC post filter"); + + #ifdef DUMP if (dump) dump_Pw(Pw); -#endif + #endif - /* Determine magnitudes by linear interpolation of P(w) -------------------*/ + /* Determine magnitudes from P(w) ----------------------------------------*/ - signal = noise = 0.0; - for(m=1; m<=model->L; m++) { - am = floor((m - 0.5)*model->Wo/r + 0.5); - bm = floor((m + 0.5)*model->Wo/r + 0.5); - Em = 0.0; + /* when used just by decoder {A} might be all zeroes so init signal + and noise to prevent log(0) errors */ - for(i=am; i<bm; i++) - Em += Pw[i].real; - Am = sqrt(Em); + signal = 1E-30; noise = 1E-32; - signal += pow(model->A[m],2.0); - noise += pow(model->A[m] - Am,2.0); - model->A[m] = Am; + for(m=1; m<=model->L; m++) { + am = (int)((m - 0.5)*model->Wo/r + 0.5); + bm = (int)((m + 0.5)*model->Wo/r + 0.5); + Em = 0.0; + + for(i=am; i<bm; i++) + Em += Pw[i].real; + Am = sqrtf(Em); + + signal += model->A[m]*model->A[m]; + noise += (model->A[m] - Am)*(model->A[m] - Am); + + /* This code significantly improves perf of LPC model, in + particular when combined with phase0. The LPC spectrum tends + to track just under the peaks of the spectral envelope, and + just above nulls. This algorithm does the reverse to + compensate - raising the amplitudes of spectral peaks, while + attenuating the null. This enhances the formants, and + supresses the energy between formants. */ + + if (sim_pf) { + if (Am > model->A[m]) + Am *= 0.7; + if (Am < model->A[m]) + Am *= 1.4; + } + + model->A[m] = Am; } - *snr = 10.0*log10(signal/noise); + *snr = 10.0*log10f(signal/noise); + + TIMER_SAMPLE_AND_LOG2(tpf, " rec"); } /*---------------------------------------------------------------------------*\ @@ -540,7 +1037,7 @@ int encode_Wo(float Wo) float norm; norm = (Wo - Wo_min)/(Wo_max - Wo_min); - index = floor(WO_LEVELS * norm + 0.5); + index = floorf(WO_LEVELS * norm + 0.5); if (index < 0 ) index = 0; if (index > (WO_LEVELS-1)) index = WO_LEVELS-1; @@ -572,6 +1069,84 @@ float decode_Wo(int index) /*---------------------------------------------------------------------------*\ + FUNCTION....: encode_Wo_dt() + AUTHOR......: David Rowe + DATE CREATED: 6 Nov 2011 + + Encodes Wo difference from last frame. + +\*---------------------------------------------------------------------------*/ + +int encode_Wo_dt(float Wo, float prev_Wo) +{ + int index, mask, max_index, min_index; + float Wo_min = TWO_PI/P_MAX; + float Wo_max = TWO_PI/P_MIN; + float norm; + + norm = (Wo - prev_Wo)/(Wo_max - Wo_min); + index = floor(WO_LEVELS * norm + 0.5); + //printf("ENC index: %d ", index); + + /* hard limit */ + + max_index = (1 << (WO_DT_BITS-1)) - 1; + min_index = - (max_index+1); + if (index > max_index) index = max_index; + if (index < min_index) index = min_index; + //printf("max_index: %d min_index: %d hard index: %d ", + // max_index, min_index, index); + + /* mask so that only LSB WO_DT_BITS remain, bit WO_DT_BITS is the sign bit */ + + mask = ((1 << WO_DT_BITS) - 1); + index &= mask; + //printf("mask: 0x%x index: 0x%x\n", mask, index); + + return index; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_Wo_dt() + AUTHOR......: David Rowe + DATE CREATED: 6 Nov 2011 + + Decodes Wo using WO_DT_BITS difference from last frame. + +\*---------------------------------------------------------------------------*/ + +float decode_Wo_dt(int index, float prev_Wo) +{ + float Wo_min = TWO_PI/P_MAX; + float Wo_max = TWO_PI/P_MIN; + float step; + float Wo; + int mask; + + /* sign extend index */ + + //printf("DEC index: %d "); + if (index & (1 << (WO_DT_BITS-1))) { + mask = ~((1 << WO_DT_BITS) - 1); + index |= mask; + } + //printf("DEC mask: 0x%x index: %d \n", mask, index); + + step = (Wo_max - Wo_min)/WO_LEVELS; + Wo = prev_Wo + step*(index); + + /* bit errors can make us go out of range leading to all sorts of + probs like seg faults */ + + if (Wo > Wo_max) Wo = Wo_max; + if (Wo < Wo_min) Wo = Wo_min; + + return Wo; +} + +/*---------------------------------------------------------------------------*\ + FUNCTION....: speech_to_uq_lsps() AUTHOR......: David Rowe DATE CREATED: 22/8/2010 @@ -592,10 +1167,22 @@ float speech_to_uq_lsps(float lsp[], int i, roots; float Wn[M]; float R[LPC_MAX+1]; - float E; + float e, E; - for(i=0; i<M; i++) + e = 0.0; + for(i=0; i<M; i++) { Wn[i] = Sn[i]*w[i]; + e += Wn[i]*Wn[i]; + } + + /* trap 0 energy case as LPC analysis will fail */ + + if (e == 0.0) { + for(i=0; i<order; i++) + lsp[i] = (PI/order)*(float)i; + return 0.0; + } + autocorrelate(Wn, R, M, order); levinson_durbin(R, ak, order); @@ -603,15 +1190,17 @@ float speech_to_uq_lsps(float lsp[], for(i=0; i<=order; i++) E += ak[i]*R[i]; + /* 15 Hz BW expansion as I can't hear the difference and it may help + help occasional fails in the LSP root finding. Important to do this + after energy calculation to avoid -ve energy values. + */ + + for(i=0; i<=order; i++) + ak[i] *= powf(0.994,(float)i); + roots = lpc_to_lsp(ak, order, lsp, 5, LSP_DELTA1); if (roots != order) { - /* for some reason LSP roots could not be found */ - /* some alpha testers are reporting this condition */ - fprintf(stderr, "LSP roots not found!\nroots = %d\n", roots); - for(i=0; i<=order; i++) - fprintf(stderr, "a[%d] = %f\n", i, ak[i]); - - /* some benign LSP values we can use instead */ + /* if root finding fails use some benign LSP values instead */ for(i=0; i<order; i++) lsp[i] = (PI/order)*(float)i; } @@ -621,22 +1210,22 @@ float speech_to_uq_lsps(float lsp[], /*---------------------------------------------------------------------------*\ - FUNCTION....: encode_lsps() + FUNCTION....: encode_lsps_scalar() AUTHOR......: David Rowe DATE CREATED: 22/8/2010 - From a vector of unquantised (floating point) LSPs finds the quantised - LSP indexes. + Thirty-six bit sclar LSP quantiser. From a vector of unquantised + (floating point) LSPs finds the quantised LSP indexes. \*---------------------------------------------------------------------------*/ -void encode_lsps(int indexes[], float lsp[], int order) +void encode_lsps_scalar(int indexes[], float lsp[], int order) { int i,k,m; float wt[1]; float lsp_hz[LPC_MAX]; const float * cb; - float se = 0.0; + float se; /* convert from radians to Hz so we can use human readable frequencies */ @@ -644,7 +1233,7 @@ void encode_lsps(int indexes[], float lsp[], int order) for(i=0; i<order; i++) lsp_hz[i] = (4000.0/PI)*lsp[i]; - /* simple uniform scalar quantisers */ + /* scalar quantisers */ wt[0] = 1.0; for(i=0; i<order; i++) { @@ -657,7 +1246,7 @@ void encode_lsps(int indexes[], float lsp[], int order) /*---------------------------------------------------------------------------*\ - FUNCTION....: decode_lsps() + FUNCTION....: decode_lsps_scalar() AUTHOR......: David Rowe DATE CREATED: 22/8/2010 @@ -666,7 +1255,7 @@ void encode_lsps(int indexes[], float lsp[], int order) \*---------------------------------------------------------------------------*/ -void decode_lsps(float lsp[], int indexes[], int order) +void decode_lsps_scalar(float lsp[], int indexes[], int order) { int i,k; float lsp_hz[LPC_MAX]; @@ -684,6 +1273,273 @@ void decode_lsps(float lsp[], int indexes[], int order) lsp[i] = (PI/4000.0)*lsp_hz[i]; } + +#ifdef __EXPERIMENTAL__ + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_lsps_diff_freq_vq() + AUTHOR......: David Rowe + DATE CREATED: 15 November 2011 + + Twenty-five bit LSP quantiser. LSPs 1-4 are quantised with scalar + LSP differences (in frequency, i.e difference from the previous + LSP). LSPs 5-10 are quantised with a VQ trained generated using + vqtrainjnd.c + +\*---------------------------------------------------------------------------*/ + +void encode_lsps_diff_freq_vq(int indexes[], float lsp[], int order) +{ + int i,k,m; + float lsp_hz[LPC_MAX]; + float lsp__hz[LPC_MAX]; + float dlsp[LPC_MAX]; + float dlsp_[LPC_MAX]; + float wt[LPC_MAX]; + const float * cb; + float se; + + for(i=0; i<LPC_ORD; i++) { + wt[i] = 1.0; + } + + /* convert from radians to Hz so we can use human readable + frequencies */ + + for(i=0; i<order; i++) + lsp_hz[i] = (4000.0/PI)*lsp[i]; + + /* scalar quantisers for LSP differences 1..4 */ + + wt[0] = 1.0; + for(i=0; i<4; i++) { + if (i) + dlsp[i] = lsp_hz[i] - lsp__hz[i-1]; + else + dlsp[0] = lsp_hz[0]; + + k = lsp_cbd[i].k; + m = lsp_cbd[i].m; + cb = lsp_cbd[i].cb; + indexes[i] = quantise(cb, &dlsp[i], wt, k, m, &se); + dlsp_[i] = cb[indexes[i]*k]; + + if (i) + lsp__hz[i] = lsp__hz[i-1] + dlsp_[i]; + else + lsp__hz[0] = dlsp_[0]; + } + + /* VQ LSPs 5,6,7,8,9,10 */ + + k = lsp_cbjnd[4].k; + m = lsp_cbjnd[4].m; + cb = lsp_cbjnd[4].cb; + indexes[4] = quantise(cb, &lsp_hz[4], &wt[4], k, m, &se); +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_lsps_diff_freq_vq() + AUTHOR......: David Rowe + DATE CREATED: 15 Nov 2011 + + From a vector of quantised LSP indexes, returns the quantised + (floating point) LSPs. + +\*---------------------------------------------------------------------------*/ + +void decode_lsps_diff_freq_vq(float lsp_[], int indexes[], int order) +{ + int i,k,m; + float dlsp_[LPC_MAX]; + float lsp__hz[LPC_MAX]; + const float * cb; + + /* scalar LSP differences */ + + for(i=0; i<4; i++) { + cb = lsp_cbd[i].cb; + dlsp_[i] = cb[indexes[i]]; + if (i) + lsp__hz[i] = lsp__hz[i-1] + dlsp_[i]; + else + lsp__hz[0] = dlsp_[0]; + } + + /* VQ */ + + k = lsp_cbjnd[4].k; + m = lsp_cbjnd[4].m; + cb = lsp_cbjnd[4].cb; + for(i=4; i<order; i++) + lsp__hz[i] = cb[indexes[4]*k+i-4]; + + /* convert back to radians */ + + for(i=0; i<order; i++) + lsp_[i] = (PI/4000.0)*lsp__hz[i]; +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_lsps_diff_time() + AUTHOR......: David Rowe + DATE CREATED: 12 Sep 2012 + + Encode difference from preious frames's LSPs using + 3,3,2,2,2,2,1,1,1,1 scalar quantisers (18 bits total). + +\*---------------------------------------------------------------------------*/ + +void encode_lsps_diff_time(int indexes[], + float lsps[], + float lsps__prev[], + int order) +{ + int i,k,m; + float lsps_dt[LPC_ORD]; + float wt[LPC_MAX]; + const float * cb; + float se; + + /* Determine difference in time and convert from radians to Hz so + we can use human readable frequencies */ + + for(i=0; i<LPC_ORD; i++) { + lsps_dt[i] = (4000/PI)*(lsps[i] - lsps__prev[i]); + } + + /* scalar quantisers */ + + wt[0] = 1.0; + for(i=0; i<order; i++) { + k = lsp_cbdt[i].k; + m = lsp_cbdt[i].m; + cb = lsp_cbdt[i].cb; + indexes[i] = quantise(cb, &lsps_dt[i], wt, k, m, &se); + } + +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_lsps_diff_time() + AUTHOR......: David Rowe + DATE CREATED: 15 Nov 2011 + + From a quantised LSP indexes, returns the quantised + (floating point) LSPs. + +\*---------------------------------------------------------------------------*/ + +void decode_lsps_diff_time( + float lsps_[], + int indexes[], + float lsps__prev[], + int order) +{ + int i,k,m; + const float * cb; + + for(i=0; i<order; i++) + lsps_[i] = lsps__prev[i]; + + for(i=0; i<order; i++) { + k = lsp_cbdt[i].k; + cb = lsp_cbdt[i].cb; + lsps_[i] += (PI/4000.0)*cb[indexes[i]*k]; + } + +} +#endif + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_lsps_vq() + AUTHOR......: David Rowe + DATE CREATED: 15 Feb 2012 + + Multi-stage VQ LSP quantiser developed by Jean-Marc Valin. + +\*---------------------------------------------------------------------------*/ + +void encode_lsps_vq(int *indexes, float *x, float *xq, int ndim) +{ + int i, n1, n2, n3; + float err[LPC_ORD], err2[LPC_ORD], err3[LPC_ORD]; + float w[LPC_ORD], w2[LPC_ORD], w3[LPC_ORD]; + const float *codebook1 = lsp_cbjvm[0].cb; + const float *codebook2 = lsp_cbjvm[1].cb; + const float *codebook3 = lsp_cbjvm[2].cb; + + assert(ndim <= LPC_ORD); + + w[0] = MIN(x[0], x[1]-x[0]); + for (i=1;i<ndim-1;i++) + w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]); + w[ndim-1] = MIN(x[ndim-1]-x[ndim-2], PI-x[ndim-1]); + + compute_weights(x, w, ndim); + + n1 = find_nearest(codebook1, lsp_cbjvm[0].m, x, ndim); + + for (i=0;i<ndim;i++) + { + xq[i] = codebook1[ndim*n1+i]; + err[i] = x[i] - xq[i]; + } + for (i=0;i<ndim/2;i++) + { + err2[i] = err[2*i]; + err3[i] = err[2*i+1]; + w2[i] = w[2*i]; + w3[i] = w[2*i+1]; + } + n2 = find_nearest_weighted(codebook2, lsp_cbjvm[1].m, err2, w2, ndim/2); + n3 = find_nearest_weighted(codebook3, lsp_cbjvm[2].m, err3, w3, ndim/2); + + indexes[0] = n1; + indexes[1] = n2; + indexes[2] = n3; +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_lsps_vq() + AUTHOR......: David Rowe + DATE CREATED: 15 Feb 2012 + +\*---------------------------------------------------------------------------*/ + +void decode_lsps_vq(int *indexes, float *xq, int ndim) +{ + int i, n1, n2, n3; + const float *codebook1 = lsp_cbjvm[0].cb; + const float *codebook2 = lsp_cbjvm[1].cb; + const float *codebook3 = lsp_cbjvm[2].cb; + + n1 = indexes[0]; + n2 = indexes[1]; + n3 = indexes[2]; + + for (i=0;i<ndim;i++) + { + xq[i] = codebook1[ndim*n1+i]; + } + for (i=0;i<ndim/2;i++) + { + xq[2*i] += codebook2[ndim*n2/2+i]; + xq[2*i+1] += codebook3[ndim*n3/2+i]; + } +} + + /*---------------------------------------------------------------------------*\ FUNCTION....: bw_expand_lsps() @@ -692,20 +1548,44 @@ void decode_lsps(float lsp[], int indexes[], int order) Applies Bandwidth Expansion (BW) to a vector of LSPs. Prevents any two LSPs getting too close together after quantisation. We know - from experiment that LSP quantisation errors < 12.5Hz (25Hz setp + from experiment that LSP quantisation errors < 12.5Hz (25Hz step size) are inaudible so we use that as the minimum LSP separation. \*---------------------------------------------------------------------------*/ -void bw_expand_lsps(float lsp[], +void bw_expand_lsps(float lsp[], int order, float min_sep_low, float min_sep_high) +{ + int i; + + for(i=1; i<4; i++) { + + if ((lsp[i] - lsp[i-1]) < min_sep_low*(PI/4000.0)) + lsp[i] = lsp[i-1] + min_sep_low*(PI/4000.0); + + } + + /* As quantiser gaps increased, larger BW expansion was required + to prevent twinkly noises. This may need more experiment for + different quanstisers. + */ + + for(i=4; i<order; i++) { + if (lsp[i] - lsp[i-1] < min_sep_high*(PI/4000.0)) + lsp[i] = lsp[i-1] + min_sep_high*(PI/4000.0); + } +} + +void bw_expand_lsps2(float lsp[], int order ) { int i; - for(i=1; i<5; i++) { - if (lsp[i] - lsp[i-1] < PI*(12.5/4000.0)) - lsp[i] = lsp[i-1] + PI*(12.5/4000.0); + for(i=1; i<4; i++) { + + if ((lsp[i] - lsp[i-1]) < 100.0*(PI/4000.0)) + lsp[i] = lsp[i-1] + 100.0*(PI/4000.0); + } /* As quantiser gaps increased, larger BW expansion was required @@ -713,16 +1593,84 @@ void bw_expand_lsps(float lsp[], different quanstisers. */ - for(i=5; i<8; i++) { - if (lsp[i] - lsp[i-1] < PI*(25.0/4000.0)) - lsp[i] = lsp[i-1] + PI*(25.0/4000.0); + for(i=4; i<order; i++) { + if (lsp[i] - lsp[i-1] < 200.0*(PI/4000.0)) + lsp[i] = lsp[i-1] + 200.0*(PI/4000.0); } - for(i=8; i<order; i++) { - if (lsp[i] - lsp[i-1] < PI*(75.0/4000.0)) - lsp[i] = lsp[i-1] + PI*(75.0/4000.0); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: locate_lsps_jnd_steps() + AUTHOR......: David Rowe + DATE CREATED: 27/10/2011 + + Applies a form of Bandwidth Expansion (BW) to a vector of LSPs. + Listening tests have determined that "quantising" the position of + each LSP to the non-linear steps below introduces a "just noticable + difference" in the synthesised speech. + + This operation can be used before quantisation to limit the input + data to the quantiser to a number of discrete steps. + + This operation can also be used during quantisation as a form of + hysteresis in the calculation of quantiser error. For example if + the quantiser target of lsp1 is 500 Hz, candidate vectors with lsp1 + of 515 and 495 Hz sound effectively the same. + +\*---------------------------------------------------------------------------*/ + +void locate_lsps_jnd_steps(float lsps[], int order) +{ + int i; + float lsp_hz, step; + + assert(order == 10); + + /* quantise to 25Hz steps */ + + step = 25; + for(i=0; i<2; i++) { + lsp_hz = lsps[i]*4000.0/PI; + lsp_hz = floorf(lsp_hz/step + 0.5)*step; + lsps[i] = lsp_hz*PI/4000.0; + if (i) { + if (lsps[i] == lsps[i-1]) + lsps[i] += step*PI/4000.0; + + } + } + + /* quantise to 50Hz steps */ + + step = 50; + for(i=2; i<4; i++) { + lsp_hz = lsps[i]*4000.0/PI; + lsp_hz = floorf(lsp_hz/step + 0.5)*step; + lsps[i] = lsp_hz*PI/4000.0; + if (i) { + if (lsps[i] == lsps[i-1]) + lsps[i] += step*PI/4000.0; + + } + } + + /* quantise to 100Hz steps */ + + step = 100; + for(i=4; i<10; i++) { + lsp_hz = lsps[i]*4000.0/PI; + lsp_hz = floorf(lsp_hz/step + 0.5)*step; + lsps[i] = lsp_hz*PI/4000.0; + if (i) { + if (lsps[i] == lsps[i-1]) + lsps[i] += step*PI/4000.0; + + } } } + /*---------------------------------------------------------------------------*\ FUNCTION....: apply_lpc_correction() @@ -758,9 +1706,9 @@ int encode_energy(float e) float e_max = E_MAX_DB; float norm; - e = 10.0*log10(e); + e = 10.0*log10f(e); norm = (e - e_min)/(e_max - e_min); - index = floor(E_LEVELS * norm + 0.5); + index = floorf(E_LEVELS * norm + 0.5); if (index < 0 ) index = 0; if (index > (E_LEVELS-1)) index = E_LEVELS-1; @@ -773,7 +1721,7 @@ int encode_energy(float e) AUTHOR......: David Rowe DATE CREATED: 22/8/2010 - Decodes energy using a WO_BITS quantiser. + Decodes energy using a E_LEVELS quantiser. \*---------------------------------------------------------------------------*/ @@ -786,39 +1734,12 @@ float decode_energy(int index) step = (e_max - e_min)/E_LEVELS; e = e_min + step*(index); - e = pow(10.0,e/10.0); + e = powf(10.0,e/10.0); return e; } -/*---------------------------------------------------------------------------*\ - - FUNCTION....: encode_amplitudes() - AUTHOR......: David Rowe - DATE CREATED: 22/8/2010 - - Time domain LPC is used model the amplitudes which are then - converted to LSPs and quantised. So we don't actually encode the - amplitudes directly, rather we derive an equivalent representation - from the time domain speech. - -\*---------------------------------------------------------------------------*/ - -void encode_amplitudes(int lsp_indexes[], - int *energy_index, - MODEL *model, - float Sn[], - float w[]) -{ - float lsps[LPC_ORD]; - float ak[LPC_ORD+1]; - float e; - - e = speech_to_uq_lsps(lsps, ak, Sn, w, LPC_ORD); - encode_lsps(lsp_indexes, lsps, LPC_ORD); - *energy_index = encode_energy(e); -} - +#ifdef NOT_USED /*---------------------------------------------------------------------------*\ FUNCTION....: decode_amplitudes() @@ -830,7 +1751,8 @@ void encode_amplitudes(int lsp_indexes[], \*---------------------------------------------------------------------------*/ -float decode_amplitudes(MODEL *model, +float decode_amplitudes(kiss_fft_cfg fft_fwd_cfg, + MODEL *model, float ak[], int lsp_indexes[], int energy_index, @@ -840,12 +1762,209 @@ float decode_amplitudes(MODEL *model, { float snr; - decode_lsps(lsps, lsp_indexes, LPC_ORD); + decode_lsps_scalar(lsps, lsp_indexes, LPC_ORD); bw_expand_lsps(lsps, LPC_ORD); lsp_to_lpc(lsps, ak, LPC_ORD); *e = decode_energy(energy_index); - aks_to_M2(ak, LPC_ORD, model, *e, &snr, 1); + aks_to_M2(ak, LPC_ORD, model, *e, &snr, 1, 0, 0, 1); apply_lpc_correction(model); return snr; } +#endif + +static float ge_coeff[2] = {0.8, 0.9}; + +void compute_weights2(const float *x, const float *xp, float *w, int ndim) +{ + w[0] = 30; + w[1] = 1; + if (x[1]<0) + { + w[0] *= .6; + w[1] *= .3; + } + if (x[1]<-10) + { + w[0] *= .3; + w[1] *= .3; + } + /* Higher weight if pitch is stable */ + if (fabsf(x[0]-xp[0])<.2) + { + w[0] *= 2; + w[1] *= 1.5; + } else if (fabsf(x[0]-xp[0])>.5) /* Lower if not stable */ + { + w[0] *= .5; + } + + /* Lower weight for low energy */ + if (x[1] < xp[1]-10) + { + w[1] *= .5; + } + if (x[1] < xp[1]-20) + { + w[1] *= .5; + } + + //w[0] = 30; + //w[1] = 1; + + /* Square the weights because it's applied on the squared error */ + w[0] *= w[0]; + w[1] *= w[1]; + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: quantise_WoE() + AUTHOR......: Jean-Marc Valin & David Rowe + DATE CREATED: 29 Feb 2012 + + Experimental joint Wo and LPC energy vector quantiser developed by + Jean-Marc Valin. Exploits correlations between the difference in + the log pitch and log energy from frame to frame. For example + both the pitch and energy tend to only change by small amounts + during voiced speech, however it is important that these changes be + coded carefully. During unvoiced speech they both change a lot but + the ear is less sensitve to errors so coarser quantisation is OK. + + The ear is sensitive to log energy and loq pitch so we quantise in + these domains. That way the error measure used to quantise the + values is close to way the ear senses errors. + + See http://jmspeex.livejournal.com/10446.html + +\*---------------------------------------------------------------------------*/ + +void quantise_WoE(MODEL *model, float *e, float xq[]) +{ + int i, n1; + float x[2]; + float err[2]; + float w[2]; + const float *codebook1 = ge_cb[0].cb; + int nb_entries = ge_cb[0].m; + int ndim = ge_cb[0].k; + float Wo_min = TWO_PI/P_MAX; + float Wo_max = TWO_PI/P_MIN; + + x[0] = log10f((model->Wo/PI)*4000.0/50.0)/log10f(2); + x[1] = 10.0*log10f(1e-4 + *e); + + compute_weights2(x, xq, w, ndim); + for (i=0;i<ndim;i++) + err[i] = x[i]-ge_coeff[i]*xq[i]; + n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim); + + for (i=0;i<ndim;i++) + { + xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i]; + err[i] -= codebook1[ndim*n1+i]; + } + + /* + x = log2(4000*Wo/(PI*50)); + 2^x = 4000*Wo/(PI*50) + Wo = (2^x)*(PI*50)/4000; + */ + + model->Wo = powf(2.0, xq[0])*(PI*50.0)/4000.0; + + /* bit errors can make us go out of range leading to all sorts of + probs like seg faults */ + + if (model->Wo > Wo_max) model->Wo = Wo_max; + if (model->Wo < Wo_min) model->Wo = Wo_min; + + model->L = PI/model->Wo; /* if we quantise Wo re-compute L */ + + *e = powf(10.0, xq[1]/10.0); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_WoE() + AUTHOR......: Jean-Marc Valin & David Rowe + DATE CREATED: 11 May 2012 + + Joint Wo and LPC energy vector quantiser developed my Jean-Marc + Valin. Returns index, and updated states xq[]. + +\*---------------------------------------------------------------------------*/ + +int encode_WoE(MODEL *model, float e, float xq[]) +{ + int i, n1; + float x[2]; + float err[2]; + float w[2]; + const float *codebook1 = ge_cb[0].cb; + int nb_entries = ge_cb[0].m; + int ndim = ge_cb[0].k; + + assert((1<<WO_E_BITS) == nb_entries); + + if (e < 0.0) e = 0; /* occasional small negative energies due LPC round off I guess */ + + x[0] = log10f((model->Wo/PI)*4000.0/50.0)/log10f(2); + x[1] = 10.0*log10f(1e-4 + e); + + compute_weights2(x, xq, w, ndim); + for (i=0;i<ndim;i++) + err[i] = x[i]-ge_coeff[i]*xq[i]; + n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim); + + for (i=0;i<ndim;i++) + { + xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i]; + err[i] -= codebook1[ndim*n1+i]; + } + + //printf("enc: %f %f (%f)(%f) \n", xq[0], xq[1], e, 10.0*log10(1e-4 + e)); + return n1; +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_WoE() + AUTHOR......: Jean-Marc Valin & David Rowe + DATE CREATED: 11 May 2012 + + Joint Wo and LPC energy vector quantiser developed my Jean-Marc + Valin. Given index and states xq[], returns Wo & E, and updates + states xq[]. + +\*---------------------------------------------------------------------------*/ + +void decode_WoE(MODEL *model, float *e, float xq[], int n1) +{ + int i; + const float *codebook1 = ge_cb[0].cb; + int ndim = ge_cb[0].k; + float Wo_min = TWO_PI/P_MAX; + float Wo_max = TWO_PI/P_MIN; + + for (i=0;i<ndim;i++) + { + xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i]; + } + + //printf("dec: %f %f\n", xq[0], xq[1]); + model->Wo = powf(2.0, xq[0])*(PI*50.0)/4000.0; + + /* bit errors can make us go out of range leading to all sorts of + probs like seg faults */ + + if (model->Wo > Wo_max) model->Wo = Wo_max; + if (model->Wo < Wo_min) model->Wo = Wo_min; + + model->L = PI/model->Wo; /* if we quantise Wo re-compute L */ + + *e = powf(10.0, xq[1]/10.0); +} + diff --git a/gr-vocoder/lib/codec2/quantise.h b/gr-vocoder/lib/codec2/quantise.h index 42b05f43bd..0932d9d1bd 100644 --- a/gr-vocoder/lib/codec2/quantise.h +++ b/gr-vocoder/lib/codec2/quantise.h @@ -26,47 +26,82 @@ #ifndef __QUANTISE__ #define __QUANTISE__ -#define WO_BITS 7 -#define WO_LEVELS (1<<WO_BITS) -#define E_BITS 5 -#define E_LEVELS (1<<E_BITS) -#define E_MIN_DB -10.0 -#define E_MAX_DB 40.0 +#include "kiss_fft.h" + +#define WO_BITS 7 +#define WO_LEVELS (1<<WO_BITS) +#define WO_DT_BITS 3 + +#define E_BITS 5 +#define E_LEVELS (1<<E_BITS) +#define E_MIN_DB -10.0 +#define E_MAX_DB 40.0 + +#define LSP_SCALAR_INDEXES 10 +#define LSPD_SCALAR_INDEXES 10 +#define LSP_PRED_VQ_INDEXES 3 +#define LSP_DIFF_FREQ_INDEXES 5 +#define LSP_DIFF_TIME_BITS 7 + +#define LSPDT_ALL 0 +#define LSPDT_LOW 1 +#define LSPDT_HIGH 2 + +#define WO_E_BITS 8 + +#define LPCPF_GAMMA 0.5 +#define LPCPF_BETA 0.2 void quantise_init(); float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order, int lsp,float ak[]); -void aks_to_M2(float ak[], int order, MODEL *model, float E, float *snr, - int dump); +void aks_to_M2(kiss_fft_cfg fft_fwd_cfg, float ak[], int order, MODEL *model, + float E, float *snr, int dump, int sim_pf, + int pf, int bass_boost, float beta, float gamma); int encode_Wo(float Wo); float decode_Wo(int index); - -void encode_lsps(int indexes[], float lsp[], int order); -void decode_lsps(float lsp[], int indexes[], int order); -void lspd_quantise(float lsp[], float lsp_[], int order); -void lspdvq_quantise(float lsp[], float lsp_[], int order); +int encode_Wo_dt(float Wo, float prev_Wo); +float decode_Wo_dt(int index, float prev_Wo); +void encode_lsps_scalar(int indexes[], float lsp[], int order); +void decode_lsps_scalar(float lsp[], int indexes[], int order); +void encode_lspds_scalar(int indexes[], float lsp[], int order); +void decode_lspds_scalar(float lsp[], int indexes[], int order); +void encode_lsps_diff_freq_vq(int indexes[], float lsp[], int order); +void decode_lsps_diff_freq_vq(float lsp_[], int indexes[], int order); +void encode_lsps_diff_time(int indexes[], + float lsp[], + float lsp__prev[], + int order); +void decode_lsps_diff_time(float lsp_[], + int indexes[], + float lsp__prev[], + int order); + +void encode_lsps_vq(int *indexes, float *x, float *xq, int ndim); +void decode_lsps_vq(int *indexes, float *xq, int ndim); + +long quantise(const float * cb, float vec[], float w[], int k, int m, float *se); +void lspvq_quantise(float lsp[], float lsp_[], int order); +void lspjnd_quantise(float lsp[], float lsp_[], int order); +void lspdt_quantise(float lsps[], float lsps_[], float lsps__prev[], int mode); +void lspjvm_quantise(float lsps[], float lsps_[], int order); +void lspanssi_quantise(float lsps[], float lsps_[], int order, int mbest_entries); + +void quantise_WoE(MODEL *model, float *e, float xq[]); +int encode_WoE(MODEL *model, float e, float xq[]); +void decode_WoE(MODEL *model, float *e, float xq[], int n1); int encode_energy(float e); float decode_energy(int index); -void encode_amplitudes(int lsp_indexes[], - int *energy_index, - MODEL *model, - float Sn[], - float w[]); - -float decode_amplitudes(MODEL *model, - float ak[], - int lsp_indexes[], - int energy_index, - float lsps[], - float *e); - void pack(unsigned char * bits, unsigned int *nbit, int index, unsigned int index_bits); int unpack(const unsigned char * bits, unsigned int *nbit, unsigned int index_bits); int lsp_bits(int i); +int lspd_bits(int i); +int lspdt_bits(int i); +int lsp_pred_vq_bits(int i); void apply_lpc_correction(MODEL *model); float speech_to_uq_lsps(float lsp[], @@ -75,9 +110,15 @@ float speech_to_uq_lsps(float lsp[], float w[], int order ); -void bw_expand_lsps(float lsp[], - int order - ); -void decode_lsps(float lsp[], int indexes[], int order); +int check_lsp_order(float lsp[], int lpc_order); +void bw_expand_lsps(float lsp[], int order, float min_sep_low, float min_sep_high); +void bw_expand_lsps2(float lsp[], int order); +void locate_lsps_jnd_steps(float lsp[], int order); +float decode_amplitudes(MODEL *model, + float ak[], + int lsp_indexes[], + int energy_index, + float lsps[], + float *e); #endif diff --git a/gr-vocoder/lib/codec2/rn.h b/gr-vocoder/lib/codec2/rn.h new file mode 100644 index 0000000000..934f458406 --- /dev/null +++ b/gr-vocoder/lib/codec2/rn.h @@ -0,0 +1,964 @@ +/* Generated by rn_file() Octave function */ + +const float gt_alpha5_root[]={ + 2.86997e-05, + 2.2286e-05, + 1.82863e-05, + 1.42303e-05, + 1.04905e-05, + 6.70859e-06, + 3.05918e-06, + -6.22187e-07, + -4.22748e-06, + -7.85603e-06, + -1.14317e-05, + -1.50227e-05, + -1.85712e-05, + -2.21275e-05, + -2.56455e-05, + -2.91642e-05, + -3.26453e-05, + -3.61199e-05, + -3.95556e-05, + -4.29778e-05, + -4.63581e-05, + -4.97179e-05, + -5.3032e-05, + -5.63184e-05, + -5.95548e-05, + -6.27565e-05, + -6.59032e-05, + -6.90085e-05, + -7.20538e-05, + -7.50509e-05, + -7.7983e-05, + -8.08605e-05, + -8.36678e-05, + -8.64141e-05, + -8.9085e-05, + -9.16888e-05, + -9.42119e-05, + -9.66619e-05, + -9.9026e-05, + -0.000101311, + -0.000103505, + -0.000105614, + -0.000107627, + -0.00010955, + -0.000111372, + -0.000113099, + -0.00011472, + -0.000116241, + -0.000117652, + -0.000118959, + -0.000120152, + -0.000121235, + -0.000122201, + -0.000123053, + -0.000123784, + -0.000124397, + -0.000124884, + -0.00012525, + -0.000125487, + -0.000125598, + -0.000125578, + -0.000125428, + -0.000125145, + -0.000124729, + -0.000124185, + -0.000123518, + -0.000122709, + -0.000121766, + -0.000120685, + -0.000119471, + -0.000118119, + -0.000116633, + -0.000115009, + -0.000113251, + -0.000111356, + -0.000109326, + -0.00010716, + -0.00010486, + -0.000102424, + -9.98553e-05, + -9.71528e-05, + -9.43199e-05, + -9.13551e-05, + -8.82623e-05, + -8.50404e-05, + -8.16936e-05, + -7.82211e-05, + -7.46271e-05, + -7.09109e-05, + -6.70773e-05, + -6.31256e-05, + -5.90607e-05, + -5.48823e-05, + -5.05954e-05, + -4.62001e-05, + -4.17016e-05, + -3.71002e-05, + -3.24015e-05, + -2.7606e-05, + -2.27195e-05, + -1.77428e-05, + -1.2682e-05, + -7.53795e-06, + -2.31702e-06, + 2.97965e-06, + 8.34567e-06, + 1.37796e-05, + 1.9275e-05, + 2.483e-05, + 3.04382e-05, + 3.60975e-05, + 4.18011e-05, + 4.75467e-05, + 5.33273e-05, + 5.91403e-05, + 6.49787e-05, + 7.08393e-05, + 7.67152e-05, + 8.26029e-05, + 8.84957e-05, + 9.43895e-05, + 0.000100278, + 0.000106157, + 0.00011202, + 0.000117864, + 0.000123681, + 0.000129468, + 0.000135218, + 0.000140929, + 0.000146583, + 0.000152183, + 0.000157725, + 0.000163202, + 0.000168608, + 0.000173938, + 0.000179183, + 0.00018434, + 0.0001894, + 0.00019436, + 0.000199211, + 0.000203949, + 0.000208568, + 0.000213063, + 0.000217426, + 0.000221654, + 0.00022574, + 0.000229678, + 0.000233463, + 0.000237089, + 0.000240551, + 0.000243843, + 0.000246959, + 0.000249895, + 0.000252644, + 0.000255202, + 0.000257562, + 0.000259721, + 0.000261672, + 0.000263411, + 0.000264933, + 0.000266234, + 0.000267308, + 0.000268152, + 0.00026876, + 0.000269128, + 0.000269253, + 0.000269129, + 0.000268754, + 0.000268123, + 0.000267232, + 0.000266079, + 0.000264658, + 0.000262968, + 0.000261006, + 0.000258767, + 0.000256251, + 0.000253453, + 0.000250373, + 0.000247007, + 0.000243354, + 0.000239412, + 0.00023518, + 0.000230655, + 0.000225837, + 0.000220723, + 0.000215314, + 0.000209608, + 0.000203605, + 0.000197304, + 0.000190706, + 0.000183812, + 0.000176621, + 0.000169145, + 0.000161363, + 0.000153275, + 0.000144895, + 0.000136224, + 0.000127266, + 0.00011802, + 0.000108491, + 9.8679e-05, + 8.85877e-05, + 7.82196e-05, + 6.7577e-05, + 5.66636e-05, + 4.54822e-05, + 3.40369e-05, + 2.23311e-05, + 1.03695e-05, + -1.844e-06, + -1.43041e-05, + -2.70061e-05, + -3.99444e-05, + -5.31139e-05, + -6.65082e-05, + -8.01218e-05, + -9.39481e-05, + -0.000107981, + -0.000122213, + -0.000136638, + -0.000151248, + -0.000166036, + -0.000180995, + -0.000196115, + -0.00021139, + -0.000226811, + -0.000242369, + -0.000258056, + -0.000273861, + -0.000289776, + -0.000305792, + -0.000321898, + -0.000338084, + -0.000354342, + -0.00037066, + -0.000387027, + -0.000403434, + -0.00041987, + -0.000436324, + -0.000452784, + -0.00046924, + -0.00048568, + -0.000502091, + -0.000518464, + -0.000534785, + -0.000551043, + -0.000567225, + -0.000583319, + -0.000599314, + -0.000615196, + -0.000630955, + -0.000646575, + -0.000662049, + -0.000677361, + -0.000692506, + -0.000707464, + -0.00072229, + -0.000736922, + -0.000751266, + -0.000765372, + -0.000779217, + -0.000792798, + -0.000806094, + -0.000819098, + -0.000831793, + -0.000844168, + -0.000856207, + -0.000867898, + -0.000879227, + -0.00089018, + -0.000900744, + -0.000910906, + -0.000920652, + -0.00092997, + -0.000938844, + -0.000947263, + -0.000955214, + -0.000962682, + -0.000969654, + -0.000976119, + -0.000982062, + -0.00098747, + -0.000992332, + -0.000996634, + -0.00100036, + -0.00100351, + -0.00100606, + -0.001008, + -0.00100932, + -0.00101, + -0.00101005, + -0.00100943, + -0.00100816, + -0.0010062, + -0.00100356, + -0.00100021, + -0.000996162, + -0.000991392, + -0.000985892, + -0.000979654, + -0.000972668, + -0.000964925, + -0.000956415, + -0.000947131, + -0.000937065, + -0.000926208, + -0.000914552, + -0.00090209, + -0.000888816, + -0.000874721, + -0.0008598, + -0.000844046, + -0.000827453, + -0.000810015, + -0.000791726, + -0.000772581, + -0.000752576, + -0.000731704, + -0.000709965, + -0.00068735, + -0.000663865, + -0.000639509, + -0.000614269, + -0.000588146, + -0.000561139, + -0.000533246, + -0.000504468, + -0.000474802, + -0.000444251, + -0.000412813, + -0.00038049, + -0.000347281, + -0.000313189, + -0.000278215, + -0.000242361, + -0.000205629, + -0.000168024, + -0.000129546, + -9.02024e-05, + -4.99954e-05, + -8.93026e-06, + 3.2988e-05, + 7.57537e-05, + 0.000119361, + 0.000163804, + 0.000209075, + 0.000255167, + 0.000302074, + 0.000349786, + 0.000398297, + 0.000447596, + 0.000497676, + 0.000548526, + 0.000600136, + 0.000652497, + 0.000705598, + 0.000759427, + 0.000813972, + 0.000869223, + 0.000925166, + 0.000981789, + 0.00103908, + 0.00109702, + 0.00115561, + 0.00121482, + 0.00127464, + 0.00133505, + 0.00139605, + 0.00145762, + 0.00151973, + 0.00158238, + 0.00164555, + 0.00170922, + 0.00177337, + 0.00183799, + 0.00190305, + 0.00196854, + 0.00203445, + 0.00210075, + 0.00216742, + 0.00223445, + 0.00230181, + 0.00236949, + 0.00243747, + 0.00250572, + 0.00257423, + 0.00264296, + 0.00271192, + 0.00278107, + 0.00285039, + 0.00291986, + 0.00298947, + 0.00305918, + 0.00312898, + 0.00319884, + 0.00326874, + 0.00333866, + 0.00340857, + 0.00347846, + 0.00354831, + 0.00361808, + 0.00368775, + 0.00375731, + 0.00382673, + 0.00389599, + 0.00396506, + 0.00403393, + 0.00410256, + 0.00417094, + 0.00423904, + 0.00430684, + 0.00437431, + 0.00444144, + 0.0045082, + 0.00457457, + 0.00464052, + 0.00470603, + 0.00477108, + 0.00483565, + 0.00489972, + 0.00496325, + 0.00502623, + 0.00508865, + 0.00515046, + 0.00521166, + 0.00527223, + 0.00533213, + 0.00539135, + 0.00544987, + 0.00550766, + 0.00556472, + 0.005621, + 0.00567651, + 0.00573121, + 0.00578508, + 0.00583811, + 0.00589028, + 0.00594157, + 0.00599196, + 0.00604143, + 0.00608996, + 0.00613754, + 0.00618415, + 0.00622977, + 0.00627439, + 0.00631798, + 0.00636054, + 0.00640204, + 0.0064425, + 0.00648186, + 0.00652009, + 0.00655722, + 0.00659322, + 0.00662808, + 0.00666179, + 0.00669433, + 0.00672571, + 0.00675589, + 0.00678488, + 0.00681266, + 0.00683921, + 0.00686454, + 0.00688863, + 0.00691147, + 0.00693305, + 0.00695336, + 0.0069724, + 0.00699016, + 0.00700663, + 0.00702181, + 0.00703569, + 0.00704826, + 0.00705952, + 0.00706947, + 0.00707809, + 0.0070854, + 0.00709138, + 0.00709604, + 0.00709937, + 0.00710136, + 0.00710203, + 0.00710136, + 0.00709937, + 0.00709604, + 0.00709138, + 0.0070854, + 0.00707809, + 0.00706947, + 0.00705952, + 0.00704826, + 0.00703569, + 0.00702181, + 0.00700663, + 0.00699016, + 0.0069724, + 0.00695336, + 0.00693305, + 0.00691147, + 0.00688863, + 0.00686454, + 0.00683921, + 0.00681266, + 0.00678488, + 0.00675589, + 0.00672571, + 0.00669433, + 0.00666179, + 0.00662808, + 0.00659322, + 0.00655722, + 0.00652009, + 0.00648186, + 0.0064425, + 0.00640204, + 0.00636054, + 0.00631798, + 0.00627439, + 0.00622977, + 0.00618415, + 0.00613754, + 0.00608996, + 0.00604143, + 0.00599196, + 0.00594157, + 0.00589028, + 0.00583811, + 0.00578508, + 0.00573121, + 0.00567651, + 0.005621, + 0.00556472, + 0.00550766, + 0.00544987, + 0.00539135, + 0.00533213, + 0.00527223, + 0.00521166, + 0.00515046, + 0.00508865, + 0.00502623, + 0.00496325, + 0.00489972, + 0.00483565, + 0.00477108, + 0.00470603, + 0.00464052, + 0.00457457, + 0.0045082, + 0.00444144, + 0.00437431, + 0.00430684, + 0.00423904, + 0.00417094, + 0.00410256, + 0.00403393, + 0.00396506, + 0.00389599, + 0.00382673, + 0.00375731, + 0.00368775, + 0.00361808, + 0.00354831, + 0.00347846, + 0.00340857, + 0.00333866, + 0.00326874, + 0.00319884, + 0.00312898, + 0.00305918, + 0.00298947, + 0.00291986, + 0.00285039, + 0.00278107, + 0.00271192, + 0.00264296, + 0.00257423, + 0.00250572, + 0.00243747, + 0.00236949, + 0.00230181, + 0.00223445, + 0.00216742, + 0.00210075, + 0.00203445, + 0.00196854, + 0.00190305, + 0.00183799, + 0.00177337, + 0.00170922, + 0.00164555, + 0.00158238, + 0.00151973, + 0.00145762, + 0.00139605, + 0.00133505, + 0.00127464, + 0.00121482, + 0.00115561, + 0.00109702, + 0.00103908, + 0.000981789, + 0.000925166, + 0.000869223, + 0.000813972, + 0.000759427, + 0.000705598, + 0.000652497, + 0.000600136, + 0.000548526, + 0.000497676, + 0.000447596, + 0.000398297, + 0.000349786, + 0.000302074, + 0.000255167, + 0.000209075, + 0.000163804, + 0.000119361, + 7.57537e-05, + 3.2988e-05, + -8.93026e-06, + -4.99954e-05, + -9.02024e-05, + -0.000129546, + -0.000168024, + -0.000205629, + -0.000242361, + -0.000278215, + -0.000313189, + -0.000347281, + -0.00038049, + -0.000412813, + -0.000444251, + -0.000474802, + -0.000504468, + -0.000533246, + -0.000561139, + -0.000588146, + -0.000614269, + -0.000639509, + -0.000663865, + -0.00068735, + -0.000709965, + -0.000731704, + -0.000752576, + -0.000772581, + -0.000791726, + -0.000810015, + -0.000827453, + -0.000844046, + -0.0008598, + -0.000874721, + -0.000888816, + -0.00090209, + -0.000914552, + -0.000926208, + -0.000937065, + -0.000947131, + -0.000956415, + -0.000964925, + -0.000972668, + -0.000979654, + -0.000985892, + -0.000991392, + -0.000996162, + -0.00100021, + -0.00100356, + -0.0010062, + -0.00100816, + -0.00100943, + -0.00101005, + -0.00101, + -0.00100932, + -0.001008, + -0.00100606, + -0.00100351, + -0.00100036, + -0.000996634, + -0.000992332, + -0.00098747, + -0.000982062, + -0.000976119, + -0.000969654, + -0.000962682, + -0.000955214, + -0.000947263, + -0.000938844, + -0.00092997, + -0.000920652, + -0.000910906, + -0.000900744, + -0.00089018, + -0.000879227, + -0.000867898, + -0.000856207, + -0.000844168, + -0.000831793, + -0.000819098, + -0.000806094, + -0.000792798, + -0.000779217, + -0.000765372, + -0.000751266, + -0.000736922, + -0.00072229, + -0.000707464, + -0.000692506, + -0.000677361, + -0.000662049, + -0.000646575, + -0.000630955, + -0.000615196, + -0.000599314, + -0.000583319, + -0.000567225, + -0.000551043, + -0.000534785, + -0.000518464, + -0.000502091, + -0.00048568, + -0.00046924, + -0.000452784, + -0.000436324, + -0.00041987, + -0.000403434, + -0.000387027, + -0.00037066, + -0.000354342, + -0.000338084, + -0.000321898, + -0.000305792, + -0.000289776, + -0.000273861, + -0.000258056, + -0.000242369, + -0.000226811, + -0.00021139, + -0.000196115, + -0.000180995, + -0.000166036, + -0.000151248, + -0.000136638, + -0.000122213, + -0.000107981, + -9.39481e-05, + -8.01218e-05, + -6.65082e-05, + -5.31139e-05, + -3.99444e-05, + -2.70061e-05, + -1.43041e-05, + -1.844e-06, + 1.03695e-05, + 2.23311e-05, + 3.40369e-05, + 4.54822e-05, + 5.66636e-05, + 6.7577e-05, + 7.82196e-05, + 8.85877e-05, + 9.8679e-05, + 0.000108491, + 0.00011802, + 0.000127266, + 0.000136224, + 0.000144895, + 0.000153275, + 0.000161363, + 0.000169145, + 0.000176621, + 0.000183812, + 0.000190706, + 0.000197304, + 0.000203605, + 0.000209608, + 0.000215314, + 0.000220723, + 0.000225837, + 0.000230655, + 0.00023518, + 0.000239412, + 0.000243354, + 0.000247007, + 0.000250373, + 0.000253453, + 0.000256251, + 0.000258767, + 0.000261006, + 0.000262968, + 0.000264658, + 0.000266079, + 0.000267232, + 0.000268123, + 0.000268754, + 0.000269129, + 0.000269253, + 0.000269128, + 0.00026876, + 0.000268152, + 0.000267308, + 0.000266234, + 0.000264933, + 0.000263411, + 0.000261672, + 0.000259721, + 0.000257562, + 0.000255202, + 0.000252644, + 0.000249895, + 0.000246959, + 0.000243843, + 0.000240551, + 0.000237089, + 0.000233463, + 0.000229678, + 0.00022574, + 0.000221654, + 0.000217426, + 0.000213063, + 0.000208568, + 0.000203949, + 0.000199211, + 0.00019436, + 0.0001894, + 0.00018434, + 0.000179183, + 0.000173938, + 0.000168608, + 0.000163202, + 0.000157725, + 0.000152183, + 0.000146583, + 0.000140929, + 0.000135218, + 0.000129468, + 0.000123681, + 0.000117864, + 0.00011202, + 0.000106157, + 0.000100278, + 9.43895e-05, + 8.84957e-05, + 8.26029e-05, + 7.67152e-05, + 7.08393e-05, + 6.49787e-05, + 5.91403e-05, + 5.33273e-05, + 4.75467e-05, + 4.18011e-05, + 3.60975e-05, + 3.04382e-05, + 2.483e-05, + 1.9275e-05, + 1.37796e-05, + 8.34567e-06, + 2.97965e-06, + -2.31702e-06, + -7.53795e-06, + -1.2682e-05, + -1.77428e-05, + -2.27195e-05, + -2.7606e-05, + -3.24015e-05, + -3.71002e-05, + -4.17016e-05, + -4.62001e-05, + -5.05954e-05, + -5.48823e-05, + -5.90607e-05, + -6.31256e-05, + -6.70773e-05, + -7.09109e-05, + -7.46271e-05, + -7.82211e-05, + -8.16936e-05, + -8.50404e-05, + -8.82623e-05, + -9.13551e-05, + -9.43199e-05, + -9.71528e-05, + -9.98553e-05, + -0.000102424, + -0.00010486, + -0.00010716, + -0.000109326, + -0.000111356, + -0.000113251, + -0.000115009, + -0.000116633, + -0.000118119, + -0.000119471, + -0.000120685, + -0.000121766, + -0.000122709, + -0.000123518, + -0.000124185, + -0.000124729, + -0.000125145, + -0.000125428, + -0.000125578, + -0.000125598, + -0.000125487, + -0.00012525, + -0.000124884, + -0.000124397, + -0.000123784, + -0.000123053, + -0.000122201, + -0.000121235, + -0.000120152, + -0.000118959, + -0.000117652, + -0.000116241, + -0.00011472, + -0.000113099, + -0.000111372, + -0.00010955, + -0.000107627, + -0.000105614, + -0.000103505, + -0.000101311, + -9.9026e-05, + -9.66619e-05, + -9.42119e-05, + -9.16888e-05, + -8.9085e-05, + -8.64141e-05, + -8.36678e-05, + -8.08605e-05, + -7.7983e-05, + -7.50509e-05, + -7.20538e-05, + -6.90085e-05, + -6.59032e-05, + -6.27565e-05, + -5.95548e-05, + -5.63184e-05, + -5.3032e-05, + -4.97179e-05, + -4.63581e-05, + -4.29778e-05, + -3.95556e-05, + -3.61199e-05, + -3.26453e-05, + -2.91642e-05, + -2.56455e-05, + -2.21275e-05, + -1.85712e-05, + -1.50227e-05, + -1.14317e-05, + -7.85603e-06, + -4.22748e-06, + -6.22187e-07, + 3.05918e-06, + 6.70859e-06, + 1.04905e-05, + 1.42303e-05, + 1.82863e-05, + 2.2286e-05 +}; diff --git a/gr-vocoder/lib/codec2/sim.sh b/gr-vocoder/lib/codec2/sim.sh deleted file mode 100755 index 10152d979a..0000000000 --- a/gr-vocoder/lib/codec2/sim.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# sim.sh -# David Rowe 10 Sep 2009 - -# Process a source file using the codec 2 simulation. An output -# speech file is generated for each major processing step, from the -# unquantised siusoidal model to fully quantised. This way we can -# listen to the effect of each processing step. Use listensim.sh to -# test the output files. - -../src/c2sim ../raw/$1.raw -o $1_uq.raw -../src/c2sim ../raw/$1.raw --phase0 -o $1_phase0.raw --postfilter -../src/c2sim ../raw/$1.raw --lpc 10 -o $1_lpc10.raw --postfilter -../src/c2sim ../raw/$1.raw --phase0 --lpc 10 -o $1_phase0_lpc10.raw --postfilter -../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --dec -o $1_phase0_lpc10_dec.raw --postfilter -../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp --dec -o $1_phase0_lsp_dec.raw --postfilter - -#../src/c2sim ../raw/$1.raw --lpc 10 --lsp -o $1_lsp.raw -#../src/c2sim ../raw/$1.raw --phase0 --lpc 10 -o $1_phase0_lpc10.raw --postfilter -#../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp -o $1_phase0_lsp.raw --postfilter -#../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp -o $1_phase0_lsp_dec.raw --postfilter --dec - diff --git a/gr-vocoder/lib/codec2/sine.c b/gr-vocoder/lib/codec2/sine.c index b30f9abad6..be4df00a6d 100644 --- a/gr-vocoder/lib/codec2/sine.c +++ b/gr-vocoder/lib/codec2/sine.c @@ -37,7 +37,7 @@ #include "defines.h" #include "sine.h" -#include "fft.h" +#include "kiss_fft.h" #define HPF_BETA 0.125 @@ -66,9 +66,10 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, \*---------------------------------------------------------------------------*/ -void make_analysis_window(float w[],COMP W[]) +void make_analysis_window(kiss_fft_cfg fft_fwd_cfg, float w[], COMP W[]) { float m; + COMP wshift[FFT_ENC]; COMP temp; int i,j; @@ -87,7 +88,7 @@ void make_analysis_window(float w[],COMP W[]) for(i=0; i<M/2-NW/2; i++) w[i] = 0.0; for(i=M/2-NW/2,j=0; i<M/2+NW/2; i++,j++) { - w[i] = 0.5 - 0.5*cos(TWO_PI*j/(NW-1)); + w[i] = 0.5 - 0.5*cosf(TWO_PI*j/(NW-1)); m += w[i]*w[i]; } for(i=M/2+NW/2; i<M; i++) @@ -96,7 +97,7 @@ void make_analysis_window(float w[],COMP W[]) /* Normalise - makes freq domain amplitude estimation straight forward */ - m = 1.0/sqrt(m*FFT_ENC); + m = 1.0/sqrtf(m*FFT_ENC); for(i=0; i<M; i++) { w[i] *= m; } @@ -123,15 +124,15 @@ void make_analysis_window(float w[],COMP W[]) */ for(i=0; i<FFT_ENC; i++) { - W[i].real = 0.0; - W[i].imag = 0.0; + wshift[i].real = 0.0; + wshift[i].imag = 0.0; } for(i=0; i<NW/2; i++) - W[i].real = w[i+M/2]; + wshift[i].real = w[i+M/2]; for(i=FFT_ENC-NW/2,j=M/2-NW/2; i<FFT_ENC; i++,j++) - W[i].real = w[j]; + wshift[i].real = w[j]; - fft(&W[0].real,FFT_ENC,-1); /* "Numerical Recipes in C" FFT */ + kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)wshift, (kiss_fft_cpx *)W); /* Re-arrange W[] to be symmetrical about FFT_ENC/2. Makes later @@ -198,13 +199,14 @@ float hpf(float x, float states[]) \*---------------------------------------------------------------------------*/ -void dft_speech(COMP Sw[], float Sn[], float w[]) +void dft_speech(kiss_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[]) { - int i; + int i; + COMP sw[FFT_ENC]; for(i=0; i<FFT_ENC; i++) { - Sw[i].real = 0.0; - Sw[i].imag = 0.0; + sw[i].real = 0.0; + sw[i].imag = 0.0; } /* Centre analysis window on time axis, we need to arrange input @@ -213,14 +215,14 @@ void dft_speech(COMP Sw[], float Sn[], float w[]) /* move 2nd half to start of FFT input vector */ for(i=0; i<NW/2; i++) - Sw[i].real = Sn[i+M/2]*w[i+M/2]; + sw[i].real = Sn[i+M/2]*w[i+M/2]; /* move 1st half to end of FFT input vector */ for(i=0; i<NW/2; i++) - Sw[FFT_ENC-NW/2+i].real = Sn[i+M/2-NW/2]*w[i+M/2-NW/2]; + sw[FFT_ENC-NW/2+i].real = Sn[i+M/2-NW/2]*w[i+M/2-NW/2]; - fft(&Sw[0].real,FFT_ENC,-1); + kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)sw, (kiss_fft_cpx *)Sw); } /*---------------------------------------------------------------------------*\ @@ -287,7 +289,7 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float float Wo; /* current "test" fundamental freq. */ float Wom; /* Wo that maximises E */ float Em; /* mamimum energy */ - float r; /* number of rads/bin */ + float r, one_on_r; /* number of rads/bin */ float p; /* current pitch */ /* Initialisation */ @@ -296,6 +298,7 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float Wom = model->Wo; Em = 0.0; r = TWO_PI/FFT_ENC; + one_on_r = 1.0/r; /* Determine harmonic sum for a range of Wo values */ @@ -304,12 +307,10 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float Wo = TWO_PI/p; /* Sum harmonic magnitudes */ - for(m=1; m<=model->L; m++) { - b = floor(m*Wo/r + 0.5); - E += Sw[b].real*Sw[b].real + Sw[b].imag*Sw[b].imag; + b = (int)(m*Wo*one_on_r + 0.5); + E += Sw[b].real*Sw[b].real + Sw[b].imag*Sw[b].imag; } - /* Compare to see if this is a maximum */ if (E > Em) { @@ -331,40 +332,45 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float \*---------------------------------------------------------------------------*/ -void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[]) +void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase) { int i,m; /* loop variables */ int am,bm; /* bounds of current harmonic */ int b; /* DFT bin of centre of current harmonic */ float den; /* denominator of amplitude expression */ - float r; /* number of rads/bin */ + float r, one_on_r; /* number of rads/bin */ int offset; COMP Am; r = TWO_PI/FFT_ENC; + one_on_r = 1.0/r; for(m=1; m<=model->L; m++) { den = 0.0; - am = floor((m - 0.5)*model->Wo/r + 0.5); - bm = floor((m + 0.5)*model->Wo/r + 0.5); - b = floor(m*model->Wo/r + 0.5); + am = (int)((m - 0.5)*model->Wo*one_on_r + 0.5); + bm = (int)((m + 0.5)*model->Wo*one_on_r + 0.5); + b = (int)(m*model->Wo/r + 0.5); /* Estimate ampltude of harmonic */ den = 0.0; Am.real = Am.imag = 0.0; + offset = FFT_ENC/2 - (int)(m*model->Wo*one_on_r + 0.5); for(i=am; i<bm; i++) { den += Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag; - offset = i + FFT_ENC/2 - floor(m*model->Wo/r + 0.5); - Am.real += Sw[i].real*W[offset].real; - Am.imag += Sw[i].imag*W[offset].real; + Am.real += Sw[i].real*W[i + offset].real; + Am.imag += Sw[i].imag*W[i + offset].real; } - model->A[m] = sqrt(den); + model->A[m] = sqrtf(den); + + if (est_phase) { - /* Estimate phase of harmonic */ + /* Estimate phase of harmonic, this is expensive in CPU for + embedded devicesso we make it an option */ - model->phi[m] = atan2(Sw[b].imag,Sw[b].real); + model->phi[m] = atan2(Sw[b].imag,Sw[b].real); + } } } @@ -396,9 +402,9 @@ float est_voicing_mbe( float Wo; float sig, snr; float elow, ehigh, eratio; - float dF0, sixty; + float sixty; - sig = 0.0; + sig = 1E-4; for(l=1; l<=model->L/4; l++) { sig += model->A[l]*model->A[l]; } @@ -410,7 +416,7 @@ float est_voicing_mbe( } Wo = model->Wo; - error = 0.0; + error = 1E-4; /* Just test across the harmonics in the first 1000 Hz (L/4) */ @@ -423,11 +429,11 @@ float est_voicing_mbe( /* Estimate amplitude of harmonic assuming harmonic is totally voiced */ + offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5; for(m=al; m<bl; m++) { - offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5; - Am.real += Sw[m].real*W[offset].real + Sw[m].imag*W[offset].imag; - Am.imag += Sw[m].imag*W[offset].real - Sw[m].real*W[offset].imag; - den += W[offset].real*W[offset].real + W[offset].imag*W[offset].imag; + Am.real += Sw[m].real*W[offset+m].real; + Am.imag += Sw[m].imag*W[offset+m].real; + den += W[offset+m].real*W[offset+m].real; } Am.real = Am.real/den; @@ -435,10 +441,10 @@ float est_voicing_mbe( /* Determine error between estimated harmonic and original */ + offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5; for(m=al; m<bl; m++) { - offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5; - Sw_[m].real = Am.real*W[offset].real - Am.imag*W[offset].imag; - Sw_[m].imag = Am.real*W[offset].imag + Am.imag*W[offset].real; + Sw_[m].real = Am.real*W[offset+m].real; + Sw_[m].imag = Am.imag*W[offset+m].real; Ew[m].real = Sw[m].real - Sw_[m].real; Ew[m].imag = Sw[m].imag - Sw_[m].imag; error += Ew[m].real*Ew[m].real; @@ -446,7 +452,7 @@ float est_voicing_mbe( } } - snr = 10.0*log10(sig/error); + snr = 10.0*log10f(sig/error); if (snr > V_THRESH) model->voiced = 1; else @@ -455,21 +461,20 @@ float est_voicing_mbe( /* post processing, helps clean up some voicing errors ------------------*/ /* - Determine the ratio of low freancy to high frequency energy, + Determine the ratio of low freqency to high frequency energy, voiced speech tends to be dominated by low frequency energy, unvoiced by high frequency. This measure can be used to determine if we have made any gross errors. */ - elow = ehigh = 0.0; + elow = ehigh = 1E-4; for(l=1; l<=model->L/2; l++) { elow += model->A[l]*model->A[l]; } for(l=model->L/2; l<=model->L; l++) { ehigh += model->A[l]*model->A[l]; } - eratio = 10.0*log10(elow/ehigh); - dF0 = 0.0; + eratio = 10.0*log10f(elow/ehigh); /* Look for Type 1 errors, strongly V speech that has been accidentally declared UV */ @@ -485,16 +490,10 @@ float est_voicing_mbe( if (eratio < -10.0) model->voiced = 0; - /* If pitch is jumping about it's likely this is UV */ - - dF0 = (model->Wo - prev_Wo)*FS/TWO_PI; - if (fabs(dF0) > 15.0) - model->voiced = 0; - /* A common source of Type 2 errors is the pitch estimator gives a low (50Hz) estimate for UV speech, which gives a good match with noise due to the close harmoonic spacing. - These errors are much more common than people with 50Hz + These errors are much more common than people with 50Hz3 pitch, so we have just a small eratio threshold. */ sixty = 60.0*TWO_PI/FS; @@ -551,6 +550,7 @@ void make_synthesis_window(float Pn[]) \*---------------------------------------------------------------------------*/ void synthesise( + kiss_fft_cfg fft_inv_cfg, float Sn_[], /* time domain synthesised signal */ MODEL *model, /* ptr to model parameters for this frame */ float Pn[], /* time domain Parzen window */ @@ -559,10 +559,10 @@ void synthesise( { int i,l,j,b; /* loop variables */ COMP Sw_[FFT_DEC]; /* DFT of synthesised signal */ + COMP sw_[FFT_DEC]; /* synthesised signal */ if (shift) { /* Update memories */ - for(i=0; i<N-1; i++) { Sn_[i] = Sn_[i+N]; } @@ -578,7 +578,7 @@ void synthesise( Nov 2010 - found that synthesis using time domain cos() functions gives better results for synthesis frames greater than 10ms. Inverse FFT synthesis using a 512 pt FFT works well for 10ms window. I think - (but am not sure) that the problem is realted to the quantisation of + (but am not sure) that the problem is related to the quantisation of the harmonic frequencies to the FFT bin size, e.g. there is a 8000/512 Hz step between FFT bins. For some reason this makes the speech from longer frame > 10ms sound poor. The effect can also @@ -592,19 +592,21 @@ void synthesise( #ifdef FFT_SYNTHESIS /* Now set up frequency domain synthesised speech */ for(l=1; l<=model->L; l++) { - b = floor(l*model->Wo*FFT_DEC/TWO_PI + 0.5); + //for(l=model->L/2; l<=model->L; l++) { + //for(l=1; l<=model->L/4; l++) { + b = (int)(l*model->Wo*FFT_DEC/TWO_PI + 0.5); if (b > ((FFT_DEC/2)-1)) { b = (FFT_DEC/2)-1; } - Sw_[b].real = model->A[l]*cos(model->phi[l]); - Sw_[b].imag = model->A[l]*sin(model->phi[l]); + Sw_[b].real = model->A[l]*cosf(model->phi[l]); + Sw_[b].imag = model->A[l]*sinf(model->phi[l]); Sw_[FFT_DEC-b].real = Sw_[b].real; Sw_[FFT_DEC-b].imag = -Sw_[b].imag; } /* Perform inverse DFT */ - fft(&Sw_[0].real,FFT_DEC,1); + kiss_fft(fft_inv_cfg, (kiss_fft_cpx *)Sw_, (kiss_fft_cpx *)sw_); #else /* Direct time domain synthesis using the cos() function. Works @@ -625,14 +627,22 @@ void synthesise( /* Overlap add to previous samples */ for(i=0; i<N-1; i++) { - Sn_[i] += Sw_[FFT_DEC-N+1+i].real*Pn[i]; + Sn_[i] += sw_[FFT_DEC-N+1+i].real*Pn[i]; } if (shift) for(i=N-1,j=0; i<2*N; i++,j++) - Sn_[i] = Sw_[j].real*Pn[i]; + Sn_[i] = sw_[j].real*Pn[i]; else for(i=N-1,j=0; i<2*N; i++,j++) - Sn_[i] += Sw_[j].real*Pn[i]; + Sn_[i] += sw_[j].real*Pn[i]; +} + + +static unsigned long next = 1; + +int codec2_rand(void) { + next = next * 1103515245 + 12345; + return((unsigned)(next/65536) % 32768); } diff --git a/gr-vocoder/lib/codec2/sine.h b/gr-vocoder/lib/codec2/sine.h index f223e2afca..3a3ce46d62 100644 --- a/gr-vocoder/lib/codec2/sine.h +++ b/gr-vocoder/lib/codec2/sine.h @@ -30,15 +30,19 @@ #include "defines.h" #include "comp.h" +#include "kiss_fft.h" -void make_analysis_window(float w[], COMP W[]); +void make_analysis_window(kiss_fft_cfg fft_fwd_cfg, float w[], COMP W[]); float hpf(float x, float states[]); -void dft_speech(COMP Sw[], float Sn[], float w[]); +void dft_speech(kiss_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[]); void two_stage_pitch_refinement(MODEL *model, COMP Sw[]); -void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[]); +void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase); float est_voicing_mbe(MODEL *model, COMP Sw[], COMP W[], COMP Sw_[],COMP Ew[], float prev_Wo); void make_synthesis_window(float Pn[]); -void synthesise(float Sn_[], MODEL *model, float Pn[], int shift); +void synthesise(kiss_fft_cfg fft_inv_cfg, float Sn_[], MODEL *model, float Pn[], int shift); + +#define CODEC2_RAND_MAX 32767 +int codec2_rand(void); #endif diff --git a/gr-vocoder/lib/codec2/test_bits.h b/gr-vocoder/lib/codec2/test_bits.h new file mode 100644 index 0000000000..d1c01a03b2 --- /dev/null +++ b/gr-vocoder/lib/codec2/test_bits.h @@ -0,0 +1,164 @@ +/* Generated by test_bits_file() Octave function */ + +const int test_bits[]={ + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1 +}; diff --git a/gr-vocoder/lib/codec2_decode_ps_impl.cc b/gr-vocoder/lib/codec2_decode_ps_impl.cc index a4f7cccf82..fa4c1839d0 100644 --- a/gr-vocoder/lib/codec2_decode_ps_impl.cc +++ b/gr-vocoder/lib/codec2_decode_ps_impl.cc @@ -24,12 +24,12 @@ #include "config.h" #endif -#include "codec2_decode_ps_impl.h" - extern "C" { #include "codec2/codec2.h" } +#include "codec2_decode_ps_impl.h" + #include <gnuradio/io_signature.h> #include <stdexcept> #include <assert.h> @@ -38,22 +38,34 @@ namespace gr { namespace vocoder { codec2_decode_ps::sptr - codec2_decode_ps::make() + codec2_decode_ps::make(int mode) { + CODEC2 *codec2; + int samples_per_frame, bits_per_frame; + + // Check the number of input samples and output bits per frame. + codec2 = codec2_create(mode); + samples_per_frame = codec2_samples_per_frame(codec2); + bits_per_frame = codec2_bits_per_frame(codec2); + codec2_destroy(codec2); + return gnuradio::get_initial_sptr - (new codec2_decode_ps_impl()); + (new codec2_decode_ps_impl(mode, samples_per_frame, bits_per_frame)); } - codec2_decode_ps_impl::codec2_decode_ps_impl () + codec2_decode_ps_impl::codec2_decode_ps_impl (int mode, int samples_per_frame, int bits_per_frame) : sync_interpolator("vocoder_codec2_decode_ps", - io_signature::make(1, 1, CODEC2_BITS_PER_FRAME * sizeof(char)), + io_signature::make(1, 1, bits_per_frame * sizeof(char)), io_signature::make (1, 1, sizeof(short)), - CODEC2_SAMPLES_PER_FRAME), - d_frame_buf(CODEC2_BYTES_PER_FRAME, 0) + samples_per_frame), + d_frame_buf((bits_per_frame + 7) / 8, 0) { - if((d_codec2 = codec2_create()) == 0) + if((d_codec2 = codec2_create(mode)) == 0) throw std::runtime_error("codec2_decode_ps_impl: codec2_create failed"); + d_samples_per_frame = samples_per_frame; + d_bits_per_frame = bits_per_frame; + d_bytes_per_frame = (bits_per_frame + 7) / 8; } codec2_decode_ps_impl::~codec2_decode_ps_impl() @@ -69,13 +81,13 @@ namespace gr { const unsigned char *in = (const unsigned char*)input_items[0]; short *out = (short *) output_items[0]; - assert((noutput_items % CODEC2_SAMPLES_PER_FRAME) == 0); + assert((noutput_items % d_samples_per_frame) == 0); - for(int i = 0; i < noutput_items; i += CODEC2_SAMPLES_PER_FRAME) { + for(int i = 0; i < noutput_items; i += d_samples_per_frame) { pack_frame(in, &d_frame_buf[0]); - codec2_decode (d_codec2, out, const_cast<unsigned char*>(&d_frame_buf[0])); - in += CODEC2_BITS_PER_FRAME * sizeof (char); - out += CODEC2_SAMPLES_PER_FRAME; + codec2_decode (d_codec2, out, const_cast<unsigned char*>(&d_frame_buf[0]), 0.0); + in += d_bits_per_frame * sizeof (char); + out += d_samples_per_frame; } return noutput_items; @@ -84,10 +96,10 @@ namespace gr { void codec2_decode_ps_impl::pack_frame(const unsigned char *in_unpacked, unsigned char *out_packed) { - memset((void *) &d_frame_buf[0], 0x00, CODEC2_BYTES_PER_FRAME); + memset((void *) &d_frame_buf[0], 0x00, d_bytes_per_frame); int byte_idx = 0, bit_idx = 0; - for(int k = 0; k < CODEC2_BITS_PER_FRAME; k++) { + for(int k = 0; k < d_bits_per_frame; k++) { out_packed[byte_idx] |= ((in_unpacked[k] & 0x01) << (7-bit_idx)); bit_idx = (bit_idx + 1) % 8; if (bit_idx == 0) { diff --git a/gr-vocoder/lib/codec2_decode_ps_impl.h b/gr-vocoder/lib/codec2_decode_ps_impl.h index b9591dce74..db5ba2eef1 100644 --- a/gr-vocoder/lib/codec2_decode_ps_impl.h +++ b/gr-vocoder/lib/codec2_decode_ps_impl.h @@ -31,13 +31,14 @@ namespace gr { class codec2_decode_ps_impl : public codec2_decode_ps { private: - void *d_codec2; + CODEC2 *d_codec2; + int d_samples_per_frame, d_bits_per_frame, d_bytes_per_frame; std::vector<unsigned char> d_frame_buf; //!< Store 1 packed frame for decoding void pack_frame(const unsigned char *in_unpacked, unsigned char *out_packed); //!< Pack the bytes from unpacked bits for codec2 public: - codec2_decode_ps_impl(); + codec2_decode_ps_impl(int mode, int samples_per_frame, int bits_per_frame); ~codec2_decode_ps_impl(); int work(int noutput_items, diff --git a/gr-vocoder/lib/codec2_encode_sp_impl.cc b/gr-vocoder/lib/codec2_encode_sp_impl.cc index fc0b3eee19..ae76b09472 100644 --- a/gr-vocoder/lib/codec2_encode_sp_impl.cc +++ b/gr-vocoder/lib/codec2_encode_sp_impl.cc @@ -24,12 +24,12 @@ #include "config.h" #endif -#include "codec2_encode_sp_impl.h" - extern "C" { #include "codec2/codec2.h" } +#include "codec2_encode_sp_impl.h" + #include <gnuradio/io_signature.h> #include <stdexcept> #include <iostream> @@ -39,21 +39,32 @@ namespace gr { namespace vocoder { codec2_encode_sp::sptr - codec2_encode_sp::make() + codec2_encode_sp::make(int mode) { + CODEC2 *codec2; + int samples_per_frame, bits_per_frame; + + // Check the number of input samples and output bits per frame. + codec2 = codec2_create(mode); + samples_per_frame = codec2_samples_per_frame(codec2); + bits_per_frame = codec2_bits_per_frame(codec2); + codec2_destroy(codec2); + return gnuradio::get_initial_sptr - (new codec2_encode_sp_impl()); + (new codec2_encode_sp_impl(mode, samples_per_frame, bits_per_frame)); } - codec2_encode_sp_impl::codec2_encode_sp_impl() + codec2_encode_sp_impl::codec2_encode_sp_impl(int mode, int samples_per_frame, int bits_per_frame) : sync_decimator("vocoder_codec2_encode_sp", io_signature::make(1, 1, sizeof(short)), - io_signature::make(1, 1, CODEC2_BITS_PER_FRAME * sizeof(char)), - CODEC2_SAMPLES_PER_FRAME), - d_frame_buf(CODEC2_BYTES_PER_FRAME, 0) + io_signature::make(1, 1, bits_per_frame * sizeof(char)), + samples_per_frame), + d_frame_buf((bits_per_frame + 7) / 8, 0) { - if((d_codec2 = codec2_create()) == 0) + if((d_codec2 = codec2_create(mode)) == 0) throw std::runtime_error("codec2_encode_sp_impl: codec2_create failed"); + d_samples_per_frame = samples_per_frame; + d_bits_per_frame = bits_per_frame; } codec2_encode_sp_impl::~codec2_encode_sp_impl() @@ -72,8 +83,8 @@ namespace gr { for(int i = 0; i < noutput_items; i++) { codec2_encode(d_codec2, &d_frame_buf[0], const_cast<short*>(in)); unpack_frame((const unsigned char *) &d_frame_buf[0], out); - in += CODEC2_SAMPLES_PER_FRAME; - out += CODEC2_BITS_PER_FRAME * sizeof(char); + in += d_samples_per_frame; + out += d_bits_per_frame * sizeof(char); } return noutput_items; @@ -83,7 +94,7 @@ namespace gr { codec2_encode_sp_impl::unpack_frame(const unsigned char *packed, unsigned char *out) { int byte_idx = 0, bit_idx = 0; - for(int k = 0; k < CODEC2_BITS_PER_FRAME; k++) { + for(int k = 0; k < d_bits_per_frame; k++) { out[k] = (packed[byte_idx] >> (7-bit_idx)) & 0x01; bit_idx = (bit_idx + 1) % 8; if (bit_idx == 0) { diff --git a/gr-vocoder/lib/codec2_encode_sp_impl.h b/gr-vocoder/lib/codec2_encode_sp_impl.h index 7402d09f90..17d6f4e2a1 100644 --- a/gr-vocoder/lib/codec2_encode_sp_impl.h +++ b/gr-vocoder/lib/codec2_encode_sp_impl.h @@ -31,13 +31,14 @@ namespace gr { class codec2_encode_sp_impl : public codec2_encode_sp { private: - void *d_codec2; + CODEC2 *d_codec2; + int d_samples_per_frame, d_bits_per_frame; std::vector<unsigned char> d_frame_buf; //!< Save 1 CODEC2 frame void unpack_frame(const unsigned char *packed, unsigned char *out); //!< Unpack the bytes from codec2 into unpacked bits public: - codec2_encode_sp_impl(); + codec2_encode_sp_impl(int mode, int samples_per_frame, int bits_per_frame); ~codec2_encode_sp_impl(); int work(int noutput_items, diff --git a/gr-vocoder/python/vocoder/qa_codec2_vocoder.py b/gr-vocoder/python/vocoder/qa_codec2_vocoder.py index 0e29401c7a..8fe3ac56b5 100755 --- a/gr-vocoder/python/vocoder/qa_codec2_vocoder.py +++ b/gr-vocoder/python/vocoder/qa_codec2_vocoder.py @@ -21,6 +21,7 @@ # from gnuradio import gr, gr_unittest, vocoder, blocks +from gnuradio.vocoder import codec2 class test_codec2_vocoder (gr_unittest.TestCase): @@ -31,27 +32,18 @@ class test_codec2_vocoder (gr_unittest.TestCase): self.tb = None def test001_module_load (self): - data = 20*(100,200,300,400,500,600,700,800) - expected_data = (0,0,0,3,2,0,1,5,6,7,1,-1,0,-5,-11,-10,-20,-22, - -20,-20,-27,-26,-36,-48,-59,-24,5,-7,-12,-27,-22, - -22,-16,13,20,39,23,25,8,-6,15,44,97,135,145,125, - 94,102,126,129,165,192,180,132,99,79,73,83,72,47, - 40,0,-32,-46,-67,-99,-123,-114,-87,-108,-131,-152, - -181,-245,-348,-294,-101,-71,-85,-26,99,123,15,2,77, - 13,-117,-145,-105,-39,-50,-89,-59,-77,-134,-95,-51, - -22,17,-19,-59,-74,-103,-78,4,77,113,60,18,13,-67, - -49,24,88,179,190,89,18,-90,-102,-50,-5,123,135,57, - 31,-82,-98,-51,6,93,104,44,-5,-84,-107,-44,45,102,104, - 15,-47,-107,-126,-87,-11,89,93,13,-95,-136,-187,-70, - -167,216,-70,-103,175,-284,-486) + data = 40*(100,200,300,400,500,600,700,800) + expected_data = (0, 5, 10, 14, 15, 13, 14, 20, 40, 46, 39, 36, 35, 33, 22, 17, 31, 34, 29, 24, 24, 15, -3, -8, -7, 1, -4, -11, -14, -22, -39, -53, -51, -52, -58, -58, -59, -58, -61, -74, -73, -79, -75, -61, -73, -76, -72, -75, -62, -74, -75, -64, -64, -59, -61, -49, -68, -60, -23, -46, -48, -33, -48, 2, 20, -3, 2, -8, 9, 38, 9, 16, 23, 16, 44, 65, 37, 24, 25, 55, 61, 57, 52, 39, 47, 57, 66, 73, 50, 46, 47, 55, 55, 45, 73, 86, 63, 66, 60, 55, 60, 55, 71, 59, 46, 58, 46, 2, 38, 50, 33, 41, 32, 0, -16, -11, 10, 16, -13, 0, -5, -33, -45, -38, -28, -24, -41, 21, -2, -53, -55, -74, -66, -64, -64, -41, -46, -94, -122, -130, -92, -126, -104, -90, -74, -118, -162, -154, -130, -133, -163, -18, -23, -155, -95, -145, -60, -63, 156, 864, 882, 607, 449, 163, 204, 17, 47, 612, 447, 200, -59, -188, -175, -418, -192, 170, 14, -73, -258, -276, -267, -335, -117, 96, 34, -28, -152, -130, -124, -187, 42, 176, 131, 78, -52, -2, -57, -75, 104, 130, 111, 29, -50, -46, -107, -64, 66, 36, 33, -39, -129, -91, -157, -39, 69, 1, -12, -84, -99, -52, -61, 86, 147, 58, 21, -63, -60, -100, -48, 68, 76, 6, -65, -79, -108, -159, -71, 89, 171, 183, 216, 152, 26, -35, 0, 87, 126, 143, 182, 151, 95, 106, 115, 155, 103, 86, 127, 12, -41, -91, -87, -32, -52, -41, -32, -123, -147, -154, -156, -61, -37, -8, -51, -127, -132, -127, -107, -54, 1, 26, -17, -100, -61, -9, 3, 57, 117, 102, 58, -47, 24, 67, 42, 116, 141, 113, 39, -15, 63, 68, 41, 118, 80, 24, -46, -72, 12, 5, -17, 18, -43, -61, -110, -119, -42, -40, -16, 2, -11, -50) + src = blocks.vector_source_s(data) - enc = vocoder.codec2_encode_sp() - dec = vocoder.codec2_decode_ps() + enc = vocoder.codec2_encode_sp(codec2.MODE_2400) + dec = vocoder.codec2_decode_ps(codec2.MODE_2400) snk = blocks.vector_sink_s() self.tb.connect(src, enc, dec, snk) self.tb.run() actual_result = snk.data() self.assertEqual(expected_data, actual_result) + self.tb.disconnect(src, enc, dec, snk) if __name__ == '__main__': # Note: The Vocoder is stateful, which means this test will produce failure when removing the xml option. diff --git a/gr-vocoder/swig/vocoder_swig.i b/gr-vocoder/swig/vocoder_swig.i index c404ea22d5..dac35c9cd4 100644 --- a/gr-vocoder/swig/vocoder_swig.i +++ b/gr-vocoder/swig/vocoder_swig.i @@ -30,6 +30,7 @@ %{ #include "gnuradio/vocoder/alaw_decode_bs.h" #include "gnuradio/vocoder/alaw_encode_sb.h" +#include "gnuradio/vocoder/codec2.h" #include "gnuradio/vocoder/codec2_decode_ps.h" #include "gnuradio/vocoder/codec2_encode_sp.h" #include "gnuradio/vocoder/cvsd_decode_bs.h" @@ -48,6 +49,7 @@ %include "gnuradio/vocoder/alaw_decode_bs.h" %include "gnuradio/vocoder/alaw_encode_sb.h" +%include "gnuradio/vocoder/codec2.h" %include "gnuradio/vocoder/codec2_decode_ps.h" %include "gnuradio/vocoder/codec2_encode_sp.h" %include "gnuradio/vocoder/cvsd_decode_bs.h" diff --git a/grc/base/Block.py b/grc/base/Block.py index 668675c685..5a91810b7d 100644 --- a/grc/base/Block.py +++ b/grc/base/Block.py @@ -18,11 +18,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA """ from . import odict +from . Constants import ADVANCED_PARAM_TAB, DEFAULT_PARAM_TAB from Element import Element from Cheetah.Template import Template from UserDict import UserDict -from .. gui import Actions +from itertools import imap class TemplateArg(UserDict): """ @@ -76,6 +77,11 @@ class Block(Element): self._block_wrapper_path = n.find('block_wrapper_path') self._bussify_sink = n.find('bus_sink') self._bussify_source = n.find('bus_source') + + # get list of param tabs + n_tabs = n.find('param_tab_order') or None + self._param_tab_labels = n_tabs.findall('tab') if n_tabs is not None else [DEFAULT_PARAM_TAB] + #create the param objects self._params = list() #add the id param @@ -97,7 +103,7 @@ class Block(Element): 'hide': 'all', }) )) - for param in map(lambda n: self.get_parent().get_parent().Param(block=self, n=n), params): + for param in imap(lambda n: self.get_parent().get_parent().Param(block=self, n=n), params): key = param.get_key() #test against repeated keys if key in self.get_param_keys(): @@ -142,6 +148,7 @@ class Block(Element): 'key': 'affinity', 'type': 'int_vector', 'hide': 'part', + 'tab': ADVANCED_PARAM_TAB }) )) if len(sources) and is_not_virtual_or_pad: @@ -151,7 +158,8 @@ class Block(Element): 'key': 'minoutbuf', 'type': 'int', 'hide': 'part', - 'value': '0' + 'value': '0', + 'tab': ADVANCED_PARAM_TAB }) )) self.get_params().append(self.get_parent().get_parent().Param( @@ -160,14 +168,14 @@ class Block(Element): 'key': 'maxoutbuf', 'type': 'int', 'hide': 'part', - 'value': '0' + 'value': '0', + 'tab': ADVANCED_PARAM_TAB }) )) def back_ofthe_bus(self, portlist): portlist.sort(key=lambda a: a.get_type() == 'bus'); - def filter_bus_port(self, ports): buslist = [i for i in ports if i.get_type() == 'bus']; @@ -213,6 +221,7 @@ class Block(Element): ############################################## # Access Params ############################################## + def get_param_tab_labels(self): return self._param_tab_labels def get_param_keys(self): return _get_keys(self._params) def get_param(self, key): return _get_elem(self._params, key) def get_params(self): return self._params diff --git a/grc/base/Constants.py b/grc/base/Constants.py index ef45be8dfe..e5026d9da7 100644 --- a/grc/base/Constants.py +++ b/grc/base/Constants.py @@ -23,3 +23,7 @@ import os DATA_DIR = os.path.dirname(__file__) FLOW_GRAPH_DTD = os.path.join(DATA_DIR, 'flow_graph.dtd') BLOCK_TREE_DTD = os.path.join(DATA_DIR, 'block_tree.dtd') + +# Param tabs +DEFAULT_PARAM_TAB = "General" +ADVANCED_PARAM_TAB = "Advanced" diff --git a/grc/base/Element.py b/grc/base/Element.py index 17b2234a8c..be73ab264f 100644 --- a/grc/base/Element.py +++ b/grc/base/Element.py @@ -89,6 +89,7 @@ class Element(object): def is_flow_graph(self): return False def is_connection(self): return False def is_block(self): return False + def is_dummy_block(self): return False def is_source(self): return False def is_sink(self): return False def is_port(self): return False diff --git a/grc/base/FlowGraph.py b/grc/base/FlowGraph.py index c85e3ce233..3c249ff71b 100644 --- a/grc/base/FlowGraph.py +++ b/grc/base/FlowGraph.py @@ -268,16 +268,20 @@ class FlowGraph(Element): #build the blocks for block_n in blocks_n: key = block_n.find('key') - if key == 'options': block = self._options_block - else: block = self.get_new_block(key) - #only load the block when the block key was valid - if block: block.import_data(block_n) - else: Messages.send_error_load('Block key "%s" not found in %s'%(key, self.get_parent())) + block = self._options_block if key == 'options' else self.get_new_block(key) + + if not block: # looks like this block key cannot be found + # create a dummy block instead + block = self.get_new_block('dummy_block') + # Ugly ugly ugly + _initialize_dummy_block(block, block_n) + Messages.send_error_load('Block key "%s" not found in %s' % (key, self.get_parent())) + + block.import_data(block_n) #build the connections block_ids = map(lambda b: b.get_id(), self.get_blocks()) for connection_n in connections_n: - #try to make the connection - try: + try: # to make the connection #get the block ids source_block_id = connection_n.find('source_block_id') sink_block_id = connection_n.find('sink_block_id') @@ -297,9 +301,17 @@ class FlowGraph(Element): sink_key = self.update_message_port_key(sink_key, sink_block.get_sinks()) #verify the ports if source_key not in source_block.get_source_keys(): - raise LookupError('source key "%s" not in source block keys'%source_key) + # dummy blocks learn their ports here + if source_block.is_dummy_block(): + _dummy_block_add_port(source_block, source_key, dir='source') + else: + raise LookupError('source key "%s" not in source block keys' % source_key) if sink_key not in sink_block.get_sink_keys(): - raise LookupError('sink key "%s" not in sink block keys'%sink_key) + # dummy blocks learn their ports here + if sink_block.is_dummy_block(): + _dummy_block_add_port(sink_block, sink_key, dir='sink') + else: + raise LookupError('sink key "%s" not in sink block keys' % sink_key) #get the ports source = source_block.get_source(source_key) sink = sink_block.get_sink(sink_key) @@ -327,7 +339,35 @@ class FlowGraph(Element): :returns: the updated key or the original one """ if key.isdigit(): # don't bother current message port keys - port = ports[int(key)] # get port (assuming liner indexed keys) - if port.get_type() == "message": - return port.get_key() # for message ports get updated key - return key # do nothing
\ No newline at end of file + try: + port = ports[int(key)] # get port (assuming liner indexed keys) + if port.get_type() == "message": + return port.get_key() # for message ports get updated key + except IndexError: + pass + return key # do nothing + + +def _initialize_dummy_block(block, block_n): + """This is so ugly... dummy-fy a block + + Modify block object to get the behaviour for a missing block + """ + block._key = block_n.find('key') + block.is_dummy_block = lambda: True + block.is_valid = lambda: False + block.get_enabled = lambda: False + for param_n in block_n.findall('param'): + if param_n['key'] not in block.get_param_keys(): + new_param_n = odict({'key': param_n['key'], 'name': param_n['key'], 'type': 'string'}) + block.get_params().append(block.get_parent().get_parent().Param(block=block, n=new_param_n)) + + +def _dummy_block_add_port(block, key, dir): + """This is so ugly... Add a port to a dummy-fied block""" + port_n = odict({'name': '?', 'key': key, 'type': ''}) + port = block.get_parent().get_parent().Port(block=block, n=port_n, dir=dir) + if port.is_source(): + block.get_sources().append(port) + else: + block.get_sinks().append(port)
\ No newline at end of file diff --git a/grc/base/Param.py b/grc/base/Param.py index 8b8362ac1a..33ba7c3dbb 100644 --- a/grc/base/Param.py +++ b/grc/base/Param.py @@ -68,12 +68,23 @@ class Param(Element): block: the parent element n: the nested odict """ - #grab the data + # if the base key is a valid param key, copy its data and overlay this params data + base_key = n.find('base_key') + if base_key and base_key in block.get_param_keys(): + n_expanded = block.get_param(base_key)._n.copy() + n_expanded.update(n) + n = n_expanded + # save odict in case this param will be base for another + self._n = n + # parse the data self._name = n.find('name') self._key = n.find('key') value = n.find('value') or '' - self._type = n.find('type') + self._type = n.find('type') or 'raw' self._hide = n.find('hide') or '' + self._tab_label = n.find('tab') or block.get_param_tab_labels()[0] + if not self._tab_label in block.get_param_tab_labels(): + block.get_param_tab_labels().append(self._tab_label) #build the param Element.__init__(self, block) #create the Option objects from the n data @@ -143,6 +154,7 @@ class Param(Element): def set_value(self, value): self._value = str(value) #must be a string def get_type(self): return self.get_parent().resolve_dependencies(self._type) + def get_tab_label(self): return self._tab_label def is_enum(self): return self._type == 'enum' def __repr__(self): diff --git a/grc/base/Platform.py b/grc/base/Platform.py index 3ff80e8a03..187a50c01c 100644 --- a/grc/base/Platform.py +++ b/grc/base/Platform.py @@ -196,6 +196,7 @@ class Platform(_Element): def get_license(self): return self._license def get_website(self): return self._website def get_colors(self): return self._colors + def get_block_paths(self): return self._block_paths ############################################## # Constructors diff --git a/grc/blocks/dummy.xml b/grc/blocks/dummy.xml new file mode 100644 index 0000000000..c0ca3b6698 --- /dev/null +++ b/grc/blocks/dummy.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Dummy Block +################################################### +--> +<block> + <name>Missing Block</name> + <key>dummy_block</key> + <make>raise NotImplementedError()</make> +</block> diff --git a/grc/grc_gnuradio/blks2/packet.py b/grc/grc_gnuradio/blks2/packet.py index 872f08ca2e..dde3ec722f 100644 --- a/grc/grc_gnuradio/blks2/packet.py +++ b/grc/grc_gnuradio/blks2/packet.py @@ -75,9 +75,9 @@ class packet_encoder(gr.hier_block2): Args: samples_per_symbol: number of samples per symbol bits_per_symbol: number of bits per symbol + preamble: string of ascii 0's and 1's access_code: AKA sync vector pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples - payload_length: number of bytes in a data-stream slice """ #setup parameters self._samples_per_symbol = samples_per_symbol diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py index 86f06aad58..65969e0d6f 100644 --- a/grc/gui/ActionHandler.py +++ b/grc/gui/ActionHandler.py @@ -25,6 +25,7 @@ import pygtk pygtk.require('2.0') import gtk import gobject +import subprocess import Preferences from threading import Thread import Messages @@ -115,7 +116,8 @@ class ActionHandler: Actions.FLOW_GRAPH_CLOSE, Actions.ABOUT_WINDOW_DISPLAY, Actions.FLOW_GRAPH_SCREEN_CAPTURE, Actions.HELP_WINDOW_DISPLAY, Actions.TYPES_WINDOW_DISPLAY, Actions.TOGGLE_BLOCKS_WINDOW, - Actions.TOGGLE_REPORTS_WINDOW, + Actions.TOGGLE_REPORTS_WINDOW, Actions.TOGGLE_HIDE_DISABLED_BLOCKS, + Actions.TOOLS_RUN_FDESIGN, ): action.set_sensitive(True) if ParseXML.xml_failures: Messages.send_xml_errors_if_any(ParseXML.xml_failures) @@ -359,12 +361,20 @@ class ActionHandler: Dialogs.ErrorsDialog(self.get_flow_graph()) elif action == Actions.TOGGLE_REPORTS_WINDOW: visible = action.get_active() - self.main_window.reports_scrolled_window.set_visible(visible) + if visible: + self.main_window.reports_scrolled_window.show() + else: + self.main_window.reports_scrolled_window.hide() Preferences.reports_window_visibility(visible) elif action == Actions.TOGGLE_BLOCKS_WINDOW: visible = action.get_active() - self.main_window.btwin.set_visible(visible) + if visible: + self.main_window.btwin.show() + else: + self.main_window.btwin.hide() Preferences.blocks_window_visibility(visible) + elif action == Actions.TOGGLE_HIDE_DISABLED_BLOCKS: + Actions.NOTHING_SELECT() ################################################## # Param Modifications ################################################## @@ -472,28 +482,34 @@ class ActionHandler: elif action == Actions.FIND_BLOCKS: self.main_window.btwin.show() self.main_window.btwin.search_entry.show() - self.main_window.set_focus(self.main_window.btwin.search_entry) + self.main_window.btwin.search_entry.grab_focus() elif action == Actions.OPEN_HIER: bn = []; for b in self.get_flow_graph().get_selected_blocks(): if b._grc_source: - self.main_window.new_page(b._grc_source, show=True); + self.main_window.new_page(b._grc_source, show=True) elif action == Actions.BUSSIFY_SOURCES: n = {'name':'bus', 'type':'bus'} for b in self.get_flow_graph().get_selected_blocks(): - b.bussify(n, 'source'); - self.get_flow_graph()._old_selected_port = None; - self.get_flow_graph()._new_selected_port = None; - Actions.ELEMENT_CREATE(); + b.bussify(n, 'source') + self.get_flow_graph()._old_selected_port = None + self.get_flow_graph()._new_selected_port = None + Actions.ELEMENT_CREATE() elif action == Actions.BUSSIFY_SINKS: n = {'name':'bus', 'type':'bus'} for b in self.get_flow_graph().get_selected_blocks(): b.bussify(n, 'sink') - self.get_flow_graph()._old_selected_port = None; - self.get_flow_graph()._new_selected_port = None; - Actions.ELEMENT_CREATE(); - else: print '!!! Action "%s" not handled !!!'%action + self.get_flow_graph()._old_selected_port = None + self.get_flow_graph()._new_selected_port = None + Actions.ELEMENT_CREATE() + + elif action == Actions.TOOLS_RUN_FDESIGN: + subprocess.Popen('gr_filter_design', + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + else: + print '!!! Action "%s" not handled !!!' % action ################################################## # Global Actions for all States ################################################## diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py index 284c78f8fc..f633e7ced0 100644 --- a/grc/gui/Actions.py +++ b/grc/gui/Actions.py @@ -236,6 +236,12 @@ BLOCK_DISABLE = Action( stock_id=gtk.STOCK_DISCONNECT, keypresses=(gtk.keysyms.d, NO_MODS_MASK), ) +TOGGLE_HIDE_DISABLED_BLOCKS = ToggleAction( + label='Hide _disabled blocks', + tooltip='Toggle visibility of disabled blocks and connections', + stock_id=gtk.STOCK_MISSING_IMAGE, + keypresses=(gtk.keysyms.d, gtk.gdk.CONTROL_MASK), +) BLOCK_CREATE_HIER = Action( label='C_reate Hier', tooltip='Create hier block from selected blocks', @@ -359,3 +365,11 @@ XML_PARSER_ERRORS_DISPLAY = Action( tooltip='View errors that occured while parsing XML files', stock_id=gtk.STOCK_DIALOG_ERROR, ) +TOOLS_RUN_FDESIGN = Action( + label='Filter design tool', + tooltip='Execute gr_filter_design', + stock_id=gtk.STOCK_EXECUTE, +) +TOOLS_MORE_TO_COME = Action( + label='More to come', +) diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py index f016209383..da1b1469e1 100644 --- a/grc/gui/Bars.py +++ b/grc/gui/Bars.py @@ -49,6 +49,7 @@ TOOLBAR_LIST = ( None, Actions.BLOCK_ENABLE, Actions.BLOCK_DISABLE, + Actions.TOGGLE_HIDE_DISABLED_BLOCKS, None, Actions.FIND_BLOCKS, Actions.RELOAD_BLOCKS, @@ -100,6 +101,11 @@ MENU_BAR_LIST = ( Actions.FLOW_GRAPH_EXEC, Actions.FLOW_GRAPH_KILL, ]), + (gtk.Action('Tools', '_Tools', None, None), [ + Actions.TOOLS_RUN_FDESIGN, + None, + Actions.TOOLS_MORE_TO_COME, + ]), (gtk.Action('Help', '_Help', None, None), [ Actions.HELP_WINDOW_DISPLAY, Actions.TYPES_WINDOW_DISPLAY, diff --git a/grc/gui/Block.py b/grc/gui/Block.py index 30031866c0..b2b391246e 100644 --- a/grc/gui/Block.py +++ b/grc/gui/Block.py @@ -131,7 +131,8 @@ class Block(Element): def create_labels(self): """Create the labels for the signal block.""" Element.create_labels(self) - self._bg_color = self.get_enabled() and Colors.BLOCK_ENABLED_COLOR or Colors.BLOCK_DISABLED_COLOR + self._bg_color = self.is_dummy_block() and Colors.MISSING_BLOCK_BACKGROUND_COLOR or \ + self.get_enabled() and Colors.BLOCK_ENABLED_COLOR or Colors.BLOCK_DISABLED_COLOR layouts = list() #create the main layout layout = gtk.DrawingArea().create_pango_layout('') @@ -139,7 +140,10 @@ class Block(Element): layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self)) self.label_width, self.label_height = layout.get_pixel_size() #display the params - markups = [param.get_markup() for param in self.get_params() if param.get_hide() not in ('all', 'part')] + if self.is_dummy_block(): + markups = ['<span foreground="black" font_desc="Sans 7.5"><b>key: </b>{}</span>'.format(self._key)] + else: + markups = [param.get_markup() for param in self.get_params() if param.get_hide() not in ('all', 'part')] if markups: layout = gtk.DrawingArea().create_pango_layout('') layout.set_spacing(LABEL_SEPARATION*pango.SCALE) @@ -191,7 +195,8 @@ class Block(Element): #draw main block Element.draw( self, gc, window, bg_color=self._bg_color, - border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR, + border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or + self.is_dummy_block() and Colors.MISSING_BLOCK_BORDER_COLOR or Colors.BORDER_COLOR, ) #draw label image if self.is_horizontal(): diff --git a/grc/gui/Colors.py b/grc/gui/Colors.py index 5f92bb07a9..541d8db0b2 100644 --- a/grc/gui/Colors.py +++ b/grc/gui/Colors.py @@ -26,6 +26,9 @@ try: HIGHLIGHT_COLOR = get_color('#00FFFF') BORDER_COLOR = get_color('black') + # missing blocks stuff + MISSING_BLOCK_BACKGROUND_COLOR = get_color('#FFF2F2') + MISSING_BLOCK_BORDER_COLOR = get_color('red') #param entry boxes PARAM_ENTRY_TEXT_COLOR = get_color('black') ENTRYENUM_CUSTOM_COLOR = get_color('#EEEEEE') diff --git a/grc/gui/DrawingArea.py b/grc/gui/DrawingArea.py index 9fac791284..05e69e7bc6 100644 --- a/grc/gui/DrawingArea.py +++ b/grc/gui/DrawingArea.py @@ -63,7 +63,7 @@ class DrawingArea(gtk.DrawingArea): def _handle_notify_event(widget, event, focus_flag): self._focus_flag = focus_flag self.connect('leave-notify-event', _handle_notify_event, False) self.connect('enter-notify-event', _handle_notify_event, True) - self.set_can_focus(True) + self.set_flags(gtk.CAN_FOCUS) # self.set_can_focus(True) self.connect('focus-out-event', self._handle_focus_lost_event) def new_pixmap(self, width, height): return gtk.gdk.Pixmap(self.window, width, height, -1) @@ -140,7 +140,7 @@ class DrawingArea(gtk.DrawingArea): def _handle_focus_lost_event(self, widget, event): # don't clear selection while context menu is active - if self._flow_graph.get_context_menu().get_visible(): return - self._flow_graph.unselect() - self._flow_graph.update_selected() - self._flow_graph.queue_draw() + if not self._flow_graph.get_context_menu().flags() & gtk.VISIBLE: + self._flow_graph.unselect() + self._flow_graph.update_selected() + self._flow_graph.queue_draw() diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py index c194dfb113..1103aa1639 100644 --- a/grc/gui/FlowGraph.py +++ b/grc/gui/FlowGraph.py @@ -37,7 +37,7 @@ class FlowGraph(Element): def __init__(self): """ - FlowGraph contructor. + FlowGraph constructor. Create a list for signal blocks and connections. Connect mouse handlers. """ Element.__init__(self) @@ -309,6 +309,8 @@ class FlowGraph(Element): window.draw_rectangle(gc, False, x, y, w, h) #draw blocks on top of connections for element in self.get_connections() + self.get_blocks(): + if Actions.TOGGLE_HIDE_DISABLED_BLOCKS.get_active() and not element.get_enabled(): + continue # skip hidden disabled blocks and connections element.draw(gc, window) #draw selected blocks on top of selected connections for selected_element in self.get_selected_connections() + self.get_selected_blocks(): @@ -374,6 +376,13 @@ class FlowGraph(Element): for element in reversed(self.get_elements()): selected_element = element.what_is_selected(coor, coor_m) if not selected_element: continue + # hidden disabled connections, blocks and their ports can not be selected + if Actions.TOGGLE_HIDE_DISABLED_BLOCKS.get_active() and ( + selected_element.is_block() and not selected_element.get_enabled() or + selected_element.is_connection() and not selected_element.get_enabled() or + selected_element.is_port() and not selected_element.get_parent().get_enabled() + ): + continue #update the selected port information if selected_element.is_port(): if not coor_m: selected_port = selected_element diff --git a/grc/gui/Messages.py b/grc/gui/Messages.py index c4706459af..2bf488bb58 100644 --- a/grc/gui/Messages.py +++ b/grc/gui/Messages.py @@ -48,7 +48,16 @@ register_messenger(sys.stdout.write) # Special functions for specific program functionalities ########################################################################### def send_init(platform): - send("""<<< Welcome to %s %s >>>\n"""%(platform.get_name(), platform.get_version())) + p = platform + send('\n'.join([ + "<<< Welcome to %s %s >>>" % (p.get_name(), p.get_version()), + "", + "Preferences file: " + p.get_prefs_file(), + "Block paths:" + ] + [ + "\t%s" % path + (" (%s)" % opath if opath != path else "") + for path, opath in p.get_block_paths().iteritems() + ]) + "\n") def send_page_switch(file_path): send('\nShowing: "%s"\n'%file_path) diff --git a/grc/gui/Param.py b/grc/gui/Param.py index f0e5a2fcb2..2ca20fab2a 100644 --- a/grc/gui/Param.py +++ b/grc/gui/Param.py @@ -23,6 +23,7 @@ import pygtk pygtk.require('2.0') import gtk import Colors +import os class InputParam(gtk.HBox): """The base class for an input parameter inside the input parameters dialog.""" @@ -36,6 +37,7 @@ class InputParam(gtk.HBox): self.pack_start(self.label, False) self.set_markup = lambda m: self.label.set_markup(m) self.tp = None + self._changed_but_unchecked = False #connect events self.connect('show', self._update_gui) def set_color(self, color): pass @@ -49,7 +51,9 @@ class InputParam(gtk.HBox): has_cb = \ hasattr(self.param.get_parent(), 'get_callbacks') and \ filter(lambda c: self.param.get_key() in c, self.param.get_parent()._callbacks) - self.set_markup(Utils.parse_template(PARAM_LABEL_MARKUP_TMPL, param=self.param, has_cb=has_cb)) + self.set_markup(Utils.parse_template(PARAM_LABEL_MARKUP_TMPL, + param=self.param, has_cb=has_cb, + modified=self._changed_but_unchecked)) #set the color self.set_color(self.param.get_color()) #set the tooltip @@ -60,7 +64,14 @@ class InputParam(gtk.HBox): if self.param.get_hide() == 'all': self.hide_all() else: self.show_all() - def _handle_changed(self, *args): + def _mark_changed(self, *args): + """ + Mark this param as modified on change, but validate only on focus-lost + """ + self._changed_but_unchecked = True + self._update_gui() + + def _apply_change(self, *args): """ Handle a gui change by setting the new param value, calling the callback (if applicable), and updating. @@ -71,6 +82,7 @@ class InputParam(gtk.HBox): if self._callback: self._callback(*args) else: self.param.validate() #gui update + self._changed_but_unchecked = False self._update_gui() class EntryParam(InputParam): @@ -80,7 +92,8 @@ class EntryParam(InputParam): InputParam.__init__(self, *args, **kwargs) self._input = gtk.Entry() self._input.set_text(self.param.get_value()) - self._input.connect('changed', self._handle_changed) + self._input.connect('changed', self._mark_changed) + self._input.connect('focus-out-event', self._apply_change) self.pack_start(self._input, True) def get_text(self): return self._input.get_text() def set_color(self, color): @@ -96,7 +109,7 @@ class EnumParam(InputParam): self._input = gtk.combo_box_new_text() for option in self.param.get_options(): self._input.append_text(option.get_name()) self._input.set_active(self.param.get_option_keys().index(self.param.get_value())) - self._input.connect('changed', self._handle_changed) + self._input.connect('changed', self._apply_change) self.pack_start(self._input, False) def get_text(self): return self.param.get_option_keys()[self._input.get_active()] def set_tooltip_text(self, text): self._input.set_tooltip_text(text) @@ -112,8 +125,9 @@ class EnumEntryParam(InputParam): except: self._input.set_active(-1) self._input.get_child().set_text(self.param.get_value()) - self._input.connect('changed', self._handle_changed) - self._input.get_child().connect('changed', self._handle_changed) + self._input.connect('changed', self._apply_change) + self._input.get_child().connect('changed', self._mark_changed) + self._input.get_child().connect('focus-out-event', self._apply_change) self.pack_start(self._input, False) def get_text(self): if self._input.get_active() == -1: return self._input.get_child().get_text() @@ -130,12 +144,50 @@ class EnumEntryParam(InputParam): self._input.get_child().modify_base(gtk.STATE_NORMAL, Colors.ENTRYENUM_CUSTOM_COLOR) self._input.get_child().modify_text(gtk.STATE_NORMAL, Colors.PARAM_ENTRY_TEXT_COLOR) + +class FileParam(EntryParam): + """Provide an entry box for filename and a button to browse for a file.""" + + def __init__(self, *args, **kwargs): + EntryParam.__init__(self, *args, **kwargs) + input = gtk.Button('...') + input.connect('clicked', self._handle_clicked) + self.pack_start(input, False) + + def _handle_clicked(self, widget=None): + """ + If the button was clicked, open a file dialog in open/save format. + Replace the text in the entry with the new filename from the file dialog. + """ + #get the paths + file_path = self.param.is_valid() and self.param.get_evaluated() or '' + (dirname, basename) = os.path.isfile(file_path) and os.path.split(file_path) or (file_path, '') + if not os.path.exists(dirname): dirname = os.getcwd() #fix bad paths + #build the dialog + if self.param.get_type() == 'file_open': + file_dialog = gtk.FileChooserDialog('Open a Data File...', None, + gtk.FILE_CHOOSER_ACTION_OPEN, ('gtk-cancel',gtk.RESPONSE_CANCEL,'gtk-open',gtk.RESPONSE_OK)) + elif self.param.get_type() == 'file_save': + file_dialog = gtk.FileChooserDialog('Save a Data File...', None, + gtk.FILE_CHOOSER_ACTION_SAVE, ('gtk-cancel',gtk.RESPONSE_CANCEL, 'gtk-save',gtk.RESPONSE_OK)) + file_dialog.set_do_overwrite_confirmation(True) + file_dialog.set_current_name(basename) #show the current filename + file_dialog.set_current_folder(dirname) #current directory + file_dialog.set_select_multiple(False) + file_dialog.set_local_only(True) + if gtk.RESPONSE_OK == file_dialog.run(): #run the dialog + file_path = file_dialog.get_filename() #get the file path + self._input.set_text(file_path) + self._apply_change() + file_dialog.destroy() #destroy the dialog + + PARAM_MARKUP_TMPL="""\ #set $foreground = $param.is_valid() and 'black' or 'red' <span foreground="$foreground" font_desc="Sans 7.5"><b>$encode($param.get_name()): </b>$encode(repr($param))</span>""" PARAM_LABEL_MARKUP_TMPL="""\ -#set $foreground = $param.is_valid() and 'black' or 'red' +#set $foreground = $modified and 'blue' or $param.is_valid() and 'black' or 'red' #set $underline = $has_cb and 'low' or 'none' <span underline="$underline" foreground="$foreground" font_desc="Sans 9">$encode($param.get_name())</span>""" @@ -179,8 +231,15 @@ class Param(Element): Returns: gtk input class """ - if self.is_enum(): return EnumParam(self, *args, **kwargs) - if self.get_options(): return EnumEntryParam(self, *args, **kwargs) + if self.get_type() in ('file_open', 'file_save'): + return FileParam(self, *args, **kwargs) + + elif self.is_enum(): + return EnumParam(self, *args, **kwargs) + + elif self.get_options(): + return EnumEntryParam(self, *args, **kwargs) + return EntryParam(self, *args, **kwargs) def get_markup(self): diff --git a/grc/gui/Platform.py b/grc/gui/Platform.py index 6a8175b9fa..db77ff2112 100644 --- a/grc/gui/Platform.py +++ b/grc/gui/Platform.py @@ -20,4 +20,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA from Element import Element class Platform(Element): - def __init__(self): Element.__init__(self) + def __init__(self, prefs_file): + Element.__init__(self) + + self._prefs_file = prefs_file + + def get_prefs_file(self): return self._prefs_file
\ No newline at end of file diff --git a/grc/gui/Port.py b/grc/gui/Port.py index fe1dc5070a..e542797ea6 100644 --- a/grc/gui/Port.py +++ b/grc/gui/Port.py @@ -126,7 +126,8 @@ class Port(Element): """ Element.draw( self, gc, window, bg_color=self._bg_color, - border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR, + border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or + self.get_parent().is_dummy_block() and Colors.MISSING_BLOCK_BORDER_COLOR or Colors.BORDER_COLOR, ) X,Y = self.get_coordinate() (x,y),(w,h) = self._areas_list[0] #use the first area's sizes to place the labels diff --git a/grc/gui/Preferences.py b/grc/gui/Preferences.py index c315436cae..b15fb9738b 100644 --- a/grc/gui/Preferences.py +++ b/grc/gui/Preferences.py @@ -24,7 +24,6 @@ _platform = None _config_parser = ConfigParser.ConfigParser() def file_extension(): return '.'+_platform.get_key() -def _prefs_file(): return os.path.join(os.path.expanduser('~'), file_extension()) def load(platform): global _platform @@ -32,10 +31,10 @@ def load(platform): #create sections _config_parser.add_section('main') _config_parser.add_section('files_open') - try: _config_parser.read(_prefs_file()) + try: _config_parser.read(_platform.get_prefs_file()) except: pass def save(): - try: _config_parser.write(open(_prefs_file(), 'w')) + try: _config_parser.write(open(_platform.get_prefs_file(), 'w')) except: pass ########################################################################### diff --git a/grc/gui/PropsDialog.py b/grc/gui/PropsDialog.py index 5c09f7cac1..05e997b3e3 100644 --- a/grc/gui/PropsDialog.py +++ b/grc/gui/PropsDialog.py @@ -23,6 +23,12 @@ import gtk from Dialogs import TextDisplay from Constants import MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT +import Utils + +TAB_LABEL_MARKUP_TMPL="""\ +#set $foreground = $valid and 'black' or 'red' +<span foreground="$foreground">$encode($tab)</span>""" + def get_title_label(title): """ @@ -41,6 +47,7 @@ def get_title_label(title): hbox.pack_start(label, False, False, padding=11) return hbox + class PropsDialog(gtk.Dialog): """ A dialog to set block parameters, view errors, and view documentation. @@ -48,57 +55,68 @@ class PropsDialog(gtk.Dialog): def __init__(self, block): """ - Properties dialog contructor. + Properties dialog constructor. Args: block: a block instance """ self._hash = 0 - LABEL_SPACING = 7 - gtk.Dialog.__init__(self, - title='Properties: %s'%block.get_name(), + + gtk.Dialog.__init__( + self, + title='Properties: %s' % block.get_name(), buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT), ) self._block = block self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT) - vbox = gtk.VBox() - #Create the scrolled window to hold all the parameters - scrolled_window = gtk.ScrolledWindow() - scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - scrolled_window.add_with_viewport(vbox) - self.vbox.pack_start(scrolled_window, True) - #Params box for block parameters - self._params_box = gtk.VBox() - self._params_box.pack_start(get_title_label('Parameters'), False) - self._input_object_params = list() - #Error Messages for the block - self._error_box = gtk.VBox() - self._error_messages_text_display = TextDisplay() - self._error_box.pack_start(gtk.Label(), False, False, LABEL_SPACING) - self._error_box.pack_start(get_title_label('Error Messages'), False) - self._error_box.pack_start(self._error_messages_text_display, False) - #Docs for the block - self._docs_box = err_box = gtk.VBox() + + vpaned = gtk.VPaned() + self.vbox.pack_start(vpaned) + + # Notebook to hold param boxes + notebook = gtk.Notebook() + notebook.set_show_border(False) + notebook.set_scrollable(True) # scroll arrows for page tabs + notebook.set_tab_pos(gtk.POS_TOP) + vpaned.pack1(notebook, True) + + # Params boxes for block parameters + self._params_boxes = list() + for tab in block.get_param_tab_labels(): + label = gtk.Label() + vbox = gtk.VBox() + scroll_box = gtk.ScrolledWindow() + scroll_box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scroll_box.add_with_viewport(vbox) + notebook.append_page(scroll_box, label) + self._params_boxes.append((tab, label, vbox)) + + # Docs for the block self._docs_text_display = TextDisplay() - self._docs_box.pack_start(gtk.Label(), False, False, LABEL_SPACING) - self._docs_box.pack_start(get_title_label('Documentation'), False) - self._docs_box.pack_start(self._docs_text_display, False) - #Add the boxes - vbox.pack_start(self._params_box, False) - vbox.pack_start(self._error_box, False) - vbox.pack_start(self._docs_box, False) - #connect events + self._docs_box = gtk.ScrolledWindow() + self._docs_box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self._docs_box.add_with_viewport(self._docs_text_display) + notebook.append_page(self._docs_box, gtk.Label("Documentation")) + + # Error Messages for the block + self._error_messages_text_display = TextDisplay() + self._error_box = gtk.ScrolledWindow() + self._error_box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self._error_box.add_with_viewport(self._error_messages_text_display) + vpaned.pack2(self._error_box) + vpaned.set_position(int(0.65 * MIN_DIALOG_HEIGHT)) + + # Connect events self.connect('key-press-event', self._handle_key_press) self.connect('show', self._update_gui) - #show all (performs initial gui update) - self.show_all() + self.show_all() # show all (performs initial gui update) def _params_changed(self): """ Have the params in this dialog changed? Ex: Added, removed, type change, hide change... To the props dialog, the hide setting of 'none' and 'part' are identical. - Therfore, the props dialog only cares if the hide setting is/not 'all'. + Therefore, the props dialog only cares if the hide setting is/not 'all'. Make a hash that uniquely represents the params' state. Returns: @@ -113,7 +131,7 @@ class PropsDialog(gtk.Dialog): def _handle_changed(self, *args): """ - A change occured within a param: + A change occurred within a param: Rewrite/validate the block and update the gui. """ #update for the block @@ -123,7 +141,7 @@ class PropsDialog(gtk.Dialog): def _update_gui(self, *args): """ - Repopulate the parameters box (if changed). + Repopulate the parameters boxes (if changed). Update all the input parameters. Update the error messages box. Hide the box if there are no errors. @@ -133,28 +151,28 @@ class PropsDialog(gtk.Dialog): #update the params box if self._params_changed(): #hide params box before changing - self._params_box.hide_all() - #empty the params box - for io_param in list(self._input_object_params): - self._params_box.remove(io_param) - self._input_object_params.remove(io_param) - io_param.destroy() - #repopulate the params box - for param in self._block.get_params(): - if param.get_hide() == 'all': continue - io_param = param.get_input(self._handle_changed) - self._input_object_params.append(io_param) - self._params_box.pack_start(io_param, False) - #show params box with new params - self._params_box.show_all() + for tab, label, vbox in self._params_boxes: + vbox.hide_all() + # empty the params box + vbox.forall(lambda c: vbox.remove(c) or c.destroy()) + # repopulate the params box + box_all_valid = True + for param in filter(lambda p: p.get_tab_label() == tab, self._block.get_params()): + if param.get_hide() == 'all': + continue + box_all_valid = box_all_valid and param.is_valid() + vbox.pack_start(param.get_input(self._handle_changed), False) + label.set_markup(Utils.parse_template(TAB_LABEL_MARKUP_TMPL, valid=box_all_valid, tab=tab)) + #show params box with new params + vbox.show_all() #update the errors box - if self._block.is_valid(): self._error_box.hide() - else: self._error_box.show() + if self._block.is_valid(): + self._error_box.hide() + else: + self._error_box.show() messages = '\n\n'.join(self._block.get_error_messages()) self._error_messages_text_display.set_text(messages) #update the docs box - if self._block.get_doc(): self._docs_box.show() - else: self._docs_box.hide() self._docs_text_display.set_text(self._block.get_doc()) def _handle_key_press(self, widget, event): @@ -167,8 +185,8 @@ class PropsDialog(gtk.Dialog): """ if event.keyval == gtk.keysyms.Return: self.response(gtk.RESPONSE_ACCEPT) - return True #handled here - return False #forward the keypress + return True # handled here + return False # forward the keypress def run(self): """ diff --git a/grc/python/Constants.py b/grc/python/Constants.py index 0e974df43c..79ff8bab35 100644 --- a/grc/python/Constants.py +++ b/grc/python/Constants.py @@ -25,7 +25,10 @@ _gr_prefs = gr.prefs() #setup paths PATH_SEP = {'/':':', '\\':';'}[os.path.sep] -HIER_BLOCKS_LIB_DIR = os.path.join(os.path.expanduser('~'), '.grc_gnuradio') +HIER_BLOCKS_LIB_DIR = os.environ.get('GRC_HIER_PATH', + os.path.expanduser('~/.grc_gnuradio')) +PREFS_FILE = os.environ.get('GRC_PREFS_PATH', + os.path.join(os.path.expanduser('~/.grc'))) BLOCKS_DIRS = filter( #filter blank strings lambda x: x, PATH_SEP.join([ os.environ.get('GRC_BLOCKS_PATH', ''), diff --git a/grc/python/Param.py b/grc/python/Param.py index 3daa37f637..3d9e52e25f 100644 --- a/grc/python/Param.py +++ b/grc/python/Param.py @@ -19,13 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA from .. base.Param import Param as _Param from .. gui.Param import Param as _GUIParam -from .. gui.Param import EntryParam import Constants import numpy -import os -import pygtk -pygtk.require('2.0') -import gtk from gnuradio import eng_notation import re from gnuradio import gr @@ -33,41 +28,6 @@ from gnuradio import gr _check_id_matcher = re.compile('^[a-z|A-Z]\w*$') _show_id_matcher = re.compile('^(variable\w*|parameter|options|notebook)$') -class FileParam(EntryParam): - """Provide an entry box for filename and a button to browse for a file.""" - - def __init__(self, *args, **kwargs): - EntryParam.__init__(self, *args, **kwargs) - input = gtk.Button('...') - input.connect('clicked', self._handle_clicked) - self.pack_start(input, False) - - def _handle_clicked(self, widget=None): - """ - If the button was clicked, open a file dialog in open/save format. - Replace the text in the entry with the new filename from the file dialog. - """ - #get the paths - file_path = self.param.is_valid() and self.param.get_evaluated() or '' - (dirname, basename) = os.path.isfile(file_path) and os.path.split(file_path) or (file_path, '') - if not os.path.exists(dirname): dirname = os.getcwd() #fix bad paths - #build the dialog - if self.param.get_type() == 'file_open': - file_dialog = gtk.FileChooserDialog('Open a Data File...', None, - gtk.FILE_CHOOSER_ACTION_OPEN, ('gtk-cancel',gtk.RESPONSE_CANCEL,'gtk-open',gtk.RESPONSE_OK)) - elif self.param.get_type() == 'file_save': - file_dialog = gtk.FileChooserDialog('Save a Data File...', None, - gtk.FILE_CHOOSER_ACTION_SAVE, ('gtk-cancel',gtk.RESPONSE_CANCEL, 'gtk-save',gtk.RESPONSE_OK)) - file_dialog.set_do_overwrite_confirmation(True) - file_dialog.set_current_name(basename) #show the current filename - file_dialog.set_current_folder(dirname) #current directory - file_dialog.set_select_multiple(False) - file_dialog.set_local_only(True) - if gtk.RESPONSE_OK == file_dialog.run(): #run the dialog - file_path = file_dialog.get_filename() #get the file path - self._input.set_text(file_path) - self._handle_changed() - file_dialog.destroy() #destroy the dialog #blacklist certain ids, its not complete, but should help import __builtin__ @@ -162,10 +122,6 @@ class Param(_Param, _GUIParam): ################################################## return _truncate(dt_str, truncate) - def get_input(self, *args, **kwargs): - if self.get_type() in ('file_open', 'file_save'): return FileParam(self, *args, **kwargs) - return _GUIParam.get_input(self, *args, **kwargs) - def get_color(self): """ Get the color that represents this param's type. diff --git a/grc/python/Platform.py b/grc/python/Platform.py index f6adaf47a5..f4f55e9d16 100644 --- a/grc/python/Platform.py +++ b/grc/python/Platform.py @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA """ import os +from collections import OrderedDict from gnuradio import gr from .. base.Platform import Platform as _Platform from .. gui.Platform import Platform as _GUIPlatform @@ -29,7 +30,7 @@ from Param import Param as _Param from Generator import Generator from Constants import \ HIER_BLOCKS_LIB_DIR, BLOCK_DTD, \ - DEFAULT_FLOW_GRAPH, BLOCKS_DIRS + DEFAULT_FLOW_GRAPH, BLOCKS_DIRS, PREFS_FILE import Constants COLORS = [(name, color) for name, key, sizeof, color in Constants.CORE_TYPES] @@ -42,8 +43,10 @@ class Platform(_Platform, _GUIPlatform): """ #ensure hier dir if not os.path.exists(HIER_BLOCKS_LIB_DIR): os.mkdir(HIER_BLOCKS_LIB_DIR) - #convert block paths to absolute paths - block_paths = set(map(os.path.abspath, BLOCKS_DIRS)) + # Convert block paths to absolute paths: + # - Create a mapping from the absolute path to what was passed in + # - Keep each unique absolute path and maintain order + block_paths = OrderedDict(map(lambda x: (os.path.abspath(x), x), BLOCKS_DIRS)) #init _Platform.__init__( self, @@ -58,7 +61,11 @@ class Platform(_Platform, _GUIPlatform): generator=Generator, colors=COLORS, ) - _GUIPlatform.__init__(self) + + _GUIPlatform.__init__( + self, + prefs_file=PREFS_FILE + ) ############################################## # Constructors diff --git a/grc/python/block.dtd b/grc/python/block.dtd index 21ffbe09af..18e53fda2a 100644 --- a/grc/python/block.dtd +++ b/grc/python/block.dtd @@ -25,11 +25,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Top level element. A block contains a name, ...parameters list, and list of IO ports. --> -<!ELEMENT block (name, key, category?, throttle?, import*, var_make?, make, callback*, param*, bus_sink?, bus_source?, check*, sink*, source*, bus_structure_sink?, bus_structure_source?, doc?, grc_source?)> +<!ELEMENT block (name, key, category?, throttle?, import*, var_make?, make, callback*, param_tab_order?, param*, bus_sink?, bus_source?, check*, sink*, source*, bus_structure_sink?, bus_structure_source?, doc?, grc_source?)> <!-- Sub level elements. --> -<!ELEMENT param (name, key, value?, type, hide?, option*)> +<!ELEMENT param_tab_order (tab+)> +<!ELEMENT param (base_key?, name, key, value?, type?, hide?, option*, tab?)> <!ELEMENT option (name, key, opt*)> <!ELEMENT sink (name, type, vlen?, nports?, optional?)> <!ELEMENT source (name, type, vlen?, nports?, optional?)> @@ -41,7 +42,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA <!ELEMENT import (#PCDATA)> <!ELEMENT doc (#PCDATA)> <!ELEMENT grc_source (#PCDATA)> +<!ELEMENT tab (#PCDATA)> <!ELEMENT name (#PCDATA)> +<!ELEMENT base_key (#PCDATA)> <!ELEMENT key (#PCDATA)> <!ELEMENT check (#PCDATA)> <!ELEMENT bus_sink (#PCDATA)> diff --git a/volk/lib/qa_utils.cc b/volk/lib/qa_utils.cc index 8007fe75a6..f30f0097ae 100644 --- a/volk/lib/qa_utils.cc +++ b/volk/lib/qa_utils.cc @@ -14,6 +14,7 @@ #include <volk/volk.h> #include <volk/volk_cpu.h> #include <volk/volk_common.h> +#include <volk/volk_malloc.h> #include <boost/typeof/typeof.hpp> #include <boost/type_traits.hpp> #include <stdio.h> @@ -171,7 +172,7 @@ static void get_signatures_from_name(std::vector<volk_type_t> &inputsig, } //we don't need an output signature (some fn's operate on the input data, "in place"), but we do need at least one input! assert(inputsig.size() != 0); - + } inline void run_cast_test1(volk_fn_1arg func, std::vector<void *> &buffs, unsigned int vlen, unsigned int iter, std::string arch) { @@ -232,8 +233,8 @@ bool fcompare(t *in1, t *in2, unsigned int vlen, float tol) { bool fail = false; int print_max_errs = 10; for(unsigned int i=0; i<vlen; i++) { - // for very small numbers we'll see round off errors due to limited - // precision. So a special test case... + // for very small numbers we'll see round off errors due to limited + // precision. So a special test case... if(fabs(((t *)(in1))[i]) < 1e-30) { if( fabs( ((t *)(in2))[i] ) > tol ) { @@ -264,8 +265,8 @@ bool ccompare(t *in1, t *in2, unsigned int vlen, float tol) { t err = std::sqrt(diff[0] * diff[0] + diff[1] * diff[1]); t norm = std::sqrt(in1[i] * in1[i] + in1[i+1] * in1[i+1]); - // for very small numbers we'll see round off errors due to limited - // precision. So a special test case... + // for very small numbers we'll see round off errors due to limited + // precision. So a special test case... if (norm < 1e-30) { if (err > tol) { @@ -307,11 +308,17 @@ class volk_qa_aligned_mem_pool{ public: void *get_new(size_t size){ size_t alignment = volk_get_alignment(); - _mems.push_back(std::vector<char>(size + alignment-1, 0)); - size_t ptr = size_t(&_mems.back().front()); - return (void *)((ptr + alignment-1) & ~(alignment-1)); + void* ptr = volk_malloc(size, alignment); + memset(ptr, 0x00, size); + _mems.push_back(ptr); + return ptr; + } + ~volk_qa_aligned_mem_pool() { + for(unsigned int ii = 0; ii < _mems.size(); ++ii) { + volk_free(_mems[ii]); + } } -private: std::list<std::vector<char> > _mems; +private: std::vector<void * > _mems; }; bool run_volk_tests(volk_func_desc_t desc, @@ -337,7 +344,7 @@ bool run_volk_tests(volk_func_desc_t desc, // The bug is the casting/assignment below do not happen, which results in false // positives when testing for errors in fcompare and icompare. // Since this only happens on armhf (reported for Cortex A9 and A15) combined with - // the following fixes it is suspected to be a compiler bug. + // the following fixes it is suspected to be a compiler bug. // Bug 1272024 on launchpad has been filed with Linaro GCC. const float tol_f = tol*1.0000001; const unsigned int tol_i = static_cast<const unsigned int>(tol); @@ -357,7 +364,7 @@ bool run_volk_tests(volk_func_desc_t desc, //now we have to get a function signature by parsing the name std::vector<volk_type_t> inputsig, outputsig; get_signatures_from_name(inputsig, outputsig, name); - + //pull the input scalars into their own vector std::vector<volk_type_t> inputsc; for(size_t i=0; i<inputsig.size(); i++) { |