Merge branch 'release-2.5.0'

This commit is contained in:
Bill Somerville 2021-06-01 15:13:44 +01:00
commit d065cb1c36
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
240 changed files with 31277 additions and 2794 deletions

View File

@ -1,975 +0,0 @@
#.rst:
# BundleUtilities
# ---------------
#
# Functions to help assemble a standalone bundle application.
#
# A collection of CMake utility functions useful for dealing with .app
# bundles on the Mac and bundle-like directories on any OS.
#
# The following functions are provided by this module:
#
# ::
#
# fixup_bundle
# copy_and_fixup_bundle
# verify_app
# get_bundle_main_executable
# get_dotapp_dir
# get_bundle_and_executable
# get_bundle_all_executables
# get_item_key
# get_item_rpaths
# clear_bundle_keys
# set_bundle_key_values
# get_bundle_keys
# copy_resolved_item_into_bundle
# copy_resolved_framework_into_bundle
# fixup_bundle_item
# verify_bundle_prerequisites
# verify_bundle_symlinks
#
# Requires CMake 2.6 or greater because it uses function, break and
# PARENT_SCOPE. Also depends on GetPrerequisites.cmake.
#
# ::
#
# FIXUP_BUNDLE(<app> <libs> <dirs>)
#
# Fix up a bundle in-place and make it standalone, such that it can be
# drag-n-drop copied to another machine and run on that machine as long
# as all of the system libraries are compatible.
#
# If you pass plugins to fixup_bundle as the libs parameter, you should
# install them or copy them into the bundle before calling fixup_bundle.
# The "libs" parameter is a list of libraries that must be fixed up, but
# that cannot be determined by otool output analysis. (i.e., plugins)
#
# Gather all the keys for all the executables and libraries in a bundle,
# and then, for each key, copy each prerequisite into the bundle. Then
# fix each one up according to its own list of prerequisites.
#
# Then clear all the keys and call verify_app on the final bundle to
# ensure that it is truly standalone.
#
# ::
#
# COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>)
#
# Makes a copy of the bundle <src> at location <dst> and then fixes up
# the new copied bundle in-place at <dst>...
#
# ::
#
# VERIFY_APP(<app>)
#
# Verifies that an application <app> appears valid based on running
# analysis tools on it. Calls "message(FATAL_ERROR" if the application
# is not verified.
#
# ::
#
# GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>)
#
# The result will be the full path name of the bundle's main executable
# file or an "error:" prefixed string if it could not be determined.
#
# ::
#
# GET_DOTAPP_DIR(<exe> <dotapp_dir_var>)
#
# Returns the nearest parent dir whose name ends with ".app" given the
# full path to an executable. If there is no such parent dir, then
# simply return the dir containing the executable.
#
# The returned directory may or may not exist.
#
# ::
#
# GET_BUNDLE_AND_EXECUTABLE(<app> <bundle_var> <executable_var> <valid_var>)
#
# Takes either a ".app" directory name or the name of an executable
# nested inside a ".app" directory and returns the path to the ".app"
# directory in <bundle_var> and the path to its main executable in
# <executable_var>
#
# ::
#
# GET_BUNDLE_ALL_EXECUTABLES(<bundle> <exes_var>)
#
# Scans the given bundle recursively for all executable files and
# accumulates them into a variable.
#
# ::
#
# GET_ITEM_KEY(<item> <key_var>)
#
# Given a file (item) name, generate a key that should be unique
# considering the set of libraries that need copying or fixing up to
# make a bundle standalone. This is essentially the file name including
# extension with "." replaced by "_"
#
# This key is used as a prefix for CMake variables so that we can
# associate a set of variables with a given item based on its key.
#
# ::
#
# CLEAR_BUNDLE_KEYS(<keys_var>)
#
# Loop over the list of keys, clearing all the variables associated with
# each key. After the loop, clear the list of keys itself.
#
# Caller of get_bundle_keys should call clear_bundle_keys when done with
# list of keys.
#
# ::
#
# SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs>
# <copyflag> [<rpaths>])
#
# Add a key to the list (if necessary) for the given item. If added,
# also set all the variables associated with that key.
#
# ::
#
# GET_BUNDLE_KEYS(<app> <libs> <dirs> <keys_var>)
#
# Loop over all the executable and library files within the bundle (and
# given as extra <libs>) and accumulate a list of keys representing
# them. Set values associated with each key such that we can loop over
# all of them and copy prerequisite libs into the bundle and then do
# appropriate install_name_tool fixups.
#
# ::
#
# COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
#
# Copy a resolved item into the bundle if necessary. Copy is not
# necessary if the resolved_item is "the same as" the
# resolved_embedded_item.
#
# ::
#
# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
#
# Copy a resolved framework into the bundle if necessary. Copy is not
# necessary if the resolved_item is "the same as" the
# resolved_embedded_item.
#
# By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set. If you want
# full frameworks embedded in your bundles, set
# BU_COPY_FULL_FRAMEWORK_CONTENTS to ON before calling fixup_bundle. By
# default, COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE copies the framework
# dylib itself plus the framework Resources directory.
#
# ::
#
# FIXUP_BUNDLE_ITEM(<resolved_embedded_item> <exepath> <dirs>)
#
# Get the direct/non-system prerequisites of the resolved embedded item.
# For each prerequisite, change the way it is referenced to the value of
# the _EMBEDDED_ITEM keyed variable for that prerequisite. (Most likely
# changing to an "@executable_path" style reference.)
#
# This function requires that the resolved_embedded_item be "inside" the
# bundle already. In other words, if you pass plugins to fixup_bundle
# as the libs parameter, you should install them or copy them into the
# bundle before calling fixup_bundle. The "libs" parameter is a list of
# libraries that must be fixed up, but that cannot be determined by
# otool output analysis. (i.e., plugins)
#
# Also, change the id of the item being fixed up to its own
# _EMBEDDED_ITEM value.
#
# Accumulate changes in a local variable and make *one* call to
# install_name_tool at the end of the function with all the changes at
# once.
#
# If the BU_CHMOD_BUNDLE_ITEMS variable is set then bundle items will be
# marked writable before install_name_tool tries to change them.
#
# ::
#
# VERIFY_BUNDLE_PREREQUISITES(<bundle> <result_var> <info_var>)
#
# Verifies that the sum of all prerequisites of all files inside the
# bundle are contained within the bundle or are "system" libraries,
# presumed to exist everywhere.
#
# ::
#
# VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>)
#
# Verifies that any symlinks found in the bundle point to other files
# that are already also in the bundle... Anything that points to an
# external file causes this function to fail the verification.
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
# The functions defined in this file depend on the get_prerequisites function
# (and possibly others) found in:
#
get_filename_component(BundleUtilities_cmake_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
include("${BundleUtilities_cmake_dir}/GetPrerequisites.cmake")
function(get_bundle_main_executable bundle result_var)
set(result "error: '${bundle}/Contents/Info.plist' file does not exist")
if(EXISTS "${bundle}/Contents/Info.plist")
set(result "error: no CFBundleExecutable in '${bundle}/Contents/Info.plist' file")
set(line_is_main_executable 0)
set(bundle_executable "")
# Read Info.plist as a list of lines:
#
set(eol_char "E")
file(READ "${bundle}/Contents/Info.plist" info_plist)
string(REPLACE ";" "\\;" info_plist "${info_plist}")
string(REPLACE "\n" "${eol_char};" info_plist "${info_plist}")
string(REPLACE "\r" "${eol_char};" info_plist "${info_plist}")
# Scan the lines for "<key>CFBundleExecutable</key>" - the line after that
# is the name of the main executable.
#
foreach(line ${info_plist})
if(line_is_main_executable)
string(REGEX REPLACE "^.*<string>(.*)</string>.*$" "\\1" bundle_executable "${line}")
break()
endif()
if(line MATCHES "<key>CFBundleExecutable</key>")
set(line_is_main_executable 1)
endif()
endforeach()
if(NOT "${bundle_executable}" STREQUAL "")
if(EXISTS "${bundle}/Contents/MacOS/${bundle_executable}")
set(result "${bundle}/Contents/MacOS/${bundle_executable}")
else()
# Ultimate goal:
# If not in "Contents/MacOS" then scan the bundle for matching files. If
# there is only one executable file that matches, then use it, otherwise
# it's an error...
#
#file(GLOB_RECURSE file_list "${bundle}/${bundle_executable}")
# But for now, pragmatically, it's an error. Expect the main executable
# for the bundle to be in Contents/MacOS, it's an error if it's not:
#
set(result "error: '${bundle}/Contents/MacOS/${bundle_executable}' does not exist")
endif()
endif()
else()
#
# More inclusive technique... (This one would work on Windows and Linux
# too, if a developer followed the typical Mac bundle naming convention...)
#
# If there is no Info.plist file, try to find an executable with the same
# base name as the .app directory:
#
endif()
set(${result_var} "${result}" PARENT_SCOPE)
endfunction()
function(get_dotapp_dir exe dotapp_dir_var)
set(s "${exe}")
if(s MATCHES "/.*\\.app/")
# If there is a ".app" parent directory,
# ascend until we hit it:
# (typical of a Mac bundle executable)
#
set(done 0)
while(NOT ${done})
get_filename_component(snamewe "${s}" NAME_WE)
get_filename_component(sname "${s}" NAME)
get_filename_component(sdir "${s}" PATH)
set(s "${sdir}")
if(sname MATCHES "\\.app$")
set(done 1)
set(dotapp_dir "${sdir}/${sname}")
endif()
endwhile()
else()
# Otherwise use a directory containing the exe
# (typical of a non-bundle executable on Mac, Windows or Linux)
#
is_file_executable("${s}" is_executable)
if(is_executable)
get_filename_component(sdir "${s}" PATH)
set(dotapp_dir "${sdir}")
else()
set(dotapp_dir "${s}")
endif()
endif()
set(${dotapp_dir_var} "${dotapp_dir}" PARENT_SCOPE)
endfunction()
function(get_bundle_and_executable app bundle_var executable_var valid_var)
set(valid 0)
if(EXISTS "${app}")
# Is it a directory ending in .app?
if(IS_DIRECTORY "${app}")
if(app MATCHES "\\.app$")
get_bundle_main_executable("${app}" executable)
if(EXISTS "${app}" AND EXISTS "${executable}")
set(${bundle_var} "${app}" PARENT_SCOPE)
set(${executable_var} "${executable}" PARENT_SCOPE)
set(valid 1)
#message(STATUS "info: handled .app directory case...")
else()
message(STATUS "warning: *NOT* handled - .app directory case...")
endif()
else()
message(STATUS "warning: *NOT* handled - directory but not .app case...")
endif()
else()
# Is it an executable file?
is_file_executable("${app}" is_executable)
if(is_executable)
get_dotapp_dir("${app}" dotapp_dir)
if(EXISTS "${dotapp_dir}")
set(${bundle_var} "${dotapp_dir}" PARENT_SCOPE)
set(${executable_var} "${app}" PARENT_SCOPE)
set(valid 1)
#message(STATUS "info: handled executable file in .app dir case...")
else()
get_filename_component(app_dir "${app}" PATH)
set(${bundle_var} "${app_dir}" PARENT_SCOPE)
set(${executable_var} "${app}" PARENT_SCOPE)
set(valid 1)
#message(STATUS "info: handled executable file in any dir case...")
endif()
else()
message(STATUS "warning: *NOT* handled - not .app dir, not executable file...")
endif()
endif()
else()
message(STATUS "warning: *NOT* handled - directory/file does not exist...")
endif()
if(NOT valid)
set(${bundle_var} "error: not a bundle" PARENT_SCOPE)
set(${executable_var} "error: not a bundle" PARENT_SCOPE)
endif()
set(${valid_var} ${valid} PARENT_SCOPE)
endfunction()
function(get_bundle_all_executables bundle exes_var)
set(exes "")
if(UNIX)
find_program(find_cmd "find")
mark_as_advanced(find_cmd)
endif()
# find command is much quicker than checking every file one by one on Unix
# which can take long time for large bundles, and since anyway we expect
# executable to have execute flag set we can narrow the list much quicker.
if(find_cmd)
execute_process(COMMAND "${find_cmd}" "${bundle}"
-type f \( -perm -0100 -o -perm -0010 -o -perm -0001 \)
OUTPUT_VARIABLE file_list
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REPLACE "\n" ";" file_list "${file_list}")
else()
file(GLOB_RECURSE file_list "${bundle}/*")
endif()
foreach(f ${file_list})
is_file_executable("${f}" is_executable)
if(is_executable)
set(exes ${exes} "${f}")
endif()
endforeach()
set(${exes_var} "${exes}" PARENT_SCOPE)
endfunction()
function(get_item_rpaths item rpaths_var)
if(APPLE)
find_program(otool_cmd "otool")
mark_as_advanced(otool_cmd)
endif()
if(otool_cmd)
execute_process(
COMMAND "${otool_cmd}" -l "${item}"
OUTPUT_VARIABLE load_cmds_ov
)
string(REGEX REPLACE "[^\n]+cmd LC_RPATH\n[^\n]+\n[^\n]+path ([^\n]+) \\(offset[^\n]+\n" "rpath \\1\n" load_cmds_ov "${load_cmds_ov}")
string(REGEX MATCHALL "rpath [^\n]+" load_cmds_ov "${load_cmds_ov}")
string(REGEX REPLACE "rpath " "" load_cmds_ov "${load_cmds_ov}")
if(load_cmds_ov)
gp_append_unique(${rpaths_var} "${load_cmds_ov}")
endif()
endif()
set(${rpaths_var} ${${rpaths_var}} PARENT_SCOPE)
endfunction()
function(get_item_key item key_var)
get_filename_component(item_name "${item}" NAME)
if(WIN32)
string(TOLOWER "${item_name}" item_name)
endif()
string(REPLACE "." "_" ${key_var} "${item_name}")
set(${key_var} ${${key_var}} PARENT_SCOPE)
endfunction()
function(clear_bundle_keys keys_var)
foreach(key ${${keys_var}})
set(${key}_ITEM PARENT_SCOPE)
set(${key}_RESOLVED_ITEM PARENT_SCOPE)
set(${key}_DEFAULT_EMBEDDED_PATH PARENT_SCOPE)
set(${key}_EMBEDDED_ITEM PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM PARENT_SCOPE)
set(${key}_COPYFLAG PARENT_SCOPE)
set(${key}_RPATHS PARENT_SCOPE)
endforeach()
set(${keys_var} PARENT_SCOPE)
endfunction()
function(set_bundle_key_values keys_var context item exepath dirs copyflag)
if(ARGC GREATER 6)
set(rpaths "${ARGV6}")
else()
set(rpaths "")
endif()
get_filename_component(item_name "${item}" NAME)
get_item_key("${item}" key)
list(LENGTH ${keys_var} length_before)
gp_append_unique(${keys_var} "${key}")
list(LENGTH ${keys_var} length_after)
if(NOT length_before EQUAL length_after)
gp_resolve_item("${context}" "${item}" "${exepath}" "${dirs}" resolved_item "${rpaths}")
gp_item_default_embedded_path("${item}" default_embedded_path)
get_item_rpaths("${resolved_item}" item_rpaths)
if(item MATCHES "[^/]+\\.framework/")
# For frameworks, construct the name under the embedded path from the
# opening "${item_name}.framework/" to the closing "/${item_name}":
#
string(REGEX REPLACE "^.*(${item_name}.framework/.*/?${item_name}).*$" "${default_embedded_path}/\\1" embedded_item "${item}")
else()
# For other items, just use the same name as the original, but in the
# embedded path:
#
set(embedded_item "${default_embedded_path}/${item_name}")
endif()
# Replace @executable_path and resolve ".." references:
#
string(REPLACE "@executable_path" "${exepath}" resolved_embedded_item "${embedded_item}")
get_filename_component(resolved_embedded_item "${resolved_embedded_item}" ABSOLUTE)
# *But* -- if we are not copying, then force resolved_embedded_item to be
# the same as resolved_item. In the case of multiple executables in the
# original bundle, using the default_embedded_path results in looking for
# the resolved executable next to the main bundle executable. This is here
# so that exes in the other sibling directories (like "bin") get fixed up
# properly...
#
if(NOT copyflag)
set(resolved_embedded_item "${resolved_item}")
endif()
set(${keys_var} ${${keys_var}} PARENT_SCOPE)
set(${key}_ITEM "${item}" PARENT_SCOPE)
set(${key}_RESOLVED_ITEM "${resolved_item}" PARENT_SCOPE)
set(${key}_DEFAULT_EMBEDDED_PATH "${default_embedded_path}" PARENT_SCOPE)
set(${key}_EMBEDDED_ITEM "${embedded_item}" PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM "${resolved_embedded_item}" PARENT_SCOPE)
set(${key}_COPYFLAG "${copyflag}" PARENT_SCOPE)
set(${key}_RPATHS "${item_rpaths}" PARENT_SCOPE)
set(${key}_RDEP_RPATHS "${rpaths}" PARENT_SCOPE)
else()
#message("warning: item key '${key}' already in the list, subsequent references assumed identical to first")
endif()
endfunction()
function(get_bundle_keys app libs dirs keys_var)
set(${keys_var} PARENT_SCOPE)
get_bundle_and_executable("${app}" bundle executable valid)
if(valid)
# Always use the exepath of the main bundle executable for @executable_path
# replacements:
#
get_filename_component(exepath "${executable}" PATH)
# But do fixups on all executables in the bundle:
#
get_bundle_all_executables("${bundle}" exes)
# Set keys for main executable first:
#
set_bundle_key_values(${keys_var} "${executable}" "${executable}" "${exepath}" "${dirs}" 0)
# Get rpaths specified by main executable:
#
get_item_key("${executable}" executable_key)
set(main_rpaths "${${executable_key}_RPATHS}")
# For each extra lib, accumulate a key as well and then also accumulate
# any of its prerequisites. (Extra libs are typically dynamically loaded
# plugins: libraries that are prerequisites for full runtime functionality
# but that do not show up in otool -L output...)
#
foreach(lib ${libs})
set_bundle_key_values(${keys_var} "${lib}" "${lib}" "${exepath}" "${dirs}" 0 "${main_rpaths}")
set(prereqs "")
get_prerequisites("${lib}" prereqs 1 1 "${exepath}" "${dirs}" "${main_rpaths}")
foreach(pr ${prereqs})
set_bundle_key_values(${keys_var} "${lib}" "${pr}" "${exepath}" "${dirs}" 1 "${main_rpaths}")
endforeach()
endforeach()
# For each executable found in the bundle, accumulate keys as we go.
# The list of keys should be complete when all prerequisites of all
# binaries in the bundle have been analyzed.
#
foreach(exe ${exes})
# Main executable is scanned first above:
#
if(NOT "${exe}" STREQUAL "${executable}")
# Add the exe itself to the keys:
#
set_bundle_key_values(${keys_var} "${exe}" "${exe}" "${exepath}" "${dirs}" 0 "${main_rpaths}")
# Get rpaths specified by executable:
#
get_item_key("${exe}" exe_key)
set(exe_rpaths "${main_rpaths}" "${${exe_key}_RPATHS}")
else()
set(exe_rpaths "${main_rpaths}")
endif()
# Add each prerequisite to the keys:
#
set(prereqs "")
get_prerequisites("${exe}" prereqs 1 1 "${exepath}" "${dirs}" "${exe_rpaths}")
foreach(pr ${prereqs})
set_bundle_key_values(${keys_var} "${exe}" "${pr}" "${exepath}" "${dirs}" 1 "${exe_rpaths}")
endforeach()
endforeach()
# Propagate values to caller's scope:
#
set(${keys_var} ${${keys_var}} PARENT_SCOPE)
foreach(key ${${keys_var}})
set(${key}_ITEM "${${key}_ITEM}" PARENT_SCOPE)
set(${key}_RESOLVED_ITEM "${${key}_RESOLVED_ITEM}" PARENT_SCOPE)
set(${key}_DEFAULT_EMBEDDED_PATH "${${key}_DEFAULT_EMBEDDED_PATH}" PARENT_SCOPE)
set(${key}_EMBEDDED_ITEM "${${key}_EMBEDDED_ITEM}" PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM "${${key}_RESOLVED_EMBEDDED_ITEM}" PARENT_SCOPE)
set(${key}_COPYFLAG "${${key}_COPYFLAG}" PARENT_SCOPE)
set(${key}_RPATHS "${${key}_RPATHS}" PARENT_SCOPE)
set(${key}_RDEP_RPATHS "${${key}_RDEP_RPATHS}" PARENT_SCOPE)
endforeach()
endif()
endfunction()
function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item)
if(WIN32)
# ignore case on Windows
string(TOLOWER "${resolved_item}" resolved_item_compare)
string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
else()
set(resolved_item_compare "${resolved_item}")
set(resolved_embedded_item_compare "${resolved_embedded_item}")
endif()
if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
else()
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
if(UNIX AND NOT APPLE)
file(RPATH_REMOVE FILE "${resolved_embedded_item}")
endif()
endif()
endfunction()
function(copy_resolved_framework_into_bundle resolved_item resolved_embedded_item)
if(WIN32)
# ignore case on Windows
string(TOLOWER "${resolved_item}" resolved_item_compare)
string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
else()
set(resolved_item_compare "${resolved_item}")
set(resolved_embedded_item_compare "${resolved_embedded_item}")
endif()
if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
else()
if(BU_COPY_FULL_FRAMEWORK_CONTENTS)
# Full Framework (everything):
get_filename_component(resolved_dir "${resolved_item}" PATH)
get_filename_component(resolved_dir "${resolved_dir}/../.." ABSOLUTE)
get_filename_component(resolved_embedded_dir "${resolved_embedded_item}" PATH)
get_filename_component(resolved_embedded_dir "${resolved_embedded_dir}/../.." ABSOLUTE)
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_dir}' '${resolved_embedded_dir}'")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${resolved_dir}" "${resolved_embedded_dir}")
else()
# Framework lib itself:
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
# Plus Resources, if they exist:
string(REGEX REPLACE "^(.*)/[^/]+$" "\\1/Resources" resolved_resources "${resolved_item}")
string(REGEX REPLACE "^(.*)/[^/]+$" "\\1/Resources" resolved_embedded_resources "${resolved_embedded_item}")
if(EXISTS "${resolved_resources}")
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_resources}' '${resolved_embedded_resources}'")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${resolved_resources}" "${resolved_embedded_resources}")
endif()
# Some frameworks e.g. Qt put Info.plist in wrong place, so when it is
# missing in resources, copy it from other well known incorrect locations:
if(NOT EXISTS "${resolved_resources}/Info.plist")
# Check for Contents/Info.plist in framework root (older Qt SDK):
string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1/Contents/Info.plist" resolved_info_plist "${resolved_item}")
string(REGEX REPLACE "^(.*)/[^/]+$" "\\1/Resources/Info.plist" resolved_embedded_info_plist "${resolved_embedded_item}")
if(EXISTS "${resolved_info_plist}")
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_info_plist}' '${resolved_embedded_info_plist}'")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_info_plist}" "${resolved_embedded_info_plist}")
endif()
endif()
# Check if framework is versioned and fix it layout
string(REGEX REPLACE "^.*/([^/]+)/[^/]+$" "\\1" resolved_embedded_version "${resolved_embedded_item}")
string(REGEX REPLACE "^(.*)/[^/]+/[^/]+$" "\\1" resolved_embedded_versions "${resolved_embedded_item}")
string(REGEX REPLACE "^.*/([^/]+)/[^/]+/[^/]+$" "\\1" resolved_embedded_versions_basename "${resolved_embedded_item}")
if(resolved_embedded_versions_basename STREQUAL "Versions")
# Ensure Current symlink points to the framework version
if(NOT EXISTS "${resolved_embedded_versions}/Current")
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${resolved_embedded_version}" "${resolved_embedded_versions}/Current")
endif()
# Restore symlinks in framework root pointing to current framework
# binary and resources:
string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1" resolved_embedded_root "${resolved_embedded_item}")
string(REGEX REPLACE "^.*/([^/]+)$" "\\1" resolved_embedded_item_basename "${resolved_embedded_item}")
if(NOT EXISTS "${resolved_embedded_root}/${resolved_embedded_item_basename}")
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "Versions/Current/${resolved_embedded_item_basename}" "${resolved_embedded_root}/${resolved_embedded_item_basename}")
endif()
if(NOT EXISTS "${resolved_embedded_root}/Resources")
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "Versions/Current/Resources" "${resolved_embedded_root}/Resources")
endif()
endif()
endif()
if(UNIX AND NOT APPLE)
file(RPATH_REMOVE FILE "${resolved_embedded_item}")
endif()
endif()
endfunction()
function(fixup_bundle_item resolved_embedded_item exepath dirs)
# This item's key is "ikey":
#
get_item_key("${resolved_embedded_item}" ikey)
# Ensure the item is "inside the .app bundle" -- it should not be fixed up if
# it is not in the .app bundle... Otherwise, we'll modify files in the build
# tree, or in other varied locations around the file system, with our call to
# install_name_tool. Make sure that doesn't happen here:
#
get_dotapp_dir("${exepath}" exe_dotapp_dir)
string(LENGTH "${exe_dotapp_dir}/" exe_dotapp_dir_length)
string(LENGTH "${resolved_embedded_item}" resolved_embedded_item_length)
set(path_too_short 0)
set(is_embedded 0)
if(${resolved_embedded_item_length} LESS ${exe_dotapp_dir_length})
set(path_too_short 1)
endif()
if(NOT path_too_short)
string(SUBSTRING "${resolved_embedded_item}" 0 ${exe_dotapp_dir_length} item_substring)
if("${exe_dotapp_dir}/" STREQUAL "${item_substring}")
set(is_embedded 1)
endif()
endif()
if(NOT is_embedded)
message(" exe_dotapp_dir/='${exe_dotapp_dir}/'")
message(" item_substring='${item_substring}'")
message(" resolved_embedded_item='${resolved_embedded_item}'")
message("")
message("Install or copy the item into the bundle before calling fixup_bundle.")
message("Or maybe there's a typo or incorrect path in one of the args to fixup_bundle?")
message("")
message(FATAL_ERROR "cannot fixup an item that is not in the bundle...")
endif()
set(rpaths "${${ikey}_RPATHS}" "${${ikey}_RDEP_RPATHS}")
set(prereqs "")
get_prerequisites("${resolved_embedded_item}" prereqs 1 0 "${exepath}" "${dirs}" "${rpaths}")
set(changes "")
foreach(pr ${prereqs})
# Each referenced item's key is "rkey" in the loop:
#
get_item_key("${pr}" rkey)
if(NOT "${${rkey}_EMBEDDED_ITEM}" STREQUAL "")
set(changes ${changes} "-change" "${pr}" "${${rkey}_EMBEDDED_ITEM}")
else()
message("warning: unexpected reference to '${pr}'")
endif()
endforeach()
if(BU_CHMOD_BUNDLE_ITEMS)
execute_process(COMMAND chmod u+w "${resolved_embedded_item}")
endif()
# Only if install_name_tool supports -delete_rpath:
#
execute_process(COMMAND install_name_tool
OUTPUT_VARIABLE install_name_tool_usage
ERROR_VARIABLE install_name_tool_usage
)
if(install_name_tool_usage MATCHES ".*-delete_rpath.*")
foreach(rpath ${${ikey}_RPATHS})
set(changes ${changes} -delete_rpath "${rpath}")
endforeach()
endif()
if(${ikey}_EMBEDDED_ITEM)
set(changes ${changes} -id "${${ikey}_EMBEDDED_ITEM}")
endif()
# Change this item's id and all of its references in one call
# to install_name_tool:
#
if(changes)
set(cmd install_name_tool ${changes} "${resolved_embedded_item}")
execute_process(COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result)
if(NOT install_name_tool_result EQUAL 0)
string(REPLACE ";" "' '" msg "'${cmd}'")
message(FATAL_ERROR "Command failed:\n ${msg}")
endif()
endif()
endfunction()
function(fixup_bundle app libs dirs)
message(STATUS "fixup_bundle")
message(STATUS " app='${app}'")
message(STATUS " libs='${libs}'")
message(STATUS " dirs='${dirs}'")
get_bundle_and_executable("${app}" bundle executable valid)
if(valid)
get_filename_component(exepath "${executable}" PATH)
message(STATUS "fixup_bundle: preparing...")
get_bundle_keys("${app}" "${libs}" "${dirs}" keys)
message(STATUS "fixup_bundle: copying...")
list(LENGTH keys n)
math(EXPR n ${n}*2)
set(i 0)
foreach(key ${keys})
math(EXPR i ${i}+1)
if(${${key}_COPYFLAG})
message(STATUS "${i}/${n}: copying '${${key}_RESOLVED_ITEM}'")
else()
message(STATUS "${i}/${n}: *NOT* copying '${${key}_RESOLVED_ITEM}'")
endif()
set(show_status 0)
if(show_status)
message(STATUS "key='${key}'")
message(STATUS "item='${${key}_ITEM}'")
message(STATUS "resolved_item='${${key}_RESOLVED_ITEM}'")
message(STATUS "default_embedded_path='${${key}_DEFAULT_EMBEDDED_PATH}'")
message(STATUS "embedded_item='${${key}_EMBEDDED_ITEM}'")
message(STATUS "resolved_embedded_item='${${key}_RESOLVED_EMBEDDED_ITEM}'")
message(STATUS "copyflag='${${key}_COPYFLAG}'")
message(STATUS "")
endif()
if(${${key}_COPYFLAG})
set(item "${${key}_ITEM}")
if(item MATCHES "[^/]+\\.framework/")
copy_resolved_framework_into_bundle("${${key}_RESOLVED_ITEM}"
"${${key}_RESOLVED_EMBEDDED_ITEM}")
else()
copy_resolved_item_into_bundle("${${key}_RESOLVED_ITEM}"
"${${key}_RESOLVED_EMBEDDED_ITEM}")
endif()
endif()
endforeach()
message(STATUS "fixup_bundle: fixing...")
foreach(key ${keys})
math(EXPR i ${i}+1)
if(APPLE)
message(STATUS "${i}/${n}: fixing up '${${key}_RESOLVED_EMBEDDED_ITEM}'")
fixup_bundle_item("${${key}_RESOLVED_EMBEDDED_ITEM}" "${exepath}" "${dirs}")
else()
message(STATUS "${i}/${n}: fix-up not required on this platform '${${key}_RESOLVED_EMBEDDED_ITEM}'")
endif()
endforeach()
message(STATUS "fixup_bundle: cleaning up...")
clear_bundle_keys(keys)
message(STATUS "fixup_bundle: verifying...")
verify_app("${app}")
else()
message(SEND_ERROR "error: fixup_bundle: not a valid bundle")
endif()
message(STATUS "fixup_bundle: done")
endfunction()
function(copy_and_fixup_bundle src dst libs dirs)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${src}" "${dst}")
fixup_bundle("${dst}" "${libs}" "${dirs}")
endfunction()
function(verify_bundle_prerequisites bundle result_var info_var)
set(result 1)
set(info "")
set(count 0)
get_bundle_main_executable("${bundle}" main_bundle_exe)
get_bundle_all_executables("${bundle}" file_list)
foreach(f ${file_list})
get_filename_component(exepath "${f}" PATH)
math(EXPR count "${count} + 1")
message(STATUS "executable file ${count}: ${f}")
set(prereqs "")
get_prerequisites("${f}" prereqs 1 1 "${exepath}" "")
# On the Mac,
# "embedded" and "system" prerequisites are fine... anything else means
# the bundle's prerequisites are not verified (i.e., the bundle is not
# really "standalone")
#
# On Windows (and others? Linux/Unix/...?)
# "local" and "system" prereqs are fine...
#
set(external_prereqs "")
foreach(p ${prereqs})
set(p_type "")
gp_file_type("${f}" "${p}" p_type)
if(APPLE)
if(NOT "${p_type}" STREQUAL "embedded" AND NOT "${p_type}" STREQUAL "system")
set(external_prereqs ${external_prereqs} "${p}")
endif()
else()
if(NOT "${p_type}" STREQUAL "local" AND NOT "${p_type}" STREQUAL "system")
set(external_prereqs ${external_prereqs} "${p}")
endif()
endif()
endforeach()
if(external_prereqs)
# Found non-system/somehow-unacceptable prerequisites:
set(result 0)
set(info ${info} "external prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
endif()
endforeach()
if(result)
set(info "Verified ${count} executable files in '${bundle}'")
endif()
set(${result_var} "${result}" PARENT_SCOPE)
set(${info_var} "${info}" PARENT_SCOPE)
endfunction()
function(verify_bundle_symlinks bundle result_var info_var)
set(result 1)
set(info "")
set(count 0)
# TODO: implement this function for real...
# Right now, it is just a stub that verifies unconditionally...
set(${result_var} "${result}" PARENT_SCOPE)
set(${info_var} "${info}" PARENT_SCOPE)
endfunction()
function(verify_app app)
set(verified 0)
set(info "")
get_bundle_and_executable("${app}" bundle executable valid)
message(STATUS "===========================================================================")
message(STATUS "Analyzing app='${app}'")
message(STATUS "bundle='${bundle}'")
message(STATUS "executable='${executable}'")
message(STATUS "valid='${valid}'")
# Verify that the bundle does not have any "external" prerequisites:
#
verify_bundle_prerequisites("${bundle}" verified info)
message(STATUS "verified='${verified}'")
message(STATUS "info='${info}'")
message(STATUS "")
if(verified)
# Verify that the bundle does not have any symlinks to external files:
#
verify_bundle_symlinks("${bundle}" verified info)
message(STATUS "verified='${verified}'")
message(STATUS "info='${info}'")
message(STATUS "")
endif()
if(NOT verified)
message(FATAL_ERROR "error: verify_app failed")
endif()
endfunction()

View File

@ -0,0 +1,64 @@
#
# Find the hamlib library
#
# This will define the following variables::
#
# Hamlib_FOUND - True if the system has the usb library
# Hamlib_VERSION - The verion of the usb library which was found
#
# and the following imported targets::
#
# Hamlib::Hamlib - The hamlib library
#
include (LibFindMacros)
libfind_pkg_detect (Hamlib hamlib
FIND_PATH hamlib/rig.h PATH_SUFFIXES hamlib
FIND_LIBRARY hamlib
)
libfind_package (Hamlib Usb)
libfind_process (Hamlib)
if (NOT Hamlib_PKGCONF_FOUND)
if (WIN32)
set (Hamlib_LIBRARIES ${Hamlib_LIBRARIES};${Usb_LIBRARY};ws2_32)
else ()
set (Hamlib_LIBRARIES ${Hamlib_LIBRARIES};m;dl)
endif ()
elseif (UNIX AND NOT APPLE)
set (Hamlib_LIBRARIES ${Hamlib_PKGCONF_STATIC_LDFLAGS})
endif ()
# fix up extra link libraries for macOS as target_link_libraries gets
# it wrong for frameworks
unset (_next_is_framework)
unset (_Hamlib_EXTRA_LIBS)
foreach (_lib IN LISTS Hamlib_LIBRARIES Hamlib_PKGCONF_LDFLAGS)
if (_next_is_framework)
list (APPEND _Hamlib_EXTRA_LIBS "-framework ${_lib}")
unset (_next_is_framework)
elseif (${_lib} STREQUAL "-framework")
set (_next_is_framework TRUE)
else ()
list (APPEND _Hamlib_EXTRA_LIBS ${_lib})
endif ()
endforeach ()
if (Hamlib_FOUND AND NOT TARGET Hamlib::Hamlib)
add_library (Hamlib::Hamlib UNKNOWN IMPORTED)
set_target_properties (Hamlib::Hamlib PROPERTIES
IMPORTED_LOCATION "${Hamlib_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${Hamlib_PKGCONF_STATIC_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${Hamlib_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${_Hamlib_EXTRA_LIBS}"
)
endif ()
mark_as_advanced (
Hamlib_INCLUDE_DIR
Hamlib_LIBRARY
Hamlib_LIBRARIES
)

View File

@ -0,0 +1,50 @@
# - Try to find portaudio
#
# Once done, this will define:
#
# Portaudio_FOUND - system has portaudio
# Portaudio_VERSION - The version of the portaudio library which was found
#
# and the following imported targets::
#
# Portaudio::Portaudio - The portaudio library
#
include (LibFindMacros)
libfind_pkg_detect (Portaudio portaudio-2.0
FIND_PATH portaudio.h
FIND_LIBRARY portaudio
)
libfind_process (Portaudio)
# fix up extra link libraries for macOS as target_link_libraries gets
# it wrong for frameworks
unset (_next_is_framework)
unset (_Portaudio_EXTRA_LIBS)
foreach (_lib IN LISTS Portaudio_PKGCONF_LDFLAGS)
if (_next_is_framework)
list (APPEND _Portaudio_EXTRA_LIBS "-framework ${_lib}")
unset (_next_is_framework)
elseif (${_lib} STREQUAL "-framework")
set (_next_is_framework TRUE)
else ()
list (APPEND _Portaudio_EXTRA_LIBS ${_lib})
endif ()
endforeach ()
if (Portaudio_FOUND AND NOT TARGET Portaudio::Portaudio)
add_library (Portaudio::Portaudio UNKNOWN IMPORTED)
set_target_properties (Portaudio::Portaudio PROPERTIES
IMPORTED_LOCATION "${Portaudio_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${Portaudio_PKGCONF_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${Portaudio_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${_Portaudio_EXTRA_LIBS}"
)
endif ()
mark_as_advanced (
Portaudio_INCLUDE_DIR
Portaudio_LIBRARY
)

View File

@ -0,0 +1,49 @@
# Findlibusb
# ==========
#
# Find the usb library
#
# This will define the following variables::
#
# Usb_FOUND - True if the system has the usb library
# Usb_VERSION - The verion of the usb library which was found
#
# and the following imported targets::
#
# Usb::Usb - The libusb library
#
include (LibFindMacros)
if (WIN32)
# Use path suffixes on MS Windows as we probably shouldn't
# trust the PATH envvar. PATH will still be searched to find the
# library as last resort.
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
set (_library_options PATH_SUFFIXES MinGW64/dll MinGW64/static)
else ()
set (_library_options PATH_SUFFIXES MinGW32/dll MinGW32/static)
endif ()
endif ()
libfind_pkg_detect (Usb usb-1.0
FIND_PATH libusb.h PATH_SUFFIXES libusb-1.0
FIND_LIBRARY usb-1.0 ${_library_options}
)
libfind_process (Usb)
if (Usb_FOUND AND NOT TARGET Usb::Usb)
add_library (Usb::Usb UNKNOWN IMPORTED)
set_target_properties (Usb::Usb PROPERTIES
IMPORTED_LOCATION "${Usb_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${Usb_PKGCONF_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${Usb_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${Usb_LIBRARIES}"
)
endif ()
mark_as_advanced (
Usb_INCLUDE_DIR
Usb_LIBRARY
Usb_LIBRARIES
)

View File

@ -1,88 +0,0 @@
# - Try to find hamlib
#
# Once done, this will define:
#
# hamlib_FOUND - system has Hamlib
# hamlib_INCLUDE_DIRS - the Hamlib include directories
# hamlib_LIBRARIES - link these to use Hamlib
# hamlib_LIBRARY_DIRS - required shared/dynamic libraries are here
#
# If hamlib_STATIC is TRUE then static linking will be assumed
#
include (LibFindMacros)
set (hamlib_LIBRARY_DIRS)
# pkg-config?
find_path (__hamlib_pc_path NAMES hamlib.pc
PATH_SUFFIXES lib/pkgconfig lib64/pkgconfig
)
if (__hamlib_pc_path)
set (__pc_path $ENV{PKG_CONFIG_PATH})
list (APPEND __pc_path "${__hamlib_pc_path}")
set (ENV{PKG_CONFIG_PATH} "${__pc_path}")
unset (__pc_path CACHE)
endif ()
unset (__hamlib_pc_path CACHE)
# Use pkg-config to get hints about paths, libs and, flags
unset (__pkg_config_checked_hamlib CACHE)
# pkg_config will fail on Windows if the Hamlib USB backends are
# configured since libusb-1.0 does not ship with a pkg_config file on
# Windows, that's OK because we fix it up below
libfind_pkg_check_modules (PC_HAMLIB hamlib)
if (NOT PC_HAMLIB_FOUND)
# The headers
find_path (hamlib_INCLUDEDIR hamlib/rig.h)
# The libraries
if (hamlib_STATIC)
libfind_library (hamlib libhamlib.a)
else ()
libfind_library (hamlib hamlib)
endif ()
if (WIN32)
set (hamlib_EXTRA_LIBRARIES ws2_32)
else ()
set (hamlib_EXTRA_LIBRARIES m dl)
endif ()
# libusb-1.0 has no pkg-config file on Windows so we have to find it
# ourselves
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
find_library (LIBUSB NAMES usb-1.0 PATH_SUFFIXES MinGW64/dll)
else ()
find_library (LIBUSB NAMES usb-1.0 PATH_SUFFIXES MinGW32/dll)
endif ()
if (LIBUSB)
set (hamlib_EXTRA_LIBRARIES ${LIBUSB} ${hamlib_EXTRA_LIBRARIES})
get_filename_component (hamlib_libusb_path ${LIBUSB} PATH)
set (hamlib_LIBRARY_DIRS ${hamlib_LIBRARY_DIRS} ${hamlib_libusb_path})
endif (LIBUSB)
set (hamlib_PROCESS_INCLUDES hamlib_INCLUDEDIR)
set (hamlib_PROCESS_LIBS hamlib_LIBRARY hamlib_EXTRA_LIBRARIES)
else ()
if (hamlib_STATIC)
set (hamlib_PROCESS_INCLUDES PC_HAMLIB_STATIC_INCLUDE_DIRS)
set (hamlib_PROCESS_LIBS PC_HAMLIB_STATIC_LDFLAGS)
set (hamlib_LIBRARY_DIRS ${PC_HAMLIB_STATIC_LIBRARY_DIRS})
else ()
set (hamlib_PROCESS_INCLUDES PC_HAMLIB_INCLUDE_DIRS)
set (hamlib_PROCESS_LIBS PC_HAMLIB_LDFLAGS)
set (hamlib_LIBRARY_DIRS ${PC_HAMLIB_LIBRARY_DIRS})
endif ()
endif ()
libfind_process (hamlib)
if (WIN32)
find_path (hamlib_dll_path libhamlib-2.dll)
if (hamlib_dll_path)
set (hamlib_LIBRARY_DIRS ${hamlib_LIBRARY_DIRS} ${hamlib_dll_path})
endif ()
endif ()
# Handle the QUIETLY and REQUIRED arguments and set HAMLIB_FOUND to
# TRUE if all listed variables are TRUE
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (hamlib DEFAULT_MSG hamlib_INCLUDE_DIRS hamlib_LIBRARIES hamlib_LIBRARY_DIRS)

View File

@ -1,998 +0,0 @@
#.rst:
# GetPrerequisites
# ----------------
#
# Functions to analyze and list executable file prerequisites.
#
# This module provides functions to list the .dll, .dylib or .so files
# that an executable or shared library file depends on. (Its
# prerequisites.)
#
# It uses various tools to obtain the list of required shared library
# files:
#
# ::
#
# dumpbin (Windows)
# objdump (MinGW on Windows)
# ldd (Linux/Unix)
# otool (Mac OSX)
#
# The following functions are provided by this module:
#
# ::
#
# get_prerequisites
# list_prerequisites
# list_prerequisites_by_glob
# gp_append_unique
# is_file_executable
# gp_item_default_embedded_path
# (projects can override with gp_item_default_embedded_path_override)
# gp_resolve_item
# (projects can override with gp_resolve_item_override)
# gp_resolved_file_type
# (projects can override with gp_resolved_file_type_override)
# gp_file_type
#
# Requires CMake 2.6 or greater because it uses function, break, return
# and PARENT_SCOPE.
#
# ::
#
# GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse>
# <exepath> <dirs> [<rpaths>])
#
# Get the list of shared library files required by <target>. The list
# in the variable named <prerequisites_var> should be empty on first
# entry to this function. On exit, <prerequisites_var> will contain the
# list of required shared library files.
#
# <target> is the full path to an executable file. <prerequisites_var>
# is the name of a CMake variable to contain the results.
# <exclude_system> must be 0 or 1 indicating whether to include or
# exclude "system" prerequisites. If <recurse> is set to 1 all
# prerequisites will be found recursively, if set to 0 only direct
# prerequisites are listed. <exepath> is the path to the top level
# executable used for @executable_path replacment on the Mac. <dirs> is
# a list of paths where libraries might be found: these paths are
# searched first when a target without any path info is given. Then
# standard system locations are also searched: PATH, Framework
# locations, /usr/lib...
#
# ::
#
# LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]])
#
# Print a message listing the prerequisites of <target>.
#
# <target> is the name of a shared library or executable target or the
# full path to a shared library or executable file. If <recurse> is set
# to 1 all prerequisites will be found recursively, if set to 0 only
# direct prerequisites are listed. <exclude_system> must be 0 or 1
# indicating whether to include or exclude "system" prerequisites. With
# <verbose> set to 0 only the full path names of the prerequisites are
# printed, set to 1 extra informatin will be displayed.
#
# ::
#
# LIST_PREREQUISITES_BY_GLOB(<glob_arg> <glob_exp>)
#
# Print the prerequisites of shared library and executable files
# matching a globbing pattern. <glob_arg> is GLOB or GLOB_RECURSE and
# <glob_exp> is a globbing expression used with "file(GLOB" or
# "file(GLOB_RECURSE" to retrieve a list of matching files. If a
# matching file is executable, its prerequisites are listed.
#
# Any additional (optional) arguments provided are passed along as the
# optional arguments to the list_prerequisites calls.
#
# ::
#
# GP_APPEND_UNIQUE(<list_var> <value>)
#
# Append <value> to the list variable <list_var> only if the value is
# not already in the list.
#
# ::
#
# IS_FILE_EXECUTABLE(<file> <result_var>)
#
# Return 1 in <result_var> if <file> is a binary executable, 0
# otherwise.
#
# ::
#
# GP_ITEM_DEFAULT_EMBEDDED_PATH(<item> <default_embedded_path_var>)
#
# Return the path that others should refer to the item by when the item
# is embedded inside a bundle.
#
# Override on a per-project basis by providing a project-specific
# gp_item_default_embedded_path_override function.
#
# ::
#
# GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>
# [<rpaths>])
#
# Resolve an item into an existing full path file.
#
# Override on a per-project basis by providing a project-specific
# gp_resolve_item_override function.
#
# ::
#
# GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>
# [<rpaths>])
#
# Return the type of <file> with respect to <original_file>. String
# describing type of prerequisite is returned in variable named
# <type_var>.
#
# Use <exepath> and <dirs> if necessary to resolve non-absolute <file>
# values -- but only for non-embedded items.
#
# Possible types are:
#
# ::
#
# system
# local
# embedded
# other
#
# Override on a per-project basis by providing a project-specific
# gp_resolved_file_type_override function.
#
# ::
#
# GP_FILE_TYPE(<original_file> <file> <type_var>)
#
# Return the type of <file> with respect to <original_file>. String
# describing type of prerequisite is returned in variable named
# <type_var>.
#
# Possible types are:
#
# ::
#
# system
# local
# embedded
# other
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
function(gp_append_unique list_var value)
set(contains 0)
foreach(item ${${list_var}})
if(item STREQUAL "${value}")
set(contains 1)
break()
endif()
endforeach()
if(NOT contains)
set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
endif()
endfunction()
function(is_file_executable file result_var)
#
# A file is not executable until proven otherwise:
#
set(${result_var} 0 PARENT_SCOPE)
get_filename_component(file_full "${file}" ABSOLUTE)
string(TOLOWER "${file_full}" file_full_lower)
# If file name ends in .exe on Windows, *assume* executable:
#
if(WIN32 AND NOT UNIX)
if("${file_full_lower}" MATCHES "\\.exe$")
set(${result_var} 1 PARENT_SCOPE)
return()
endif()
# A clause could be added here that uses output or return value of dumpbin
# to determine ${result_var}. In 99%+? practical cases, the exe name
# match will be sufficient...
#
endif()
# Use the information returned from the Unix shell command "file" to
# determine if ${file_full} should be considered an executable file...
#
# If the file command's output contains "executable" and does *not* contain
# "text" then it is likely an executable suitable for prerequisite analysis
# via the get_prerequisites macro.
#
if(UNIX)
if(NOT file_cmd)
find_program(file_cmd "file")
mark_as_advanced(file_cmd)
endif()
if(file_cmd)
execute_process(COMMAND "${file_cmd}" "${file_full}"
RESULT_VARIABLE file_rv
OUTPUT_VARIABLE file_ov
ERROR_VARIABLE file_ev
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT file_rv STREQUAL "0")
message(FATAL_ERROR "${file_cmd} failed: ${file_rv}\n${file_ev}")
endif()
# Replace the name of the file in the output with a placeholder token
# (the string " _file_full_ ") so that just in case the path name of
# the file contains the word "text" or "executable" we are not fooled
# into thinking "the wrong thing" because the file name matches the
# other 'file' command output we are looking for...
#
string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}")
string(TOLOWER "${file_ov}" file_ov)
#message(STATUS "file_ov='${file_ov}'")
if("${file_ov}" MATCHES "executable")
#message(STATUS "executable!")
if("${file_ov}" MATCHES "text")
#message(STATUS "but text, so *not* a binary executable!")
else()
set(${result_var} 1 PARENT_SCOPE)
return()
endif()
endif()
# Also detect position independent executables on Linux,
# where "file" gives "shared object ... (uses shared libraries)"
if("${file_ov}" MATCHES "shared object.*\(uses shared libs\)")
set(${result_var} 1 PARENT_SCOPE)
return()
endif()
# "file" version 5.22 does not print "(used shared libraries)"
# but uses "interpreter"
if("${file_ov}" MATCHES "shared object.*interpreter")
set(${result_var} 1 PARENT_SCOPE)
return()
endif()
else()
message(STATUS "warning: No 'file' command, skipping execute_process...")
endif()
endif()
endfunction()
function(gp_item_default_embedded_path item default_embedded_path_var)
# On Windows and Linux, "embed" prerequisites in the same directory
# as the executable by default:
#
set(path "@executable_path")
set(overridden 0)
# On the Mac, relative to the executable depending on the type
# of the thing we are embedding:
#
if(APPLE)
#
# The assumption here is that all executables in the bundle will be
# in same-level-directories inside the bundle. The parent directory
# of an executable inside the bundle should be MacOS or a sibling of
# MacOS and all embedded paths returned from here will begin with
# "@executable_path/../" and will work from all executables in all
# such same-level-directories inside the bundle.
#
# By default, embed things right next to the main bundle executable:
#
set(path "@executable_path/../../Contents/MacOS")
# Embed .dylibs right next to the main bundle executable:
#
if(item MATCHES "\\.dylib$")
set(path "@executable_path/../MacOS")
set(overridden 1)
endif()
# Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
#
if(NOT overridden)
if(item MATCHES "[^/]+\\.framework/")
set(path "@executable_path/../Frameworks")
set(overridden 1)
endif()
endif()
endif()
# Provide a hook so that projects can override the default embedded location
# of any given library by whatever logic they choose:
#
if(COMMAND gp_item_default_embedded_path_override)
gp_item_default_embedded_path_override("${item}" path)
endif()
set(${default_embedded_path_var} "${path}" PARENT_SCOPE)
endfunction()
function(gp_resolve_item context item exepath dirs resolved_item_var)
set(resolved 0)
set(resolved_item "${item}")
if(ARGC GREATER 5)
set(rpaths "${ARGV5}")
else()
set(rpaths "")
endif()
# Is it already resolved?
#
if(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
set(resolved 1)
endif()
if(NOT resolved)
if(item MATCHES "^@executable_path")
#
# @executable_path references are assumed relative to exepath
#
string(REPLACE "@executable_path" "${exepath}" ri "${item}")
get_filename_component(ri "${ri}" ABSOLUTE)
if(EXISTS "${ri}")
#message(STATUS "info: embedded item exists (${ri})")
set(resolved 1)
set(resolved_item "${ri}")
else()
message(STATUS "warning: embedded item does not exist '${ri}'")
endif()
endif()
endif()
if(NOT resolved)
if(item MATCHES "^@loader_path")
#
# @loader_path references are assumed relative to the
# PATH of the given "context" (presumably another library)
#
get_filename_component(contextpath "${context}" PATH)
string(REPLACE "@loader_path" "${contextpath}" ri "${item}")
get_filename_component(ri "${ri}" ABSOLUTE)
if(EXISTS "${ri}")
#message(STATUS "info: embedded item exists (${ri})")
set(resolved 1)
set(resolved_item "${ri}")
else()
message(STATUS "warning: embedded item does not exist '${ri}'")
endif()
endif()
endif()
if(NOT resolved)
if(item MATCHES "^@rpath")
#
# @rpath references are relative to the paths built into the binaries with -rpath
# We handle this case like we do for other Unixes
#
string(REPLACE "@rpath/" "" norpath_item "${item}")
set(ri "ri-NOTFOUND")
find_file(ri "${norpath_item}" ${exepath} ${dirs} ${rpaths} NO_DEFAULT_PATH)
if(ri)
#message(STATUS "info: 'find_file' in exepath/dirs/rpaths (${ri})")
set(resolved 1)
set(resolved_item "${ri}")
set(ri "ri-NOTFOUND")
endif()
endif()
endif()
if(NOT resolved)
set(ri "ri-NOTFOUND")
find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
if(ri)
#message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
set(resolved 1)
set(resolved_item "${ri}")
set(ri "ri-NOTFOUND")
endif()
endif()
if(NOT resolved)
if(item MATCHES "[^/]+\\.framework/")
set(fw "fw-NOTFOUND")
find_file(fw "${item}"
"~/Library/Frameworks"
"/Library/Frameworks"
"/System/Library/Frameworks"
)
if(fw)
#message(STATUS "info: 'find_file' found framework (${fw})")
set(resolved 1)
set(resolved_item "${fw}")
set(fw "fw-NOTFOUND")
endif()
endif()
endif()
# Using find_program on Windows will find dll files that are in the PATH.
# (Converting simple file names into full path names if found.)
#
if(WIN32 AND NOT UNIX)
if(NOT resolved)
set(ri "ri-NOTFOUND")
find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
find_program(ri "${item}" PATHS "${exepath};${dirs}")
if(ri)
#message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
set(resolved 1)
set(resolved_item "${ri}")
set(ri "ri-NOTFOUND")
endif()
endif()
endif()
# Provide a hook so that projects can override item resolution
# by whatever logic they choose:
#
if(COMMAND gp_resolve_item_override)
gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved)
endif()
if(NOT resolved)
message(STATUS "
warning: cannot resolve item '${item}'
possible problems:
need more directories?
need to use InstallRequiredSystemLibraries?
run in install tree instead of build tree?
")
# message(STATUS "
#******************************************************************************
#warning: cannot resolve item '${item}'
#
# possible problems:
# need more directories?
# need to use InstallRequiredSystemLibraries?
# run in install tree instead of build tree?
#
# context='${context}'
# item='${item}'
# exepath='${exepath}'
# dirs='${dirs}'
# resolved_item_var='${resolved_item_var}'
#******************************************************************************
#")
endif()
set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
endfunction()
function(gp_resolved_file_type original_file file exepath dirs type_var)
if(ARGC GREATER 5)
set(rpaths "${ARGV5}")
else()
set(rpaths "")
endif()
#message(STATUS "**")
if(NOT IS_ABSOLUTE "${original_file}")
message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
endif()
set(is_embedded 0)
set(is_local 0)
set(is_system 0)
set(resolved_file "${file}")
if("${file}" MATCHES "^@(executable|loader)_path")
set(is_embedded 1)
endif()
if(NOT is_embedded)
if(NOT IS_ABSOLUTE "${file}")
gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file "${rpaths}")
endif()
string(TOLOWER "${original_file}" original_lower)
string(TOLOWER "${resolved_file}" lower)
if(UNIX)
if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/|/usr/bin/)")
set(is_system 1)
endif()
endif()
if(APPLE)
if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
set(is_system 1)
endif()
endif()
if(WIN32)
string(TOLOWER "$ENV{SystemRoot}" sysroot)
file(TO_CMAKE_PATH "${sysroot}" sysroot)
string(TOLOWER "$ENV{windir}" windir)
file(TO_CMAKE_PATH "${windir}" windir)
if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
set(is_system 1)
endif()
if(UNIX)
# if cygwin, we can get the properly formed windows paths from cygpath
find_program(CYGPATH_EXECUTABLE cygpath)
if(CYGPATH_EXECUTABLE)
execute_process(COMMAND ${CYGPATH_EXECUTABLE} -W
RESULT_VARIABLE env_rv
OUTPUT_VARIABLE env_windir
ERROR_VARIABLE env_ev
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT env_rv STREQUAL "0")
message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -W failed: ${env_rv}\n${env_ev}")
endif()
execute_process(COMMAND ${CYGPATH_EXECUTABLE} -S
RESULT_VARIABLE env_rv
OUTPUT_VARIABLE env_sysdir
ERROR_VARIABLE env_ev
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT env_rv STREQUAL "0")
message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -S failed: ${env_rv}\n${env_ev}")
endif()
string(TOLOWER "${env_windir}" windir)
string(TOLOWER "${env_sysdir}" sysroot)
if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
set(is_system 1)
endif()
endif()
endif()
endif()
if(NOT is_system)
get_filename_component(original_path "${original_lower}" PATH)
get_filename_component(path "${lower}" PATH)
if(original_path STREQUAL path)
set(is_local 1)
else()
string(LENGTH "${original_path}/" original_length)
string(LENGTH "${lower}" path_length)
if(${path_length} GREATER ${original_length})
string(SUBSTRING "${lower}" 0 ${original_length} path)
if("${original_path}/" STREQUAL path)
set(is_embedded 1)
endif()
endif()
endif()
endif()
endif()
# Return type string based on computed booleans:
#
set(type "other")
if(is_system)
set(type "system")
elseif(is_embedded)
set(type "embedded")
elseif(is_local)
set(type "local")
endif()
#message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
#message(STATUS " type: '${type}'")
if(NOT is_embedded)
if(NOT IS_ABSOLUTE "${resolved_file}")
if(lower MATCHES "^msvc[^/]+dll" AND is_system)
message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
else()
message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
endif()
endif()
endif()
# Provide a hook so that projects can override the decision on whether a
# library belongs to the system or not by whatever logic they choose:
#
if(COMMAND gp_resolved_file_type_override)
gp_resolved_file_type_override("${resolved_file}" type)
endif()
set(${type_var} "${type}" PARENT_SCOPE)
#message(STATUS "**")
endfunction()
function(gp_file_type original_file file type_var)
if(NOT IS_ABSOLUTE "${original_file}")
message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
endif()
get_filename_component(exepath "${original_file}" PATH)
set(type "")
gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)
set(${type_var} "${type}" PARENT_SCOPE)
endfunction()
function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
set(verbose 0)
set(eol_char "E")
if(ARGC GREATER 6)
set(rpaths "${ARGV6}")
else()
set(rpaths "")
endif()
if(NOT IS_ABSOLUTE "${target}")
message("warning: target '${target}' is not absolute...")
endif()
if(NOT EXISTS "${target}")
message("warning: target '${target}' does not exist...")
endif()
set(gp_cmd_paths ${gp_cmd_paths}
"C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
"C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
"C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
"C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
"C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
"C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
"/usr/local/bin"
"/usr/bin"
)
# <setup-gp_tool-vars>
#
# Try to choose the right tool by default. Caller can set gp_tool prior to
# calling this function to force using a different tool.
#
if(NOT gp_tool)
set(gp_tool "ldd")
if(APPLE)
set(gp_tool "otool")
endif()
if(WIN32 AND NOT UNIX) # This is how to check for cygwin, har!
find_program(gp_dumpbin "dumpbin" PATHS ${gp_cmd_paths})
if(gp_dumpbin)
set(gp_tool "dumpbin")
else() # Try harder. Maybe we're on MinGW
set(gp_tool "objdump")
endif()
endif()
endif()
find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
if(NOT gp_cmd)
message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
return()
endif()
set(gp_cmd_maybe_filter) # optional command to pre-filter gp_tool results
if(gp_tool STREQUAL "ldd")
set(gp_cmd_args "")
set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$")
set(gp_regex_error "not found${eol_char}$")
set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$")
set(gp_regex_cmp_count 1)
elseif(gp_tool STREQUAL "otool")
set(gp_cmd_args "-L")
set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
set(gp_regex_error "")
set(gp_regex_fallback "")
set(gp_regex_cmp_count 3)
elseif(gp_tool STREQUAL "dumpbin")
set(gp_cmd_args "/dependents")
set(gp_regex "^ ([^ ].*[Dd][Ll][Ll])${eol_char}$")
set(gp_regex_error "")
set(gp_regex_fallback "")
set(gp_regex_cmp_count 1)
elseif(gp_tool STREQUAL "objdump")
set(gp_cmd_args "-p")
set(gp_regex "^\t*DLL Name: (.*\\.[Dd][Ll][Ll])${eol_char}$")
set(gp_regex_error "")
set(gp_regex_fallback "")
set(gp_regex_cmp_count 1)
# objdump generaates copious output so we create a grep filter to pre-filter results
find_program(gp_grep_cmd grep)
if(gp_grep_cmd)
set(gp_cmd_maybe_filter COMMAND ${gp_grep_cmd} "^[[:blank:]]*DLL Name: ")
endif()
else()
message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
message(STATUS "Valid gp_tool values are dumpbin, ldd, objdump and otool.")
return()
endif()
if(gp_tool STREQUAL "dumpbin")
# When running dumpbin, it also needs the "Common7/IDE" directory in the
# PATH. It will already be in the PATH if being run from a Visual Studio
# command prompt. Add it to the PATH here in case we are running from a
# different command prompt.
#
get_filename_component(gp_cmd_dir "${gp_cmd}" PATH)
get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE)
# Use cmake paths as a user may have a PATH element ending with a backslash.
# This will escape the list delimiter and create havoc!
if(EXISTS "${gp_cmd_dlls_dir}")
# only add to the path if it is not already in the path
set(gp_found_cmd_dlls_dir 0)
file(TO_CMAKE_PATH "$ENV{PATH}" env_path)
foreach(gp_env_path_element ${env_path})
if(gp_env_path_element STREQUAL gp_cmd_dlls_dir)
set(gp_found_cmd_dlls_dir 1)
endif()
endforeach()
if(NOT gp_found_cmd_dlls_dir)
file(TO_NATIVE_PATH "${gp_cmd_dlls_dir}" gp_cmd_dlls_dir)
set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}")
endif()
endif()
endif()
#
# </setup-gp_tool-vars>
if(gp_tool STREQUAL "ldd")
set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
set(new_ld_env "${exepath}")
foreach(dir ${dirs})
set(new_ld_env "${new_ld_env}:${dir}")
endforeach()
set(ENV{LD_LIBRARY_PATH} "${new_ld_env}:$ENV{LD_LIBRARY_PATH}")
endif()
# Track new prerequisites at each new level of recursion. Start with an
# empty list at each level:
#
set(unseen_prereqs)
# Run gp_cmd on the target:
#
execute_process(
COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
${gp_cmd_maybe_filter}
RESULT_VARIABLE gp_rv
OUTPUT_VARIABLE gp_cmd_ov
ERROR_VARIABLE gp_ev
)
if(NOT gp_rv STREQUAL "0")
if(gp_tool STREQUAL "dumpbin")
# dumpbin error messages seem to go to stdout
message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}\n${gp_cmd_ov}")
else()
message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}")
endif()
endif()
if(gp_tool STREQUAL "ldd")
set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
endif()
if(verbose)
message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
message(STATUS "gp_cmd_ov='${gp_cmd_ov}'")
message(STATUS "</RawOutput>")
endif()
get_filename_component(target_dir "${target}" PATH)
# Convert to a list of lines:
#
string(REPLACE ";" "\\;" candidates "${gp_cmd_ov}")
string(REPLACE "\n" "${eol_char};" candidates "${candidates}")
# check for install id and remove it from list, since otool -L can include a
# reference to itself
set(gp_install_id)
if(gp_tool STREQUAL "otool")
execute_process(
COMMAND otool -D ${target}
RESULT_VARIABLE otool_rv
OUTPUT_VARIABLE gp_install_id_ov
ERROR_VARIABLE otool_ev
)
if(NOT otool_rv STREQUAL "0")
message(FATAL_ERROR "otool -D failed: ${otool_rv}\n${otool_ev}")
endif()
# second line is install name
string(REGEX REPLACE ".*:\n" "" gp_install_id "${gp_install_id_ov}")
if(gp_install_id)
# trim
string(REGEX MATCH "[^\n ].*[^\n ]" gp_install_id "${gp_install_id}")
#message("INSTALL ID is \"${gp_install_id}\"")
endif()
endif()
# Analyze each line for file names that match the regular expression:
#
foreach(candidate ${candidates})
if("${candidate}" MATCHES "${gp_regex}")
# Extract information from each candidate:
if(gp_regex_error AND "${candidate}" MATCHES "${gp_regex_error}")
string(REGEX REPLACE "${gp_regex_fallback}" "\\1" raw_item "${candidate}")
else()
string(REGEX REPLACE "${gp_regex}" "\\1" raw_item "${candidate}")
endif()
if(gp_regex_cmp_count GREATER 1)
string(REGEX REPLACE "${gp_regex}" "\\2" raw_compat_version "${candidate}")
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}")
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}")
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}")
endif()
if(gp_regex_cmp_count GREATER 2)
string(REGEX REPLACE "${gp_regex}" "\\3" raw_current_version "${candidate}")
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}")
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}")
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}")
endif()
# Use the raw_item as the list entries returned by this function. Use the
# gp_resolve_item function to resolve it to an actual full path file if
# necessary.
#
set(item "${raw_item}")
# Add each item unless it is excluded:
#
set(add_item 1)
if(item STREQUAL gp_install_id)
set(add_item 0)
endif()
if(add_item AND ${exclude_system})
set(type "")
gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type "${rpaths}")
if(type STREQUAL "system")
set(add_item 0)
endif()
endif()
if(add_item)
list(LENGTH ${prerequisites_var} list_length_before_append)
gp_append_unique(${prerequisites_var} "${item}")
list(LENGTH ${prerequisites_var} list_length_after_append)
if(${recurse})
# If item was really added, this is the first time we have seen it.
# Add it to unseen_prereqs so that we can recursively add *its*
# prerequisites...
#
# But first: resolve its name to an absolute full path name such
# that the analysis tools can simply accept it as input.
#
if(NOT list_length_before_append EQUAL list_length_after_append)
gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item "${rpaths}")
set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
endif()
endif()
endif()
else()
if(verbose)
message(STATUS "ignoring non-matching line: '${candidate}'")
endif()
endif()
endforeach()
list(LENGTH ${prerequisites_var} prerequisites_var_length)
if(prerequisites_var_length GREATER 0)
list(SORT ${prerequisites_var})
endif()
if(${recurse})
set(more_inputs ${unseen_prereqs})
foreach(input ${more_inputs})
get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}" "${rpaths}")
endforeach()
endif()
set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE)
endfunction()
function(list_prerequisites target)
if(ARGC GREATER 1 AND NOT "${ARGV1}" STREQUAL "")
set(all "${ARGV1}")
else()
set(all 1)
endif()
if(ARGC GREATER 2 AND NOT "${ARGV2}" STREQUAL "")
set(exclude_system "${ARGV2}")
else()
set(exclude_system 0)
endif()
if(ARGC GREATER 3 AND NOT "${ARGV3}" STREQUAL "")
set(verbose "${ARGV3}")
else()
set(verbose 0)
endif()
set(count 0)
set(count_str "")
set(print_count "${verbose}")
set(print_prerequisite_type "${verbose}")
set(print_target "${verbose}")
set(type_str "")
get_filename_component(exepath "${target}" PATH)
set(prereqs "")
get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "")
if(print_target)
message(STATUS "File '${target}' depends on:")
endif()
foreach(d ${prereqs})
math(EXPR count "${count} + 1")
if(print_count)
set(count_str "${count}. ")
endif()
if(print_prerequisite_type)
gp_file_type("${target}" "${d}" type)
set(type_str " (${type})")
endif()
message(STATUS "${count_str}${d}${type_str}")
endforeach()
endfunction()
function(list_prerequisites_by_glob glob_arg glob_exp)
message(STATUS "=============================================================================")
message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'")
message(STATUS "")
file(${glob_arg} file_list ${glob_exp})
foreach(f ${file_list})
is_file_executable("${f}" is_f_executable)
if(is_f_executable)
message(STATUS "=============================================================================")
list_prerequisites("${f}" ${ARGN})
message(STATUS "")
endif()
endforeach()
endfunction()

View File

@ -1,46 +1,101 @@
# Version 1.0 (2013-04-12)
# Public Domain, originally written by Lasse Kärkkäinen <tronic@zi.fi>
# Published at http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
# Version 2.3
# Public Domain, originally written by Lasse Kärkkäinen <tronic>
# Maintained at https://github.com/Tronic/cmake-modules
# Please send your improvements as pull requests on Github.
# If you improve the script, please modify the forementioned wiki page because
# I no longer maintain my scripts (hosted as static files at zi.fi). Feel free
# to remove this entire header if you use real version control instead.
# Changelog:
# 2013-04-12 Added version number (1.0) and this header, no other changes
# 2009-10-08 Originally published
# Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments
# used for the current package. For this to work, the first parameter must be the
# prefix of the current package, then the prefix of the new package etc, which are
# passed to find_package.
macro (libfind_package PREFIX)
set (LIBFIND_PACKAGE_ARGS ${ARGN})
if (${PREFIX}_FIND_QUIETLY)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET)
endif (${PREFIX}_FIND_QUIETLY)
# Find another package and make it a dependency of the current package.
# This also automatically forwards the "REQUIRED" argument.
# Usage: libfind_package(<prefix> <another package> [extra args to find_package])
macro (libfind_package PREFIX PKG)
set(${PREFIX}_args ${PKG} ${ARGN})
if (${PREFIX}_FIND_REQUIRED)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED)
endif (${PREFIX}_FIND_REQUIRED)
find_package(${LIBFIND_PACKAGE_ARGS})
endmacro (libfind_package)
set(${PREFIX}_args ${${PREFIX}_args} REQUIRED)
endif()
find_package(${${PREFIX}_args})
set(${PREFIX}_DEPENDENCIES ${${PREFIX}_DEPENDENCIES};${PKG})
unset(${PREFIX}_args)
endmacro()
# CMake developers made the UsePkgConfig system deprecated in the same release (2.6)
# where they added pkg_check_modules. Consequently I need to support both in my scripts
# to avoid those deprecated warnings. Here's a helper that does just that.
# Works identically to pkg_check_modules, except that no checks are needed prior to use.
macro (libfind_pkg_check_modules PREFIX PKGNAME)
if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
include(UsePkgConfig)
pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS)
else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(${PREFIX} ${PKGNAME})
endif (PKG_CONFIG_FOUND)
endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
endmacro (libfind_pkg_check_modules)
# A simple wrapper to make pkg-config searches a bit easier.
# Works the same as CMake's internal pkg_check_modules but is always quiet.
macro (libfind_pkg_check_modules)
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(${ARGN} QUIET)
endif()
endmacro()
# Avoid useless copy&pasta by doing what most simple libraries do anyway:
# pkg-config, find headers, find library.
# Usage: libfind_pkg_detect(<prefix> <pkg-config args> FIND_PATH <name> [other args] FIND_LIBRARY <name> [other args])
# E.g. libfind_pkg_detect(SDL2 sdl2 FIND_PATH SDL.h PATH_SUFFIXES SDL2 FIND_LIBRARY SDL2)
function (libfind_pkg_detect PREFIX)
# Parse arguments
set(argname pkgargs)
foreach (i ${ARGN})
if ("${i}" STREQUAL "FIND_PATH")
set(argname pathargs)
elseif ("${i}" STREQUAL "FIND_LIBRARY")
set(argname libraryargs)
else()
set(${argname} ${${argname}} ${i})
endif()
endforeach()
if (NOT pkgargs)
message(FATAL_ERROR "libfind_pkg_detect requires at least a pkg_config package name to be passed.")
endif()
# Find library
libfind_pkg_check_modules(${PREFIX}_PKGCONF ${pkgargs})
if (pathargs)
find_path(${PREFIX}_INCLUDE_DIR NAMES ${pathargs} HINTS ${${PREFIX}_PKGCONF_INCLUDE_DIRS})
endif()
if (libraryargs)
find_library(${PREFIX}_LIBRARY NAMES ${libraryargs} HINTS ${${PREFIX}_PKGCONF_LIBRARY_DIRS})
endif()
# Read pkg-config version
if (${PREFIX}_PKGCONF_VERSION)
set(${PREFIX}_VERSION ${${PREFIX}_PKGCONF_VERSION} PARENT_SCOPE)
endif()
endfunction()
# Extracts a version #define from a version.h file, output stored to <PREFIX>_VERSION.
# Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR)
# Fourth argument "QUIET" may be used for silently testing different define names.
# This function does nothing if the version variable is already defined.
function (libfind_version_header PREFIX VERSION_H DEFINE_NAME)
# Skip processing if we already have a version or if the include dir was not found
if (${PREFIX}_VERSION OR NOT ${PREFIX}_INCLUDE_DIR)
return()
endif()
set(quiet ${${PREFIX}_FIND_QUIETLY})
# Process optional arguments
foreach(arg ${ARGN})
if (arg STREQUAL "QUIET")
set(quiet TRUE)
else()
message(AUTHOR_WARNING "Unknown argument ${arg} to libfind_version_header ignored.")
endif()
endforeach()
# Read the header and parse for version number
set(filename "${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
if (NOT EXISTS ${filename})
if (NOT quiet)
message(AUTHOR_WARNING "Unable to find ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
endif()
return()
endif()
file(READ "${filename}" header)
string(REGEX REPLACE ".*#[ \t]*define[ \t]*${DEFINE_NAME}[ \t]*\"([^\n]*)\".*" "\\1" match "${header}")
# No regex match?
if (match STREQUAL header)
if (NOT quiet)
message(AUTHOR_WARNING "Unable to find \#define ${DEFINE_NAME} \"<version>\" from ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
endif()
return()
endif()
# Export the version string
set(${PREFIX}_VERSION "${match}" PARENT_SCOPE)
endfunction()
# Do the final processing once the paths have been detected.
# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
@ -48,65 +103,167 @@ endmacro (libfind_pkg_check_modules)
# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
# Also handles errors in case library detection was required, etc.
macro (libfind_process PREFIX)
# Skip processing if already processed during this run
if (NOT ${PREFIX}_FOUND)
# Start with the assumption that the library was found
set (${PREFIX}_FOUND TRUE)
function (libfind_process PREFIX)
# Skip processing if already processed during this configuration run
if (${PREFIX}_FOUND)
return()
endif()
# Process all includes and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_INCLUDES})
if (${i})
set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)
set(found TRUE) # Start with the assumption that the package was found
# Process all libraries and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_LIBS})
if (${i})
set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)
# Did we find any files? Did we miss includes? These are for formatting better error messages.
set(some_files FALSE)
set(missing_headers FALSE)
# Print message and/or exit on fatal error
if (${PREFIX}_FOUND)
if (NOT ${PREFIX}_FIND_QUIETLY)
message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
endif (NOT ${PREFIX}_FIND_QUIETLY)
else (${PREFIX}_FOUND)
if (${PREFIX}_FIND_REQUIRED)
foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS})
message("${i}=${${i}}")
endforeach (i)
message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.")
endif (${PREFIX}_FIND_REQUIRED)
endif (${PREFIX}_FOUND)
endif (NOT ${PREFIX}_FOUND)
endmacro (libfind_process)
# Shorthands for some variables that we need often
set(quiet ${${PREFIX}_FIND_QUIETLY})
set(required ${${PREFIX}_FIND_REQUIRED})
set(exactver ${${PREFIX}_FIND_VERSION_EXACT})
set(findver "${${PREFIX}_FIND_VERSION}")
set(version "${${PREFIX}_VERSION}")
macro(libfind_library PREFIX basename)
set(TMP "")
if(MSVC80)
set(TMP -vc80)
endif(MSVC80)
if(MSVC90)
set(TMP -vc90)
endif(MSVC90)
set(${PREFIX}_LIBNAMES ${basename}${TMP})
if(${ARGC} GREATER 2)
set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2})
string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES})
set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP})
endif(${ARGC} GREATER 2)
find_library(${PREFIX}_LIBRARY
NAMES ${${PREFIX}_LIBNAMES}
PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}
)
endmacro(libfind_library)
# Lists of config option names (all, includes, libs)
unset(configopts)
set(includeopts ${${PREFIX}_PROCESS_INCLUDES})
set(libraryopts ${${PREFIX}_PROCESS_LIBS})
# Process deps to add to
foreach (i ${PREFIX} ${${PREFIX}_DEPENDENCIES})
if (DEFINED ${i}_INCLUDE_OPTS OR DEFINED ${i}_LIBRARY_OPTS)
# The package seems to export option lists that we can use, woohoo!
list(APPEND includeopts ${${i}_INCLUDE_OPTS})
list(APPEND libraryopts ${${i}_LIBRARY_OPTS})
else()
# If plural forms don't exist or they equal singular forms
if ((NOT DEFINED ${i}_INCLUDE_DIRS AND NOT DEFINED ${i}_LIBRARIES) OR
(${i}_INCLUDE_DIR STREQUAL ${i}_INCLUDE_DIRS AND ${i}_LIBRARY STREQUAL ${i}_LIBRARIES))
# Singular forms can be used
if (DEFINED ${i}_INCLUDE_DIR)
list(APPEND includeopts ${i}_INCLUDE_DIR)
endif()
if (DEFINED ${i}_LIBRARY)
list(APPEND libraryopts ${i}_LIBRARY)
endif()
else()
# Oh no, we don't know the option names
message(FATAL_ERROR "We couldn't determine config variable names for ${i} includes and libs. Aieeh!")
endif()
endif()
endforeach()
if (includeopts)
list(REMOVE_DUPLICATES includeopts)
endif()
if (libraryopts)
list(REMOVE_DUPLICATES libraryopts)
endif()
string(REGEX REPLACE ".*[ ;]([^ ;]*(_INCLUDE_DIRS|_LIBRARIES))" "\\1" tmp "${includeopts} ${libraryopts}")
if (NOT tmp STREQUAL "${includeopts} ${libraryopts}")
message(AUTHOR_WARNING "Plural form ${tmp} found in config options of ${PREFIX}. This works as before but is now deprecated. Please only use singular forms INCLUDE_DIR and LIBRARY, and update your find scripts for LibFindMacros > 2.0 automatic dependency system (most often you can simply remove the PROCESS variables entirely).")
endif()
# Include/library names separated by spaces (notice: not CMake lists)
unset(includes)
unset(libs)
# Process all includes and set found false if any are missing
foreach (i ${includeopts})
list(APPEND configopts ${i})
if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND")
list(APPEND includes "${${i}}")
else()
set(found FALSE)
set(missing_headers TRUE)
endif()
endforeach()
# Process all libraries and set found false if any are missing
foreach (i ${libraryopts})
list(APPEND configopts ${i})
if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND")
list(APPEND libs "${${i}}")
else()
set (found FALSE)
endif()
endforeach()
# Version checks
if (found AND findver)
if (NOT version)
message(WARNING "The find module for ${PREFIX} does not provide version information, so we'll just assume that it is OK. Please fix the module or remove package version requirements to get rid of this warning.")
elseif (version VERSION_LESS findver OR (exactver AND NOT version VERSION_EQUAL findver))
set(found FALSE)
set(version_unsuitable TRUE)
endif()
endif()
# If all-OK, hide all config options, export variables, print status and exit
if (found)
foreach (i ${configopts})
mark_as_advanced(${i})
endforeach()
if (NOT quiet)
message(STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
if (LIBFIND_DEBUG)
message(STATUS " ${PREFIX}_DEPENDENCIES=${${PREFIX}_DEPENDENCIES}")
message(STATUS " ${PREFIX}_INCLUDE_OPTS=${includeopts}")
message(STATUS " ${PREFIX}_INCLUDE_DIRS=${includes}")
message(STATUS " ${PREFIX}_LIBRARY_OPTS=${libraryopts}")
message(STATUS " ${PREFIX}_LIBRARIES=${libs}")
endif()
endif()
set (${PREFIX}_INCLUDE_OPTS ${includeopts} PARENT_SCOPE)
set (${PREFIX}_LIBRARY_OPTS ${libraryopts} PARENT_SCOPE)
set (${PREFIX}_INCLUDE_DIRS ${includes} PARENT_SCOPE)
set (${PREFIX}_LIBRARIES ${libs} PARENT_SCOPE)
set (${PREFIX}_FOUND TRUE PARENT_SCOPE)
return()
endif()
# Format messages for debug info and the type of error
set(vars "Relevant CMake configuration variables:\n")
foreach (i ${configopts})
mark_as_advanced(CLEAR ${i})
set(val ${${i}})
if ("${val}" STREQUAL "${i}-NOTFOUND")
set (val "<not found>")
elseif (val AND NOT EXISTS ${val})
set (val "${val} (does not exist)")
else()
set(some_files TRUE)
endif()
set(vars "${vars} ${i}=${val}\n")
endforeach()
set(vars "${vars}You may use CMake GUI, cmake -D or ccmake to modify the values. Delete CMakeCache.txt to discard all values and force full re-detection if necessary.\n")
if (version_unsuitable)
set(msg "${PREFIX} ${${PREFIX}_VERSION} was found but")
if (exactver)
set(msg "${msg} only version ${findver} is acceptable.")
else()
set(msg "${msg} version ${findver} is the minimum requirement.")
endif()
else()
if (missing_headers)
set(msg "We could not find development headers for ${PREFIX}. Do you have the necessary dev package installed?")
elseif (some_files)
set(msg "We only found some files of ${PREFIX}, not all of them. Perhaps your installation is incomplete or maybe we just didn't look in the right place?")
if(findver)
set(msg "${msg} This could also be caused by incompatible version (if it helps, at least ${PREFIX} ${findver} should work).")
endif()
else()
set(msg "We were unable to find package ${PREFIX}.")
endif()
endif()
# Fatal error out if REQUIRED
if (required)
set(msg "REQUIRED PACKAGE NOT FOUND\n${msg} This package is REQUIRED and you need to install it or adjust CMake configuration in order to continue building ${CMAKE_PROJECT_NAME}.")
message(FATAL_ERROR "${msg}\n${vars}")
endif()
# Otherwise just print a nasty warning
if (NOT quiet)
message(WARNING "WARNING: MISSING PACKAGE\n${msg} This package is NOT REQUIRED and you may ignore this warning but by doing so you may miss some functionality of ${CMAKE_PROJECT_NAME}. \n${vars}")
endif()
endfunction()

View File

@ -45,7 +45,7 @@ if (POLICY CMP0075)
endif ()
project (wsjtx
VERSION 2.4.0.0
VERSION 2.5.0.0
LANGUAGES C CXX Fortran
)
set (PROJECT_DESCRIPTION "WSJT-X: Digital Modes for Weak Signal Communications in Amateur Radio")
@ -71,7 +71,7 @@ message (STATUS "******************************************************")
include (set_build_type)
# RC 0 or omitted is a development build, GA is a General Availability release build
set_build_type (GA)
set_build_type (RC 1)
set (wsjtx_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
#
@ -333,6 +333,7 @@ set (wsjt_FSRCS
lib/timer_impl.f90
lib/timer_module.f90
lib/wavhdr.f90
lib/qra/q65/q65_encoding_modules.f90
# remaining non-module sources
lib/addit.f90
@ -462,6 +463,7 @@ set (wsjt_FSRCS
lib/lorentzian.f90
lib/fst4/lorentzian_fading.f90
lib/lpf1.f90
lib/map65_mmdec.f90
lib/mixlpf.f90
lib/makepings.f90
lib/moondopjpl.f90
@ -813,12 +815,27 @@ endif (APPLE)
#
include (CheckTypeSize)
include (CheckCSourceCompiles)
include (CheckIncludeFiles)
include (CheckSymbolExists)
include (generate_version_info)
find_program(CTAGS ctags)
find_program(ETAGS etags)
#
# Platform checks
#
check_include_files ("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
check_include_files (stdio.h HAVE_STDIO_H)
check_include_files (stdlib.h HAVE_STDLIB_H)
check_include_files (unistd.h HAVE_UNISTD_H)
check_include_files (sys/ioctl.h HAVE_SYS_IOCTL_H)
check_include_files (sys/types.h HAVE_SYS_TYPES_H)
check_include_files (fcntl.h HAVE_FCNTL_H)
check_include_files (sys/stat.h HAVE_SYS_STAT_H)
check_include_files ("linux/ppdev.h;linux/parport.h" HAVE_LINUX_PPDEV_H)
check_include_files ("dev/ppbus/ppi.h;dev/ppbus/ppbconf.h" HAVE_DEV_PPBUS_PPI_H)
#
# Standard C Math Library
#
@ -855,24 +872,19 @@ find_package (OpenMP)
find_package (FFTW3 COMPONENTS single threads REQUIRED)
#
# libhamlib setup
# hamlib setup
#
set (hamlib_STATIC 1)
find_package (hamlib 3 REQUIRED)
find_package (Hamlib REQUIRED)
find_program (RIGCTL_EXE rigctl)
find_program (RIGCTLD_EXE rigctld)
find_program (RIGCTLCOM_EXE rigctlcom)
message (STATUS "hamlib_INCLUDE_DIRS: ${hamlib_INCLUDE_DIRS}")
message (STATUS "hamlib_LIBRARIES: ${hamlib_LIBRARIES}")
message (STATUS "hamlib_LIBRARY_DIRS: ${hamlib_LIBRARY_DIRS}")
set (CMAKE_REQUIRED_INCLUDES "${hamlib_INCLUDE_DIRS}")
set (CMAKE_REQUIRED_LIBRARIES "${hamlib_LIBRARIES}")
set (CMAKE_EXTRA_INCLUDE_FILES "hamlib/rig.h")
check_type_size (CACHE_ALL HAMLIB_OLD_CACHING)
check_symbol_exists (rig_set_cache_timeout_ms "hamlib/rig.h" HAVE_HAMLIB_CACHING)
find_package (Portaudio REQUIRED)
find_package (Usb REQUIRED)
#
# Qt5 setup
@ -886,19 +898,6 @@ if (WIN32)
find_package (Qt5AxContainer REQUIRED)
endif (WIN32)
#
# sub-directories
#
if (EXISTS ${CMAKE_SOURCE_DIR}/samples AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/samples)
add_subdirectory (samples)
endif ()
if (WSJT_GENERATE_DOCS)
add_subdirectory (doc)
endif (WSJT_GENERATE_DOCS)
if (EXISTS ${CMAKE_SOURCE_DIR}/tests AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/tests)
add_subdirectory (tests)
endif ()
#
# Library building setup
#
@ -961,8 +960,15 @@ if (Fortran_COMPILER_NAME MATCHES "gfortran.*")
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -isysroot ${CMAKE_OSX_SYSROOT}")
endif (CMAKE_OSX_SYSROOT)
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -fbounds-check -funroll-all-loops -fno-f2c ${General_FFLAGS}")
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fbounds-check -fno-f2c ${General_FFLAGS}")
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -fbounds-check -funroll-all-loops -fno-f2c -ffpe-summary=invalid,zero,overflow,underflow ${General_FFLAGS}")
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -g -fbacktrace -fbounds-check -fno-f2c -ffpe-summary=invalid,zero,overflow,underflow ${General_FFLAGS}")
# FPE traps currently disabled in Debug configuration builds until
# we decide if they are meaningful, without these FP instructions
# run in nonstop mode and do not trap
#set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} ${CMAKE_Fortran_FLAGS_DEBUG} -ffpe-trap=invalid,zero,overflow")
elseif (Fortran_COMPILER_NAME MATCHES "ifort.*")
# ifort (untested)
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -f77rtl ${General_FFLAGS}")
@ -1064,6 +1070,19 @@ elseif (CMAKE_HOST_WIN32)
add_definitions (-DWIN32)
endif ()
#
# sub-directories
#
if (EXISTS ${CMAKE_SOURCE_DIR}/samples AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/samples)
add_subdirectory (samples)
endif ()
if (WSJT_GENERATE_DOCS)
add_subdirectory (doc)
endif (WSJT_GENERATE_DOCS)
if (EXISTS ${CMAKE_SOURCE_DIR}/tests AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/tests)
add_subdirectory (tests)
endif ()
# build a library of package functionality (without and optionally with OpenMP support)
add_library (wsjt_cxx STATIC ${wsjt_CSRCS} ${wsjt_CXXSRCS})
target_link_libraries (wsjt_cxx ${LIBM_LIBRARIES} Boost::log_setup ${LIBM_LIBRARIES})
@ -1110,6 +1129,9 @@ target_link_libraries (sumsim wsjt_fort wsjt_cxx)
add_executable (q65sim lib/qra/q65/q65sim.f90)
target_link_libraries (q65sim wsjt_fort wsjt_cxx)
add_executable (q65code lib/qra/q65/q65code.f90)
target_link_libraries (q65code wsjt_fort wsjt_cxx)
add_executable (test_q65 lib/test_q65.f90)
target_link_libraries (test_q65 wsjt_fort wsjt_cxx)
@ -1317,8 +1339,7 @@ target_link_libraries (qcp Qt5::Widgets Qt5::PrintSupport)
add_library (wsjt_qt STATIC ${wsjt_qt_CXXSRCS} ${wsjt_qt_GENUISRCS} ${GENAXSRCS})
# set wsjtx_udp exports to static variants
target_compile_definitions (wsjt_qt PUBLIC UDP_STATIC_DEFINE)
target_link_libraries (wsjt_qt Boost::log qcp Qt5::Widgets Qt5::Network Qt5::Sql)
target_include_directories (wsjt_qt BEFORE PRIVATE ${hamlib_INCLUDE_DIRS})
target_link_libraries (wsjt_qt Hamlib::Hamlib Boost::log qcp Qt5::Widgets Qt5::Network Qt5::Sql)
if (WIN32)
target_link_libraries (wsjt_qt Qt5::AxContainer Qt5::AxBase)
endif (WIN32)
@ -1380,6 +1401,9 @@ else (${OPENMP_FOUND} OR APPLE)
target_link_libraries (jt9 wsjt_fort wsjt_cxx fort_qt)
endif (${OPENMP_FOUND} OR APPLE)
# build map65
add_subdirectory (map65)
# build the main application
generate_version_info (wsjtx_VERSION_RESOURCES
NAME wsjtx
@ -1432,7 +1456,7 @@ else ()
)
endif ()
endif ()
target_link_libraries (wsjtx Qt5::SerialPort wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES} ${LIBM_LIBRARIES})
target_link_libraries (wsjtx Qt5::SerialPort wsjt_cxx wsjt_qt wsjt_qtmm ${FFTW3_LIBRARIES} ${LIBM_LIBRARIES})
# make a library for WSJT-X UDP servers
# add_library (wsjtx_udp SHARED ${UDP_library_CXXSRCS})
@ -1543,7 +1567,8 @@ install (TARGETS jt9 wsprd fmtave fcal fmeasure
)
if(WSJT_BUILD_UTILS)
install (TARGETS ft8code jt65code jt9code jt4code msk144code fst4sim q65sim
install (TARGETS ft8code jt65code jt9code jt4code msk144code
q65code fst4sim q65sim
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
@ -1663,174 +1688,27 @@ if (NOT WIN32 AND NOT APPLE)
)
endif (NOT WIN32 AND NOT APPLE)
if (APPLE)
set (CMAKE_POSTFLIGHT_SCRIPT
"${wsjtx_BINARY_DIR}/postflight.sh")
set (CMAKE_POSTUPGRADE_SCRIPT
"${wsjtx_BINARY_DIR}/postupgrade.sh")
configure_file ("${wsjtx_SOURCE_DIR}/Darwin/postflight.sh.in"
"${CMAKE_POSTFLIGHT_SCRIPT}")
configure_file ("${wsjtx_SOURCE_DIR}/Darwin/postupgrade.sh.in"
"${CMAKE_POSTUPGRADE_SCRIPT}")
endif ()
#
# bundle fixup only done in non-Debug configurations
#
if (NOT is_debug_build)
get_target_property (QtCore_location Qt5::Core LOCATION)
get_filename_component (QtCore_location ${QtCore_location} PATH)
list (APPEND fixup_library_dirs ${QtCore_location})
if (APPLE)
set (CMAKE_POSTFLIGHT_SCRIPT
"${wsjtx_BINARY_DIR}/postflight.sh")
set (CMAKE_POSTUPGRADE_SCRIPT
"${wsjtx_BINARY_DIR}/postupgrade.sh")
configure_file ("${wsjtx_SOURCE_DIR}/Darwin/postflight.sh.in"
"${CMAKE_POSTFLIGHT_SCRIPT}")
configure_file ("${wsjtx_SOURCE_DIR}/Darwin/postupgrade.sh.in"
"${CMAKE_POSTUPGRADE_SCRIPT}")
endif ()
if (APPLE OR WIN32)
# install rules for including 3rd party libs such as Qt
# install a qt.conf file
install (CODE "
get_filename_component (the_qt_conf \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION}/qt.conf\" REALPATH)
file (WRITE \"\${the_qt_conf}\"
\"[Paths]
\")
"
#COMPONENT runtime
)
# if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation
set (fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/${CMAKE_PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
#get_filename_component (hamlib_lib_dir ${hamlib_LIBRARIES} PATH)
if (APPLE)
# install required Qt plugins
install (
DIRECTORY
${QT_PLUGINS_DIR}/platforms
${QT_PLUGINS_DIR}/audio
${QT_PLUGINS_DIR}/accessible
${QT_PLUGINS_DIR}/imageformats
${QT_PLUGINS_DIR}/styles
DESTINATION ${WSJT_PLUGIN_DESTINATION}
CONFIGURATIONS Release MinSizeRel RelWithDebInfo
#COMPONENT runtime
FILES_MATCHING PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}"
PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*quick*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*webgl*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*_debug${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}.dSYM" EXCLUDE
)
install (
FILES
${QT_PLUGINS_DIR}/sqldrivers/libqsqlite${CMAKE_SHARED_LIBRARY_SUFFIX}
DESTINATION ${WSJT_PLUGIN_DESTINATION}/sqldrivers
CONFIGURATIONS Release MinSizeRel RelWithDebInfo
#COMPONENT runtime
)
# install (
# DIRECTORY
# ${QT_PLUGINS_DIR}/platforms
# ${QT_PLUGINS_DIR}/audio
# ${QT_PLUGINS_DIR}/accessible
# DESTINATION ${WSJT_PLUGIN_DESTINATION}
# CONFIGURATIONS Debug
# #COMPONENT runtime
# FILES_MATCHING PATTERN "*_debug${CMAKE_SHARED_LIBRARY_SUFFIX}"
# PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# PATTERN "*quick*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# )
# add plugins path for Mac Bundle
install (CODE "
get_filename_component (the_qt_conf \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION}/qt.conf\" REALPATH)
file (APPEND \"\${the_qt_conf}\"
\"Plugins = PlugIns
\")
"
#COMPONENT runtime
)
endif (APPLE)
if (WIN32)
# DLL directory
#set (hamlib_lib_dir ${hamlib_lib_dir}/../bin)
get_filename_component (fftw_lib_dir ${FFTW3F_LIBRARY} PATH)
list (APPEND fixup_library_dirs ${fftw_lib_dir})
# install required Qt plugins
install (
DIRECTORY
${QT_PLUGINS_DIR}/platforms
${QT_PLUGINS_DIR}/styles
${QT_PLUGINS_DIR}/accessible
${QT_PLUGINS_DIR}/audio
${QT_PLUGINS_DIR}/imageformats
DESTINATION ${WSJT_PLUGIN_DESTINATION}
CONFIGURATIONS Release MinSizeRel RelWithDebInfo
#COMPONENT runtime
FILES_MATCHING PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}"
PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*quick*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*d${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
)
install (
FILES
${QT_PLUGINS_DIR}/sqldrivers/qsqlite${CMAKE_SHARED_LIBRARY_SUFFIX}
DESTINATION ${WSJT_PLUGIN_DESTINATION}/sqldrivers
CONFIGURATIONS Release MinSizeRel RelWithDebInfo
#COMPONENT runtime
)
# install (
# DIRECTORY
# ${QT_PLUGINS_DIR}/platforms
# ${QT_PLUGINS_DIR}/accessible
# ${QT_PLUGINS_DIR}/audio
# DESTINATION ${WSJT_PLUGIN_DESTINATION}
# CONFIGURATIONS Debug
# #COMPONENT runtime
# FILES_MATCHING PATTERN "*d${CMAKE_SHARED_LIBRARY_SUFFIX}"
# PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# PATTERN "*quick*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# )
# add paths for WIN32
file (RELATIVE_PATH _plugins_path "${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION}" "${CMAKE_INSTALL_PREFIX}/${WSJT_PLUGIN_DESTINATION}")
install (CODE "
get_filename_component (the_qt_conf \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION}/qt.conf\" REALPATH)
file (APPEND \"\${the_qt_conf}\"
\"Plugins = ${_plugins_path}
\")
"
#COMPONENT runtime
)
set (gp_tool "objdump") # we want MinGW tool - not MSVC (See GetPrerequisites.cmake)
endif (WIN32)
#list (APPEND fixup_library_dirs ${hamlib_lib_dir})
list (APPEND fixup_library_dirs ${hamlib_LIBRARY_DIRS})
install (CODE "
get_filename_component (the_path \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_PLUGIN_DESTINATION}\" REALPATH)
file (GLOB_RECURSE QTPLUGINS \"\${the_path}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake/Modules ${CMAKE_MODULE_PATH})
include (BundleUtilities)
set (BU_CHMOD_BUNDLE_ITEMS ON)
set (gp_tool ${gp_tool})
# canonicalize path in install context
get_filename_component (the_exe ${fixup_exe} REALPATH)
fixup_bundle (\"\${the_exe}\" \"\${QTPLUGINS}\" \"${fixup_library_dirs}\")"
#COMPONENT runtime
)
endif (APPLE OR WIN32)
endif (NOT is_debug_build)
# add this sub-sirectory after all install steps and other
# sub-directories to ensure that all executables are in-place before
# any fixup is done
add_subdirectory (bundle_fixup)
endif ()
#

153
bundle_fixup/CMakeLists.txt Normal file
View File

@ -0,0 +1,153 @@
get_target_property (QtCore_location Qt5::Core LOCATION)
get_filename_component (QtCore_location ${QtCore_location} PATH)
list (APPEND fixup_library_dirs ${QtCore_location})
if (APPLE OR WIN32)
# install rules for including 3rd party libs such as Qt
# install a qt.conf file
install (CODE "
get_filename_component (the_qt_conf \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION}/qt.conf\" REALPATH)
file (WRITE \"\${the_qt_conf}\"
\"[Paths]
\")
"
#COMPONENT runtime
)
# if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation
set (fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/${CMAKE_PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
#get_filename_component (hamlib_lib_dir ${Hamlib_LIBRARIES} PATH)
if (APPLE)
# install required Qt plugins
install (
DIRECTORY
${QT_PLUGINS_DIR}/platforms
${QT_PLUGINS_DIR}/audio
${QT_PLUGINS_DIR}/accessible
${QT_PLUGINS_DIR}/imageformats
${QT_PLUGINS_DIR}/styles
DESTINATION ${WSJT_PLUGIN_DESTINATION}
CONFIGURATIONS Release MinSizeRel RelWithDebInfo
#COMPONENT runtime
FILES_MATCHING PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}"
PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*quick*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*webgl*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*_debug${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}.dSYM" EXCLUDE
)
install (
FILES
${QT_PLUGINS_DIR}/sqldrivers/libqsqlite${CMAKE_SHARED_LIBRARY_SUFFIX}
DESTINATION ${WSJT_PLUGIN_DESTINATION}/sqldrivers
CONFIGURATIONS Release MinSizeRel RelWithDebInfo
#COMPONENT runtime
)
# install (
# DIRECTORY
# ${QT_PLUGINS_DIR}/platforms
# ${QT_PLUGINS_DIR}/audio
# ${QT_PLUGINS_DIR}/accessible
# DESTINATION ${WSJT_PLUGIN_DESTINATION}
# CONFIGURATIONS Debug
# #COMPONENT runtime
# FILES_MATCHING PATTERN "*_debug${CMAKE_SHARED_LIBRARY_SUFFIX}"
# PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# PATTERN "*quick*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# )
# add plugins path for Mac Bundle
install (CODE "
get_filename_component (the_qt_conf \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION}/qt.conf\" REALPATH)
file (APPEND \"\${the_qt_conf}\"
\"Plugins = PlugIns
\")
"
#COMPONENT runtime
)
endif (APPLE)
if (WIN32)
# DLL directories
get_filename_component (hamlib_lib_dir ${Hamlib_LIBRARY} PATH)
list (APPEND fixup_library_dirs ${hamlib_lib_dir}/../bin)
get_filename_component (usb_lib_dir ${Usb_LIBRARY} PATH)
list (APPEND fixup_library_dirs ${usb_lib_dir})
get_filename_component (portaudio_lib_dir ${Portaudio_LIBRARY} PATH)
list (APPEND fixup_library_dirs ${portaudio_lib_dir}/../bin)
get_filename_component (fftw_lib_dir ${FFTW3F_LIBRARY} PATH)
list (APPEND fixup_library_dirs ${fftw_lib_dir})
# install required Qt plugins
install (
DIRECTORY
${QT_PLUGINS_DIR}/platforms
${QT_PLUGINS_DIR}/styles
${QT_PLUGINS_DIR}/accessible
${QT_PLUGINS_DIR}/audio
${QT_PLUGINS_DIR}/imageformats
DESTINATION ${WSJT_PLUGIN_DESTINATION}
CONFIGURATIONS Release MinSizeRel RelWithDebInfo
#COMPONENT runtime
FILES_MATCHING PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}"
PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*quick*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
PATTERN "*d${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
)
install (
FILES
${QT_PLUGINS_DIR}/sqldrivers/qsqlite${CMAKE_SHARED_LIBRARY_SUFFIX}
DESTINATION ${WSJT_PLUGIN_DESTINATION}/sqldrivers
CONFIGURATIONS Release MinSizeRel RelWithDebInfo
#COMPONENT runtime
)
# install (
# DIRECTORY
# ${QT_PLUGINS_DIR}/platforms
# ${QT_PLUGINS_DIR}/accessible
# ${QT_PLUGINS_DIR}/audio
# DESTINATION ${WSJT_PLUGIN_DESTINATION}
# CONFIGURATIONS Debug
# #COMPONENT runtime
# FILES_MATCHING PATTERN "*d${CMAKE_SHARED_LIBRARY_SUFFIX}"
# PATTERN "*minimal*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# PATTERN "*offscreen*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# PATTERN "*quick*${CMAKE_SHARED_LIBRARY_SUFFIX}" EXCLUDE
# )
# add paths for WIN32
file (RELATIVE_PATH _plugins_path "${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION}" "${CMAKE_INSTALL_PREFIX}/${WSJT_PLUGIN_DESTINATION}")
install (CODE "
get_filename_component (the_qt_conf \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_QT_CONF_DESTINATION}/qt.conf\" REALPATH)
file (APPEND \"\${the_qt_conf}\"
\"Plugins = ${_plugins_path}
\")
"
#COMPONENT runtime
)
set (gp_tool "objdump") # we want MinGW tool - not MSVC (See GetPrerequisites.cmake)
endif (WIN32)
INSTALL (CODE "
get_filename_component (the_path \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${WSJT_PLUGIN_DESTINATION}\" REALPATH)
file (GLOB_RECURSE QTPLUGINS \"\${the_path}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
include (BundleUtilities)
set (BU_CHMOD_BUNDLE_ITEMS ON)
set (gp_tool ${gp_tool})
# canonicalize path in install context
get_filename_component (the_exe ${fixup_exe} REALPATH)
fixup_bundle (\"\${the_exe}\" \"\${QTPLUGINS}\" \"${fixup_library_dirs}\")"
#COMPONENT runtime
)
endif (APPLE OR WIN32)

View File

@ -26,10 +26,9 @@ typedef struct dec_data {
int nutc; //UTC as integer, HHMM
bool ndiskdat; //true ==> data read from *.wav file
int ntrperiod; //TR period (seconds)
int nQSOProgress; /* QSO state machine state */
int nQSOProgress; //QSO state machine state
int nfqso; //User-selected QSO freq (kHz)
int nftx; /* Transmit audio offset where
replies might be expected */
int nftx; //TX audio offset where replies might be expected
bool newdat; //true ==> new data, must do long FFT
int npts8; //npts for c0() array
int nfa; //Low decode limit (Hz)
@ -59,6 +58,7 @@ typedef struct dec_data {
int naggressive;
bool nrobust;
int nexp_decode;
int max_drift;
char datetime[20];
char mycall[12];
char mygrid[6];

446
cty.dat
View File

@ -682,12 +682,12 @@ Bosnia-Herzegovina: 15: 28: EU: 44.32: -17.57: -1.0: E7:
E7,=YU4WU;
Spain: 14: 37: EU: 40.32: 3.43: -1.0: EA:
AM,AN,AO,EA,EB,EC,ED,EE,EF,EG,EH,=AM95WARD,=AN92EXPO,=EF6,=EG90IARU,
=AM1TDH/LH,=EA1APV/LH,=EA1BEY/Y,=EA1EEY/L,=EA1EEY/LGT,=EA1EEY/LH,=EA1EK/ZAP,=EA1FGS/LH,=EA1HLW/YL,
=EA1RCG/CPV,=EA1RCG/SEU,=EA1RCG/YOA,=EA1RCI/CA,=EA1RCI/CR,=EA1RCI/CVG,=EA1RCI/DAC,=EA1RCI/ESM,
=EA1RCI/IA,=EA1RCI/ICA,=EA1RCI/JBN,=EA1RCI/KD,=EA1RCI/PAZ,=EA1RCI/PCV,=EA1RCI/RCC,=EA1RCI/RSM,
=EA1RCI/YOA,=EA1RCP/NM,=EA1URL/CVL,=EA1URO/D,=EA1URO/KD,=EA5AER/P,=EA6QB/1,=EA8BFH/1,=EA8CZT/1,
=EA8FC/1,=EA8RV/P,=EA9CD/1,=EA9CI/1,=EA9CP/1,=EA9PD/1,=EB1DH/LH,=ED1IRM/LH,=EG1ILW/LH,=EG1LWB/LH,
=EG1LWC/LH,=EG1LWI/LH,=EG1LWN/LH,=EG1TDH/LH,=EG90IARU/1,
=AM1TDH/LH,=EA1APV/LH,=EA1BEY/Y,=EA1BPC/DE,=EA1EEY/L,=EA1EEY/LGT,=EA1EEY/LH,=EA1EK/ZAP,=EA1FDD/DE,
=EA1FGS/LH,=EA1HLW/YL,=EA1RCG/CPV,=EA1RCG/SEU,=EA1RCG/YOA,=EA1RCI/CA,=EA1RCI/CR,=EA1RCI/CVG,
=EA1RCI/DAC,=EA1RCI/ESM,=EA1RCI/IA,=EA1RCI/ICA,=EA1RCI/JBN,=EA1RCI/KD,=EA1RCI/PAZ,=EA1RCI/PCV,
=EA1RCI/RCC,=EA1RCI/RSM,=EA1RCI/YOA,=EA1RCP/NM,=EA1URL/CVL,=EA1URO/D,=EA1URO/KD,=EA5AER/P,
=EA6QB/1,=EA8BFH/1,=EA8CZT/1,=EA8FC/1,=EA8RV/P,=EA9CD/1,=EA9CI/1,=EA9CP/1,=EA9PD/1,=EB1DH/LH,
=ED1IRM/LH,=EG1ILW/LH,=EG1LWB/LH,=EG1LWC/LH,=EG1LWI/LH,=EG1LWN/LH,=EG1TDH/LH,=EG90IARU/1,
=AM08ATU/H,=AM08CAZ/H,=AM08CYQ/H,=AM08EIE/Z,=AM08FAC/H,=AN08ADE/H,=AO08BQH/Z,=AO08BTM/Z,
=AO08CIK/H,=AO08CVV/Z,=AO08CXK/H,=AO08CYL/H,=AO08DI/Z,=AO08EIE/Z,=AO08HV/Z,=AO08ICA/Z,=AO08ID/Z,
=AO08KJ/Z,=AO08KV/Z,=AO08OK/H,=AO08PB/Z,=AO08RKO/H,=AO08VK/Z,=AO2016DSS/LH,=EA2/ON7RU/LH,
@ -1257,22 +1257,22 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K:
=AL1B(5)[8],=AL1B/M(5)[8],=AL2G(5)[8],=AL3C(5)[8],=AL7AB(5)[8],=AL7NN(5)[8],=AL7NN/3(5)[8],
=AL7RS(5)[8],=KH2EI(5)[8],=KH2JH(5)[8],=KH2JX(5)[8],=KH2SX(5)[8],=KH6CUJ(5)[8],=KH6GRG(5)[8],
=KH6ILR/3(5)[8],=KH6JGA(5)[8],=KH6LDO(5)[8],=KH6PX(5)[8],=KH6RE(5)[8],=KH8CN(5)[8],=KL1CNN(5)[8],
=KL1HA(5)[8],=KL1KM(5)[8],=KL2A/3(5)[8],=KL2BV(5)[8],=KL2UR(5)[8],=KL2XF(5)[8],=KL7FD(5)[8],
=KL7GLK/3(5)[8],=KL7HR/3(5)[8],=KL7IUI(5)[8],=KL7IUI/3(5)[8],=KL7JO(5)[8],=KL7OF/3(5)[8],
=KL7OQ(5)[8],=KL7YN(5)[8],=KL9A/3(5)[8],=KP3M(5)[8],=KP3N(5)[8],=KP4BEP(5)[8],=KP4CAM(5)[8],
=KP4FCF(5)[8],=KP4GB/3(5)[8],=KP4IP(5)[8],=KP4JB(5)[8],=KP4N(5)[8],=KP4N/3(5)[8],=KP4PRI(5)[8],
=KP4UV(5)[8],=KP4VW(5)[8],=KP4WR(5)[8],=KP4XO(5)[8],=KP4XX(5)[8],=KP4YH(5)[8],=NH2CW(5)[8],
=NH2LA(5)[8],=NH6BD(5)[8],=NH6BK(5)[8],=NH7C(5)[8],=NH7C/3(5)[8],=NH7CC(5)[8],=NH7TV(5)[8],
=NH7YK(5)[8],=NL7CK(5)[8],=NL7PJ(5)[8],=NL7V/3(5)[8],=NL7WA(5)[8],=NL7XM(5)[8],=NL7XM/B(5)[8],
=NP2EP(5)[8],=NP2G(5)[8],=NP2NC(5)[8],=NP3ES(5)[8],=NP3IP(5)[8],=NP3YN(5)[8],=NP4RH(5)[8],
=NP4YZ(5)[8],=WH6ADS(5)[8],=WH6AWO(5)[8],=WH6AZN(5)[8],=WH6CE(5)[8],=WH6CTO(5)[8],=WH6DOA(5)[8],
=WH6ECO(5)[8],=WH6EEL(5)[8],=WH6EEN(5)[8],=WH6EIJ(5)[8],=WH6FPS(5)[8],=WH6GEU(5)[8],=WH6IO(5)[8],
=WH6OB(5)[8],=WH6RN(5)[8],=WH7F(5)[8],=WH7USA(5)[8],=WL7AF(5)[8],=WL7L(5)[8],=WP2XX(5)[8],
=WP3BX(5)[8],=WP3CC(5)[8],=WP3EC(5)[8],=WP3FK(5)[8],=WP4DA(5)[8],=WP4DCK(5)[8],=WP4EDM(5)[8],
=WP4GJL(5)[8],=WP4HRK(5)[8],=WP4HSZ(5)[8],=WP4IYE(5)[8],=WP4KDN(5)[8],=WP4KKX(5)[8],=WP4KTU(5)[8],
=WP4LEM(5)[8],=WP4LNP(5)[8],=WP4LTI(5)[8],=WP4MNV(5)[8],=WP4MSX(5)[8],=WP4MYN(5)[8],=WP4NXG(5)[8],
=WP4OSQ(5)[8],=WP4PPH(5)[8],=WP4PUR(5)[8],=WP4PYL(5)[8],=WP4PYM(5)[8],=WP4PYU(5)[8],=WP4PYV(5)[8],
=WP4PYZ(5)[8],=WP4PZA(5)[8],
=KL1HA(5)[8],=KL1KM(5)[8],=KL2A/3(5)[8],=KL2BV(5)[8],=KL2UR(5)[8],=KL2XF(5)[8],=KL4QG(5)[8],
=KL7FD(5)[8],=KL7GLK/3(5)[8],=KL7HR/3(5)[8],=KL7IUI(5)[8],=KL7IUI/3(5)[8],=KL7JO(5)[8],
=KL7OF/3(5)[8],=KL7OQ(5)[8],=KL7YN(5)[8],=KL9A/3(5)[8],=KP3M(5)[8],=KP3N(5)[8],=KP4BEP(5)[8],
=KP4CAM(5)[8],=KP4FCF(5)[8],=KP4GB/3(5)[8],=KP4IP(5)[8],=KP4JB(5)[8],=KP4N(5)[8],=KP4N/3(5)[8],
=KP4PRI(5)[8],=KP4UV(5)[8],=KP4VW(5)[8],=KP4WR(5)[8],=KP4XO(5)[8],=KP4XX(5)[8],=KP4YH(5)[8],
=NH2CW(5)[8],=NH2LA(5)[8],=NH6BD(5)[8],=NH6BK(5)[8],=NH7C(5)[8],=NH7C/3(5)[8],=NH7CC(5)[8],
=NH7TV(5)[8],=NH7YK(5)[8],=NL7CK(5)[8],=NL7PJ(5)[8],=NL7V/3(5)[8],=NL7WA(5)[8],=NL7XM(5)[8],
=NL7XM/B(5)[8],=NP2EP(5)[8],=NP2G(5)[8],=NP2NC(5)[8],=NP3ES(5)[8],=NP3IP(5)[8],=NP3YN(5)[8],
=NP4RH(5)[8],=NP4YZ(5)[8],=WH6ADS(5)[8],=WH6AWO(5)[8],=WH6AZN(5)[8],=WH6CE(5)[8],=WH6CTO(5)[8],
=WH6DOA(5)[8],=WH6ECO(5)[8],=WH6EEL(5)[8],=WH6EEN(5)[8],=WH6EIJ(5)[8],=WH6FPS(5)[8],=WH6GEU(5)[8],
=WH6IO(5)[8],=WH6OB(5)[8],=WH6RN(5)[8],=WH7F(5)[8],=WH7USA(5)[8],=WL7AF(5)[8],=WL7L(5)[8],
=WP2XX(5)[8],=WP3BX(5)[8],=WP3CC(5)[8],=WP3EC(5)[8],=WP3FK(5)[8],=WP4DA(5)[8],=WP4DCK(5)[8],
=WP4EDM(5)[8],=WP4GJL(5)[8],=WP4HRK(5)[8],=WP4HSZ(5)[8],=WP4IYE(5)[8],=WP4KDN(5)[8],=WP4KKX(5)[8],
=WP4KTU(5)[8],=WP4LEM(5)[8],=WP4LNP(5)[8],=WP4LTI(5)[8],=WP4MNV(5)[8],=WP4MSX(5)[8],=WP4MYN(5)[8],
=WP4NXG(5)[8],=WP4OSQ(5)[8],=WP4PPH(5)[8],=WP4PUR(5)[8],=WP4PYL(5)[8],=WP4PYM(5)[8],=WP4PYU(5)[8],
=WP4PYV(5)[8],=WP4PYZ(5)[8],=WP4PZA(5)[8],
=AH0BV(5)[8],=AH0BZ(5)[8],=AH0G(5)[8],=AH2AJ(5)[8],=AH2AM(5)[8],=AH2AV/4(5)[8],=AH2DF(5)[8],
=AH2EB(5)[8],=AH2EJ(5)[8],=AH2X(5)[8],=AH3B(5)[8],=AH6AL(5)[8],=AH6AT(5)[8],=AH6AU(5)[8],
=AH6BJ(5)[8],=AH6C(5)[8],=AH6EZ/4(5)[8],=AH6FX(5)[8],=AH6FX/4(5)[8],=AH6IC(5)[8],=AH6IW(5)[8],
@ -1348,37 +1348,37 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K:
=WH2ABJ(5)[8],=WH2G(5)[8],=WH6A(5)[8],=WH6ACF(5)[8],=WH6AJS(5)[8],=WH6AQ(5)[8],=WH6AVU(5)[8],
=WH6AX(5)[8],=WH6BRQ(5)[8],=WH6CEF(5)[8],=WH6CMT(5)[8],=WH6CNC(5)[8],=WH6CTC(5)[8],=WH6CXA(5)[8],
=WH6CXT(5)[8],=WH6DBX(5)[8],=WH6DMJ(5)[8],=WH6DNF(5)[8],=WH6DOL(5)[8],=WH6DUJ(5)[8],=WH6DXT(5)[8],
=WH6DZ(5)[8],=WH6ECQ(5)[8],=WH6EFI(5)[8],=WH6EFX(5)[8],=WH6EIK(5)[8],=WH6EIR(5)[8],=WH6EKW(5)[8],
=WH6ELG(5)[8],=WH6ELM(5)[8],=WH6ETF(5)[8],=WH6FCP(5)[8],=WH6GHO(5)[8],=WH6HA(5)[8],=WH6IF(5)[8],
=WH6IZ(5)[8],=WH6J(5)[8],=WH6L(5)[8],=WH6LE(5)[8],=WH6LE/4(5)[8],=WH6LE/M(5)[8],=WH6LE/P(5)[8],
=WH6NE(5)[8],=WH6NU(5)[8],=WH6WX(5)[8],=WH6YH(5)[8],=WH6YH/4(5)[8],=WH6YM(5)[8],=WH6ZF(5)[8],
=WH7GD(5)[8],=WH7HX(5)[8],=WH7NI(5)[8],=WH7XK(5)[8],=WH7XU(5)[8],=WH7YL(5)[8],=WH7YV(5)[8],
=WH7ZM(5)[8],=WH9AAF(5)[8],=WL4X(5)[8],=WL7AUL(5)[8],=WL7AX(5)[8],=WL7CHA(5)[8],=WL7CIB(5)[8],
=WL7CKJ(5)[8],=WL7COL(5)[8],=WL7CPA(5)[8],=WL7CQT(5)[8],=WL7CUY(5)[8],=WL7E/4(5)[8],=WL7GV(5)[8],
=WL7IO(5)[8],=WL7JE(5)[8],=WL7SR(5)[8],=WL7UN(5)[8],=WL7YX(5)[8],=WP2AGD(5)[8],=WP2AGO(5)[8],
=WP2AHC(5)[8],=WP2AIG(5)[8],=WP2AIL(5)[8],=WP2BB(5)[8],=WP2C(5)[8],=WP2J(5)[8],=WP2L(5)[8],
=WP2MA(5)[8],=WP2P(5)[8],=WP3AY(5)[8],=WP3BC(5)[8],=WP3DW(5)[8],=WP3HL(5)[8],=WP3IM(5)[8],
=WP3JE(5)[8],=WP3JQ(5)[8],=WP3JU(5)[8],=WP3K(5)[8],=WP3LE(5)[8],=WP3MB(5)[8],=WP3ME(5)[8],
=WP3NIS(5)[8],=WP3O(5)[8],=WP3PW(5)[8],=WP3QE(5)[8],=WP3TQ(5)[8],=WP3ZA(5)[8],=WP4AIE(5)[8],
=WP4AIL(5)[8],=WP4AIZ(5)[8],=WP4ALH(5)[8],=WP4AQK(5)[8],=WP4AVW(5)[8],=WP4B(5)[8],=WP4BFP(5)[8],
=WP4BGM(5)[8],=WP4BIN(5)[8],=WP4BJS(5)[8],=WP4BK(5)[8],=WP4BOC(5)[8],=WP4BQV(5)[8],=WP4BXS(5)[8],
=WP4BZG(5)[8],=WP4CKW(5)[8],=WP4CLS(5)[8],=WP4CMH(5)[8],=WP4DC(5)[8],=WP4DCB(5)[8],=WP4DFK(5)[8],
=WP4DMV(5)[8],=WP4DNE(5)[8],=WP4DPX(5)[8],=WP4ENX(5)[8],=WP4EXH(5)[8],=WP4FEI(5)[8],=WP4FRK(5)[8],
=WP4FS(5)[8],=WP4GAK(5)[8],=WP4GFH(5)[8],=WP4GX(5)[8],=WP4GYA(5)[8],=WP4HFZ(5)[8],=WP4HNN(5)[8],
=WP4HOX(5)[8],=WP4IF(5)[8],=WP4IJ(5)[8],=WP4IK(5)[8],=WP4ILP(5)[8],=WP4INP(5)[8],=WP4JC(5)[8],
=WP4JKO(5)[8],=WP4JNB(5)[8],=WP4JQJ(5)[8],=WP4JSR(5)[8],=WP4JSV(5)[8],=WP4JT(5)[8],=WP4KCJ(5)[8],
=WP4KDH(5)[8],=WP4KFP(5)[8],=WP4KGE(5)[8],=WP4KGI(5)[8],=WP4KI(5)[8],=WP4KJV(5)[8],=WP4KPK(5)[8],
=WP4KSK(5)[8],=WP4KTD(5)[8],=WP4LBK(5)[8],=WP4LDG(5)[8],=WP4LDL(5)[8],=WP4LDP(5)[8],=WP4LE(5)[8],
=WP4LEO(5)[8],=WP4LHA(5)[8],=WP4LTA(5)[8],=WP4MAE(5)[8],=WP4MD(5)[8],=WP4MO(5)[8],=WP4MQF(5)[8],
=WP4MWE(5)[8],=WP4MWK(5)[8],=WP4MWS(5)[8],=WP4MXE(5)[8],=WP4MYG(5)[8],=WP4MYK(5)[8],=WP4NAI(5)[8],
=WP4NAQ(5)[8],=WP4NBF(5)[8],=WP4NBG(5)[8],=WP4NFU(5)[8],=WP4NKU(5)[8],=WP4NLQ(5)[8],=WP4NVL(5)[8],
=WP4NWV(5)[8],=WP4NWW(5)[8],=WP4NYU(5)[8],=WP4O/4(5)[8],=WP4O/M(5)[8],=WP4OAT(5)[8],=WP4OBD(5)[8],
=WP4OBH(5)[8],=WP4ODR(5)[8],=WP4ODT(5)[8],=WP4OEO(5)[8],=WP4OFA(5)[8],=WP4OFL(5)[8],=WP4OHJ(5)[8],
=WP4OKI(5)[8],=WP4OLM(5)[8],=WP4OMG(5)[8],=WP4OMV(5)[8],=WP4ONR(5)[8],=WP4OOI(5)[8],=WP4OPD(5)[8],
=WP4OPF(5)[8],=WP4OQH(5)[8],=WP4OTP(5)[8],=WP4OXA(5)[8],=WP4P(5)[8],=WP4PEP(5)[8],=WP4PR(5)[8],
=WP4PUV(5)[8],=WP4PWV(5)[8],=WP4PXG(5)[8],=WP4QER(5)[8],=WP4QGV(5)[8],=WP4QHU(5)[8],=WP4RRR(5)[8],
=WP4TD(5)[8],=WP4TX(5)[8],=WP4UC(5)[8],=WP4UM(5)[8],=WP4UO(5)[8],=WP4VL(5)[8],=WP4VM(5)[8],
=WP4YG(5)[8],=WP4ZW(5)[8],
=WH6DZ(5)[8],=WH6ECQ(5)[8],=WH6EFI(5)[8],=WH6EFX(5)[8],=WH6EFY(5)[8],=WH6EIK(5)[8],=WH6EIR(5)[8],
=WH6EKW(5)[8],=WH6ELG(5)[8],=WH6ELM(5)[8],=WH6ETF(5)[8],=WH6FCP(5)[8],=WH6GHO(5)[8],=WH6HA(5)[8],
=WH6IF(5)[8],=WH6IZ(5)[8],=WH6J(5)[8],=WH6L(5)[8],=WH6LE(5)[8],=WH6LE/4(5)[8],=WH6LE/M(5)[8],
=WH6LE/P(5)[8],=WH6NE(5)[8],=WH6NU(5)[8],=WH6WX(5)[8],=WH6YH(5)[8],=WH6YH/4(5)[8],=WH6YM(5)[8],
=WH6ZF(5)[8],=WH7GD(5)[8],=WH7HX(5)[8],=WH7NI(5)[8],=WH7XK(5)[8],=WH7XU(5)[8],=WH7YL(5)[8],
=WH7YV(5)[8],=WH7ZM(5)[8],=WH9AAF(5)[8],=WL4X(5)[8],=WL7AUL(5)[8],=WL7AX(5)[8],=WL7CHA(5)[8],
=WL7CIB(5)[8],=WL7CKJ(5)[8],=WL7COL(5)[8],=WL7CPA(5)[8],=WL7CQT(5)[8],=WL7CUY(5)[8],=WL7E/4(5)[8],
=WL7GV(5)[8],=WL7IO(5)[8],=WL7JE(5)[8],=WL7SR(5)[8],=WL7UN(5)[8],=WL7YX(5)[8],=WP2AGD(5)[8],
=WP2AGO(5)[8],=WP2AHC(5)[8],=WP2AIG(5)[8],=WP2AIL(5)[8],=WP2BB(5)[8],=WP2C(5)[8],=WP2J(5)[8],
=WP2L(5)[8],=WP2MA(5)[8],=WP2P(5)[8],=WP3AY(5)[8],=WP3BC(5)[8],=WP3DW(5)[8],=WP3HL(5)[8],
=WP3IM(5)[8],=WP3JE(5)[8],=WP3JQ(5)[8],=WP3JU(5)[8],=WP3K(5)[8],=WP3LE(5)[8],=WP3MB(5)[8],
=WP3ME(5)[8],=WP3NIS(5)[8],=WP3O(5)[8],=WP3PW(5)[8],=WP3QE(5)[8],=WP3TQ(5)[8],=WP3ZA(5)[8],
=WP4AIE(5)[8],=WP4AIL(5)[8],=WP4AIZ(5)[8],=WP4ALH(5)[8],=WP4AQK(5)[8],=WP4AVW(5)[8],=WP4B(5)[8],
=WP4BFP(5)[8],=WP4BGM(5)[8],=WP4BIN(5)[8],=WP4BJS(5)[8],=WP4BK(5)[8],=WP4BOC(5)[8],=WP4BQV(5)[8],
=WP4BXS(5)[8],=WP4BZG(5)[8],=WP4CKW(5)[8],=WP4CLS(5)[8],=WP4CMH(5)[8],=WP4DC(5)[8],=WP4DCB(5)[8],
=WP4DFK(5)[8],=WP4DMV(5)[8],=WP4DNE(5)[8],=WP4DPX(5)[8],=WP4ENX(5)[8],=WP4EXH(5)[8],=WP4FEI(5)[8],
=WP4FRK(5)[8],=WP4FS(5)[8],=WP4GAK(5)[8],=WP4GFH(5)[8],=WP4GX(5)[8],=WP4GYA(5)[8],=WP4HFZ(5)[8],
=WP4HNN(5)[8],=WP4HOX(5)[8],=WP4IF(5)[8],=WP4IJ(5)[8],=WP4IK(5)[8],=WP4ILP(5)[8],=WP4INP(5)[8],
=WP4JC(5)[8],=WP4JKO(5)[8],=WP4JNB(5)[8],=WP4JQJ(5)[8],=WP4JSR(5)[8],=WP4JSV(5)[8],=WP4JT(5)[8],
=WP4KCJ(5)[8],=WP4KDH(5)[8],=WP4KFP(5)[8],=WP4KGE(5)[8],=WP4KGI(5)[8],=WP4KI(5)[8],=WP4KJV(5)[8],
=WP4KPK(5)[8],=WP4KSK(5)[8],=WP4KTD(5)[8],=WP4LBK(5)[8],=WP4LDG(5)[8],=WP4LDL(5)[8],=WP4LDP(5)[8],
=WP4LE(5)[8],=WP4LEO(5)[8],=WP4LHA(5)[8],=WP4LTA(5)[8],=WP4MAE(5)[8],=WP4MD(5)[8],=WP4MO(5)[8],
=WP4MQF(5)[8],=WP4MWE(5)[8],=WP4MWK(5)[8],=WP4MWS(5)[8],=WP4MXE(5)[8],=WP4MYG(5)[8],=WP4MYK(5)[8],
=WP4NAI(5)[8],=WP4NAQ(5)[8],=WP4NBF(5)[8],=WP4NBG(5)[8],=WP4NFU(5)[8],=WP4NKU(5)[8],=WP4NLQ(5)[8],
=WP4NVL(5)[8],=WP4NWV(5)[8],=WP4NWW(5)[8],=WP4NYU(5)[8],=WP4O/4(5)[8],=WP4O/M(5)[8],=WP4OAT(5)[8],
=WP4OBD(5)[8],=WP4OBH(5)[8],=WP4ODR(5)[8],=WP4ODT(5)[8],=WP4OEO(5)[8],=WP4OFA(5)[8],=WP4OFL(5)[8],
=WP4OHJ(5)[8],=WP4OKI(5)[8],=WP4OLM(5)[8],=WP4OMG(5)[8],=WP4OMV(5)[8],=WP4ONR(5)[8],=WP4OOI(5)[8],
=WP4OPD(5)[8],=WP4OPF(5)[8],=WP4OQH(5)[8],=WP4OTP(5)[8],=WP4OXA(5)[8],=WP4P(5)[8],=WP4PEP(5)[8],
=WP4PR(5)[8],=WP4PUV(5)[8],=WP4PWV(5)[8],=WP4PXG(5)[8],=WP4QER(5)[8],=WP4QGV(5)[8],=WP4QHU(5)[8],
=WP4RRR(5)[8],=WP4TD(5)[8],=WP4TX(5)[8],=WP4UC(5)[8],=WP4UM(5)[8],=WP4UO(5)[8],=WP4VL(5)[8],
=WP4VM(5)[8],=WP4YG(5)[8],=WP4ZW(5)[8],
AA5(4)[7],AB5(4)[7],AC5(4)[7],AD5(4)[7],AE5(4)[7],AF5(4)[7],AG5(4)[7],AI5(4)[7],AJ5(4)[7],
AK5(4)[7],K5(4)[7],KA5(4)[7],KB5(4)[7],KC5(4)[7],KD5(4)[7],KE5(4)[7],KF5(4)[7],KG5(4)[7],
KI5(4)[7],KJ5(4)[7],KK5(4)[7],KM5(4)[7],KN5(4)[7],KO5(4)[7],KQ5(4)[7],KR5(4)[7],KS5(4)[7],
@ -1403,45 +1403,45 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K:
=KH6TG(4)[7],=KH6UW(4)[7],=KH7CF(4)[7],=KH7CU(4)[7],=KH7FB(4)[7],=KH7IC(4)[7],=KH7JE(4)[7],
=KH7QL(4)[7],=KH7QO(4)[7],=KH8CG(4)[7],=KH9AE(4)[7],=KL0EX(4)[7],=KL0HU(4)[7],=KL0IF(4)[7],
=KL0PG(4)[7],=KL0WH(4)[7],=KL0XI(4)[7],=KL0ZY(4)[7],=KL1DA(4)[7],=KL1DJ(4)[7],=KL1DY(4)[7],
=KL1MM(4)[7],=KL1RX(4)[7],=KL1TS(4)[7],=KL1UR(4)[7],=KL1WG(4)[7],=KL1WO(4)[7],=KL1XK(4)[7],
=KL1Y(4)[7],=KL1ZW(4)[7],=KL2AX(4)[7],=KL2AX/5(4)[7],=KL2CD(4)[7],=KL2HC(4)[7],=KL2HN(4)[7],
=KL2MI(4)[7],=KL2OY(4)[7],=KL2RA(4)[7],=KL2RB(4)[7],=KL2TV(4)[7],=KL2UO(4)[7],=KL2UP(4)[7],
=KL2VA(4)[7],=KL2ZJ(4)[7],=KL2ZK(4)[7],=KL3DB(4)[7],=KL3DP(4)[7],=KL3FI(4)[7],=KL3HK(4)[7],
=KL3HX(4)[7],=KL3HZ(4)[7],=KL3JL(4)[7],=KL3KH(4)[7],=KL3KI(4)[7],=KL3TB(4)[7],=KL4JQ(4)[7],
=KL4LS(4)[7],=KL4QZ(4)[7],=KL4RA(4)[7],=KL5L(4)[7],=KL5Z(4)[7],=KL7AH(4)[7],=KL7AU(4)[7],
=KL7AX(4)[7],=KL7BCD(4)[7],=KL7BL(4)[7],=KL7BOB(4)[7],=KL7BX(4)[7],=KL7BZ/5(4)[7],=KL7BZL(4)[7],
=KL7CD(4)[7],=KL7DB(4)[7],=KL7EBE(4)[7],=KL7EMH(4)[7],=KL7EMH/M(4)[7],=KL7EQQ(4)[7],=KL7F(4)[7],
=KL7FB(4)[7],=KL7FHX(4)[7],=KL7FLY(4)[7],=KL7FQR(4)[7],=KL7GNW(4)[7],=KL7HH(4)[7],=KL7IDM(4)[7],
=KL7IK(4)[7],=KL7ITF(4)[7],=KL7IWU(4)[7],=KL7IZW(4)[7],=KL7JAR(4)[7],=KL7JEX(4)[7],=KL7JIU(4)[7],
=KL7JR/5(4)[7],=KL7JW(4)[7],=KL7LJ(4)[7],=KL7LY(4)[7],=KL7MA(4)[7],=KL7ME(4)[7],=KL7ML(4)[7],
=KL7NE(4)[7],=KL7NI(4)[7],=KL7OI(4)[7],=KL7PZ(4)[7],=KL7QC(4)[7],=KL7SG(4)[7],=KL7TN/5(4)[7],
=KL7U(4)[7],=KL7UHF(4)[7],=KL7USI/5(4)[7],=KL7XA(4)[7],=KL7XP(4)[7],=KL7XS(4)[7],=KL7YY/5(4)[7],
=KP2AZ(4)[7],=KP4CV(4)[7],=KP4DJT(4)[7],=KP4FF(4)[7],=KP4FFW(4)[7],=KP4GMC(4)[7],=KP4JE(4)[7],
=KP4JG(4)[7],=KP4JY(4)[7],=KP4YP(4)[7],=KP4YY(4)[7],=NH0V/5(4)[7],=NH2BV(4)[7],=NH2LP(4)[7],
=NH6AZ(4)[7],=NH6CJ(4)[7],=NH6EF(4)[7],=NH6FA(4)[7],=NH6KN(4)[7],=NH6L(4)[7],=NH6MG(4)[7],
=NH6PK(4)[7],=NH6TD(4)[7],=NH6VB(4)[7],=NH6VJ(4)[7],=NH6VR(4)[7],=NH6WL(4)[7],=NH6WL/5(4)[7],
=NH7FO(4)[7],=NH7MV(4)[7],=NH7PZ(4)[7],=NH7R(4)[7],=NH7RO(4)[7],=NH7RO/5(4)[7],=NH7TR(4)[7],
=NH7VA(4)[7],=NH7WB(4)[7],=NL5J(4)[7],=NL7AX(4)[7],=NL7C(4)[7],=NL7CO(4)[7],=NL7CO/5(4)[7],
=NL7DC(4)[7],=NL7HB(4)[7],=NL7IE(4)[7],=NL7JH(4)[7],=NL7JI(4)[7],=NL7JV(4)[7],=NL7JZ(4)[7],
=NL7K/5(4)[7],=NL7KB(4)[7],=NL7LE(4)[7],=NL7NP(4)[7],=NL7OM(4)[7],=NL7PD(4)[7],=NL7RQ(4)[7],
=NL7RQ/5(4)[7],=NL7SI(4)[7],=NL7TO(4)[7],=NL7WY(4)[7],=NL7ZL(4)[7],=NP2EE(4)[7],=NP2PR(4)[7],
=NP2RA(4)[7],=NP3BA(4)[7],=NP3CV(4)[7],=NP3NT(4)[7],=NP3PG(4)[7],=NP3RG(4)[7],=NP3SU(4)[7],
=NP3TY(4)[7],=NP4EA(4)[7],=NP4NQ(4)[7],=NP4NQ/5(4)[7],=NP4RW(4)[7],=NP4RZ(4)[7],=WH2ACT(4)[7],
=WH2ACT/5(4)[7],=WH6ARN(4)[7],=WH6BYJ(4)[7],=WH6BYP(4)[7],=WH6CCQ(4)[7],=WH6CDU(4)[7],
=WH6CUL(4)[7],=WH6DMP(4)[7],=WH6DSR(4)[7],=WH6DZU(4)[7],=WH6ECJ(4)[7],=WH6EMW(4)[7],=WH6EOF(4)[7],
=WH6ERS(4)[7],=WH6EUA(4)[7],=WH6EXQ(4)[7],=WH6FAD(4)[7],=WH6FGK(4)[7],=WH6FGM(4)[7],=WH6FTZ(4)[7],
=WH6FZ/5(4)[7],=WH6FZL(4)[7],=WH6FZN(4)[7],=WH6GBC(4)[7],=WH6GEA(4)[7],=WH6GL(4)[7],=WH6KK(4)[7],
=WH6L/5(4)[7],=WH7DC(4)[7],=WH7DW(4)[7],=WH7IN(4)[7],=WH7R(4)[7],=WH7YM(4)[7],=WH7YN(4)[7],
=WL3WX(4)[7],=WL5H(4)[7],=WL7AIU(4)[7],=WL7AWC(4)[7],=WL7BBV(4)[7],=WL7BKF(4)[7],=WL7BPY(4)[7],
=WL7CA(4)[7],=WL7CJA(4)[7],=WL7CJC(4)[7],=WL7CQE(4)[7],=WL7CTP(4)[7],=WL7CTQ(4)[7],=WL7D(4)[7],
=WL7FC(4)[7],=WL7FE(4)[7],=WL7FT(4)[7],=WL7FT/5(4)[7],=WL7K/5(4)[7],=WL7ME(4)[7],=WL7MQ/5(4)[7],
=WL7OP(4)[7],=WL7OU(4)[7],=WL7SG(4)[7],=WL7W(4)[7],=WL7WN(4)[7],=WL7XI(4)[7],=WL7XR(4)[7],
=WP2AHG(4)[7],=WP2N(4)[7],=WP2U(4)[7],=WP2WP(4)[7],=WP3AL(4)[7],=WP3HG(4)[7],=WP3JM(4)[7],
=WP3JN(4)[7],=WP4A(4)[7],=WP4ADA(4)[7],=WP4APJ(4)[7],=WP4BAB(4)[7],=WP4BAT(4)[7],=WP4CJY(4)[7],
=WP4EVA(4)[7],=WP4EVL(4)[7],=WP4IXT(4)[7],=WP4IYJ(4)[7],=WP4KSP(4)[7],=WP4KTF(4)[7],=WP4KUW(4)[7],
=WP4LKA(4)[7],=WP4LQR(4)[7],=WP4MJP(4)[7],=WP4MYI(4)[7],=WP4MZR(4)[7],=WP4NAK(4)[7],=WP4NEP(4)[7],
=WP4NQA(4)[7],=WP4NQL(4)[7],=WP4OEB(4)[7],=WP4OUE(4)[7],=WP4OZK(4)[7],=WP4OZP(4)[7],=WP4QLB(4)[7],
=WP4RON(4)[7],
=KL1DZ(4)[7],=KL1MM(4)[7],=KL1RX(4)[7],=KL1TS(4)[7],=KL1UR(4)[7],=KL1WG(4)[7],=KL1WO(4)[7],
=KL1XK(4)[7],=KL1Y(4)[7],=KL1ZW(4)[7],=KL2AX(4)[7],=KL2AX/5(4)[7],=KL2CD(4)[7],=KL2HC(4)[7],
=KL2HN(4)[7],=KL2MI(4)[7],=KL2OY(4)[7],=KL2RA(4)[7],=KL2RB(4)[7],=KL2TV(4)[7],=KL2UO(4)[7],
=KL2UP(4)[7],=KL2VA(4)[7],=KL2ZJ(4)[7],=KL2ZK(4)[7],=KL3DB(4)[7],=KL3DP(4)[7],=KL3FI(4)[7],
=KL3HK(4)[7],=KL3HX(4)[7],=KL3HZ(4)[7],=KL3JL(4)[7],=KL3KH(4)[7],=KL3KI(4)[7],=KL3TB(4)[7],
=KL4JQ(4)[7],=KL4LS(4)[7],=KL4QZ(4)[7],=KL4RA(4)[7],=KL5L(4)[7],=KL5Z(4)[7],=KL7AH(4)[7],
=KL7AU(4)[7],=KL7AX(4)[7],=KL7BCD(4)[7],=KL7BL(4)[7],=KL7BOB(4)[7],=KL7BX(4)[7],=KL7BZ/5(4)[7],
=KL7BZL(4)[7],=KL7CD(4)[7],=KL7DB(4)[7],=KL7EBE(4)[7],=KL7EMH(4)[7],=KL7EMH/M(4)[7],=KL7EQQ(4)[7],
=KL7F(4)[7],=KL7FB(4)[7],=KL7FHX(4)[7],=KL7FLY(4)[7],=KL7FQR(4)[7],=KL7GNW(4)[7],=KL7HH(4)[7],
=KL7IDM(4)[7],=KL7IK(4)[7],=KL7ITF(4)[7],=KL7IWU(4)[7],=KL7IZW(4)[7],=KL7JAR(4)[7],=KL7JEX(4)[7],
=KL7JIU(4)[7],=KL7JR/5(4)[7],=KL7JW(4)[7],=KL7LJ(4)[7],=KL7LY(4)[7],=KL7MA(4)[7],=KL7ME(4)[7],
=KL7ML(4)[7],=KL7NE(4)[7],=KL7NI(4)[7],=KL7OI(4)[7],=KL7PZ(4)[7],=KL7QC(4)[7],=KL7SG(4)[7],
=KL7TN/5(4)[7],=KL7U(4)[7],=KL7UHF(4)[7],=KL7USI/5(4)[7],=KL7XA(4)[7],=KL7XP(4)[7],=KL7XS(4)[7],
=KL7YY/5(4)[7],=KP2AZ(4)[7],=KP4CV(4)[7],=KP4DJT(4)[7],=KP4FF(4)[7],=KP4FFW(4)[7],=KP4GMC(4)[7],
=KP4JE(4)[7],=KP4JG(4)[7],=KP4JY(4)[7],=KP4YP(4)[7],=KP4YY(4)[7],=NH0V/5(4)[7],=NH2BV(4)[7],
=NH2LP(4)[7],=NH6AZ(4)[7],=NH6CJ(4)[7],=NH6EF(4)[7],=NH6FA(4)[7],=NH6KN(4)[7],=NH6L(4)[7],
=NH6MG(4)[7],=NH6PK(4)[7],=NH6TD(4)[7],=NH6VB(4)[7],=NH6VJ(4)[7],=NH6VR(4)[7],=NH6WL(4)[7],
=NH6WL/5(4)[7],=NH7FO(4)[7],=NH7MV(4)[7],=NH7PZ(4)[7],=NH7R(4)[7],=NH7RO(4)[7],=NH7RO/5(4)[7],
=NH7TR(4)[7],=NH7VA(4)[7],=NH7WB(4)[7],=NL5J(4)[7],=NL7AX(4)[7],=NL7C(4)[7],=NL7CO(4)[7],
=NL7CO/5(4)[7],=NL7DC(4)[7],=NL7HB(4)[7],=NL7IE(4)[7],=NL7JH(4)[7],=NL7JI(4)[7],=NL7JV(4)[7],
=NL7JZ(4)[7],=NL7K/5(4)[7],=NL7KB(4)[7],=NL7LE(4)[7],=NL7NP(4)[7],=NL7OM(4)[7],=NL7PD(4)[7],
=NL7RQ(4)[7],=NL7RQ/5(4)[7],=NL7SI(4)[7],=NL7TO(4)[7],=NL7WY(4)[7],=NL7ZL(4)[7],=NP2EE(4)[7],
=NP2PR(4)[7],=NP2RA(4)[7],=NP3BA(4)[7],=NP3CV(4)[7],=NP3NT(4)[7],=NP3PG(4)[7],=NP3RG(4)[7],
=NP3SU(4)[7],=NP3TY(4)[7],=NP4EA(4)[7],=NP4NQ(4)[7],=NP4NQ/5(4)[7],=NP4RW(4)[7],=NP4RZ(4)[7],
=WH2ACT(4)[7],=WH2ACT/5(4)[7],=WH6ARN(4)[7],=WH6BYJ(4)[7],=WH6BYP(4)[7],=WH6CCQ(4)[7],
=WH6CDU(4)[7],=WH6CUL(4)[7],=WH6DMP(4)[7],=WH6DSR(4)[7],=WH6DZU(4)[7],=WH6ECJ(4)[7],=WH6EMW(4)[7],
=WH6EOF(4)[7],=WH6ERS(4)[7],=WH6EUA(4)[7],=WH6EXQ(4)[7],=WH6FAD(4)[7],=WH6FGK(4)[7],=WH6FGM(4)[7],
=WH6FTZ(4)[7],=WH6FZ/5(4)[7],=WH6FZL(4)[7],=WH6FZN(4)[7],=WH6GBC(4)[7],=WH6GEA(4)[7],=WH6GL(4)[7],
=WH6KK(4)[7],=WH6L/5(4)[7],=WH7DC(4)[7],=WH7DW(4)[7],=WH7IN(4)[7],=WH7R(4)[7],=WH7YM(4)[7],
=WH7YN(4)[7],=WL3WX(4)[7],=WL5H(4)[7],=WL7AIU(4)[7],=WL7AWC(4)[7],=WL7BBV(4)[7],=WL7BKF(4)[7],
=WL7BPY(4)[7],=WL7CA(4)[7],=WL7CJA(4)[7],=WL7CJC(4)[7],=WL7CQE(4)[7],=WL7CTP(4)[7],=WL7CTQ(4)[7],
=WL7D(4)[7],=WL7FC(4)[7],=WL7FE(4)[7],=WL7FT(4)[7],=WL7FT/5(4)[7],=WL7K/5(4)[7],=WL7ME(4)[7],
=WL7MQ/5(4)[7],=WL7OP(4)[7],=WL7OU(4)[7],=WL7SG(4)[7],=WL7W(4)[7],=WL7WN(4)[7],=WL7XI(4)[7],
=WL7XR(4)[7],=WP2AHG(4)[7],=WP2N(4)[7],=WP2U(4)[7],=WP2WP(4)[7],=WP3AL(4)[7],=WP3HG(4)[7],
=WP3JM(4)[7],=WP3JN(4)[7],=WP4A(4)[7],=WP4ADA(4)[7],=WP4APJ(4)[7],=WP4BAB(4)[7],=WP4BAT(4)[7],
=WP4CJY(4)[7],=WP4EVA(4)[7],=WP4EVL(4)[7],=WP4IXT(4)[7],=WP4IYJ(4)[7],=WP4KSP(4)[7],=WP4KTF(4)[7],
=WP4KUW(4)[7],=WP4LKA(4)[7],=WP4LQR(4)[7],=WP4MJP(4)[7],=WP4MYI(4)[7],=WP4MZR(4)[7],=WP4NAK(4)[7],
=WP4NEP(4)[7],=WP4NQA(4)[7],=WP4NQL(4)[7],=WP4OEB(4)[7],=WP4OFH(4)[7],=WP4OUE(4)[7],=WP4OZK(4)[7],
=WP4OZP(4)[7],=WP4QLB(4)[7],=WP4RON(4)[7],
AA6(3)[6],AB6(3)[6],AC6(3)[6],AD6(3)[6],AE6(3)[6],AF6(3)[6],AG6(3)[6],AI6(3)[6],AJ6(3)[6],
AK6(3)[6],K6(3)[6],KA6(3)[6],KB6(3)[6],KC6(3)[6],KD6(3)[6],KE6(3)[6],KF6(3)[6],KG6(3)[6],
KI6(3)[6],KJ6(3)[6],KK6(3)[6],KM6(3)[6],KN6(3)[6],KO6(3)[6],KQ6(3)[6],KR6(3)[6],KS6(3)[6],
@ -1519,11 +1519,11 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K:
=AH2DP(3)[6],=AH2DS(3)[6],=AH2S(3)[6],=AH6B/7(3)[6],=AH6D(3)[6],=AH6ET(3)[6],=AH6EZ(3)[6],
=AH6EZ/7(3)[6],=AH6FC/7(3)[6],=AH6GA(3)[6],=AH6HK(3)[6],=AH6HS(3)[6],=AH6HX(3)[6],=AH6I(3)[6],
=AH6IP(3)[6],=AH6JS(3)[6],=AH6LA(3)[6],=AH6LE(3)[6],=AH6LE/7(3)[6],=AH6NJ(3)[6],=AH6NR(3)[6],
=AH6OD(3)[6],=AH6PJ(3)[6],=AH6PW(3)[6],=AH6QW(3)[6],=AH6RI/7(3)[6],=AH6SV(3)[6],=AH6VM(3)[6],
=AH6Y(3)[6],=AH7MP(3)[6],=AH7Q(3)[6],=AH8AC(3)[6],=AH8DX(3)[6],=AH8K(3)[6],=AH9A(3)[6],
=AH9AC(3)[6],=AL0AA(3)[6],=AL0FT(3)[6],=AL0H(3)[6],=AL0X(3)[6],=AL1N(3)[6],=AL1P(3)[6],
=AL1R(3)[6],=AL1VE(3)[6],=AL2B(3)[6],=AL2GR(3)[6],=AL2I(3)[6],=AL2N(3)[6],=AL3L(3)[6],=AL4D(3)[6],
=AL4F(3)[6],=AL4K(3)[6],=AL4Q/7(3)[6],=AL4R(3)[6],=AL5B(3)[6],=AL5W(3)[6],=AL6U(3)[6],
=AH6OD(3)[6],=AH6P(3)[6],=AH6PJ(3)[6],=AH6PW(3)[6],=AH6QW(3)[6],=AH6RI/7(3)[6],=AH6SV(3)[6],
=AH6VM(3)[6],=AH6Y(3)[6],=AH7MP(3)[6],=AH7Q(3)[6],=AH8AC(3)[6],=AH8DX(3)[6],=AH8K(3)[6],
=AH9A(3)[6],=AH9AC(3)[6],=AL0AA(3)[6],=AL0FT(3)[6],=AL0H(3)[6],=AL0X(3)[6],=AL1N(3)[6],
=AL1P(3)[6],=AL1R(3)[6],=AL1VE(3)[6],=AL2B(3)[6],=AL2GR(3)[6],=AL2I(3)[6],=AL2N(3)[6],=AL3L(3)[6],
=AL4D(3)[6],=AL4F(3)[6],=AL4K(3)[6],=AL4Q/7(3)[6],=AL4R(3)[6],=AL5B(3)[6],=AL5W(3)[6],=AL6U(3)[6],
=AL7AA(3)[6],=AL7AN(3)[6],=AL7AW(3)[6],=AL7BN(3)[6],=AL7BQ(3)[6],=AL7CC(3)[6],=AL7CG(3)[6],
=AL7CM(3)[6],=AL7CM/7(3)[6],=AL7CR(3)[6],=AL7CS(3)[6],=AL7D(3)[6],=AL7D/7(3)[6],=AL7D/P(3)[6],
=AL7D/R(3)[6],=AL7DD(3)[6],=AL7DU(3)[6],=AL7EI(3)[6],=AL7EJ(3)[6],=AL7FA(3)[6],=AL7FB(3)[6],
@ -1558,80 +1558,81 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K:
=KL0PC(3)[6],=KL0PP(3)[6],=KL0QD(3)[6],=KL0RA(3)[6],=KL0SA(3)[6],=KL0SZ(3)[6],=KL0TQ(3)[6],
=KL0TR(3)[6],=KL0TU(3)[6],=KL0VB(3)[6],=KL0VZ(3)[6],=KL0WN(3)[6],=KL0ZF(3)[6],=KL0ZL(3)[6],
=KL1AA(3)[6],=KL1AE(3)[6],=KL1AK(3)[6],=KL1CQ(3)[6],=KL1DO(3)[6],=KL1DW(3)[6],=KL1ED(3)[6],
=KL1HS(3)[6],=KL1JF(3)[6],=KL1K(3)[6],=KL1KU(3)[6],=KL1LE(3)[6],=KL1LZ(3)[6],=KL1MF(3)[6],
=KL1OH(3)[6],=KL1QL(3)[6],=KL1RH(3)[6],=KL1RV(3)[6],=KL1SF/7(3)[6],=KL1SO(3)[6],=KL1SP(3)[6],
=KL1U(3)[6],=KL1UA(3)[6],=KL1UM(3)[6],=KL1XI(3)[6],=KL1YO(3)[6],=KL1YY/7(3)[6],=KL1ZN(3)[6],
=KL1ZP(3)[6],=KL1ZR(3)[6],=KL2A(3)[6],=KL2A/7(3)[6],=KL2BO(3)[6],=KL2BP(3)[6],=KL2BW(3)[6],
=KL2BY(3)[6],=KL2BZ(3)[6],=KL2FD(3)[6],=KL2FL(3)[6],=KL2JY(3)[6],=KL2K(3)[6],=KL2KY(3)[6],
=KL2LA(3)[6],=KL2LN(3)[6],=KL2LT(3)[6],=KL2MA(3)[6],=KL2MB(3)[6],=KL2MP(3)[6],=KL2NJ(3)[6],
=KL2NU(3)[6],=KL2NW(3)[6],=KL2OH(3)[6],=KL2OJ(3)[6],=KL2P(3)[6],=KL2QE(3)[6],=KL2TR(3)[6],
=KL2TZ(3)[6],=KL2VK(3)[6],=KL2WE(3)[6],=KL2XQ(3)[6],=KL2YH(3)[6],=KL2YQ(3)[6],=KL3DL(3)[6],
=KL3ET(3)[6],=KL3EZ(3)[6],=KL3FE(3)[6],=KL3FY(3)[6],=KL3HL(3)[6],=KL3IC(3)[6],=KL3II(3)[6],
=KL3IO(3)[6],=KL3ML(3)[6],=KL3NE(3)[6],=KL3NO(3)[6],=KL3OQ(3)[6],=KL3PD(3)[6],=KL3TW(3)[6],
=KL3TY(3)[6],=KL3VJ(3)[6],=KL3XS(3)[6],=KL4BQ(3)[6],=KL4BS(3)[6],=KL4FX(3)[6],=KL4KF(3)[6],
=KL4LB(3)[6],=KL4NG(3)[6],=KL4QJ(3)[6],=KL4RKH(3)[6],=KL4RY(3)[6],=KL4YFD(3)[6],=KL7AB(3)[6],
=KL7AD(3)[6],=KL7AW(3)[6],=KL7BB(3)[6],=KL7BD(3)[6],=KL7BDC(3)[6],=KL7BH(3)[6],=KL7BJ(3)[6],
=KL7BR(3)[6],=KL7BS(3)[6],=KL7BT(3)[6],=KL7BUR(3)[6],=KL7BXP(3)[6],=KL7C(3)[6],=KL7CPO(3)[6],
=KL7CR(3)[6],=KL7CT(3)[6],=KL7CY(3)[6],=KL7DC(3)[6],=KL7DF(3)[6],=KL7DI(3)[6],=KL7DK(3)[6],
=KL7DLG(3)[6],=KL7DSI(3)[6],=KL7DZQ(3)[6],=KL7EBN(3)[6],=KL7EF(3)[6],=KL7EFL(3)[6],=KL7EH(3)[6],
=KL7EIN(3)[6],=KL7EU(3)[6],=KL7FDQ(3)[6],=KL7FDQ/7(3)[6],=KL7FIR(3)[6],=KL7FLR(3)[6],
=KL7FOZ(3)[6],=KL7FRQ(3)[6],=KL7FS(3)[6],=KL7GA(3)[6],=KL7GCS(3)[6],=KL7GKY(3)[6],=KL7GRF(3)[6],
=KL7GT(3)[6],=KL7GU(3)[6],=KL7HB(3)[6],=KL7HBV(3)[6],=KL7HFI/7(3)[6],=KL7HFV(3)[6],=KL7HI(3)[6],
=KL7HJR(3)[6],=KL7HLF(3)[6],=KL7HM(3)[6],=KL7HMK(3)[6],=KL7HQL(3)[6],=KL7HSR(3)[6],=KL7IAL(3)[6],
=KL7IBT(3)[6],=KL7IDY(3)[6],=KL7IEI(3)[6],=KL7IFK(3)[6],=KL7IG(3)[6],=KL7IGB(3)[6],=KL7IHK(3)[6],
=KL7IIK(3)[6],=KL7IKV(3)[6],=KL7IL(3)[6],=KL7IME(3)[6],=KL7IOW(3)[6],=KL7IPV(3)[6],=KL7ISE(3)[6],
=KL7IUX(3)[6],=KL7IWC/7(3)[6],=KL7IZC(3)[6],=KL7IZH(3)[6],=KL7JAV(3)[6],=KL7JBB(3)[6],
=KL7JDQ(3)[6],=KL7JEA(3)[6],=KL7JES(3)[6],=KL7JIJ(3)[6],=KL7JJE(3)[6],=KL7JKV(3)[6],=KL7KA(3)[6],
=KL7KG/7(3)[6],=KL7LG(3)[6],=KL7LI(3)[6],=KL7LX(3)[6],=KL7LZ(3)[6],=KL7M(3)[6],=KL7MY(3)[6],
=KL7MZ(3)[6],=KL7NA(3)[6],=KL7NP(3)[6],=KL7NP/7(3)[6],=KL7OA(3)[6],=KL7OF(3)[6],=KL7OL(3)[6],
=KL7OR(3)[6],=KL7OR/7(3)[6],=KL7OS(3)[6],=KL7OY(3)[6],=KL7PC(3)[6],=KL7PO(3)[6],=KL7QA(3)[6],
=KL7QK(3)[6],=KL7QK/140(3)[6],=KL7QK/7(3)[6],=KL7QR(3)[6],=KL7QR/7(3)[6],=KL7R(3)[6],=KL7RC(3)[6],
=KL7RK(3)[6],=KL7RM(3)[6],=KL7RN(3)[6],=KL7RS(3)[6],=KL7S(3)[6],=KL7SK(3)[6],=KL7SP(3)[6],
=KL7SV(3)[6],=KL7T(3)[6],=KL7TU(3)[6],=KL7UP(3)[6],=KL7UT(3)[6],=KL7VK(3)[6],=KL7VL(3)[6],
=KL7VN(3)[6],=KL7VQ(3)[6],=KL7WC(3)[6],=KL7WG(3)[6],=KL7WM(3)[6],=KL7WN(3)[6],=KL7WP(3)[6],
=KL7WP/7(3)[6],=KL7WT(3)[6],=KL7XL(3)[6],=KL7YJ(3)[6],=KL7YQ(3)[6],=KL7YY/M(3)[6],=KL7ZH(3)[6],
=KL7ZW(3)[6],=KL8RV(3)[6],=KL8SU(3)[6],=KL9PC(3)[6],=KP2BX(3)[6],=KP2CB(3)[6],=KP2CT(3)[6],
=KP4EFZ(3)[6],=KP4UZ(3)[6],=KP4X(3)[6],=NH0F(3)[6],=NH0K(3)[6],=NH0O(3)[6],=NH2DM(3)[6],
=NH2JE(3)[6],=NH2KR(3)[6],=NH6AD(3)[6],=NH6AJ(3)[6],=NH6AY(3)[6],=NH6B(3)[6],=NH6BF(3)[6],
=NH6CI(3)[6],=NH6CO(3)[6],=NH6DQ(3)[6],=NH6DX(3)[6],=NH6F(3)[6],=NH6FF(3)[6],=NH6GZ(3)[6],
=NH6HE(3)[6],=NH6HZ(3)[6],=NH6KF(3)[6],=NH6LF(3)[6],=NH6LM(3)[6],=NH6NS(3)[6],=NH6SO(3)[6],
=NH6U(3)[6],=NH6WE(3)[6],=NH6XN(3)[6],=NH6XP(3)[6],=NH6YR(3)[6],=NH6Z(3)[6],=NH6ZA(3)[6],
=NH6ZE(3)[6],=NH7DZ(3)[6],=NH7FU(3)[6],=NH7FZ(3)[6],=NH7L(3)[6],=NH7M(3)[6],=NH7MY(3)[6],
=NH7N(3)[6],=NH7ND(3)[6],=NH7NJ/7(3)[6],=NH7OC(3)[6],=NH7PL(3)[6],=NH7RS(3)[6],=NH7S(3)[6],
=NH7SH(3)[6],=NH7TG(3)[6],=NH7VZ(3)[6],=NH7W(3)[6],=NH7WT(3)[6],=NH7WU(3)[6],=NH7YE(3)[6],
=NH7YI(3)[6],=NH8A(3)[6],=NL5L(3)[6],=NL7AH(3)[6],=NL7AR(3)[6],=NL7AZ(3)[6],=NL7BI(3)[6],
=NL7CH(3)[6],=NL7D(3)[6],=NL7D/7(3)[6],=NL7DH(3)[6],=NL7DY(3)[6],=NL7EO(3)[6],=NL7FQ(3)[6],
=NL7FX(3)[6],=NL7FY(3)[6],=NL7GM(3)[6],=NL7GN(3)[6],=NL7GO(3)[6],=NL7GU(3)[6],=NL7GW(3)[6],
=NL7HH(3)[6],=NL7HK(3)[6],=NL7HQ(3)[6],=NL7HU(3)[6],=NL7IN(3)[6],=NL7JE(3)[6],=NL7JJ(3)[6],
=NL7JN(3)[6],=NL7KV(3)[6],=NL7LI(3)[6],=NL7MS(3)[6],=NL7MT(3)[6],=NL7NL(3)[6],=NL7OF(3)[6],
=NL7PN(3)[6],=NL7QI(3)[6],=NL7RL(3)[6],=NL7RN(3)[6],=NL7TK(3)[6],=NL7UE(3)[6],=NL7US(3)[6],
=NL7VS(3)[6],=NL7WD(3)[6],=NL7WJ(3)[6],=NL7XX(3)[6],=NL7ZM(3)[6],=NL7ZN(3)[6],=NL7ZP(3)[6],
=NP2CT(3)[6],=NP2KL(3)[6],=NP2LK(3)[6],=NP2X/7(3)[6],=NP3PH(3)[6],=NP4AI/M(3)[6],=NP4ES(3)[6],
=NP4FP(3)[6],=NP4I(3)[6],=NP4JV(3)[6],=NP4JV/7(3)[6],=VA2GLB/P(3)[6],=WH0AAM(3)[6],=WH0J(3)[6],
=WH2ACV(3)[6],=WH2AJF(3)[6],=WH6ANB(3)[6],=WH6ARU(3)[6],=WH6ASB(3)[6],=WH6B(3)[6],=WH6BDR(3)[6],
=WH6BLM(3)[6],=WH6BPL(3)[6],=WH6BPU(3)[6],=WH6CF(3)[6],=WH6CMS(3)[6],=WH6CN(3)[6],=WH6CUS(3)[6],
=WH6CWD(3)[6],=WH6CXB(3)[6],=WH6CXE(3)[6],=WH6CXN(3)[6],=WH6CYB(3)[6],=WH6CZ(3)[6],=WH6DAP(3)[6],
=WH6DAY(3)[6],=WH6DJO(3)[6],=WH6DKC(3)[6],=WH6DKG(3)[6],=WH6DKO(3)[6],=WH6DLQ(3)[6],=WH6DMS(3)[6],
=WH6DQ(3)[6],=WH6DRP(3)[6],=WH6DST(3)[6],=WH6DTH(3)[6],=WH6EEC(3)[6],=WH6EEG(3)[6],=WH6EGM(3)[6],
=WH6EHW(3)[6],=WH6EJV(3)[6],=WH6EQB(3)[6],=WH6EQE(3)[6],=WH6EQH(3)[6],=WH6ESS(3)[6],=WH6ETO(3)[6],
=WH6EWE(3)[6],=WH6FCT(3)[6],=WH6FEU(3)[6],=WH6FJR(3)[6],=WH6FL(3)[6],=WH6FOJ(3)[6],=WH6FPR(3)[6],
=WH6FPV(3)[6],=WH6FQ(3)[6],=WH6FQK(3)[6],=WH6GCT(3)[6],=WH6GEV(3)[6],=WH6OL(3)[6],=WH6OY(3)[6],
=WH6QV(3)[6],=WH6SD(3)[6],=WH6SR(3)[6],=WH6TI(3)[6],=WH6U(3)[6],=WH6XV(3)[6],=WH6YT(3)[6],
=WH6YX(3)[6],=WH6ZR(3)[6],=WH6ZV(3)[6],=WH7A(3)[6],=WH7CY(3)[6],=WH7DA(3)[6],=WH7DB(3)[6],
=WH7DE(3)[6],=WH7G(3)[6],=WH7GC(3)[6],=WH7GY(3)[6],=WH7HU(3)[6],=WH7LB(3)[6],=WH7NS(3)[6],
=WH7OK(3)[6],=WH7P(3)[6],=WH7RG(3)[6],=WH7TC(3)[6],=WH7TN(3)[6],=WH7TR(3)[6],=WH7U(3)[6],
=WH7UP(3)[6],=WH7WP(3)[6],=WH7WT(3)[6],=WH7XP(3)[6],=WH8AAG(3)[6],=WL7AAW(3)[6],=WL7AL(3)[6],
=WL7AP(3)[6],=WL7AQ(3)[6],=WL7AUY(3)[6],=WL7AWD(3)[6],=WL7AXI(3)[6],=WL7AZG(3)[6],=WL7AZL(3)[6],
=WL7BCR(3)[6],=WL7BHR(3)[6],=WL7BLM(3)[6],=WL7BM(3)[6],=WL7BNQ(3)[6],=WL7BON(3)[6],=WL7BOO(3)[6],
=WL7BSW(3)[6],=WL7BUI(3)[6],=WL7BVN(3)[6],=WL7BVS(3)[6],=WL7CAZ(3)[6],=WL7CBF(3)[6],=WL7CES(3)[6],
=WL7COQ(3)[6],=WL7CPE(3)[6],=WL7CPI(3)[6],=WL7CQX(3)[6],=WL7CRJ(3)[6],=WL7CSL(3)[6],=WL7CTB(3)[6],
=WL7CTC(3)[6],=WL7CTE(3)[6],=WL7DD(3)[6],=WL7FA(3)[6],=WL7FR(3)[6],=WL7FU(3)[6],=WL7H(3)[6],
=WL7HE(3)[6],=WL7HK(3)[6],=WL7HL(3)[6],=WL7IQ(3)[6],=WL7IS(3)[6],=WL7JG(3)[6],=WL7JM(3)[6],
=WL7K(3)[6],=WL7K/7(3)[6],=WL7K/M(3)[6],=WL7LB(3)[6],=WL7LK(3)[6],=WL7OA(3)[6],=WL7P(3)[6],
=WL7PJ(3)[6],=WL7QC(3)[6],=WL7QX(3)[6],=WL7RV/140(3)[6],=WL7SD(3)[6],=WL7SO(3)[6],=WL7SV(3)[6],
=WL7T/P(3)[6],=WL7VK(3)[6],=WL7VV(3)[6],=WL7WB(3)[6],=WL7WF(3)[6],=WL7WG(3)[6],=WL7WK(3)[6],
=WL7WM(3)[6],=WL7WU(3)[6],=WL7XE(3)[6],=WL7XJ(3)[6],=WL7XN(3)[6],=WL7XW(3)[6],=WL7Z(3)[6],
=WL7ZM(3)[6],=WP2ADG(3)[6],=WP3ZO(3)[6],=WP4DYP(3)[6],=WP4NBP(3)[6],
=KL1HF(3)[6],=KL1HS(3)[6],=KL1JF(3)[6],=KL1K(3)[6],=KL1KU(3)[6],=KL1LE(3)[6],=KL1LZ(3)[6],
=KL1MF(3)[6],=KL1OH(3)[6],=KL1QL(3)[6],=KL1RH(3)[6],=KL1RV(3)[6],=KL1SF/7(3)[6],=KL1SO(3)[6],
=KL1SP(3)[6],=KL1U(3)[6],=KL1UA(3)[6],=KL1UM(3)[6],=KL1XI(3)[6],=KL1YO(3)[6],=KL1YY/7(3)[6],
=KL1ZN(3)[6],=KL1ZP(3)[6],=KL1ZR(3)[6],=KL2A(3)[6],=KL2A/7(3)[6],=KL2BO(3)[6],=KL2BP(3)[6],
=KL2BW(3)[6],=KL2BY(3)[6],=KL2BZ(3)[6],=KL2FD(3)[6],=KL2FL(3)[6],=KL2JY(3)[6],=KL2K(3)[6],
=KL2KY(3)[6],=KL2LA(3)[6],=KL2LN(3)[6],=KL2LT(3)[6],=KL2MA(3)[6],=KL2MB(3)[6],=KL2MP(3)[6],
=KL2NJ(3)[6],=KL2NU(3)[6],=KL2NW(3)[6],=KL2OH(3)[6],=KL2OJ(3)[6],=KL2P(3)[6],=KL2QE(3)[6],
=KL2TR(3)[6],=KL2TZ(3)[6],=KL2VK(3)[6],=KL2WE(3)[6],=KL2XQ(3)[6],=KL2YH(3)[6],=KL2YQ(3)[6],
=KL3DL(3)[6],=KL3ET(3)[6],=KL3EZ(3)[6],=KL3FE(3)[6],=KL3FY(3)[6],=KL3HL(3)[6],=KL3HM(3)[6],
=KL3HN(3)[6],=KL3IC(3)[6],=KL3II(3)[6],=KL3IO(3)[6],=KL3ML(3)[6],=KL3NE(3)[6],=KL3NO(3)[6],
=KL3OQ(3)[6],=KL3PD(3)[6],=KL3RH(3)[6],=KL3TW(3)[6],=KL3TY(3)[6],=KL3VJ(3)[6],=KL3XS(3)[6],
=KL4BQ(3)[6],=KL4BS(3)[6],=KL4FX(3)[6],=KL4KF(3)[6],=KL4LB(3)[6],=KL4NG(3)[6],=KL4QJ(3)[6],
=KL4RKH(3)[6],=KL4RY(3)[6],=KL4YFD(3)[6],=KL7AB(3)[6],=KL7AD(3)[6],=KL7AW(3)[6],=KL7BB(3)[6],
=KL7BD(3)[6],=KL7BDC(3)[6],=KL7BH(3)[6],=KL7BJ(3)[6],=KL7BR(3)[6],=KL7BS(3)[6],=KL7BT(3)[6],
=KL7BUR(3)[6],=KL7BXP(3)[6],=KL7C(3)[6],=KL7CPO(3)[6],=KL7CR(3)[6],=KL7CT(3)[6],=KL7CY(3)[6],
=KL7DC(3)[6],=KL7DF(3)[6],=KL7DI(3)[6],=KL7DK(3)[6],=KL7DLG(3)[6],=KL7DSI(3)[6],=KL7DZQ(3)[6],
=KL7EBN(3)[6],=KL7EF(3)[6],=KL7EFL(3)[6],=KL7EH(3)[6],=KL7EIN(3)[6],=KL7EU(3)[6],=KL7FDQ(3)[6],
=KL7FDQ/7(3)[6],=KL7FIR(3)[6],=KL7FLR(3)[6],=KL7FOZ(3)[6],=KL7FRQ(3)[6],=KL7FS(3)[6],=KL7GA(3)[6],
=KL7GCS(3)[6],=KL7GKY(3)[6],=KL7GRF(3)[6],=KL7GT(3)[6],=KL7GU(3)[6],=KL7HB(3)[6],=KL7HBV(3)[6],
=KL7HFI/7(3)[6],=KL7HFV(3)[6],=KL7HI(3)[6],=KL7HJR(3)[6],=KL7HLF(3)[6],=KL7HM(3)[6],=KL7HMK(3)[6],
=KL7HQL(3)[6],=KL7HSR(3)[6],=KL7IAL(3)[6],=KL7IBT(3)[6],=KL7IDY(3)[6],=KL7IEI(3)[6],=KL7IFK(3)[6],
=KL7IG(3)[6],=KL7IGB(3)[6],=KL7IHK(3)[6],=KL7IIK(3)[6],=KL7IKV(3)[6],=KL7IL(3)[6],=KL7IME(3)[6],
=KL7IOW(3)[6],=KL7IPV(3)[6],=KL7ISE(3)[6],=KL7IUX(3)[6],=KL7IWC/7(3)[6],=KL7IZC(3)[6],
=KL7IZH(3)[6],=KL7JAV(3)[6],=KL7JBB(3)[6],=KL7JDQ(3)[6],=KL7JEA(3)[6],=KL7JES(3)[6],=KL7JIJ(3)[6],
=KL7JJE(3)[6],=KL7JKV(3)[6],=KL7KA(3)[6],=KL7KG/7(3)[6],=KL7LG(3)[6],=KL7LI(3)[6],=KL7LX(3)[6],
=KL7LZ(3)[6],=KL7M(3)[6],=KL7MY(3)[6],=KL7MZ(3)[6],=KL7NA(3)[6],=KL7NP(3)[6],=KL7NP/7(3)[6],
=KL7OA(3)[6],=KL7OF(3)[6],=KL7OL(3)[6],=KL7OR(3)[6],=KL7OR/7(3)[6],=KL7OS(3)[6],=KL7OY(3)[6],
=KL7PC(3)[6],=KL7PO(3)[6],=KL7QA(3)[6],=KL7QK(3)[6],=KL7QK/140(3)[6],=KL7QK/7(3)[6],=KL7QR(3)[6],
=KL7QR/7(3)[6],=KL7R(3)[6],=KL7RC(3)[6],=KL7RK(3)[6],=KL7RM(3)[6],=KL7RN(3)[6],=KL7RS(3)[6],
=KL7S(3)[6],=KL7SK(3)[6],=KL7SP(3)[6],=KL7SV(3)[6],=KL7T(3)[6],=KL7TU(3)[6],=KL7UP(3)[6],
=KL7UT(3)[6],=KL7VK(3)[6],=KL7VL(3)[6],=KL7VN(3)[6],=KL7VQ(3)[6],=KL7WC(3)[6],=KL7WG(3)[6],
=KL7WM(3)[6],=KL7WN(3)[6],=KL7WP(3)[6],=KL7WP/7(3)[6],=KL7WT(3)[6],=KL7XL(3)[6],=KL7YJ(3)[6],
=KL7YQ(3)[6],=KL7YY/M(3)[6],=KL7ZH(3)[6],=KL7ZW(3)[6],=KL8RV(3)[6],=KL8SU(3)[6],=KL9PC(3)[6],
=KP2BX(3)[6],=KP2CB(3)[6],=KP2CT(3)[6],=KP4EFZ(3)[6],=KP4UZ(3)[6],=KP4X(3)[6],=NH0F(3)[6],
=NH0K(3)[6],=NH0O(3)[6],=NH2DM(3)[6],=NH2JE(3)[6],=NH2KR(3)[6],=NH6AD(3)[6],=NH6AJ(3)[6],
=NH6AY(3)[6],=NH6B(3)[6],=NH6BF(3)[6],=NH6CI(3)[6],=NH6CO(3)[6],=NH6DQ(3)[6],=NH6DX(3)[6],
=NH6F(3)[6],=NH6FF(3)[6],=NH6GZ(3)[6],=NH6HE(3)[6],=NH6HZ(3)[6],=NH6KF(3)[6],=NH6LF(3)[6],
=NH6LM(3)[6],=NH6NS(3)[6],=NH6SO(3)[6],=NH6U(3)[6],=NH6WE(3)[6],=NH6XN(3)[6],=NH6XP(3)[6],
=NH6YR(3)[6],=NH6Z(3)[6],=NH6ZA(3)[6],=NH6ZE(3)[6],=NH7DZ(3)[6],=NH7FU(3)[6],=NH7FZ(3)[6],
=NH7L(3)[6],=NH7M(3)[6],=NH7MY(3)[6],=NH7N(3)[6],=NH7ND(3)[6],=NH7NJ/7(3)[6],=NH7OC(3)[6],
=NH7PL(3)[6],=NH7RS(3)[6],=NH7S(3)[6],=NH7SH(3)[6],=NH7TG(3)[6],=NH7VZ(3)[6],=NH7W(3)[6],
=NH7WT(3)[6],=NH7WU(3)[6],=NH7YE(3)[6],=NH7YI(3)[6],=NH8A(3)[6],=NL5L(3)[6],=NL7AH(3)[6],
=NL7AR(3)[6],=NL7AZ(3)[6],=NL7BI(3)[6],=NL7CH(3)[6],=NL7D(3)[6],=NL7D/7(3)[6],=NL7DH(3)[6],
=NL7DY(3)[6],=NL7EO(3)[6],=NL7FQ(3)[6],=NL7FX(3)[6],=NL7FY(3)[6],=NL7GM(3)[6],=NL7GN(3)[6],
=NL7GO(3)[6],=NL7GU(3)[6],=NL7GW(3)[6],=NL7HH(3)[6],=NL7HK(3)[6],=NL7HQ(3)[6],=NL7HU(3)[6],
=NL7IN(3)[6],=NL7JE(3)[6],=NL7JJ(3)[6],=NL7JN(3)[6],=NL7KV(3)[6],=NL7LI(3)[6],=NL7MS(3)[6],
=NL7MT(3)[6],=NL7NL(3)[6],=NL7OF(3)[6],=NL7PN(3)[6],=NL7QI(3)[6],=NL7RL(3)[6],=NL7RN(3)[6],
=NL7TK(3)[6],=NL7UE(3)[6],=NL7US(3)[6],=NL7VS(3)[6],=NL7WD(3)[6],=NL7WJ(3)[6],=NL7XX(3)[6],
=NL7ZM(3)[6],=NL7ZN(3)[6],=NL7ZP(3)[6],=NP2CT(3)[6],=NP2KL(3)[6],=NP2LK(3)[6],=NP2X/7(3)[6],
=NP3PH(3)[6],=NP4AI/M(3)[6],=NP4ES(3)[6],=NP4FP(3)[6],=NP4I(3)[6],=NP4JV(3)[6],=NP4JV/7(3)[6],
=VA2GLB/P(3)[6],=WH0AAM(3)[6],=WH0J(3)[6],=WH2ACV(3)[6],=WH2AJF(3)[6],=WH6ANB(3)[6],=WH6ARU(3)[6],
=WH6ASB(3)[6],=WH6B(3)[6],=WH6BDR(3)[6],=WH6BLM(3)[6],=WH6BPL(3)[6],=WH6BPU(3)[6],=WH6CF(3)[6],
=WH6CMS(3)[6],=WH6CN(3)[6],=WH6CUS(3)[6],=WH6CWD(3)[6],=WH6CXB(3)[6],=WH6CXE(3)[6],=WH6CXN(3)[6],
=WH6CYB(3)[6],=WH6CZ(3)[6],=WH6DAP(3)[6],=WH6DAY(3)[6],=WH6DJO(3)[6],=WH6DKC(3)[6],=WH6DKG(3)[6],
=WH6DKO(3)[6],=WH6DLQ(3)[6],=WH6DMS(3)[6],=WH6DQ(3)[6],=WH6DRP(3)[6],=WH6DST(3)[6],=WH6DTH(3)[6],
=WH6EEC(3)[6],=WH6EEG(3)[6],=WH6EGM(3)[6],=WH6EHW(3)[6],=WH6EJV(3)[6],=WH6EQB(3)[6],=WH6EQE(3)[6],
=WH6EQH(3)[6],=WH6ESS(3)[6],=WH6ETO(3)[6],=WH6EWE(3)[6],=WH6FCT(3)[6],=WH6FEU(3)[6],=WH6FJR(3)[6],
=WH6FL(3)[6],=WH6FOJ(3)[6],=WH6FPR(3)[6],=WH6FPV(3)[6],=WH6FQ(3)[6],=WH6FQK(3)[6],=WH6GCT(3)[6],
=WH6GEV(3)[6],=WH6OL(3)[6],=WH6OY(3)[6],=WH6QV(3)[6],=WH6SD(3)[6],=WH6SR(3)[6],=WH6TI(3)[6],
=WH6U(3)[6],=WH6XV(3)[6],=WH6YT(3)[6],=WH6YX(3)[6],=WH6ZR(3)[6],=WH6ZV(3)[6],=WH7A(3)[6],
=WH7CY(3)[6],=WH7DA(3)[6],=WH7DB(3)[6],=WH7DE(3)[6],=WH7G(3)[6],=WH7GC(3)[6],=WH7GY(3)[6],
=WH7HU(3)[6],=WH7LB(3)[6],=WH7NS(3)[6],=WH7OK(3)[6],=WH7P(3)[6],=WH7RG(3)[6],=WH7TC(3)[6],
=WH7TN(3)[6],=WH7TR(3)[6],=WH7U(3)[6],=WH7UP(3)[6],=WH7WP(3)[6],=WH7WT(3)[6],=WH7XP(3)[6],
=WH8AAG(3)[6],=WL7AAW(3)[6],=WL7AL(3)[6],=WL7AP(3)[6],=WL7AQ(3)[6],=WL7AUY(3)[6],=WL7AWD(3)[6],
=WL7AXI(3)[6],=WL7AZG(3)[6],=WL7AZL(3)[6],=WL7BCR(3)[6],=WL7BHR(3)[6],=WL7BLM(3)[6],=WL7BM(3)[6],
=WL7BNQ(3)[6],=WL7BON(3)[6],=WL7BOO(3)[6],=WL7BSW(3)[6],=WL7BUI(3)[6],=WL7BVN(3)[6],=WL7BVS(3)[6],
=WL7CAZ(3)[6],=WL7CBF(3)[6],=WL7CES(3)[6],=WL7COQ(3)[6],=WL7CPE(3)[6],=WL7CPI(3)[6],=WL7CQX(3)[6],
=WL7CRJ(3)[6],=WL7CSL(3)[6],=WL7CTB(3)[6],=WL7CTC(3)[6],=WL7CTE(3)[6],=WL7DD(3)[6],=WL7FA(3)[6],
=WL7FR(3)[6],=WL7FU(3)[6],=WL7H(3)[6],=WL7HE(3)[6],=WL7HK(3)[6],=WL7HL(3)[6],=WL7IQ(3)[6],
=WL7IS(3)[6],=WL7JG(3)[6],=WL7JM(3)[6],=WL7K(3)[6],=WL7K/7(3)[6],=WL7K/M(3)[6],=WL7LB(3)[6],
=WL7LK(3)[6],=WL7OA(3)[6],=WL7P(3)[6],=WL7PJ(3)[6],=WL7QC(3)[6],=WL7QX(3)[6],=WL7RV/140(3)[6],
=WL7SD(3)[6],=WL7SO(3)[6],=WL7SV(3)[6],=WL7T/P(3)[6],=WL7VK(3)[6],=WL7VV(3)[6],=WL7WB(3)[6],
=WL7WF(3)[6],=WL7WG(3)[6],=WL7WK(3)[6],=WL7WM(3)[6],=WL7WU(3)[6],=WL7XE(3)[6],=WL7XJ(3)[6],
=WL7XN(3)[6],=WL7XW(3)[6],=WL7Z(3)[6],=WL7ZM(3)[6],=WP2ADG(3)[6],=WP3ZO(3)[6],=WP4DYP(3)[6],
=WP4NBP(3)[6],
AA8(4)[8],AB8(4)[8],AC8(4)[8],AD8(4)[8],AE8(4)[8],AF8(4)[8],AG8(4)[8],AI8(4)[8],AJ8(4)[8],
AK8(4)[8],K8(4)[8],KA8(4)[8],KB8(4)[8],KC8(4)[8],KD8(4)[8],KE8(4)[8],KF8(4)[8],KG8(4)[8],
KI8(4)[8],KJ8(4)[8],KK8(4)[8],KM8(4)[8],KN8(4)[8],KO8(4)[8],KQ8(4)[8],KR8(4)[8],KS8(4)[8],
@ -1778,7 +1779,7 @@ Hawaii: 31: 61: OC: 21.12: 157.48: 10.0: KH6:
=WA6IIQ,=WA6JDA,=WA6JJQ,=WA6QDQ,=WA6UVF,=WA7ESE,=WA7HEO,=WA7TFE,=WA7WSU,=WA7ZK,=WA8HEB,=WA8JQP,
=WB0RUA,=WB0TZQ,=WB1HAL,=WB2AHM,=WB2SQW,=WB4JTT,=WB4MNF,=WB5ZDH,=WB5ZOV,=WB6CVJ,=WB6PIO,=WB6PJT,
=WB6SAA,=WB6VBM,=WB8NCD,=WB9SMM,=WD0FTF,=WD0LFN,=WD4MLF,=WD8LIB,=WD8OBO,=WH2Y,=WH7K,=WK1K,=WL7CSW,
=WL7CSW/H,=WV0Z,=WV6K,=WX0H,=WY6F;
=WL7CSW/H,=WL7M,=WV0Z,=WV6K,=WX0H,=WY6F;
Kure Island: 31: 61: OC: 29.00: 178.00: 10.0: KH7K:
AH7K,KH7K,NH7K,WH7K;
American Samoa: 32: 62: OC: -14.32: 170.78: 11.0: KH8:
@ -1792,9 +1793,9 @@ Alaska: 01: 01: NA: 61.40: 148.87: 8.0: KL:
=AC9QX,=AD0DK,=AD0FQ,=AD0ZL,=AD3BJ,=AD5PT,=AD6GC,=AD7MF,=AD7VV,=AE1DJ,=AE4QH,=AE5CP,=AE5EX,=AE5FN,
=AE5IR,=AE7ES,=AE7KS,=AE7SB,=AF7FV,=AG5LN,=AG5OF,=AH0AH,=AH0H,=AI7CF,=AJ4MY,=AJ4ZI,=AK0O,=AK4CM,
=K0AZZ,=K0BHC,=K0ESQ,=K1BZD,=K1IEE,=K1KAO,=K1LQ,=K1MAT,=K1TMT,=K2ICW,=K2NPS,=K3JMI,=K4DRC,=K4ETC,
=K4HOE,=K4PSG,=K4RND,=K4WGX,=K4WPK,=K5DOW,=K5HL,=K5RD,=K5RSO,=K5RZW,=K5TDN,=K6ANE,=K6GKW,=K7BUF,
=K7CAP,=K7EJM,=K7GRW,=K7LOP,=K7MVX,=K7OCL,=K7RDR,=K7UNX,=K7VRK,=K8IEL,=K8OUA,=K9DUG,=KA0SIM,
=KA0YPV,=KA1NCN,=KA2TJZ,=KA2ZSD,=KA6DBB,=KA6PJV,=KA6UGT,=KA7ETQ,=KA7HHF,=KA7HOX,=KA7JOR,=KA7PUB,
=K4HOE,=K4PSG,=K4RND,=K4WGX,=K4WPK,=K5DOW,=K5HL,=K5RD,=K5RSO,=K5RZW,=K5TDN,=K5VOR,=K6ANE,=K6GKW,
=K7BUF,=K7CAP,=K7EJM,=K7GRW,=K7LOP,=K7MVX,=K7OCL,=K7RDR,=K7UNX,=K7VRK,=K8IEL,=K8OUA,=K9DUG,
=KA0SIM,=KA0YPV,=KA1NCN,=KA2TJZ,=KA6DBB,=KA6PJV,=KA6UGT,=KA7ETQ,=KA7HHF,=KA7HOX,=KA7JOR,=KA7PUB,
=KA7TMU,=KA7TOM,=KA7UKN,=KA7VCR,=KA7YEY,=KA7ZSX,=KA9GYQ,=KB0APK,=KB0LOW,=KB0TSU,=KB0UGE,=KB0UVK,
=KB1CRT,=KB1FCX,=KB1IEV,=KB1KLH,=KB1PHP,=KB1QCD,=KB1QCE,=KB1SYV,=KB1WQL,=KB2FWF,=KB2JWV,=KB2ZME,
=KB3CYB,=KB3JFK,=KB3NCR,=KB3VQE,=KB4DX,=KB5DNT,=KB5HEV,=KB5NOW,=KB5UWU,=KB5YLG,=KB6DKJ,=KB7AMA,
@ -1837,18 +1838,18 @@ Alaska: 01: 01: NA: 61.40: 148.87: 8.0: KL:
=N8EX,=N8JKB,=N8KCJ,=N8KYW,=N8SUG,=N9AIG,=N9YD,=NA7WM,=NC2US,=NC4OI,=NE7EK,=NH2GZ,=NH2LS,=NH7UO,
=NM0H,=NN5H,=NP4FU,=NU9Q,=NW7F,=W0EZM,=W0FJN,=W0HPD,=W0OPT,=W0RWS,=W0UZJ,=W0ZEE,=W1JM,=W1LYD,
=W1RSC,=W1ZKA,=W2DLS,=W2KRZ,=W2LUV,=W3ICG,=W3JPN,=W3MKG,=W4AUL,=W4BMR,=W4RSB,=W5AIT,=W5JKT,=W5SPY,
=W6DDP,=W6GTE,=W6ROW,=W7DDG,=W7EGG,=W7EIK,=W7JMR,=W7PWA,=W7RAZ,=W7ROS,=W7WEZ,=W7ZWT,=W8MDD,=W8PVZ,
=W8TCX,=W9ITU,=W9JMC,=W9WLN,=WA0JS,=WA1FVJ,=WA1OUS,=WA2BGL,=WA2BIW,=WA4RRE,=WA6GFS,=WA7B,=WA7MDS,
=WA7PXH,=WA7USX,=WA7YXF,=WB0CMZ,=WB1GZL,=WB1ILS,=WB6COP,=WB7ULO,=WB8BRU,=WB9JZL,=WD6CET,=WE3B,
=WH6CYY,=WH6DPL,=WH6GBB,=WH6GCO,=WH7AK,=WI5GUY,=WJ6AA,=WJ8M,=WT5T,=WW4AL,=WX1NCC;
=W6DDP,=W6GTE,=W6ROW,=W6SMA,=W7DDG,=W7EGG,=W7EIK,=W7JMR,=W7PWA,=W7RAZ,=W7ROS,=W7WEZ,=W7ZWT,=W8MDD,
=W8PVZ,=W8TCX,=W9ITU,=W9JMC,=W9WLN,=WA0JS,=WA1FVJ,=WA1OUS,=WA2BGL,=WA2BIW,=WA4RRE,=WA6GFS,=WA7B,
=WA7MDS,=WA7PXH,=WA7USX,=WA7YXF,=WB0CMZ,=WB1GZL,=WB1ILS,=WB6COP,=WB7ULO,=WB8BRU,=WB9JZL,=WD6CET,
=WE3B,=WH6CYY,=WH6DPL,=WH6GBB,=WH6GCO,=WH7AK,=WI5GUY,=WJ6AA,=WJ8M,=WT5T,=WW4AL,=WX1NCC;
Navassa Island: 08: 11: NA: 18.40: 75.00: 5.0: KP1:
KP1,NP1,WP1;
US Virgin Islands: 08: 11: NA: 17.73: 64.80: 4.0: KP2:
KP2,NP2,WP2,=AC7FX,=AJ2O,=K5KFL,=K5KUB,=K5TP,=K8RF,=K9VV,=KA7KDU,=KB1MDZ,=KB1ZTY,=KB3ZUD,=KB9ALR,
=KC9MCN,=KD4SGB,=KD5QJN,=KE3QL,=KF2HC,=KF4CGR,=KF4MSI,=KG4CZD,=KG4SZC,=KG5KHO,=KG6KVR,=KH2XQ,
=KH2XR,=KI4FOE,=KI4FZD,=KI6BLD,=KJ6IR,=KL7NZ,=KO4ALI,=KR7O/R,=KV4/W2KW,=KV4AD,=KV4BA,=KV4BT,
=KV4BW,=KV4CF,=KV4CQ/P,=KV4DN,=KV4EY,=KV4FZ,=KV4HR,=KV4IH,=KV4JC,=KV4KW,=N1TKK,=N1VKI,=N4QXL,
=W0AIH/KV4,=W0YNY,=W2AZK,=W2KW/KV4,=W3K/KD2CLB,=W4LIS,=WA4HLB,=WB2KQW,=WB4WFU,=WD8AHQ;
=KV4BW,=KV4CF,=KV4CQ/P,=KV4EY,=KV4FZ,=KV4HR,=KV4IH,=KV4JC,=KV4KW,=N1TKK,=N1VKI,=N4QXL,=W0AIH/KV4,
=W0YNY,=W2AZK,=W2KW/KV4,=W3K/KD2CLB,=W4LIS,=WA4HLB,=WB2KQW,=WB4WFU,=WD8AHQ;
Puerto Rico: 08: 11: NA: 18.18: 66.55: 4.0: KP4:
KP3,KP4,NP3,NP4,WP3,WP4,=AA2ZN,=AB2DR,=AF4OU,=AF5IZ,=AG4CD,=AI4EZ,=K1NDN,=K4C/LH,=K4LCR,=K4PFH,
=K5YJR,=K6BOT,=K9JOS,=KA2ABJ,=KA2GNG,=KA2MBR,=KA2UCX,=KA2YGB,=KA3ZGQ,=KA4ROB,=KA7URH,=KA9UTY,
@ -2431,7 +2432,7 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA:
=R90DOSAAF,=R9AV/6,=R9FCH/6,=R9HV/6,=R9JBF/1,=R9JBH/7,=R9JI/1,=R9KC/6/M,=R9WR/1,=R9XAU/6,=RA0AM/6,
=RA0BM/6,=RA0ZZ/3,=RA3CQ/9/M(17)[20],=RA80SP,=RA9JR/3,=RA9JX/3,=RA9P/4,=RA9RT/3,=RA9UEZ/6,
=RA9UUY/6,=RA9YA/6,=RC80SP,=RG0F/5,=RG50P(17),=RG50P/9(17)[30],=RJ80SP,=RK0HWW/1,=RK80X(17)[19],
=RK8O/4,=RL9AA/6,=RM80SP,=RM8A/4/M,=RM94AE,=RN9M/4,=RN9OI/3,=RO6C/8(17),=RO80RO,=RP61XX(17)[19],
=RK8O/4,=RL9AA/6,=RM80SP,=RM8A/4/M,=RM94AE,=RN9M/4,=RN9OI/3,=RO80RO,=RP61XX(17)[19],
=RP62X(17)[19],=RP63X(17)[19],=RP63XO(17)[19],=RP64X(17)[19],=RP65FPP(17)[30],=RP8X(17)[30],
=RQ80SP,=RT9T/3,=RU0ZW/6,=RU2FB/3,=RU2FB/3/P,=RU4SS/9(17)[30],=RU4WA/9(17)[30],=RU9MU/3,=RV9LM/3,
=RV9XX/3,=RW0IM/1,=RW0QE/6,=RW2F/6,=RW9FF/3,=RW9W/3,=RW9W/4,=RX2FS/3,=RX9TC/1,=RX9UL/1,=RZ9AWN/6,
@ -2444,8 +2445,8 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA:
=UA9B/1,=UA9KG/1,=UA9KGH/1,=UA9KK/1,=UA9UDX/1,=UB9YUW/1,=UE21A,=UE21B,=UE21M,=UE22A,=UE25AC,
=UE25AQ,=UE2AT/1,
=R0XAC/1,=R1CF/M,=R8FF/1,=R8XF/1,=R8XF/M,=R90LPU,=R9JNO/1,=RA0FU/1,=RA9FNV/1,=RN2FA/1,=RN9N/1,
=RU9MU/1,=RV0CA/1,=RV1CC/1,=RV2FW/1,=RV9JD/1,=RX9TN/1,=UA0BDS/1,=UA0SIK/1,=UA1CDA/LH,=UA1CIO/LH,
=UA9MA/1,=UA9MQR/1,=UB5O/1/M,
=RU9MU/1,=RV0CA/1,=RV1CC/1,=RV1CC/M,=RV2FW/1,=RV9JD/1,=RX9TN/1,=UA0BDS/1,=UA0SIK/1,=UA1CDA/LH,
=UA1CIO/LH,=UA9MA/1,=UA9MQR/1,=UB5O/1/M,
R1N[19],RA1N[19],RC1N[19],RD1N[19],RE1N[19],RF1N[19],RG1N[19],RJ1N[19],RK1N[19],RL1N[19],RM1N[19],
RN1N[19],RO1N[19],RQ1N[19],RT1N[19],RU1N[19],RV1N[19],RW1N[19],RX1N[19],RY1N[19],RZ1N[19],U1N[19],
UA1N[19],UB1N[19],UC1N[19],UD1N[19],UE1N[19],UF1N[19],UG1N[19],UH1N[19],UI1N[19],=R01DTV/1[19],
@ -2477,9 +2478,9 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA:
=R01DTV/3,=R85PAR,=R870B,=R870C,=R870K,=R870M,=R870O,=R9FM/3,=RA2AT,=RA2FDX/3,=RA3AL/M,=RA9CO/3,
=RA9USU/3,=RC85MP,=RL3AB/FF,=RT2F/3/M,=RT9K/3,=RW0LF/3,=RX9UL/3,=RX9WN/3,=RZ9UA/3,=UA0KCX/3,
=UA3AV/ANT,=UA8AA/3,=UA8AA/5,=UA9KHD/3,=UA9MA/3,=UA9MDU/3,=UA9MRX/3,=UA9QCP/3,=UA9UAX/3,=UE24SU,
=R85AAL,=R85QMR,=R85WDW,=R8B,=R8FF/3,=R90DNF,=R90PAR,=R90WDW,=R99FSB,=R9YU/3,=RA0BY/3,=RA80KEDR,
=RA9KV/3,=RA9SB/3,=RA9XY/3,=RD0L/3,=RK3DSW/ANT,=RK3DWA/3/N,=RN9MD/3,=RT80KEDR,=RU0LM/3,=RU2FA/3,
=RU3HD/ANT,=RV0AO/3,=RV1CC/M,=RV9LM/3/P,=RW0IM/3,=RW3DU/N,=RW9UEW/3,=RX9SN/3,=RZ9OL/3/M,
=R18JPN,=R85AAL,=R85QMR,=R85WDW,=R8B,=R8FF/3,=R90DNF,=R90PAR,=R90WDW,=R99FSB,=R9YU/3,=RA0BY/3,
=RA80KEDR,=RA9KV/3,=RA9SB/3,=RA9XY/3,=RD0L/3,=RK3DSW/ANT,=RK3DWA/3/N,=RN9MD/3,=RT80KEDR,=RU0LM/3,
=RU2FA/3,=RU3HD/ANT,=RV0AO/3,=RV9LM/3/P,=RW0IM/3,=RW3DU/N,=RW9UEW/3,=RX9SN/3,=RZ9OL/3/M,
=RZ9OL/3/P,=RZ9SZ/3,=RZ9W/3,=UA0JAD/3,=UA0KCL/3,=UA0ZAZ/3,=UA9AJ/3/M,=UA9DD/3,=UA9HSI/3,=UA9ONJ/3,
=UA9XGD/3,=UA9XMC/3,=UE23DSA,=UE25FO,=UE95GA,=UE96WS,
=R80ORL,=UA0QGM/3,=UE80O,=UE80OL,
@ -2489,9 +2490,8 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA:
=RZ90W/3,=UA3LMR/P,=UA9JFM/3,=UA9XZ/3,=UE80G,=UE80V,=UE80YG,
=R800AN,=R800RAN,=RK3MXT/FF,=RV9AZ/3,=UA0AD/3,
=R870T,=RT90PK,=RU0ZW/3,=RW0UM/3,=RW9JV/3,
=R0AI/M,=R0AIB/3,=R89AFG,=RA0CCV/3,=RA0QA/3,=RC9YA/3/P,=RM8X/3,=RU9SO/M,=RV9LC/3,=UA0QJE/3,
=UA0QQO/3,=UA9CGL/3,=UA9JLY/3,=UA9XLE/3,=UB0AJJ/3,=UC0LAF/3,=UE25AFG,=UE25R,=UE27AFG,=UE28AFG,
=UE96SN,
=R0AI/M,=R0AIB/3,=R89AFG,=RA0CCV/3,=RA0QA/3,=RC9YA/3/P,=RM8X/3,=RV9LC/3,=UA0QJE/3,=UA0QQO/3,
=UA9CGL/3,=UA9JLY/3,=UA9XLE/3,=UB0AJJ/3,=UC0LAF/3,=UE25AFG,=UE25R,=UE27AFG,=UE28AFG,=UE96SN,
=R80RTL,=R90IARU,=R9CZ/3,=RU80TO,=RZ9HK/3/P,
=R920RZ,=R925RZ,=R95DOD,=RA0QQ/3,=UA0KBA/3,=UE80S,=UE85NKN,=UE85WDW,
=R3TT/FF,=R800ANG,=R8TA/4/P,=R8TR/3,=R90NOR,=R9KW/3,=R9KW/4,=R9PA/4,=RA95FL,=RA9AP/3,=RA9CKQ/4,
@ -2503,8 +2503,8 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA:
=R110A/P,=R80PVB,=RK3AW/M,
=R8XF/3,=RA9XF/3,=RC80KEDR,=RK0BWW/3,=RN80KEDR,=RW9XC/3/M,=RX3XX/N,=UA0KBA/3/P,=UA9SIV/3,
=UE0ZOO/3,
=R85WTA,=R8FF/3/P,=R90WDWR,=R98KPM,=R99KPM,=RA3YV/ANT,=RK0UT/3,=RW0LX/3,=UA3YH/ANT,=UA9KZ/3,
=UB8JAF/3,=UE91L,=UE95K,=UE95RA,
=R85WTA,=R8FF/3/P,=R90WDWR,=R90WTA,=R98KPM,=R99KPM,=RA3YV/ANT,=RK0UT/3,=RW0LX/3,=UA3YH/ANT,
=UA9KZ/3,=UB8JAF/3,=UE91L,=UE95K,=UE95RA,
=R3ZK/FF,=RA3ZZ/ANT,=RA9AK/3,=RA9KD/3,=RU3ZK/FF,=RW0BG/3,=UA0QBC/3,
=R89DRA,=RA07DR,=RA9DF/4/P,=RA9ODR/4/M,=RC4AF/FF,=RN4ACA/FF,=RV9CX/6/M,=UA4ASE/FF,=UA4ATL/FF,
=UA8WAA/6,=UA9FGR/4,=UE00S,=UE00S/P,=UE09VG,=UE80RWW,
@ -2544,23 +2544,23 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA:
UA4W[30],UB4W[30],UC4W[30],UD4W[30],UE4W[30],UF4W[30],UG4W[30],UH4W[30],UI4W[30],=R0CM/4[30],
=R100MTK[30],=R100UD[30],=R9GM/4[30],=R9UT/4[30],=RA9FDR/4/P[30],=RA9KV/4/M[30],=RA9WU/4[30],
=RA9WU/4/M[30],=RA9WU/4/P[30],=RP72IZ[30],=RP73IZ[30],=RP74IZ[30],=RP75IZ[30],=RP76IZ[30],
=RT20NY[30],=RT21NY[30],=RT30DX[30],=RT60YG[30],=RT78ML[30],=RW9FWB/4[30],=RW9FWR/4[30],
=RW9FWR/4/M[30],=RX9FW/4[30],=UA9UAX/4/M[30],
=RT20NY[30],=RT21NY[30],=RT30DX[30],=RT36MS[30],=RT60YG[30],=RT78ML[30],=RW9FWB/4[30],
=RW9FWR/4[30],=RW9FWR/4/M[30],=RX9FW/4[30],=UA9UAX/4/M[30],
=RT9T/4,=RV9MD/4,=UA4PCM/M,=UE04YCS,=UE85AGN,=UE90AGN,
=R01DTV,=R01DTV/7,=R0IT/6,=R80TV,=R8XW/6,=R9JO/6,=R9KD/6,=R9OM/6,=R9WGM/6/M,=RA0APW/6,=RA0FW/6,
=RA0LIF/6,=RA0LLW/6,=RA0QR/6,=RA9ODR/6,=RA9ODR/6/M,=RA9SAS/6,=RA9UWD/6,=RA9WW/6,=RD9CX/6,
=R01DTV,=R01DTV/7,=R0IT/6,=R7AB/M,=R80TV,=R8XW/6,=R9JO/6,=R9KD/6,=R9OM/6,=R9WGM/6/M,=RA0APW/6,
=RA0FW/6,=RA0LIF/6,=RA0LLW/6,=RA0QR/6,=RA9ODR/6,=RA9ODR/6/M,=RA9SAS/6,=RA9UWD/6,=RA9WW/6,=RD9CX/6,
=RD9CX/6/P,=RK6AH/LH,=RK75KH,=RK75MP,=RK9JA/6,=RM8W/6,=RN0CF/6,=RN0JT/6,=RQ0C/6,=RT9K/6,=RT9K/6/P,
=RT9K/6/QRP,=RU2FB/6,=RU9MX/6,=RU9QRP/6/M,=RU9QRP/6/P,=RU9SO/6,=RV9FQ/6,=RW0LIF/6,=RW0LIF/6/LH,
=RW6AWW/LH,=RW9JZ/6,=RW9WA/6,=RX6AA/ANT,=RX6AAP/ANT,=RX9TX/6,=RZ9HG/6,=RZ9HT/6,=RZ9UF/6,=RZ9UZV/6,
=UA0AGE/6,=UA0IT/6,=UA0JL/6,=UA0LQQ/6/P,=UA0SEP/6,=UA2FT/6,=UA6ADC/N,=UA9COO/6,=UA9CTT/6,
=UA9JON/6,=UA9JPX/6,=UA9KB/6,=UA9KJ/6,=UA9KW/6,=UA9MQR/6,=UA9UAX/6,=UA9VR/6,=UA9XC/6,=UA9XCI/6,
=UE9WDA/6,=UE9WFF/6,=UF0W/6,
=RT9K/6/QRP,=RU2FB/6,=RU9MX/6,=RU9QRP/6/M,=RU9QRP/6/P,=RU9SO/6,=RU9SO/M,=RV9FQ/6,=RW0LIF/6,
=RW0LIF/6/LH,=RW6AWW/LH,=RW9JZ/6,=RW9WA/6,=RX6AA/ANT,=RX6AAP/ANT,=RX9TX/6,=RZ9HG/6,=RZ9HT/6,
=RZ9UF/6,=RZ9UZV/6,=UA0AGE/6,=UA0IT/6,=UA0JL/6,=UA0LQQ/6/P,=UA0SEP/6,=UA2FT/6,=UA6ADC/N,=UA9COO/6,
=UA9CTT/6,=UA9JON/6,=UA9JPX/6,=UA9KB/6,=UA9KJ/6,=UA9KW/6,=UA9MQR/6,=UA9UAX/6,=UA9VR/6,=UA9XC/6,
=UA9XCI/6,=UE9WDA/6,=UE9WFF/6,=UF0W/6,
=RA6EE/FF,=RN7G/FF,=UA0LEC/6,=UA9KAS/6,=UA9KAS/6/P,
=R7AB/M,=R7AB/P,=R9XV/6,=RA0ZG/6,=RA9CHS/6,=RA9CHS/7,=RK7G/FF,=RT9K/7,=RU9CK/7,=RU9ZA/7,=RZ7G/FF,
=RZ9ON/6,=UA0ZDA/6,=UA0ZS/6,=UA6HBO/N,=UA6HBO/ST30,=UA6IC/6/FF,=UA9CE/6,=UA9UAX/7/M,=UE80HS,
=R9XV/6,=RA0ZG/6,=RA9CHS/6,=RA9CHS/7,=RK7G/FF,=RT9K/7,=RU9CK/7,=RU9ZA/7,=RZ7G/FF,=RZ9ON/6,
=UA0ZDA/6,=UA0ZS/6,=UA6HBO/N,=UA6HBO/ST30,=UA6IC/6/FF,=UA9CE/6,=UA9UAX/7/M,=UE80HS,
=RM8A/6/M,=UA6IC/FF,
=RU2FB/6/P,=UA9UAX/7,
=R6LCA/J,=R8WC/6,=R8WC/6/P,=RA20NY,=RA21NY,=RA98AE,=RU97AE,=RV9CMT/6,=RV9DC/6/P,=RV9LC/6,
=R6LCA/J,=R7AB/P,=R8WC/6,=R8WC/6/P,=RA20NY,=RA21NY,=RA98AE,=RU97AE,=RV9CMT/6,=RV9DC/6/P,=RV9LC/6,
=RW9XC/6/M,=RX9KT/6,=UA0QBR/6,=UA0ZED/6,=UA6LP/P/LH,=UA6LV/ANT,=UA6MM/LH,=UE20DS,=UE28DX,=UE29DX,
=UE92L,
=RV0ANH/6,=RV0APR/6,=RW0AF/6,
@ -2641,7 +2641,7 @@ Kaliningrad: 15: 29: EU: 54.72: -20.52: -3.0: UA2:
=RP75GC,=RP75IGS,=RP75KB,=RP75MW,=RP75STP,=RP76GC,=RP76IGS,=RP76KB,=RT9T/2,=RU3FS/2,=RU5A/2,
=RU5D/2,=RV21NY,=RV30DX,=RV3FF/2,=RV3MA/2,=RV3UK/2,=RV60YG,=RV9WZ/2,=RW9QA/2,=RY1AAA/2,=RZ3FA/2,
=RZ6HB/2,=UA0SIK/2,=UA1AAE/2,=UA1AFT/2,=UA2DC/RP,=UA2FM/MM(13),=UA3DJG/2,=UA4RC/2,=UA4WHX/2,
=UA9UAX/2,=UB5O/2,=UB5O/2/M,=UB9KAA/2,=UE08F,=UE1RLH/2,=UE3QRP/2,=UE6MAC/2,=UF1M/2;
=UA9UAX/2,=UB5O/2,=UB5O/2/M,=UB9KAA/2,=UE08F,=UE1RLH/2,=UE3QRP/2,=UE6MAC/2,=UE90WTA,=UF1M/2;
Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9:
R0(19)[33],R8,R9,RA0(19)[33],RA8,RA9,RC0(19)[33],RC8,RC9,RD0(19)[33],RD8,RD9,RE0(19)[33],RE8,RE9,
RF0(19)[33],RF8,RF9,RG0(19)[33],RG8,RG9,RI0(19)[33],RI8,RI9,RJ0(19)[33],RJ8,RJ9,RK0(19)[33],RK8,
@ -2665,10 +2665,10 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9:
=RP76U,=RQ4D/8,=RT60RT,=RT73AB,=RU22AZ,=RV1AQ/9,=RV1CC/8,=RV1CC/9,=RV3BA/9,=RV9WB/9/M,=RV9WMZ/9/P,
=RV9WMZ/P,=RX3RC/9,=RX9WN/9/M,=RX9WT/8,=RZ0OO/9,=RZ6DR/9/M,=RZ9OO/9/M,=UA0MF/9,=UA3AKO/8,=UA4RC/9,
=UA6A/9,=UA6CW/9,=UA6YGY/8,=UA6YGY/9,=UA8WAA/9,=UA8WAA/9/P,=UA8WAA/M,=UA9SG/9,=UA9TO/9/M,
=UA9WMN/9/P,=UE45AWT,=UE70AAA,=UE9WDA/9,
=R01DTV/8,=R100RGA,=R105WWS,=R14CWC/8,=R14CWC/9,=R150DMP,=R155AP,=R15CWC/8,=R15CWC/8/QRP,=R160DMP,
=R16SVK,=R170GS/8,=R2015BP,=R2015R,=R2016DR,=R20EKB,=R22SKJ,=R27EKB,=R30ZF,=R35CZF,=R375I,
=R44YETI/8,=R4WAB/9/P,=R55EPC,=R55EPC/P,=R6UAE/9,=R70NIK,=R7LZ/8,=R8FF/8,=R9GM/8,=R9GM/8/M,
=UA9WMN/9/P,=UB5O/8,=UE45AWT,=UE70AAA,=UE9WDA/9,
=R01DTV/8,=R100RGA,=R103PS,=R105WWS,=R14CWC/8,=R14CWC/9,=R150DMP,=R155AP,=R15CWC/8,=R15CWC/8/QRP,
=R160DMP,=R16SVK,=R170GS/8,=R2015BP,=R2015R,=R2016DR,=R20EKB,=R22SKJ,=R27EKB,=R30ZF,=R35CZF,
=R375I,=R44YETI/8,=R4WAB/9/P,=R55EPC,=R55EPC/P,=R6UAE/9,=R70NIK,=R7LZ/8,=R8FF/8,=R9GM/8,=R9GM/8/M,
=R9WCJ/8,=RA/DL6XK,=RA/US5ETV,=RA0BA/8,=RA0BA/9,=RA27AA,=RA27EK,=RA36GS,=RA36ZF,=RA4YW/9,
=RA4YW/9/M,=RA9FW/9,=RC18EK,=RD0B/8,=RK3AW/8,=RK9AD/9/M,=RK9DR/N,=RL20NY,=RL21NY,=RL4R/8,=RL60YG,
=RM0B/9,=RM19NY,=RN16CW,=RN3QBG/9,=RP68DT,=RP68RG,=RP68TG,=RP68TK,=RP69GR,=RP70DT,=RP70G,=RP70GB,
@ -2679,7 +2679,7 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9:
=RT73HE,=RT73KB,=RT73SK,=RU22CR,=RU5D/8,=RU5D/9,=RU9CK/M,=RV6LGY/9,=RV6LGY/9/M,=RV6LGY/9/P,
=RV6MD/9,=RV9WB/8,=RW4NX/9,=RW9C[20],=RX0SD/9,=RX3Q/8,=RX3Q/9,=RX9UL/9,=RY9C/P,=RZ1CWC/8,=RZ37ZF,
=RZ38ZF,=RZ39ZF,=UA0BA/8,=UA3FQ/8,=UA3IHJ/8,=UA4WHX/9,=UA8WAA/8,=UA9CGL/M,=UA9MW/9,=UA9UAX/8,
=UA9UAX/8/M,=UB5O/8,=UE16SR,=UE25F,=UE40CZF,=UE4NFF/9,=UE56S,=UE64RWA,=UE70SL,=UE75DT,
=UA9UAX/8/M,=UE16SR,=UE25F,=UE40CZF,=UE4NFF/9,=UE56S,=UE64RWA,=UE70SL,=UE75DT,
R8H(18)[31],R8I(18)[31],R9H(18)[31],R9I(18)[31],RA8H(18)[31],RA8I(18)[31],RA9H(18)[31],
RA9I(18)[31],RC8H(18)[31],RC8I(18)[31],RC9H(18)[31],RC9I(18)[31],RD8H(18)[31],RD8I(18)[31],
RD9H(18)[31],RD9I(18)[31],RE8H(18)[31],RE8I(18)[31],RE9H(18)[31],RE9I(18)[31],RF8H(18)[31],
@ -2734,19 +2734,19 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9:
=RW4HIF/9[20],=RW4HIH/9[20],=RW6BA/9[20],=RW9XU/9[20],=RX6CP/8[20],=RX6LMA/9[20],=RX9SN/8[20],
=UA0KY/9[20],=UA0QMU/0[20],=UA0QQO/9/P[20],=UA1FBP/9[20],=UA1PBA/9[20],=UA1PBP/9[20],
=UA3DFM/8[20],=UA3DFM/9[20],=UA3MGA/9[20],=UA6BTN/9[20],=UA9SUV/8[20],
=R110WG,=R115AN,=R11QRP/8,=R11QRP/8/P,=R120RL,=R18POR,=R1PN/8,=R2015EP,=R2015LY,=R2015LY/8,
=R22BIA,=R30STM,=R430LT,=R4FAA/8,=R8MC/9,=R8MD/9,=RA/EW8ADX,=RA0UAC/8,=RA0UF/8,=RA3CW/9,=RA9JG/9,
=RC1M/8/M,=RO25TN,=RP67JH,=RP67LK,=RP67LL,=RP67TT,=RP68LS,=RP68TT,=RP69CM,=RP69DK,=RP69GP,=RP69LK,
=RP69LL,=RP69LS,=RP69MM,=RP69P,=RP69YN,=RP70GP,=RP70LL,=RP70LM,=RP70P,=RP70TM,=RP71GP,=RP71LL,
=RP71P,=RP72GP,=RP72LL,=RP72P,=RP72PJ,=RP73LL,=RP73P,=RP74LL,=RP74P,=RP75GP,=RP75LL,=RP75P,
=RP75YN,=RP76P,=RR110RAEM,=RU22LR,=RW0QJ/9,=RX4W/8,=RX6DL/8,=RX6DL/8/P,=RX6DL/8/P/QRP,=RX6DL/9/P,
=RZ9MXM/9/M,=UB5O/8/P,=UE44Y/8,=UE9FDA/9/M,=UE9MDA/9,
R18J,=R110WG,=R115AN,=R11QRP/8,=R11QRP/8/P,=R120RL,=R18POR,=R18UGRA,=R1PN/8,=R2015EP,=R2015LY,
=R2015LY/8,=R22BIA,=R30STM,=R430LT,=R4FAA/8,=R8MC/9,=R8MD/9,=RA/EW8ADX,=RA0UAC/8,=RA0UF/8,
=RA3CW/9,=RA9JG/9,=RC1M/8/M,=RO25TN,=RO6C/8,=RO6C/8/P,=RP67JH,=RP67LK,=RP67LL,=RP67TT,=RP68LS,
=RP68TT,=RP69CM,=RP69DK,=RP69GP,=RP69LK,=RP69LL,=RP69LS,=RP69MM,=RP69P,=RP69YN,=RP70GP,=RP70LL,
=RP70LM,=RP70P,=RP70TM,=RP71GP,=RP71LL,=RP71P,=RP72GP,=RP72LL,=RP72P,=RP72PJ,=RP73LL,=RP73P,
=RP74LL,=RP74P,=RP75GP,=RP75LL,=RP75P,=RP75YN,=RP76P,=RR110RAEM,=RU22LR,=RW0QJ/9,=RX4W/8,=RX6DL/8,
=RX6DL/8/P,=RX6DL/8/P/QRP,=RX6DL/9/P,=RZ9MXM/9/M,=UB5O/8/P,=UE44Y/8,=UE9FDA/9/M,=UE9MDA/9,
=R16CAN,=R1716K,=R1716M,=R1716O,=R1716S,=R21HNY,=R30MDXC,=R9MJ/M,=RA/DK2AI/M,=RA22MX,=RA4CQ/9/M,
=RA9MR/0,=RA9MX/P,=RC20MX,=RG78ML,=RK6YYA/9,=RN0SZ/9,=RN9N/9,=RN9N/M,=RP65MOH,=RP67MC,=RP67MD,
=RP68MC,=RP68MD,=RP69MC,=RP69MD,=RP70GK,=RP70MC,=RP70MD,=RP70OB,=RP70OF,=RP70OS,=RP71GK,=RP71MJ,
=RP71OB,=RP72GK,=RP72MJ,=RP72OB,=RP72ZW,=RP73GK,=RP73OB,=RP74PO,=RP75GK,=RP8M,=RT22MC,=RT22MD,
=RU20NY,=RU20RU,=RV0SR/9,=RW22MW,=RY22MC,=RZ5D/9,=UA1ZGD/9,=UA3AKO/9,=UA9UAX/M,=UB5O/9,=UE55OM,
=UE70KRM/9,=UE70KRM/9/M,=UE9OFF/9,
=RU20NY,=RU20RU,=RV0SR/9,=RW22MW,=RY22MC,=RZ5D/9,=UA1ZGD/9,=UA3AKO/9,=UA9MA/M,=UA9UAX/M,=UB5O/9,
=UE55OM,=UE70KRM/9,=UE70KRM/9/M,=UE9OFF/9,
R8O(18)[31],R8P(18)[31],R9O(18)[31],R9P(18)[31],RA8O(18)[31],RA8P(18)[31],RA9O(18)[31],
RA9P(18)[31],RC8O(18)[31],RC8P(18)[31],RC9O(18)[31],RC9P(18)[31],RD8O(18)[31],RD8P(18)[31],
RD9O(18)[31],RD9P(18)[31],RE8O(18)[31],RE8P(18)[31],RE9O(18)[31],RE9P(18)[31],RF8O(18)[31],
@ -2829,7 +2829,7 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9:
=RP70ZF(18)[31],=RP71KM(18)[31],=RP72KM(18)[31],=RP72NM(18)[31],=RP73KM(18)[31],=RP73NZ(18)[31],
=RP73ZF(18)[31],=RP74KM(18)[31],=RP75KM(18)[31],=RP75YE(18)[31],=RP76KM(18)[31],=RP76KUF(18)[31],
=RT22UA(18)[31],=RT77VV(18)[31],=RW0CE/9(18)[31],=RW4CG/9(18)[31],=UA9JFE/9/P(18)[31],
=UA9MA/M(18)[31],=UE3ATV/9(18)[31],
=UE3ATV/9(18)[31],
R8W(16),R9W(16),RA8W(16),RA9W(16),RC8W(16),RC9W(16),RD8W(16),RD9W(16),RE8W(16),RE9W(16),RF8W(16),
RF9W(16),RG8W(16),RG9W(16),RJ8W(16),RJ9W(16),RK8W(16),RK9W(16),RL8W(16),RL9W(16),RM8W(16),
RM9W(16),RN8W(16),RN9W(16),RO8W(16),RO9W(16),RQ8W(16),RQ9W(16),RT8W(16),RT9W(16),RU8W(16),
@ -3141,7 +3141,7 @@ Marshall Islands: 31: 65: OC: 9.08: -167.33: -12.0: V7:
Brunei Darussalam: 28: 54: OC: 4.50: -114.60: -8.0: V8:
V8;
Canada: 05: 09: NA: 44.35: 78.75: 5.0: VE:
CF,CG,CJ,CK,VA,VB,VC,VE,VG,VX,VY9,XL,XM,=VE2EM/M,=VER20210517,
CF,CG,CJ,CK,VA,VB,VC,VE,VG,VX,VY9,XL,XM,=VE2EM/M,=VER20210526,
=CF7AAW/1,=CK7IG/1,=VA3QSL/1,=VA3WR/1,=VE1REC/LH,=VE1REC/M/LH,=VE3RSA/1,=VE7IG/1,
CF2[4],CG2[4],CJ2[4],CK2[4],VA2[4],VB2[4],VC2[4],VE2[4],VG2[4],VX2[4],XL2[4],XM2[4],=4Y1CAO[4],
=CY2ZT/2[4],=VA3MPM/2[4],=VA7AQ/P[4],=VE2/G3ZAY/P[4],=VE2/M0BLF/P[4],=VE2FK[9],=VE2HAY/P[4],
@ -3272,7 +3272,7 @@ South Sandwich Islands: 13: 73: SA: -58.43: 26.33: 2.0: VP8/s:
Bermuda: 05: 11: NA: 32.32: 64.73: 4.0: VP9:
VP9,=VP400BO,=VP9400/HW;
Chagos Islands: 39: 41: AF: -7.32: -72.42: -6.0: VQ9:
VQ9;
VQ9,=VERSION;
Hong Kong: 24: 44: AS: 22.28: -114.18: -8.0: VR:
VR;
India: 22: 41: AS: 22.50: -77.58: -5.5: VU:
@ -3386,7 +3386,7 @@ New Zealand: 32: 60: OC: -39.03: -174.47: -12.0: ZL:
Chatham Islands: 32: 60: OC: -43.85: 176.48: -12.75: ZL7:
ZL7,ZM7;
Kermadec Islands: 32: 60: OC: -29.25: 177.92: -12.0: ZL8:
ZL8,ZM8,=VERSION,=ZL1GO/8;
ZL8,ZM8,=ZL1GO/8;
N.Z. Subantarctic Is.: 32: 60: OC: -51.62: -167.62: -12.0: ZL9:
ZL9;
Paraguay: 11: 14: SA: -25.27: 57.67: 4.0: ZP:

View File

@ -1,34 +1,34 @@
Here are the "displayWidgets()" strings for WSJT-X modes
1 2 3
0123456789012345678901234567890123456
------------------------------------------------
JT4 1110100000001100001100000000000000000
JT4/VHF 1111100100101101101111000000000000000
JT9 1110100000001110000100000000000010000
JT9/VHF 1111101010001111100100000000000000000
JT9+JT65 1110100000011110000100000000000010000
JT65 1110100000001110000100000000000010000
JT65/VHF 1111100100001101101011000100000000000
Q65 1111110101101101001110000001000000001
ISCAT 1001110000000001100000000000000000000
MSK144 1011111101000000000100010000000000000
WSPR 0000000000000000010100000000000000000
FST4 1111110001001110000100000001000000110
FST4W 0000000000000000010100000000000001000
Echo 0000000000000000000000100000000000000
FCal 0011010000000000000000000000010000000
FT8 1110100001001110000100001001100010000
FT8/VHF 1110100001001110000100001001100010000
FT8/Fox 1110100001001110000100000000001000000
FT8/Hound 1110100001001110000100000000001100000
----------------------------------------------
01234567890123456789012345678901234567
-------------------------------------------------
JT4 11101000000011000011000000000000000000
JT4/VHF 11111001001011011011110000000000000000
JT9 11101000000011100001000000000000100000
JT9/VHF 11111010100011111001000000000000000000
JT9+JT65 11101000000111100001000000000000100000
JT65 11101000000011100001000000000000100000
JT65/VHF 11111001000011011010110001000000000000
Q65 11111101011011010011100000010000000011
ISCAT 10011100000000011000000000000000000000
MSK144 10111111010000000001000100000000000000
WSPR 00000000000000000101000000000000000000
FST4 11111100010011100001000000010000001100
FST4W 00000000000000000101000000000000010000
Echo 00000000000000000000001000000000000000
FCal 00110100000000000000000000000100000000
FT8 11101000010011100001000010011000100000
FT8/VHF 11101000010011100001000010011000100000
FT8/Fox 11101000010011100001000000000010000000
FT8/Hound 11101000010011100001000000000011000000
-------------------------------------------------
1 2 3
012345678901234567890123456789012
01234567890123456789012345678901234567
----------------------------------------------
-------------------------------------------------
Mapping of column numbers to widgets
----------------------------------------------
-------------------------------------------------
0. txFirstCheckbox
1. TxFreqSpinBox
2. RxFreqSpinBox
@ -66,3 +66,4 @@ Mapping of column numbers to widgets
34. sbF_Low
35. sbF_High
36. AutoClrAvg
37. sbMaxDrift

View File

@ -19,6 +19,7 @@ Here is an overview list, details are filled out below:
* Hamlib rig control library
* Pkg Config Lite
* Boost C++ libraries (see separate document)
* portaudio library (used by map65)
Qt Framework
------------
@ -80,7 +81,7 @@ installed and updated you will need to install some packages, these
are needed to provide the necessary *nix tools and utilities to build
Hamlib from sources.
pacman -S autoconf automake libtool make
pacman -S autoconf automake libtool make tar
Hamlib
------
@ -98,13 +99,13 @@ fork is a git repository which can be cloned with this command:
Next you must build Hamlib using the MinGW compiler tools bundled with
Qt. As you will build Hamlib again when there are updates you should
set up you Msys2 command line environment for this. I use a
set up you MSYS2 command line environment for this. I use a
$HOME/.bash_profile file containing these lines:
dll_paths_64bit=/c/Tools/libusb-1.0.23/MinGW64/dll:$HOME/local/hamlib/mingw64/release/bin
export PATH=/c/Qt/Tools/mingw810_64/bin:$dll_paths_64bit:$PATH
Test the amended ~/.bash_profile file by opening a new Msys2 shell and
Test the amended ~/.bash_profile file by opening a new MSYS2 shell and
typing:
which gcc
@ -117,7 +118,7 @@ Hamlib sources:
cd ~/src/sf/bsomervi/hamlib
./bootstrap
Now you need to configure and build Hamlib from an Msys2 shell. Create
Now you need to configure and build Hamlib from an MSYS2 shell. Create
a build directory outside of the Hamlib sources you have just cloned,
then change working directory to that build directory.
@ -171,3 +172,74 @@ from https://sourceforge.net/projects/pkgconfiglite/files/0.28-1/ and
unzip it into a convenient location, as with other ancillary tools and
libraries I put these under C:\Tools\.
portaudio
---------
This library is only available as sources so must be built. It uses
autotools and building using MinGW tools from an MSYS2 shell is
recommended. Ensure your MSYS2 shell environment (PATH) is correctly
set up for the MinGW tool chain you wish to build with, i.e. the MinGW
tools bundled with the Qt installation for 32-, or 64-bit as required.
Download this specific version's sources tarball from
http://files.portaudio.com/download.html , at the time of writing that
was the pa_stable_v190600_20161030.tgz file. Unzip and unpack the
tarball in a suitable location like ~/src :
cd ~/src
tar xf ~/Downloads/pa_stable_v190600_20161030.tgz
Note that on Windows portaudio will only build static libraries using
the standard configuration, we prefer dynamic libraries for portaudio
as users may wish to substitute a build of the library with ASIO
support for personal use (we cannot redistribute binaries built from
proprietary closed source sources like the Steinberg ASIO SDK).
In order to build DLLs on Windows the configure script requires a
patch as follows:
sed -i -e 's/-luuid//g' ~/src/portaudio/configure
This removes linker dependencies on the MS uuid library since it is
only available as a static archive and using that would disallow
shared library creation.
Out-of-source-tree builds are recommended, create a build directory in
a suitable location like ~/build and change working directory to it:
mkdir -p ~/build/portaudio/mingw64
cd !$
Configure and build and install the library in a suitable place (I use
~/local as a root directory for installed packages.
~/src/portaudio/configure --prefix=$(HOME)/local/portaudio/mingw64 \
--with-winapi=wmme,directx,wdmks --disable-static --enable-shared CFLAGS=-DNDEBUG
make && make install
Repeat for the 32-bit architecture if required, using a suitable MSYS2
environment for the required tool chain, different build directory,
and install location.
Update your CMake tool chain files to include the install directory,
or directories, above. I have something like this in the 64-bit tool
chain files:
# ...
set (PORTAUDIODIR C:/Users/bill/local/portaudio/mingw64)
# ...
set (CMAKE_PREFIX_PATH ... ${PORTAUDIODIR} ...)
#...
and similarly with the 32-bit tool chain file specifying the mingw32
portaudio installation root directory.
To run Debug configuration WSJT-X builds you will also need to add the
location of the portaudio DLL to your PATH environment variable, like:
SET "Path=%UserProfile%\local\portaudio\mingw64\bin;%Path%"
Verify the setup with:
WHERE libportaudio-2.dll

View File

@ -1,15 +1,27 @@
[[NEW_FEATURES]]
=== New in Version {VERSION}
_WSJT-X 2.4.0_ introduces *Q65*, a new digital protocol designed for
minimal two-way QSOs over especially difficult propagation paths. On
paths with Doppler spread more than a few Hz, the weak-signal
performance of Q65 is the best among all WSJT-X modes.
_WSJT-X 2.5.0_ introduces an enhanced Q65 decoder that measures and
compensates for linear frequency drifts of Q65 signals. Activate this
feature by setting a spinner control *Max Drift* on the _WSJT-X_ main
window to a number greater than 0. We suggest a setting of 10 for
submode Q65-60A, the recommended submode for EME on 50 and 144 MHz,
which will accommodate drift rates up to 20 Hz/minute. Similarly, we
suggest *Max Drift* = 40 for submode Q65-15C, used for for 10 GHz QSOs
(up to 900 km) via aircraft scatter and drift rates up to about 20
Hz/s.
Q65 uses message formats and sequencing identical to those used in
FST4, FT4, FT8, and MSK144. Submodes are provided with a wide variety
of tone spacings and T/R sequence lengths 15, 30, 60, 120, and 300 s.
A new, highly reliable list-decoding technique is used for messages
that contain previously copied message fragments. Message averaging
is provided for situations where single transmissions are too weak or
signal enhancements too sparse for a signal to be decoded.
On the Windows platform only, _WSJT-X 2.5.0_ installations now include
an early version of _MAP65 3.0_. This program works together with
suitable hardware that converts RF to baseband. The hardware/software
combination implements a wideband, highly optimized receiver for the
Q65 and JT65 protocols, with matching transmitting features that
require a standard SSB transceiver. _MAP65_ is effective in both
single-polarization and dual-polarization systems. If two
polarization channels are available, _MAP65_ determines and matches
the linear polarization angle of each decodable signal. This
capability provides a major advantage for efficient EME communication
on bands up to 432 MHz. A single-channel _MAP65_ system works
extremely well for EME on 1296 MHz and higher bands, displaying all
signals in a 90 kHz sub-band and decoding all the Q65 and JT65
signals.

View File

@ -41,9 +41,7 @@ subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
if(nflip.eq.0) go to 900
! Find best DF, drift, curvature, and DT. Start by downsampling to 344.53125 Hz
call timer('fil6521 ',0)
call fil6521(cx,n5,c5x,n6)
call timer('fil6521 ',1)
fsample=1378.125/4.
@ -60,10 +58,8 @@ subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
! Apply AFC corrections to the time-domain signal
! Now we are back to using the 1378.125 Hz sample rate, enough to
! accommodate the full JT65C bandwidth.
a(3)=0
call timer('twkfreq ',0)
a(3)=0
call twkfreq65(cx,n5,a)
call timer('twkfreq ',1)
! Compute spectrum for each symbol.
nsym=126
@ -71,7 +67,6 @@ subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
df=1378.125/nfft
j=int(dtbest*1378.125)
call timer('sh_ffts ',0)
c5a=cmplx(0.0,0.0)
do k=1,nsym
do i=1,nfft
@ -89,7 +84,6 @@ subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
s1(jj,k)=real(c5a(i))**2 + aimag(c5a(i))**2
enddo
enddo
call timer('sh_ffts ',1)
call timer('dec65b ',0)
qualbest=0.

View File

@ -205,10 +205,11 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
open(17,file=trim(temp_dir)//'/red.dat',status='unknown')
open(14,file=trim(temp_dir)//'/avemsg.txt',status='unknown')
call timer('dec_q65 ',0)
call my_q65%decode(q65_decoded,id2,params%nutc,params%ntr, &
nqd=1
call my_q65%decode(q65_decoded,id2,nqd,params%nutc,params%ntr, &
params%nsubmode,params%nfqso,params%ntol,params%ndepth, &
params%nfa,params%nfb,logical(params%nclearave), &
single_decode,logical(params%nagain), &
single_decode,logical(params%nagain),params%max_drift, &
logical(params%newdat),params%emedelay,mycall,hiscall,hisgrid, &
params%nQSOProgress,ncontest,logical(params%lapcqonly),navg0)
call timer('dec_q65 ',1)

View File

@ -13,24 +13,19 @@
#endif
void ENCODE_RS(
#ifdef FIXED
DTYPE *data, DTYPE *bb,int pad){
#else
void *p,DTYPE *data, DTYPE *bb){
#ifndef FIXED
void *p,
#endif
DTYPE *data, DTYPE *bb){
#ifndef FIXED
struct rs *rs = (struct rs *)p;
#endif
int i, j;
DTYPE feedback;
#ifdef FIXED
/* Check pad parameter for validity */
if(pad < 0 || pad >= NN)
return;
#endif
memset(bb,0,NROOTS*sizeof(DTYPE));
for(i=0;i<NN-NROOTS-PAD;i++){
for(i=0;i<NN-NROOTS;i++){
feedback = INDEX_OF[data[i] ^ bb[0]];
if(feedback != A0){ /* feedback term is non-zero */
#ifdef UNNORMALIZED

View File

@ -9,7 +9,6 @@ subroutine fast_decode(id2,narg,trperiod,line,mycall_12, &
double precision trperiod
real dat(30*12000)
complex cdat(262145),cdat2(262145)
real psavg(450)
logical pick,first
character*6 cfile6
character*80 line(100)

View File

@ -630,7 +630,7 @@ contains
close(42)
endif
900 return
return
end subroutine decode
subroutine sync_fst4(cd0,i0,f0,hmod,ncoh,np,nss,ntr,fs,sync)

0
lib/ft2/portaudio.h Normal file → Executable file
View File

View File

@ -38,7 +38,7 @@ void ftrsd2_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
int nera_best=0;
float pp,pp1,pp2;
static unsigned int nseed;
// Power-percentage symbol metrics - composite gnnf/hf
int perr[8][8] = {
{ 4, 9, 11, 13, 14, 14, 15, 15},
@ -203,7 +203,7 @@ NB: j is the symbol-vector index of the symbol with rank i.
param[1]=nhard_min;
param[2]=nsoft_min;
param[3]=nera_best;
param[4]=1000.0*pp2/pp1;
param[4]= pp1 > 0 ? 1000.0*pp2/pp1 : 1000.0;
param[5]=ntotal_min;
param[6]=ntry[0];
param[7]=1000.0*pp2;

View File

@ -28,10 +28,9 @@ void FREE_RS(void *p){
* fcr = first root of RS code generator polynomial, index form
* prim = primitive element to generate polynomial roots
* nroots = RS code generator polynomial degree (number of roots)
* pad = padding bytes at front of shortened block
*/
void *INIT_RS(int symsize,int gfpoly,int fcr,int prim,
int nroots,int pad){
void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned fcr,unsigned prim,
unsigned int nroots){
struct rs *rs;
int i, j, sr,root,iprim;
@ -39,19 +38,16 @@ void *INIT_RS(int symsize,int gfpoly,int fcr,int prim,
if(symsize < 0 || symsize > (int)(8*sizeof(DTYPE)))
return NULL; /* Need version with ints rather than chars */
if(fcr < 0 || fcr >= (1<<symsize))
if(fcr >= (1<<symsize))
return NULL;
if(prim <= 0 || prim >= (1<<symsize))
if(prim == 0 || prim >= (1<<symsize))
return NULL;
if(nroots < 0 || nroots >= (1<<symsize))
if(nroots >= (1<<symsize))
return NULL; /* Can't have more roots than symbol values! */
if(pad < 0 || pad >= ((1<<symsize) -1 - nroots))
return NULL; /* Too much padding */
rs = (struct rs *)calloc(1,sizeof(struct rs));
rs->mm = symsize;
rs->nn = (1<<symsize)-1;
rs->pad = pad;
rs->alpha_to = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
if(rs->alpha_to == NULL){

View File

@ -20,7 +20,7 @@ program jt9
real*8 TRperiod
character c
character(len=500) optarg, infile
character wisfile*80
character wisfile*256
!### ndepth was defined as 60001. Why???
integer :: arglen,stat,offset,remain,mode=0,flow=200,fsplit=2700, &
fhigh=4000,nrxfreq=1500,ndepth=1,nexp_decode=0,nQSOProg=0
@ -301,6 +301,9 @@ program jt9
shared_data%params%napwid=75
shared_data%params%dttol=3.
if(mode.eq.164 .and. nsubmode.lt.100) nsubmode=nsubmode+100
shared_data%params%nagain=.false.
shared_data%params%nclearave=.false.
shared_data%params%lapcqonly=.false.
shared_data%params%naggressive=0
shared_data%params%n2pass=2
shared_data%params%nQSOprogress=nQSOProg
@ -322,6 +325,10 @@ program jt9
shared_data%params%nmode=mode
end if
shared_data%params%nsubmode=nsubmode
!### temporary, for MAP65:
if(mode.eq.66 .and. TRperiod.eq.60) shared_data%params%emedelay=2.5
datetime="2013-Apr-16 15:13" !### Temp
shared_data%params%datetime=transfer(datetime,shared_data%params%datetime)
if(mode.eq.9 .and. fsplit.ne.2700) shared_data%params%nfa=fsplit

View File

@ -41,6 +41,7 @@
integer(c_int) :: naggressive
logical(c_bool) :: nrobust
integer(c_int) :: nexp_decode
integer(c_int) :: max_drift
character(kind=c_char) :: datetime(20)
character(kind=c_char) :: mycall(12)
character(kind=c_char) :: mygrid(6)

95
lib/map65_mmdec.f90 Normal file
View File

@ -0,0 +1,95 @@
subroutine map65_mmdec(nutc,id2,nqd,nsubmode,nfa,nfb,nfqso,ntol,newdat, &
nagain,max_drift,mycall,hiscall,hisgrid)
use prog_args
use timer_module, only: timer
use q65_decode
include 'jt9com.f90'
include 'timer_common.inc'
type, extends(q65_decoder) :: counting_q65_decoder
integer :: decoded
end type counting_q65_decoder
logical single_decode,bVHF,lnewdat,lagain,lclearave,lapcqonly
integer*2 id2(300*12000)
! type(params_block) :: params
character(len=20) :: datetime
character(len=12) :: mycall, hiscall
character(len=6) :: hisgrid
data ntr0/-1/
save
type(counting_q65_decoder) :: my_q65
! Cast C character arrays to Fortran character strings
! datetime=transfer(params%datetime, datetime)
! mycall=transfer(params%mycall,mycall)
! hiscall=transfer(params%hiscall,hiscall)
! mygrid=transfer(params%mygrid,mygrid)
! hisgrid=transfer(params%hisgrid,hisgrid)
datetime=' '
my_q65%decoded = 0
ncontest=0
nQSOprogress=0
lclearave=.false.
single_decode=.false.
lapcqonly=.false.
lnewdat=(newdat.ne.0)
lagain=(nagain.ne.0)
bVHF=.true.
emedelay=2.5
ndepth=1
ntrperiod=60
open(17,file=trim(temp_dir)//'/red.dat',status='unknown')
open(14,file=trim(temp_dir)//'/avemsg.txt',status='unknown')
call timer('dec_q65 ',0)
call my_q65%decode(q65_decoded,id2,nqd,nutc,ntrperiod,nsubmode,nfqso, &
ntol,ndepth,nfa,nfb,lclearave,single_decode,lagain,max_drift,lnewdat, &
emedelay,mycall,hiscall,hisgrid,nQSOProgress,ncontest,lapcqonly,navg0)
call timer('dec_q65 ',1)
return
contains
subroutine q65_decoded (this,nutc,snr1,nsnr,dt,freq,decoded,idec, &
nused,ntrperiod)
use q65_decode
implicit none
class(q65_decoder), intent(inout) :: this
integer, intent(in) :: nutc
real, intent(in) :: snr1
integer, intent(in) :: nsnr
real, intent(in) :: dt
real, intent(in) :: freq
character(len=37), intent(in) :: decoded
integer, intent(in) :: idec
integer, intent(in) :: nused
integer, intent(in) :: ntrperiod
if(nutc+snr1+nsnr+dt+freq+idec+nused+ntrperiod.eq.-999) stop
if(decoded.eq.'-999') stop
cq0='q '
write(cq0(2:2),'(i1)') idec
if(nused.ge.2) write(cq0(3:3),'(i1)') nused
nsnr0=nsnr
xdt0=dt
nfreq0=nint(freq)
msg0=decoded
select type(this)
type is (counting_q65_decoder)
if(idec.ge.0) this%decoded = this%decoded + 1
end select
return
end subroutine q65_decoded
end subroutine map65_mmdec

View File

@ -1,5 +1,9 @@
module q65_decode
integer nsnr0,nfreq0
real xdt0
character msg0*37,cq0*3
type :: q65_decoder
procedure(q65_decode_callback), pointer :: callback
contains
@ -26,9 +30,10 @@ module q65_decode
contains
subroutine decode(this,callback,iwave,nutc,ntrperiod,nsubmode,nfqso, &
ntol,ndepth,nfa0,nfb0,lclearave,single_decode,lagain,lnewdat0, &
emedelay,mycall,hiscall,hisgrid,nQSOprogress,ncontest,lapcqonly,navg0)
subroutine decode(this,callback,iwave,nqd0,nutc,ntrperiod,nsubmode,nfqso, &
ntol,ndepth,nfa0,nfb0,lclearave,single_decode,lagain,max_drift0, &
lnewdat0,emedelay,mycall,hiscall,hisgrid,nQSOprogress,ncontest, &
lapcqonly,navg0)
! Top-level routine that organizes the decoding of Q65 signals
! Input: iwave Raw data, i*2
@ -67,15 +72,17 @@ contains
integer dat4(13) !Decoded message as 12 6-bit integers
integer dgen(13)
logical lclearave,lnewdat0,lapcqonly,unpk77_success
logical single_decode,lagain,ex
logical single_decode,lagain
complex, allocatable :: c00(:) !Analytic signal, 6000 Sa/s
complex, allocatable :: c0(:) !Analytic signal, 6000 Sa/s
! Start by setting some parameters and allocating storage for large arrays
call sec0(0,tdecode)
nfa=nfa0
nfb=nfb0
nqd=nqd0
lnewdat=lnewdat0
max_drift=max_drift0
idec=-1
idf=0
idt=0
@ -84,6 +91,7 @@ contains
npts=ntrperiod*12000
nfft1=ntrperiod*12000
nfft2=ntrperiod*6000
npasses=1
! Determine the T/R sequence: iseq=0 (even), or iseq=1 (odd)
n=nutc
@ -116,33 +124,33 @@ contains
baud=12000.0/nsps
this%callback => callback
nFadingModel=1
inquire(file='ndepth.dat',exist=ex)
if(.not.ex) ndepth=iand(ndepth,not(3)) + 1 !Treat any ndepth as "Fast"
maxiters=67
maxiters=33
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 1)
ibwb=min(10,ibwa+4)
ibwb=min(10,ibwa+2)
if(iand(ndepth,3).ge.2) then
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 1)
ibwb=min(10,ibwa+5)
maxiters=67
else if(iand(ndepth,3).eq.3) then
ibwa=max(1,ibwa-1)
ibwb=min(10,ibwb+1)
maxiters=100
endif
! Generate codewords for full-AP list decoding
call q65_set_list(mycall,hiscall,hisgrid,codewords,ncw)
! Generate codewords for full-AP list decoding
if(ichar(hiscall(1:1)).eq.0) hiscall=' '
if(ichar(hisgrid(1:1)).eq.0) hisgrid=' '
ncw=0
if(nqd.eq.1 .or. lagain) then
call q65_set_list(mycall,hiscall,hisgrid,codewords,ncw)
endif
dgen=0
call q65_enc(dgen,codewords) !Initialize the Q65 codec
nused=1
iavg=0
call timer('q65_dec0',0)
! Call top-level routine in q65 module: establish sync and try for a q3 decode.
call q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
emedelay,xdt,f0,snr1,width,dat4,snr2,idec)
! idec=-1 !### TEMPORARY ###
call timer('q65_dec0',1)
if(idec.ge.0) then
@ -298,7 +306,6 @@ contains
call timer('q65loops',0)
call q65_loops(c00,npts/2,nsps/2,nsubmode,ndepth,jpk0, &
xdt,f0,iaptype,xdt1,f1,snr2,dat4,idec)
! idec=-1 !### TEMPORARY ###
call timer('q65loops',1)
if(idec.ge.0) then
dtdec=xdt1

View File

@ -434,11 +434,14 @@ int q65_intrinsics_fastfading(q65_codec_ds *pCodec,
// exponentiate and accumulate the normalization constant
sumix = 0.0f;
for (k=0;k<nM;k++) {
fTemp = expf(pCurIx[k]-maxlogp);
pCurIx[k]=fTemp;
sumix +=fTemp;
}
for (k=0;k<nM;k++) {
float x=pCurIx[k]-maxlogp;
if(x < -85.0) x=-85.0;
if(x > 85.0) x= 85.0;
fTemp = expf(x);
pCurIx[k]=fTemp;
sumix +=fTemp;
}
// scale to a probability distribution
sumix = 1.0f/sumix;
@ -663,9 +666,11 @@ int q65_check_llh(float *llh, const int* ydec, const int nN, const int nM, const
float t = 0;
for (k=0;k<nN;k++) {
t+=logf(pIntrin[ydec[k]]);
pIntrin+=nM;
}
float x=pIntrin[ydec[k]];
if(x < 1.0e-36) x = 1.0e-36;
t+=logf(x);
pIntrin+=nM;
}
if (llh!=NULL)
*llh = t;

View File

@ -10,8 +10,8 @@ module q65
integer,dimension(22) :: isync = (/1,9,12,13,15,22,23,26,27,33,35, &
38,46,50,55,60,62,66,69,74,76,85/)
integer codewords(63,206)
integer ibwa,ibwb,ncw,nsps,mode_q65,nfa,nfb
integer idfbest,idtbest,ibw,ndistbest,maxiters
integer ibwa,ibwb,ncw,nsps,mode_q65,nfa,nfb,nqd
integer idfbest,idtbest,ibw,ndistbest,maxiters,max_drift
integer istep,nsmo,lag1,lag2,npasses,nused,iseq,ncand,nrc
integer i0,j0
integer navg(0:1)
@ -23,7 +23,7 @@ module q65
real, allocatable,save :: ccf2(:) !Max CCF(freq) at any lag, single seq
real, allocatable,save :: ccf2_avg(:) !Like ccf2, but for accumulated average
real sync(85) !sync vector
real df,dtstep,dtdec,f0dec,ftol,plog
real df,dtstep,dtdec,f0dec,ftol,plog,drift
contains
@ -69,6 +69,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
data first/.true./
save first
NN=63
if(nutc+ndepth.eq.-999) stop !Silence compiler warnings
! Set some parameters and allocate storage for large arrays
@ -161,15 +162,22 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
call timer('list_dec',0)
call q65_dec_q3(s1,iz,jz,s3,LL,ipk,jpk,snr2,dat4,idec,decoded)
call timer('list_dec',1)
if(idec.eq.3) go to 900 !Good q3 decode, we're done
endif
if(iavg.eq.0) then
call q65_ccf_22(s1,iz,jz,nfqso,ipk,jpk,f0a,xdta,ccf2)
call timer('ccf_22a ',0)
call q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
f0a,xdta,ccf2)
call timer('ccf_22a ',1)
endif
! Get 2d CCF and ccf2 using sync symbols only
if(iavg.ge.1) then
call q65_ccf_22(s1,iz,jz,nfqso,ipk,jpk,f0a,xdta,ccf2_avg)
call timer('ccf_22b ',0)
call q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
f0a,xdta,ccf2_avg)
call timer('ccf_22b ',1)
endif
if(idec.lt.0) then
f0=f0a
@ -190,7 +198,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
smax=maxval(ccf1)
! Estimate frequenct spread
! Estimate frequency spread
i1=-9999
i2=-9999
do i=-ia,ia
@ -200,11 +208,10 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
width=df*(i2-i1)
if(ncw.eq.0) ccf1=0.
! write(*,3001) nutc,iavg,navg(0),sum(ccf2_avg),sum(ccf2)
!3001 format(i4.4,2i4,2f8.2)
call q65_write_red(iz,xdt,ccf2_avg,ccf2)
if(iavg.eq.2) then
if(iavg.eq.0 .or. iavg.eq.2) then
call q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
endif
@ -412,7 +419,8 @@ subroutine q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best,ccf1)
return
end subroutine q65_ccf_85
subroutine q65_ccf_22(s1,iz,jz,nfqso,ipk,jpk,f0,xdt,ccf2)
subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
f0,xdt,ccf2)
! Attempt synchronization using only the 22 sync symbols. Return ccf2
! for the "orange sync curve".
@ -420,57 +428,80 @@ subroutine q65_ccf_22(s1,iz,jz,nfqso,ipk,jpk,f0,xdt,ccf2)
real s1(iz,jz)
real ccf2(iz) !Orange sync curve
real, allocatable :: xdt2(:)
real, allocatable :: s1avg(:)
integer, allocatable :: indx(:)
allocate(xdt2(iz))
allocate(s1avg(iz))
allocate(indx(iz))
ia=max(nfa,100)/df
ib=min(nfb,4900)/df
if(nqd.ne.1 .or. iavg.ne.0) max_drift=0
if(max_drift.ne.0) then
ia=nint((nfqso-ntol)/df)
ib=nint((nfqso+ntol)/df)
endif
do i=ia,ib
s1avg(i)=sum(s1(i,1:jz))
enddo
ccfbest=0.
ibest=0
lagpk=0
lagbest=0
do i=1,iz
do i=ia,ib
ccfmax=0.
do lag=lag1,lag2
ccft=0.
do k=1,85
n=NSTEP*(k-1) + 1
j=n+lag+j0
if(j.ge.1 .and. j.le.jz) then
ccft=ccft + sync(k)*s1(i,j)
do idrift=-max_drift,max_drift
ccft=0.
do kk=1,22
k=isync(kk)
ii=i + nint(idrift*(k-43)/85.0)
if(ii.lt.1 .or. ii.gt.iz) cycle
n=NSTEP*(k-1) + 1
j=n+lag+j0
if(j.ge.1 .and. j.le.jz) ccft=ccft + s1(ii,j)
enddo ! kk
ccft=ccft - (22.0/jz)*s1avg(i)
if(ccft.gt.ccfmax) then
ccfmax=ccft
lagpk=lag
idrift_max=idrift
endif
enddo
if(ccft.gt.ccfmax) then
ccfmax=ccft
lagpk=lag
endif
enddo
enddo ! idrift
enddo ! lag
ccf2(i)=ccfmax
xdt2(i)=lagpk*dtstep
if(ccfmax.gt.ccfbest .and. abs(i*df-nfqso).le.ftol) then
ccfbest=ccfmax
ibest=i
lagbest=lagpk
idrift_best=idrift_max
endif
enddo
enddo ! i
! Parameters for the top candidate:
ipk=ibest - i0
jpk=lagbest
f0=nfqso + ipk*df
xdt=jpk*dtstep
drift=df*idrift_best
ccf2(:ia)=0.
ccf2(ib:)=0.
! Save parameters for best candidates
i1=max(nfa,100)/df
i2=min(nfb,4900)/df
jzz=i2-i1+1
call pctile(ccf2(i1:i2),jzz,40,base)
jzz=ib-ia+1
call pctile(ccf2(ia:ib),jzz,40,base)
ccf2=ccf2/base
call indexx(ccf2(i1:i2),jzz,indx)
call indexx(ccf2(ia:ib),jzz,indx)
ncand=0
maxcand=20
do j=1,20
i=indx(jzz-j+1)+i1-1
k=jzz-j+1
if(k.lt.1 .or. k.gt.iz) cycle
i=indx(k)+ia-1
if(ccf2(i).lt.3.3) exit !Candidate limit
f=i*df
if(f.ge.(nfqso-ftol) .and. f.le.(nfqso+ftol)) cycle !Looked here already
@ -692,12 +723,6 @@ subroutine q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
if(nused.eq.3) snr2=snr2 - 2.9
if(nused.ge.4) snr2=snr2 - 3.5
! do i=ia,ib
! write(71,3071) i*df,spec(i),db(spec(i))
!3071 format(3f10.3)
! enddo
! flush(71)
return
end subroutine q65_snr
@ -736,7 +761,8 @@ subroutine q65_hist(if0,msg0,dxcall,dxgrid)
msg(nhist)=msg0
go to 900
100 dxcall=' ' !This is a lookup request
100 if(dxcall(1:3).ne.' ') go to 900
dxcall=' ' !This is a lookup request
dxgrid=' '
! Look for a decode close to if0, starting with most recent ones
do i=nhist,1,-1

View File

@ -0,0 +1,223 @@
module gf64math
! add and subtract in GF(2^6) based on primitive polynomial x^6+x+1
implicit none
integer, private :: gf64log(0:63)
integer, private :: gf64antilog(0:62)
! table of the logarithms of the elements of GF(M) (log(0) never used)
data gf64log/ &
-1, 0, 1, 6, 2, 12, 7, 26, 3, 32, &
13, 35, 8, 48, 27, 18, 4, 24, 33, 16, &
14, 52, 36, 54, 9, 45, 49, 38, 28, 41, &
19, 56, 5, 62, 25, 11, 34, 31, 17, 47, &
15, 23, 53, 51, 37, 44, 55, 40, 10, 61, &
46, 30, 50, 22, 39, 43, 29, 60, 42, 21, &
20, 59, 57, 58/
! table of GF(M) elements given their logarithm
data gf64antilog/ &
1, 2, 4, 8, 16, 32, 3, 6, 12, 24, &
48, 35, 5, 10, 20, 40, 19, 38, 15, 30, &
60, 59, 53, 41, 17, 34, 7, 14, 28, 56, &
51, 37, 9, 18, 36, 11, 22, 44, 27, 54, &
47, 29, 58, 55, 45, 25, 50, 39, 13, 26, &
52, 43, 21, 42, 23, 46, 31, 62, 63, 61, &
57, 49, 33/
contains
integer function gf64_add(i1,i2)
implicit none
integer::i1
integer::i2
gf64_add=iand(ieor(i1,i2),63)
end function gf64_add
integer function gf64_mult(i1,i2)
implicit none
integer::i1
integer::i2
integer::j
if(i1.eq.0 .or. i2.eq.0) then
gf64_mult=0
elseif(i1.eq.1) then
gf64_mult=i2
elseif(i2.eq.1) then
gf64_mult=i1
else
j=mod(gf64log(i1)+gf64log(i2),63)
gf64_mult=gf64antilog(j)
endif
end function gf64_mult
end module gf64math
module q65_generator
integer generator(15,50)
data generator/ &
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, &
0,20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, &
0,20, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, &
0,20, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, &
0,20, 0, 1, 1, 0, 0, 0,10, 0, 0, 0, 0, 1, 0, &
0,20, 0, 1, 1, 0, 0, 0,10, 0, 0, 0,44, 1, 0, &
0,20, 0, 1, 1, 0, 0, 0,10, 1, 0, 0,44, 1, 0, &
0,20, 0, 1, 1, 0, 0, 0,10, 1, 0, 0,44, 1,14, &
0,20, 0, 1, 1, 0, 0, 0,10, 1,31, 0,44, 1,14, &
0,20, 0, 1, 1,33, 0, 0,10, 1,31, 0,44, 1,14, &
56,20, 0, 1, 1,33, 0, 0,10, 1,31, 0,44, 1,14, &
56,20, 0, 1, 1,33, 0, 1,10, 1,31, 0,44, 1,14, &
56, 1, 0, 1, 1,33, 0, 1,10, 1,31, 0,44, 1,14, &
56, 1, 0, 1, 1,33, 0, 1,10, 1,31,36,44, 1,14, &
56, 1, 0, 1, 1,33, 0, 1,43, 1,31,36,44, 1,14, &
56, 1, 0, 1, 1,33, 0, 1,43,17,31,36,44, 1,14, &
56, 1, 0, 1, 1,33, 0, 1,43,17,31,36,36, 1,14, &
56, 1, 0, 1, 1,33,53, 1,43,17,31,36,36, 1,14, &
56, 1, 0,35, 1,33,53, 1,43,17,31,36,36, 1,14, &
56, 1, 0,35, 1,33,53, 1,43,17,30,36,36, 1,14, &
56, 1, 0,35, 1,33,53,52,43,17,30,36,36, 1,14, &
56, 1, 0,35, 1,32,53,52,43,17,30,36,36, 1,14, &
56, 1,60,35, 1,32,53,52,43,17,30,36,36, 1,14, &
56, 1,60,35, 1,32,53,52,43,17,30,36,36,49,14, &
56, 1,60,35, 1,32,53,52,43,17,30,36,37,49,14, &
56, 1,60,35,54,32,53,52,43,17,30,36,37,49,14, &
56, 1,60,35,54,32,53,52, 1,17,30,36,37,49,14, &
1, 1,60,35,54,32,53,52, 1,17,30,36,37,49,14, &
1, 0,60,35,54,32,53,52, 1,17,30,36,37,49,14, &
1, 0,60,35,54,32,53,52, 1,17,30,37,37,49,14, &
1, 0,61,35,54,32,53,52, 1,17,30,37,37,49,14, &
1, 0,61,35,54,32,53,52, 1,48,30,37,37,49,14, &
1, 0,61,35,54,32,53,52, 1,48,30,37,37,49,15, &
1, 0,61,35,54, 0,53,52, 1,48,30,37,37,49,15, &
1, 0,61,35,54, 0,52,52, 1,48,30,37,37,49,15, &
1, 0,61,35,54, 0,52,52, 1,48,30,37,37, 0,15, &
1, 0,61,35,54, 0,52,34, 1,48,30,37,37, 0,15, &
1, 0,61,35,54, 0,52,34, 1,48,30,37, 0, 0,15, &
1, 0,61,35,54, 0,52,34, 1,48,30,20, 0, 0,15, &
1, 0, 0,35,54, 0,52,34, 1,48,30,20, 0, 0,15, &
1, 0, 0,35,54, 0,52,34, 1, 0,30,20, 0, 0,15, &
0, 0, 0,35,54, 0,52,34, 1, 0,30,20, 0, 0,15, &
0, 0, 0,35,54, 0,52,34, 1, 0,38,20, 0, 0,15, &
0, 0, 0,35, 0, 0,52,34, 1, 0,38,20, 0, 0,15, &
0, 0, 0,35, 0, 0,52, 0, 1, 0,38,20, 0, 0,15, &
0, 0, 0,35, 0, 0,52, 0, 1, 0,38,20, 0, 0, 0, &
0, 0, 0,35, 0, 0,52, 0, 0, 0,38,20, 0, 0, 0, &
0, 0, 0,35, 0, 0,52, 0, 0, 0,38, 0, 0, 0, 0, &
0, 0, 0, 0, 0, 0,52, 0, 0, 0,38, 0, 0, 0, 0, &
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,38, 0, 0, 0, 0/
end module q65_generator
module q65_encoding
contains
subroutine q65_encode(message,codeword)
use gf64math
use q65_generator
integer message(15)
integer codeword(65)
integer i,j
codeword=0
codeword(1:15)=message
do i=1,15
do j=16,65
codeword(j)=gf64_add(codeword(j),gf64_mult(message(i),generator(i,j-15)))
enddo
enddo
return
end
subroutine get_q65crc12(mc2,ncrc1,ncrc2)
!
character c12*12,c6*6
integer*1 mc(90),mc2(90),tmp(6)
integer*1 r(13),p(13)
integer ncrc
! polynomial for 12-bit CRC 0xF01
data p/1,1,0,0,0,0,0,0,0,1,1,1,1/
! flip bit order of each 6-bit symbol for consistency with Nico's calculation
do i=0,14
tmp=mc2(i*6+1:i*6+6)
mc(i*6+1:i*6+6)=tmp(6:1:-1)
enddo
! divide by polynomial
r=mc(1:13)
do i=0,77
r(13)=mc(i+13)
r=mod(r+r(1)*p,2)
r=cshift(r,1)
enddo
write(c6,'(6b1)') r(6:1:-1)
read(c6,'(b6.6)') ncrc1
read(c6,'(6b1)') mc2(79:84)
write(c6,'(6b1)') r(12:7:-1)
read(c6,'(b6.6)') ncrc2
read(c6,'(6b1)') mc2(85:90)
end subroutine get_q65crc12
subroutine get_q65_tones(msg37,codeword,itone)
use packjt77
implicit none
character*37 msg37
character*77 c77
character*12 c12
character*6 c6
integer codeword(65)
integer sync(22)
integer message(15)
integer shortcodeword(63)
integer itone(85)
integer i,j,k
integer*1 mbits(90)
integer i3,n3,ncrc1,ncrc2
data sync/1,9,12,13,15,22,23,26,27,33,35,38,46,50,55,60,62,66,69,74,76,85/
i3=-1
n3=-1
call pack77(msg37,i3,n3,c77)
mbits=0
read(c77,'(77i1)') mbits(1:77)
! Message is 77 bits long. Add a 0 bit to create a 78-bit message and pad with
! 12 zeros to create 90-bit mbit array for CRC calculation.
call get_q65crc12(mbits,ncrc1,ncrc2)
! Now have message in bits 1:78 and CRC in bits 79:90.
! Group message bits into 15 6-bit symbols:
do i=0,14
write(c6,'(6i1)') mbits( (i*6+1):(i*6+6) )
read(c6,'(b6.6)') message(i+1)
enddo
! Encode to create a 65-symbol codeword
call q65_encode(message,codeword)
!Shorten the codeword by omitting the CRC symbols (symbols 14 and 15)
shortcodeword(1:13)=codeword(1:13)
shortcodeword(14:63)=codeword(16:65)
!Insert sync symbols to create array of channel symbols
j=1
k=0
do i=1,85
if(i.eq.sync(j)) then
j=j+1
itone(i)=0
else
k=k+1
itone(i)=shortcodeword(k)+1
endif
enddo
end subroutine get_q65_tones
end module q65_encoding

View File

@ -11,30 +11,35 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
complex ,allocatable :: c0(:) !Ditto, with freq shift
character decoded*37
real a(3) !twkfreq params f,f1,f2
real s3(LN) !Symbol spectra
real,allocatable :: s3(:) !Symbol spectra
integer dat4(13) !Decoded message (as 13 six-bit integers)
integer nap(0:11) !AP return codes
data nap/0,2,3,2,3,4,2,3,6,4,6,6/
LL=64*(mode_q65+2)
allocate(s3(LL*NN))
allocate(c0(0:npts2-1))
idec=-1
ircbest=9999
allocate(c0(0:npts2-1))
irc=-99
s3lim=20.
baud=6000.0/nsps2
idfmax=3
idtmax=3
idfmax=1
idtmax=1
maxdist=4
ibw0=(ibwa+ibwb)/2
maxdist=5
if(iand(ndepth,3).ge.2) then
if(iand(ndepth,3).eq.2) then
idfmax=3
idtmax=3
maxdist=5
endif
if(iand(ndepth,3).eq.3) then
idfmax=5
idtmax=5
maxdist=10
maxdist=15
endif
if(iand(ndepth,3).eq.3) maxdist=15
LL=64*(mode_q65+2)
napmin=99
xdt1=xdt0
f1=f0
@ -47,15 +52,15 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
if(mod(idf,2).eq.0) ndf=-ndf
a=0.
a(1)=-(f0+0.5*baud*ndf)
! Variable 'drift' is frequency increase over full TxT. Therefore we want:
a(2)=-0.5*drift
call twkfreq(c00,c0,npts2,6000.0,a)
do idt=1,idtmax
ndt=idt/2
if(mod(idt,2).eq.0) ndt=-ndt
jpk=jpk0 + nsps2*ndt/16 !tsym/16
if(jpk.lt.0) jpk=0
call timer('spec64 ',0)
call spec64(c0,nsps2,mode_q65,jpk,s3,LL,NN)
call timer('spec64 ',1)
call pctile(s3,LL*NN,40,base)
s3=s3/base
where(s3(1:LL*NN)>s3lim) s3(1:LL*NN)=s3lim

29
lib/qra/q65/q65code.f90 Normal file
View File

@ -0,0 +1,29 @@
program q65code
use q65_encoding
implicit none
character*37 msg37
integer nargs
integer codeword(65),tones(85)
nargs=iargc()
if(nargs .ne. 1) then
print*,'Usage: q65code "msg"'
goto 999
endif
call getarg(1,msg37)
call get_q65_tones(msg37,codeword,tones)
write(*,*) 'Generated message plus CRC (90 bits)'
write(*,'(a8,15i4)') '6 bit : ',codeword(1:15)
write(*,'(a8,15b6.6)') 'binary: ',codeword(1:15)
write(*,*) ' '
write(*,*) 'Codeword with CRC symbols (65 symbols)'
write(*,'(20i3)') codeword
write(*,*) ' '
write(*,*) 'Channel symbols (85 total)'
write(*,'(20i3)') tones
999 end program q65code

View File

@ -494,7 +494,7 @@ static const int qra_pmat[qra_M*qra_M] = {
3, 1, 7, 5, 11, 9, 15, 13, 19, 17, 23, 21, 27, 25, 31, 29,
35, 33, 39, 37, 43, 41, 47, 45, 51, 49, 55, 53, 59, 57, 63, 61
};
/*
// SO array
static const int SO[qra_N-qra_K+1] = {
14, 2, 4, 5, 9, 13, 10, 15, 11, 6, 1, 8, 2, 12, 9, 10,
@ -515,6 +515,7 @@ static const int LOGWO[qra_N-qra_K+1] = {
static const int repfact[qra_K] = {
3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 3, 3
};
*/
const qracode qra15_65_64_irr_e23 = {
qra_K,

View File

@ -126,35 +126,3 @@ subroutine symspec(shared_data,k,TRperiod,nsps,ingain,bLowSidelobes, &
return
end subroutine symspec
subroutine chk_samples(ihsym,k,nstop)
integer*8 count0,count1,clkfreq
integer itime(8)
real*8 dtime,fsample
character*12 ctime
data count0/-1/,k0/99999999/,maxhsym/0/
save count0,k0,maxhsym
if(k.lt.k0 .or. count0.eq.-1) then
call system_clock(count0,clkfreq)
maxhsym=0
endif
! if((mod(ihsym,100).eq.0 .or. ihsym.ge.nstop-100) .and. &
! k0.ne.99999999) then
! call system_clock(count1,clkfreq)
! dtime=dfloat(count1-count0)/dfloat(clkfreq)
! if(dtime.lt.28.0) return
! if(dtime.gt.1.d-6) fsample=(k-3456)/dtime
! call date_and_time(values=itime)
! sec=itime(7)+0.001*itime(8)
! write(ctime,3000) itime(5)-itime(4)/60,itime(6),sec
!3000 format(i2.2,':',i2.2,':',f6.3)
! write(33,3033) ctime,dtime,ihsym,nstop,k,fsample
!3033 format(a12,f12.6,2i7,i10,f15.3)
! flush(33)
! endif
k0=k
return
end subroutine chk_samples

View File

@ -1,6 +1,6 @@
program test_q65
character*82 cmd1,cmd2,line
character*84 cmd1,cmd2,line
character*22 msg
character*8 arg
character*1 csubmode
@ -71,8 +71,8 @@ program test_q65
tsym=1.0/baud
! 1 2 3 4 5 6 7
! 123456789012345678901234567890123456789012345678901234567890123456789012345'
cmd1='q65sim "K1ABC W9XYZ EN37 " A 1500 5.0 0.0 0.0 1 60 100 -10.0 > junk0'
! 1234567890123456789012345678901234567890123456789012345678901234567890123456'
cmd1='q65sim "K1ABC W9XYZ EN37 " A 1500 5.0 0.0 0.0 1 60 100 -10.0 > junk0'
cmd2='jt9 -3 -p 15 -L 300 -H 3000 -d 3 -b A -Q 3 -f 1500 *.wav > junk'
write(cmd1(10:33),'(a)') '"'//msg//'"'
@ -80,10 +80,10 @@ program test_q65
write(cmd1(37:40),'(i4)') nf0
write(cmd1(41:45),'(f5.0)') fDop
write(cmd1(46:50),'(f5.2)') dt
write(cmd1(51:54),'(f4.0)') f1
write(cmd1(55:57),'(i3)') nstp
write(cmd1(58:61),'(i4)') ntrperiod
write(cmd1(62:66),'(i5)') nfiles
write(cmd1(51:56),'(i6)') nint(f1)
write(cmd1(57:59),'(i3)') nstp
write(cmd1(60:63),'(i4)') ntrperiod
write(cmd1(64:68),'(i5)') nfiles
write(cmd2(11:13),'(i3)') ntrperiod
write(cmd2(33:35),'(i3)') ndepth
@ -94,7 +94,7 @@ program test_q65
call system('rm -f *.wav')
write(*,1008) ntrperiod,csubmode,ndepth,fDop,f1,nstp
1008 format('Mode:',i4,a1,' Depth:',i3,' fDop:',f6.1,' Drift:',f6.1, &
1008 format('Mode:',i4,a1,' Depth:',i3,' fDop:',f6.1,' Drift:',f8.1, &
' Steps:',i3)
write(*,1010) (j,j=0,5)
write(12,1010) (j,j=0,5)
@ -112,7 +112,7 @@ program test_q65
nfalse=0
naptype=0
ndecn=0
write(cmd1(70:74),'(f5.1)') snr1
write(cmd1(72:76),'(f5.1)') snr1
call system(cmd1)
call sec0(0,tdec)
call system(cmd2)

View File

@ -1,5 +1,9 @@
subroutine twkfreq(c3,c4,npts,fsample,a)
! Adjust frequency of complex data
! a(1) Hz
! a(2) Hz/(0.5*TxT), where TxT = npts/fsample = file duration
complex c3(npts)
complex c4(npts)
complex w,wstep

1
map65/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
~*

70
map65/CMakeLists.txt Normal file
View File

@ -0,0 +1,70 @@
set (map65_CXXSRCS
about.cpp
astro.cpp
bandmap.cpp
devsetup.cpp
displaytext.cpp
getdev.cpp
getfile.cpp
main.cpp
mainwindow.cpp
messages.cpp
meterwidget.cpp
plotter.cpp
set570.cpp
signalmeter.cpp
soundin.cpp
soundout.cpp
txtune.cpp
widegraph.cpp
)
if (WIN32)
set (map65_CXXSRCS ${map65_CXXSRCS} killbyname.cpp)
endif (WIN32)
set (map65_UISRCS
about.ui
astro.ui
bandmap.ui
devsetup.ui
mainwindow.ui
messages.ui
txtune.ui
widegraph.ui
)
set (map65_C_and_CXXSRCS
${map65_CSRCS}
${map65_CXXSRCS}
)
set_property (SOURCE ${map65_C_and_CXXSRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -include wsjtx_config.h")
set_property (SOURCE ${map65_C_and_CXXSRCS} APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_BINARY_DIR}/wsjtx_config.h)
# build the subdirectories
add_subdirectory (libm65)
# UI generation
qt5_wrap_ui (map65_GENUISRCS ${map65_UISRCS})
add_executable (map65 ${map65_CXXSRCS} ${map65_CSRCS} ${map65_GENUISRCS} map65.rc)
target_include_directories (map65 PRIVATE ${CMAKE_SOURCE_DIR} ${FFTW3_INCLUDE_DIRS})
target_link_libraries (map65 wsjt_qt m65impl ${FFTW3_LIBRARIES} Qt5::Widgets Qt5::Network Portaudio::Portaudio Usb::Usb)
if (WIN32)
install (
CODE "get_filename_component (_path \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/wsjtx_dir.txt\" REALPATH)
if (WIN32)
set (_separator \"\\\\\")
else ()
set (_separator \"/\")
endif ()
file (WRITE \"\${_path}\" \".\${_separator}\\n\")"
)
install (
TARGETS map65
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION . COMPONENT runtime
)
endif ()

View File

@ -0,0 +1,30 @@
+ + + This Software is released under the "Simplified BSD License" + + +
Copyright 2010 Moe Wheatley. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY Moe Wheatley ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Moe Wheatley OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation
are those of the authors and should not be interpreted as representing
official policies, either expressed or implied, of Moe Wheatley.

Binary file not shown.

23
map65/about.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "about.h"
#include "revision_utils.hpp"
#include "ui_about.h"
CAboutDlg::CAboutDlg(QWidget *parent) :
QDialog(parent),
ui(new Ui::CAboutDlg)
{
ui->setupUi(this);
ui->labelTxt->setText("<html><h2>" + QString {"MAP65 v"
+ QCoreApplication::applicationVersion ()
+ " " + revision ()}.simplified () + "</h2><br />"
"MAP65 implements a wideband polarization-matching receiver <br />"
"for the JT65 protocol, with a matching transmitting facility. <br />"
"It is primarily intended for amateur radio EME communication. <br /><br />"
"Copyright 2001-2021 by Joe Taylor, K1JT. Additional <br />"
"acknowledgments are contained in the source code.");
}
CAboutDlg::~CAboutDlg()
{
delete ui;
}

23
map65/about.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef ABOUTDLG_H
#define ABOUTDLG_H
#include <QDialog>
namespace Ui {
class CAboutDlg;
}
class CAboutDlg : public QDialog
{
Q_OBJECT
public:
explicit CAboutDlg(QWidget *parent = nullptr);
~CAboutDlg();
private:
Ui::CAboutDlg *ui;
QString m_Str;
};
#endif // ABOUTDLG_H

37
map65/about.ui Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CAboutDlg</class>
<widget class="QDialog" name="CAboutDlg">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>374</width>
<height>164</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>About MAP65</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labelTxt">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

257
map65/afmhot.dat Normal file
View File

@ -0,0 +1,257 @@
0 0.0000 0.0000 0.0000
1 0.0000 0.0000 0.0000
2 0.0078 0.0000 0.0000
3 0.0157 0.0000 0.0000
4 0.0235 0.0000 0.0000
5 0.0314 0.0000 0.0000
6 0.0392 0.0000 0.0000
7 0.0471 0.0000 0.0000
8 0.0549 0.0000 0.0000
9 0.0627 0.0000 0.0000
10 0.0706 0.0000 0.0000
11 0.0784 0.0000 0.0000
12 0.0863 0.0000 0.0000
13 0.0941 0.0000 0.0000
14 0.1020 0.0000 0.0000
15 0.1098 0.0000 0.0000
16 0.1176 0.0000 0.0000
17 0.1255 0.0000 0.0000
18 0.1333 0.0000 0.0000
19 0.1412 0.0000 0.0000
20 0.1490 0.0000 0.0000
21 0.1569 0.0000 0.0000
22 0.1647 0.0000 0.0000
23 0.1725 0.0000 0.0000
24 0.1804 0.0000 0.0000
25 0.1882 0.0000 0.0000
26 0.1961 0.0000 0.0000
27 0.2039 0.0000 0.0000
28 0.2118 0.0000 0.0000
29 0.2196 0.0000 0.0000
30 0.2275 0.0000 0.0000
31 0.2353 0.0000 0.0000
32 0.2431 0.0000 0.0000
33 0.2510 0.0000 0.0000
34 0.2588 0.0000 0.0000
35 0.2667 0.0000 0.0000
36 0.2745 0.0000 0.0000
37 0.2824 0.0000 0.0000
38 0.2902 0.0000 0.0000
39 0.2980 0.0000 0.0000
40 0.3059 0.0000 0.0000
41 0.3137 0.0000 0.0000
42 0.3216 0.0000 0.0000
43 0.3294 0.0000 0.0000
44 0.3373 0.0000 0.0000
45 0.3451 0.0000 0.0000
46 0.3529 0.0000 0.0000
47 0.3608 0.0000 0.0000
48 0.3686 0.0000 0.0000
49 0.3765 0.0000 0.0000
50 0.3843 0.0000 0.0000
51 0.3922 0.0000 0.0000
52 0.4000 0.0000 0.0000
53 0.4078 0.0000 0.0000
54 0.4157 0.0000 0.0000
55 0.4235 0.0000 0.0000
56 0.4314 0.0000 0.0000
57 0.4392 0.0000 0.0000
58 0.4471 0.0000 0.0000
59 0.4549 0.0000 0.0000
60 0.4627 0.0000 0.0000
61 0.4706 0.0000 0.0000
62 0.4784 0.0000 0.0000
63 0.4863 0.0000 0.0000
64 0.4941 0.0000 0.0000
65 0.5020 0.0000 0.0000
66 0.5098 0.0098 0.0000
67 0.5176 0.0176 0.0000
68 0.5255 0.0255 0.0000
69 0.5333 0.0333 0.0000
70 0.5412 0.0412 0.0000
71 0.5490 0.0490 0.0000
72 0.5569 0.0569 0.0000
73 0.5647 0.0647 0.0000
74 0.5725 0.0725 0.0000
75 0.5804 0.0804 0.0000
76 0.5882 0.0882 0.0000
77 0.5961 0.0961 0.0000
78 0.6039 0.1039 0.0000
79 0.6118 0.1118 0.0000
80 0.6196 0.1196 0.0000
81 0.6275 0.1275 0.0000
82 0.6353 0.1353 0.0000
83 0.6431 0.1431 0.0000
84 0.6510 0.1510 0.0000
85 0.6588 0.1588 0.0000
86 0.6667 0.1667 0.0000
87 0.6745 0.1745 0.0000
88 0.6824 0.1824 0.0000
89 0.6902 0.1902 0.0000
90 0.6980 0.1980 0.0000
91 0.7059 0.2059 0.0000
92 0.7137 0.2137 0.0000
93 0.7216 0.2216 0.0000
94 0.7294 0.2294 0.0000
95 0.7373 0.2373 0.0000
96 0.7451 0.2451 0.0000
97 0.7529 0.2529 0.0000
98 0.7608 0.2608 0.0000
99 0.7686 0.2686 0.0000
100 0.7765 0.2765 0.0000
101 0.7843 0.2843 0.0000
102 0.7922 0.2922 0.0000
103 0.8000 0.3000 0.0000
104 0.8078 0.3078 0.0000
105 0.8157 0.3157 0.0000
106 0.8235 0.3235 0.0000
107 0.8314 0.3314 0.0000
108 0.8392 0.3392 0.0000
109 0.8471 0.3471 0.0000
110 0.8549 0.3549 0.0000
111 0.8627 0.3627 0.0000
112 0.8706 0.3706 0.0000
113 0.8784 0.3784 0.0000
114 0.8863 0.3863 0.0000
115 0.8941 0.3941 0.0000
116 0.9020 0.4020 0.0000
117 0.9098 0.4098 0.0000
118 0.9176 0.4176 0.0000
119 0.9255 0.4255 0.0000
120 0.9333 0.4333 0.0000
121 0.9412 0.4412 0.0000
122 0.9490 0.4490 0.0000
123 0.9569 0.4569 0.0000
124 0.9647 0.4647 0.0000
125 0.9725 0.4725 0.0000
126 0.9804 0.4804 0.0000
127 0.9882 0.4882 0.0000
128 0.9961 0.4961 0.0000
129 1.0000 0.5039 0.0000
130 1.0000 0.5118 0.0118
131 1.0000 0.5196 0.0196
132 1.0000 0.5275 0.0275
133 1.0000 0.5353 0.0353
134 1.0000 0.5431 0.0431
135 1.0000 0.5510 0.0510
136 1.0000 0.5588 0.0588
137 1.0000 0.5667 0.0667
138 1.0000 0.5745 0.0745
139 1.0000 0.5824 0.0824
140 1.0000 0.5902 0.0902
141 1.0000 0.5980 0.0980
142 1.0000 0.6059 0.1059
143 1.0000 0.6137 0.1137
144 1.0000 0.6216 0.1216
145 1.0000 0.6294 0.1294
146 1.0000 0.6373 0.1373
147 1.0000 0.6451 0.1451
148 1.0000 0.6529 0.1529
149 1.0000 0.6608 0.1608
150 1.0000 0.6686 0.1686
151 1.0000 0.6765 0.1765
152 1.0000 0.6843 0.1843
153 1.0000 0.6922 0.1922
154 1.0000 0.7000 0.2000
155 1.0000 0.7078 0.2078
156 1.0000 0.7157 0.2157
157 1.0000 0.7235 0.2235
158 1.0000 0.7314 0.2314
159 1.0000 0.7392 0.2392
160 1.0000 0.7471 0.2471
161 1.0000 0.7549 0.2549
162 1.0000 0.7627 0.2627
163 1.0000 0.7706 0.2706
164 1.0000 0.7784 0.2784
165 1.0000 0.7863 0.2863
166 1.0000 0.7941 0.2941
167 1.0000 0.8020 0.3020
168 1.0000 0.8098 0.3098
169 1.0000 0.8176 0.3176
170 1.0000 0.8255 0.3255
171 1.0000 0.8333 0.3333
172 1.0000 0.8412 0.3412
173 1.0000 0.8490 0.3490
174 1.0000 0.8569 0.3569
175 1.0000 0.8647 0.3647
176 1.0000 0.8725 0.3725
177 1.0000 0.8804 0.3804
178 1.0000 0.8882 0.3882
179 1.0000 0.8961 0.3961
180 1.0000 0.9039 0.4039
181 1.0000 0.9118 0.4118
182 1.0000 0.9196 0.4196
183 1.0000 0.9275 0.4275
184 1.0000 0.9353 0.4353
185 1.0000 0.9431 0.4431
186 1.0000 0.9510 0.4510
187 1.0000 0.9588 0.4588
188 1.0000 0.9667 0.4667
189 1.0000 0.9745 0.4745
190 1.0000 0.9824 0.4824
191 1.0000 0.9902 0.4902
192 1.0000 0.9980 0.4980
193 1.0000 1.0000 0.5059
194 1.0000 1.0000 0.5137
195 1.0000 1.0000 0.5216
196 1.0000 1.0000 0.5294
197 1.0000 1.0000 0.5373
198 1.0000 1.0000 0.5451
199 1.0000 1.0000 0.5529
200 1.0000 1.0000 0.5608
201 1.0000 1.0000 0.5686
202 1.0000 1.0000 0.5765
203 1.0000 1.0000 0.5843
204 1.0000 1.0000 0.5922
205 1.0000 1.0000 0.6000
206 1.0000 1.0000 0.6078
207 1.0000 1.0000 0.6157
208 1.0000 1.0000 0.6235
209 1.0000 1.0000 0.6314
210 1.0000 1.0000 0.6392
211 1.0000 1.0000 0.6471
212 1.0000 1.0000 0.6549
213 1.0000 1.0000 0.6627
214 1.0000 1.0000 0.6706
215 1.0000 1.0000 0.6784
216 1.0000 1.0000 0.6863
217 1.0000 1.0000 0.6941
218 1.0000 1.0000 0.7020
219 1.0000 1.0000 0.7098
220 1.0000 1.0000 0.7176
221 1.0000 1.0000 0.7255
222 1.0000 1.0000 0.7333
223 1.0000 1.0000 0.7412
224 1.0000 1.0000 0.7490
225 1.0000 1.0000 0.7569
226 1.0000 1.0000 0.7647
227 1.0000 1.0000 0.7725
228 1.0000 1.0000 0.7804
229 1.0000 1.0000 0.7882
230 1.0000 1.0000 0.7961
231 1.0000 1.0000 0.8039
232 1.0000 1.0000 0.8118
233 1.0000 1.0000 0.8196
234 1.0000 1.0000 0.8275
235 1.0000 1.0000 0.8353
236 1.0000 1.0000 0.8431
237 1.0000 1.0000 0.8510
238 1.0000 1.0000 0.8588
239 1.0000 1.0000 0.8667
240 1.0000 1.0000 0.8745
241 1.0000 1.0000 0.8824
242 1.0000 1.0000 0.8902
243 1.0000 1.0000 0.8980
244 1.0000 1.0000 0.9059
245 1.0000 1.0000 0.9137
246 1.0000 1.0000 0.9216
247 1.0000 1.0000 0.9294
248 1.0000 1.0000 0.9373
249 1.0000 1.0000 0.9451
250 1.0000 1.0000 0.9529
251 1.0000 1.0000 0.9608
252 1.0000 1.0000 0.9686
253 1.0000 1.0000 0.9765
254 1.0 0.0 0.0
255 1.0 1.0 0.0
256 0.0 1.000 0.0

122
map65/astro.cpp Normal file
View File

@ -0,0 +1,122 @@
#include "astro.h"
#include <QSettings>
#include "ui_astro.h"
#include <QDebug>
#include <QFile>
#include <QMessageBox>
#include <stdio.h>
#include "SettingsGroup.hpp"
#include "commons.h"
extern "C" {
void astrosub_ (int* nyear, int* month, int* nday, double* uth, int* nfreq,
const char* mygrid, const char* hisgrid, double* azsun,
double* elsun, double* azmoon, double* elmoon, double* azmoondx,
double* elmoondx, int* ntsky, int* ndop, int* ndop00,
double* ramoon, double* decmoon, double* dgrd, double* poloffset,
double* xnr, int len1, int len2);
}
Astro::Astro (QString const& settings_filename, QWidget *parent) :
QWidget(parent),
ui(new Ui::Astro),
m_settings_filename {settings_filename}
{
ui->setupUi (this);
setWindowTitle ("Astronomical Data");
setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint);
QSettings settings {m_settings_filename, QSettings::IniFormat};
SettingsGroup g {&settings, "MainWindow"}; // MainWindow group for
// historical reasons
setGeometry (settings.value ("AstroGeom", QRect {71, 390, 227, 403}).toRect ());
ui->astroTextBrowser->setStyleSheet(
"QTextBrowser { background-color : cyan; color : black; }");
ui->astroTextBrowser->clear();
m_AzElDir0="";
}
Astro::~Astro()
{
QSettings settings {m_settings_filename, QSettings::IniFormat};
SettingsGroup g {&settings, "MainWindow"};
settings.setValue ("AstroGeom", geometry ());
delete ui;
}
void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid,
int fQSO, int nsetftx, int ntxFreq, QString azelDir)
{
static int ntxFreq0=-99;
char cc[300];
double azsun,elsun,azmoon,elmoon,azmoondx,elmoondx;
double ramoon,decmoon,dgrd,poloffset,xnr;
int ntsky,ndop,ndop00;
QString date = t.date().toString("yyyy MMM dd");
QString utc = t.time().toString();
int nyear=t.date().year();
int month=t.date().month();
int nday=t.date().day();
int nhr=t.time().hour();
int nmin=t.time().minute();
double sec=t.time().second() + 0.001*t.time().msec();
int isec=sec;
double uth=nhr + nmin/60.0 + sec/3600.0;
int nfreq=(int)datcom_.fcenter;
if(nfreq<10 or nfreq > 50000) nfreq=144;
astrosub_(&nyear, &month, &nday, &uth, &nfreq, mygrid.toLatin1(),
hisgrid.toLatin1(), &azsun, &elsun, &azmoon, &elmoon,
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00,&ramoon, &decmoon,
&dgrd, &poloffset, &xnr, 6, 6);
sprintf(cc,
"Az: %6.1f\n"
"El: %6.1f\n"
"MyDop: %6d\n"
"DxAz: %6.1f\n"
"DxEl: %6.1f\n"
"DxDop: %6d\n"
"Dec: %6.1f\n"
"SunAz: %6.1f\n"
"SunEl: %6.1f\n"
"Tsky: %6d\n"
"MNR: %6.1f\n"
"Dgrd: %6.1f",
azmoon,elmoon,ndop00,azmoondx,elmoondx,ndop,decmoon,azsun,elsun,
ntsky,xnr,dgrd);
ui->astroTextBrowser->setText(" "+ date + "\nUTC: " + utc + "\n" + cc);
QString fname=azelDir+"/azel.dat";
QFile f(fname);
if(!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
if(azelDir==m_AzElDir0) return;
m_AzElDir0=azelDir;
QMessageBox mb;
mb.setText("Cannot open " + fname + "\nCorrect the setting of AzEl Directory in Setup?");
mb.exec();
return;
}
int ndiff=0;
if(ntxFreq != ntxFreq0) ndiff=1;
ntxFreq0=ntxFreq;
QTextStream out(&f);
sprintf(cc,"%2.2d:%2.2d:%2.2d,%5.1f,%5.1f,Moon\n"
"%2.2d:%2.2d:%2.2d,%5.1f,%5.1f,Sun\n"
"%2.2d:%2.2d:%2.2d,%5.1f,%5.1f,Source\n"
"%4d,%6d,Doppler\n"
"%3d,%1d,fQSO\n"
"%3d,%1d,fQSO2\n",
nhr,nmin,isec,azmoon,elmoon,
nhr,nmin,isec,azsun,elsun,
nhr,nmin,isec,0.0,0.0,
nfreq,ndop,
fQSO,nsetftx,
ntxFreq,ndiff);
out << cc;
f.close();
}
void Astro::setFontSize(int n)
{
ui->astroTextBrowser->setFontPointSize(n);
}

28
map65/astro.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef ASTRO_H
#define ASTRO_H
#include <QWidget>
#include <QDateTime>
namespace Ui {
class Astro;
}
class Astro : public QWidget
{
Q_OBJECT
public:
explicit Astro (QString const& settings_filename, QWidget *parent = 0);
void astroUpdate(QDateTime t, QString mygrid, QString hisgrid,
int fQSO, int nsetftx, int ntxFreq, QString azelDir);
void setFontSize(int n);
~Astro ();
private:
Ui::Astro *ui;
QString m_settings_filename;
QString m_AzElDir0;
};
#endif

37
map65/astro.ui Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Astro</class>
<widget class="QWidget" name="Astro">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>262</width>
<height>483</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QTextBrowser" name="astroTextBrowser">
<property name="geometry">
<rect>
<x>0</x>
<y>10</y>
<width>256</width>
<height>451</height>
</rect>
</property>
<property name="font">
<font>
<family>Courier New</family>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

100
map65/bandmap.cpp Normal file
View File

@ -0,0 +1,100 @@
#include "bandmap.h"
#include <QSettings>
#include "ui_bandmap.h"
#include "qt_helpers.hpp"
#include "SettingsGroup.hpp"
#include <QDebug>
BandMap::BandMap (QString const& settings_filename, QWidget * parent)
: QWidget {parent},
ui {new Ui::BandMap},
m_settings_filename {settings_filename}
{
ui->setupUi (this);
setWindowTitle ("Band Map");
setWindowFlags (Qt::Dialog | Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint);
QSettings settings {m_settings_filename, QSettings::IniFormat};
SettingsGroup g {&settings, "MainWindow"}; // MainWindow group for
// historical reasons
setGeometry (settings.value ("BandMapGeom", QRect {280, 400, 142, 400}).toRect ());
ui->bmTextBrowser->setStyleSheet(
"QTextBrowser { background-color : #000066; color : red; }");
}
BandMap::~BandMap ()
{
QSettings settings {m_settings_filename, QSettings::IniFormat};
SettingsGroup g {&settings, "MainWindow"};
settings.setValue ("BandMapGeom", geometry ());
delete ui;
}
void BandMap::setText(QString t)
{
m_bandMapText=t;
int w=ui->bmTextBrowser->size().width();
int ncols=1;
if(w>220) ncols=2;
QString s="QTextBrowser{background-color: "+m_colorBackground+"}";
ui->bmTextBrowser->setStyleSheet(s);
QString t0="<html style=\" font-family:'Courier New';"
"font-size:9pt; background-color:#000066\">"
"<table border=0 cellspacing=7><tr><td>\n";
QString tfreq,tspace,tcall;
QString s0,s1,s2,s3,bg;
bg="<span style=color:"+m_colorBackground+";>.</span>";
s0="<span style=color:"+m_color0+";>";
s1="<span style=color:"+m_color1+";>";
s2="<span style=color:"+m_color2+";>";
s3="<span style=color:"+m_color3+";>";
ui->bmTextBrowser->clear();
QStringList lines = t.split( "\n", SkipEmptyParts );
int nrows=(lines.length()+ncols-1)/ncols;
for(int i=0; i<nrows; i++) {
tfreq=lines[i].mid(0,3);
tspace=lines[i].mid(4,1);
if(tspace==" ") tspace=bg;
tcall=lines[i].mid(5,7);
int n=lines[i].mid(13,1).toInt();
if(n==0) t0 += s0;
if(n==1) t0 += s1;
if(n==2) t0 += s2;
if(n>=3) t0 += s3;
t0 += (tfreq + tspace + tcall + "</span><br>\n");
}
if(ncols==2) { //2-column display
t0 += "<td><br><td>\n";
for(int i=nrows; i<lines.length(); i++) {
tfreq=lines[i].mid(0,3);
tspace=lines[i].mid(4,1);
if(tspace==" ") tspace=bg;
tcall=lines[i].mid(5,7);
int n=lines[i].mid(13,1).toInt();
if(n==0) t0 += s0;
if(n==1) t0 += s1;
if(n==2) t0 += s2;
if(n>=3) t0 += s3;
t0 += (tfreq + tspace + tcall + "</span><br>\n");
}
if(2*nrows>lines.length()) t0 += (s0 + "</span><br>\n");
}
ui->bmTextBrowser->setHtml(t0);
}
void BandMap::resizeEvent(QResizeEvent* )
{
setText(m_bandMapText);
}
void BandMap::setColors(QString t)
{
m_colorBackground = "#"+t.mid(0,6);
m_color0 = "#"+t.mid(6,6);
m_color1 = "#"+t.mid(12,6);
m_color2 = "#"+t.mid(18,6);
m_color3 = "#"+t.mid(24,6);
setText(m_bandMapText);
}

35
map65/bandmap.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef BANDMAP_H
#define BANDMAP_H
#include <QWidget>
namespace Ui {
class BandMap;
}
class BandMap : public QWidget
{
Q_OBJECT
public:
explicit BandMap (QString const& settings_filename, QWidget *parent = 0);
void setText(QString t);
void setColors(QString t);
~BandMap();
protected:
void resizeEvent(QResizeEvent* event);
private:
Ui::BandMap *ui;
QString m_settings_filename;
QString m_bandMapText;
QString m_colorBackground;
QString m_color0;
QString m_color1;
QString m_color2;
QString m_color3;
};
#endif

43
map65/bandmap.ui Normal file
View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BandMap</class>
<widget class="QWidget" name="BandMap">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>329</width>
<height>379</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTextBrowser" name="bmTextBrowser">
<property name="minimumSize">
<size>
<width>107</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<family>Courier New</family>
<pointsize>9</pointsize>
</font>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

256
map65/blue.dat Normal file
View File

@ -0,0 +1,256 @@
0 0.0000 0.0000 0.0000
1 0.0902 0.0902 0.2558
2 0.1176 0.1176 0.2694
3 0.1412 0.1412 0.2820
4 0.1569 0.1569 0.2938
5 0.1725 0.1725 0.3049
6 0.1843 0.1843 0.3154
7 0.1961 0.1961 0.3254
8 0.2039 0.2039 0.3349
9 0.2157 0.2157 0.3440
10 0.2235 0.2235 0.3528
11 0.2314 0.2314 0.3612
12 0.2392 0.2392 0.3693
13 0.2471 0.2471 0.3772
14 0.2549 0.2549 0.3848
15 0.2588 0.2588 0.3921
16 0.2667 0.2667 0.3992
17 0.2706 0.2706 0.4061
18 0.2784 0.2784 0.4129
19 0.2824 0.2824 0.4194
20 0.2902 0.2902 0.4258
21 0.2941 0.2941 0.4319
22 0.2980 0.2980 0.4380
23 0.3059 0.3059 0.4439
24 0.3098 0.3098 0.4496
25 0.3137 0.3137 0.4553
26 0.3176 0.3176 0.4608
27 0.3216 0.3216 0.4661
28 0.3294 0.3294 0.4714
29 0.3333 0.3333 0.4765
30 0.3373 0.3373 0.4815
31 0.3412 0.3412 0.4865
32 0.3451 0.3451 0.4913
33 0.3490 0.3490 0.4960
34 0.3529 0.3529 0.5006
35 0.3569 0.3569 0.5052
36 0.3608 0.3608 0.5096
37 0.3647 0.3647 0.5140
38 0.3686 0.3686 0.5183
39 0.3725 0.3725 0.5225
40 0.3765 0.3765 0.5266
41 0.3804 0.3804 0.5306
42 0.3843 0.3843 0.5346
43 0.3843 0.3843 0.5385
44 0.3882 0.3882 0.5423
45 0.3922 0.3922 0.5460
46 0.3961 0.3961 0.5497
47 0.4000 0.4000 0.5533
48 0.4039 0.4039 0.5569
49 0.4078 0.4078 0.5603
50 0.4118 0.4118 0.5638
51 0.4118 0.4118 0.5671
52 0.4157 0.4157 0.5704
53 0.4196 0.4196 0.5736
54 0.4235 0.4235 0.5768
55 0.4275 0.4275 0.5799
56 0.4314 0.4314 0.5829
57 0.4314 0.4314 0.5859
58 0.4353 0.4353 0.5889
59 0.4392 0.4392 0.5917
60 0.4431 0.4431 0.5946
61 0.4471 0.4471 0.5973
62 0.4471 0.4471 0.6001
63 0.4510 0.4510 0.6027
64 0.4549 0.4549 0.6053
65 0.4588 0.4588 0.6079
66 0.4627 0.4627 0.6104
67 0.4627 0.4627 0.6129
68 0.4667 0.4667 0.6153
69 0.4706 0.4706 0.6176
70 0.4745 0.4745 0.6199
71 0.4745 0.4745 0.6222
72 0.4784 0.4784 0.6244
73 0.4824 0.4824 0.6266
74 0.4863 0.4863 0.6287
75 0.4863 0.4863 0.6308
76 0.4902 0.4902 0.6328
77 0.4941 0.4941 0.6348
78 0.4980 0.4980 0.6367
79 0.5020 0.5020 0.6386
80 0.5020 0.5020 0.6404
81 0.5059 0.5059 0.6422
82 0.5098 0.5098 0.6440
83 0.5098 0.5098 0.6457
84 0.5137 0.5137 0.6474
85 0.5176 0.5176 0.6490
86 0.5216 0.5216 0.6506
87 0.5216 0.5216 0.6521
88 0.5255 0.5255 0.6536
89 0.5294 0.5294 0.6551
90 0.5333 0.5333 0.6565
91 0.5333 0.5333 0.6578
92 0.5373 0.5373 0.6591
93 0.5412 0.5412 0.6604
94 0.5451 0.5451 0.6617
95 0.5451 0.5451 0.6629
96 0.5490 0.5490 0.6640
97 0.5529 0.5529 0.6651
98 0.5569 0.5569 0.6662
99 0.5569 0.5569 0.6672
100 0.5608 0.5608 0.6682
101 0.5647 0.5647 0.6692
102 0.5647 0.5647 0.6701
103 0.5686 0.5686 0.6710
104 0.5725 0.5725 0.6718
105 0.5765 0.5765 0.6726
106 0.5765 0.5765 0.6733
107 0.5804 0.5804 0.6740
108 0.5843 0.5843 0.6747
109 0.5843 0.5843 0.6753
110 0.5882 0.5882 0.6759
111 0.5922 0.5922 0.6765
112 0.5961 0.5961 0.6770
113 0.5961 0.5961 0.6774
114 0.6000 0.6000 0.6779
115 0.6039 0.6039 0.6783
116 0.6039 0.6039 0.6786
117 0.6078 0.6078 0.6789
118 0.6118 0.6118 0.6792
119 0.6157 0.6157 0.6794
120 0.6157 0.6157 0.6796
121 0.6196 0.6196 0.6798
122 0.6235 0.6235 0.6799
123 0.6235 0.6235 0.6800
124 0.6275 0.6275 0.6800
125 0.6314 0.6314 0.6800
126 0.6353 0.6353 0.6799
127 0.6353 0.6353 0.6799
128 0.6392 0.6392 0.6797
129 0.6431 0.6431 0.6796
130 0.6431 0.6431 0.6794
131 0.6471 0.6471 0.6791
132 0.6510 0.6510 0.6789
133 0.6549 0.6549 0.6785
134 0.6549 0.6549 0.6782
135 0.6588 0.6588 0.6778
136 0.6627 0.6627 0.6773
137 0.6627 0.6627 0.6769
138 0.6667 0.6667 0.6763
139 0.6706 0.6706 0.6758
140 0.6745 0.6745 0.6752
141 0.6745 0.6745 0.6746
142 0.6784 0.6784 0.6739
143 0.6824 0.6824 0.6732
144 0.6824 0.6824 0.6724
145 0.6863 0.6863 0.6716
146 0.6902 0.6902 0.6708
147 0.6941 0.6941 0.6699
148 0.6941 0.6941 0.6690
149 0.6980 0.6980 0.6680
150 0.7020 0.7020 0.6670
151 0.7020 0.7020 0.6660
152 0.7059 0.7059 0.6649
153 0.7098 0.7098 0.6638
154 0.7098 0.7098 0.6626
155 0.7137 0.7137 0.6614
156 0.7176 0.7176 0.6601
157 0.7216 0.7216 0.6589
158 0.7216 0.7216 0.6575
159 0.7255 0.7255 0.6561
160 0.7294 0.7294 0.6547
161 0.7294 0.7294 0.6533
162 0.7333 0.7333 0.6518
163 0.7373 0.7373 0.6502
164 0.7412 0.7412 0.6486
165 0.7412 0.7412 0.6470
166 0.7451 0.7451 0.6453
167 0.7490 0.7490 0.6436
168 0.7490 0.7490 0.6418
169 0.7529 0.7529 0.6400
170 0.7569 0.7569 0.6382
171 0.7608 0.7608 0.6363
172 0.7608 0.7608 0.6343
173 0.7647 0.7647 0.6324
174 0.7686 0.7686 0.6303
175 0.7686 0.7686 0.6282
176 0.7725 0.7725 0.6261
177 0.7765 0.7765 0.6239
178 0.7804 0.7804 0.6217
179 0.7804 0.7804 0.6194
180 0.7843 0.7843 0.6171
181 0.7882 0.7882 0.6147
182 0.7882 0.7882 0.6123
183 0.7922 0.7922 0.6098
184 0.7961 0.7961 0.6073
185 0.8000 0.8000 0.6047
186 0.8000 0.8000 0.6021
187 0.8039 0.8039 0.5994
188 0.8078 0.8078 0.5967
189 0.8078 0.8078 0.5939
190 0.8118 0.8118 0.5911
191 0.8157 0.8157 0.5882
192 0.8196 0.8196 0.5853
193 0.8196 0.8196 0.5823
194 0.8235 0.8235 0.5792
195 0.8275 0.8275 0.5761
196 0.8275 0.8275 0.5729
197 0.8314 0.8314 0.5697
198 0.8353 0.8353 0.5664
199 0.8392 0.8392 0.5630
200 0.8392 0.8392 0.5596
201 0.8431 0.8431 0.5561
202 0.8471 0.8471 0.5525
203 0.8471 0.8471 0.5489
204 0.8510 0.8510 0.5452
205 0.8549 0.8549 0.5414
206 0.8588 0.8588 0.5376
207 0.8588 0.8588 0.5337
208 0.8627 0.8627 0.5297
209 0.8667 0.8667 0.5257
210 0.8667 0.8667 0.5215
211 0.8706 0.8706 0.5173
212 0.8745 0.8745 0.5130
213 0.8784 0.8784 0.5086
214 0.8784 0.8784 0.5042
215 0.8824 0.8824 0.4996
216 0.8863 0.8863 0.4950
217 0.8863 0.8863 0.4902
218 0.8902 0.8902 0.4854
219 0.8941 0.8941 0.4804
220 0.8980 0.8980 0.4754
221 0.8980 0.8980 0.4702
222 0.9020 0.9020 0.4649
223 0.9059 0.9059 0.4595
224 0.9098 0.9098 0.4540
225 0.9098 0.9098 0.4484
226 0.9137 0.9137 0.4426
227 0.9176 0.9176 0.4366
228 0.9176 0.9176 0.4306
229 0.9216 0.9216 0.4243
230 0.9255 0.9255 0.4179
231 0.9294 0.9294 0.4114
232 0.9294 0.9294 0.4046
233 0.9333 0.9333 0.3977
234 0.9373 0.9373 0.3905
235 0.9373 0.9373 0.3831
236 0.9412 0.9412 0.3754
237 0.9451 0.9451 0.3675
238 0.9490 0.9490 0.3594
239 0.9490 0.9490 0.3509
240 0.9529 0.9529 0.3420
241 0.9569 0.9569 0.3328
242 0.9608 0.9608 0.3232
243 0.9608 0.9608 0.3131
244 0.9647 0.9647 0.3024
245 0.9686 0.9686 0.2912
246 0.9686 0.9686 0.2792
247 0.9725 0.9725 0.2664
248 0.9765 0.9765 0.2526
249 0.9804 0.9804 0.2375
250 0.9804 0.9804 0.2208
251 0.9843 0.9843 0.2020
252 0.9882 0.9882 0.1800
253 1.0 0.0 0.0
254 1.0 1.0 0.0
255 0.0 1.000 0.0

45
map65/commons.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef COMMONS_H
#define COMMONS_H
#define NFFT 32768
extern "C" {
extern struct { //This is "common/datcom/..." in Fortran
float d4[4*5760000]; //Raw I/Q data from Linrad
float ss[4*322*NFFT]; //Half-symbol spectra at 0,45,90,135 deg pol
float savg[4*NFFT]; //Avg spectra at 0,45,90,135 deg pol
double fcenter; //Center freq from Linrad (MHz)
int nutc; //UTC as integer, HHMM
int idphi; //Phase correction for Y pol'n, degrees
int mousedf; //User-selected DF
int mousefqso; //User-selected QSO freq (kHz)
int nagain; //1 ==> decode only at fQSO +/- Tol
int ndepth; //How much hinted decoding to do?
int ndiskdat; //1 ==> data read from *.tf2 or *.iq file
int neme; //Hinted decoding tries only for EME calls
int newdat; //1 ==> new data, must do long FFT
int nfa; //Low decode limit (kHz)
int nfb; //High decode limit (kHz)
int nfcal; //Frequency correction, for calibration (Hz)
int nfshift; //Shift of displayed center freq (kHz)
int mcall3; //1 ==> CALL3.TXT has been modified
int ntimeout; //Max for timeouts in Messages and BandMap
int ntol; //+/- decoding range around fQSO (Hz)
int nxant; //1 ==> add 45 deg to measured pol angle
int map65RxLog; //Flags to control log files
int nfsample; //Input sample rate
int nxpol; //1 if using xpol antennas, 0 otherwise
int nmode; //nmode = 10*m_modeQ65 + m_modeJT65
int nfast; //No longer used
int nsave; //Number of s3(64,63) spectra saved
int max_drift; //Maximum Q65 drift: units symbol_rate/TxT
char mycall[12];
char mygrid[6];
char hiscall[12];
char hisgrid[6];
char datetime[20];
} datcom_;
}
#endif // COMMONS_H

384
map65/devsetup.cpp Normal file
View File

@ -0,0 +1,384 @@
#include "devsetup.h"
#include "mainwindow.h"
#include <QTextStream>
#include <QDebug>
#include <cstdio>
#include <portaudio.h>
#define MAXDEVICES 200
//----------------------------------------------------------- DevSetup()
DevSetup::DevSetup(QWidget *parent) : QDialog(parent)
{
ui.setupUi(this); //setup the dialog form
m_restartSoundIn=false;
m_restartSoundOut=false;
}
DevSetup::~DevSetup()
{
}
void DevSetup::initDlg()
{
int k,id;
int valid_devices=0;
int minChan[MAXDEVICES];
int maxChan[MAXDEVICES];
int minSpeed[MAXDEVICES];
int maxSpeed[MAXDEVICES];
char hostAPI_DeviceName[MAXDEVICES][50];
char s[256];
int numDevices=Pa_GetDeviceCount();
getDev(&numDevices,hostAPI_DeviceName,minChan,maxChan,minSpeed,maxSpeed);
k=0;
for(id=0; id<numDevices; id++) {
if(96000 >= minSpeed[id] && 96000 <= maxSpeed[id]) {
m_inDevList[k]=id;
k++;
sprintf(s,"%2d %d %-49s",id,maxChan[id],hostAPI_DeviceName[id]);
QString t(s);
ui.comboBoxSndIn->addItem(t);
valid_devices++;
}
}
const PaDeviceInfo *pdi;
int nchout;
char *p,*p1;
char p2[256];
char pa_device_name[128];
char pa_device_hostapi[128];
k=0;
for(id=0; id<numDevices; id++ ) {
pdi=Pa_GetDeviceInfo(id);
nchout=pdi->maxOutputChannels;
if(nchout>=2) {
m_outDevList[k]=id;
k++;
sprintf((char*)(pa_device_name),"%s",pdi->name);
sprintf((char*)(pa_device_hostapi),"%s",
Pa_GetHostApiInfo(pdi->hostApi)->name);
p1=(char*)"";
p=strstr(pa_device_hostapi,"MME");
if(p!=NULL) p1=(char*)"MME";
p=strstr(pa_device_hostapi,"Direct");
if(p!=NULL) p1=(char*)"DirectX";
p=strstr(pa_device_hostapi,"WASAPI");
if(p!=NULL) p1=(char*)"WASAPI";
p=strstr(pa_device_hostapi,"ASIO");
if(p!=NULL) p1=(char*)"ASIO";
p=strstr(pa_device_hostapi,"WDM-KS");
if(p!=NULL) p1=(char*)"WDM-KS";
sprintf(p2,"%2d %-8s %-39s",id,p1,pa_device_name);
QString t(p2);
ui.comboBoxSndOut->addItem(t);
}
}
ui.myCallEntry->setText(m_myCall);
ui.myGridEntry->setText(m_myGrid);
ui.idIntSpinBox->setValue(m_idInt);
ui.pttComboBox->setCurrentIndex(m_pttPort);
ui.astroFont->setValue(m_astroFont);
ui.cbXpol->setChecked(m_xpol);
ui.rbAntennaX->setChecked(m_xpolx);
ui.saveDirEntry->setText(m_saveDir);
ui.azelDirEntry->setText(m_azelDir);
ui.editorEntry->setText(m_editorCommand);
ui.dxccEntry->setText(m_dxccPfx);
ui.timeoutSpinBox->setValue(m_timeout);
ui.dPhiSpinBox->setValue(m_dPhi);
ui.fCalSpinBox->setValue(m_fCal);
ui.faddEntry->setText(QString::number(m_fAdd,'f',3));
ui.networkRadioButton->setChecked(m_network);
ui.soundCardRadioButton->setChecked(!m_network);
ui.rb96000->setChecked(m_fs96000);
ui.rb95238->setChecked(!m_fs96000);
ui.rbIQXT->setChecked(m_bIQxt);
ui.rbSi570->setChecked(!m_bIQxt);
ui.mult570TxSpinBox->setEnabled(m_bIQxt);
ui.comboBoxSndIn->setEnabled(!m_network);
ui.comboBoxSndIn->setCurrentIndex(m_nDevIn);
ui.comboBoxSndOut->setCurrentIndex(m_nDevOut);
ui.sbPort->setValue(m_udpPort);
ui.cbIQswap->setChecked(m_IQswap);
ui.cb10db->setChecked(m_10db);
ui.cbInitIQplus->setChecked(m_initIQplus);
ui.mult570SpinBox->setValue(m_mult570);
ui.mult570TxSpinBox->setValue(m_mult570Tx);
ui.cal570SpinBox->setValue(m_cal570);
ui.sbTxOffset->setValue(m_TxOffset);
::sscanf (m_colors.toLatin1(),"%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
&r,&g,&b,&r0,&g0,&b0,&r1,&g1,&b1,&r2,&g2,&b2,&r3,&g3,&b3);
updateColorLabels();
ui.sbBackgroundRed->setValue(r);
ui.sbBackgroundGreen->setValue(g);
ui.sbBackgroundBlue->setValue(b);
ui.sbRed0->setValue(r0);
ui.sbRed1->setValue(r1);
ui.sbRed2->setValue(r2);
ui.sbRed3->setValue(r3);
ui.sbGreen0->setValue(g0);
ui.sbGreen1->setValue(g1);
ui.sbGreen2->setValue(g2);
ui.sbGreen3->setValue(g3);
ui.sbBlue0->setValue(b0);
ui.sbBlue1->setValue(b1);
ui.sbBlue2->setValue(b2);
ui.sbBlue3->setValue(b3);
m_paInDevice=m_inDevList[m_nDevIn];
m_paOutDevice=m_outDevList[m_nDevOut];
}
//------------------------------------------------------- accept()
void DevSetup::accept()
{
// Called when OK button is clicked.
// Check to see whether SoundInThread must be restarted,
// and save user parameters.
if(m_network!=ui.networkRadioButton->isChecked() or
m_nDevIn!=ui.comboBoxSndIn->currentIndex() or
m_paInDevice!=m_inDevList[m_nDevIn] or
m_xpol!=ui.cbXpol->isChecked() or
m_udpPort!=ui.sbPort->value()) m_restartSoundIn=true;
if(m_nDevOut!=ui.comboBoxSndOut->currentIndex() or
m_paOutDevice!=m_outDevList[m_nDevOut]) m_restartSoundOut=true;
m_myCall=ui.myCallEntry->text();
m_myGrid=ui.myGridEntry->text();
m_idInt=ui.idIntSpinBox->value();
m_pttPort=ui.pttComboBox->currentIndex();
m_astroFont=ui.astroFont->value();
m_xpol=ui.cbXpol->isChecked();
m_xpolx=ui.rbAntennaX->isChecked();
m_saveDir=ui.saveDirEntry->text();
m_azelDir=ui.azelDirEntry->text();
m_editorCommand=ui.editorEntry->text();
m_dxccPfx=ui.dxccEntry->text();
m_timeout=ui.timeoutSpinBox->value();
m_dPhi=ui.dPhiSpinBox->value();
m_fCal=ui.fCalSpinBox->value();
m_fAdd=ui.faddEntry->text().toDouble();
m_network=ui.networkRadioButton->isChecked();
m_fs96000=ui.rb96000->isChecked();
m_bIQxt=ui.rbIQXT->isChecked();
m_nDevIn=ui.comboBoxSndIn->currentIndex();
m_paInDevice=m_inDevList[m_nDevIn];
m_nDevOut=ui.comboBoxSndOut->currentIndex();
m_paOutDevice=m_outDevList[m_nDevOut];
m_udpPort=ui.sbPort->value();
m_IQswap=ui.cbIQswap->isChecked();
m_10db=ui.cb10db->isChecked();
m_initIQplus=ui.cbInitIQplus->isChecked();
m_mult570=ui.mult570SpinBox->value();
m_mult570Tx=ui.mult570TxSpinBox->value();
m_cal570=ui.cal570SpinBox->value();
m_TxOffset=ui.sbTxOffset->value();
QDialog::accept();
}
void DevSetup::on_soundCardRadioButton_toggled(bool checked)
{
ui.comboBoxSndIn->setEnabled(ui.soundCardRadioButton->isChecked());
ui.rb96000->setChecked(checked);
ui.rb95238->setEnabled(!checked);
ui.label_InputDev->setEnabled(checked);
ui.label_Port->setEnabled(!checked);
ui.sbPort->setEnabled(!checked);
ui.cbIQswap->setEnabled(checked);
ui.cb10db->setEnabled(checked);
}
void DevSetup::on_cbXpol_stateChanged(int n)
{
m_xpol = (n!=0);
ui.rbAntenna->setEnabled(m_xpol);
ui.rbAntennaX->setEnabled(m_xpol);
ui.dPhiSpinBox->setEnabled(m_xpol);
ui.labelDphi->setEnabled(m_xpol);
}
void DevSetup::on_cal570SpinBox_valueChanged(double ppm)
{
m_cal570=ppm;
}
void DevSetup::on_mult570SpinBox_valueChanged(int mult)
{
m_mult570=mult;
}
void DevSetup::updateColorLabels()
{
QString t;
int r=ui.sbBackgroundRed->value();
int g=ui.sbBackgroundGreen->value();
int b=ui.sbBackgroundBlue->value();
int r0=ui.sbRed0->value();
int r1=ui.sbRed1->value();
int r2=ui.sbRed2->value();
int r3=ui.sbRed3->value();
int g0=ui.sbGreen0->value();
int g1=ui.sbGreen1->value();
int g2=ui.sbGreen2->value();
int g3=ui.sbGreen3->value();
int b0=ui.sbBlue0->value();
int b1=ui.sbBlue1->value();
int b2=ui.sbBlue2->value();
int b3=ui.sbBlue3->value();
ui.lab0->setStyleSheet (
QString {"QLabel{background-color: #%1%2%3; color: #%4%5%6}"}
.arg (r, 2, 16, QLatin1Char {'0'})
.arg (g, 2, 16, QLatin1Char {'0'})
.arg (b, 2, 16, QLatin1Char {'0'})
.arg (r0, 2, 16, QLatin1Char {'0'})
.arg (g0, 2, 16, QLatin1Char {'0'})
.arg (b0, 2, 16, QLatin1Char {'0'})
);
ui.lab1->setStyleSheet(
QString {"QLabel{background-color: #%1%2%3; color: #%4%5%6}"}
.arg (r, 2, 16, QLatin1Char {'0'})
.arg (g, 2, 16, QLatin1Char {'0'})
.arg (b, 2, 16, QLatin1Char {'0'})
.arg (r1, 2, 16, QLatin1Char {'0'})
.arg (g1, 2, 16, QLatin1Char {'0'})
.arg (b1, 2, 16, QLatin1Char {'0'})
);
ui.lab2->setStyleSheet(
QString {"QLabel{background-color: #%1%2%3; color: #%4%5%6}"}
.arg (r, 2, 16, QLatin1Char {'0'})
.arg (g, 2, 16, QLatin1Char {'0'})
.arg (b, 2, 16, QLatin1Char {'0'})
.arg (r2, 2, 16, QLatin1Char {'0'})
.arg (g2, 2, 16, QLatin1Char {'0'})
.arg (b2, 2, 16, QLatin1Char {'0'})
);
ui.lab3->setStyleSheet(
QString {"QLabel{background-color: #%1%2%3; color: #%4%5%6}"}
.arg (r, 2, 16, QLatin1Char {'0'})
.arg (g, 2, 16, QLatin1Char {'0'})
.arg (b, 2, 16, QLatin1Char {'0'})
.arg (r3, 2, 16, QLatin1Char {'0'})
.arg (g3, 2, 16, QLatin1Char {'0'})
.arg (b3, 2, 16, QLatin1Char {'0'})
);
m_colors.clear ();
QTextStream ots {&m_colors, QIODevice::WriteOnly};
ots.setIntegerBase (16);
ots.setFieldWidth (2);
ots.setPadChar ('0');
ots << r << g << b << r0 << g0 << b0 << r1 << g1 << b1 << r2 << g2 << b2 << r3 << g3 << b3;
}
void DevSetup::on_sbBackgroundRed_valueChanged(int /*r*/)
{
updateColorLabels();
}
void DevSetup::on_sbBackgroundGreen_valueChanged(int /*g*/)
{
updateColorLabels();
}
void DevSetup::on_sbBackgroundBlue_valueChanged(int /*b*/)
{
updateColorLabels();
}
void DevSetup::on_sbRed0_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbGreen0_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbBlue0_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbRed1_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbGreen1_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbBlue1_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbRed2_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbGreen2_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbBlue2_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbRed3_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbGreen3_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_sbBlue3_valueChanged(int /*arg1*/)
{
updateColorLabels();
}
void DevSetup::on_pushButton_5_clicked()
{
QColor color = QColorDialog::getColor(Qt::green, this);
if (color.isValid()) {
}
}
void DevSetup::on_mult570TxSpinBox_valueChanged(int n)
{
m_mult570Tx=n;
}
void DevSetup::on_rbIQXT_toggled(bool checked)
{
m_bIQxt=checked;
ui.mult570TxSpinBox->setEnabled(m_bIQxt);
ui.label_25->setEnabled(m_bIQxt);
ui.sbTxOffset->setEnabled(m_bIQxt);
ui.label_26->setEnabled(m_bIQxt);
}
void DevSetup::on_sbTxOffset_valueChanged(double f)
{
m_TxOffset=f;
}

90
map65/devsetup.h Normal file
View File

@ -0,0 +1,90 @@
#ifndef DEVSETUP_H
#define DEVSETUP_H
#include <QDialog>
#include "ui_devsetup.h"
class DevSetup : public QDialog
{
Q_OBJECT
public:
DevSetup(QWidget *parent=0);
~DevSetup();
void initDlg();
qint32 m_idInt;
qint32 m_pttPort;
qint32 m_nDevIn;
qint32 m_nDevOut;
qint32 m_inDevList[100];
qint32 m_outDevList[100];
qint32 m_paInDevice;
qint32 m_paOutDevice;
qint32 m_timeout;
qint32 m_dPhi;
qint32 m_fCal;
qint32 m_udpPort;
qint32 m_astroFont;
qint32 m_mult570;
qint32 m_mult570Tx;
double m_fAdd;
double m_cal570;
double m_TxOffset;
bool m_xpolx;
bool m_network;
bool m_fs96000;
bool m_xpol;
bool m_IQswap;
bool m_restartSoundIn;
bool m_restartSoundOut;
bool m_10db;
bool m_initIQplus;
bool m_bIQxt;
QString m_myCall;
QString m_myGrid;
QString m_saveDir;
QString m_azelDir;
QString m_dxccPfx;
QString m_colors;
QString m_editorCommand;
QColor m_colorBackground;
public slots:
void accept();
private slots:
void on_soundCardRadioButton_toggled(bool checked);
void on_cbXpol_stateChanged(int arg1);
void on_cal570SpinBox_valueChanged(double ppm);
void on_mult570SpinBox_valueChanged(int mult);
void on_sbBackgroundRed_valueChanged(int arg1);
void on_sbBackgroundGreen_valueChanged(int arg1);
void on_sbBackgroundBlue_valueChanged(int arg1);
void updateColorLabels(void);
void on_sbRed0_valueChanged(int arg1);
void on_sbGreen0_valueChanged(int arg1);
void on_sbBlue0_valueChanged(int arg1);
void on_sbRed1_valueChanged(int arg1);
void on_sbGreen1_valueChanged(int arg1);
void on_sbBlue1_valueChanged(int arg1);
void on_sbRed2_valueChanged(int arg1);
void on_sbGreen2_valueChanged(int arg1);
void on_sbBlue2_valueChanged(int arg1);
void on_sbRed3_valueChanged(int arg1);
void on_sbGreen3_valueChanged(int arg1);
void on_sbBlue3_valueChanged(int arg1);
void on_pushButton_5_clicked();
void on_mult570TxSpinBox_valueChanged(int arg1);
void on_rbIQXT_toggled(bool checked);
void on_sbTxOffset_valueChanged(double f);
private:
int r,g,b,r0,g0,b0,r1,g1,b1,r2,g2,b2,r3,g3,b3;
Ui::DialogSndCard ui;
};
#endif // DEVSETUP_H

1801
map65/devsetup.ui Normal file

File diff suppressed because it is too large Load Diff

15
map65/displaytext.cpp Normal file
View File

@ -0,0 +1,15 @@
#include "displaytext.h"
#include <QDebug>
#include <QMouseEvent>
DisplayText::DisplayText(QWidget *parent) :
QTextBrowser(parent)
{
}
void DisplayText::mouseDoubleClickEvent(QMouseEvent *e)
{
bool ctrl = (e->modifiers() & 0x4000000);
emit(selectCallsign(ctrl));
QTextBrowser::mouseDoubleClickEvent(e);
}

22
map65/displaytext.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef DISPLAYTEXT_H
#define DISPLAYTEXT_H
#include <QTextBrowser>
class DisplayText : public QTextBrowser
{
Q_OBJECT
public:
explicit DisplayText(QWidget *parent = 0);
signals:
void selectCallsign(bool ctrl);
public slots:
protected:
void mouseDoubleClickEvent(QMouseEvent *e);
};
#endif // DISPLAYTEXT_H

69
map65/ffft.f Normal file
View File

@ -0,0 +1,69 @@
subroutine ffft(d,npts,isign,ireal)
C Fourier transform of length npts=2**k, performed in place.
C Input data in array d, treated as complex if ireal=0, and as real if ireal=1.
C In either case the transform values are returned in array d, treated as
C complex. The DC term is d(1), and d(npts/2+1) is the term at the Nyquist
C frequency. The basic algorithm is the same as Norm Brenner's FOUR1, and
C uses radix-2 transforms.
C J. H. Taylor, Princeton University.
complex d(npts),t,w,wstep,tt,uu
data pi/3.14159265359/
C Shuffle the data to bit-reversed order.
imax=npts/(ireal+1)
irev=1
do 5 i=1,imax
if(i.ge.irev) go to 2
t=d(i)
d(i)=d(irev)
d(irev)=t
2 mmax=imax/2
3 if(irev.le.mmax) go to 5
irev=irev-mmax
mmax=mmax/2
if(mmax.ge.1) go to 3
5 irev=irev+mmax
C The radix-2 transform begins here.
api=isign*pi/2.
mmax=1
6 istep=2*mmax
wstep=cmplx(-2.*sin(api/mmax)**2,sin(2.*api/mmax))
w=1.
do 9 m=1,mmax
C This in the inner-most loop -- optimization here is important!
do 8 i=m,imax,istep
t=w*d(i+mmax)
d(i+mmax)=d(i)-t
8 d(i)=d(i)+t
9 w=w*(1.+wstep)
mmax=istep
if(mmax.lt.imax) go to 6
if(ireal.eq.0) return
C Now complete the last stage of a doubled-up real transform.
jmax=imax/2 + 1
wstep=cmplx(-2.*sin(isign*pi/npts)**2,sin(isign*pi/imax))
w=1.0
d(imax+1)=d(1)
do 10 j=1,jmax
uu=cmplx(real(d(j))+real(d(2+imax-j)),aimag(d(j)) -
+ aimag(d(2+imax-j)))
tt=w*cmplx(aimag(d(j))+aimag(d(2+imax-j)),-real(d(j)) +
+ real(d(2+imax-j)))
d(j)=uu+tt
d(2+imax-j)=conjg(uu-tt)
10 w=w*(1.+wstep)
return
end

1
map65/ft2000_freq.sh Normal file
View File

@ -0,0 +1 @@
rigctl-wsjtx -m 129 -r COM1 -s 38400 -C data_bits=8 -C stop_bits=2 -C serial_handshake=Hardware f

259
map65/getdev.cpp Normal file
View File

@ -0,0 +1,259 @@
#include <stdio.h>
#define MAXDEVICES 100
#include <string.h>
#include <portaudio.h>
#include <QDebug>
//------------------------------------------------------- pa_get_device_info
int pa_get_device_info (int n,
void *pa_device_name,
void *pa_device_hostapi,
double *pa_device_max_speed,
double *pa_device_min_speed,
int *pa_device_max_bytes,
int *pa_device_min_bytes,
int *pa_device_max_channels,
int *pa_device_min_channels )
{
(void) n ;
(void) pa_device_name;
(void) pa_device_hostapi;
(void) pa_device_max_speed;
(void) pa_device_min_speed;
(void) pa_device_max_bytes;
(void) pa_device_min_bytes;
(void) pa_device_max_channels;
(void) pa_device_min_channels;
const PaDeviceInfo *deviceInfo;
PaError pa_err;
PaStreamParameters inputParameters;
int i,j, speed_warning;
int minBytes, maxBytes;
double maxStandardSampleRate;
double minStandardSampleRate;
int minInputChannels;
int maxInputChannels;
// negative terminated list
static double standardSampleRates[] = {8000.0, 9600.0,
11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1};
// *******************************************************
*pa_device_max_speed=0;
*pa_device_min_speed=0;
*pa_device_max_bytes=0;
*pa_device_min_bytes=0;
*pa_device_max_channels=0;
*pa_device_min_channels=0;
minInputChannels=0;
if(n >= Pa_GetDeviceCount() ) return -1;
deviceInfo = Pa_GetDeviceInfo(n);
if (deviceInfo->maxInputChannels==0) return -1;
sprintf((char*)(pa_device_name),"%s",deviceInfo->name);
sprintf((char*)(pa_device_hostapi),"%s",
Pa_GetHostApiInfo( deviceInfo->hostApi )->name);
speed_warning=0;
// bypass bug in Juli@ ASIO driver:
// this driver hangs after a Pa_IsFormatSupported call
i = strncmp(deviceInfo->name, "ASIO 2.0 - ESI Juli@", 19);
if (i == 0) {
minStandardSampleRate=44100;
maxStandardSampleRate=192000;
minBytes=1;
maxBytes=4;
maxInputChannels= deviceInfo->maxInputChannels;
minInputChannels= 1;
goto end_pa_get_device_info;
}
// Investigate device capabilities.
// Check min and max samplerates with 16 bit data.
maxStandardSampleRate=0;
minStandardSampleRate=0;
inputParameters.device = n;
inputParameters.channelCount = deviceInfo->maxInputChannels;
inputParameters.sampleFormat = paInt16;
inputParameters.suggestedLatency = 0;
inputParameters.hostApiSpecificStreamInfo = NULL;
// ************************************************************************
//filter for portaudio Windows hostapi's with non experts.
//only allow ASIO or WASAPI or WDM-KS
i = strncmp(Pa_GetHostApiInfo(deviceInfo->hostApi)->name, "ASIO", 4);
if (i==0 ) goto end_filter_hostapi;
i = strncmp(Pa_GetHostApiInfo(deviceInfo->hostApi)->name,
"Windows WASAPI", 14);
if (i==0 ) goto end_filter_hostapi;
i = strncmp(Pa_GetHostApiInfo(deviceInfo->hostApi)->name,
"Windows WDM-KS", 14);
if (i==0 ) goto end_filter_hostapi;
speed_warning=1;
end_filter_hostapi:;
// ************************************************************************
i=0;
while(standardSampleRates[i] > 0 && minStandardSampleRate==0) {
pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
standardSampleRates[i] );
if(pa_err == paDeviceUnavailable) return -1;
if(pa_err == paInvalidDevice) return -1;
if(pa_err == paFormatIsSupported ) {
minStandardSampleRate=standardSampleRates[i];
}
i++;
}
if(minStandardSampleRate == 0) return -1;
j=i;
while(standardSampleRates[i] > 0 ) i++;
i--;
while(i >= j && maxStandardSampleRate==0) {
pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
standardSampleRates[i] );
if(pa_err == paDeviceUnavailable) return -1;
if(pa_err == paInvalidDevice) return -1;
if( pa_err == paFormatIsSupported ) {
maxStandardSampleRate=standardSampleRates[i];
}
i--;
}
// check if min SampleRate = max SampleRate
if(maxStandardSampleRate==0 && (minStandardSampleRate != 0)) {
maxStandardSampleRate= minStandardSampleRate;
}
// check min and max bytes
minBytes=2;
maxBytes=2;
inputParameters.sampleFormat = paUInt8;
pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
maxStandardSampleRate );
if( pa_err == paFormatIsSupported ) {
minBytes=1;
}
inputParameters.sampleFormat = paInt32;
pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
maxStandardSampleRate );
if( pa_err == paFormatIsSupported ) {
maxBytes=4;
}
// check min channel count
maxInputChannels= deviceInfo->maxInputChannels;
inputParameters.channelCount = 1;
inputParameters.sampleFormat = paInt16;
pa_err=paFormatIsSupported+32000;
while(pa_err != paFormatIsSupported &&
( inputParameters.channelCount < (maxInputChannels+1)) ) {
pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
maxStandardSampleRate );
inputParameters.channelCount++;
}
if( pa_err == paFormatIsSupported ) {
minInputChannels=inputParameters.channelCount-1;
} else {
return -1;
}
end_pa_get_device_info:;
*pa_device_max_speed=maxStandardSampleRate;
*pa_device_min_speed=minStandardSampleRate;
*pa_device_max_bytes=maxBytes;
*pa_device_min_bytes=minBytes;
*pa_device_max_channels= maxInputChannels;
*pa_device_min_channels= minInputChannels;
return speed_warning;
}
void paInputDevice(int id, char* hostAPI_DeviceName, int* minChan,
int* maxChan, int* minSpeed, int* maxSpeed)
{
int i;
char pa_device_name[128];
char pa_device_hostapi[128];
double pa_device_max_speed;
double pa_device_min_speed;
int pa_device_max_bytes;
int pa_device_min_bytes;
int pa_device_max_channels;
int pa_device_min_channels;
char p2[256];
char *p,*p1;
static int iret, valid_dev_cnt;
iret=pa_get_device_info (id,
&pa_device_name,
&pa_device_hostapi,
&pa_device_max_speed,
&pa_device_min_speed,
&pa_device_max_bytes,
&pa_device_min_bytes,
&pa_device_max_channels,
&pa_device_min_channels);
if (iret >= 0 ) {
valid_dev_cnt++;
p1=(char*)"";
p=strstr(pa_device_hostapi,"MME");
if(p!=NULL) p1=(char*)"MME";
p=strstr(pa_device_hostapi,"Direct");
if(p!=NULL) p1=(char*)"DirectX";
p=strstr(pa_device_hostapi,"WASAPI");
if(p!=NULL) p1=(char*)"WASAPI";
p=strstr(pa_device_hostapi,"ASIO");
if(p!=NULL) p1=(char*)"ASIO";
p=strstr(pa_device_hostapi,"WDM-KS");
if(p!=NULL) p1=(char*)"WDM-KS";
sprintf(p2,"%-8s %-39s",p1,pa_device_name);
for(i=0; i<50; i++) {
hostAPI_DeviceName[i]=p2[i];
if(p2[i]==0) break;
}
*minChan=pa_device_min_channels;
*maxChan=pa_device_max_channels;
*minSpeed=(int)pa_device_min_speed;
*maxSpeed=(int)pa_device_max_speed;
} else {
for(i=0; i<50; i++) {
hostAPI_DeviceName[i]=0;
}
*minChan=0;
*maxChan=0;
*minSpeed=0;
*maxSpeed=0;
}
}
void getDev(int* numDevices0, char hostAPI_DeviceName[][50],
int minChan[], int maxChan[],
int minSpeed[], int maxSpeed[])
{
int i,id,numDevices;
int minch,maxch,minsp,maxsp;
char apidev[256];
numDevices=Pa_GetDeviceCount();
*numDevices0=numDevices;
for(id=0; id<numDevices; id++) {
paInputDevice(id,apidev,&minch,&maxch,&minsp,&maxsp);
for(i=0; i<50; i++) {
hostAPI_DeviceName[id][i]=apidev[i];
}
hostAPI_DeviceName[id][49]=0;
minChan[id]=minch;
maxChan[id]=maxch;
minSpeed[id]=minsp;
maxSpeed[id]=maxsp;
}
}

107
map65/getfile.cpp Normal file
View File

@ -0,0 +1,107 @@
#include "getfile.h"
#include <QDir>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
extern qint16 id[4*60*96000];
void getfile(QString fname, bool xpol, int dbDgrd)
{
int npts=2*52*96000;
if(xpol) npts=2*npts;
// Degrade S/N by dbDgrd dB -- for tests only!!
float dgrd=0.0;
if(dbDgrd<0) dgrd = 23.0*sqrt(pow(10.0,-0.1*(double)dbDgrd) - 1.0);
float fac=23.0/sqrt(dgrd*dgrd + 23.0*23.0);
memset(id,0,2*npts);
char name[80];
strcpy(name,fname.toLatin1());
FILE* fp=fopen(name,"rb");
if(fp != NULL) {
auto n = fread(&datcom_.fcenter,sizeof(datcom_.fcenter),1,fp);
n = fread(id,2,npts,fp);
Q_UNUSED (n);
int j=0;
if(dbDgrd<0) {
for(int i=0; i<npts; i+=2) {
datcom_.d4[j++]=fac*((float)id[i] + dgrd*gran());
datcom_.d4[j++]=fac*((float)id[i+1] + dgrd*gran());
if(!xpol) j+=2; //Skip over d4(3,x) and d4(4,x)
}
} else {
for(int i=0; i<npts; i+=2) {
datcom_.d4[j++]=(float)id[i];
datcom_.d4[j++]=(float)id[i+1];
if(!xpol) j+=2; //Skip over d4(3,x) and d4(4,x)
}
}
fclose(fp);
datcom_.ndiskdat=1;
int nfreq=(int)datcom_.fcenter;
if(nfreq!=144 and nfreq != 432 and nfreq != 1296) datcom_.fcenter=144.125;
int i0=fname.indexOf(".tf2");
if(i0<0) i0=fname.indexOf(".iq");
datcom_.nutc=0;
if(i0>0) {
datcom_.nutc=100*fname.mid(i0-4,2).toInt() + fname.mid(i0-2,2).toInt();
}
}
}
void savetf2(QString fname, bool xpol)
{
int npts=2*52*96000;
if(xpol) npts=2*npts;
qint16* buf=(qint16*)malloc(2*npts);
char name[80];
strcpy(name,fname.toLatin1());
FILE* fp=fopen(name,"wb");
if(fp != NULL) {
fwrite(&datcom_.fcenter,sizeof(datcom_.fcenter),1,fp);
int j=0;
for(int i=0; i<npts; i+=2) {
buf[i]=(qint16)datcom_.d4[j++];
buf[i+1]=(qint16)datcom_.d4[j++];
if(!xpol) j+=2; //Skip over d4(3,x) and d4(4,x)
}
fwrite(buf,2,npts,fp);
fclose(fp);
}
free(buf);
}
//#define MAX_RANDOM 0x7fffffff
/* Generate gaussian random float with mean=0 and std_dev=1 */
float gran()
{
float fac,rsq,v1,v2;
static float gset;
static int iset;
if(iset){
/* Already got one */
iset = 0;
return gset;
}
/* Generate two evenly distributed numbers between -1 and +1
* that are inside the unit circle
*/
do {
v1 = 2.0 * (float)rand() / RAND_MAX - 1;
v2 = 2.0 * (float)rand() / RAND_MAX - 1;
rsq = v1*v1 + v2*v2;
} while(rsq >= 1.0 || rsq == 0.0);
fac = sqrt(-2.0*log(rsq)/rsq);
gset = v1*fac;
iset++;
return v2*fac;
}

12
map65/getfile.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef GETFILE_H
#define GETFILE_H
#include <QString>
#include <QFile>
#include <QDebug>
#include "commons.h"
void getfile(QString fname, bool xpol, int dbDgrd);
void savetf2(QString fname, bool xpol);
float gran();
#endif // GETFILE_H

16
map65/getsvn.cmake Normal file
View File

@ -0,0 +1,16 @@
find_package (Subversion)
if (Subversion_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.svn)
# the FindSubversion.cmake module is part of the standard distribution
include (FindSubversion)
# extract working copy information for SOURCE_DIR into MY_XXX variables
Subversion_WC_INFO (${SOURCE_DIR} MY)
# write a file with the SVNVERSION define
file (WRITE svnversion.h.txt "#define SVNVERSION ${MY_WC_REVISION}\n")
else (Subversion_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.svn)
file (WRITE svnversion.h.txt "#define SVNVERSION local\n")
endif (Subversion_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.svn)
# copy the file to the final header only if the version changes
# reduces needless rebuilds
execute_process (COMMAND ${CMAKE_COMMAND} -E copy_if_different
svnversion.h.txt svnversion.h)

16
map65/in.dat Normal file
View File

@ -0,0 +1,16 @@
35 36 22 8 31 11 14 55 20 36 55 13 24 15 56 38 16 28 61 58
15 26 45 8 41 53 37 57 59 60 29 29 41 46 44 35 52 61 24 26
16 20 53 35 2 6 9 27 47 28 57 6 15 9 16 10 56 9 63 46
9 15 3
74 61 44 233 29 245 254 64 119 64 250 111 38 145 53 29 140 194 119 99
55 86 48 110 142 95 48 120 61 66 252 252 245 88 62 41 124 249 246 68
250 249 65 64 140 142 88 190 237 90 240 52 79 216 55 31 112 135 66 44
99 57 68
54 61 26 5 13 60 3 56 30 58 57 4 16 43 28 43 6 61 13 19
56 8 4 9 45 32 9 7 14 52 4 38 40 27 3 26 51 54 40 29
36 63 34 43 3 48 36 49 46 30 8 20 40 59 29 28 17 11 8 19
11 63 5
38 25 35 8 28 0 0 60 60 25 0 31 28 52 14 24 9 30 18 54
49 55 48 15 27 54 26 22 30 27 1 1 4 31 35 29 23 2 2 27
0 1 25 32 21 84 28 19 5 60 2 27 15 9 39 23 42 12 29 17
16 50 49

282
map65/killbyname.cpp Normal file
View File

@ -0,0 +1,282 @@
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
int killbyname(const char *szToTerminate)
// Created: 6/23/2000 (Ravi Kochhar)
// Last modified: 3/10/2002 (RK)
// Please report any problems or bugs to kochhar@physiology.wisc.edu
// The latest version of this routine can be found at:
// http://www.neurophys.wisc.edu/ravi/software/killproc/
// Terminate the process "szToTerminate" if it is currently running
// This works for Win/95/98/ME and also Win/NT/2000/XP
// The process name is case-insensitive, i.e. "notepad.exe" and "NOTEPAD.EXE"
// will both work (for szToTerminate)
// Return codes are as follows:
// 0 = Process was successfully terminated
// 602 = Unable to terminate process for some other reason
// 603 = Process was not currently running
// 604 = No permission to terminate process
// 605 = Unable to load PSAPI.DLL
// 606 = Unable to identify system type
// 607 = Unsupported OS
// 632 = Invalid process name
// 700 = Unable to get procedure address from PSAPI.DLL
// 701 = Unable to get process list, EnumProcesses failed
// 702 = Unable to load KERNEL32.DLL
// 703 = Unable to get procedure address from KERNEL32.DLL
// 704 = CreateToolhelp32Snapshot failed
{
BOOL bResult,bResultm;
DWORD aiPID[1000],iCb=1000,iNumProc; //,iV2000=0;
DWORD iCbneeded,i,iFound=0;
char szName[MAX_PATH],szToTermUpper[MAX_PATH];
HANDLE hProc,hSnapShot,hSnapShotm;
OSVERSIONINFO osvi;
HINSTANCE hInstLib;
int iLenP,indx;
HMODULE hMod;
PROCESSENTRY32 procentry;
MODULEENTRY32 modentry;
// Transfer Process name into "szToTermUpper" and convert to upper case
iLenP=strlen(szToTerminate);
if(iLenP<1 || iLenP>MAX_PATH) return 632;
for(indx=0;indx<iLenP;indx++)
szToTermUpper[indx]=toupper(szToTerminate[indx]);
szToTermUpper[iLenP]=0;
// PSAPI Function Pointers.
BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
DWORD, LPDWORD );
DWORD (WINAPI *lpfGetModuleBaseName)( HANDLE, HMODULE,
LPTSTR, DWORD );
// ToolHelp Function Pointers.
HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;
BOOL (WINAPI *lpfModule32First)(HANDLE,LPMODULEENTRY32) ;
BOOL (WINAPI *lpfModule32Next)(HANDLE,LPMODULEENTRY32) ;
// First check what version of Windows we're in
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
bResult=GetVersionEx(&osvi);
if(!bResult) return 606; // Unable to identify system version
// At Present we only support Win/NT/2000/XP or Win/9x/ME
// Seems to work OK in Win7
if((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) &&
(osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)) return 607;
if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT)
{
// Win/NT or 2000 or XP
// Load library and get the procedures explicitly. We do
// this so that we don't have to worry about modules using
// this code failing to load under Windows 9x, because
// it can't resolve references to the PSAPI.DLL.
hInstLib = LoadLibraryA("PSAPI.DLL");
if(hInstLib == NULL) return 605;
// Get procedure addresses.
lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))(void (*)())
GetProcAddress( hInstLib, "EnumProcesses" ) ;
lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
DWORD, LPDWORD))(void (*)()) GetProcAddress( hInstLib, "EnumProcessModules" ) ;
lpfGetModuleBaseName =(DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR,
DWORD )) (void (*)())GetProcAddress( hInstLib, "GetModuleBaseNameA" ) ;
if(lpfEnumProcesses == NULL || lpfEnumProcessModules == NULL ||
lpfGetModuleBaseName == NULL) {
FreeLibrary(hInstLib);
return 700;
}
bResult=lpfEnumProcesses(aiPID,iCb,&iCbneeded);
if(!bResult) {
// Unable to get process list, EnumProcesses failed
FreeLibrary(hInstLib);
return 701;
}
// How many processes are there?
iNumProc=iCbneeded/sizeof(DWORD);
// Get and match the name of each process
for(i=0;i<iNumProc;i++) {
// Get the (module) name for this process
strcpy(szName,"Unknown");
// First, get a handle to the process
hProc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,
aiPID[i]);
// Now, get the process name
if(hProc) {
if(lpfEnumProcessModules(hProc,&hMod,sizeof(hMod),&iCbneeded) ) {
lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH);
}
}
CloseHandle(hProc);
// We will match regardless of lower or upper case
if(strcmp(_strupr(szName),szToTermUpper)==0) {
// Process found, now terminate it
iFound=1;
// First open for termination
hProc=OpenProcess(PROCESS_TERMINATE,FALSE,aiPID[i]);
if(hProc) {
if(TerminateProcess(hProc,0)) {
// process terminated
CloseHandle(hProc);
FreeLibrary(hInstLib);
return 0;
} else {
// Unable to terminate process
CloseHandle(hProc);
FreeLibrary(hInstLib);
return 602;
}
} else {
// Unable to open process for termination
FreeLibrary(hInstLib);
return 604;
}
}
}
}
if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
{
// Win/95 or 98 or ME
hInstLib = LoadLibraryA("Kernel32.DLL");
if( hInstLib == NULL )
return 702;
// Get procedure addresses.
// We are linking to these functions of Kernel32
// explicitly, because otherwise a module using
// this code would fail to load under Windows NT,
// which does not have the Toolhelp32
// functions in the Kernel 32.
lpfCreateToolhelp32Snapshot=
(HANDLE(WINAPI *)(DWORD,DWORD))(void (*)())
GetProcAddress( hInstLib,
"CreateToolhelp32Snapshot" ) ;
lpfProcess32First=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))(void (*)())
GetProcAddress( hInstLib, "Process32First" ) ;
lpfProcess32Next=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))(void (*)())
GetProcAddress( hInstLib, "Process32Next" ) ;
lpfModule32First=
(BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))(void (*)())
GetProcAddress( hInstLib, "Module32First" ) ;
lpfModule32Next=
(BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))(void (*)())
GetProcAddress( hInstLib, "Module32Next" ) ;
if( lpfProcess32Next == NULL ||
lpfProcess32First == NULL ||
lpfModule32Next == NULL ||
lpfModule32First == NULL ||
lpfCreateToolhelp32Snapshot == NULL )
{
FreeLibrary(hInstLib);
return 703;
}
// The Process32.. and Module32.. routines return names in all uppercase
// Get a handle to a Toolhelp snapshot of all the systems processes.
hSnapShot = lpfCreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS, 0 ) ;
if( hSnapShot == INVALID_HANDLE_VALUE )
{
FreeLibrary(hInstLib);
return 704;
}
// Get the first process' information.
procentry.dwSize = sizeof(PROCESSENTRY32);
bResult=lpfProcess32First(hSnapShot,&procentry);
// While there are processes, keep looping and checking.
while(bResult)
{
// Get a handle to a Toolhelp snapshot of this process.
hSnapShotm = lpfCreateToolhelp32Snapshot(
TH32CS_SNAPMODULE, procentry.th32ProcessID) ;
if( hSnapShotm == INVALID_HANDLE_VALUE )
{
CloseHandle(hSnapShot);
FreeLibrary(hInstLib);
return 704;
}
// Get the module list for this process
modentry.dwSize=sizeof(MODULEENTRY32);
bResultm=lpfModule32First(hSnapShotm,&modentry);
// While there are modules, keep looping and checking
while(bResultm)
{
if(strcmp(modentry.szModule,szToTermUpper)==0)
{
// Process found, now terminate it
iFound=1;
// First open for termination
hProc=OpenProcess(PROCESS_TERMINATE,FALSE,procentry.th32ProcessID);
if(hProc)
{
if(TerminateProcess(hProc,0))
{
// process terminated
CloseHandle(hSnapShotm);
CloseHandle(hSnapShot);
CloseHandle(hProc);
FreeLibrary(hInstLib);
return 0;
}
else
{
// Unable to terminate process
CloseHandle(hSnapShotm);
CloseHandle(hSnapShot);
CloseHandle(hProc);
FreeLibrary(hInstLib);
return 602;
}
}
else
{
// Unable to open process for termination
CloseHandle(hSnapShotm);
CloseHandle(hSnapShot);
FreeLibrary(hInstLib);
return 604;
}
}
else
{ // Look for next modules for this process
modentry.dwSize=sizeof(MODULEENTRY32);
bResultm=lpfModule32Next(hSnapShotm,&modentry);
}
}
//Keep looking
CloseHandle(hSnapShotm);
procentry.dwSize = sizeof(PROCESSENTRY32);
bResult = lpfProcess32Next(hSnapShot,&procentry);
}
CloseHandle(hSnapShot);
}
if(iFound==0)
{
FreeLibrary(hInstLib);
return 603;
}
FreeLibrary(hInstLib);
return 0;
}

147
map65/libm65/CMakeLists.txt Normal file
View File

@ -0,0 +1,147 @@
set (libm65_FSRCS
# Modules come first:
wideband_sync.f90
# Non-module Fortran routines:
afc65b.f90
astro.f90
astro0.f90
astrosub.f90
averms.f90
badmsg.f90
ccf2.f90
ccf65.f90
cgen65.f90
chkhist.f90
chkmsg.f90
coord.f90
dcoord.f90
decode0.f90
decode1a.f90
decode65b.f90
deep65.f90
deg2grid.f90
demod64a.f90
display.f90
dot.f90
dpol.f90
encode65.f90
extract.f90
fchisq.f90
fchisq0.f90
fil6521.f90
filbig.f90
fmtmsg.f90
four2a.f90
ftninit.f90
ftnquit.f90
q65b.f90
gen65.f90
gen_q65_cwave.f90
gen_q65_wave.f90
geocentric.f90
getdphi.f90
getpfx1.f90
getpfx2.f90
graycode.f90
graycode65.f90
grid2deg.f90
grid2k.f90
indexx.f90
interleave63.f90
iqcal.f90
iqfix.f90
jt65code.f90
k2grid.f90
lorentzian.f90
map65a.f90
moon2.f90
moondop.f90
nchar.f90
noisegen.f90
packjt.f90
# pctile.f90
pfxdump.f90
recvpkt.f90
rfile3a.f90
s3avg.f90
sec_midn.f90
set.f90
setup65.f90
shell.f90
sleep_msec.f90
smo.f90
sun.f90
symspec.f90
# timer.f90
timf2.f90
tm2.f90
toxyz.f90
trimlist.f90
twkfreq.f90
twkfreq_xy.f90
wavhdr.f90
f77_wisdom.f
)
set (libm65_ka9q_CSRCS
decode_rs.c
encode_rs.c
init_rs.c
)
set_source_files_properties (${libm65_ka9q_CSRCS} PROPERTIES COMPILE_FLAGS -Wno-sign-compare)
set (libm65_CSRCS
${libm65_ka9q_CSRCS}
ftrsd2.c
# gran.c
igray.c
tmoonsub.c
usleep.c
wrapkarn.c
)
if (WIN32)
set (libm65_CSRCS ${libm65_CSRCS} ptt.c)
else ()
set (libm65_CSRCS ${libm65_CSRCS} ptt_unix.c)
endif ()
set (libm65_CXXSRCS
ipcomm.cpp
)
add_definitions (-DBIGSYM=1)
set_source_files_properties (sec_midn.f90 PROPERTIES COMPILE_FLAGS -fno-second-underscore)
set (libm65_C_and_CXXSRCS
${libm65_CSRCS}
${libm65_CXXSRCS}
)
set_property (SOURCE ${libm65_C_and_CXXSRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -include wsjtx_config.h")
set_property (SOURCE ${libm65_C_and_CXXSRCS} APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_BINARY_DIR}/wsjtx_config.h)
#
# build our targets
#
add_library (m65impl STATIC ${libm65_FSRCS} ${libm65_CSRCS} ${libm65_CXXSRCS})
target_link_libraries (m65impl wsjt_fort wsjt_cxx Qt5::Core)
add_executable (m65 m65.f90 m65a.f90)
target_link_libraries (m65 m65impl ${FFTW3_LIBRARIES})
add_executable (mapsim mapsim.f90)
target_link_libraries (mapsim m65impl ${FFTW3_LIBRARIES})
add_executable (synctest synctest.f90)
target_link_libraries (synctest m65impl ${FFTW3_LIBRARIES})
if (WIN32)
install (
TARGETS m65 mapsim
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION . COMPONENT runtime
)
endif ()

130
map65/libm65/Makefile Normal file
View File

@ -0,0 +1,130 @@
# Makefile for MinGW on Windows
CC = c:/JTSDK/Qt55/Tools/mingw492_32/bin/gcc
FC = c:/JTSDK/Qt55/Tools/mingw492_32/bin/gfortran
CXX = c:/JTSDK/Qt55/Tools/mingw492_32/bin/g++
FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion -Wno-precision-loss \
-fno-second-underscore -fbacktrace \
-ffpe-summary=none
# -ffpe-trap=invalid,zero,overflow,underflow,denormal
CFLAGS = -I. -fbounds-check
# Default rules
%.o: %.c
${CC} ${CFLAGS} -c $<
%.o: %.f
${FC} ${FFLAGS} -c $<
%.o: %.F
${FC} ${FFLAGS} -c $<
%.o: %.f90
${FC} ${FFLAGS} -c $<
%.o: %.F90
${FC} ${FFLAGS} -c $<
all: packjt.o wavhdr.o libm65.a m65.exe mapsim.exe libastro.a
OBJS1 = trimlist.o display.o getdphi.o pctile.o ccf65.o \
decode1a.o sort.o filbig.o fil6521.o afc65b.o \
twkfreq.o decode65b.o indexx.o ssort.o fchisq.o setup65.o \
extract.o deep65.o ccf2.o demod64a.o chkhist.o graycode.o \
interleave63.o encode65.o igray.o set.o shell.o qra64_subs.o \
grid2k.o getpfx2.o q65b.o qra64c.o twkfreq_xy.o qra64zap.o \
deg2grid.o getpfx1.o k2grid.o ftrsd2.o graycode65.o \
wrapkarn.o nchar.o init_rs.o encode_rs.o decode_rs.o \
four2a.o rfile3a.o grid2deg.o pfxdump.o dpol.o sync64.o spec64.o \
astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \
geocentric.o moon2.o toxyz.o dot.o dcoord.o f77_wisdom.o \
gen65.o chkmsg.o ptt.o astrosub.o astro0.o recvpkt.o symspec.o \
iqcal.o iqfix.o timf2.o s3avg.o packjt.o badmsg.o fmtmsg.o \
qracodes.o qra64.o smo.o averms.o lorentzian.o npfwht.o pdmath.o \
qra13_64_64_irr_e.o fchisq0.o gen_q65_wave.o wavhdr.o
packjt.o: packjt.f90
$(FC) -c packjt.f90
libm65.a: $(OBJS1)
ar cr libm65.a $(OBJS1)
ranlib libm65.a
qra64_subs.o: ./qra64/qra64_subs.c
gcc -c -O2 -o qra64_subs.o ./qra64/qra64_subs.c
qracodes.o: qracodes/qracodes.c
gcc -c -O2 -o qracodes.o qracodes/qracodes.c
qra64.o: qra64/qra64.c
gcc -c -O2 -o qra64.o qra64/qra64.c
qra13_64_64_irr_e.o: qracodes/qra13_64_64_irr_e.c
gcc -c -O2 -o qra13_64_64_irr_e.o \
qracodes/qra13_64_64_irr_e.c
npfwht.o: qracodes/npfwht.c
gcc -c -O2 -o npfwht.o qracodes/npfwht.c
pdmath.o: qracodes/pdmath.c
gcc -c -O2 -o pdmath.o qracodes/pdmath.c
OBJS3 = m65.o m65a.o map65a.o symspec.o decode0.o ftninit.o ftnquit.o \
timer.o ipcomm.o sec_midn.o usleep.o
# cutil.o
LIBS3 = -L'C:/JTSDK/Qt55/5.5/mingw492_32/lib' -lQt5Core
m65.exe: $(OBJS3) libm65.a
$(CXX) -o m65.exe $(OBJS3) $(LIBS3) libm65.a ../libfftw3f_win.a \
-lgfortran
# cp m65.exe ../../map65_install
cp m65.exe /c/MAP65_2.9
OBJS7 = astrosub.o astro0.o astro.o tm2.o grid2deg.o sun.o moondop.o \
coord.o dot.o moon2.o tmoonsub.o toxyz.o geocentric.o \
dcoord.o
libastro.a: $(OBJS7)
ar cr libastro.a $(OBJS7)
ranlib libastro.a
OBJS6 = mapsim.o cgen65.o noisegen.o gran.o
mapsim.exe: $(OBJS6) libm65.a
$(FC) -o mapsim.exe $(OBJS6) libm65.a
INCPATH = -I'C:/JTSDK/Qt55/5.5/mingw492_32/include/QtCore' \
-I'C:/JTSDK/Qt55/5.5/mingw492_32/include'
ipcomm.o: ipcomm.cpp
$(CXX) -c $(INCPATH) ipcomm.cpp
#m65a.o: m65a.f90
# $(FC) -c -fno-second-underscore -cpp m65a.f90
sec_midn.o: sec_midn.f90
$(FC) -c -fno-second-underscore sec_midn.f90
#symspec.o: ../symspec.f90
# $(FC) -c $(FFLAGS) -o symspec.o ../symspec.f90
OBJS4 = tastro.o astro0.o libm65.a
tastro.exe: $(OBJS4)
$(FC) $(FFLAGS) -o tastro.exe $(OBJS4) libm65.a
OBJS5 = t1.o timer.o libm65.a
t1.exe: $(OBJS5)
$(FC) $(FFLAGS) -o t1.exe $(OBJS5) libm65.a
#astro0.o: ../astro0.f90
# $(FC) -c $(FFLAGS) -o astro0.o ../astro0.f90
init_rs.o: init_rs.c
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
encode_rs.o: encode_rs.c
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
decode_rs.o: decode_rs.c
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
.PHONY : clean
clean:
rm -f *.o *.mod libm65.a m65.exe

114
map65/libm65/Makefile.0 Normal file
View File

@ -0,0 +1,114 @@
# Makefile for Linux
CC = gcc
FC = gfortran
CXX = g++
FFLAGS = -O2 -fbounds-check -Wall -Wno-precision-loss -fno-second-underscore
# For ptt_unix:
CFLAGS = -I. -fbounds-check -DHAVE_STDLIB_H=1 -DHAVE_STDIO_H=1 \
-DHAVE_FCNTL_H=1 -DHAVE_SYS_IOCTL_H=1
# Default rules
%.o: %.c
${CC} ${CFLAGS} -c $<
%.o: %.f
${FC} ${FFLAGS} -c $<
%.o: %.F
${FC} ${FFLAGS} -c $<
%.o: %.f90
${FC} ${FFLAGS} -c $<
%.o: %.F90
${FC} ${FFLAGS} -c $<
all: packjt.o libm65.a m65 mapsim libastro.a
OBJS1 = trimlist.o display.o getdphi.o pctile.o ccf65.o \
decode1a.o sort.o filbig.o fil6521.o afc65b.o \
twkfreq.o decode65b.o indexx.o ssort.o fchisq.o setup65.o \
extract.o deep65.o ccf2.o demod64a.o chkhist.o graycode.o \
interleave63.o encode65.o igray.o set.o shell.o qra64_subs.o \
grid2k.o getpfx2.o qra64b.o qra64c.o twkfreq_xy.o qra64zap.o \
deg2grid.o getpfx1.o k2grid.o ftrsd2.o graycode65.o \
wrapkarn.o nchar.o init_rs.o encode_rs.o decode_rs.o \
four2a.o rfile3a.o grid2deg.o pfxdump.o dpol.o sync64.o spec64.o \
astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \
geocentric.o moon2.o toxyz.o dot.o dcoord.o f77_wisdom.o \
gen65.o chkmsg.o astrosub.o astro0.o recvpkt.o symspec.o \
iqcal.o iqfix.o timf2.o s3avg.o packjt.o badmsg.o fmtmsg.o \
qracodes.o qra64.o smo.o averms.o lorentzian.o npfwht.o pdmath.o \
qra13_64_64_irr_e.o fchisq0.o genqra64a.o ptt_unix.o
packjt.o: packjt.f90
$(FC) -c packjt.f90
libm65.a: $(OBJS1)
ar cr libm65.a $(OBJS1)
ranlib libm65.a
qra64_subs.o: ./qra64/qra64_subs.c
gcc -c -O2 -o qra64_subs.o ./qra64/qra64_subs.c
qracodes.o: ./qracodes/qracodes.c
gcc -c -O2 -o qracodes.o ./qracodes/qracodes.c
qra64.o: ./qra64/qra64.c
gcc -c -O2 -o qra64.o ./qra64/qra64.c
qra13_64_64_irr_e.o: ./qracodes/qra13_64_64_irr_e.c
gcc -c -O2 -o qra13_64_64_irr_e.o ./qracodes/qra13_64_64_irr_e.c
npfwht.o: ./qracodes/npfwht.c
gcc -c -O2 -o npfwht.o ./qracodes/npfwht.c
pdmath.o: ./qracodes/pdmath.c
gcc -c -O2 -o pdmath.o ./qracodes/pdmath.c
OBJS3 = m65.o m65a.o map65a.o symspec.o decode0.o ftninit.o ftnquit.o \
timer.o ipcomm.o sec_midn.o usleep.o
m65: $(OBJS3) libm65.a
$(CXX) -o m65 $(OBJS3) libm65.a -lfftw3f -lQt5Core -lfftw3f -lgfortran
cp m65 ../../map65_install
OBJS7 = astrosub.o astro0.o astro.o tm2.o grid2deg.o sun.o moondop.o \
coord.o dot.o moon2.o tmoonsub.o toxyz.o geocentric.o \
dcoord.o
libastro.a: $(OBJS7)
ar cr libastro.a $(OBJS7)
ranlib libastro.a
OBJS6 = mapsim.o cgen65.o noisegen.o gran.o
mapsim: $(OBJS6) libm65.a
$(FC) -o mapsim $(OBJS6) libm65.a
INCPATH = -I. -I'/usr/include/x86_64-linux-gnu/qt5' \
-I'/usr/include/x86_64-linux-gnu/qt5/QtCore'
ipcomm.o: ipcomm.cpp
$(CXX) -c $(INCPATH) -fPIC ipcomm.cpp
sec_midn.o: sec_midn.f90
$(FC) -c -fno-second-underscore sec_midn.f90
OBJS4 = tastro.o astro0.o libm65.a
tastro: $(OBJS4)
$(FC) $(FFLAGS) -o tastro $(OBJS4) libm65.a
OBJS5 = t1.o timer.o libm65.a
t1: $(OBJS5)
$(FC) $(FFLAGS) -o t1 $(OBJS5) libm65.a
init_rs.o: init_rs.c
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
encode_rs.o: encode_rs.c
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
decode_rs.o: decode_rs.c
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
.PHONY : clean
clean:
rm -f *.o *.mod libm65.a m65

105
map65/libm65/Makefile.MinGW Normal file
View File

@ -0,0 +1,105 @@
# Makefile for MinGW on Windows
CC = gcc
FC = g95
CXX = c:/wsjt-env/Qt5/Tools/mingw48_32/bin/g++
FFLAGS = -O2 -fbounds-check -Wall -Wno-precision-loss -fno-second-underscore
CFLAGS = -I. -fbounds-check
# Default rules
%.o: %.c
${CC} ${CFLAGS} -c $<
%.o: %.f
${FC} ${FFLAGS} -c $<
%.o: %.F
${FC} ${FFLAGS} -c $<
%.o: %.f90
${FC} ${FFLAGS} -c $<
%.o: %.F90
${FC} ${FFLAGS} -c $<
all: libm65.a m65.exe JT65code.exe mapsim.exe libastro.a
OBJS1 = trimlist.o display.o getdphi.o pctile.o ccf65.o \
decode1a.o sort.o filbig.o fil6521.o afc65b.o \
twkfreq.o decode65b.o indexx.o ssort.o fchisq.o setup65.o \
extract.o deep65.o ccf2.o demod64a.o chkhist.o graycode.o \
interleave63.o unpackmsg.o encode65.o igray.o set.o unpackcall.o \
unpackgrid.o grid2k.o unpacktext.o getpfx2.o packmsg.o \
deg2grid.o packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
wrapkarn.o nchar.o init_rs.o encode_rs.o decode_rs.o \
four2a.o rfile3a.o grid2deg.o pfxdump.o dpol.o \
astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \
geocentric.o moon2.o toxyz.o dot.o dcoord.o f77_wisdom.o \
gen65.o chkmsg.o ptt.o astrosub.o astro0.o recvpkt.o symspec.o \
iqcal.o iqfix.o timf2.o s3avg.o
libm65.a: $(OBJS1)
ar cr libm65.a $(OBJS1)
ranlib libm65.a
OBJS3 = m65.o m65a.o map65a.o symspec.o decode0.o ftninit.o ftnquit.o \
timer.o ipcomm.o sec_midn.o cutil.o
LIBS3 = -L'C:/wsjt-env/Qt5/5.2.1/mingw48_32/lib' -lQt5Core
m65.exe: $(OBJS3) libm65.a
$(CXX) -o m65.exe $(OBJS3) $(LIBS3) libm65.a ../libfftw3f_win.a \
c:/MinGW/lib/libf95.a
cp m65.exe ../../map65_install
OBJS2 = JT65code.o
JT65code.exe: $(OBJS2) libm65.a
$(FC) -o JT65code.exe $(OBJS2) libm65.a
OBJS7 = astrosub.o astro0.o astro.o tm2.o grid2deg.o sun.o moondop.o \
coord.o dot.o moon2.o tmoonsub.o toxyz.o geocentric.o \
dcoord.o
libastro.a: $(OBJS7)
ar cr libastro.a $(OBJS7)
ranlib libastro.a
OBJS6 = mapsim.o cgen65.o noisegen.o gran.o
mapsim.exe: $(OBJS6) libm65.a
$(FC) -o mapsim.exe $(OBJS6) libm65.a
INCPATH = -I'C:/wsjt-env/Qt5/5.2.1/mingw48_32/include/QtCore' \
-I'C:/wsjt-env/Qt5/5.2.1/mingw48_32/include'
ipcomm.o: ipcomm.cpp
$(CXX) -c $(INCPATH) ipcomm.cpp
#m65a.o: m65a.f90
# $(FC) -c -fno-second-underscore -cpp m65a.f90
sec_midn.o: sec_midn.f90
$(FC) -c -fno-second-underscore sec_midn.f90
#symspec.o: ../symspec.f90
# $(FC) -c $(FFLAGS) -o symspec.o ../symspec.f90
OBJS4 = tastro.o astro0.o libm65.a
tastro.exe: $(OBJS4)
$(FC) $(FFLAGS) -o tastro.exe $(OBJS4) libm65.a
OBJS5 = t1.o timer.o libm65.a
t1.exe: $(OBJS5)
$(FC) $(FFLAGS) -o t1.exe $(OBJS5) libm65.a
#astro0.o: ../astro0.f90
# $(FC) -c $(FFLAGS) -o astro0.o ../astro0.f90
init_rs.o: init_rs.c
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
encode_rs.o: encode_rs.c
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
decode_rs.o: decode_rs.c
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
.PHONY : clean
clean:
rm -f *.o libm65.a m65.exe jt65code.exe

129
map65/libm65/Makefile.jtsdk Normal file
View File

@ -0,0 +1,129 @@
# Makefile for MinGW on Windows
CC = c:/JTSDK/Qt55/Tools/mingw492_32/bin/gcc
FC = c:/JTSDK/Qt55/Tools/mingw492_32/bin/gfortran
CXX = c:/JTSDK/Qt55/Tools/mingw492_32/bin/g++
FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion -Wno-precision-loss \
-fno-second-underscore -fbacktrace \
-ffpe-summary=none
# -ffpe-trap=invalid,zero,overflow,underflow,denormal
CFLAGS = -I. -fbounds-check
# Default rules
%.o: %.c
${CC} ${CFLAGS} -c $<
%.o: %.f
${FC} ${FFLAGS} -c $<
%.o: %.F
${FC} ${FFLAGS} -c $<
%.o: %.f90
${FC} ${FFLAGS} -c $<
%.o: %.F90
${FC} ${FFLAGS} -c $<
all: packjt.o wavhdr.o libm65.a m65.exe mapsim.exe libastro.a
OBJS1 = trimlist.o display.o getdphi.o pctile.o ccf65.o \
decode1a.o sort.o filbig.o fil6521.o afc65b.o \
twkfreq.o decode65b.o indexx.o ssort.o fchisq.o setup65.o \
extract.o deep65.o ccf2.o demod64a.o chkhist.o graycode.o \
interleave63.o encode65.o igray.o set.o shell.o qra64_subs.o \
grid2k.o getpfx2.o q65b.o qra64c.o twkfreq_xy.o qra64zap.o \
deg2grid.o getpfx1.o k2grid.o ftrsd2.o graycode65.o \
wrapkarn.o nchar.o init_rs.o encode_rs.o decode_rs.o \
four2a.o rfile3a.o grid2deg.o pfxdump.o dpol.o sync64.o spec64.o \
astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \
geocentric.o moon2.o toxyz.o dot.o dcoord.o f77_wisdom.o \
gen65.o chkmsg.o ptt.o astrosub.o astro0.o recvpkt.o symspec.o \
iqcal.o iqfix.o timf2.o s3avg.o packjt.o badmsg.o fmtmsg.o \
qracodes.o qra64.o smo.o averms.o lorentzian.o npfwht.o pdmath.o \
qra13_64_64_irr_e.o fchisq0.o genqra64a.o wavhdr.o
packjt.o: packjt.f90
$(FC) -c packjt.f90
libm65.a: $(OBJS1)
ar cr libm65.a $(OBJS1)
ranlib libm65.a
qra64_subs.o: ./qra64/qra64_subs.c
gcc -c -O2 -o qra64_subs.o ./qra64/qra64_subs.c
qracodes.o: qracodes/qracodes.c
gcc -c -O2 -o qracodes.o qracodes/qracodes.c
qra64.o: qra64/qra64.c
gcc -c -O2 -o qra64.o qra64/qra64.c
qra13_64_64_irr_e.o: qracodes/qra13_64_64_irr_e.c
gcc -c -O2 -o qra13_64_64_irr_e.o \
qracodes/qra13_64_64_irr_e.c
npfwht.o: qracodes/npfwht.c
gcc -c -O2 -o npfwht.o qracodes/npfwht.c
pdmath.o: qracodes/pdmath.c
gcc -c -O2 -o pdmath.o qracodes/pdmath.c
OBJS3 = m65.o m65a.o map65a.o symspec.o decode0.o ftninit.o ftnquit.o \
timer.o ipcomm.o sec_midn.o usleep.o
# cutil.o
LIBS3 = -L'C:/JTSDK/Qt55/5.5/mingw492_32/lib' -lQt5Core
m65.exe: $(OBJS3) libm65.a
$(CXX) -o m65.exe $(OBJS3) $(LIBS3) libm65.a ../libfftw3f_win.a \
-lgfortran
cp m65.exe ../../map65_install
OBJS7 = astrosub.o astro0.o astro.o tm2.o grid2deg.o sun.o moondop.o \
coord.o dot.o moon2.o tmoonsub.o toxyz.o geocentric.o \
dcoord.o
libastro.a: $(OBJS7)
ar cr libastro.a $(OBJS7)
ranlib libastro.a
OBJS6 = mapsim.o cgen65.o noisegen.o gran.o
mapsim.exe: $(OBJS6) libm65.a
$(FC) -o mapsim.exe $(OBJS6) libm65.a
INCPATH = -I'C:/JTSDK/Qt55/5.5/mingw492_32/include/QtCore' \
-I'C:/JTSDK/Qt55/5.5/mingw492_32/include'
ipcomm.o: ipcomm.cpp
$(CXX) -c $(INCPATH) ipcomm.cpp
#m65a.o: m65a.f90
# $(FC) -c -fno-second-underscore -cpp m65a.f90
sec_midn.o: sec_midn.f90
$(FC) -c -fno-second-underscore sec_midn.f90
#symspec.o: ../symspec.f90
# $(FC) -c $(FFLAGS) -o symspec.o ../symspec.f90
OBJS4 = tastro.o astro0.o libm65.a
tastro.exe: $(OBJS4)
$(FC) $(FFLAGS) -o tastro.exe $(OBJS4) libm65.a
OBJS5 = t1.o timer.o libm65.a
t1.exe: $(OBJS5)
$(FC) $(FFLAGS) -o t1.exe $(OBJS5) libm65.a
#astro0.o: ../astro0.f90
# $(FC) -c $(FFLAGS) -o astro0.o ../astro0.f90
init_rs.o: init_rs.c
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
encode_rs.o: encode_rs.c
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
decode_rs.o: decode_rs.c
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
.PHONY : clean
clean:
rm -f *.o *.mod libm65.a m65.exe

View File

@ -0,0 +1,96 @@
CC = gcc
FC = gfortran
FFLAGS = -O2 -fbounds-check -Wall
# For ptt_unix:
CFLAGS = -I. -fbounds-check -DHAVE_STDLIB_H=1 -DHAVE_STDIO_H=1 \
-DHAVE_FCNTL_H=1 -DHAVE_SYS_IOCTL_H=1
# Default rules
%.o: %.c
${CC} ${CFLAGS} -c $<
%.o: %.f
${FC} ${FFLAGS} -c $<
%.o: %.F
${FC} ${FFLAGS} -c $<
%.o: %.f90
${FC} ${FFLAGS} -c $<
%.o: %.F90
${FC} ${FFLAGS} -c $<
all: libm65.a m65
OBJS1 = trimlist.o display.o getdphi.o pctile.o ccf65.o \
decode1a.o sort.o filbig.o fil6521.o afc65b.o \
twkfreq.o decode65b.o indexx.o ssort.o fchisq.o setup65.o \
extract.o deep65.o ccf2.o demod64a.o chkhist.o graycode.o \
interleave63.o unpackmsg.o encode65.o igray.o set.o unpackcall.o \
unpackgrid.o grid2k.o unpacktext.o getpfx2.o packmsg.o \
deg2grid.o packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
wrapkarn.o nchar.o init_rs.o encode_rs.o decode_rs.o \
four2a.o rfile3a.o grid2deg.o pfxdump.o dpol.o \
astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \
geocentric.o moon2.o toxyz.o dot.o dcoord.o f77_wisdom.o \
gen65.o chkmsg.o ptt_unix.o astrosub.o astro0.o recvpkt.o \
symspec.o iqcal.o iqfix.o timf2.o s3avg.o
libm65.a: $(OBJS1)
ar cr libm65.a $(OBJS1)
ranlib libm65.a
OBJS3 = m65.o m65a.o map65a.o symspec.o decode0.o ftninit.o ftnquit.o \
timer.o ipcomm.o sec_midn.o cutil.o
m65: $(OBJS3) libm65.a
g++ -o m65 $(OBJS3) libm65.a -lfftw3f -lQtCore -lfftw3f -lgfortran
OBJS2 = m65a.o ipcomm.o sec_midn.o cutil.o decode0.o map65a.o \
timer.o ftninit.o ftnquit.o
LIBS2 = -lQtCore -lfftw3f -lgfortran
m65a: $(OBJS2) libm65.a
g++ -o m65a $(OBJS2) libm65.a -lQtCore -lfftw3f -lgfortran
OBJS6 = t3.o ipcomm.o
LIBS2 = -lQtCore -lgfortran
t3: $(OBJS6)
g++ -o t3 $(OBJS6) $(LIBS2)
t3:
INCPATH = -I. -I'/usr/include/qt4' -I'/usr/include/qt4/QtCore'
ipcomm.o: ipcomm.cpp
g++ -c $(INCPATH) ipcomm.cpp
m65a.o: m65a.F90
$(FC) -c -fno-second-underscore -DUNIX m65a.F90
extract.o: extract.F
$(FC) -c -fno-second-underscore -DUNIX extract.F
sec_midn.o: sec_midn.f90
$(FC) -c -fno-second-underscore sec_midn.f90
OBJS4 = tastro.o astro0.o libm65.a
tastro: $(OBJS4)
$(FC) $(FFLAGS) -o tastro $(OBJS4) libm65.a
OBJS5 = t1.o timer.o libm65.a
t1: $(OBJS5)
$(FC) $(FFLAGS) -o t1 $(OBJS5) libm65.a
init_rs.o: init_rs.c
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
encode_rs.o: encode_rs.c
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
decode_rs.o: decode_rs.c
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
.PHONY : clean
clean:
rm -f *.o libm65.a m65 m65a

70
map65/libm65/afc65b.f90 Normal file
View File

@ -0,0 +1,70 @@
subroutine afc65b(cx,cy,npts,fsample,nflip,ipol,xpol,ndphi,a,ccfbest,dtbest)
logical xpol
complex cx(npts)
complex cy(npts)
real a(5),deltaa(5)
a(1)=0.
a(2)=0.
a(3)=0.
a(4)=45.0*(ipol-1.0)
deltaa(1)=2.0
deltaa(2)=2.0
deltaa(3)=2.0
deltaa(4)=22.5
deltaa(5)=0.05
nterms=3
if(xpol) nterms=4
! Don't fit polarization when solving for dphi
if(ndphi.ne.0) nterms=3
! Start the iteration
chisqr=0.
chisqr0=1.e6
do iter=1,3 !One iteration is enough?
do j=1,nterms
chisq1=fchisq(cx,cy,npts,fsample,nflip,a,ccfmax,dtmax)
fn=0.
delta=deltaa(j)
10 a(j)=a(j)+delta
chisq2=fchisq(cx,cy,npts,fsample,nflip,a,ccfmax,dtmax)
if(chisq2.eq.chisq1) go to 10
if(chisq2.gt.chisq1) then
delta=-delta !Reverse direction
a(j)=a(j)+delta
tmp=chisq1
chisq1=chisq2
chisq2=tmp
endif
20 fn=fn+1.0
a(j)=a(j)+delta
chisq3=fchisq(cx,cy,npts,fsample,nflip,a,ccfmax,dtmax)
if(chisq3.lt.chisq2) then
chisq1=chisq2
chisq2=chisq3
go to 20
endif
! Find minimum of parabola defined by last three points
delta=delta*(1./(1.+(chisq1-chisq2)/(chisq3-chisq2))+0.5)
a(j)=a(j)-delta
deltaa(j)=deltaa(j)*fn/3.
enddo
chisqr=fchisq(cx,cy,npts,fsample,nflip,a,ccfmax,dtmax)
if(chisqr/chisqr0.gt.0.9999) go to 30
chisqr0=chisqr
enddo
30 ccfbest=ccfmax * (1378.125/fsample)**2
dtbest=dtmax
if(a(4).lt.0.0) a(4)=a(4)+180.0
if(a(4).ge.180.0) a(4)=a(4)-180.0
if(nint(a(4)).eq.180) a(4)=0.
ipol=nint(a(4)/45.0) + 1
if(ipol.gt.4) ipol=ipol-4
return
end subroutine afc65b

105
map65/libm65/astro.f90 Normal file
View File

@ -0,0 +1,105 @@
subroutine astro(nyear,month,nday,uth,nfreq,Mygrid,NStation,MoonDX, &
AzSun,ElSun,AzMoon0,ElMoon0,ntsky,doppler00,doppler,dbMoon,RAMoon, &
DecMoon,HA,Dgrd,sd,poloffset,xnr,day,lon,lat,LST)
! Computes astronomical quantities for display and tracking.
! NB: may want to smooth the Tsky map to 10 degrees or so.
character*6 MyGrid,HisGrid
real LST
real lat,lon
integer*2 nt144(180)
! common/echo/xdop(2),techo,AzMoon,ElMoon,mjd
real xdop(2)
data rad/57.2957795/
data nt144/ &
234, 246, 257, 267, 275, 280, 283, 286, 291, 298, &
305, 313, 322, 331, 341, 351, 361, 369, 376, 381, &
383, 382, 379, 374, 370, 366, 363, 361, 363, 368, &
376, 388, 401, 415, 428, 440, 453, 467, 487, 512, &
544, 579, 607, 618, 609, 588, 563, 539, 512, 482, &
450, 422, 398, 379, 363, 349, 334, 319, 302, 282, &
262, 242, 226, 213, 205, 200, 198, 197, 196, 197, &
200, 202, 204, 205, 204, 203, 202, 201, 203, 206, &
212, 218, 223, 227, 231, 236, 240, 243, 247, 257, &
276, 301, 324, 339, 346, 344, 339, 331, 323, 316, &
312, 310, 312, 317, 327, 341, 358, 375, 392, 407, &
422, 437, 451, 466, 480, 494, 511, 530, 552, 579, &
612, 653, 702, 768, 863,1008,1232,1557,1966,2385, &
2719,2924,3018,3038,2986,2836,2570,2213,1823,1461, &
1163, 939, 783, 677, 602, 543, 494, 452, 419, 392, &
373, 360, 353, 350, 350, 350, 350, 350, 350, 348, &
344, 337, 329, 319, 307, 295, 284, 276, 272, 272, &
273, 274, 274, 271, 266, 260, 252, 245, 238, 231/
save
call grid2deg(MyGrid,elon,lat)
lon=-elon
call sun(nyear,month,nday,uth,lon,lat,RASun,DecSun,LST,AzSun,ElSun,mjd,day)
freq=nfreq*1.e6
if(nfreq.eq.2) freq=1.8e6
if(nfreq.eq.4) freq=3.5e6
call MoonDop(nyear,month,nday,uth,lon,lat,RAMoon,DecMoon,LST,HA, &
AzMoon,ElMoon,vr,dist)
! Compute spatial polarization offset
xx=sin(lat/rad)*cos(ElMoon/rad) - cos(lat/rad)*cos(AzMoon/rad)*sin(ElMoon/rad)
yy=cos(lat/rad)*sin(AzMoon/rad)
if(NStation.eq.1) poloffset1=rad*atan2(yy,xx)
if(NStation.eq.2) poloffset2=rad*atan2(yy,xx)
techo=2.0 * dist/2.99792458e5 !Echo delay time
doppler=-freq*vr/2.99792458e5 !One-way Doppler
call coord(0.,0.,-1.570796,1.161639,RAMoon/rad,DecMoon/rad,el,eb)
longecl_half=nint(rad*el/2.0)
if(longecl_half.lt.1 .or. longecl_half.gt.180) longecl_half=180
t144=nt144(longecl_half)
tsky=(t144-2.7)*(144.0/nfreq)**2.6 + 2.7 !Tsky for obs freq
xdop(NStation)=doppler
if(NStation.eq.2) then
HisGrid=MyGrid
go to 900
endif
doppler00=2.0*xdop(1)
doppler=xdop(1)+xdop(2)
! if(mode.eq.3) doppler=2.0*xdop(1)
dBMoon=-40.0*log10(dist/356903.)
sd=16.23*370152.0/dist
! if(NStation.eq.1 .and. MoonDX.ne.0 .and.
! + (mode.eq.2 .or. mode.eq.5)) then
if(NStation.eq.1 .and. MoonDX.ne.0) then
poloffset=mod(poloffset2-poloffset1+720.0,180.0)
if(poloffset.gt.90.0) poloffset=poloffset-180.0
x1=abs(cos(2*poloffset/rad))
if(x1.lt.0.056234) x1=0.056234
xnr=-20.0*log10(x1)
if(HisGrid(1:1).lt.'A' .or. HisGrid(1:1).gt.'R') xnr=0
endif
tr=80.0 !Good preamp
tskymin=13.0*(408.0/nfreq)**2.6 !Cold sky temperature
tsysmin=tskymin+tr
tsys=tsky+tr
dgrd=-10.0*log10(tsys/tsysmin) + dbMoon
900 AzMoon0=Azmoon
ElMoon0=Elmoon
ntsky=nint(tsky)
! auxHA = 15.0*(LST-auxra) !HA in degrees
! pi=3.14159265
! pio2=0.5*pi
! call coord(pi,pio2-lat/rad,0.0,lat/rad,auxha*pi/180.0,
! + auxdec/rad,azaux,elaux)
! AzAux=azaux*rad
! ElAux=ElAux*rad
return
end subroutine astro

81
map65/libm65/astro0.f90 Normal file
View File

@ -0,0 +1,81 @@
subroutine astro0(nyear,month,nday,uth8,nfreq,mygrid,hisgrid, &
AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, &
dbMoon8,RAMoon8,DecMoon8,HA8,Dgrd8,sd8,poloffset8,xnr8,dfdt,dfdt0, &
width1,width2,w501,w502,xlst8)
parameter (DEGS=57.2957795130823d0)
character*6 mygrid,hisgrid
real*8 AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8
real*8 dbMoon8,RAMoon8,DecMoon8,HA8,Dgrd8,xnr8,dfdt,dfdt0,dt
real*8 sd8,poloffset8,day8,width1,width2,w501,w502,xlst8
real*8 uth8
data uth8z/0.d0/
save
uth=uth8
call astro(nyear,month,nday,uth,nfreq,hisgrid,2,1, &
AzSun,ElSun,AzMoon,ElMoon,ntsky,doppler00,doppler, &
dbMoon,RAMoon,DecMoon,HA,Dgrd,sd,poloffset,xnr, &
day,xlon2,xlat2,xlst)
AzMoonB8=AzMoon
ElMoonB8=ElMoon
call astro(nyear,month,nday,uth,nfreq,mygrid,1,1, &
AzSun,ElSun,AzMoon,ElMoon,ntsky,doppler00,doppler, &
dbMoon,RAMoon,DecMoon,HA,Dgrd,sd,poloffset,xnr, &
day,xlon1,xlat1,xlst)
day8=day
xlst8=xlst
call tm2(day8,xlat1,xlon1,xl1,b1)
call tm2(day8,xlat2,xlon2,xl2,b2)
call tm2(day8+1.d0/1440.0,xlat1,xlon1,xl1a,b1a)
call tm2(day8+1.d0/1440.0,xlat2,xlon2,xl2a,b2a)
fghz=0.001*nfreq
dldt1=DEGS*(xl1a-xl1)
dbdt1=DEGS*(b1a-b1)
dldt2=DEGS*(xl2a-xl2)
dbdt2=DEGS*(b2a-b2)
rate1=2.0*sqrt(dldt1**2 + dbdt1**2)
width1=0.5*6741*fghz*rate1
rate2=sqrt((dldt1+dldt2)**2 + (dbdt1+dbdt2)**2)
width2=0.5*6741*fghz*rate2
fbend=0.7
a2=0.0045*log(fghz/fbend)/log(1.05)
if(fghz.lt.fbend) a2=0.0
f50=0.19 * (fghz/fbend)**a2
if(f50.gt.1.0) f50=1.0
w501=f50*width1
w502=f50*width2
AzSun8=AzSun
ElSun8=ElSun
AzMoon8=AzMoon
ElMoon8=ElMoon
dbMoon8=dbMoon
RAMoon8=RAMoon/15.0
DecMoon8=DecMoon
HA8=HA
Dgrd8=Dgrd
sd8=sd
poloffset8=poloffset
xnr8=xnr
ndop=nint(doppler)
ndop00=nint(doppler00)
if(uth8z.eq.0.d0) then
uth8z=uth8-1.d0/3600.d0
dopplerz=doppler
doppler00z=doppler00
endif
dt=60.0*(uth8-uth8z)
if(dt.le.0) dt=1.d0/60.d0
dfdt=(doppler-dopplerz)/dt
dfdt0=(doppler00-doppler00z)/dt
uth8z=uth8
dopplerz=doppler
doppler00z=doppler00
return
end subroutine astro0

14
map65/libm65/astrosub.f90 Normal file
View File

@ -0,0 +1,14 @@
subroutine astrosub(nyear,month,nday,uth8,nfreq,mygrid,hisgrid, &
AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, &
RAMoon8,DecMoon8,Dgrd8,poloffset8,xnr8)
implicit real*8 (a-h,o-z)
character*6 mygrid,hisgrid
call astro0(nyear,month,nday,uth8,nfreq,mygrid,hisgrid, &
AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, &
dbMoon8,RAMoon8,DecMoon8,HA8,Dgrd8,sd8,poloffset8,xnr8,dfdt,dfdt0, &
width1,width2,w501,w502,xlst8)
return
end subroutine astrosub

20
map65/libm65/averms.f90 Normal file
View File

@ -0,0 +1,20 @@
subroutine averms(x,n,nskip,ave,rms)
real x(n)
integer ipk(1)
ns=0
s=0.
sq=0.
ipk=maxloc(x)
do i=1,n
if(abs(i-ipk(1)).gt.nskip) then
s=s + x(i)
sq=sq + x(i)**2
ns=ns+1
endif
enddo
ave=s/ns
rms=sqrt(sq/ns - ave*ave)
return
end subroutine averms

46
map65/libm65/badmsg.f90 Normal file
View File

@ -0,0 +1,46 @@
subroutine badmsg(irc,dat,nc1,nc2,ng2)
! Get rid of a few QRA64 false decodes that cannot be correct messages.
integer dat(12) !Decoded message (as 12 integers)
ic1=ishft(dat(1),22) + ishft(dat(2),16) + ishft(dat(3),10)+ &
ishft(dat(4),4) + iand(ishft(dat(5),-2),15)
! Test for "......" or "CQ 000"
if(ic1.eq.262177560 .or. ic1.eq.262177563) then
irc=-1
return
endif
ic2=ishft(iand(dat(5),3),26) + ishft(dat(6),20) + &
ishft(dat(7),14) + ishft(dat(8),8) + ishft(dat(9),2) + &
iand(ishft(dat(10),-4),3)
ig=ishft(iand(dat(10),15),12) + ishft(dat(11),6) + dat(12)
! Test for blank, -01 to -30, R-01 to R-30, RO, RRR, 73
if(ig.ge.32401 .and. ig.le.32464) return
if(ig.ge.14220 .and. ig.le.14229) return !-41 to -50
if(ig.ge.14040 .and. ig.le.14049) return !-31 to -40
if(ig.ge.13320 .and. ig.le.13329) return !+00 to +09
if(ig.ge.13140 .and. ig.le.13149) return !+10 to +19
if(ig.ge.12960 .and. ig.le.12969) return !+20 to +29
if(ig.ge.12780 .and. ig.le.12789) return !+30 to +39
if(ig.ge.12600 .and. ig.le.12609) return !+40 to +49
if(ig.ge.12420 .and. ig.le.12429) return !R-41 to R-50
if(ig.ge.12240 .and. ig.le.12249) return !R-31 to R-40
if(ig.ge.11520 .and. ig.le.11529) return !R+00 to R+09
if(ig.ge.11340 .and. ig.le.11349) return !R+10 to R+19
if(ig.ge.11160 .and. ig.le.11169) return !R+20 to R+29
if(ig.ge.10980 .and. ig.le.10989) return !R+30 to R+39
if(ig.ge.10800 .and. ig.le.10809) return !R+40 to R+49
if(ic1.eq.nc1 .and. ic2.eq.nc2 .and. ng2.ne.32401 .and. ig.ne.ng2) irc=-1
return
end subroutine badmsg

45
map65/libm65/ccf2.f90 Normal file
View File

@ -0,0 +1,45 @@
subroutine ccf2(ss,nz,nflip,ccfbest,lagpk)
! parameter (LAGMAX=60)
parameter (LAGMAX=200)
real ss(nz)
real ccf(-LAGMAX:LAGMAX)
integer npr(126)
! The JT65 pseudo-random sync pattern:
data npr/ &
1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, &
0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, &
0,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,0,1,1, &
0,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,1, &
1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1, &
0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, &
1,1,1,1,1,1/
save
ccfbest=0.
lag1=-LAGMAX
lag2=LAGMAX
do lag=lag1,lag2
s0=0.
s1=0.
do i=1,126
j=2*(8*i + 43) + lag
if(j.ge.1 .and. j.le.nz-8) then
x=ss(j)+ss(j+8) !Add two half-symbol contributions
if(npr(i).eq.0) then
s0=s0 + x
else
s1=s1 + x
endif
endif
enddo
ccf(lag)=nflip*(s1-s0)
if(ccf(lag).gt.ccfbest) then
ccfbest=ccf(lag)
lagpk=lag
endif
enddo
return
end subroutine ccf2

128
map65/libm65/ccf65.f90 Normal file
View File

@ -0,0 +1,128 @@
subroutine ccf65(ss,nhsym,ssmax,sync1,ipol1,jpz,dt1,flipk, &
syncshort,snr2,ipol2,dt2)
parameter (NFFT=512,NH=NFFT/2)
real ss(4,322) !Input: half-symbol powers, 4 pol'ns
real s(NFFT) !CCF = ss*pr
complex cs(0:NH) !Complex FT of s
real s2(NFFT) !CCF = ss*pr2
complex cs2(0:NH) !Complex FT of s2
real pr(NFFT) !JT65 pseudo-random sync pattern
complex cpr(0:NH) !Complex FT of pr
real pr2(NFFT) !JT65 shorthand pattern
complex cpr2(0:NH) !Complex FT of pr2
real tmp1(322)
real ccf(-11:54,4)
logical first
integer npr(126)
data first/.true./
equivalence (s,cs),(pr,cpr),(s2,cs2),(pr2,cpr2)
save
! The JT65 pseudo-random sync pattern:
data npr/ &
1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, &
0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, &
0,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,0,1,1, &
0,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,1, &
1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1, &
0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, &
1,1,1,1,1,1/
if(first) then
! Initialize pr, pr2; compute cpr, cpr2.
fac=1.0/NFFT
do i=1,NFFT
pr(i)=0.
pr2(i)=0.
k=2*mod((i-1)/8,2)-1
if(i.le.NH) pr2(i)=fac*k
enddo
do i=1,126
j=2*i
pr(j)=fac*(2*npr(i)-1)
! Not sure why, but it works significantly better without the following line:
! pr(j-1)=pr(j)
enddo
call four2a(cpr,NFFT,1,-1,0)
call four2a(cpr2,NFFT,1,-1,0)
first=.false.
endif
syncshort=0.
snr2=0.
! Look for JT65 sync pattern and shorthand square-wave pattern.
ccfbest=0.
ccfbest2=0.
ipol1=1
ipol2=1
do ip=1,jpz !Do jpz polarizations
do i=1,nhsym-1
! s(i)=ss(ip,i)+ss(ip,i+1)
s(i)=min(ssmax,ss(ip,i)+ss(ip,i+1))
enddo
call pctile(s,nhsym-1,50,base)
s(1:nhsym-1)=s(1:nhsym-1)-base
s(nhsym:NFFT)=0.
call four2a(cs,NFFT,1,-1,0) !Real-to-complex FFT
do i=0,NH
cs2(i)=cs(i)*conjg(cpr2(i)) !Mult by complex FFT of pr2
cs(i)=cs(i)*conjg(cpr(i)) !Mult by complex FFT of pr
enddo
call four2a(cs,NFFT,1,1,-1) !Complex-to-real inv-FFT
call four2a(cs2,NFFT,1,1,-1) !Complex-to-real inv-FFT
do lag=-11,54 !Check for best JT65 sync
j=lag
if(j.lt.1) j=j+NFFT
ccf(lag,ip)=s(j)
if(abs(ccf(lag,ip)).gt.ccfbest) then
ccfbest=abs(ccf(lag,ip))
lagpk=lag
ipol1=ip
flipk=1.0
if(ccf(lag,ip).lt.0.0) flipk=-1.0
endif
enddo
!### Not sure why this is ever true???
if(sum(ccf).eq.0.0) return
!###
do lag=-11,54 !Check for best shorthand
ccf2=s2(lag+28)
if(ccf2.gt.ccfbest2) then
ccfbest2=ccf2
lagpk2=lag
ipol2=ip
endif
enddo
enddo
! Find rms level on baseline of "ccfblue", for normalization.
sumccf=0.
do lag=-11,54
if(abs(lag-lagpk).gt.1) sumccf=sumccf + ccf(lag,ipol1)
enddo
base=sumccf/50.0
sq=0.
do lag=-11,54
if(abs(lag-lagpk).gt.1) sq=sq + (ccf(lag,ipol1)-base)**2
enddo
rms=sqrt(sq/49.0)
sync1=-4.0
if(rms.gt.0.0) sync1=ccfbest/rms - 4.0
dt1=lagpk*(2048.0/11025.0) - 2.5
! Find base level for normalizing snr2.
do i=1,nhsym
tmp1(i)=ss(ipol2,i)
enddo
call pctile(tmp1,nhsym,40,base)
snr2=0.01
if(base.gt.0.0) snr2=0.398107*ccfbest2/base !### empirical
syncshort=0.5*ccfbest2/rms - 4.0 !### better normalizer than rms?
dt2=2.5 + lagpk2*(2048.0/11025.0)
return
end subroutine ccf65

99
map65/libm65/cgen65.f90 Normal file
View File

@ -0,0 +1,99 @@
subroutine cgen65(message,mode65,samfac,nsendingsh,msgsent,cwave,nwave)
! Encodes a JT65 message into a wavefile.
! Executes in 17 ms on opti-745.
use packjt
parameter (NMAX=60*96000) !Max length of wave file
character*22 message !Message to be generated
character*22 msgsent !Message as it will be received
character*3 cok !' ' or 'OOO'
real*8 t,dt,phi,f,f0,dfgen,dphi,twopi,samfac,tsymbol
complex cwave(NMAX) !Generated complex wave file
integer dgen(12)
integer sent(63)
logical first
integer nprc(126)
real pr(126)
data nprc/1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, &
0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, &
0,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,0,1,1, &
0,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,1, &
1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1, &
0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, &
1,1,1,1,1,1/
data twopi/6.283185307179586476d0/,first/.true./
save
if(first) then
do i=1,126
pr(i)=2*nprc(i)-1
enddo
first=.false.
endif
call chkmsg(message,cok,nspecial,flip) !See if it's a shorthand
if(nspecial.eq.0) then
call packmsg(message,dgen,itype) !Pack message into 72 bits
nsendingsh=0
if(iand(dgen(10),8).ne.0) nsendingsh=-1 !Plain text flag
call rs_encode(dgen,sent)
call interleave63(sent,1) !Apply interleaving
call graycode(sent,63,1) !Apply Gray code
nsym=126 !Symbols per transmission
tsymbol=4096.d0/11025.d0 !Time per symbol
else
nsendingsh=1 !Flag for shorthand message
nsym=32
tsymbol=16384.d0/11025.d0
endif
! Set up necessary constants
dt=1.d0/(samfac*96000.d0)
f0=118*11025.d0/1024
dfgen=mode65*11025.d0/4096.d0
t=0.d0
phi=0.d0
k=0
j0=0
ndata=nsym*96000.d0*samfac*tsymbol
do i=1,ndata
t=t+dt
j=int(t/tsymbol) + 1 !Symbol number, 1-126
if(j.ne.j0) then
f=f0
if(nspecial.ne.0 .and. mod(j,2).eq.0) f=f0+10*nspecial*dfgen
if(nspecial.eq.0 .and. flip*pr(j).lt.0.0) then
k=k+1
f=f0+(sent(k)+2)*dfgen
endif
dphi=twopi*dt*f
j0=j
endif
phi=phi+dphi
if(phi.gt.twopi) phi=phi-twopi
xphi=phi
cwave(i)=cmplx(cos(xphi),-sin(xphi))
enddo
cwave(ndata+1:)=0
nwave=ndata + 48000
call unpackmsg(dgen,msgsent)
if(flip.lt.0.0) then
do i=22,1,-1
if(msgsent(i:i).ne.' ') goto 10
enddo
10 msgsent=msgsent(1:i)//' OOO'
endif
if(nsendingsh.eq.1) then
if(nspecial.eq.2) msgsent='RO'
if(nspecial.eq.3) msgsent='RRR'
if(nspecial.eq.4) msgsent='73'
endif
return
end subroutine cgen65

23
map65/libm65/chkhist.f90 Normal file
View File

@ -0,0 +1,23 @@
subroutine chkhist(mrsym,nmax,ipk)
integer mrsym(63)
integer hist(0:63)
do i=0,63
hist(i)=0
enddo
do j=1,63
i=mrsym(j)
hist(i)=hist(i)+1
enddo
nmax=0
do i=0,63
if(hist(i).gt.nmax) then
nmax=hist(i)
ipk=i+1
endif
enddo
return
end subroutine chkhist

31
map65/libm65/chkmsg.f90 Normal file
View File

@ -0,0 +1,31 @@
subroutine chkmsg(message,cok,nspecial,flip)
character message*22,cok*3
nspecial=0
flip=1.0
cok=" "
do i=22,1,-1
if(message(i:i).ne.' ') go to 10
enddo
i=22
10 if(i.ge.11) then
if ((message(i-3:i).eq.' OOO') .or. (message(20:22).eq.' OO')) then
cok='OOO'
flip=-1.0
if(message(20:22).eq.' OO') then
message=message(1:19)
else
message=message(1:i-4)
endif
endif
endif
if(message(1:3).eq.'RO ') nspecial=2
if(message(1:4).eq.'RRR ') nspecial=3
if(message(1:3).eq.'73 ') nspecial=4
return
end subroutine chkmsg

40
map65/libm65/coord.f90 Normal file
View File

@ -0,0 +1,40 @@
SUBROUTINE COORD(A0,B0,AP,BP,A1,B1,A2,B2)
! Examples:
! 1. From ha,dec to az,el:
! call coord(pi,pio2-lat,0.,lat,ha,dec,az,el)
! 2. From az,el to ha,dec:
! call coord(pi,pio2-lat,0.,lat,az,el,ha,dec)
! 3. From ra,dec to l,b
! call coord(4.635594495,-0.504691042,3.355395488,0.478220215,
! ra,dec,l,b)
! 4. From l,b to ra,dec
! call coord(1.705981071d0,-1.050357016d0,2.146800277d0,
! 0.478220215d0,l,b,ra,dec)
! 5. From ra,dec to ecliptic latitude (eb) and longitude (el):
! call coord(0.d0,0.d0,-pio2,pio2-23.443*pi/180,ra,dec,el,eb)
! 6. From ecliptic latitude (eb) and longitude (el) to ra,dec:
! call coord(0.d0,0.d0,-pio2,pio2-23.443*pi/180,el,eb,ra,dec)
SB0=sin(B0)
CB0=cos(B0)
SBP=sin(BP)
CBP=cos(BP)
SB1=sin(B1)
CB1=cos(B1)
SB2=SBP*SB1 + CBP*CB1*cos(AP-A1)
CB2=SQRT(1.e0-SB2**2)
B2=atan(SB2/CB2)
SAA=sin(AP-A1)*CB1/CB2
CAA=(SB1-SB2*SBP)/(CB2*CBP)
CBB=SB0/CBP
SBB=sin(AP-A0)*CB0
SA2=SAA*CBB-CAA*SBB
CA2=CAA*CBB+SAA*SBB
TA2O2=0.0 !Shut up compiler warnings. -db
IF(CA2.LE.0.e0) TA2O2=(1.e0-CA2)/SA2
IF(CA2.GT.0.e0) TA2O2=SA2/(1.e0+CA2)
A2=2.e0*atan(TA2O2)
IF(A2.LT.0.e0) A2=A2+6.2831853
RETURN
END SUBROUTINE COORD

93
map65/libm65/cutil.c Normal file
View File

@ -0,0 +1,93 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// #include <sys/times.h>
// #include <time.h>
// #include <sys/time.h>
#include "sleep.h"
#include "timeval.h"
/* FORTRAN: fd = close(filedes) */
int close_(int *filedes)
{
return(close(*filedes));
}
/* FORTRAN: fd = open(filnam,mode) */
int open_(char filnam[], int *mode)
{
return(open(filnam,*mode));
}
/* FORTRAN: fd = creat(filnam,mode) */
int creat_(char filnam[],int *mode)
{
return(creat(filnam,*mode));
}
/* FORTRAN: nread = read(fd,buf,n) */
int read_(int *fd, char buf[], int *n)
{
return(read(*fd,buf,*n));
}
/* FORTRAN: nwrt = write(fd,buf,n) */
int write_(int *fd, char buf[], int *n)
{
return(write(*fd,buf,*n));
}
/* FORTRAN: ns = lseek(fd,offset,origin) */
int lseek_(int *fd,int *offset, int *origin)
{
return(lseek(*fd,*offset,*origin));
}
/* times(2) */
//int times_(struct tms *buf)
//{
// return (times(buf));
//}
/* ioperm(2) */
//ioperm_(from,num,turn_on)
//unsigned long *from,*num,*turn_on;
//{
// return (ioperm(*from,*num,*turn_on));
// return (i386_get_ioperm(*from,*num,*turn_on));
//}
/* usleep(3) */
void usleep_(unsigned long *microsec)
{
usleep(*microsec);
}
/* returns random numbers between 0 and 32767 to FORTRAN program */
int iran_(int *arg)
{
return (rand());
}
int exit_(int *n)
{
printf("\n\n");
exit(*n);
}
/*
struct tm *
gmtime_r_(const time_t *clock, struct tm *result)
{
gmtime_r(clock, result);
}
*/
time_t time_(void)
{
return time(0);
}
/* hrtime() */
double hrtime_(void)
{
struct timeval tv;
gettimeofday(&tv,NULL);
return(tv.tv_sec+1.e-6*tv.tv_usec);
}

40
map65/libm65/dcoord.f90 Normal file
View File

@ -0,0 +1,40 @@
SUBROUTINE DCOORD(A0,B0,AP,BP,A1,B1,A2,B2)
implicit real*8 (a-h,o-z)
! Examples:
! 1. From ha,dec to az,el:
! call coord(pi,pio2-lat,0.,lat,ha,dec,az,el)
! 2. From az,el to ha,dec:
! call coord(pi,pio2-lat,0.,lat,az,el,ha,dec)
! 3. From ra,dec to l,b
! call coord(4.635594495,-0.504691042,3.355395488,0.478220215,
! ra,dec,l,b)
! 4. From l,b to ra,dec
! call coord(1.705981071d0,-1.050357016d0,2.146800277d0,
! 0.478220215d0,l,b,ra,dec)
! 5. From ecliptic latitude (eb) and longitude (el) to ra, dec:
! call coord(0.d0,0.d0,-pio2,pio2-23.443*pi/180,ra,dec,el,eb)
SB0=sin(B0)
CB0=cos(B0)
SBP=sin(BP)
CBP=cos(BP)
SB1=sin(B1)
CB1=cos(B1)
SB2=SBP*SB1 + CBP*CB1*cos(AP-A1)
CB2=SQRT(1.D0-SB2**2)
B2=atan(SB2/CB2)
SAA=sin(AP-A1)*CB1/CB2
CAA=(SB1-SB2*SBP)/(CB2*CBP)
CBB=SB0/CBP
SBB=sin(AP-A0)*CB0
SA2=SAA*CBB-CAA*SBB
CA2=CAA*CBB+SAA*SBB
TA2O2=0.0 !Shut up compiler warnings. -db
IF(CA2.LE.0.D0) TA2O2=(1.D0-CA2)/SA2
IF(CA2.GT.0.D0) TA2O2=SA2/(1.D0+CA2)
A2=2.D0*atan(TA2O2)
IF(A2.LT.0.D0) A2=A2+6.2831853071795864D0
RETURN
END SUBROUTINE DCOORD

64
map65/libm65/decode0.f90 Normal file
View File

@ -0,0 +1,64 @@
subroutine decode0(dd,ss,savg,nstandalone)
use timer_module, only: timer
parameter (NSMAX=60*96000)
real*4 dd(4,NSMAX),ss(4,322,NFFT),savg(4,NFFT)
real*8 fcenter
integer hist(0:32768)
character mycall*12,hiscall*12,mygrid*6,hisgrid*6,datetime*20
character mycall0*12,hiscall0*12,hisgrid0*6
common/npar/fcenter,nutc,idphi,mousedf,mousefqso,nagain, &
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
nfast,nsave,max_drift,mycall,mygrid,hiscall,hisgrid,datetime
data neme0/-99/,mcall3b/1/
save
call timer('decode0 ',0)
if(newdat.ne.0) then
nz=52*96000
hist=0
do i=1,nz
j1=min(abs(dd(1,i)),32768.0)
hist(j1)=hist(j1)+1
j2=min(abs(dd(2,i)),32768.0)
hist(j2)=hist(j2)+1
j3=min(abs(dd(3,i)),32768.0)
hist(j3)=hist(j3)+1
j4=min(abs(dd(4,i)),32768.0)
hist(j4)=hist(j4)+1
enddo
m=0
do i=0,32768
m=m+hist(i)
if(m.ge.2*nz) go to 10
enddo
10 rmsdd=1.5*i
endif
nhsym=279
ndphi=0
if(iand(nrxlog,8).ne.0) ndphi=1
if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0 .or. &
hisgrid.ne.hisgrid0 .or. mcall3.ne.0 .or. neme.ne.neme0) mcall3b=1
mycall0=mycall
hiscall0=hiscall
hisgrid0=hisgrid
neme0=neme
call timer('map65a ',0)
call map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
mousedf,mousefqso,nagain,ndecdone,nfshift,ndphi,max_drift, &
nfcal,nkeep,mcall3b,nsum,nsave,nxant,mycall,mygrid, &
neme,ndepth,nstandalone,hiscall,hisgrid,nhsym,nfsample,nxpol,nmode)
call timer('map65a ',1)
call timer('decode0 ',1)
write(*,1010) nsum,nsave
1010 format('<DecodeFinished>',2i4)
flush(6)
return
end subroutine decode0

145
map65/libm65/decode1a.f90 Normal file
View File

@ -0,0 +1,145 @@
subroutine decode1a(dd,newdat,f0,nflip,mode65,nfsample,xpol, &
mycall,hiscall,hisgrid,neme,ndepth,nqd,dphi,ndphi, &
nutc,nkhz,ndf,ipol,ntol,sync2,a,dt,pol,nkv,nhist,nsum,nsave, &
qual,decoded)
! Apply AFC corrections to a candidate JT65 signal, then decode it.
use timer_module, only: timer
parameter (NMAX=60*96000) !Samples per 60 s
real*4 dd(4,NMAX) !92 MB: raw data from Linrad timf2
complex cx(NMAX/64), cy(NMAX/64) !Data at 1378.125 samples/s
complex c5x(NMAX/256),c5y(NMAX/256) !Data at 344.53125 Hz
complex c5a(512)
complex z
real s2(66,126)
real s3(64,63),sy(63)
real a(5)
logical first,xpol
character decoded*22
character mycall*12,hiscall*12,hisgrid*6
data first/.true./,jjjmin/1000/,jjjmax/-1000/
data nutc0/-999/,nhz0/-9999999/
save
! Mix sync tone to baseband, low-pass filter, downsample to 1378.125 Hz
dt00=dt
call timer('filbig ',0)
call filbig(dd,NMAX,f0,newdat,nfsample,xpol,cx,cy,n5)
! NB: cx, cy have sample rate 96000*77125/5376000 = 1378.125 Hz
call timer('filbig ',1)
if(mode65.eq.0) goto 900
sqa=0.
sqb=0.
do i=1,n5
sqa=sqa + real(cx(i))**2 + aimag(cx(i))**2
if(xpol) sqb=sqb + real(cy(i))**2 + aimag(cy(i))**2
enddo
sqa=sqa/n5
sqb=sqb/n5
! Find best DF, f1, f2, DT, and pol. Start by downsampling to 344.53125 Hz
if(xpol) then
z=cmplx(cos(dphi),sin(dphi))
cy(:n5)=z*cy(:n5) !Adjust for cable length difference
endif
! Add some zeros at start of c5 arrays -- empirical fix for negative DT's
nadd=1089
c5x(:nadd)=0.
call fil6521(cx,n5,c5x(nadd+1),n6)
if(xpol) then
c5y(:nadd)=0.
call fil6521(cy,n5,c5y(nadd+1),n6)
endif
n6=n6+nadd
fsample=1378.125/4.
a(5)=dt00
i0=nint((a(5)+0.5)*fsample) - 2 + nadd
if(i0.lt.1) then
write(13,*) 'i0 too small in decode1a:',i0,f0
flush(13)
i0=1
endif
nz=n6+1-i0
! We're looking only at sync tone here... so why not downsample by another
! factor of 1/8, say? Should be a significant execution speed-up.
! Best fit for DF, f1, f2, pol
call afc65b(c5x(i0),c5y(i0),nz,fsample,nflip,ipol,xpol,ndphi,a,ccfbest,dtbest)
pol=a(4)/57.2957795
aa=cos(pol)
bb=sin(pol)
sq0=aa*aa*sqa + bb*bb*sqb
sync2=3.7*ccfbest/sq0
! Apply AFC corrections to the time-domain signal
! Now we are back to using the 1378.125 Hz sample rate, enough to
! accommodate the full JT65C bandwidth.
call twkfreq_xy(cx,cy,n5,a)
! Compute spectrum at best polarization for each half symbol.
! Adding or subtracting a small number (e.g., 5) to j may make it decode.\
! NB: might want to try computing full-symbol spectra (nfft=512, even for
! submodes B and C).
nsym=126
nfft=512
j=(dt00+dtbest+2.685)*1378.125
if(j.lt.0) j=0
! Perhaps should try full-symbol-length FFTs even in B, C sub-modes?
! (Tried this, found no significant difference in decodes.)
do k=1,nsym
! do n=1,mode65
do n=1,1
do i=1,nfft
j=min(j+1,NMAX/64)
c5a(i)=aa*cx(j) + bb*cy(j)
enddo
call four2a(c5a,nfft,1,1,1)
if(n.eq.1) then
do i=1,66
! s2(i,k)=real(c5a(i))**2 + aimag(c5a(i))**2
jj=i
if(mode65.eq.2) jj=2*i-1
if(mode65.eq.4) jj=4*i-3
s2(i,k)=real(c5a(jj))**2 + aimag(c5a(jj))**2
enddo
else
do i=1,66
s2(i,k)=s2(i,k) + real(c5a(i))**2 + aimag(c5a(i))**2
enddo
endif
enddo
enddo
flip=nflip
call timer('dec65b ',0)
call decode65b(s2,flip,mycall,hiscall,hisgrid,mode65,neme,ndepth, &
nqd,nkv,nhist,qual,decoded,s3,sy)
dt=dt00 + dtbest + 1.7
call timer('dec65b ',1)
if(nqd.eq.1 .and. decoded.eq.' ') then
nhz=1000*nkhz + ndf
ihzdiff=min(500,ntol)
if(nutc.ne.nutc0 .or. abs(nhz-nhz0).ge.ihzdiff) syncbest=0.
if(sync2.gt.0.99999*syncbest) then
nsave=nsave+1
nsave=mod(nsave-1,64)+1
npol=nint(57.296*pol)
call s3avg(nsave,mode65,nutc,nhz,xdt,npol,ntol,s3,nsum,nkv,decoded)
syncbest=sync2
nhz0=nhz
endif
nutc0=nutc
endif
900 return
end subroutine decode1a

View File

@ -0,0 +1,48 @@
subroutine decode65b(s2,flip,mycall,hiscall,hisgrid,mode65,neme,ndepth, &
nqd,nkv,nhist,qual,decoded,s3,sy)
real s2(66,126)
real s3(64,63),sy(63)
logical first,ltext
character decoded*22,deepmsg*22
character mycall*12,hiscall*12,hisgrid*6
common/prcom/pr(126),mdat(126),mref(126,2),mdat2(126),mref2(126,2)
data first/.true./
save
if(first) call setup65
first=.false.
do j=1,63
k=mdat(j) !Points to data symbol
if(flip.lt.0.0) k=mdat2(j)
do i=1,64
s3(i,j)=s2(i+2,k)
enddo
k=mdat2(j) !Points to data symbol
if(flip.lt.0.0) k=mdat(j)
sy(j)=s2(1,k)
enddo
nadd=mode65
call extract(s3,nadd,ncount,nhist,decoded,ltext) !Extract the message
! Suppress "birdie messages" and other garbage decodes:
if(decoded(1:7).eq.'000AAA ') ncount=-1
if(decoded(1:7).eq.'0L6MWK ') ncount=-1
if(flip.lt.0.0 .and. ltext) ncount=-1
nkv=1
if(ncount.lt.0) then
nkv=0
decoded=' '
endif
qual=0.
if(ndepth.ge.1 .and. (nqd.eq.1 .or. flip.eq.1.0)) then
call deep65(s3,mode65,neme,flip,mycall,hiscall,hisgrid,deepmsg,qual)
if(nqd.ne.1 .and. qual.lt.10.0) qual=0.0
if(ndepth.lt.2 .and. qual.lt.6.0) qual=0.0
endif
if(nkv.eq.0 .and. qual.ge.1.0) decoded=deepmsg
return
end subroutine decode65b

268
map65/libm65/decode_rs.c Normal file
View File

@ -0,0 +1,268 @@
/* Reed-Solomon decoder
* Copyright 2002 Phil Karn, KA9Q
* May be used under the terms of the GNU General Public License (GPL)
* Modified by Steve Franke, K9AN, for use in a soft-symbol RS decoder
*/
#ifdef DEBUG
#include <stdio.h>
#endif
#include <string.h>
#define NULL ((void *)0)
#define min(a,b) ((a) < (b) ? (a) : (b))
#ifdef FIXED
#include "fixed.h"
#elif defined(BIGSYM)
#include "int.h"
#else
#include "char.h"
#endif
int DECODE_RS(
#ifndef FIXED
void *p,
#endif
DTYPE *data, int *eras_pos, int no_eras, int calc_syn){
#ifndef FIXED
struct rs *rs = (struct rs *)p;
#endif
int deg_lambda, el, deg_omega;
int i, j, r,k;
DTYPE u,q,tmp,num1,num2,den,discr_r;
DTYPE lambda[NROOTS+1]; // Err+Eras Locator poly
static DTYPE s[51]; // and syndrome poly
DTYPE b[NROOTS+1], t[NROOTS+1], omega[NROOTS+1];
DTYPE root[NROOTS], reg[NROOTS+1], loc[NROOTS];
int syn_error, count;
if( calc_syn ) {
/* form the syndromes; i.e., evaluate data(x) at roots of g(x) */
for(i=0;i<NROOTS;i++)
s[i] = data[0];
for(j=1;j<NN;j++){
for(i=0;i<NROOTS;i++){
if(s[i] == 0){
s[i] = data[j];
} else {
s[i] = data[j] ^ ALPHA_TO[MODNN(INDEX_OF[s[i]] + (FCR+i)*PRIM)];
}
}
}
/* Convert syndromes to index form, checking for nonzero condition */
syn_error = 0;
for(i=0;i<NROOTS;i++){
syn_error |= s[i];
s[i] = INDEX_OF[s[i]];
}
if (!syn_error) {
/* if syndrome is zero, data[] is a codeword and there are no
* errors to correct. So return data[] unmodified
*/
count = 0;
goto finish;
}
}
memset(&lambda[1],0,NROOTS*sizeof(lambda[0]));
lambda[0] = 1;
if (no_eras > 0) {
/* Init lambda to be the erasure locator polynomial */
lambda[1] = ALPHA_TO[MODNN(PRIM*(NN-1-eras_pos[0]))];
for (i = 1; i < no_eras; i++) {
u = MODNN(PRIM*(NN-1-eras_pos[i]));
for (j = i+1; j > 0; j--) {
tmp = INDEX_OF[lambda[j - 1]];
if(tmp != A0)
lambda[j] ^= ALPHA_TO[MODNN(u + tmp)];
}
}
#if DEBUG >= 1
/* Test code that verifies the erasure locator polynomial just constructed
Needed only for decoder debugging. */
/* find roots of the erasure location polynomial */
for(i=1;i<=no_eras;i++)
reg[i] = INDEX_OF[lambda[i]];
count = 0;
for (i = 1,k=IPRIM-1; i <= NN; i++,k = MODNN(k+IPRIM)) {
q = 1;
for (j = 1; j <= no_eras; j++)
if (reg[j] != A0) {
reg[j] = MODNN(reg[j] + j);
q ^= ALPHA_TO[reg[j]];
}
if (q != 0)
continue;
/* store root and error location number indices */
root[count] = i;
loc[count] = k;
count++;
}
if (count != no_eras) {
printf("count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras);
count = -1;
goto finish;
}
#if DEBUG >= 2
printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
for (i = 0; i < count; i++)
printf("%d ", loc[i]);
printf("\n");
#endif
#endif
}
for(i=0;i<NROOTS+1;i++)
b[i] = INDEX_OF[lambda[i]];
/*
* Begin Berlekamp-Massey algorithm to determine error+erasure
* locator polynomial
*/
r = no_eras;
el = no_eras;
while (++r <= NROOTS) { /* r is the step number */
/* Compute discrepancy at the r-th step in poly-form */
discr_r = 0;
for (i = 0; i < r; i++){
if ((lambda[i] != 0) && (s[r-i-1] != A0)) {
discr_r ^= ALPHA_TO[MODNN(INDEX_OF[lambda[i]] + s[r-i-1])];
}
}
discr_r = INDEX_OF[discr_r]; /* Index form */
if (discr_r == A0) {
/* 2 lines below: B(x) <-- x*B(x) */
memmove(&b[1],b,NROOTS*sizeof(b[0]));
b[0] = A0;
} else {
/* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
t[0] = lambda[0];
for (i = 0 ; i < NROOTS; i++) {
if(b[i] != A0)
t[i+1] = lambda[i+1] ^ ALPHA_TO[MODNN(discr_r + b[i])];
else
t[i+1] = lambda[i+1];
}
if (2 * el <= r + no_eras - 1) {
el = r + no_eras - el;
/*
* 2 lines below: B(x) <-- inv(discr_r) *
* lambda(x)
*/
for (i = 0; i <= NROOTS; i++)
b[i] = (lambda[i] == 0) ? A0 : MODNN(INDEX_OF[lambda[i]] - discr_r + NN);
} else {
/* 2 lines below: B(x) <-- x*B(x) */
memmove(&b[1],b,NROOTS*sizeof(b[0]));
b[0] = A0;
}
memcpy(lambda,t,(NROOTS+1)*sizeof(t[0]));
}
}
/* Convert lambda to index form and compute deg(lambda(x)) */
deg_lambda = 0;
for(i=0;i<NROOTS+1;i++){
lambda[i] = INDEX_OF[lambda[i]];
if(lambda[i] != A0)
deg_lambda = i;
}
/* Find roots of the error+erasure locator polynomial by Chien search */
memcpy(&reg[1],&lambda[1],NROOTS*sizeof(reg[0]));
count = 0; /* Number of roots of lambda(x) */
for (i = 1,k=IPRIM-1; i <= NN; i++,k = MODNN(k+IPRIM)) {
q = 1; /* lambda[0] is always 0 */
for (j = deg_lambda; j > 0; j--){
if (reg[j] != A0) {
reg[j] = MODNN(reg[j] + j);
q ^= ALPHA_TO[reg[j]];
}
}
if (q != 0)
continue; /* Not a root */
/* store root (index-form) and error location number */
#if DEBUG>=2
printf("count %d root %d loc %d\n",count,i,k);
#endif
root[count] = i;
loc[count] = k;
/* If we've already found max possible roots,
* abort the search to save time
*/
if(++count == deg_lambda)
break;
}
if (deg_lambda != count) {
/*
* deg(lambda) unequal to number of roots => uncorrectable
* error detected
*/
count = -1;
goto finish;
}
/*
* Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
* x**NROOTS). in index form. Also find deg(omega).
*/
deg_omega = 0;
for (i = 0; i < NROOTS;i++){
tmp = 0;
j = (deg_lambda < i) ? deg_lambda : i;
for(;j >= 0; j--){
if ((s[i - j] != A0) && (lambda[j] != A0))
tmp ^= ALPHA_TO[MODNN(s[i - j] + lambda[j])];
}
if(tmp != 0)
deg_omega = i;
omega[i] = INDEX_OF[tmp];
}
omega[NROOTS] = A0;
/*
* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
* inv(X(l))**(FCR-1) and den = lambda_pr(inv(X(l))) all in poly-form
*/
for (j = count-1; j >=0; j--) {
num1 = 0;
for (i = deg_omega; i >= 0; i--) {
if (omega[i] != A0)
num1 ^= ALPHA_TO[MODNN(omega[i] + i * root[j])];
}
num2 = ALPHA_TO[MODNN(root[j] * (FCR - 1) + NN)];
den = 0;
/* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
for (i = min(deg_lambda,NROOTS-1) & ~1; i >= 0; i -=2) {
if(lambda[i+1] != A0)
den ^= ALPHA_TO[MODNN(lambda[i+1] + i * root[j])];
}
if (den == 0) {
#if DEBUG >= 1
printf("\n ERROR: denominator = 0\n");
#endif
count = -1;
goto finish;
}
/* Apply error to data */
if (num1 != 0) {
data[loc[j]] ^= ALPHA_TO[MODNN(INDEX_OF[num1] + INDEX_OF[num2] + NN - INDEX_OF[den])];
}
}
finish:
if(eras_pos != NULL){
for(i=0;i<count;i++)
eras_pos[i] = loc[i];
}
return count;
}

170
map65/libm65/deep65.f90 Normal file
View File

@ -0,0 +1,170 @@
subroutine deep65(s3,mode65,neme,flip,mycall,hiscall,hisgrid,decoded,qual)
use timer_module, only: timer
parameter (MAXCALLS=10000,MAXRPT=63)
real s3(64,63)
character callsign*12,grid*4,message*22,hisgrid*6,c*1,ceme*3
character*12 mycall,hiscall
character*22 decoded,bestmsg
character*22 testmsg(2*MAXCALLS + 2 + MAXRPT)
character*15 callgrid(MAXCALLS)
character*180 line
character*4 rpt(MAXRPT)
integer ncode(63,2*MAXCALLS + 2 + MAXRPT)
real pp(2*MAXCALLS + 2 + MAXRPT)
common/mrscom/ mrs(63),mrs2(63)
common/c3com/ mcall3a
data rpt/'-01','-02','-03','-04','-05', &
'-06','-07','-08','-09','-10', &
'-11','-12','-13','-14','-15', &
'-16','-17','-18','-19','-20', &
'-21','-22','-23','-24','-25', &
'-26','-27','-28','-29','-30', &
'R-01','R-02','R-03','R-04','R-05', &
'R-06','R-07','R-08','R-09','R-10', &
'R-11','R-12','R-13','R-14','R-15', &
'R-16','R-17','R-18','R-19','R-20', &
'R-21','R-22','R-23','R-24','R-25', &
'R-26','R-27','R-28','R-29','R-30', &
'RO','RRR','73'/
save
if(mcall3a.eq.0) go to 30
call timer('deep65a ',0)
mcall3a=0
rewind 23
k=0
icall=0
do n=1,MAXCALLS
if(n.eq.1) then
callsign=hiscall
do i=4,12
if(ichar(callsign(i:i)).eq.0) callsign(i:i)=' '
enddo
grid=hisgrid(1:4)
if(ichar(grid(3:3)).eq.0) grid(3:3)=' '
if(ichar(grid(4:4)).eq.0) grid(4:4)=' '
else
read(23,1002,end=20) line
1002 format (A80)
if(line(1:4).eq.'ZZZZ') go to 20
if(line(1:2).eq.'//') go to 10
i1=index(line,',')
if(i1.lt.4) go to 10
i2=index(line(i1+1:),',')
if(i2.lt.5) go to 10
i2=i2+i1
i3=index(line(i2+1:),',')
if(i3.lt.1) i3=index(line(i2+1:),' ')
i3=i2+i3
callsign=line(1:i1-1)
grid=line(i1+1:i2-1)
ceme=line(i2+1:i3-1)
if(neme.eq.1 .and. ceme.ne.'EME') go to 10
endif
icall=icall+1
j1=index(mycall,' ') - 1
if(j1.le.-1) j1=12
if(j1.lt.3) j1=6
j2=index(callsign,' ') - 1
if(j2.le.-1) j2=12
if(j2.lt.3) j2=6
j3=index(mycall,'/') ! j3>0 means compound mycall
j4=index(callsign,'/') ! j4>0 means compound hiscall
callgrid(icall)=callsign(1:j2)
mz=1
! Allow MyCall + HisCall + rpt (?)
if(n.eq.1 .and. j3.lt.1 .and. j4.lt.1 .and. callsign(1:6).ne.' ') &
mz=MAXRPT+1
do m=1,mz
if(m.gt.1) grid=rpt(m-1)
if(j3.lt.1 .and.j4.lt.1) callgrid(icall)=callsign(1:j2)//' '//grid
message=mycall(1:j1)//' '//callgrid(icall)
k=k+1
testmsg(k)=message
call encode65(message,ncode(1,k))
! Insert CQ message
if(j4.lt.1) callgrid(icall)=callsign(1:j2)//' '//grid
message='CQ '//callgrid(icall)
k=k+1
testmsg(k)=message
call encode65(message,ncode(1,k))
enddo
10 continue
enddo
20 continue
ntot=k
call timer('deep65a ',1)
30 continue
call timer('deep65b ',0)
ref0=0.
do j=1,63
ref0=ref0 + s3(mrs(j),j)
enddo
p1=-1.e30
do k=1,ntot
pp(k)=0.
if(k.ge.2 .and. k.le.64 .and. flip.lt.0.0) cycle
! Test all messages if flip=+1; skip the CQ messages if flip=-1.
if(flip.gt.0.0 .or. testmsg(k)(1:3).ne.'CQ ') then
sum=0.
ref=ref0
do j=1,63
i=ncode(j,k)+1
sum=sum + s3(i,j)
if(i.eq.mrs(j)) ref=ref - s3(i,j) + s3(mrs2(j),j)
enddo
p=sum/ref
pp(k)=p
if(p.gt.p1) then
p1=p
ip1=k
bestmsg=testmsg(k)
endif
endif
enddo
p2=-1.e30
do i=1,ntot
if(pp(i).gt.p2 .and. testmsg(i).ne.bestmsg) p2=pp(i)
enddo
if(mode65.eq.1) bias=max(1.12*p2,0.335)
if(mode65.eq.2) bias=max(1.08*p2,0.405)
if(mode65.ge.4) bias=max(1.04*p2,0.505)
if(p2.eq.p1 .and. p1.ne.-1.e30) then
open(77,file='error.log',status='unknown',access='append')
write(77,*) p1,p2,ip1,bestmsg
close(77)
endif
qual=100.0*(p1-bias)
decoded=' '
c=' '
if(qual.gt.1.0) then
if(qual.lt.6.0) c='?'
decoded=testmsg(ip1)
else
qual=0.
endif
decoded(22:22)=c
! Make sure everything is upper case.
do i=1,22
if(decoded(i:i).ge.'a' .and. decoded(i:i).le.'z') &
decoded(i:i)=char(ichar(decoded(i:i))-32)
enddo
call timer('deep65b ',1)
return
end subroutine deep65

30
map65/libm65/deg2grid.f90 Normal file
View File

@ -0,0 +1,30 @@
subroutine deg2grid(dlong0,dlat,grid)
real dlong !West longitude (deg)
real dlat !Latitude (deg)
character grid*6
dlong=dlong0
if(dlong.lt.-180.0) dlong=dlong+360.0
if(dlong.gt.180.0) dlong=dlong-360.0
! Convert to units of 5 min of longitude, working east from 180 deg.
nlong=60.0*(180.0-dlong)/5.0
n1=nlong/240 !20-degree field
n2=(nlong-240*n1)/24 !2 degree square
n3=nlong-240*n1-24*n2 !5 minute subsquare
grid(1:1)=char(ichar('A')+n1)
grid(3:3)=char(ichar('0')+n2)
grid(5:5)=char(ichar('a')+n3)
! Convert to units of 2.5 min of latitude, working north from -90 deg.
nlat=60.0*(dlat+90)/2.5
n1=nlat/240 !10-degree field
n2=(nlat-240*n1)/24 !1 degree square
n3=nlat-240*n1-24*n2 !2.5 minuts subsquare
grid(2:2)=char(ichar('A')+n1)
grid(4:4)=char(ichar('0')+n2)
grid(6:6)=char(ichar('a')+n3)
return
end subroutine deg2grid

77
map65/libm65/demod64a.f90 Normal file
View File

@ -0,0 +1,77 @@
subroutine demod64a(s3,nadd,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
! Demodulate the 64-bin spectra for each of 63 symbols in a frame.
! Parameters
! nadd number of spectra already summed
! mrsym most reliable symbol value
! mr2sym second most likely symbol value
! mrprob probability that mrsym was the transmitted value
! mr2prob probability that mr2sym was the transmitted value
implicit real*8 (a-h,o-z)
real*4 s3(64,63)
real*8 fs(64)
integer mrsym(63),mrprob(63),mr2sym(63),mr2prob(63)
common/mrscom/ mrs(63),mrs2(63)
afac=1.1 * float(nadd)**0.64
scale=255.999
! Compute average spectral value
sum=0.
do j=1,63
do i=1,64
sum=sum+s3(i,j)
enddo
enddo
ave=sum/(64.*63.)
i1=1 !Silence warning
i2=1
! Compute probabilities for most reliable symbol values
do j=1,63
s1=-1.e30
fsum=0.
psum=0.
do i=1,64
x=min(afac*s3(i,j)/ave,50.d0)
fs(i)=exp(x)
fsum=fsum+fs(i)
psum=psum + s3(i,j)
if(s3(i,j).gt.s1) then
s1=s3(i,j)
i1=i !Most reliable
endif
enddo
s2=-1.e30
do i=1,64
if(i.ne.i1 .and. s3(i,j).gt.s2) then
s2=s3(i,j)
i2=i !Second most reliable
endif
enddo
! p1=fs(i1)/fsum !Normalized probabilities
! p2=fs(i2)/fsum
p1=s1/psum
p2=s2/psum
mrsym(j)=i1-1
mr2sym(j)=i2-1
mrprob(j)=scale*p1
mr2prob(j)=scale*p2
mrs(j)=i1
mrs2(j)=i2
enddo
sum=0.
nlow=0
do j=1,63
sum=sum+mrprob(j)
if(mrprob(j).le.5) nlow=nlow+1
enddo
! ntest=sum/63
ntest=sum
return
end subroutine demod64a

169
map65/libm65/display.f90 Normal file
View File

@ -0,0 +1,169 @@
subroutine display(nkeep,ftol)
parameter (MAXLINES=400,MX=400,MAXCALLS=500)
integer indx(MAXLINES),indx2(MX)
character*83 line(MAXLINES),line2(MX),line3(MAXLINES)
character out*52,cfreq0*3,livecq*58
character*6 callsign,callsign0
character*12 freqcall(MAXCALLS)
real freqkHz(MAXLINES)
integer utc(MAXLINES),utc2(MX),utcz
real*8 f0
rewind 26
do i=1,MAXLINES
read(26,1010,end=10) line(i)
1010 format(a77)
read(line(i),1020) f0,ndf,nh,nm
1020 format(f8.3,i5,25x,i3,i2)
utc(i)=60*nh + nm
freqkHz(i)=1000.d0*(f0-144.d0) + 0.001d0*ndf
enddo
10 backspace(26)
nz=i-1
utcz=utc(nz)
nz=nz-1
if(nz.lt.1) go to 999
nquad=max(nkeep/4,3)
do i=1,nz
nage=utcz-utc(i)
if(nage.lt.0) nage=nage+1440
iage=nage/nquad
write(line(i)(73:74),1021) iage
1021 format(i2)
enddo
nage=utcz-utc(1)
if(nage.lt.0) nage=nage+1440
if(nage.gt.nkeep) then
do i=1,nz
nage=utcz-utc(i)
if(nage.lt.0) nage=nage+1440
if(nage.le.nkeep) go to 20
enddo
20 i0=i
nz=nz-i0+1
rewind 26
if(nz.lt.1) go to 999
do i=1,nz
j=i+i0-1
line(i)=line(j)
utc(i)=utc(j)
freqkHz(i)=freqkHz(j)
write(26,1022) line(i)
1022 format(a77)
enddo
endif
call flush(26)
call indexx(freqkHz,nz,indx)
nstart=1
k3=0
k=1
m=indx(1)
if(m.lt.1 .or. m.gt.MAXLINES) then
print*,'Error in display.f90: ',nz,m
m=1
endif
line2(1)=line(m)
utc2(1)=utc(m)
do i=2,nz
j0=indx(i-1)
j=indx(i)
if(freqkHz(j)-freqkHz(j0).gt.2.0*ftol) then
if(nstart.eq.0) then
k=k+1
line2(k)=""
utc2(k)=-1
endif
kz=k
if(nstart.eq.1) then
call indexx(float(utc2(1:kz)),kz,indx2)
k3=0
do k=1,kz
k3=min(k3+1,400)
line3(k3)=line2(indx2(k))
enddo
nstart=0
else
call indexx(float(utc2(1:kz)),kz,indx2)
do k=1,kz
k3=min(k3+1,400)
line3(k3)=line2(indx2(k))
enddo
endif
k=0
endif
if(i.eq.nz) then
k=k+1
line2(k)=""
utc2(k)=-1
endif
k=k+1
line2(k)=line(j)
utc2(k)=utc(j)
j0=j
enddo
kz=k
call indexx(float(utc2(1:kz)),kz,indx2)
do k=1,kz
k3=min(k3+1,400)
line3(k3)=line2(indx2(k))
enddo
rewind 19
rewind 20
cfreq0=' '
nc=0
callsign0=' '
do k=1,k3
out=line3(k)(6:13)//line3(k)(28:31)//line3(k)(39:45)// &
line3(k)(35:38)//line3(k)(46:74)
if(out(1:3).ne.' ') then
cfreq0=out(1:3)
livecq=line3(k)(6:13)//line3(k)(28:31)//line3(k)(39:45)// &
line3(k)(23:27)//line3(k)(35:38)//line3(k)(46:70)// &
line3(k)(73:77)
if(index(livecq,' CQ ').gt.0 .or. index(livecq,' QRZ ').gt.0 .or. &
index(livecq,' QRT ').gt.0 .or. index(livecq,' CQV ').gt.0 .or. &
index(livecq,' CQH ').gt.0) write(19,1029) livecq
1029 format(a58)
write(*,1030) out !Messages
1030 format('@',a52)
i1=index(out(26:),' ')
callsign=out(i1+26:)
i2=index(callsign,' ')
if(i2.gt.1) callsign(i2:)=' '
if(callsign.ne.' ' .and. callsign.ne.callsign0) then
len=i2-1
if(len.lt.0) len=6
if(len.ge.4) then !Omit short "callsigns"
if(nc.lt.MAXCALLS) nc=nc+1
freqcall(nc)=cfreq0//' '//callsign//line3(k)(73:74)
callsign0=callsign
endif
endif
if(callsign.ne.' ' .and. callsign.eq.callsign0) then
freqcall(nc)=cfreq0//' '//callsign//line3(k)(73:74)
endif
endif
enddo
flush(19)
if(nc.lt.MAXCALLS) nc=nc+1
freqcall(nc)=' '
if(nc.lt.MAXCALLS) nc=nc+1
freqcall(nc)=' '
freqcall(nc+1)=' '
freqcall(nc+2)=' '
do i=1,nc
write(*,1042) freqcall(i) !Band Map
1042 format('&',a12)
enddo
999 continue
return
end subroutine display

11
map65/libm65/dot.f90 Normal file
View File

@ -0,0 +1,11 @@
real*8 function dot(x,y)
real*8 x(3),y(3)
dot=0.d0
do i=1,3
dot=dot+x(i)*y(i)
enddo
return
end function dot

41
map65/libm65/dpol.f90 Normal file
View File

@ -0,0 +1,41 @@
real function dpol(mygrid,hisgrid)
! Compute spatial polartzation offset in degrees for the present
! time, between two specified grid locators.
character*6 MyGrid,HisGrid
real lat,lon,LST
character cdate*8,ctime2*10,czone*5
integer it(8)
data rad/57.2957795/
call date_and_time(cdate,ctime2,czone,it)
nyear=it(1)
month=it(2)
nday=it(3)
nh=it(5)-it(4)/60
nm=it(6)
ns=it(7)
uth=nh + nm/60.0 + ns/3600.0
call grid2deg(MyGrid,lon,lat)
call MoonDop(nyear,month,nday,uth,-lon,lat,RAMoon,DecMoon, &
LST,HA,AzMoon,ElMoon,vr,dist)
xx=sin(lat/rad)*cos(ElMoon/rad) - cos(lat/rad)* &
cos(AzMoon/rad)*sin(ElMoon/rad)
yy=cos(lat/rad)*sin(AzMoon/rad)
poloffset1=rad*atan2(yy,xx)
call grid2deg(hisGrid,lon,lat)
call MoonDop(nyear,month,nday,uth,-lon,lat,RAMoon,DecMoon, &
LST,HA,AzMoon,ElMoon,vr,dist)
xx=sin(lat/rad)*cos(ElMoon/rad) - cos(lat/rad)* &
cos(AzMoon/rad)*sin(ElMoon/rad)
yy=cos(lat/rad)*sin(AzMoon/rad)
poloffset2=rad*atan2(yy,xx)
dpol=mod(poloffset2-poloffset1+720.0,180.0)
if(dpol.gt.90.0) dpol=dpol-180.0
return
end function dpol

14
map65/libm65/encode65.f90 Normal file
View File

@ -0,0 +1,14 @@
subroutine encode65(message,sent)
use packjt
character message*22
integer dgen(12)
integer sent(63)
call packmsg(message,dgen,itype)
call rs_encode(dgen,sent)
call interleave63(sent,1)
call graycode(sent,63,1)
return
end subroutine encode65

47
map65/libm65/encode_rs.c Normal file
View File

@ -0,0 +1,47 @@
/* Reed-Solomon encoder
* Copyright 2002, Phil Karn, KA9Q
* May be used under the terms of the GNU General Public License (GPL)
*/
#include <string.h>
#ifdef FIXED
#include "fixed.h"
#elif defined(BIGSYM)
#include "int.h"
#else
#include "char.h"
#endif
void ENCODE_RS(
#ifndef FIXED
void *p,
#endif
DTYPE *data, DTYPE *bb){
#ifndef FIXED
struct rs *rs = (struct rs *)p;
#endif
int i, j;
DTYPE feedback;
memset(bb,0,NROOTS*sizeof(DTYPE));
for(i=0;i<NN-NROOTS;i++){
feedback = INDEX_OF[data[i] ^ bb[0]];
if(feedback != A0){ /* feedback term is non-zero */
#ifdef UNNORMALIZED
/* This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
* always be for the polynomials constructed by init_rs()
*/
feedback = MODNN(NN - GENPOLY[NROOTS] + feedback);
#endif
for(j=1;j<NROOTS;j++)
bb[j] ^= ALPHA_TO[MODNN(feedback + GENPOLY[NROOTS-j])];
}
/* Shift */
memmove(&bb[0],&bb[1],sizeof(DTYPE)*(NROOTS-1));
if(feedback != A0)
bb[NROOTS-1] = ALPHA_TO[MODNN(feedback + GENPOLY[0])];
else
bb[NROOTS-1] = 0;
}
}

136
map65/libm65/extract.f90 Normal file
View File

@ -0,0 +1,136 @@
subroutine extract(s3,nadd,ncount,nhist,decoded,ltext)
use packjt
use timer_module, only: timer
real s3(64,63)
character decoded*22
integer dat4(12)
integer mrsym(63),mr2sym(63),mrprob(63),mr2prob(63)
logical first,ltext
integer correct(63),itmp(63)
integer param(0:8)
integer h0(0:11),d0(0:11)
real r0(0:11)
common/test001/s3a(64,63),mrs(63),mrs2(63) !### TEST ONLY ###
! 0 1 2 3 4 5 6 7 8 9 10 11
data h0/41,42,43,43,44,45,46,47,48,48,49,49/
data d0/71,72,73,74,76,77,78,80,81,82,83,83/
! 0 1 2 3 4 5 6 7 8 9 10 11
data r0/0.70,0.72,0.74,0.76,0.78,0.80,0.82,0.84,0.86,0.88,0.90,0.90/
data first/.true./,nsec1/0/
save
nfail=0
call pctile(s3,4032,50,base) ! ### or, use ave from demod64a
s3=s3/base
s3a=s3
1 call demod64a(s3,nadd,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
! if(ntest.lt.50 .or. nlow.gt.20) then
! ncount=-999 !Flag bad data
! go to 900
! endif
call chkhist(mrsym,nhist,ipk)
if(nhist.ge.20) then
nfail=nfail+1
call pctile(s3,4032,50,base) ! ### or, use ave from demod64a
s3(ipk,1:63)=base
if(nfail.gt.30) then
decoded=' '
ncount=-1
go to 900
endif
go to 1
endif
mrs=mrsym
mrs2=mr2sym
call graycode(mrsym,63,-1)
call interleave63(mrsym,-1)
call interleave63(mrprob,-1)
call graycode(mr2sym,63,-1)
call interleave63(mr2sym,-1)
call interleave63(mr2prob,-1)
ntrials=10000
naggressive=10
ntry=0
param=0
call timer('ftrsd ',0)
call ftrsd2(mrsym,mrprob,mr2sym,mr2prob,ntrials,correct,param,ntry)
call timer('ftrsd ',1)
ncandidates=param(0)
nhard=param(1)
nsoft=param(2)
nerased=param(3)
rtt=0.001*param(4)
ntotal=param(5)
qual=0.001*param(7)
nd0=81
r00=0.87
if(naggressive.eq.10) then
nd0=83
r00=0.90
endif
if(ntotal.le.nd0 .and. rtt.le.r00) nft=1
n=naggressive
if(nhard.gt.50) nft=0
if(nhard.gt.h0(n)) nft=0
if(ntotal.gt.d0(n)) nft=0
if(rtt.gt.r0(n)) nft=0
ncount=-1
decoded=' '
ltext=.false.
if(nft.gt.0) then
! Turn the corrected symbol array into channel symbols for subtraction;
! pass it back to jt65a via common block "chansyms65".
do i=1,12
dat4(i)=correct(13-i)
enddo
do i=1,63
itmp(i)=correct(64-i)
enddo
correct(1:63)=itmp(1:63)
call interleave63(correct,63,1)
call graycode65(correct,63,1)
call unpackmsg(dat4,decoded) !Unpack the user message
ncount=0
if(iand(dat4(10),8).ne.0) ltext=.true.
endif
900 continue
if(nft.eq.1 .and. nhard.lt.0) decoded=' '
! write(81,3001) naggressive,ncandidates,nhard,ntotal,rtt,qual,decoded
!3001 format(i2,i6,i3,i4,2f8.2,2x,a22)
return
end subroutine extract
subroutine getpp(workdat,p)
integer workdat(63)
integer a(63)
common/test001/s3a(64,63),mrs(63),mrs2(63)
a(1:63)=workdat(63:1:-1)
call interleave63(a,1)
call graycode(a,63,1,a)
psum=0.
do j=1,63
i=a(j)+1
x=s3a(i,j)
s3a(i,j)=0.
psum=psum + x
s3a(i,j)=x
enddo
p=psum/63.0
return
end subroutine getpp

45
map65/libm65/f77_wisdom.f Normal file
View File

@ -0,0 +1,45 @@
subroutine write_char(c, iunit)
character c
integer iunit
write(iunit,1000) c
1000 format(a,$)
end
subroutine export_wisdom_to_file(iunit)
integer iunit
external write_char
c call dfftw_export_wisdom(write_char, iunit)
call sfftw_export_wisdom(write_char, iunit)
end
subroutine read_char(ic, iunit)
integer ic
integer iunit
character*256 buf
save buf
integer ibuf
data ibuf/257/
save ibuf
if (ibuf .lt. 257) then
ic = ichar(buf(ibuf:ibuf))
ibuf = ibuf + 1
return
endif
read(iunit,1000,end=10) buf
1000 format(a256)
ic = ichar(buf(1:1))
ibuf = 2
return
10 ic = -1
ibuf = 257
rewind iunit
return
end
subroutine import_wisdom_from_file(isuccess, iunit)
integer isuccess
integer iunit
external read_char
c call dfftw_import_wisdom(isuccess, read_char, iunit)
call sfftw_import_wisdom(isuccess, read_char, iunit)
end

77
map65/libm65/fchisq.f90 Normal file
View File

@ -0,0 +1,77 @@
real function fchisq(cx,cy,npts,fsample,nflip,a,ccfmax,dtmax)
use timer_module, only: timer
parameter (NMAX=60*96000) !Samples per 60 s
complex cx(npts),cy(npts)
real a(5)
complex w,wstep,za,zb,z
real ss(3000)
complex csx(0:NMAX/64),csy(0:NMAX/64)
data twopi/6.283185307/a1,a2,a3/99.,99.,99./
save
call timer('fchisq ',0)
baud=11025.0/4096.0
nsps=nint(fsample/baud) !Samples per symbol
nsph=nsps/2 !Samples per half-symbol
ndiv=16 !Output ss() steps per symbol
nout=ndiv*npts/nsps
dtstep=1.0/(ndiv*baud) !Time per output step
if(a(1).ne.a1 .or. a(2).ne.a2 .or. a(3).ne.a3) then
a1=a(1)
a2=a(2)
a3=a(3)
! Mix and integrate the complex X and Y signals
csx(0)=0.
csy(0)=0.
w=1.0
x0=0.5*(npts+1)
s=2.0/npts
do i=1,npts
x=s*(i-x0)
if(mod(i,100).eq.1) then
p2=1.5*x*x - 0.5
! p3=2.5*(x**3) - 1.5*x
! p4=4.375*(x**4) - 3.75*(x**2) + 0.375
dphi=(a(1) + x*a(2) + p2*a(3)) * (twopi/fsample)
wstep=cmplx(cos(dphi),sin(dphi))
endif
w=w*wstep
csx(i)=csx(i-1) + w*cx(i)
csy(i)=csy(i-1) + w*cy(i)
enddo
endif
! Compute 1/2-symbol powers at 1/16-symbol steps.
fac=1.e-4
pol=a(4)/57.2957795
aa=cos(pol)
bb=sin(pol)
do i=1,nout
j=i*nsps/ndiv
k=j-nsph
ss(i)=0.
if(k.ge.1) then
za=csx(j)-csx(k)
zb=csy(j)-csy(k)
z=aa*za + bb*zb
ss(i)=fac*(real(z)**2 + aimag(z)**2)
endif
enddo
ccfmax=0.
call timer('ccf2 ',0)
call ccf2(ss,nout,nflip,ccf,lagpk)
call timer('ccf2 ',1)
if(ccf.gt.ccfmax) then
ccfmax=ccf
dtmax=lagpk*dtstep
endif
fchisq=-ccfmax
call timer('fchisq ',1)
return
end function fchisq

23
map65/libm65/fchisq0.f90 Normal file
View File

@ -0,0 +1,23 @@
real function fchisq0(y,npts,a)
real y(npts),a(4)
! rewind 51
chisq = 0.
do i=1,npts
x=i
z=(x-a(3))/(0.5*a(4))
yfit=a(1)
if(abs(z).lt.3.0) then
d=1.0 + z*z
yfit=a(1) + a(2) * (1.0/d - 0.1)
endif
chisq=chisq + (y(i) - yfit)**2
! write(51,3001) i,y(i),yfit,y(i)-yfit
!3001 format(i5,3f10.4)
enddo
fchisq0=chisq
return
end function fchisq0

Some files were not shown because too many files have changed in this diff Show More