[hamradio-commits] [wsjtx] 01/07: Imported Upstream version 1.1.r3496

Iain R. Learmonth irl at moszumanska.debian.org
Sun Oct 18 17:53:45 UTC 2015


This is an automated email from the git hooks/post-receive script.

irl pushed a commit to branch master
in repository wsjtx.

commit c720a3d55c5ec832c29cb7ce50b6fb4b70c55b11
Author: Iain R. Learmonth <irl at debian.org>
Date:   Sun Oct 18 17:55:15 2015 +0100

    Imported Upstream version 1.1.r3496
---
 LICENSE_WHEATLEY.TXT |   30 +
 PSKReporter.h        |  127 +++
 QtSupport.iss        |   10 +
 about.cpp            |   23 +
 about.h              |   24 +
 about.ui             |   40 +
 afmhot.dat           |  257 +++++
 blue.dat             |  256 +++++
 commons.h            |   35 +
 devsetup.cpp         |  595 ++++++++++
 devsetup.h           |  120 ++
 devsetup.ui          | 2599 ++++++++++++++++++++++++++++++++++++++++++
 displaytext.cpp      |   16 +
 displaytext.h        |   22 +
 ffft.f               |   69 ++
 fftw3.f              |   64 ++
 getdev.cpp           |  259 +++++
 getfile.cpp          |  199 ++++
 getfile.h            |   18 +
 in.dat               |   16 +
 jt9.txt              |   65 ++
 killbyname.cpp       |  284 +++++
 lib/Makefile.MinGW   |  117 ++
 lib/Makefile.linux   |  104 ++
 lib/afc65b.f90       |   59 +
 lib/afc9.f90         |   58 +
 lib/analytic.f90     |   25 +
 lib/azdist.f90       |  107 ++
 lib/bpskmetrics.dat  |  256 +++++
 lib/ccf2.f90         |   45 +
 lib/ccf65.f90        |  117 ++
 lib/char.h           |   57 +
 lib/chkhist.f90      |   21 +
 lib/chkmsg.f90       |   31 +
 lib/chkss2.f90       |   24 +
 lib/constants.f90    |    5 +
 lib/conv232.f90      |   38 +
 lib/cutil.c          |   93 ++
 lib/db.f90           |    5 +
 lib/decode65a.f90    |   95 ++
 lib/decode65b.f90    |   36 +
 lib/decode9.f90      |   85 ++
 lib/decode_rs.c      |  263 +++++
 lib/decoder.f90      |  173 +++
 lib/deep24.f90       |  182 +++
 lib/deg2grid.f90     |   30 +
 lib/demod64a.f90     |   73 ++
 lib/downsam9.f90     |   66 ++
 lib/encode232.f90    |   33 +
 lib/encode4.f90      |   20 +
 lib/encode_rs.c      |   52 +
 lib/entail.f90       |   30 +
 lib/extract.F90      |  103 ++
 lib/extract4.f90     |   61 +
 lib/f77_wisdom.f90   |   45 +
 lib/fano232.f90      |  140 +++
 lib/fchisq.f90       |   41 +
 lib/fchisq65.f90     |   68 ++
 lib/fftw3.f90        |   64 ++
 lib/fil3.f90         |  159 +++
 lib/fil61.f90        |   64 ++
 lib/fil6521.f90      |   44 +
 lib/filbig.f90       |  127 +++
 lib/fillcom.f90      |   25 +
 lib/flat1.f90        |   30 +
 lib/flat2.f90        |   18 +
 lib/flat65.f90       |   25 +
 lib/four2a.f90       |   90 ++
 lib/gen24.f90        |   86 ++
 lib/gen65.f90        |   65 ++
 lib/genjt9.f90       |   58 +
 lib/genmet.f90       |   88 ++
 lib/geodist.f90      |   96 ++
 lib/getlags.f90      |   27 +
 lib/getmet24.f90     |   52 +
 lib/getpfx1.f90      |   97 ++
 lib/getpfx2.f90      |   24 +
 lib/gran.c           |   28 +
 lib/graycode.f90     |    9 +
 lib/graycode65.f90   |    9 +
 lib/grid2deg.f90     |   38 +
 lib/grid2k.f90       |   12 +
 lib/grid2n.f90       |   10 +
 lib/igray.c          |   18 +
 lib/indexx.f90       |   19 +
 lib/init_rs.c        |  126 +++
 lib/int.h            |   57 +
 lib/interleave24.f90 |   43 +
 lib/interleave63.f90 |   25 +
 lib/interleave8.f90  |   17 +
 lib/interleave9.f90  |   39 +
 lib/ipcomm.cpp       |   50 +
 lib/jt65.f90         |   68 ++
 lib/jt65a.f90        |   85 ++
 lib/jt9.f90          |  111 ++
 lib/jt9a.f90         |   72 ++
 lib/jt9b.f90         |   12 +
 lib/jt9c.f90         |   21 +
 lib/jt9code.f90      |   29 +
 lib/jt9sim.f90       |  166 +++
 lib/jt9sync.f90      |   18 +
 lib/k2grid.f90       |   12 +
 lib/libhamlib.dll.a  |  Bin 0 -> 177492 bytes
 lib/met8.21          |  256 +++++
 lib/morse.f90        |   86 ++
 lib/move.f90         |    7 +
 lib/msgs.txt         |   60 +
 lib/n2grid.f90       |   14 +
 lib/nchar.f90        |   23 +
 lib/noisegen.f90     |   13 +
 lib/packbits.f90     |   21 +
 lib/packcall.f90     |   79 ++
 lib/packdxcc.f90     |   64 ++
 lib/packgrid.f90     |   76 ++
 lib/packmsg.f90      |  113 ++
 lib/packtext.f90     |   47 +
 lib/pctile.f90       |   22 +
 lib/peakdt9.f90      |   54 +
 lib/peakup.f90       |    8 +
 lib/pfx.f90          |   50 +
 lib/pfxdump.f90      |   13 +
 lib/ps24.f90         |   27 +
 lib/ptt.c            |   50 +
 lib/rig_control.c    |   99 ++
 lib/rs.h             |   35 +
 lib/s3avg.f90        |   60 +
 lib/sec_midn.f90     |   11 +
 lib/setup65.f90      |   96 ++
 lib/sleep.h          |   32 +
 lib/sleep_msec.f90   |    4 +
 lib/slope.f90        |   40 +
 lib/smo121.f90       |   13 +
 lib/softsym.f90      |   50 +
 lib/sort.f90         |    4 +
 lib/ss.bat           |    1 +
 lib/ssort.f90        |  264 +++++
 lib/stdmsg.f90       |   12 +
 lib/symspec.f90      |  113 ++
 lib/symspec2.f90     |   88 ++
 lib/symspec65.f90    |   47 +
 lib/sync24.f90       |  179 +++
 lib/sync9.f90        |  101 ++
 lib/tab.c            |   36 +
 lib/timer.f90        |  112 ++
 lib/timeval.h        |   74 ++
 lib/tstrig.c         |   26 +
 lib/tstrig.h         |   50 +
 lib/twkfreq.f90      |   28 +
 lib/twkfreq65.f90    |   25 +
 lib/unpackbits.f90   |   22 +
 lib/unpackcall.f90   |  142 +++
 lib/unpackgrid.f90   |   45 +
 lib/unpackmsg.f90    |  107 ++
 lib/unpacktext.f90   |   35 +
 lib/vit216.c         |  219 ++++
 lib/wrapkarn.c       |   70 ++
 lib/wsjt24.f90       |  181 +++
 lib/wsjt24d.f90      |   43 +
 lib/xcor24.f90       |   94 ++
 lib/zplot9.f90       |   31 +
 logqso.cpp           |  174 +++
 logqso.h             |   53 +
 logqso.ui            |  759 +++++++++++++
 main.cpp             |   60 +
 mainwindow.cpp       | 3052 ++++++++++++++++++++++++++++++++++++++++++++++++++
 mainwindow.h         |  392 +++++++
 mainwindow.ui        | 2925 +++++++++++++++++++++++++++++++++++++++++++++++
 meterwidget.cpp      |   51 +
 meterwidget.h        |   30 +
 mouse_commands.txt   |   18 +
 paInputDevice.c      |   56 +
 pa_get_device_info.c |  172 +++
 plotter.cpp          |  565 ++++++++++
 plotter.h            |  139 +++
 psk_reporter.cpp     |  104 ++
 psk_reporter.h       |   41 +
 rigclass.cpp         |  324 ++++++
 rigclass.h           |   98 ++
 shortcuts.txt        |   26 +
 signalmeter.cpp      |   53 +
 signalmeter.h        |   32 +
 sleep.h              |   16 +
 soundin.cpp          |  208 ++++
 soundin.h            |   50 +
 soundout.cpp         |  270 +++++
 soundout.h           |   53 +
 ss.bat               |    1 +
 sss.bat              |    1 +
 widegraph.cpp        |  314 ++++++
 widegraph.h          |   89 ++
 widegraph.ui         |  398 +++++++
 wsjt.ico             |  Bin 0 -> 1078 bytes
 wsjtx.iss            |   23 +
 wsjtx.pro            |   81 ++
 wsjtx.rc             |    1 +
 wsjtx_changelog.txt  |  791 +++++++++++++
 wsjtx_opti.iss       |   23 +
 197 files changed, 25334 insertions(+)

diff --git a/LICENSE_WHEATLEY.TXT b/LICENSE_WHEATLEY.TXT
new file mode 100644
index 0000000..8b0ce24
--- /dev/null
+++ b/LICENSE_WHEATLEY.TXT
@@ -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.
diff --git a/PSKReporter.h b/PSKReporter.h
new file mode 100644
index 0000000..a6c52c4
--- /dev/null
+++ b/PSKReporter.h
@@ -0,0 +1,127 @@
+#pragma once
+
+// Main header file for the external interface to the PSK Reporter API
+// For documentation see http://psk.gladstonefamily.net/PSKReporterAPI.pdf
+
+/*
+
+Copyright (c) 2008 Philip Gladstone
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+ */
+
+
+#ifdef _DLL_OPTION_PSKREPORTER_EXPORT
+#define DllImportExport __declspec ( dllexport )
+#else
+#define DllImportExport __declspec ( dllimport )
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif 
+
+#define REPORTER_SOURCE_MASK		0x07
+#define REPORTER_SOURCE_AUTOMATIC	0x01
+#define REPORTER_SOURCE_LOG			0x02
+#define REPORTER_SOURCE_MANUAL		0x03
+#define REPORTER_SOURCE_TENTATIVE	0x40 
+#define REPORTER_SOURCE_TEST		0x80 
+
+typedef struct {
+	wchar_t 	  hostname[256];
+	wchar_t 	  port[32];
+	bool	  	  connected;
+	unsigned int  callsigns_sent;
+	unsigned int  callsigns_buffered;
+	unsigned int  callsigns_discarded;
+	unsigned int  last_send_time;
+	unsigned int  next_send_time;
+	wchar_t	      last_callsign_queued[24];
+	unsigned int  bytes_sent;
+	unsigned int  bytes_sent_total;
+	unsigned int  packets_sent;
+	unsigned int  packets_sent_total;
+} REPORTER_STATISTICS;
+
+
+
+
+unsigned long DllImportExport __cdecl ReporterInitialize(
+	const wchar_t *hostname,
+	const wchar_t *port
+);
+
+unsigned long DllImportExport __cdecl ReporterSeenCallsign(
+	const wchar_t *remoteInformation,
+	const wchar_t *localInformation,
+	unsigned long flags
+);
+
+unsigned long DllImportExport __cdecl ReporterTickle(
+);
+
+unsigned long DllImportExport __cdecl ReporterGetInformation(
+	wchar_t *buffer,
+	unsigned long maxlen
+);
+
+unsigned long DllImportExport __cdecl ReporterGetStatistics(
+	REPORTER_STATISTICS *buffer,
+	unsigned long maxlen
+);
+
+unsigned long DllImportExport __cdecl ReporterUninitialize(
+);
+
+
+unsigned long DllImportExport __stdcall ReporterInitializeSTD(
+	const char *hostname,
+	const char *port
+);
+
+unsigned long DllImportExport __stdcall ReporterSeenCallsignSTD(
+	const char *remoteInformation,
+	const char *localInformation,
+	unsigned long flags
+);
+
+unsigned long DllImportExport __stdcall ReporterTickleSTD(
+);
+
+unsigned long DllImportExport __stdcall ReporterGetInformationSTD(
+	char *buffer,
+	unsigned long maxlen
+);
+
+unsigned long DllImportExport __stdcall ReporterGetStatisticsSTD(
+	REPORTER_STATISTICS *buffer,
+	unsigned long maxlen
+);
+
+unsigned long DllImportExport __stdcall ReporterUninitializeSTD(
+);
+
+#ifdef __cplusplus
+}
+#endif 
+
+
diff --git a/QtSupport.iss b/QtSupport.iss
new file mode 100644
index 0000000..a7144c2
--- /dev/null
+++ b/QtSupport.iss
@@ -0,0 +1,10 @@
+[Setup]
+AppName="QtSupport for MAP65"
+AppVerName=QtSupport
+DefaultDirName=C:\MAP65
+
+[Files]
+Source: "c:\Users\joe\map65\QtSupport\*.dll";           DestDir: "{app}";  Flags: onlyifdoesntexist
+
+
+
diff --git a/about.cpp b/about.cpp
new file mode 100644
index 0000000..5cab294
--- /dev/null
+++ b/about.cpp
@@ -0,0 +1,23 @@
+#include "about.h"
+#include "ui_about.h"
+
+CAboutDlg::CAboutDlg(QWidget *parent, QString Revision) :
+  QDialog(parent),
+  m_Revision(Revision),
+  ui(new Ui::CAboutDlg)
+{
+  ui->setupUi(this);
+  ui->labelTxt->clear();
+  m_Str  = "<html><h2>" + m_Revision + "</h2>\n\n";
+  m_Str += "WSJT-X implements experimental mode JT9 for <br>";
+  m_Str += "Amateur Radio communication at HF, MF, and LF.  <br><br>";
+  m_Str += "Copyright 2001-2013 by Joe Taylor, K1JT.   Additional <br>";
+  m_Str += "contributions from AC6SL, AE4JY, G4KLA, K3WYC, PY2SDR, <br>";
+  m_Str += "and VK4BDJ.<br>";
+  ui->labelTxt->setText(m_Str);
+}
+
+CAboutDlg::~CAboutDlg()
+{
+  delete ui;
+}
diff --git a/about.h b/about.h
new file mode 100644
index 0000000..ca45d19
--- /dev/null
+++ b/about.h
@@ -0,0 +1,24 @@
+#ifndef ABOUTDLG_H
+#define ABOUTDLG_H
+
+#include <QDialog>
+
+namespace Ui {
+    class CAboutDlg;
+}
+
+class CAboutDlg : public QDialog
+{
+    Q_OBJECT
+
+public:
+	explicit CAboutDlg(QWidget *parent=0, QString Revision="");
+    ~CAboutDlg();
+
+private:
+	QString m_Revision;
+	Ui::CAboutDlg *ui;
+	QString m_Str;
+};
+
+#endif // ABOUTDLG_H
diff --git a/about.ui b/about.ui
new file mode 100644
index 0000000..3a86259
--- /dev/null
+++ b/about.ui
@@ -0,0 +1,40 @@
+<?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 WSJT-X</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="labelTxt">
+     <property name="text">
+      <string/>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/afmhot.dat b/afmhot.dat
new file mode 100644
index 0000000..8b312a1
--- /dev/null
+++ b/afmhot.dat
@@ -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
diff --git a/blue.dat b/blue.dat
new file mode 100644
index 0000000..d9fc886
--- /dev/null
+++ b/blue.dat
@@ -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
diff --git a/commons.h b/commons.h
new file mode 100644
index 0000000..e521841
--- /dev/null
+++ b/commons.h
@@ -0,0 +1,35 @@
+#ifndef COMMONS_H
+#define COMMONS_H
+
+//#define NSMAX 1365
+#define NSMAX 6827
+#define NTMAX 120
+
+extern "C" {
+
+extern struct {
+  float ss[184*NSMAX];              //This is "common/jt9com/..." in fortran
+  float savg[NSMAX];
+  short int d2[NTMAX*12000];
+  int nutc;                         //UTC as integer, HHMM
+  int ndiskdat;                     //1 ==> data read from *.wav file
+  int ntrperiod;                    //TR period (seconds)
+  int nfqso;                        //User-selected QSO freq (kHz)
+  int newdat;                       //1 ==> new data, must do long FFT
+  int npts8;                        //npts for c0() array
+  int nfa;                          //Low decode limit (Hz)
+  int nfb;                          //High decode limit (Hz)
+  int ntol;                         //+/- decoding range around fQSO (Hz)
+  int kin;
+  int nzhsym;
+  int nsave;
+  int nagain;
+  int ndepth;
+  int ntxmode;
+  int nmode;
+  char datetime[20];
+} jt9com_;
+
+}
+
+#endif // COMMONS_H
diff --git a/devsetup.cpp b/devsetup.cpp
new file mode 100644
index 0000000..018a188
--- /dev/null
+++ b/devsetup.cpp
@@ -0,0 +1,595 @@
+#include "devsetup.h"
+#include <QDebug>
+#include <QSettings>
+#include <portaudio.h>
+
+#define MAXDEVICES 100
+
+extern double dFreq[16];
+qint32  g2_iptt;
+qint32  g2_COMportOpen;
+
+//----------------------------------------------------------- DevSetup()
+DevSetup::DevSetup(QWidget *parent) :	QDialog(parent)
+{
+  ui.setupUi(this);	                              //setup the dialog form
+  m_restartSoundIn=false;
+  m_restartSoundOut=false;
+  m_firstCall=true;
+  g2_iptt=0;
+  m_test=0;
+  m_bRigOpen=false;
+  g2_COMportOpen=0;
+}
+
+DevSetup::~DevSetup()
+{
+}
+
+void DevSetup::initDlg()
+{
+  QString m_appDir = QApplication::applicationDirPath();
+  QString inifile = m_appDir + "/wsjtx.ini";
+  QSettings settings(inifile, QSettings::IniFormat);
+  settings.beginGroup("Common");
+  QString catPortDriver = settings.value("CATdriver","None").toString();
+  settings.endGroup();
+
+  int k,id;
+  int numDevices=Pa_GetDeviceCount();
+
+  const PaDeviceInfo *pdi;
+  int nchin;
+  int nchout;
+  char pa_device_name[128];
+  char pa_device_hostapi[128];
+
+  k=0;
+  for(id=0; id<numDevices; id++ )  {
+    pdi=Pa_GetDeviceInfo(id);
+    nchin=pdi->maxInputChannels;
+    if(nchin>0) {
+      m_inDevList[k]=id;
+      if (id == m_paInDevice)
+        m_nDevIn = k;
+      k++;
+      sprintf((char*)(pa_device_name),"%s",pdi->name);
+      sprintf((char*)(pa_device_hostapi),"%s",
+              Pa_GetHostApiInfo(pdi->hostApi)->name);
+
+#ifdef WIN32
+      char *p,*p1;
+      char p2[50];
+      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   %d   %-8s  %-39s",id,nchin,p1,pa_device_name);
+      QString t(p2);
+#else
+      QString t;
+      t.sprintf("%2d   %d   %-8s  %-39s",id,nchin,
+                Pa_GetHostApiInfo(pdi->hostApi)->name,pdi->name);
+#endif
+      ui.comboBoxSndIn->addItem(t);
+    }
+  }
+
+  k=0;
+  for(id=0; id<numDevices; id++ )  {
+    pdi=Pa_GetDeviceInfo(id);
+    nchout=pdi->maxOutputChannels;
+    if(nchout>0) {
+      m_outDevList[k]=id;
+      if (id == m_paOutDevice)
+        m_nDevOut = k;
+      k++;
+      sprintf((char*)(pa_device_name),"%s",pdi->name);
+      sprintf((char*)(pa_device_hostapi),"%s",
+              Pa_GetHostApiInfo(pdi->hostApi)->name);
+
+#ifdef WIN32
+      char *p,*p1;
+      char p2[50];
+      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   %d   %-8s  %-39s",id,nchout,p1,pa_device_name);
+      QString t(p2);
+#else
+      QString t;
+      t.sprintf("%2d   %d   %-8s  %-39s",id,nchout,
+                Pa_GetHostApiInfo(pdi->hostApi)->name,pdi->name);
+#endif
+      ui.comboBoxSndOut->addItem(t);
+    }
+  }
+
+  connect(&p4, SIGNAL(readyReadStandardOutput()),
+                    this, SLOT(p4ReadFromStdout()));
+  connect(&p4, SIGNAL(readyReadStandardError()),
+          this, SLOT(p4ReadFromStderr()));
+  connect(&p4, SIGNAL(error(QProcess::ProcessError)),
+          this, SLOT(p4Error()));
+  p4.start("rigctl -l");
+  p4.waitForFinished(1000);
+  ui.rigComboBox->addItem("  9998 Commander");
+  ui.rigComboBox->addItem("  9999 Ham Radio Deluxe");
+
+  QPalette pal(ui.myCallEntry->palette());
+  if(m_myCall=="") {
+    pal.setColor(QPalette::Base,"#ffccff");
+  } else {
+    pal.setColor(QPalette::Base,Qt::white);
+  }
+  ui.myCallEntry->setPalette(pal);
+  ui.myGridEntry->setPalette(pal);
+  ui.myCallEntry->setText(m_myCall);
+  ui.myGridEntry->setText(m_myGrid);
+  ui.pskReporterAntenna->setText(m_pskAntenna);
+
+  ui.idIntSpinBox->setValue(m_idInt);
+  ui.pttMethodComboBox->setCurrentIndex(m_pttMethodIndex);
+  ui.saveDirEntry->setText(m_saveDir);
+  ui.comboBoxSndIn->setCurrentIndex(m_nDevIn);
+  ui.comboBoxSndOut->setCurrentIndex(m_nDevOut);
+  ui.cbID73->setChecked(m_After73);
+  ui.cbPSKReporter->setChecked(m_pskReporter);
+  ui.cbSplit->setChecked(m_bSplit and m_catEnabled);
+  ui.cbXIT->setChecked(m_bXIT);
+  ui.cbXIT->setVisible(false);
+
+  enableWidgets();
+
+  ui.rigComboBox->setCurrentIndex(m_rigIndex);
+  ui.catPortComboBox->setCurrentIndex(m_catPortIndex);
+  ui.serialRateComboBox->setCurrentIndex(m_serialRateIndex);
+  ui.dataBitsComboBox->setCurrentIndex(m_dataBitsIndex);
+  ui.stopBitsComboBox->setCurrentIndex(m_stopBitsIndex);
+  ui.handshakeComboBox->setCurrentIndex(m_handshakeIndex);
+  ui.rbData->setChecked(m_pttData);
+  ui.pollSpinBox->setValue(m_poll);
+
+  // PY2SDR -- Per OS serial port names
+  m_tmp=m_pttPort;
+  ui.pttComboBox->clear();
+  ui.catPortComboBox->clear();
+  ui.pttComboBox->addItem("None");
+  ui.catPortComboBox->addItem("None");
+#ifdef WIN32
+  for ( int i = 1; i < 100; i++ ) {
+    ui.pttComboBox->addItem("COM" + QString::number(i));
+    ui.catPortComboBox->addItem("COM" + QString::number(i));
+  }
+  ui.pttComboBox->addItem("USB");
+  ui.catPortComboBox->addItem("USB");
+#else
+  ui.catPortComboBox->addItem("/dev/ttyS0");
+  ui.catPortComboBox->addItem("/dev/ttyS1");
+  ui.catPortComboBox->addItem("/dev/ttyS2");
+  ui.catPortComboBox->addItem("/dev/ttyS3");
+  ui.catPortComboBox->addItem("/dev/ttyS4");
+  ui.catPortComboBox->addItem("/dev/ttyS5");
+  ui.catPortComboBox->addItem("/dev/ttyS6");
+  ui.catPortComboBox->addItem("/dev/ttyS7");
+  ui.catPortComboBox->addItem("/dev/ttyUSB0");
+  ui.catPortComboBox->addItem("/dev/ttyUSB1");
+  ui.catPortComboBox->addItem("/dev/ttyUSB2");
+  ui.catPortComboBox->addItem("/dev/ttyUSB3");
+  ui.catPortComboBox->addItem(catPortDriver);
+
+  ui.pttComboBox->addItem("/dev/ttyS0");
+  ui.pttComboBox->addItem("/dev/ttyS1");
+  ui.pttComboBox->addItem("/dev/ttyS2");
+  ui.pttComboBox->addItem("/dev/ttyS3");
+  ui.pttComboBox->addItem("/dev/ttyS4");
+  ui.pttComboBox->addItem("/dev/ttyS5");
+  ui.pttComboBox->addItem("/dev/ttyS6");
+  ui.pttComboBox->addItem("/dev/ttyS7");
+  ui.pttComboBox->addItem("/dev/ttyUSB0");
+  ui.pttComboBox->addItem("/dev/ttyUSB1");
+  ui.pttComboBox->addItem("/dev/ttyUSB2");
+  ui.pttComboBox->addItem("/dev/ttyUSB3");
+#endif
+  ui.pttComboBox->setCurrentIndex(m_tmp);
+  ui.catPortComboBox->setCurrentIndex(m_catPortIndex);
+
+  int n=m_macro.length();
+  if(n>=1) ui.macro1->setText(m_macro[0].toUpper());
+  if(n>=2) ui.macro2->setText(m_macro[1].toUpper());
+  if(n>=3) ui.macro3->setText(m_macro[2].toUpper());
+  if(n>=4) ui.macro4->setText(m_macro[3].toUpper());
+  if(n>=5) ui.macro5->setText(m_macro[4].toUpper());
+  if(n>=6) ui.macro6->setText(m_macro[5].toUpper());
+  if(n>=7) ui.macro7->setText(m_macro[6].toUpper());
+  if(n>=8) ui.macro8->setText(m_macro[7].toUpper());
+  if(n>=8) ui.macro9->setText(m_macro[8].toUpper());
+  if(n>=10) ui.macro10->setText(m_macro[9].toUpper());
+
+  ui.f1->setText(m_dFreq[0]);
+  ui.f2->setText(m_dFreq[1]);
+  ui.f3->setText(m_dFreq[2]);
+  ui.f4->setText(m_dFreq[3]);
+  ui.f5->setText(m_dFreq[4]);
+  ui.f6->setText(m_dFreq[5]);
+  ui.f7->setText(m_dFreq[6]);
+  ui.f8->setText(m_dFreq[7]);
+  ui.f9->setText(m_dFreq[8]);
+  ui.f10->setText(m_dFreq[9]);
+  ui.f11->setText(m_dFreq[10]);
+  ui.f12->setText(m_dFreq[11]);
+  ui.f13->setText(m_dFreq[12]);
+  ui.f14->setText(m_dFreq[13]);
+  ui.f15->setText(m_dFreq[14]);
+  ui.f16->setText(m_dFreq[15]);
+}
+
+//------------------------------------------------------- accept()
+void DevSetup::accept()
+{
+  // Called when OK button is clicked.
+  // Check to see whether SoundInThread must be restarted,
+  // and save user parameters.
+
+  if(m_nDevIn!=ui.comboBoxSndIn->currentIndex() or
+     m_paInDevice!=m_inDevList[m_nDevIn]) 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_pskAntenna=ui.pskReporterAntenna->text();
+  m_idInt=ui.idIntSpinBox->value();
+  m_pttMethodIndex=ui.pttMethodComboBox->currentIndex();
+  m_pttPort=ui.pttComboBox->currentIndex();
+  m_saveDir=ui.saveDirEntry->text();
+  m_nDevIn=ui.comboBoxSndIn->currentIndex();
+  m_paInDevice=m_inDevList[m_nDevIn];
+  m_nDevOut=ui.comboBoxSndOut->currentIndex();
+  m_paOutDevice=m_outDevList[m_nDevOut];
+
+  m_macro.clear();
+  m_macro.append(ui.macro1->text());
+  m_macro.append(ui.macro2->text());
+  m_macro.append(ui.macro3->text());
+  m_macro.append(ui.macro4->text());
+  m_macro.append(ui.macro5->text());
+  m_macro.append(ui.macro6->text());
+  m_macro.append(ui.macro7->text());
+  m_macro.append(ui.macro8->text());
+  m_macro.append(ui.macro9->text());
+  m_macro.append(ui.macro10->text());
+
+  m_dFreq.clear();
+  m_dFreq.append(ui.f1->text());
+  m_dFreq.append(ui.f2->text());
+  m_dFreq.append(ui.f3->text());
+  m_dFreq.append(ui.f4->text());
+  m_dFreq.append(ui.f5->text());
+  m_dFreq.append(ui.f6->text());
+  m_dFreq.append(ui.f7->text());
+  m_dFreq.append(ui.f8->text());
+  m_dFreq.append(ui.f9->text());
+  m_dFreq.append(ui.f10->text());
+  m_dFreq.append(ui.f11->text());
+  m_dFreq.append(ui.f12->text());
+  m_dFreq.append(ui.f13->text());
+  m_dFreq.append(ui.f14->text());
+  m_dFreq.append(ui.f15->text());
+  m_dFreq.append(ui.f16->text());
+
+  if(m_bRigOpen) {
+    rig->close();
+    if(m_rig<9900) delete rig;
+    m_bRigOpen=false;
+  }
+
+  QDialog::accept();
+}
+
+//------------------------------------------------------- reject()
+void DevSetup::reject()
+{
+  if(m_bRigOpen) rig->close();
+  QDialog::reject();
+}
+
+void DevSetup::p4ReadFromStdout()                        //p4readFromStdout
+{
+  while(p4.canReadLine()) {
+    QString t(p4.readLine());
+    QString t1,t2,t3;
+    if(t.mid(0,6)!=" Rig #") {
+      t1=t.mid(0,6);
+      t2=t.mid(8,22).trimmed();
+      t3=t.mid(31,23).trimmed();
+      t=t1 + "  " + t2 + "  " + t3;
+      ui.rigComboBox->addItem(t);
+    }
+  }
+}
+
+void DevSetup::p4ReadFromStderr()                        //p4readFromStderr
+{
+  QByteArray t=p4.readAllStandardError();
+  if(t.length()>0) {
+    msgBox(t);
+  }
+}
+
+void DevSetup::p4Error()                                     //p4rror
+{
+  msgBox("Error running 'rigctl -l'.");
+}
+
+void DevSetup::msgBox(QString t)                             //msgBox
+{
+  msgBox0.setText(t);
+  msgBox0.exec();
+}
+
+void DevSetup::on_myCallEntry_editingFinished()
+{
+  QString t=ui.myCallEntry->text();
+  ui.myCallEntry->setText(t.toUpper());
+}
+
+void DevSetup::on_myGridEntry_editingFinished()
+{
+  QString t=ui.myGridEntry->text();
+  t=t.mid(0,4).toUpper()+t.mid(4,2).toLower();
+  ui.myGridEntry->setText(t);
+}
+
+void DevSetup::on_cbPSKReporter_clicked(bool b)
+{
+  m_pskReporter=b;
+  ui.label_8->setEnabled(m_pskReporter);
+  ui.pskReporterAntenna->setEnabled(m_pskReporter);
+}
+
+void DevSetup::on_pttMethodComboBox_activated(int index)
+{
+  m_pttMethodIndex=index;
+  enableWidgets();
+}
+
+void DevSetup::on_catPortComboBox_activated(int index)
+{
+  m_catPortIndex=index;
+  m_catPort=ui.catPortComboBox->itemText(index);
+}
+
+void DevSetup::on_cbEnableCAT_toggled(bool b)
+{
+  m_catEnabled=b;
+  enableWidgets();
+  ui.cbSplit->setChecked(m_bSplit and m_catEnabled);
+}
+
+void DevSetup::on_serialRateComboBox_activated(int index)
+{
+  m_serialRateIndex=index;
+  m_serialRate=ui.serialRateComboBox->itemText(index).toInt();
+}
+
+void DevSetup::on_handshakeComboBox_activated(int index)
+{
+  m_handshakeIndex=index;
+  m_handshake=ui.handshakeComboBox->itemText(index);
+}
+
+void DevSetup::on_dataBitsComboBox_activated(int index)
+{
+  m_dataBitsIndex=index;
+  m_dataBits=ui.dataBitsComboBox->itemText(index).toInt();
+}
+
+void DevSetup::on_stopBitsComboBox_activated(int index)
+{
+  m_stopBitsIndex=index;
+  m_stopBits=ui.stopBitsComboBox->itemText(index).toInt();
+}
+
+void DevSetup::on_rigComboBox_activated(int index)
+{
+  m_rigIndex=index;
+  QString t=ui.rigComboBox->itemText(index);
+  m_rig=t.mid(0,7).toInt();
+  enableWidgets();
+}
+
+void DevSetup::on_cbID73_toggled(bool checked)
+{
+  m_After73=checked;
+}
+
+void DevSetup::on_testCATButton_clicked()
+{
+  openRig();
+  if(!m_catEnabled) return;
+  QString t;
+  double fMHz=rig->getFreq(RIG_VFO_CURR)/1000000.0;
+  if(fMHz>0.0) {
+    t.sprintf("Rig control appears to be working.\nDial Frequency:  %.6f MHz",
+              fMHz);
+  } else {
+    t.sprintf("Rig control error %d\nFailed to read frequency.",
+              int(1000000.0*fMHz));
+    if(m_poll>0) {
+      m_catEnabled=false;
+      ui.cbEnableCAT->setChecked(false);
+    }
+  }
+  msgBox(t);
+}
+
+void DevSetup::openRig()
+{
+  QString t;
+  int ret;
+
+  if(!m_catEnabled) return;
+  if(m_bRigOpen) {
+    rig->close();
+    if(m_rig<9900) delete rig;
+    m_bRigOpen=false;
+  }
+
+  rig = new Rig();
+
+  if(m_rig<9900) {
+    if (!rig->init(m_rig)) {
+      msgBox("Rig init failure");
+      m_catEnabled=false;
+      return;
+    }
+    QString sCATport=m_catPort;
+#ifdef WIN32
+    sCATport="\\\\.\\" + m_catPort;    //Allow COM ports above 9
+#endif
+    rig->setConf("rig_pathname", sCATport.toLatin1().data());
+    char buf[80];
+    sprintf(buf,"%d",m_serialRate);
+    rig->setConf("serial_speed",buf);
+    sprintf(buf,"%d",m_dataBits);
+    rig->setConf("data_bits",buf);
+    sprintf(buf,"%d",m_stopBits);
+    rig->setConf("stop_bits",buf);
+    rig->setConf("serial_handshake",m_handshake.toLatin1().data());
+    if(m_bDTRoff) {
+      rig->setConf("rts_state","OFF");
+      rig->setConf("dtr_state","OFF");
+    }
+  }
+
+  ret=rig->open(m_rig);
+  if(ret==RIG_OK) {
+    m_bRigOpen=true;
+  } else {
+    t="Open rig failed";
+    msgBox(t);
+    m_catEnabled=false;
+    ui.cbEnableCAT->setChecked(false);
+    return;
+  }
+}
+
+void DevSetup::on_testPTTButton_clicked()
+{
+  m_test=1-m_test;
+  if(m_pttMethodIndex==1 or m_pttMethodIndex==2) {
+    ptt(m_pttPort,m_test,&g2_iptt,&g2_COMportOpen);
+  }
+  if(m_pttMethodIndex==0 and !m_bRigOpen) {
+//    on_testCATButton_clicked();
+    openRig();
+  }
+  if(m_pttMethodIndex==0 and m_bRigOpen) {
+    if(m_test==0) rig->setPTT(RIG_PTT_OFF, RIG_VFO_CURR);
+    if(m_test==1) {
+      if(m_pttData) rig->setPTT(RIG_PTT_ON_DATA, RIG_VFO_CURR);
+      if(!m_pttData) rig->setPTT(RIG_PTT_ON_MIC, RIG_VFO_CURR);
+    }
+  }
+}
+
+void DevSetup::on_cbDTRoff_toggled(bool checked)
+{
+  m_bDTRoff=checked;
+}
+
+void DevSetup::on_rbData_toggled(bool checked)
+{
+  m_pttData=checked;
+}
+
+void DevSetup::on_pollSpinBox_valueChanged(int n)
+{
+  m_poll=n;
+}
+
+void DevSetup::on_pttComboBox_currentIndexChanged(int index)
+{
+  m_pttPort=index;
+  enableWidgets();
+}
+
+void DevSetup::on_pttMethodComboBox_currentIndexChanged(int index)
+{
+  m_pttMethodIndex=index;
+  bool b=m_pttMethodIndex==1 or m_pttMethodIndex==2;
+  ui.pttComboBox->setEnabled(b);
+}
+
+void DevSetup::enableWidgets()
+{
+  ui.label_8->setEnabled(m_pskReporter);
+  ui.pskReporterAntenna->setEnabled(m_pskReporter);
+
+  ui.cbEnableCAT->setChecked(m_catEnabled);
+  ui.cbDTRoff->setChecked(m_bDTRoff);
+  ui.rigComboBox->setEnabled(m_catEnabled);
+  ui.testCATButton->setEnabled(m_catEnabled);
+  ui.label_4->setEnabled(m_catEnabled);
+  ui.label_47->setEnabled(m_catEnabled);
+  ui.cbSplit->setEnabled(m_catEnabled);
+  if(m_rig==9999) {                    //No Split Tx with HRD
+    ui.cbSplit->setChecked(false);
+    ui.cbSplit->setEnabled(false);
+  }
+  ui.cbXIT->setEnabled(m_catEnabled);
+
+  bool bSerial=m_catEnabled and (m_rig<9900);
+  ui.catPortComboBox->setEnabled(bSerial);
+  ui.serialRateComboBox->setEnabled(bSerial);
+  ui.dataBitsComboBox->setEnabled(bSerial);
+  ui.stopBitsComboBox->setEnabled(bSerial);
+  ui.handshakeComboBox->setEnabled(bSerial);
+  ui.cbDTRoff->setEnabled(bSerial);
+  ui.rbData->setEnabled(bSerial);
+  ui.rbMic->setEnabled(bSerial);
+  ui.label_21->setEnabled(bSerial);
+  ui.label_22->setEnabled(bSerial);
+  ui.label_23->setEnabled(bSerial);
+  ui.label_24->setEnabled(bSerial);
+  ui.label_25->setEnabled(bSerial);
+
+  ui.pollSpinBox->setEnabled(m_catEnabled);
+  bool b1=(m_pttMethodIndex==1 or m_pttMethodIndex==2);
+  ui.pttComboBox->setEnabled(b1);
+  b1=b1 and (m_pttPort!=0);
+  bool b2 = (m_catEnabled and m_pttMethodIndex==1 and m_rig<9900) or
+            (m_catEnabled and m_pttMethodIndex==2 and m_rig<9900);
+  bool b3 = (m_catEnabled and m_pttMethodIndex==0);
+  ui.testPTTButton->setEnabled(b1 or b2 or b3);  //Include PTT via HRD or Commander
+}
+
+void DevSetup::on_cbSplit_toggled(bool checked)
+{
+  m_bSplit=checked;
+  if(m_bSplit and m_bXIT) ui.cbXIT->setChecked(false);
+}
+
+void DevSetup::on_cbXIT_toggled(bool checked)
+{
+  m_bXIT=checked;
+  if(m_bSplit and m_bXIT) ui.cbSplit->setChecked(false);
+}
diff --git a/devsetup.h b/devsetup.h
new file mode 100644
index 0000000..f483470
--- /dev/null
+++ b/devsetup.h
@@ -0,0 +1,120 @@
+#ifndef DEVSETUP_H
+#define DEVSETUP_H
+
+#include <QDialog>
+#include <QProcess>
+#include <QMessageBox>
+#include "ui_devsetup.h"
+#include "rigclass.h"
+
+class DevSetup : public QDialog
+{
+  Q_OBJECT
+public:
+  DevSetup(QWidget *parent=0);
+  ~DevSetup();
+
+  void initDlg();
+
+  qint32  m_idInt;
+  qint32  m_pttMethodIndex;
+  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_catPortIndex;
+  qint32  m_rig;
+  qint32  m_rigIndex;
+  qint32  m_serialRate;
+  qint32  m_serialRateIndex;
+  qint32  m_dataBits;
+  qint32  m_dataBitsIndex;
+  qint32  m_stopBits;
+  qint32  m_stopBitsIndex;
+  qint32  m_handshakeIndex;
+  qint32  m_test;
+  qint32  m_poll;
+  qint32  m_tmp;
+
+  bool    m_restartSoundIn;
+  bool    m_restartSoundOut;
+  bool    m_pskReporter;
+  bool    m_firstCall;
+  bool    m_catEnabled;
+  bool    m_After73;
+  bool    m_bRigOpen;
+  bool    m_bDTRoff;
+  bool    m_pttData;
+  bool    m_bSplit;
+  bool    m_bXIT;
+
+  QString m_myCall;
+  QString m_myGrid;
+  QString m_saveDir;
+  QString m_azelDir;
+  QString m_catPort;
+  QString m_handshake;
+  QString m_pskAntenna;
+
+  QStringList m_macro;
+  QStringList m_dFreq;
+
+  QProcess p4;
+  QMessageBox msgBox0;
+
+public slots:
+  void accept();
+  void reject();
+  void p4ReadFromStdout();
+  void p4ReadFromStderr();
+  void p4Error();
+
+private slots:
+  void on_myCallEntry_editingFinished();
+  void on_myGridEntry_editingFinished();
+  void on_cbPSKReporter_clicked(bool checked);
+  void on_pttMethodComboBox_activated(int index);
+  void on_catPortComboBox_activated(int index);
+  void on_cbEnableCAT_toggled(bool checked);
+  void on_serialRateComboBox_activated(int index);
+  void on_handshakeComboBox_activated(int index);
+  void on_dataBitsComboBox_activated(int index);
+  void on_stopBitsComboBox_activated(int index);
+  void on_rigComboBox_activated(int index);
+  void on_cbID73_toggled(bool checked);
+  void on_testCATButton_clicked();
+  void on_testPTTButton_clicked();
+  void on_cbDTRoff_toggled(bool checked);
+  void on_rbData_toggled(bool checked);
+  void on_pollSpinBox_valueChanged(int n);
+  void on_pttComboBox_currentIndexChanged(int index);
+  void on_pttMethodComboBox_currentIndexChanged(int index);
+
+  void on_cbSplit_toggled(bool checked);
+
+  void on_cbXIT_toggled(bool checked);
+
+private:
+  Rig* rig;
+  void msgBox(QString t);
+  void enableWidgets();
+  void openRig();
+  Ui::DialogSndCard ui;
+};
+
+extern int ptt(int nport, int ntx, int* iptt, int* nopen);
+
+#ifdef WIN32
+extern "C" {
+  bool HRDInterfaceConnect(const wchar_t *host, const ushort);
+  void HRDInterfaceDisconnect();
+  bool HRDInterfaceIsConnected();
+  wchar_t* HRDInterfaceSendMessage(const wchar_t *msg);
+  void HRDInterfaceFreeString(const wchar_t *lstring);
+}
+#endif
+
+#endif // DEVSETUP_H
diff --git a/devsetup.ui b/devsetup.ui
new file mode 100644
index 0000000..b1a31cd
--- /dev/null
+++ b/devsetup.ui
@@ -0,0 +1,2599 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogSndCard</class>
+ <widget class="QDialog" name="DialogSndCard">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>569</width>
+    <height>493</height>
+   </rect>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>569</width>
+    <height>493</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Configuration</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <widget class="QTabWidget" name="ioTabWidget">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="tab">
+      <attribute name="title">
+       <string>Station</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout">
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_5">
+         <item>
+          <widget class="QLabel" name="label">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>80</width>
+             <height>20</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>80</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>My Call:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="myCallEntry">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Station callsign</string>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_8"/>
+         </item>
+         <item>
+          <spacer name="verticalSpacer_2">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_2">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>80</width>
+             <height>20</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>80</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>My Grid:</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="myGridEntry">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>100</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Maidenhead locator</string>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_2">
+         <item>
+          <widget class="QLabel" name="label_5">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>80</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>80</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>PTT method:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="pttMethodComboBox">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Select method for T/R switching</string>
+           </property>
+           <property name="currentIndex">
+            <number>1</number>
+           </property>
+           <item>
+            <property name="text">
+             <string>CAT</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>DTR</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>RTS</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>VOX</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_2">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_9">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>80</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>80</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>PTT Port:</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="pttComboBox">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>100</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Select port for hardware T/R switching</string>
+           </property>
+           <item>
+            <property name="text">
+             <string>None</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_6">
+         <item>
+          <widget class="QCheckBox" name="cbPSKReporter">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>146</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>146</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Send spots to PSK Reporter web site</string>
+           </property>
+           <property name="text">
+            <string>Enable PSK Reporter</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_7">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QCheckBox" name="cbID73">
+           <property name="toolTip">
+            <string>Send CW ID after a message with 73 or free text</string>
+           </property>
+           <property name="text">
+            <string>CW ID after 73</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_3">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_3">
+           <property name="minimumSize">
+            <size>
+             <width>0</width>
+             <height>20</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>CW ID Interval (min):</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QSpinBox" name="idIntSpinBox">
+           <property name="enabled">
+            <bool>true</bool>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Select CW ID interval (0 for none)</string>
+           </property>
+           <property name="minimum">
+            <number>0</number>
+           </property>
+           <property name="maximum">
+            <number>10</number>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_12">
+         <item>
+          <widget class="QLabel" name="label_8">
+           <property name="text">
+            <string>Antenna for PSK Reporter:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="pskReporterAntenna"/>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>13</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_7">
+         <item>
+          <widget class="QCheckBox" name="cbEnableCAT">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>110</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Enable computer control of transceiver</string>
+           </property>
+           <property name="text">
+            <string>Enable CAT</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_4">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Rig:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="rigComboBox">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Select radio type</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_1">
+         <item>
+          <widget class="QLabel" name="label_21">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>110</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>CAT port:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="catPortComboBox">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>100</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Select port for CAT control</string>
+           </property>
+           <property name="currentIndex">
+            <number>0</number>
+           </property>
+           <item>
+            <property name="text">
+             <string>None</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_4">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Fixed</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QCheckBox" name="cbDTRoff">
+           <property name="text">
+            <string>RTS/DTR OFF</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_14">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Fixed</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_24">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>60</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Data bits:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="dataBitsComboBox">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>50</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>50</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="currentIndex">
+            <number>1</number>
+           </property>
+           <item>
+            <property name="text">
+             <string>7</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>8</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_9">
+         <item>
+          <widget class="QLabel" name="label_22">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>110</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Serial rate:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="serialRateComboBox">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>100</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="currentIndex">
+            <number>1</number>
+           </property>
+           <item>
+            <property name="text">
+             <string>1200</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>4800</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>9600</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>19200</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>38400</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>57600</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_13">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Fixed</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="rbData">
+           <property name="toolTip">
+            <string>Use special Tx command for "data"</string>
+           </property>
+           <property name="text">
+            <string>Data</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="rbMic">
+           <property name="toolTip">
+            <string>Use normal Tx command</string>
+           </property>
+           <property name="text">
+            <string>Mic</string>
+           </property>
+           <property name="checked">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_5">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_25">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>60</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Stop bits:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="stopBitsComboBox">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>50</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>50</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="currentIndex">
+            <number>1</number>
+           </property>
+           <item>
+            <property name="text">
+             <string>1</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>2</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_10">
+         <item>
+          <widget class="QLabel" name="label_23">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>110</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Handshake:</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="handshakeComboBox">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>100</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="currentIndex">
+            <number>2</number>
+           </property>
+           <item>
+            <property name="text">
+             <string>None</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>XonXoff</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Hardware</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_16">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Fixed</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QCheckBox" name="cbSplit">
+           <property name="text">
+            <string>Split Tx</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_6">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_11">
+         <item>
+          <widget class="QPushButton" name="testCATButton">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>110</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>100</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Check to see if CAT control is working</string>
+           </property>
+           <property name="text">
+            <string>Test CAT Control</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="testPTTButton">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>100</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Test to see if T/R switching is working</string>
+           </property>
+           <property name="text">
+            <string>Test PTT</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_17">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Fixed</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QCheckBox" name="cbXIT">
+           <property name="text">
+            <string>XIT</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_12">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_47">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>60</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Polling interval (s):</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QSpinBox" name="pollSpinBox">
+           <property name="minimumSize">
+            <size>
+             <width>50</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="toolTip">
+            <string>Select interval for reading dial frequency</string>
+           </property>
+           <property name="maximum">
+            <number>60</number>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_1">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>13</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_13">
+         <item>
+          <spacer name="horizontalSpacer_15">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Fixed</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>96</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QLabel" name="label_26">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>16777215</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>Dev Ch  API       Name</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_6">
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_3">
+           <item>
+            <widget class="QLabel" name="label_6">
+             <property name="minimumSize">
+              <size>
+               <width>90</width>
+               <height>0</height>
+              </size>
+             </property>
+             <property name="maximumSize">
+              <size>
+               <width>90</width>
+               <height>16777215</height>
+              </size>
+             </property>
+             <property name="text">
+              <string>Audio In:</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QComboBox" name="comboBoxSndIn">
+             <property name="enabled">
+              <bool>true</bool>
+             </property>
+             <property name="toolTip">
+              <string>Select audio input device and driver API</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_4">
+           <item>
+            <widget class="QLabel" name="label_7">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+               <horstretch>0</horstretch>
+               <verstretch>0</verstretch>
+              </sizepolicy>
+             </property>
+             <property name="minimumSize">
+              <size>
+               <width>90</width>
+               <height>0</height>
+              </size>
+             </property>
+             <property name="maximumSize">
+              <size>
+               <width>90</width>
+               <height>16777215</height>
+              </size>
+             </property>
+             <property name="text">
+              <string>Audio Out:</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QComboBox" name="comboBoxSndOut">
+             <property name="toolTip">
+              <string>select audio output device and driver API</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout">
+           <item>
+            <widget class="QLabel" name="label_10">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+               <horstretch>0</horstretch>
+               <verstretch>0</verstretch>
+              </sizepolicy>
+             </property>
+             <property name="minimumSize">
+              <size>
+               <width>90</width>
+               <height>20</height>
+              </size>
+             </property>
+             <property name="text">
+              <string>Save Directory:</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QLineEdit" name="saveDirEntry">
+             <property name="toolTip">
+              <string>Directory for saved audio files</string>
+             </property>
+             <property name="text">
+              <string>C:\Users\joe\wsjt\map65\save</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_2">
+      <attribute name="title">
+       <string>Tx Macros</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_4">
+       <item>
+        <spacer name="verticalSpacer_5">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <layout class="QGridLayout" name="gridLayout">
+         <item row="6" column="1">
+          <widget class="QLabel" name="label_17">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>7</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="2">
+          <widget class="QLineEdit" name="macro6">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="2">
+          <widget class="QLineEdit" name="macro1">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLabel" name="label_13">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>3</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="2">
+          <widget class="QLineEdit" name="macro3">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>10W DPL 73 GL</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="1">
+          <widget class="QLabel" name="label_15">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>5</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="1">
+          <widget class="QLabel" name="label_18">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>8</string>
+           </property>
+          </widget>
+         </item>
+         <item row="8" column="1">
+          <widget class="QLabel" name="label_19">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>9</string>
+           </property>
+          </widget>
+         </item>
+         <item row="9" column="1">
+          <widget class="QLabel" name="label_20">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>10</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="1">
+          <widget class="QLabel" name="label_16">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>6</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1">
+          <widget class="QLabel" name="label_14">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>4</string>
+           </property>
+          </widget>
+         </item>
+         <item row="9" column="2">
+          <widget class="QLineEdit" name="macro10">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="2">
+          <widget class="QLineEdit" name="macro5">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="2">
+          <widget class="QLineEdit" name="macro4">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string/>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2">
+          <widget class="QLineEdit" name="macro2">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>5W DPL 73 GL</string>
+           </property>
+          </widget>
+         </item>
+         <item row="8" column="2">
+          <widget class="QLineEdit" name="macro9">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="3">
+          <spacer name="horizontalSpacer_8">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item row="0" column="1">
+          <widget class="QLabel" name="label_11">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>1</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="2">
+          <widget class="QLineEdit" name="macro7">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLabel" name="label_12">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>20</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>20</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>2</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="2">
+          <widget class="QLineEdit" name="macro8">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>200</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>200</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="0">
+          <spacer name="horizontalSpacer">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_3">
+      <attribute name="title">
+       <string>Default Frequencies</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_5">
+       <item>
+        <spacer name="verticalSpacer_6">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <layout class="QGridLayout" name="gridLayout_2">
+         <item row="5" column="4">
+          <widget class="QLabel" name="label_39">
+           <property name="text">
+            <string>6 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="5">
+          <widget class="QLineEdit" name="f13">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>50.293</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QLabel" name="label_43">
+           <property name="text">
+            <string>Band</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="2">
+          <widget class="QLabel" name="label_44">
+           <property name="text">
+            <string>Freq (MHz)</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="5">
+          <widget class="QLineEdit" name="f11">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>24.9246</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="1">
+          <widget class="QLabel" name="label_30">
+           <property name="text">
+            <string>80 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="4">
+          <widget class="QLabel" name="label_36">
+           <property name="text">
+            <string>15 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="5">
+          <widget class="QLineEdit" name="f10">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>21.078</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="4">
+          <widget class="QLabel" name="label_38">
+           <property name="text">
+            <string>10 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLabel" name="label_27">
+           <property name="text">
+            <string>2200 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="4">
+          <widget class="QLabel" name="label_37">
+           <property name="text">
+            <string>12 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="5">
+          <widget class="QLineEdit" name="f12">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>28.078</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="5">
+          <widget class="QLineEdit" name="f14">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>70.091</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="1">
+          <widget class="QLabel" name="label_31">
+           <property name="text">
+            <string>60 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="1">
+          <widget class="QLabel" name="label_32">
+           <property name="text">
+            <string>40 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="4">
+          <widget class="QLabel" name="label_40">
+           <property name="text">
+            <string>4 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="4">
+          <widget class="QLabel" name="label_35">
+           <property name="text">
+            <string>17 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="4">
+          <widget class="QLabel" name="label_45">
+           <property name="text">
+            <string>Band</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="5">
+          <widget class="QLabel" name="label_46">
+           <property name="text">
+            <string>Freq (MHz)</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="1">
+          <widget class="QLabel" name="label_33">
+           <property name="text">
+            <string>30 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="8" column="5">
+          <widget class="QLineEdit" name="f16">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>432.178</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1">
+          <widget class="QLabel" name="label_29">
+           <property name="text">
+            <string>160 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLabel" name="label_28">
+           <property name="text">
+            <string>630 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="8" column="1">
+          <widget class="QLabel" name="label_34">
+           <property name="text">
+            <string>20 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="8" column="4">
+          <widget class="QLabel" name="label_42">
+           <property name="text">
+            <string>Other</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="5">
+          <widget class="QLineEdit" name="f9">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>18.1046</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="2">
+          <widget class="QLineEdit" name="f2">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>0.4742</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="4">
+          <widget class="QLabel" name="label_41">
+           <property name="text">
+            <string>2 m</string>
+           </property>
+          </widget>
+         </item>
+         <item row="7" column="5">
+          <widget class="QLineEdit" name="f15">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>144.489</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2">
+          <widget class="QLineEdit" name="f1">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>0.136</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="2">
+          <widget class="QLineEdit" name="f3">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>1.838</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="2">
+          <widget class="QLineEdit" name="f5">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>5.2872</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="2">
+          <widget class="QLineEdit" name="f4">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>3.578</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="3">
+          <spacer name="horizontalSpacer_9">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item row="7" column="2">
+          <widget class="QLineEdit" name="f7">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>10.130</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="6" column="2">
+          <widget class="QLineEdit" name="f6">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>7.078</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="8" column="2">
+          <widget class="QLineEdit" name="f8">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>90</width>
+             <height>27</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>90</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="text">
+            <string>14.078</string>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignCenter</set>
+           </property>
+          </widget>
+         </item>
+         <item row="4" column="0">
+          <spacer name="horizontalSpacer_10">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item row="4" column="6">
+          <spacer name="horizontalSpacer_11">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_4">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="maximumSize">
+      <size>
+       <width>469</width>
+       <height>16777215</height>
+      </size>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>myCallEntry</tabstop>
+  <tabstop>myGridEntry</tabstop>
+  <tabstop>pttMethodComboBox</tabstop>
+  <tabstop>pttComboBox</tabstop>
+  <tabstop>cbPSKReporter</tabstop>
+  <tabstop>cbID73</tabstop>
+  <tabstop>idIntSpinBox</tabstop>
+  <tabstop>pskReporterAntenna</tabstop>
+  <tabstop>cbEnableCAT</tabstop>
+  <tabstop>rigComboBox</tabstop>
+  <tabstop>catPortComboBox</tabstop>
+  <tabstop>dataBitsComboBox</tabstop>
+  <tabstop>serialRateComboBox</tabstop>
+  <tabstop>stopBitsComboBox</tabstop>
+  <tabstop>handshakeComboBox</tabstop>
+  <tabstop>testCATButton</tabstop>
+  <tabstop>testPTTButton</tabstop>
+  <tabstop>pollSpinBox</tabstop>
+  <tabstop>comboBoxSndIn</tabstop>
+  <tabstop>comboBoxSndOut</tabstop>
+  <tabstop>saveDirEntry</tabstop>
+  <tabstop>macro1</tabstop>
+  <tabstop>macro2</tabstop>
+  <tabstop>macro3</tabstop>
+  <tabstop>macro4</tabstop>
+  <tabstop>macro5</tabstop>
+  <tabstop>macro6</tabstop>
+  <tabstop>macro7</tabstop>
+  <tabstop>macro8</tabstop>
+  <tabstop>macro9</tabstop>
+  <tabstop>macro10</tabstop>
+  <tabstop>f1</tabstop>
+  <tabstop>f2</tabstop>
+  <tabstop>f3</tabstop>
+  <tabstop>f4</tabstop>
+  <tabstop>f5</tabstop>
+  <tabstop>f6</tabstop>
+  <tabstop>f7</tabstop>
+  <tabstop>f8</tabstop>
+  <tabstop>f9</tabstop>
+  <tabstop>f10</tabstop>
+  <tabstop>f11</tabstop>
+  <tabstop>f12</tabstop>
+  <tabstop>f13</tabstop>
+  <tabstop>f14</tabstop>
+  <tabstop>f15</tabstop>
+  <tabstop>f16</tabstop>
+  <tabstop>buttonBox</tabstop>
+  <tabstop>ioTabWidget</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>DialogSndCard</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>DialogSndCard</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/displaytext.cpp b/displaytext.cpp
new file mode 100644
index 0000000..0b8181e
--- /dev/null
+++ b/displaytext.cpp
@@ -0,0 +1,16 @@
+#include "displaytext.h"
+#include <QDebug>
+#include <QMouseEvent>
+
+DisplayText::DisplayText(QWidget *parent) :
+    QTextBrowser(parent)
+{
+}
+
+void DisplayText::mouseDoubleClickEvent(QMouseEvent *e)
+{
+  bool ctrl = (e->modifiers() & Qt::ControlModifier);
+  bool shift = (e->modifiers() & Qt::ShiftModifier);
+  emit(selectCallsign(shift,ctrl));
+  QTextBrowser::mouseDoubleClickEvent(e);
+}
diff --git a/displaytext.h b/displaytext.h
new file mode 100644
index 0000000..c07f00e
--- /dev/null
+++ b/displaytext.h
@@ -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 shift, bool ctrl);
+
+public slots:
+
+protected:
+  void mouseDoubleClickEvent(QMouseEvent *e);
+
+};
+
+#endif // DISPLAYTEXT_H
diff --git a/ffft.f b/ffft.f
new file mode 100644
index 0000000..9c3c091
--- /dev/null
+++ b/ffft.f
@@ -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
diff --git a/fftw3.f b/fftw3.f
new file mode 100644
index 0000000..3410184
--- /dev/null
+++ b/fftw3.f
@@ -0,0 +1,64 @@
+      INTEGER FFTW_R2HC
+      PARAMETER (FFTW_R2HC=0)
+      INTEGER FFTW_HC2R
+      PARAMETER (FFTW_HC2R=1)
+      INTEGER FFTW_DHT
+      PARAMETER (FFTW_DHT=2)
+      INTEGER FFTW_REDFT00
+      PARAMETER (FFTW_REDFT00=3)
+      INTEGER FFTW_REDFT01
+      PARAMETER (FFTW_REDFT01=4)
+      INTEGER FFTW_REDFT10
+      PARAMETER (FFTW_REDFT10=5)
+      INTEGER FFTW_REDFT11
+      PARAMETER (FFTW_REDFT11=6)
+      INTEGER FFTW_RODFT00
+      PARAMETER (FFTW_RODFT00=7)
+      INTEGER FFTW_RODFT01
+      PARAMETER (FFTW_RODFT01=8)
+      INTEGER FFTW_RODFT10
+      PARAMETER (FFTW_RODFT10=9)
+      INTEGER FFTW_RODFT11
+      PARAMETER (FFTW_RODFT11=10)
+      INTEGER FFTW_FORWARD
+      PARAMETER (FFTW_FORWARD=-1)
+      INTEGER FFTW_BACKWARD
+      PARAMETER (FFTW_BACKWARD=+1)
+      INTEGER FFTW_MEASURE
+      PARAMETER (FFTW_MEASURE=0)
+      INTEGER FFTW_DESTROY_INPUT
+      PARAMETER (FFTW_DESTROY_INPUT=1)
+      INTEGER FFTW_UNALIGNED
+      PARAMETER (FFTW_UNALIGNED=2)
+      INTEGER FFTW_CONSERVE_MEMORY
+      PARAMETER (FFTW_CONSERVE_MEMORY=4)
+      INTEGER FFTW_EXHAUSTIVE
+      PARAMETER (FFTW_EXHAUSTIVE=8)
+      INTEGER FFTW_PRESERVE_INPUT
+      PARAMETER (FFTW_PRESERVE_INPUT=16)
+      INTEGER FFTW_PATIENT
+      PARAMETER (FFTW_PATIENT=32)
+      INTEGER FFTW_ESTIMATE
+      PARAMETER (FFTW_ESTIMATE=64)
+      INTEGER FFTW_ESTIMATE_PATIENT
+      PARAMETER (FFTW_ESTIMATE_PATIENT=128)
+      INTEGER FFTW_BELIEVE_PCOST
+      PARAMETER (FFTW_BELIEVE_PCOST=256)
+      INTEGER FFTW_DFT_R2HC_ICKY
+      PARAMETER (FFTW_DFT_R2HC_ICKY=512)
+      INTEGER FFTW_NONTHREADED_ICKY
+      PARAMETER (FFTW_NONTHREADED_ICKY=1024)
+      INTEGER FFTW_NO_BUFFERING
+      PARAMETER (FFTW_NO_BUFFERING=2048)
+      INTEGER FFTW_NO_INDIRECT_OP
+      PARAMETER (FFTW_NO_INDIRECT_OP=4096)
+      INTEGER FFTW_ALLOW_LARGE_GENERIC
+      PARAMETER (FFTW_ALLOW_LARGE_GENERIC=8192)
+      INTEGER FFTW_NO_RANK_SPLITS
+      PARAMETER (FFTW_NO_RANK_SPLITS=16384)
+      INTEGER FFTW_NO_VRANK_SPLITS
+      PARAMETER (FFTW_NO_VRANK_SPLITS=32768)
+      INTEGER FFTW_NO_VRECURSE
+      PARAMETER (FFTW_NO_VRECURSE=65536)
+      INTEGER FFTW_NO_SIMD
+      PARAMETER (FFTW_NO_SIMD=131072)
diff --git a/getdev.cpp b/getdev.cpp
new file mode 100644
index 0000000..751c87f
--- /dev/null
+++ b/getdev.cpp
@@ -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[50];
+  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;
+  }
+}
diff --git a/getfile.cpp b/getfile.cpp
new file mode 100644
index 0000000..ecc7bbb
--- /dev/null
+++ b/getfile.cpp
@@ -0,0 +1,199 @@
+#include "getfile.h"
+#include <QDir>
+#include <stdlib.h>
+#include <math.h>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <err.h>
+#endif
+
+void getfile(QString fname, int ntrperiod)
+{
+
+  char name[80];
+  strcpy(name,fname.toLatin1());
+  FILE* fp=fopen(name,"rb");
+
+  int i0=fname.indexOf(".wav");
+  jt9com_.nutc=0;
+  if(i0>0) jt9com_.nutc=100*fname.mid(i0-4,2).toInt() +
+      fname.mid(i0-2,2).toInt();
+  int npts=ntrperiod*12000;
+  memset(jt9com_.d2,0,2*npts);
+
+  if(fp != NULL) {
+// Read (and ignore) a 44-byte WAV header; then read data
+    int n=fread(jt9com_.d2,1,44,fp);
+    n=fread(jt9com_.d2,2,npts,fp);
+    fclose(fp);
+    jt9com_.newdat=1;
+    if(n==-99999) jt9com_.newdat=2;             //Silence compiler warning
+  }
+}
+
+void savewav(QString fname, int ntrperiod)
+{
+  struct {
+    char ariff[4];         //ChunkID:    "RIFF"
+    int nchunk;            //ChunkSize: 36+SubChunk2Size
+    char awave[4];         //Format: "WAVE"
+    char afmt[4];          //Subchunk1ID: "fmt "
+    int lenfmt;            //Subchunk1Size: 16
+    short int nfmt2;       //AudioFormat: 1
+    short int nchan2;      //NumChannels: 1
+    int nsamrate;          //SampleRate: 12000
+    int nbytesec;          //ByteRate: SampleRate*NumChannels*BitsPerSample/8
+    short int nbytesam2;   //BlockAlign: NumChannels*BitsPerSample/8
+    short int nbitsam2;    //BitsPerSample: 16
+    char adata[4];         //Subchunk2ID: "data"
+    int ndata;             //Subchunk2Size: numSamples*NumChannels*BitsPerSample/8
+  } hdr;
+
+  int npts=ntrperiod*12000;
+//  qint16* buf=(qint16*)malloc(2*npts);
+  char name[80];
+  strcpy(name,fname.toLatin1());
+  FILE* fp=fopen(name,"wb");
+
+  if(fp != NULL) {
+// Write a WAV header
+    hdr.ariff[0]='R';
+    hdr.ariff[1]='I';
+    hdr.ariff[2]='F';
+    hdr.ariff[3]='F';
+    hdr.nchunk=36 + 2*npts;
+    hdr.awave[0]='W';
+    hdr.awave[1]='A';
+    hdr.awave[2]='V';
+    hdr.awave[3]='E';
+    hdr.afmt[0]='f';
+    hdr.afmt[1]='m';
+    hdr.afmt[2]='t';
+    hdr.afmt[3]=' ';
+    hdr.lenfmt=16;
+    hdr.nfmt2=1;
+    hdr.nchan2=1;
+    hdr.nsamrate=12000;
+    hdr.nbytesec=2*12000;
+    hdr.nbytesam2=2;
+    hdr.nbitsam2=16;
+    hdr.adata[0]='d';
+    hdr.adata[1]='a';
+    hdr.adata[2]='t';
+    hdr.adata[3]='a';
+    hdr.ndata=2*npts;
+
+    fwrite(&hdr,sizeof(hdr),1,fp);
+//    memcpy(jt9com_.d2,buf,2*npts);
+//    fwrite(buf,2,npts,fp);
+    fwrite(jt9com_.d2,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;
+}
+
+int ptt(int nport, int ntx, int* iptt, int* nopen)
+{
+#ifdef WIN32
+  static HANDLE hFile;
+  char s[10];
+  int i3=1,i4=1,i5=1,i6=1,i9=1,i00=1;  //Defs to silence compiler warning
+
+  if(nport==0) {
+    *iptt=ntx;
+    return 0;
+  }
+
+  if(ntx && (!(*nopen))) {
+    sprintf(s,"\\\\.\\COM%d",nport);
+    hFile=CreateFile(TEXT(s),GENERIC_WRITE,0,NULL,OPEN_EXISTING,
+                     FILE_ATTRIBUTE_NORMAL,NULL);
+    if(hFile==INVALID_HANDLE_VALUE) {
+      QString t;
+      t.sprintf("Cannot open COM port %d for PTT\n",nport);
+      return 1;
+    }
+    *nopen=1;
+  }
+
+  if(ntx && *nopen) {
+    i3=EscapeCommFunction(hFile,SETRTS);
+    i5=EscapeCommFunction(hFile,SETDTR);
+    *iptt=1;
+  }
+
+  else {
+    i4=EscapeCommFunction(hFile,CLRRTS);
+    i6=EscapeCommFunction(hFile,CLRDTR);
+    i9=EscapeCommFunction(hFile,CLRBREAK);
+    i00=CloseHandle(hFile);
+    *iptt=0;
+    *nopen=0;
+  }
+  if((i3+i4+i5+i6+i9+i00)==-999) return 1;    //Silence compiler warning
+  return 0;
+#else
+  int control=TIOCM_RTS | TIOCM_DTR;
+//  int control = TIOCM_RTS;
+  static int fd;
+
+  if(*nopen==0) {
+    fd=open("/dev/ttyUSB0",O_RDWR | O_NONBLOCK);
+    if(fd<0) {
+      return -1;
+    }
+    *nopen=1;
+  }
+
+  if(ntx) {
+    ioctl(fd, TIOCMBIS, &control);
+    *iptt=1;
+    *nopen=1;
+  } else {
+    ioctl(fd, TIOCMBIC, &control);
+    close(fd);
+    *iptt=0;
+    *nopen=0;
+  }
+  return 0;
+#endif
+  if((nport+ntx+(*iptt)==-99999)) *nopen=0;   //Silence compiler warning
+  return 0;
+}
diff --git a/getfile.h b/getfile.h
new file mode 100644
index 0000000..2e255d1
--- /dev/null
+++ b/getfile.h
@@ -0,0 +1,18 @@
+#ifndef GETFILE_H
+#define GETFILE_H
+#include <QString>
+#include <QFile>
+#include <QDebug>
+#include "commons.h"
+
+void getfile(QString fname, int ntrperiod);
+float gran();
+//int ptt(int* nport, int* ntx, int* iptt);
+int ptt(int nport, int ntx, int* iptt, int* nopen);
+
+extern "C" {
+int ptt_(int nport, int ntx, int* iptt, int* nopen);
+}
+
+
+#endif // GETFILE_H
diff --git a/in.dat b/in.dat
new file mode 100644
index 0000000..5294129
--- /dev/null
+++ b/in.dat
@@ -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
diff --git a/jt9.txt b/jt9.txt
new file mode 100644
index 0000000..ddbd86b
--- /dev/null
+++ b/jt9.txt
@@ -0,0 +1,65 @@
+JT9 is a mode designed for amateur QSOs at MF and LF.  The mode uses
+the same 72-bit structured messages as JT65.  Error control coding
+(ECC) uses a strong convolutional code with constraint length K=32,
+rate r=1/2, and a zero tail, leading to an encoded message length of
+(72+31)*2 = 206 information-carrying bits.  Modulation is 9-FSK: 8
+tones for data, one for synchronization.  Sixteen symbol intervals are
+used for synchronization, so a transmission requires a total of 207/3
++ 16 = 85 channel symbols.  Symbol durations tsym are approximately
+(TRperiod-8)/85, where TRperiod is the T/R sequence length in seconds.
+Exact symbol lengths are chosen so that nsps, the number of samples
+per symbol (at 12000 samples per second) is a number with no prime
+factor greater than 7.  This choice makes for efficient FFTs.  Tone
+spacing of the 9-FSK modulation is df=1/tsym=12000/nsps, equal to the
+keying rate.  The total occupied bandwidth is 9*df.  The generated
+signal has continuous phase, and there are no key clicks.
+
+Parameters of five JT9 sub-modes are summarized in the following
+table, along with S/N thresholds measured by simulation on an AWGN
+channel.  Numbers following "JT9-" in the sub-mode names specify the
+T/R sequence length in minutes.
+
+--------------------------------------------------------------------------
+Mode     nsps nsps2  df    tsym  BW   S/N*   Tdec Tfree Factors 
+        12000  1500 (Hz)   (s)  (Hz)  (dB)   (s)   (s)  of nsps      nfft3
+--------------------------------------------------------------------------
+JT9-1    6912   864 1.736  0.58 15.6 -26.9   52.5  7.5 2^8 3^3        2048
+JT9-2   15360  1920 0.781  1.28  7.0 -30.2  112.3  7.7 2^10 3 5       2048
+JT9-5   40960  5120 0.293  3.41  2.6 -34.4  293.6  6.4 2^13 5         6144
+JT9-10  82944 10368 0.145  6.91  1.3 -37.5  591.0  9.0 2^10 3^4      12288
+JT9-30 252000 31500 0.048 21.00  0.4 -42.3 1788.5 11.5 2^5 3^2 5^3 7 32768
+--------------------------------------------------------------------------
+* Noise power measured in a 2500 Hz bandwidth.
+NB: nfft3 might be doubled and used with a sin^2 window.
+
+Transmitting
+------------
+1. Source encode the structured message to 72 bits
+2. Apply convolutional ECC (K=32, r=1/2) to yield (72+31)*2 = 206 bits
+3. Interleave to scramble the bit order
+4. Assemble 3-bit groups to make (206+1)/3 = 69 symbols
+5. Gray-code the symbol values
+6. Insert 16 sync symbols ==> 69+16=85 channel symbols, values 0-8
+
+
+Receiving
+---------
+1.  Apply noise blanking with the timf2 method
+2.  Filter to 1000 Hz bandwidth and downsample (1/8) to 1500 Hz, saving
+    complex data to array c0(2,700,000).
+3.  Compute spectra at half-symbol steps.  Use for waterfall display 
+    s(22000) and save in ss(184,22000) and savg(22000) for detecting 
+    sync vectors.
+4.  At time Tdec, find sync vectors in ss(); get approx DF or list of DFs
+5.  Do full-length FFT, NFFT1=96*nsps2, zero-padded as required.
+6.  For each candidate signal, do inverse FFT of length 1536 (or 3072?).  
+    This yields 16 complex samples per symbol; sync tone should be 
+    close to zero frequency.
+7.  Use afc65b method to get improved values of DF, DT.
+8.  Tweak freq and time offset to 0.
+9.  Compute 8-bin spectra of 69 data symbols: ssym(0:7,69).  Re-order the
+    bins to remove Gray code.
+10. Compute soft symbols for 206 bits (bit 207 is always 0).
+11. Remove interleaving
+12. Pack bits into bytes, send to Fano decoder
+13. If Fano succeeds, remove source encoding and display user message.
diff --git a/killbyname.cpp b/killbyname.cpp
new file mode 100644
index 0000000..240ad5a
--- /dev/null
+++ b/killbyname.cpp
@@ -0,0 +1,284 @@
+#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 at 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 iLen,iLenP,indx;
+  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*))
+        GetProcAddress( hInstLib, "EnumProcesses" ) ;
+    lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
+        DWORD, LPDWORD)) GetProcAddress( hInstLib,                                                                     "EnumProcessModules" ) ;
+        lpfGetModuleBaseName =(DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR,
+        DWORD )) 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) ) {
+//          iLen=lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH);
+          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))
+        GetProcAddress( hInstLib,
+                        "CreateToolhelp32Snapshot" ) ;
+    lpfProcess32First=
+        (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
+        GetProcAddress( hInstLib, "Process32First" ) ;
+    lpfProcess32Next=
+        (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
+        GetProcAddress( hInstLib, "Process32Next" ) ;
+    lpfModule32First=
+        (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
+        GetProcAddress( hInstLib, "Module32First" ) ;
+    lpfModule32Next=
+        (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
+        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;
+}
diff --git a/lib/Makefile.MinGW b/lib/Makefile.MinGW
new file mode 100644
index 0000000..e09924b
--- /dev/null
+++ b/lib/Makefile.MinGW
@@ -0,0 +1,117 @@
+# Makefile for MinGW on Windows
+# Windows re-direct:
+#   C> make > junk1 2>&1
+
+CC = gcc
+FC = g95
+
+FFLAGS = -O2 -fbounds-check -Wall -Wno-precision-loss -fno-second-underscore
+CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
+
+# 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:    libjt9.a jt9sim.exe jt9.exe jt9code.exe jt65.exe
+
+OBJS1 = pctile.o graycode.o sort.o ssort.o \
+	unpackmsg.o igray.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 \
+	nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.o \
+	symspec.o analytic.o db.o genjt9.o \
+	packbits.o unpackbits.o encode232.o interleave9.o \
+	entail.o fano232.o gran.o sync9.o decode9.o \
+	fil3.o decoder.o grid2n.o n2grid.o timer.o \
+	softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
+	peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
+	fillcom.o chkss2.o zplot9.o flat2.o \
+	jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
+	filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
+	extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
+	move.o indexx.o graycode65.o twkfreq65.o smo121.o \
+	wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o
+
+libjt9.a: $(OBJS1)
+	ar cr libjt9.a $(OBJS1) 
+	ranlib libjt9.a
+
+OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o cutil.o
+LIBS2 = -L'c:/QtSDK/Desktop/Qt/4.7.4/mingw/lib' -lQtCore4
+jt9.exe: $(OBJS2) libjt9.a
+	g++ -o jt9.exe $(OBJS2) $(LIBS2) libjt9.a ../libfftw3f_win.a \
+	c:/MinGW/lib/libf95.a
+	cp jt9.exe ../../wsjtx_install
+
+OBJS3 = jt9sim.o 
+jt9sim.exe: $(OBJS3) libjt9.a
+	$(FC) -o jt9sim.exe $(OBJS3) libjt9.a
+
+OBJS4 = jt9code.o 
+jt9code.exe: $(OBJS4) libjt9.a
+	$(FC) -o jt9code.exe $(OBJS4) libjt9.a
+
+OBJS5 = jt65.o 
+jt65.exe: $(OBJS5) libjt9.a 
+	$(FC) -o jt65.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
+
+INCPATH = -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore' \
+	 -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include' \
+	 -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/ActiveQt' \
+	 -I'release' -I'.' -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/mkspecs/win32-g++'
+
+sync9.o: sync9.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c sync9.f90
+
+spec9.o: spec9.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c spec9.f90
+
+peakdt9.o: peakdt9.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c peakdt9.f90
+
+jt9sim.o: jt9sim.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c jt9sim.f90
+
+genjt9.o: genjt9.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c genjt9.f90
+
+redsync.o: redsync.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c redsync.f90
+
+unpackmsg.o: unpackmsg.f90
+	$(FC) -c -O0 -fbounds-check -Wall -Wno-precision-loss unpackmsg.f90
+
+ipcomm.o: ipcomm.cpp
+	g++ -c $(INCPATH) ipcomm.cpp
+
+sec_midn.o: sec_midn.f90
+	$(FC) -c -fno-second-underscore sec_midn.f90
+
+#rig_control.o: rig_control.c
+#	$(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include rig_control.c
+
+tstrig.o: tstrig.c
+	$(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
+
+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 libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe
diff --git a/lib/Makefile.linux b/lib/Makefile.linux
new file mode 100644
index 0000000..19e6096
--- /dev/null
+++ b/lib/Makefile.linux
@@ -0,0 +1,104 @@
+CC = gcc
+FC = gfortran
+
+FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion -fno-second-underscore
+CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
+
+# 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:    libjt9.a jt9sim jt9 jt9code
+
+OBJS1 = pctile.o graycode.o sort.o ssort.o \
+	unpackmsg.o igray.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 \
+	nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.o \
+	symspec.o analytic.o db.o genjt9.o \
+	packbits.o unpackbits.o encode232.o interleave9.o \
+	entail.o fano232.o gran.o sync9.o decode9.o \
+	fil3.o decoder.o grid2n.o n2grid.o timer.o \
+	softsym.o peakdt9.o getlags.o afc9.o fchisq.o \
+	twkfreq.o downsam9.o symspec2.o ipcomm.o sleep_msec.o \
+	stdmsg.o sec_midn.o cutil.o azdist.o geodist.o morse.o \
+	fillcom.o chkss2.o zplot9.o flat2.o \
+	jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
+	filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
+	extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
+	move.o indexx.o graycode65.o twkfreq65.o smo121.o \
+	wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o
+
+libjt9.a: $(OBJS1)
+	ar cr libjt9.a $(OBJS1) 
+	ranlib libjt9.a
+
+OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o
+
+jt9: 	$(OBJS2) libjt9.a 
+	g++ -o jt9 $(OBJS2) libjt9.a -lfftw3f -lgfortran -lQtCore
+	cp jt9 ../../wsjtx_install
+
+OBJS3 = jt9sim.o 
+jt9sim: $(OBJS3) libjt9.a
+	$(FC) -o jt9sim $(OBJS3) libjt9.a
+
+OBJS4 = jt9code.o 
+jt9code: $(OBJS4) libjt9.a
+	$(FC) -o jt9code $(OBJS4) libjt9.a
+
+#INCPATH = -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore' \
+#	 -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include' \
+#	 -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/ActiveQt' \
+#	 -I'release' -I'.' -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/mkspecs/win32-g++'
+
+INCPATH =  -I'/usr/include/qt4' -I'/usr/include/qt4/QtCore' 
+
+#jt9.o:	jt9.f90
+#	$(FC) -O0 -c jt9.f90
+
+sync9.o: sync9.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c sync9.f90
+
+peakdf9.o: peakdf9.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c peakdf9.f90
+
+peakdt9.o: peakdt9.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c peakdt9.f90
+
+jt9sim.o: jt9sim.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c jt9sim.f90
+
+genjt9.o: genjt9.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c genjt9.f90
+
+redsync.o: redsync.f90 jt9sync.f90
+	$(FC) $(FFLAGS) -c redsync.f90
+
+ipcomm.o: ipcomm.cpp
+	g++ -c $(INCPATH) ipcomm.cpp
+
+sec_midn.o: sec_midn.f90
+	$(FC) -c -fno-second-underscore sec_midn.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 libjt9.a wsjtx jt9sim jt9 jt9code
diff --git a/lib/afc65b.f90 b/lib/afc65b.f90
new file mode 100644
index 0000000..f78f275
--- /dev/null
+++ b/lib/afc65b.f90
@@ -0,0 +1,59 @@
+subroutine afc65b(cx,npts,fsample,nflip,a,ccfbest,dtbest)
+
+! Find delta f, f1, f2 ==> a(1:3)
+
+  complex cx(npts)
+  real a(5),deltaa(5)
+
+  a(1)=0.
+  a(2)=0.
+  a(3)=0.
+  a(4)=0.
+  deltaa(1)=2.0
+  deltaa(2)=2.0
+  deltaa(3)=2.0
+  deltaa(4)=0.05
+  nterms=3                                  !Maybe 2 is enough?
+
+!  Start the iteration
+  chisqr=0.
+  chisqr0=1.e6
+  do iter=1,3                               !One iteration is enough?
+     do j=1,nterms
+        chisq1=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
+        fn=0.
+        delta=deltaa(j)
+10      a(j)=a(j)+delta
+        chisq2=fchisq65(cx,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=fchisq65(cx,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=fchisq65(cx,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
+
+  return
+end subroutine afc65b
diff --git a/lib/afc9.f90 b/lib/afc9.f90
new file mode 100644
index 0000000..1fbcf2f
--- /dev/null
+++ b/lib/afc9.f90
@@ -0,0 +1,58 @@
+subroutine afc9(c3,npts,fsample,a,syncpk)
+
+  complex c3(0:npts-1)
+  real a(3),deltaa(3)
+
+  a(1)=0.                                   !f0
+  a(2)=0.                                   !f1
+  a(3)=0.                                   !f2
+  deltaa(1)=0.2
+  deltaa(2)=0.01
+  deltaa(3)=0.01
+  nterms=3
+
+! Start the iteration
+  chisqr=0.
+  chisqr0=1.e6
+  do iter=1,4                               !One iteration is enough?
+     do j=1,nterms
+        chisq1=fchisq(c3,npts,fsample,a)
+        fn=0.
+        delta=deltaa(j)
+10      a(j)=a(j)+delta
+        chisq2=fchisq(c3,npts,fsample,a)
+        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(c3,npts,fsample,a)
+        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.
+!        write(*,4000) iter,j,a,deltaa,-chisq2
+!4000    format(i1,i2,6f10.4,f9.3)
+     enddo
+     chisqr=fchisq(c3,npts,fsample,a)
+     if(chisqr/chisqr0.gt.0.9999) exit
+     chisqr0=chisqr
+  enddo
+
+  syncpk=-chisqr
+!  write(*,4001) a,deltaa,-chisq2
+!4001 format(3x,6f10.4,f9.3)
+
+  return
+end subroutine afc9
diff --git a/lib/analytic.f90 b/lib/analytic.f90
new file mode 100644
index 0000000..33d5fc7
--- /dev/null
+++ b/lib/analytic.f90
@@ -0,0 +1,25 @@
+subroutine analytic(d,npts,nfft,s,c)
+
+! Convert real data to analytic signal
+
+  parameter (NFFTMAX=128*1024)
+  real d(npts)
+  real s(npts)
+  complex c(NFFTMAX)
+
+  nh=nfft/2
+  fac=2.0/nfft
+  c(1:npts)=fac*d(1:npts)
+  c(npts+1:nfft)=0.
+  call four2a(c,nfft,1,-1,1)               !Forward c2c FFT
+
+  do i=1,nh
+     s(i)=real(c(i))**2 + aimag(c(i))**2
+  enddo
+
+  c(1)=0.5*c(1)
+  c(nh+2:nfft)=0.
+  call four2a(c,nfft,1,1,1)                !Inverse c2c FFT
+
+  return
+end subroutine analytic
diff --git a/lib/azdist.f90 b/lib/azdist.f90
new file mode 100644
index 0000000..528801f
--- /dev/null
+++ b/lib/azdist.f90
@@ -0,0 +1,107 @@
+subroutine azdist(MyGrid,HisGrid,utch,nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter)
+
+  character*6 MyGrid,HisGrid,mygrid0,hisgrid0
+  real*8 utch,utch0
+  logical HotABetter,IamEast
+  real eltab(22),daztab(22)
+  data eltab/18.,15.,13.,11.,9.,8.,7.,6.,5.3,4.7,4.,3.3,2.7,    &
+       2.,1.5,1.,0.8,0.6,0.4,0.2,0.0,0.0/
+  data daztab/21.,18.,16.,15.,14.,13.,12.,11.,10.7,10.3,10.,    &
+       10.,10.,10.,10.,10.,10.,9.,9.,9.,8.,8./
+  data mygrid0/"      "/,hisgrid0/"      "/,utch0/-999.d0/
+  save
+
+  if(MyGrid.eq.HisGrid) then
+     naz=0
+     nel=0
+     ndmiles=0
+     ndkm=0
+     nhotaz=0
+     nhotabetter=1
+     go to 999
+  endif
+
+  if(mygrid.eq.mygrid0 .and. hisgrid.eq.hisgrid0 .and.              &
+       abs(utch-utch0).lt.0.1666667d0) go to 900
+  utch0=utch
+  mygrid0=mygrid
+  hisgrid0=hisgrid
+  utchours=utch
+
+  if(MyGrid(5:5).eq.' ') MyGrid(5:5)='m'
+  if(MyGrid(6:6).eq.' ') MyGrid(6:6)='m'
+  if(HisGrid(5:5).eq.' ') HisGrid(5:5)='m'
+  if(HisGrid(6:6).eq.' ') HisGrid(6:6)='m'
+
+  if(MyGrid.eq.HisGrid) then
+     Az=0.
+     Dmiles=0.
+     Dkm=0.0
+     El=0.
+     HotA=0.
+     HotB=0.
+     HotABetter=.true.
+     go to 900
+  endif
+
+  call grid2deg(MyGrid,dlong1,dlat1)
+  call grid2deg(HisGrid,dlong2,dlat2)
+  call geodist(dlat1,dlong1,dlat2,dlong2,Az,Baz,Dkm)
+
+  ndkm=Dkm/100
+  j=ndkm-4
+  if(j.lt.1) j=1
+  if(j.gt.21)j=21
+  if(Dkm.lt.500.0) then
+     El=18.0
+  else
+     u=(Dkm-100.0*ndkm)/100.0
+     El=(1.0-u)*eltab(j) + u*eltab(j+1)
+  endif
+
+  daz=daztab(j) + u * (daztab(j+1)-daztab(j))
+  Dmiles=Dkm/1.609344
+
+  tmid=mod(UTChours-0.5*(dlong1+dlong2)/15.0+48.0,24.0)
+  IamEast=.false.
+  if(dlong1.lt.dlong2) IamEast=.true.
+  if(dlong1.eq.dlong2 .and. dlat1.gt.dlat2) IamEast=.false.
+  azEast=baz
+  if(IamEast) azEast=az
+  if((azEast.ge.45.0 .and. azEast.lt.135.0) .or.                    &
+       (azEast.ge.225.0 .and. azEast.lt.315.0)) then
+! The path will be taken as "east-west".
+     HotABetter=.true.
+     if(abs(tmid-6.0).lt.6.0) HotABetter=.false.
+     if((dlat1+dlat2)/2.0 .lt. 0.0) HotABetter=.not.HotABetter
+  else
+! The path will be taken as "north-south".
+     HotABetter=.false.
+     if(abs(tmid-12.0).lt.6.0) HotABetter=.true.
+  endif
+  if(IamEast) then
+     HotA = Az - daz
+     HotB = Az + daz
+  else
+     HotA = Az + daz
+     HotB = Az - daz
+  endif
+  if(HotA.lt.0.0)   HotA=HotA+360.0
+  if(HotA.gt.360.0) HotA=HotA-360.0
+  if(HotB.lt.0.0)   HotB=HotB+360.0
+  if(HotB.gt.360.0) HotB=HotB-360.0
+
+900 continue
+  naz=nint(Az)
+  nel=nint(el)
+  nDmiles=nint(Dmiles)
+  nDkm=nint(Dkm)
+  nHotAz=nint(HotB)
+  nHotABetter=0
+  if(HotABetter) then
+     nHotAz=nint(HotA)
+     nHotABetter=1
+  endif
+
+999 return
+end subroutine azdist
diff --git a/lib/bpskmetrics.dat b/lib/bpskmetrics.dat
new file mode 100644
index 0000000..4073e57
--- /dev/null
+++ b/lib/bpskmetrics.dat
@@ -0,0 +1,256 @@
+  -12.8   1.000  -9.966 1.000000 0.000000
+  -12.7   1.000  -9.966 1.000000 0.000000
+  -12.6   1.000  -9.966 1.000000 0.000000
+  -12.5   1.000  -9.966 1.000000 0.000000
+  -12.4   1.000  -9.966 1.000000 0.000000
+  -12.3   1.000  -9.966 1.000000 0.000000
+  -12.2   1.000  -9.966 1.000000 0.000000
+  -12.1   1.000  -9.966 1.000000 0.000000
+  -12.0   1.000  -9.966 1.000000 0.000000
+  -11.9   1.000  -9.966 1.000000 0.000000
+  -11.8   1.000  -9.966 1.000000 0.000000
+  -11.7   1.000  -9.966 1.000000 0.000000
+  -11.6   1.000  -9.966 1.000000 0.000000
+  -11.5   1.000  -9.966 1.000000 0.000000
+  -11.4   1.000  -9.966 1.000000 0.000000
+  -11.3   1.000  -9.966 1.000000 0.000000
+  -11.2   1.000  -9.966 1.000000 0.000000
+  -11.1   1.000  -9.966 1.000000 0.000000
+  -11.0   1.000  -9.966 1.000000 0.000000
+  -10.9   1.000  -9.966 1.000000 0.000000
+  -10.8   1.000  -9.966 1.000000 0.000000
+  -10.7   1.000  -9.966 1.000000 0.000000
+  -10.6   1.000  -9.966 1.000000 0.000000
+  -10.5   1.000  -9.966 1.000000 0.000000
+  -10.4   1.000  -9.966 1.000000 0.000000
+  -10.3   1.000  -9.966 1.000000 0.000000
+  -10.2   1.000  -9.966 1.000000 0.000000
+  -10.1   1.000  -9.966 1.000000 0.000000
+  -10.0   1.000  -9.966 1.000000 0.000000
+   -9.9   1.000  -9.966 1.000000 0.000000
+   -9.8   1.000  -9.966 1.000000 0.000000
+   -9.7   1.000  -9.966 1.000000 0.000000
+   -9.6   1.000  -9.966 1.000000 0.000000
+   -9.5   1.000  -9.966 1.000000 0.000000
+   -9.4   1.000  -9.966 1.000000 0.000000
+   -9.3   1.000  -9.966 1.000000 0.000000
+   -9.2   1.000  -9.966 1.000000 0.000000
+   -9.1   1.000  -9.966 1.000000 0.000000
+   -9.0   1.000  -9.966 1.000000 0.000000
+   -8.9   1.000  -9.966 1.000000 0.000000
+   -8.8   1.000  -9.966 1.000000 0.000000
+   -8.7   1.000  -9.966 1.000000 0.000000
+   -8.6   1.000  -9.966 1.000000 0.000000
+   -8.5   1.000  -9.966 1.000000 0.000000
+   -8.4   1.000  -9.966 1.000000 0.000000
+   -8.3   1.000  -9.966 1.000000 0.000000
+   -8.2   1.000  -9.966 1.000000 0.000000
+   -8.1   1.000  -9.966 1.000000 0.000000
+   -8.0   1.000  -9.966 1.000000 0.000000
+   -7.9   1.000  -9.966 1.000000 0.000000
+   -7.8   1.000  -9.966 1.000000 0.000000
+   -7.7   1.000  -9.966 1.000000 0.000000
+   -7.6   1.000  -9.966 1.000000 0.000000
+   -7.5   1.000  -9.966 1.000000 0.000000
+   -7.4   1.000  -9.966 1.000000 0.000000
+   -7.3   1.000  -9.966 1.000000 0.000000
+   -7.2   1.000  -9.966 1.000000 0.000000
+   -7.1   1.000  -9.966 1.000000 0.000000
+   -7.0   1.000  -9.966 1.000000 0.000000
+   -6.9   1.000  -9.966 1.000000 0.000000
+   -6.8   1.000  -9.966 1.000000 0.000000
+   -6.7   1.000  -9.966 1.000000 0.000000
+   -6.6   1.000  -9.966 1.000000 0.000000
+   -6.5   1.000  -9.966 1.000000 0.000000
+   -6.4   1.000  -9.966 1.000000 0.000000
+   -6.3   1.000  -9.966 1.000000 0.000000
+   -6.2   1.000  -9.966 1.000000 0.000000
+   -6.1   1.000  -9.966 1.000000 0.000000
+   -6.0   1.000  -9.966 1.000000 0.000000
+   -5.9   1.000  -9.966 1.000000 0.000000
+   -5.8   1.000  -9.966 1.000000 0.000000
+   -5.7   1.000  -9.966 1.000000 0.000000
+   -5.6   1.000  -9.966 1.000000 0.000000
+   -5.5   1.000  -9.966 1.000000 0.000000
+   -5.4   1.000  -9.966 1.000000 0.000000
+   -5.3   1.000  -9.966 1.000000 0.000000
+   -5.2   1.000  -9.966 1.000000 0.000000
+   -5.1   1.000  -9.966 1.000000 0.000000
+   -5.0   1.000  -9.966 1.000000 0.000000
+   -4.9   1.000  -9.966 1.000000 0.000000
+   -4.8   1.000  -9.966 1.000000 0.000000
+   -4.7   1.000  -9.966 1.000000 0.000000
+   -4.6   1.000  -9.966 1.000000 0.000000
+   -4.5   1.000  -9.966 1.000000 0.000000
+   -4.4   1.000  -9.966 1.000000 0.000000
+   -4.3   1.000  -9.966 1.000000 0.000000
+   -4.2   1.000  -9.966 1.000000 0.000000
+   -4.1   1.000  -9.966 1.000000 0.000000
+   -4.0   1.000  -9.966 1.000000 0.000000
+   -3.9   1.000  -9.966 1.000000 0.000000
+   -3.8   1.000  -9.966 1.000000 0.000000
+   -3.7   1.000  -9.966 1.000000 0.000000
+   -3.6   1.000  -9.966 1.000000 0.000000
+   -3.5   1.000  -9.966 1.000000 0.000000
+   -3.4   1.000  -9.966 1.000000 0.000000
+   -3.3   1.000  -9.966 1.000000 0.000000
+   -3.2   1.000  -9.966 1.000000 0.000000
+   -3.1   1.000  -9.966 1.000000 0.000000
+   -3.0   1.000  -9.966 1.000000 0.000000
+   -2.9   1.000  -9.966 1.000000 0.000000
+   -2.8   1.000  -9.966 0.999955 0.000045
+   -2.7   1.000  -9.966 0.999968 0.000032
+   -2.6   1.000  -9.966 0.999909 0.000091
+   -2.5   1.000  -9.966 0.999983 0.000017
+   -2.4   1.000  -9.966 0.999937 0.000063
+   -2.3   1.000  -9.966 0.999914 0.000086
+   -2.2   1.000  -9.966 0.999813 0.000187
+   -2.1   1.000  -9.966 0.999775 0.000225
+   -2.0   1.000  -9.966 0.999671 0.000329
+   -1.9   0.999  -9.966 0.999531 0.000469
+   -1.8   0.999  -9.308 0.999211 0.000789
+   -1.7   0.998  -8.893 0.998948 0.001052
+   -1.6   0.998  -8.191 0.998290 0.001710
+   -1.5   0.996  -7.655 0.997519 0.002481
+   -1.4   0.994  -7.037 0.996192 0.003808
+   -1.3   0.992  -6.513 0.994525 0.005475
+   -1.2   0.988  -5.931 0.991804 0.008196
+   -1.1   0.982  -5.359 0.987816 0.012184
+   -1.0   0.974  -4.789 0.981916 0.018084
+   -0.9   0.961  -4.217 0.973110 0.026890
+   -0.8   0.942  -3.672 0.960785 0.039215
+   -0.7   0.915  -3.123 0.942613 0.057387
+   -0.6   0.874  -2.582 0.916477 0.083523
+   -0.5   0.816  -2.062 0.880296 0.119704
+   -0.4   0.734  -1.573 0.831905 0.168095
+   -0.3   0.619  -1.109 0.768168 0.231832
+   -0.2   0.465  -0.690 0.690103 0.309897
+   -0.1   0.260  -0.317 0.598759 0.401241
+    0.0   0.000   0.000 0.500000 0.500000
+    0.1  -0.317   0.260 0.401241 0.598759
+    0.2  -0.690   0.465 0.309897 0.690103
+    0.3  -1.109   0.619 0.231832 0.768168
+    0.4  -1.573   0.734 0.168095 0.831905
+    0.5  -2.062   0.816 0.119704 0.880296
+    0.6  -2.582   0.874 0.083523 0.916477
+    0.7  -3.123   0.915 0.057387 0.942613
+    0.8  -3.672   0.942 0.039215 0.960785
+    0.9  -4.217   0.961 0.026890 0.973110
+    1.0  -4.789   0.974 0.018084 0.981916
+    1.1  -5.359   0.982 0.012184 0.987816
+    1.2  -5.931   0.988 0.008196 0.991804
+    1.3  -6.513   0.992 0.005475 0.994525
+    1.4  -7.037   0.994 0.003808 0.996192
+    1.5  -7.655   0.996 0.002481 0.997519
+    1.6  -8.191   0.998 0.001710 0.998290
+    1.7  -8.893   0.998 0.001052 0.998948
+    1.8  -9.308   0.999 0.000789 0.999211
+    1.9  -9.966   0.999 0.000469 0.999531
+    2.0  -9.966   1.000 0.000329 0.999671
+    2.1  -9.966   1.000 0.000225 0.999775
+    2.2  -9.966   1.000 0.000187 0.999813
+    2.3  -9.966   1.000 0.000086 0.999914
+    2.4  -9.966   1.000 0.000063 0.999937
+    2.5  -9.966   1.000 0.000017 0.999983
+    2.6  -9.966   1.000 0.000091 0.999909
+    2.7  -9.966   1.000 0.000032 0.999968
+    2.8  -9.966   1.000 0.000045 0.999955
+    2.9  -9.966   1.000 0.000000 1.000000
+    3.0  -9.966   1.000 0.000000 1.000000
+    3.1  -9.966   1.000 0.000000 1.000000
+    3.2  -9.966   1.000 0.000000 1.000000
+    3.3  -9.966   1.000 0.000000 1.000000
+    3.4  -9.966   1.000 0.000000 1.000000
+    3.5  -9.966   1.000 0.000000 1.000000
+    3.6  -9.966   1.000 0.000000 1.000000
+    3.7  -9.966   1.000 0.000000 1.000000
+    3.8  -9.966   1.000 0.000000 1.000000
+    3.9  -9.966   1.000 0.000000 1.000000
+    4.0  -9.966   1.000 0.000000 1.000000
+    4.1  -9.966   1.000 0.000000 1.000000
+    4.2  -9.966   1.000 0.000000 1.000000
+    4.3  -9.966   1.000 0.000000 1.000000
+    4.4  -9.966   1.000 0.000000 1.000000
+    4.5  -9.966   1.000 0.000000 1.000000
+    4.6  -9.966   1.000 0.000000 1.000000
+    4.7  -9.966   1.000 0.000000 1.000000
+    4.8  -9.966   1.000 0.000000 1.000000
+    4.9  -9.966   1.000 0.000000 1.000000
+    5.0  -9.966   1.000 0.000000 1.000000
+    5.1  -9.966   1.000 0.000000 1.000000
+    5.2  -9.966   1.000 0.000000 1.000000
+    5.3  -9.966   1.000 0.000000 1.000000
+    5.4  -9.966   1.000 0.000000 1.000000
+    5.5  -9.966   1.000 0.000000 1.000000
+    5.6  -9.966   1.000 0.000000 1.000000
+    5.7  -9.966   1.000 0.000000 1.000000
+    5.8  -9.966   1.000 0.000000 1.000000
+    5.9  -9.966   1.000 0.000000 1.000000
+    6.0  -9.966   1.000 0.000000 1.000000
+    6.1  -9.966   1.000 0.000000 1.000000
+    6.2  -9.966   1.000 0.000000 1.000000
+    6.3  -9.966   1.000 0.000000 1.000000
+    6.4  -9.966   1.000 0.000000 1.000000
+    6.5  -9.966   1.000 0.000000 1.000000
+    6.6  -9.966   1.000 0.000000 1.000000
+    6.7  -9.966   1.000 0.000000 1.000000
+    6.8  -9.966   1.000 0.000000 1.000000
+    6.9  -9.966   1.000 0.000000 1.000000
+    7.0  -9.966   1.000 0.000000 1.000000
+    7.1  -9.966   1.000 0.000000 1.000000
+    7.2  -9.966   1.000 0.000000 1.000000
+    7.3  -9.966   1.000 0.000000 1.000000
+    7.4  -9.966   1.000 0.000000 1.000000
+    7.5  -9.966   1.000 0.000000 1.000000
+    7.6  -9.966   1.000 0.000000 1.000000
+    7.7  -9.966   1.000 0.000000 1.000000
+    7.8  -9.966   1.000 0.000000 1.000000
+    7.9  -9.966   1.000 0.000000 1.000000
+    8.0  -9.966   1.000 0.000000 1.000000
+    8.1  -9.966   1.000 0.000000 1.000000
+    8.2  -9.966   1.000 0.000000 1.000000
+    8.3  -9.966   1.000 0.000000 1.000000
+    8.4  -9.966   1.000 0.000000 1.000000
+    8.5  -9.966   1.000 0.000000 1.000000
+    8.6  -9.966   1.000 0.000000 1.000000
+    8.7  -9.966   1.000 0.000000 1.000000
+    8.8  -9.966   1.000 0.000000 1.000000
+    8.9  -9.966   1.000 0.000000 1.000000
+    9.0  -9.966   1.000 0.000000 1.000000
+    9.1  -9.966   1.000 0.000000 1.000000
+    9.2  -9.966   1.000 0.000000 1.000000
+    9.3  -9.966   1.000 0.000000 1.000000
+    9.4  -9.966   1.000 0.000000 1.000000
+    9.5  -9.966   1.000 0.000000 1.000000
+    9.6  -9.966   1.000 0.000000 1.000000
+    9.7  -9.966   1.000 0.000000 1.000000
+    9.8  -9.966   1.000 0.000000 1.000000
+    9.9  -9.966   1.000 0.000000 1.000000
+   10.0  -9.966   1.000 0.000000 1.000000
+   10.1  -9.966   1.000 0.000000 1.000000
+   10.2  -9.966   1.000 0.000000 1.000000
+   10.3  -9.966   1.000 0.000000 1.000000
+   10.4  -9.966   1.000 0.000000 1.000000
+   10.5  -9.966   1.000 0.000000 1.000000
+   10.6  -9.966   1.000 0.000000 1.000000
+   10.7  -9.966   1.000 0.000000 1.000000
+   10.8  -9.966   1.000 0.000000 1.000000
+   10.9  -9.966   1.000 0.000000 1.000000
+   11.0  -9.966   1.000 0.000000 1.000000
+   11.1  -9.966   1.000 0.000000 1.000000
+   11.2  -9.966   1.000 0.000000 1.000000
+   11.3  -9.966   1.000 0.000000 1.000000
+   11.4  -9.966   1.000 0.000000 1.000000
+   11.5  -9.966   1.000 0.000000 1.000000
+   11.6  -9.966   1.000 0.000000 1.000000
+   11.7  -9.966   1.000 0.000000 1.000000
+   11.8  -9.966   1.000 0.000000 1.000000
+   11.9  -9.966   1.000 0.000000 1.000000
+   12.0  -9.966   1.000 0.000000 1.000000
+   12.1  -9.966   1.000 0.000000 1.000000
+   12.2  -9.966   1.000 0.000000 1.000000
+   12.3  -9.966   1.000 0.000000 1.000000
+   12.4  -9.966   1.000 0.000000 1.000000
+   12.5  -9.966   1.000 0.000000 1.000000
+   12.6  -9.966   1.000 0.000000 1.000000
+   12.7  -9.966   1.000 0.000000 1.000000
diff --git a/lib/ccf2.f90 b/lib/ccf2.f90
new file mode 100644
index 0000000..4e74a52
--- /dev/null
+++ b/lib/ccf2.f90
@@ -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
diff --git a/lib/ccf65.f90 b/lib/ccf65.f90
new file mode 100644
index 0000000..9e667df
--- /dev/null
+++ b/lib/ccf65.f90
@@ -0,0 +1,117 @@
+subroutine ccf65(ss,nhsym,ssmax,sync1,dt1,flipk,syncshort,snr2,dt2)
+
+  parameter (NFFT=512,NH=NFFT/2)
+  real ss(322)                     !Input: half-symbol normalized powers
+  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)
+  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
+
+! Look for JT65 sync pattern and shorthand square-wave pattern.
+  ccfbest=0.
+  ccfbest2=0.
+  do i=1,nhsym-1
+     s(i)=min(ssmax,ss(i)+ss(i+1))
+!     s(i)=ss(i)+ss(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)=s(j)
+!     if(abs(ccf(lag)).gt.ccfbest) then
+     if(ccf(lag).gt.ccfbest) then           !No inverted sync for use at HF
+!        ccfbest=abs(ccf(lag))
+        ccfbest=ccf(lag)
+        lagpk=lag
+        flipk=1.0
+!        if(ccf(lag).lt.0.0) flipk=-1.0
+     endif
+  enddo
+
+!  do lag=-11,54                             !Check for best shorthand
+!     ccf2=s2(lag+28)
+!     if(ccf2.gt.ccfbest2) then
+!        ccfbest2=ccf2
+!        lagpk2=lag
+!     endif
+!  enddo
+
+! Find rms level on baseline of "ccfblue", for normalization.
+  sum=0.
+  do lag=-11,54
+     if(abs(lag-lagpk).gt.1) sum=sum + ccf(lag)
+  enddo
+  base=sum/50.0
+  sq=0.
+  do lag=-11,54
+     if(abs(lag-lagpk).gt.1) sq=sq + (ccf(lag)-base)**2
+  enddo
+  rms=sqrt(sq/49.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(i)
+  enddo
+  call pctile(tmp1,nhsym,40,base)
+  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))
+  dt2=0.
+
+  return
+end subroutine ccf65
diff --git a/lib/char.h b/lib/char.h
new file mode 100644
index 0000000..cc477ec
--- /dev/null
+++ b/lib/char.h
@@ -0,0 +1,57 @@
+/* Include file to configure the RS codec for character symbols
+ *
+ * Copyright 2002, Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define DTYPE unsigned char
+
+/* Reed-Solomon codec control block */
+struct rs {
+  int mm;              /* Bits per symbol */
+  int nn;              /* Symbols per block (= (1<<mm)-1) */
+  DTYPE *alpha_to;     /* log lookup table */
+  DTYPE *index_of;     /* Antilog lookup table */
+  DTYPE *genpoly;      /* Generator polynomial */
+  int nroots;     /* Number of generator roots = number of parity symbols */
+  int fcr;        /* First consecutive root, index form */
+  int prim;       /* Primitive element, index form */
+  int iprim;      /* prim-th root of 1, index form */
+  int pad;        /* Padding bytes in shortened block */
+};
+
+static inline int modnn(struct rs *rs,int x){
+  while (x >= rs->nn) {
+    x -= rs->nn;
+    x = (x >> rs->mm) + (x & rs->nn);
+  }
+  return x;
+}
+#define MODNN(x) modnn(rs,x)
+
+#define MM (rs->mm)
+#define NN (rs->nn)
+#define ALPHA_TO (rs->alpha_to) 
+#define INDEX_OF (rs->index_of)
+#define GENPOLY (rs->genpoly)
+#define NROOTS (rs->nroots)
+#define FCR (rs->fcr)
+#define PRIM (rs->prim)
+#define IPRIM (rs->iprim)
+#define PAD (rs->pad)
+#define A0 (NN)
+
+#define ENCODE_RS encode_rs_char
+#define DECODE_RS decode_rs_char
+#define INIT_RS init_rs_char
+#define FREE_RS free_rs_char
+
+void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
+int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras);
+void *INIT_RS(int symsize,int gfpoly,int fcr,
+		    int prim,int nroots,int pad);
+void FREE_RS(void *p);
+
+
+
+
+
diff --git a/lib/chkhist.f90 b/lib/chkhist.f90
new file mode 100644
index 0000000..6aa4a80
--- /dev/null
+++ b/lib/chkhist.f90
@@ -0,0 +1,21 @@
+subroutine chkhist(mrsym,nmax,ipk)
+
+  integer mrsym(63)
+  integer hist(0:63)
+
+  hist=0
+  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
diff --git a/lib/chkmsg.f90 b/lib/chkmsg.f90
new file mode 100644
index 0000000..ade13bc
--- /dev/null
+++ b/lib/chkmsg.f90
@@ -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:2).eq.'RO')  nspecial=2
+  if(message(1:3).eq.'RRR') nspecial=3
+  if(message(1:2).eq.'73')  nspecial=4
+
+  return
+end subroutine chkmsg
diff --git a/lib/chkss2.f90 b/lib/chkss2.f90
new file mode 100644
index 0000000..12b2a2e
--- /dev/null
+++ b/lib/chkss2.f90
@@ -0,0 +1,24 @@
+subroutine chkss2(ss2,freq,drift,schk)
+
+  real ss2(0:8,85)
+  real s(0:8,85)
+  real s1(0:5)
+  include 'jt9sync.f90'
+
+  ave=sum(ss2)/(9*85)
+  if(freq+drift.eq.-999999.0) ave=0.      !To silence compiler warning
+  s=ss2/ave-1.0
+
+!  call zplot9(s,freq,drift)
+  s1=0.
+  do lag=0,5
+     do i=1,16
+        j=ii(i)+lag
+        if(j.le.85) s1(lag)=s1(lag) + s(0,j)
+     enddo
+  enddo
+  schk=s1(0)/16.0
+
+  return
+end subroutine chkss2
+
diff --git a/lib/constants.f90 b/lib/constants.f90
new file mode 100644
index 0000000..2acf6bb
--- /dev/null
+++ b/lib/constants.f90
@@ -0,0 +1,5 @@
+  parameter (NTMAX=120)
+  parameter (NMAX=NTMAX*12000)        !Total sample intervals per 30 minutes
+  parameter (NDMAX=NTMAX*1500)        !Sample intervals at 1500 Hz rate
+  parameter (NSMAX=6827)              !Max length of saved spectra
+  parameter (MAXFFT3=16384)
diff --git a/lib/conv232.f90 b/lib/conv232.f90
new file mode 100644
index 0000000..3a347e1
--- /dev/null
+++ b/lib/conv232.f90
@@ -0,0 +1,38 @@
+! Layland-Lushbaugh polynomials for a K=32, r=1/2 convolutional code,
+! and 8-bit parity lookup table.
+
+      data npoly1/-221228207/,npoly2/-463389625/
+      integer*1 partab(0:255)
+      data partab/                &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         0, 1, 1, 0, 1, 0, 0, 1,  &
+         1, 0, 0, 1, 0, 1, 1, 0/
diff --git a/lib/cutil.c b/lib/cutil.c
new file mode 100644
index 0000000..69a526b
--- /dev/null
+++ b/lib/cutil.c
@@ -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);
+}
diff --git a/lib/db.f90 b/lib/db.f90
new file mode 100644
index 0000000..aa58f43
--- /dev/null
+++ b/lib/db.f90
@@ -0,0 +1,5 @@
+real function db(x)
+  db=-99.0
+  if(x.gt.1.259e-10) db=10.0*log10(x)
+  return
+end function db
diff --git a/lib/decode65a.f90 b/lib/decode65a.f90
new file mode 100644
index 0000000..ea61d35
--- /dev/null
+++ b/lib/decode65a.f90
@@ -0,0 +1,95 @@
+subroutine decode65a(dd,npts,newdat,f0,nflip,mode65,sync2,a,dt,    &
+     nbmkv,nhist,decoded)
+
+! Apply AFC corrections to a candidate JT65 signal, then decode it.
+
+  parameter (NMAX=60*12000)          !Samples per 60 s
+  real*4  dd(NMAX)                   !92 MB: raw data from Linrad timf2
+  complex cx(NMAX/8)                 !Data at 1378.125 samples/s
+  complex c5x(NMAX/32)               !Data at 344.53125 Hz
+  complex c5a(512)
+  real s2(66,126)
+  real a(5)
+  logical first
+  character decoded*22
+  data first/.true./,jjjmin/1000/,jjjmax/-1000/
+  data 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,npts,f0,newdat,cx,n5,sq0)
+  call timer('filbig  ',1)
+
+! NB: cx has sample rate 12000*77125/672000 = 1378.125 Hz
+
+! Find best DF, f1, f2, and DT.  Start by downsampling to 344.53125 Hz
+  call timer('fil6521 ',0)
+! 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)
+  n6=n6+nadd
+  call timer('fil6521 ',1)
+
+  fsample=1378.125/4.
+  a(5)=dt00
+  i0=nint((a(5)+0.5)*fsample) - 2 + nadd
+  if(i0.lt.1) then
+!     write(23,*) 'i0 too small in decode1a:',i0,f0,a(5),fsample,nadd
+!     flush(23)
+     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.
+  call timer('afc65b  ',0)
+! Best fit for DF, f1, and f2
+  call afc65b(c5x(i0),nz,fsample,nflip,a,ccfbest,dtbest)
+  call timer('afc65b  ',1)
+
+  sync2=3.7e-4*ccfbest/sq0                    !Constant is empirical 
+
+! 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 timer('twkfreq ',0)
+  call twkfreq65(cx,n5,a)
+  call timer('twkfreq ',1)
+
+! Compute spectrum 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
+
+  call timer('sh_ffts ',0)
+  do k=1,nsym
+     do i=1,nfft
+        j=j+1
+        c5a(i)=cx(j)
+     enddo
+     call four2a(c5a,nfft,1,1,1)
+     do i=1,66
+        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
+  enddo
+  call timer('sh_ffts ',1)
+
+  call timer('dec65b  ',0)
+  call decode65b(s2,nflip,mode65,nbmkv,nhist,decoded)
+  dt=dt00 + dtbest + 1.7
+  call timer('dec65b  ',1)
+
+  return
+end subroutine decode65a
diff --git a/lib/decode65b.f90 b/lib/decode65b.f90
new file mode 100644
index 0000000..729a218
--- /dev/null
+++ b/lib/decode65b.f90
@@ -0,0 +1,36 @@
+subroutine decode65b(s2,nflip,mode65,nbmkv,nhist,decoded)
+
+  real s2(66,126)
+  real s3(64,63)
+  logical first,ltext
+  character decoded*22
+  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(nflip.lt.0) k=mdat2(j)
+     do i=1,64
+        s3(i,j)=s2(i+2,k)
+     enddo
+     k=mdat2(j)                       !Points to data symbol
+     if(nflip.lt.0) k=mdat(j)
+  enddo
+
+  nadd=mode65
+  call extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv)   !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(nflip.lt.0 .and. ltext) ncount=-1
+  if(ncount.lt.0) then 
+     nbmkv=0
+     decoded='                      '
+  endif
+
+  return
+end subroutine decode65b
diff --git a/lib/decode9.f90 b/lib/decode9.f90
new file mode 100644
index 0000000..06809eb
--- /dev/null
+++ b/lib/decode9.f90
@@ -0,0 +1,85 @@
+subroutine decode9(i1SoftSymbols,limit,nlim,msg)
+
+! Decoder for JT9
+! Input:   i1SoftSymbols(207) - Single-bit soft symbols
+! Output:  msg                - decoded message (blank if erasure)
+
+  character*22 msg
+  integer*4 i4DecodedBytes(9)
+  integer*4 i4Decoded6BitWords(12)
+  integer*1 i1DecodedBytes(13)   !72 bits and zero tail as 8-bit bytes
+  integer*1 i1SoftSymbols(207)
+  integer*1 i1DecodedBits(72)
+
+  real*4 xx0(0:255)
+
+  logical first
+  integer*4 mettab(0:255,0:1)
+  data first/.true./
+  data xx0/                                                      & !Metric table
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        0.988, 1.000, 0.991, 0.993, 1.000, 0.995, 1.000, 0.991,  &
+        1.000, 0.991, 0.992, 0.991, 0.990, 0.990, 0.992, 0.996,  &
+        0.990, 0.994, 0.993, 0.991, 0.992, 0.989, 0.991, 0.987,  &
+        0.985, 0.989, 0.984, 0.983, 0.979, 0.977, 0.971, 0.975,  &
+        0.974, 0.970, 0.970, 0.970, 0.967, 0.962, 0.960, 0.957,  &
+        0.956, 0.953, 0.942, 0.946, 0.937, 0.933, 0.929, 0.920,  &
+        0.917, 0.911, 0.903, 0.895, 0.884, 0.877, 0.869, 0.858,  &
+        0.846, 0.834, 0.821, 0.806, 0.790, 0.775, 0.755, 0.737,  &
+        0.713, 0.691, 0.667, 0.640, 0.612, 0.581, 0.548, 0.510,  &
+        0.472, 0.425, 0.378, 0.328, 0.274, 0.212, 0.146, 0.075,  &
+        0.000,-0.079,-0.163,-0.249,-0.338,-0.425,-0.514,-0.606,  &
+       -0.706,-0.796,-0.895,-0.987,-1.084,-1.181,-1.280,-1.376,  &
+       -1.473,-1.587,-1.678,-1.790,-1.882,-1.992,-2.096,-2.201,  &
+       -2.301,-2.411,-2.531,-2.608,-2.690,-2.829,-2.939,-3.058,  &
+       -3.164,-3.212,-3.377,-3.463,-3.550,-3.768,-3.677,-3.975,  &
+       -4.062,-4.098,-4.186,-4.261,-4.472,-4.621,-4.623,-4.608,  &
+       -4.822,-4.870,-4.652,-4.954,-5.108,-5.377,-5.544,-5.995,  &
+       -5.632,-5.826,-6.304,-6.002,-6.559,-6.369,-6.658,-7.016,  &
+       -6.184,-7.332,-6.534,-6.152,-6.113,-6.288,-6.426,-6.313,  &
+       -9.966,-6.371,-9.966,-7.055,-9.966,-6.629,-6.313,-9.966,  &
+       -5.858,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966/
+  save
+
+  if(first) then
+! Get the metric table
+     bias=0.5
+     scale=10
+     do i=0,255
+        mettab(i,0)=nint(scale*(xx0(i)-bias))
+        if(i.ge.1) mettab(256-i,1)=mettab(i,0)
+     enddo
+     first=.false.
+  endif
+
+  msg='                      '
+  nbits=72
+  ndelta=17
+  call fano232(i1SoftSymbols,nbits+31,mettab,ndelta,limit,i1DecodedBytes,   &
+       ncycles,metric,ierr)
+
+  nlim=ncycles/(nbits+31)
+  if(ncycles.lt.(nbits*limit)) then
+     nbytes=(nbits+7)/8
+     do i=1,nbytes
+        n=i1DecodedBytes(i)
+        i4DecodedBytes(i)=iand(n,255)
+     enddo
+     call unpackbits(i4DecodedBytes,nbytes,8,i1DecodedBits)
+     call packbits(i1DecodedBits,12,6,i4Decoded6BitWords)
+     call unpackmsg(i4Decoded6BitWords,msg)                !Unpack decoded msg
+     if(index(msg,'000AAA ').gt.0) msg='                      '
+  endif
+
+  return
+end subroutine decode9
diff --git a/lib/decode_rs.c b/lib/decode_rs.c
new file mode 100644
index 0000000..ac85edd
--- /dev/null
+++ b/lib/decode_rs.c
@@ -0,0 +1,263 @@
+/* Reed-Solomon decoder
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+
+#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(
+#ifdef FIXED
+DTYPE *data, int *eras_pos, int no_eras,int pad){
+#else
+void *p,DTYPE *data, int *eras_pos, int no_eras){
+  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], s[NROOTS];	/* Err+Eras Locator poly
+					 * 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;
+
+#ifdef FIXED
+  /* Check pad parameter for validity */
+  if(pad < 0 || pad >= NN)
+    return -1;
+#endif
+
+  /* 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-PAD;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++)
+    //    printf("%d  %d  %d\n",i,lambda[i],INDEX_OF[lambda[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 = deg_lambda-1;
+  for (i = 0; i <= deg_omega;i++){
+    tmp = 0;
+    for(j=i;j >= 0; j--){
+      if ((s[i - j] != A0) && (lambda[j] != A0))
+	tmp ^= ALPHA_TO[MODNN(s[i - j] + lambda[j])];
+    }
+    omega[i] = INDEX_OF[tmp];
+  }
+
+  /*
+   * 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 DEBUG >= 1
+    if (den == 0) {
+      printf("\n ERROR: denominator = 0\n");
+      count = -1;
+      goto finish;
+    }
+#endif
+    /* Apply error to data */
+    if (num1 != 0 && loc[j] >= PAD) {
+      data[loc[j]-PAD] ^= 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;
+}
diff --git a/lib/decoder.f90 b/lib/decoder.f90
new file mode 100644
index 0000000..83e63a2
--- /dev/null
+++ b/lib/decoder.f90
@@ -0,0 +1,173 @@
+subroutine decoder(ss,id2)
+
+! Decoder for JT9.
+
+  include 'constants.f90'
+  real ss(184,NSMAX)
+  character*22 msg
+  character*20 datetime
+  real*4 ccfred(NSMAX)
+  real*4 red2(NSMAX)
+  logical ccfok(NSMAX)
+  logical done(NSMAX)
+  logical done65
+  integer*2 id2(NTMAX*12000)
+  real*4 dd(NTMAX*12000)
+  integer*1 i1SoftSymbols(207)
+  common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol,  &
+       kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,datetime
+  common/tracer/limtrace,lu
+  save
+
+  call system_clock(iclock0,iclock_rate,iclock_max)           !###
+  nfreqs0=0
+  nfreqs1=0
+  ndecodes0=0
+  ndecodes1=0
+
+  open(13,file='decoded.txt',status='unknown')
+  open(22,file='kvasd.dat',access='direct',recl=1024,status='unknown')
+
+  npts65=52*12000
+  ntol65=20
+  done65=.false.
+  if(nmode.ge.65 .and. ntxmode.eq.65) then
+     if(newdat.ne.0) dd(1:npts65)=id2(1:npts65)
+     call jt65a(dd,npts65,newdat,nutc,nfa,nfqso,ntol65,nagain,ndecoded)
+     done65=.true.
+  endif
+
+  if(nmode.eq.65) go to 800
+
+  nsynced=0
+  ndecoded=0
+  nsps=0
+
+  nsps=6912                                   !Params for JT9-1
+  df3=1500.0/2048.0
+
+  tstep=0.5*nsps/12000.0                      !Half-symbol step (seconds)
+  done=.false.
+
+  nf0=0
+  ia=max(1,nint((nfa-nf0)/df3))
+  ib=min(NSMAX,nint((nfb-nf0)/df3))
+  lag1=-(2.5/tstep + 0.9999)
+  lag2=5.0/tstep + 0.9999
+  if(newdat.ne.0) then
+     call timer('sync9   ',0)
+     call sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipk)
+     call timer('sync9   ',1)
+  endif
+
+  nsps8=nsps/8
+  df8=1500.0/nsps8
+  dblim=db(864.0/nsps8) - 26.2
+
+  do nqd=1,0,-1
+     limit=1000
+     ccflim=4.0
+     red2lim=1.6
+     schklim=2.2
+     if(ndepth.eq.2) then
+        limit=10000
+        ccflim=3.5
+     endif
+     if(ndepth.ge.3 .or. nqd.eq.1) then
+        limit=100000
+        ccflim=2.5
+     endif
+     ccfok=.false.
+
+     if(nqd.eq.1) then
+        nfa1=nfqso-ntol
+        nfb1=nfqso+ntol
+        ia=max(1,nint((nfa1-nf0)/df3))
+        ib=min(NSMAX,nint((nfb1-nf0)/df3))
+        ccfok(ia:ib)=(ccfred(ia:ib).gt.(ccflim-2.0)) .and.               &
+                     (red2(ia:ib).gt.(red2lim-1.0))
+        ia1=ia
+        ib1=ib
+     else
+        nfa1=nfa
+        nfb1=nfb
+        ia=max(1,nint((nfa1-nf0)/df3))
+        ib=min(NSMAX,nint((nfb1-nf0)/df3))
+        do i=ia,ib
+           ccfok(i)=ccfred(i).gt.ccflim .and. red2(i).gt.red2lim
+        enddo
+        ccfok(ia1:ib1)=.false.
+     endif
+
+     fgood=0.
+     do i=ia,ib
+        if(done(i) .or. (.not.ccfok(i))) cycle
+        f=(i-1)*df3
+        if(nqd.eq.1 .or.                                                   &
+           (ccfred(i).ge.ccflim .and. abs(f-fgood).gt.10.0*df8)) then
+
+           if(nqd.eq.0) nfreqs0=nfreqs0+1
+           if(nqd.eq.1) nfreqs1=nfreqs1+1
+
+           call timer('softsym ',0)
+           fpk=nf0 + df3*(i-1)
+
+           call softsym(id2,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,    &
+                freq,drift,schk,i1SoftSymbols)
+           call timer('softsym ',1)
+
+!           write(71,3001) nqd,i,f,fpk,ccfred(i),red2(i),schk
+!3001       format(2i6,2f8.1,3f6.1)
+!           call flush(71)
+
+           if(schk.lt.schklim) cycle
+
+           call timer('decode9 ',0)
+           call decode9(i1SoftSymbols,limit,nlim,msg)
+           call timer('decode9 ',1)
+
+           sync=(syncpk+1)/4.0
+           if(sync.lt.0.0 .or. snrdb.lt.dblim-2.0) sync=0.0
+           nsync=sync
+           if(nsync.gt.10) nsync=10
+           nsnr=nint(snrdb)
+           ndrift=nint(drift/df3)
+              
+           if(msg.ne.'                      ') then
+              if(nqd.eq.0) ndecodes0=ndecodes0+1
+              if(nqd.eq.1) ndecodes1=ndecodes1+1
+                 
+              write(*,1000) nutc,nsnr,xdt,nint(freq),msg
+1000          format(i4.4,i4,f5.1,i5,1x,'@',1x,a22)
+              write(13,1002) nutc,nsync,nsnr,xdt,freq,ndrift,msg
+1002          format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22,' JT9')
+
+              iaa=max(1,i-1)
+              ibb=min(NSMAX,i+22)
+              fgood=f
+              nsynced=1
+              ndecoded=1
+              ccfok(iaa:ibb)=.false.
+              done(iaa:ibb)=.true.              
+              call flush(6)
+           endif
+        endif
+     enddo
+     call flush(6)
+     if(nagain.ne.0) exit
+  enddo
+
+  if(nmode.ge.65 .and. (.not.done65)) then
+     if(newdat.ne.0) dd(1:npts65)=id2(1:npts65)
+     call jt65a(dd,npts65,newdat,nutc,nfa,nfqso,ntol65,nagain,ndecoded)
+  endif
+
+!### JT65 is not yet producing info for nsynced, ndecoded.
+800 write(*,1010) nsynced,ndecoded
+1010 format('<DecodeFinished>',2i4)
+  call flush(6)
+  close(13)
+  close(22)
+
+  return
+end subroutine decoder
diff --git a/lib/deep24.f90 b/lib/deep24.f90
new file mode 100644
index 0000000..70a69ae
--- /dev/null
+++ b/lib/deep24.f90
@@ -0,0 +1,182 @@
+subroutine deep24(sym,neme,flip,mycall,hiscall,hisgrid,decoded,qual)
+
+! Have barely begun converting this from JT65 to JT4
+
+  parameter (MAXCALLS=7000,MAXRPT=63)
+  real*4 sym(206)
+  character callsign*12,grid*4,message*22,hisgrid*6,c*1,ceme*3
+  character*12 mycall,hiscall
+  character mycall0*12,hiscall0*12,hisgrid0*6
+  character*22 decoded
+  character*22 testmsg(2*MAXCALLS + 2 + MAXRPT)
+  character*15 callgrid(MAXCALLS)
+  character*180 line
+  character*4 rpt(MAXRPT)
+  integer ncode(206)
+  real*4   code(206,2*MAXCALLS + 2 + MAXRPT)
+  real pp(2*MAXCALLS + 2 + MAXRPT)
+!  common/c3com/ mcall3a
+
+  data neme0/-99/
+  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(mycall.eq.mycall0 .and. hiscall.eq.hiscall0 .and.         &
+       hisgrid.eq.hisgrid0 .and. mcall3a.eq.0 .and. neme.eq.neme0) go to 30
+      
+  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.                       &
+          flip.gt.0.0 .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 encode4(message,ncode)
+        code(1:206,k)=2*ncode(1:206)-1
+        if(n.ge.2) then
+! Insert CQ message
+           if(j4.lt.1) callgrid(icall)=callsign(1:j2)//' '//grid
+           message='CQ '//callgrid(icall)
+           k=k+1
+           testmsg(k)=message
+           call encode4(message,ncode)
+        code(1:206,k)=2*ncode(1:206)-1
+        endif
+     enddo
+10   continue
+  enddo
+
+20 continue
+  ntot=k
+  neme0=neme
+
+30 mycall0=mycall
+  hiscall0=hiscall
+  hisgrid0=hisgrid
+
+  sq=0.
+  do j=1,206
+     sq=sq + sym(j)**2
+  enddo
+  rms=sqrt(sq/206.0)
+  sym=sym/rms
+
+  p1=-1.e30
+  p2=-1.e30
+  do k=1,ntot
+     pp(k)=0.
+! 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
+        p=0.
+        do j=1,206
+           i=code(j,k)+1
+           p=p + code(j,k)*sym(j)
+        enddo
+        pp(k)=p
+        if(p.gt.p1) then
+           p1=p
+           ip1=k
+        endif
+     endif
+  enddo
+
+  do i=1,ntot
+     if(pp(i).gt.p2 .and. pp(i).ne.p1) p2=pp(i)
+  enddo
+
+! ### DO NOT REMOVE ### 
+!  rewind 77
+!  write(77,*) p1,p2
+! ### Works OK without it (in both Windows and Linux) if compiled 
+! ### without optimization.  However, in Windows this is a colossal 
+! ### pain because of the way F2PY wants to run the compile step.
+
+
+  bias=1.1*p2
+!  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) stop 'Error in deep24'
+  qual=10.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
+
+!  write(*,3010) p1,p2,p1-p2,p1/p2,qual,decoded
+!3010 format('DS:',5f9.1,2x,a22)
+
+  return
+end subroutine deep24
diff --git a/lib/deg2grid.f90 b/lib/deg2grid.f90
new file mode 100644
index 0000000..4fdc2af
--- /dev/null
+++ b/lib/deg2grid.f90
@@ -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=int(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=int(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
diff --git a/lib/demod64a.f90 b/lib/demod64a.f90
new file mode 100644
index 0000000..9d1a379
--- /dev/null
+++ b/lib/demod64a.f90
@@ -0,0 +1,73 @@
+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)
+
+  if(nadd.eq.-999) return
+  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.
+     do i=1,64
+        x=min(afac*s3(i,j)/ave,50.d0)
+        fs(i)=exp(x)
+        fsum=fsum+fs(i)
+        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
+     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
+
+  return
+end subroutine demod64a
diff --git a/lib/downsam9.f90 b/lib/downsam9.f90
new file mode 100644
index 0000000..851d497
--- /dev/null
+++ b/lib/downsam9.f90
@@ -0,0 +1,66 @@
+subroutine downsam9(id2,npts8,nsps8,newdat,nspsd,fpk,c2,nz2)
+
+!Downsample from id2() into C2() so as to yield nspsd samples per symbol, 
+!mixing from fpk down to zero frequency.
+
+  include 'constants.f90'
+  parameter (NMAX1=1024*1920)
+  integer*2 id2(0:8*npts8-1)
+  real*4 x1(0:NMAX1-1)
+  complex c1(0:NMAX1/2)
+  complex c2(0:4096-1)
+  real s(5000)
+  equivalence (c1,x1)
+  save
+
+  nfft1=1024*nsps8                          !Forward FFT length
+  df1=12000.0/nfft1
+  npts=8*npts8
+
+  if(newdat.eq.1) then
+     fac=6.963e-6                             !Why this weird constant?
+     do i=0,npts-1
+        x1(i)=fac*id2(i)
+     enddo
+     x1(npts:nfft1-1)=0.                      !Zero the rest of x1
+     call timer('fft_forw',0)
+     call four2a(c1,nfft1,1,-1,0)             !Forward FFT, r2c
+     call timer('fft_forw',1)
+
+     nadd=1.0/df1
+     s=0.
+     do i=1,5000
+        j=(i-1)/df1
+        do n=1,nadd
+           j=j+1
+           s(i)=s(i)+real(c1(j))**2 + aimag(c1(j))**2
+        enddo
+     enddo
+  endif
+
+  ndown=8*nsps8/nspsd                      !Downsample factor
+  nfft2=nfft1/ndown                        !Backward FFT length
+  nh2=nfft2/2
+  nf=nint(fpk)
+  i0=fpk/df1
+
+  nw=100
+  ia=max(1,nf-nw)
+  ib=min(5000,nf+nw)
+  call timer('pctile_1',0)
+  call pctile(s(ia),ib-ia+1,40,avenoise)
+  call timer('pctile_1',1)
+
+  fac=sqrt(1.0/avenoise)
+  do i=0,nfft2-1
+     j=i0+i
+     if(i.gt.nh2) j=j-nfft2
+     c2(i)=fac*c1(j)
+  enddo
+  call timer('fft_back',0)
+  call four2a(c2,nfft2,1,1,1)              !FFT back to time domain
+  call timer('fft_back',1)
+  nz2=8*npts8/ndown
+
+  return
+end subroutine downsam9
diff --git a/lib/encode232.f90 b/lib/encode232.f90
new file mode 100644
index 0000000..bc904b4
--- /dev/null
+++ b/lib/encode232.f90
@@ -0,0 +1,33 @@
+subroutine encode232(dat,nsym,symbol)
+
+! Convolutional encoder for a K=32, r=1/2 code.
+
+  integer*1 dat(13)                 !User data, packed 8 bits per byte
+  integer*1 symbol(500)             !Channel symbols, one bit per byte
+  integer*1 i1
+  include 'conv232.f90'
+
+  nstate=0
+  k=0
+  do j=1,nsym
+     do i=7,0,-1
+        i1=dat(j)
+        i4=i1
+        if (i4.lt.0) i4=i4+256
+        nstate=ior(ishft(nstate,1),iand(ishft(i4,-i),1))
+        n=iand(nstate,npoly1)
+        n=ieor(n,ishft(n,-16))
+        k=k+1
+        symbol(k)=partab(iand(ieor(n,ishft(n,-8)),255))
+        n=iand(nstate,npoly2)
+        n=ieor(n,ishft(n,-16))
+        k=k+1
+        symbol(k)=partab(iand(ieor(n,ishft(n,-8)),255))
+        if(k.ge.nsym) go to 100
+     enddo
+  enddo
+
+100 continue
+
+  return
+end subroutine encode232
diff --git a/lib/encode4.f90 b/lib/encode4.f90
new file mode 100644
index 0000000..64b9dfc
--- /dev/null
+++ b/lib/encode4.f90
@@ -0,0 +1,20 @@
+subroutine encode4(message,ncode)
+
+  parameter (MAXCALLS=7000,MAXRPT=63)
+  integer ncode(206)
+  character*22 message          !Message to be generated
+  character*3 cok               !'   ' or 'OOO'
+  integer dgen(13)
+  integer*1 data0(13),symbol(216)
+  logical text
+
+  call chkmsg(message,cok,nspecial,flip)
+  call packmsg(message,dgen,text)  !Pack 72-bit message into 12 six-bit symbols
+  call entail(dgen,data0)
+  call encode232(data0,206,symbol)       !Convolutional encoding
+  call interleave24(symbol,1)            !Apply JT4 interleaving
+  do i=1,206
+     ncode(i)=symbol(i)
+  enddo
+
+end subroutine encode4
diff --git a/lib/encode_rs.c b/lib/encode_rs.c
new file mode 100644
index 0000000..911bc36
--- /dev/null
+++ b/lib/encode_rs.c
@@ -0,0 +1,52 @@
+/* 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(
+#ifdef FIXED
+DTYPE *data, DTYPE *bb,int pad){
+#else
+void *p,DTYPE *data, DTYPE *bb){
+  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++){
+    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;
+  }
+}
diff --git a/lib/entail.f90 b/lib/entail.f90
new file mode 100644
index 0000000..1228a75
--- /dev/null
+++ b/lib/entail.f90
@@ -0,0 +1,30 @@
+subroutine entail(dgen,data0)
+
+! Move 72-bit packed data from 6-bit to 8-bit symbols and add a zero tail.
+  integer dgen(13)
+  integer*1 data0(13)
+
+  i4=0
+  k=0
+  m=0
+  do i=1,12
+     n=dgen(i)
+     do j=1,6
+        k=k+1
+        i4=i4+i4+iand(1,ishft(n,j-6))
+        i4=iand(i4,255)
+        if(k.eq.8) then
+           m=m+1
+           if(i4.gt.127) i4=i4-256
+           data0(m)=i4
+           k=0
+        endif
+     enddo
+  enddo
+  do m=10,13
+     data0(m)=0
+  enddo
+
+  return
+end subroutine entail
+
diff --git a/lib/extract.F90 b/lib/extract.F90
new file mode 100644
index 0000000..2b580f6
--- /dev/null
+++ b/lib/extract.F90
@@ -0,0 +1,103 @@
+subroutine extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv)
+
+  real s3(64,63)
+  character decoded*22
+  integer era(51),dat4(12),indx(64)
+  integer mrsym(63),mr2sym(63),mrprob(63),mr2prob(63)
+  logical nokv,ltext
+  data nokv/.false./,nsec1/0/
+  save
+
+  nbmkv=0
+  nfail=0
+1 continue
+  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
+     do j=1,63
+        s3(ipk,j)=base
+     enddo
+     if(nfail.gt.30) then
+        decoded='                      '
+        ncount=-1
+        go to 900
+     endif
+     go to 1
+  endif
+
+  call graycode65(mrsym,63,-1)
+  call interleave63(mrsym,-1)
+  call interleave63(mrprob,-1)
+
+! Decode using Berlekamp-Massey algorithm
+  nemax=30                                         !Max BM erasures
+  call indexx(63,mrprob,indx)
+  do i=1,nemax
+     j=indx(i)
+     if(mrprob(j).gt.120) then
+        ne2=i-1
+        go to 2
+     endif
+     era(i)=j-1
+  enddo
+  ne2=nemax
+2 decoded='                      '
+  do nerase=0,ne2,2
+     call rs_decode(mrsym,era,nerase,dat4,ncount)
+     if(ncount.ge.0) then
+        call unpackmsg(dat4,decoded)
+        if(iand(dat4(10),8).ne.0) ltext=.true.
+        nbmkv=1
+        go to 900
+     endif
+  enddo
+
+! Berlekamp-Massey algorithm failed, try Koetter-Vardy
+
+  if(nokv) go to 900
+
+  maxe=8                             !Max KV errors in 12 most reliable symbols
+!  xlambda=12.0
+  xlambda=7.99
+  call graycode65(mr2sym,63,-1)
+  call interleave63(mr2sym,-1)
+  call interleave63(mr2prob,-1)
+
+  nsec1=nsec1+1
+  write(22,rec=1) nsec1,xlambda,maxe,200,mrsym,mrprob,mr2sym,mr2prob
+  call flush(22)
+  call timer('kvasd   ',0)
+#ifdef UNIX
+  iret=system('./kvasd -q > dev_null')
+#else
+  iret=system('kvasd -q > dev_null')
+#endif
+  call timer('kvasd   ',1)
+  if(iret.ne.0) then
+     if(.not.nokv) write(*,1000) 
+1000 format('Error in KV decoder, or no KV decoder present.')
+     nokv=.true.
+     go to 900
+  endif
+
+  read(22,rec=2,err=900) nsec2,ncount,dat4
+  j=nsec2                !Silence compiler warning
+  decoded='                      '
+  ltext=.false.
+  if(ncount.ge.0) then
+     call unpackmsg(dat4,decoded)     !Unpack the user message
+     if(iand(dat4(10),8).ne.0) ltext=.true.
+     nbmkv=2
+  endif
+
+900 continue
+
+  return
+end subroutine extract
diff --git a/lib/extract4.f90 b/lib/extract4.f90
new file mode 100644
index 0000000..0622946
--- /dev/null
+++ b/lib/extract4.f90
@@ -0,0 +1,61 @@
+subroutine extract4(sym,nadd,ncount,decoded)
+
+  real sym(207)
+  character decoded*22, submode*1
+  character*72 c72
+  integer*1 symbol(207)
+  integer*1 data1(13)                   !Decoded data (8-bit bytes)
+  integer   data4a(9)                   !Decoded data (8-bit bytes)
+  integer   data4(12)                   !Decoded data (6-bit bytes)
+  integer mettab(0:255,0:1)             !Metric table
+  logical first
+  data first/.true./
+  save first,mettab
+
+  if(first) then
+     call getmet24(mode,mettab)
+     first=.false.
+  endif
+
+  do j=1,207
+     r=sym(j) + 128.
+     if(r.gt.255.0) r=255.0
+     if(r.lt.0.0) r=0.0
+     i4=nint(r)
+     if(i4.gt.127) i4=i4-256
+     symbol(j)=i4
+  enddo
+
+  nbits=72+31
+  ndelta=50
+  limit=100000
+  ncycles=0
+  ncount=-1
+  decoded='                      '
+  submode=' '
+
+  call interleave24(symbol(2),-1)         !Remove the interleaving
+  call fano232(symbol(2),nbits,mettab,ndelta,limit,data1,ncycles,metric,ncount)
+  nlim=ncycles/nbits
+
+  if(ncount.ge.0) then
+     do i=1,9
+        i4=data1(i)
+        if(i4.lt.0) i4=i4+256
+        data4a(i)=i4
+     enddo
+     write(c72,1100) (data4a(i),i=1,9)
+1100 format(9b8.8)
+     read(c72,1102) data4
+1102 format(12b6)
+
+     call unpackmsg(data4,decoded)
+     submode=char(ichar('A')+ich-1)
+     if(decoded(1:6).eq.'000AAA') then
+        decoded='***WRONG MODE?***'
+        ncount=-1
+     endif
+  endif
+
+  return
+end subroutine extract4
diff --git a/lib/f77_wisdom.f90 b/lib/f77_wisdom.f90
new file mode 100644
index 0000000..39bdff8
--- /dev/null
+++ b/lib/f77_wisdom.f90
@@ -0,0 +1,45 @@
+subroutine write_char(c, iunit)
+  character c
+  integer iunit
+  write(iunit,1000) c
+1000 format(a,$)
+end subroutine write_char
+
+subroutine export_wisdom_to_file(iunit)
+  integer iunit
+  external write_char
+!      call dfftw_export_wisdom(write_char, iunit)
+  call sfftw_export_wisdom(write_char, iunit)
+end subroutine export_wisdom_to_file
+
+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 read_char
+      
+subroutine import_wisdom_from_file(isuccess, iunit)
+  integer isuccess
+  integer iunit
+  external read_char
+!     call dfftw_import_wisdom(isuccess, read_char, iunit)
+  call sfftw_import_wisdom(isuccess, read_char, iunit)
+end subroutine import_wisdom_from_file
diff --git a/lib/fano232.f90 b/lib/fano232.f90
new file mode 100644
index 0000000..1e12950
--- /dev/null
+++ b/lib/fano232.f90
@@ -0,0 +1,140 @@
+subroutine fano232(symbol,nbits,mettab,ndelta,maxcycles,dat,     &
+     ncycles,metric,ierr)
+
+! Sequential decoder for K=32, r=1/2 convolutional code using 
+! the Fano algorithm.  Translated from C routine for same purpose
+! written by Phil Karn, KA9Q.
+
+  parameter (MAXBITS=103)
+  parameter (MAXBYTES=(MAXBITS+7)/8)
+  integer*1 symbol(0:2*MAXBITS-1)  !Soft symbols (as unsigned i*1)
+  integer*1 dat(MAXBYTES)          !Decoded user data, 8 bits per byte
+  integer mettab(0:255,0:1)        !Metric table
+
+! These were the "node" structure in Karn's C code:
+  integer nstate(0:MAXBITS-1)      !Encoder state of next node
+  integer gamma(0:MAXBITS-1)       !Cumulative metric to this node
+  integer metrics(0:3,0:MAXBITS-1) !Metrics indexed by all possible Tx syms
+  integer tm(0:1,0:MAXBITS-1)      !Sorted metrics for current hypotheses
+  integer ii(0:MAXBITS-1)          !Current branch being tested
+
+  logical noback
+  include 'conv232.f90'            !Polynomials defined here
+
+  ntail=nbits-31
+
+! Compute all possible branch metrics for each symbol pair.
+! This is the only place we actually look at the raw input symbols
+  i4a=0
+  i4b=0
+  do np=0,nbits-1
+     j=2*np
+     i4a=symbol(j)
+     i4b=symbol(j+1)
+     if (i4a.lt.0) i4a=i4a+256
+     if (i4b.lt.0) i4b=i4b+256
+     metrics(0,np) = mettab(i4a,0) + mettab(i4b,0)
+     metrics(1,np) = mettab(i4a,0) + mettab(i4b,1)
+     metrics(2,np) = mettab(i4a,1) + mettab(i4b,0)
+     metrics(3,np) = mettab(i4a,1) + mettab(i4b,1)
+  enddo
+
+  np=0
+  nstate(np)=0
+
+  n=iand(nstate(np),npoly1)                  !Compute and sort branch metrics 
+  n=ieor(n,ishft(n,-16))                     !from the root node
+  lsym=partab(iand(ieor(n,ishft(n,-8)),255))
+  n=iand(nstate(np),npoly2)
+  n=ieor(n,ishft(n,-16))
+  lsym=lsym+lsym+partab(iand(ieor(n,ishft(n,-8)),255))
+  m0=metrics(lsym,np)
+  m1=metrics(ieor(3,lsym),np)
+  if(m0.gt.m1) then
+     tm(0,np)=m0                             !0-branch has better metric
+     tm(1,np)=m1
+  else
+     tm(0,np)=m1                             !1-branch is better
+     tm(1,np)=m0
+     nstate(np)=nstate(np) + 1               !Set low bit
+  endif
+
+  ii(np)=0                                   !Start with best branch
+  gamma(np)=0
+  nt=0
+
+  do i=1,nbits*maxcycles                     !Start the Fano decoder
+     ngamma=gamma(np) + tm(ii(np),np)        !Look forward
+     if(ngamma.ge.nt) then
+! Node is acceptable.  If first time visiting this node, tighten threshold:
+        if(gamma(np).lt.(nt+ndelta)) nt=nt + ndelta * ((ngamma-nt)/ndelta)
+        gamma(np+1)=ngamma                   !Move forward
+        nstate(np+1)=ishft(nstate(np),1)
+        np=np+1
+        if(np.eq.nbits-1) go to 100          !We're done!
+
+        n=iand(nstate(np),npoly1)
+        n=ieor(n,ishft(n,-16))
+        lsym=partab(iand(ieor(n,ishft(n,-8)),255))
+        n=iand(nstate(np),npoly2)
+        n=ieor(n,ishft(n,-16))
+        lsym=lsym+lsym+partab(iand(ieor(n,ishft(n,-8)),255))
+            
+        if(np.ge.ntail) then
+           tm(0,np)=metrics(lsym,np)      !We're in the tail, now all zeros
+        else
+           m0=metrics(lsym,np)
+           m1=metrics(ieor(3,lsym),np)
+           if(m0.gt.m1) then
+              tm(0,np)=m0                 !0-branch has better metric
+              tm(1,np)=m1
+           else
+              tm(0,np)=m1                 !1-branch is better
+              tm(1,np)=m0
+              nstate(np)=nstate(np) + 1   !Set low bit
+           endif
+        endif
+        ii(np)=0                          !Start with best branch
+     else
+        do while(.true.)
+           noback=.false.                 !Threshold violated, can't go forward
+           if(np.eq.0) noback=.true.
+           if(np.gt.0) then
+              if(gamma(np-1).lt.nt) noback=.true.
+           endif
+
+           if(noback) then               !Can't back up, either
+              nt=nt-ndelta               !Relax threshold and look forward again
+              if(ii(np).ne.0) then
+                 ii(np)=0
+                 nstate(np)=ieor(nstate(np),1)
+              endif
+              exit
+           endif
+
+           np=np-1                       !Back up
+           if(np.lt.ntail .and. ii(np).ne.1) then
+              ii(np)=ii(np)+1            !Search the next best branch
+              nstate(np)=ieor(nstate(np),1)
+              exit
+           endif
+        enddo
+     endif
+  enddo
+  i=nbits*maxcycles
+  
+100 metric=gamma(np)                       !Final path metric
+  nbytes=(nbits+7)/8                       !Copy decoded data to user's buffer
+  np=7
+  do j=1,nbytes-1
+     i4a=nstate(np)
+     dat(j)=i4a
+     np=np+8
+  enddo
+  dat(nbytes)=0
+  ncycles=i+1
+  ierr=0
+  if(i.ge.maxcycles*nbits) ierr=-1
+
+  return
+end subroutine fano232
diff --git a/lib/fchisq.f90 b/lib/fchisq.f90
new file mode 100644
index 0000000..1dece10
--- /dev/null
+++ b/lib/fchisq.f90
@@ -0,0 +1,41 @@
+real function fchisq(c3,npts,fsample,a)
+
+  parameter (NMAX=85*16)
+  complex c3(npts)
+  complex c4(NMAX)
+  real a(3)
+  complex z
+  data a1,a2,a3/99.,99.,99./
+  include 'jt9sync.f90'
+  save
+
+  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)
+     call twkfreq(c3,c4,npts,fsample,a)
+  endif
+
+! Get sync power.
+  nspsd=16
+  sum1=0.
+  sum0=0.
+  k=-1
+  do i=1,85
+     z=0.
+     do j=1,nspsd
+        k=k+1
+        z=z+c4(k+1)
+     enddo
+     pp=real(z)**2 + aimag(z)**2     
+     if(isync(i).eq.1) then
+        sum1=sum1+pp
+     else
+        sum0=sum0+pp
+     endif
+  enddo
+  sync=(sum1/16.0)/(sum0/69.0) - 1.0
+  fchisq=-sync
+
+  return
+end function fchisq
diff --git a/lib/fchisq65.f90 b/lib/fchisq65.f90
new file mode 100644
index 0000000..b91444e
--- /dev/null
+++ b/lib/fchisq65.f90
@@ -0,0 +1,68 @@
+real function fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
+
+  parameter (NMAX=60*12000)          !Samples per 60 s
+  complex cx(npts)
+  real a(5)
+  complex w,wstep,z
+  real ss(3000)
+  complex csx(0:NMAX/8)
+  data twopi/6.283185307/a1,a2,a3/99.,99.,99./
+  save
+
+  call timer('fchisq65',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 signal
+     csx(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
+           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)
+     enddo
+  endif
+
+! Compute 1/2-symbol powers at 1/16-symbol steps.
+  fac=1.e-4
+  
+  do i=1,nout
+     j=i*nsps/ndiv
+     k=j-nsph
+     ss(i)=0.
+     if(k.ge.1) then
+        z=csx(j)-csx(k)
+        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
+  fchisq65=-ccfmax
+
+  call timer('fchisq65',1)
+
+  return
+end function fchisq65
diff --git a/lib/fftw3.f90 b/lib/fftw3.f90
new file mode 100644
index 0000000..440ccc2
--- /dev/null
+++ b/lib/fftw3.f90
@@ -0,0 +1,64 @@
+  INTEGER FFTW_R2HC
+  PARAMETER (FFTW_R2HC=0)
+  INTEGER FFTW_HC2R
+  PARAMETER (FFTW_HC2R=1)
+  INTEGER FFTW_DHT
+  PARAMETER (FFTW_DHT=2)
+  INTEGER FFTW_REDFT00
+  PARAMETER (FFTW_REDFT00=3)
+  INTEGER FFTW_REDFT01
+  PARAMETER (FFTW_REDFT01=4)
+  INTEGER FFTW_REDFT10
+  PARAMETER (FFTW_REDFT10=5)
+  INTEGER FFTW_REDFT11
+  PARAMETER (FFTW_REDFT11=6)
+  INTEGER FFTW_RODFT00
+  PARAMETER (FFTW_RODFT00=7)
+  INTEGER FFTW_RODFT01
+  PARAMETER (FFTW_RODFT01=8)
+  INTEGER FFTW_RODFT10
+  PARAMETER (FFTW_RODFT10=9)
+  INTEGER FFTW_RODFT11
+  PARAMETER (FFTW_RODFT11=10)
+  INTEGER FFTW_FORWARD
+  PARAMETER (FFTW_FORWARD=-1)
+  INTEGER FFTW_BACKWARD
+  PARAMETER (FFTW_BACKWARD=+1)
+  INTEGER FFTW_MEASURE
+  PARAMETER (FFTW_MEASURE=0)
+  INTEGER FFTW_DESTROY_INPUT
+  PARAMETER (FFTW_DESTROY_INPUT=1)
+  INTEGER FFTW_UNALIGNED
+  PARAMETER (FFTW_UNALIGNED=2)
+  INTEGER FFTW_CONSERVE_MEMORY
+  PARAMETER (FFTW_CONSERVE_MEMORY=4)
+  INTEGER FFTW_EXHAUSTIVE
+  PARAMETER (FFTW_EXHAUSTIVE=8)
+  INTEGER FFTW_PRESERVE_INPUT
+  PARAMETER (FFTW_PRESERVE_INPUT=16)
+  INTEGER FFTW_PATIENT
+  PARAMETER (FFTW_PATIENT=32)
+  INTEGER FFTW_ESTIMATE
+  PARAMETER (FFTW_ESTIMATE=64)
+  INTEGER FFTW_ESTIMATE_PATIENT
+  PARAMETER (FFTW_ESTIMATE_PATIENT=128)
+  INTEGER FFTW_BELIEVE_PCOST
+  PARAMETER (FFTW_BELIEVE_PCOST=256)
+  INTEGER FFTW_DFT_R2HC_ICKY
+  PARAMETER (FFTW_DFT_R2HC_ICKY=512)
+  INTEGER FFTW_NONTHREADED_ICKY
+  PARAMETER (FFTW_NONTHREADED_ICKY=1024)
+  INTEGER FFTW_NO_BUFFERING
+  PARAMETER (FFTW_NO_BUFFERING=2048)
+  INTEGER FFTW_NO_INDIRECT_OP
+  PARAMETER (FFTW_NO_INDIRECT_OP=4096)
+  INTEGER FFTW_ALLOW_LARGE_GENERIC
+  PARAMETER (FFTW_ALLOW_LARGE_GENERIC=8192)
+  INTEGER FFTW_NO_RANK_SPLITS
+  PARAMETER (FFTW_NO_RANK_SPLITS=16384)
+  INTEGER FFTW_NO_VRANK_SPLITS
+  PARAMETER (FFTW_NO_VRANK_SPLITS=32768)
+  INTEGER FFTW_NO_VRECURSE
+  PARAMETER (FFTW_NO_VRECURSE=65536)
+  INTEGER FFTW_NO_SIMD
+  PARAMETER (FFTW_NO_SIMD=131072)
diff --git a/lib/fil3.f90 b/lib/fil3.f90
new file mode 100644
index 0000000..0d66061
--- /dev/null
+++ b/lib/fil3.f90
@@ -0,0 +1,159 @@
+subroutine fil3(x1,n1,c2,n2)
+
+! FIR real-to-complex filter designed using ScopeFIR
+!
+!-----------------------------------------------
+! fsample    (Hz)  12000      Input sample rate
+! Ntaps            113        Number of filter taps
+! fc         (Hz)  500        Cutoff frequency
+! fstop      (Hz)  750        Lower limit of stopband
+! Ripple     (dB)  0.2        Ripple in passband
+! Stop Atten (dB)  50         Stopband attenuation
+! fmix       (HZ)  1500       Mixing frequency
+! fout       (Hz)  1500       Output sample rate
+
+! Resulting passband is 1000 - 2000 Hz
+
+! Suggest calling with n1 = 8*n2 + 105, where n2 is the desired number
+! of 1500 Hz output samples.
+
+  parameter (NTAPS=113)
+  parameter (NH=NTAPS/2)
+  parameter (NDOWN=8)                !Downsample ratio = 1/8
+  real x1(n1)
+  complex z
+  complex c2(n1/NDOWN)
+
+! Filter coefficients:
+  complex ca(-NH:NH)
+  data ca/                                   &
+        (-0.001818142144, 0.000000000000),   &
+        (-0.000664066641,-0.000664066640),   &
+        (-0.000000000000,-0.001044063550),   &
+        ( 0.000737290018,-0.000737290010),   &
+        ( 0.000908957610,-0.000000000000),   &
+        ( 0.000444156615, 0.000444156610),   &
+        (-0.000000000000, 0.000202701460),   &
+        ( 0.000244876473,-0.000244876470),   &
+        ( 0.000978154552, 0.000000000000),   &
+        ( 0.001155650277, 0.001155650270),   &
+        ( 0.000000000000, 0.002243121590),   &
+        (-0.001927618608, 0.001927618600),   &
+        (-0.003006201675, 0.000000000000),   &
+        (-0.002134087852,-0.002134087850),   &
+        ( 0.000000000000,-0.002717699570),   &
+        ( 0.001478946738,-0.001478946730),   &
+        ( 0.001162489032, 0.000000000000),   &
+        (-0.000005589545,-0.000005589540),   &
+        (-0.000000000000,-0.001321554800),   &
+        ( 0.001873767954,-0.001873767950),   &
+        ( 0.003843608784,-0.000000000000),   &
+        ( 0.003356874940, 0.003356874940),   &
+        (-0.000000000000, 0.005218967040),   &
+        (-0.003640348011, 0.003640348010),   &
+        (-0.004470167307, 0.000000000000),   &
+        (-0.002247131477,-0.002247131470),   &
+        (-0.000000000000,-0.001335998900),   &
+        (-0.000647656208, 0.000647656200),   &
+        (-0.003386100636, 0.000000000000),   &
+        (-0.004114456189,-0.004114456180),   &
+        ( 0.000000000000,-0.007939147960),   &
+        ( 0.006692816134,-0.006692816130),   &
+        ( 0.010145641899, 0.000000000000),   &
+        ( 0.006920770724, 0.006920770720),   &
+        ( 0.000000000000, 0.008285915750),   &
+        (-0.003992321524, 0.003992321520),   &
+        (-0.001995842303, 0.000000000000),   &
+        ( 0.001704388774, 0.001704388770),   &
+        (-0.000000000000, 0.007202515550),   &
+        (-0.008426458377, 0.008426458370),   &
+        (-0.016028350845, 0.000000000000),   &
+        (-0.013430355885,-0.013430355880),   &
+        (-0.000000000000,-0.020297455950),   &
+        ( 0.013791263729,-0.013791263720),   &
+        ( 0.016298136197,-0.000000000000),   &
+        ( 0.007443596155, 0.007443596150),   &
+        (-0.000000000000, 0.002223837360),   &
+        ( 0.005924356866,-0.005924356860),   &
+        ( 0.020854478160, 0.000000000000),   &
+        ( 0.024471928130, 0.024471928130),   &
+        ( 0.000000000000, 0.048909701460),   &
+        (-0.044508219241, 0.044508219240),   &
+        (-0.075874892030, 0.000000000000),   &
+        (-0.061450241075,-0.061450241070),   &
+        ( 0.000000000000,-0.095332017640),   &
+        ( 0.071148679982,-0.071148679980),   &
+        ( 0.102420526192, 0.000000000000),   &
+        ( 0.071148679982, 0.071148679980),   &
+        ( 0.000000000000, 0.095332017640),   &
+        (-0.061450241075, 0.061450241070),   &
+        (-0.075874892030, 0.000000000000),   &
+        (-0.044508219241,-0.044508219240),   &
+        ( 0.000000000000,-0.048909701460),   &
+        ( 0.024471928130,-0.024471928130),   &
+        ( 0.020854478160, 0.000000000000),   &
+        ( 0.005924356866, 0.005924356860),   &
+        (-0.000000000000,-0.002223837360),   &
+        ( 0.007443596155,-0.007443596150),   &
+        ( 0.016298136197,-0.000000000000),   &
+        ( 0.013791263729, 0.013791263720),   &
+        (-0.000000000000, 0.020297455950),   &
+        (-0.013430355885, 0.013430355880),   &
+        (-0.016028350845, 0.000000000000),   &
+        (-0.008426458377,-0.008426458370),   &
+        (-0.000000000000,-0.007202515550),   &
+        ( 0.001704388774,-0.001704388770),   &
+        (-0.001995842303, 0.000000000000),   &
+        (-0.003992321524,-0.003992321520),   &
+        ( 0.000000000000,-0.008285915750),   &
+        ( 0.006920770724,-0.006920770720),   &
+        ( 0.010145641899, 0.000000000000),   &
+        ( 0.006692816134, 0.006692816130),   &
+        ( 0.000000000000, 0.007939147960),   &
+        (-0.004114456189, 0.004114456180),   &
+        (-0.003386100636, 0.000000000000),   &
+        (-0.000647656208,-0.000647656200),   &
+        (-0.000000000000, 0.001335998900),   &
+        (-0.002247131477, 0.002247131470),   &
+        (-0.004470167307, 0.000000000000),   &
+        (-0.003640348011,-0.003640348010),   &
+        (-0.000000000000,-0.005218967040),   &
+        ( 0.003356874940,-0.003356874940),   &
+        ( 0.003843608784,-0.000000000000),   &
+        ( 0.001873767954, 0.001873767950),   &
+        (-0.000000000000, 0.001321554800),   &
+        (-0.000005589545, 0.000005589540),   &
+        ( 0.001162489032, 0.000000000000),   &
+        ( 0.001478946738, 0.001478946730),   &
+        ( 0.000000000000, 0.002717699570),   &
+        (-0.002134087852, 0.002134087850),   &
+        (-0.003006201675, 0.000000000000),   &
+        (-0.001927618608,-0.001927618600),   &
+        ( 0.000000000000,-0.002243121590),   &
+        ( 0.001155650277,-0.001155650270),   &
+        ( 0.000978154552, 0.000000000000),   &
+        ( 0.000244876473, 0.000244876470),   &
+        (-0.000000000000,-0.000202701460),   &
+        ( 0.000444156615,-0.000444156610),   &
+        ( 0.000908957610,-0.000000000000),   &
+        ( 0.000737290018, 0.000737290010),   &
+        (-0.000000000000, 0.001044063550),   &
+        (-0.000664066641, 0.000664066640),   &
+        (-0.001818142144, 0.000000000000)/
+  save ca
+
+  n2=(n1-NTAPS+NDOWN)/NDOWN
+  k0=NH-NDOWN+1
+
+! Loop over all output samples
+  do i=1,n2
+     z=0.
+     k=k0 + NDOWN*i
+     do j=-NH,NH
+        z=z + x1(j+k)*ca(j)
+     enddo
+     c2(i)=z
+  enddo
+
+  return
+end subroutine fil3
diff --git a/lib/fil61.f90 b/lib/fil61.f90
new file mode 100644
index 0000000..faf62a3
--- /dev/null
+++ b/lib/fil61.f90
@@ -0,0 +1,64 @@
+12000 61 250 750 0.2 50, mix at 1500
+
+
+-0.000000000000  0.001944450121
+-0.000668730681  0.000668730681
+-0.000974850191 -0.000000000000
+-0.000581679123 -0.000581679123
+ 0.000000000000 -0.000439648787
+-0.000148911451  0.000148911451
+-0.001140891736 -0.000000000000
+-0.001653102965 -0.001653102965
+ 0.000000000000 -0.003749915818
+ 0.003740834397 -0.003740834397
+ 0.006834087490  0.000000000000
+ 0.005812808655  0.005812808655
+-0.000000000000  0.009262713933
+-0.006900370427  0.006900370427
+-0.009503248519 -0.000000000000
+-0.005874581677 -0.005874581677
+ 0.000000000000 -0.006017530719
+ 0.001785268072 -0.001785268072
+-0.002214736448 -0.000000000000
+-0.005777038427 -0.005777038427
+ 0.000000000000 -0.015228682747
+ 0.016402831440 -0.016402831440
+ 0.031806920774  0.000000000000
+ 0.028800401613  0.028800401613
+-0.000000000000  0.049589395998
+-0.041000303659  0.041000303659
+-0.065514139214 -0.000000000000
+-0.050781544715 -0.050781544715
+ 0.000000000000 -0.076562341482
+ 0.056225821996 -0.056225821996
+ 0.080516569816  0.000000000000
+ 0.056225821996  0.056225821996
+-0.000000000000  0.076562341482
+-0.050781544715  0.050781544715
+-0.065514139214 -0.000000000000
+-0.041000303659 -0.041000303659
+ 0.000000000000 -0.049589395998
+ 0.028800401613 -0.028800401613
+ 0.031806920774  0.000000000000
+ 0.016402831440  0.016402831440
+-0.000000000000  0.015228682747
+-0.005777038427  0.005777038427
+-0.002214736448 -0.000000000000
+ 0.001785268072  0.001785268072
+-0.000000000000  0.006017530719
+-0.005874581677  0.005874581677
+-0.009503248519 -0.000000000000
+-0.006900370427 -0.006900370427
+ 0.000000000000 -0.009262713933
+ 0.005812808655 -0.005812808655
+ 0.006834087490  0.000000000000
+ 0.003740834397  0.003740834397
+-0.000000000000  0.003749915818
+-0.001653102965  0.001653102965
+-0.001140891736 -0.000000000000
+-0.000148911451 -0.000148911451
+-0.000000000000  0.000439648787
+-0.000581679123  0.000581679123
+-0.000974850191 -0.000000000000
+-0.000668730681 -0.000668730681
+ 0.000000000000 -0.001944450121
diff --git a/lib/fil6521.f90 b/lib/fil6521.f90
new file mode 100644
index 0000000..6e78e63
--- /dev/null
+++ b/lib/fil6521.f90
@@ -0,0 +1,44 @@
+subroutine fil6521(c1,n1,c2,n2)
+
+! FIR lowpass filter designed using ScopeFIR
+
+!                  Pass #1   Pass #2  
+! -----------------------------------------------
+! fsample    (Hz)  1378.125   Input sample rate
+! Ntaps            21         Number of filter taps
+! fc         (Hz)  40         Cutoff frequency
+! fstop      (Hz)  172.266    Lower limit of stopband
+! Ripple     (dB)  0.1        Ripple in passband
+! Stop Atten (dB)  38         Stopband attenuation
+! fout       (Hz)  344.531    Output sample rate
+
+  parameter (NTAPS=21)
+  parameter (NH=NTAPS/2)
+  parameter (NDOWN=4)                !Downsample ratio = 1/4
+  complex c1(n1)
+  complex c2(n1/NDOWN)
+
+! Filter coefficients:
+  real a(-NH:NH)
+  data a/                                                                &
+       -0.011958606980,-0.013888627387,-0.015601306443,-0.010602249570,  &
+        0.003804023436, 0.028320058273, 0.060903935217, 0.096841904411,  &
+        0.129639871228, 0.152644580853, 0.160917511283, 0.152644580853,  &
+        0.129639871228, 0.096841904411, 0.060903935217, 0.028320058273,  &
+        0.003804023436,-0.010602249570,-0.015601306443,-0.013888627387,  &
+       -0.011958606980/
+
+  n2=(n1-NTAPS+NDOWN)/NDOWN
+  k0=NH-NDOWN+1
+
+! Loop over all output samples
+  do i=1,n2
+     c2(i)=0.
+     k=k0 + NDOWN*i
+     do j=-NH,NH
+        c2(i)=c2(i) + c1(j+k)*a(j)
+     enddo
+  enddo
+
+  return
+end subroutine fil6521
diff --git a/lib/filbig.f90 b/lib/filbig.f90
new file mode 100644
index 0000000..cb59b2f
--- /dev/null
+++ b/lib/filbig.f90
@@ -0,0 +1,127 @@
+subroutine filbig(dd,npts,f0,newdat,c4a,n4,sq0)
+
+! Filter and downsample the real data in array dd(npts), sampled at 12000 Hz.
+! Output is complex, sampled at 1378.125 Hz.
+
+  parameter (NSZ=3413)
+  parameter (NFFT1=672000,NFFT2=77175)
+  parameter (NZ2=1000)
+  real*4  dd(npts)                           !Input data
+  complex ca(NFFT1)                          !FFT of input
+  complex c4a(NFFT2)                         !Output data
+  real*4 s(NZ2)
+  real*8 df
+  real halfpulse(8)                 !Impulse response of filter (one sided)
+  complex cfilt(NFFT2)                       !Filter (complex; imag = 0)
+  real rfilt(NFFT2)                          !Filter (real)
+  integer*8 plan1,plan2,plan3
+  logical first
+  include 'fftw3.f90'
+  equivalence (rfilt,cfilt)
+  data first/.true./,npatience/0/
+  data halfpulse/114.97547150,36.57879257,-20.93789101,              &
+       5.89886379,1.59355187,-2.49138308,0.60910773,-0.04248129/
+  common/refspec/dfref,ref(NSZ)
+  save
+
+  if(npts.lt.0) go to 900                    !Clean up at end of program
+
+  if(first) then
+     nflags=FFTW_ESTIMATE
+     if(npatience.eq.1) nflags=FFTW_ESTIMATE_PATIENT
+     if(npatience.eq.2) nflags=FFTW_MEASURE
+     if(npatience.eq.3) nflags=FFTW_PATIENT
+     if(npatience.eq.4) nflags=FFTW_EXHAUSTIVE
+! Plan the FFTs just once
+     call timer('FFTplans ',0)
+     call sfftw_plan_dft_1d(plan1,nfft1,ca,ca,FFTW_BACKWARD,nflags)
+     call sfftw_plan_dft_1d(plan2,nfft2,c4a,c4a,FFTW_FORWARD,nflags)
+     call sfftw_plan_dft_1d(plan3,nfft2,cfilt,cfilt,FFTW_BACKWARD,nflags)
+     call timer('FFTplans ',1)
+
+! Convert impulse response to filter function
+     do i=1,nfft2
+        cfilt(i)=0.
+     enddo
+     fac=0.00625/nfft1
+     cfilt(1)=fac*halfpulse(1)
+     do i=2,8
+        cfilt(i)=fac*halfpulse(i)
+        cfilt(nfft2+2-i)=fac*halfpulse(i)
+     enddo
+     call timer('FFTfilt ',0)
+     call sfftw_execute(plan3)
+     call timer('FFTfilt ',1)
+
+     base=cfilt(nfft2/2+1)
+     do i=1,nfft2
+        rfilt(i)=real(cfilt(i))-base
+     enddo
+
+     df=12000.d0/nfft1
+     first=.false.
+  endif
+
+! When new data comes along, we need to compute a new "big FFT"
+! If we just have a new f0, continue with the existing data in ca.
+
+  if(newdat.ne.0) then
+     nz=min(npts,nfft1)
+     ca(1:nz)=dd(1:nz)
+     ca(nz+1:)=0.                   !### Should change this to r2c FFT ###
+     call timer('FFTbig  ',0)
+     call sfftw_execute(plan1)
+     call timer('FFTbig  ',1)
+
+     do i=1,NFFT1/2                             !Flatten the spectrum
+        j=nint(i*df/dfref)
+        if(j.lt.1) j=1
+        if(j.gt.NSZ) j=NSZ
+        fac=sqrt(min(30.0,1.0/ref(j)))
+        ca(i)=fac * ca(i)
+     enddo
+  endif
+
+! NB: f0 is the frequency at which we want our filter centered.
+!     i0 is the bin number in ca closest to f0.
+
+  i0=nint(f0/df) + 1
+  nh=nfft2/2
+  do i=1,nh                                !Copy data into c4a and apply
+     j=i0+i-1                              !the filter function
+     if(j.ge.1 .and. j.le.nfft1) then
+        c4a(i)=rfilt(i)*ca(j)
+     else
+        c4a(i)=0.
+     endif
+  enddo
+  do i=nh+1,nfft2
+     j=i0+i-1-nfft2
+     if(j.lt.1) j=j+nfft1                  !nfft1 was nfft2
+     c4a(i)=rfilt(i)*ca(j)
+  enddo
+
+  nadd=nfft2/NZ2
+  i=0
+  do j=1,NZ2
+     s(j)=0.
+     do n=1,nadd
+        i=i+1
+        s(j)=s(j) + real(c4a(i))**2 + aimag(c4a(i))**2
+     enddo
+  enddo
+  call pctile(s,NZ2,30,sq0)
+
+! Do the short reverse transform, to go back to time domain.
+  call timer('FFTsmall',0)
+  call sfftw_execute(plan2)
+  call timer('FFTsmall',1)
+  n4=min(npts/8,nfft2)
+  return
+
+900 call sfftw_destroy_plan(plan1)
+  call sfftw_destroy_plan(plan2)
+  call sfftw_destroy_plan(plan3)
+  
+  return
+end subroutine filbig
diff --git a/lib/fillcom.f90 b/lib/fillcom.f90
new file mode 100644
index 0000000..03fbb2c
--- /dev/null
+++ b/lib/fillcom.f90
@@ -0,0 +1,25 @@
+subroutine fillcom(nutc0,ndepth0,nrxfreq)
+  character*20 datetime
+  common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol,  &
+       kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,datetime
+  save
+
+  nutc=nutc0
+  ndiskdat=1
+  ntrperiod=60
+  nfqso=nrxfreq
+  newdat=1
+  npts8=74736
+  nfa=2700
+  nfb=4007
+  ntol=3
+  kin=1024
+  nzhsym=173
+  nsave=0
+  ndepth=ndepth0
+  ntxmode=9
+  nmode=9+65
+  datetime="2013-Apr-16 15:13"
+  
+  return
+end subroutine fillcom
diff --git a/lib/flat1.f90 b/lib/flat1.f90
new file mode 100644
index 0000000..526ab9b
--- /dev/null
+++ b/lib/flat1.f90
@@ -0,0 +1,30 @@
+subroutine flat1(psavg,s2,nh,nsteps,nhmax,nsmax)
+
+  real psavg(nh)
+  real s2(nhmax,nsmax)
+  real x(8192),tmp(33)
+
+  nsmo=33
+  ia=nsmo/2 + 1
+  ib=nh - nsmo/2 - 1
+  do i=ia,ib
+     call pctile(psavg(i-nsmo/2),nsmo,50,x(i))
+  enddo
+  do i=1,ia-1
+     x(i)=x(ia)
+  enddo
+  do i=ib+1,nh
+     x(i)=x(ib)
+  enddo
+
+  do i=1,nh
+     psavg(i)=psavg(i)/x(i)
+     do j=1,nsteps
+        s2(i,j)=s2(i,j)/x(i)
+     enddo
+  enddo
+
+  return
+end subroutine flat1
+
+      
diff --git a/lib/flat2.f90 b/lib/flat2.f90
new file mode 100644
index 0000000..cebd989
--- /dev/null
+++ b/lib/flat2.f90
@@ -0,0 +1,18 @@
+subroutine flat2(s,nz,ref)
+
+  parameter (NSMAX=6827)
+  real s(NSMAX)
+  real ref(NSMAX)
+
+  nsmo=10
+  ia=nsmo+1
+  ib=nz-nsmo-1
+  do i=ia,ib
+     call pctile(s(i-nsmo),2*nsmo+1,5,ref(i))
+  enddo
+
+  ref(:ia-1)=ref(ia)
+  ref(ib+1:)=ref(ib)
+
+  return
+end subroutine flat2
diff --git a/lib/flat65.f90 b/lib/flat65.f90
new file mode 100644
index 0000000..7aa106c
--- /dev/null
+++ b/lib/flat65.f90
@@ -0,0 +1,25 @@
+subroutine flat65(ss,nhsym,maxhsym,nsz,ref)
+
+  real stmp(nsz)
+  real ss(maxhsym,nsz)
+  real ref(nsz)
+
+  npct=28                                       !Somewhat arbitrary
+  do i=1,nsz
+     call pctile(ss(1,i),nhsym,npct,stmp(i))
+  enddo
+
+  nsmo=33
+  ia=nsmo/2 + 1
+  ib=nsz - nsmo/2 - 1
+  do i=ia,ib
+     call pctile(stmp(i-nsmo/2),nsmo,npct,ref(i))
+  enddo
+  ref(:ia-1)=ref(ia)
+  ref(ib+1:)=ref(ib)
+  ref=4.0*ref
+
+  return
+end subroutine flat65
+
+      
diff --git a/lib/four2a.f90 b/lib/four2a.f90
new file mode 100644
index 0000000..c095629
--- /dev/null
+++ b/lib/four2a.f90
@@ -0,0 +1,90 @@
+subroutine four2a(a,nfft,ndim,isign,iform)
+
+!     IFORM = 1, 0 or -1, as data is
+!     complex, real, or the first half of a complex array.  Transform
+!     values are returned in array DATA.  They are complex, real, or
+!     the first half of a complex array, as IFORM = 1, -1 or 0.
+
+!     The transform of a real array (IFORM = 0) dimensioned N(1) by N(2)
+!     by ... will be returned in the same array, now considered to
+!     be complex of dimensions N(1)/2+1 by N(2) by ....  Note that if
+!     IFORM = 0 or -1, N(1) must be even, and enough room must be
+!     reserved.  The missing values may be obtained by complex conjugation.  
+
+!     The reverse transformation of a half complex array dimensioned
+!     N(1)/2+1 by N(2) by ..., is accomplished by setting IFORM
+!     to -1.  In the N array, N(1) must be the true N(1), not N(1)/2+1.
+!     The transform will be real and returned to the input array.
+
+  parameter (NPMAX=100)
+  parameter (NSMALL=16384)
+  complex a(nfft)
+  complex aa(NSMALL)
+  integer nn(NPMAX),ns(NPMAX),nf(NPMAX)
+  integer*8 plan(NPMAX),nl(NPMAX),nloc
+  data nplan/0/,npatience/1/
+!  data nplan/0/,npatience/0/
+  include 'fftw3.f90'
+  save plan,nplan,nn,ns,nf,nl
+
+  if(nfft.lt.0) go to 999
+
+  nloc=loc(a)
+  do i=1,nplan
+     if(nfft.eq.nn(i) .and. isign.eq.ns(i) .and.                     &
+          iform.eq.nf(i) .and. nloc.eq.nl(i)) go to 10
+  enddo
+  if(nplan.ge.NPMAX) stop 'Too many FFTW plans requested.'
+  nplan=nplan+1
+  i=nplan
+  nn(i)=nfft
+  ns(i)=isign
+  nf(i)=iform
+  nl(i)=nloc
+
+! Planning: FFTW_ESTIMATE, FFTW_ESTIMATE_PATIENT, FFTW_MEASURE, 
+!            FFTW_PATIENT,  FFTW_EXHAUSTIVE
+  nflags=FFTW_ESTIMATE
+  if(npatience.eq.1) nflags=FFTW_ESTIMATE_PATIENT
+  if(npatience.eq.2) nflags=FFTW_MEASURE
+  if(npatience.eq.3) nflags=FFTW_PATIENT
+  if(npatience.eq.4) nflags=FFTW_EXHAUSTIVE
+
+  if(nfft.le.NSMALL) then
+     jz=nfft
+     if(iform.eq.0) jz=nfft/2
+     do j=1,jz
+        aa(j)=a(j)
+     enddo
+  endif
+  if(isign.eq.-1 .and. iform.eq.1) then
+     call sfftw_plan_dft_1d(plan(i),nfft,a,a,FFTW_FORWARD,nflags)
+  else if(isign.eq.1 .and. iform.eq.1) then
+     call sfftw_plan_dft_1d(plan(i),nfft,a,a,FFTW_BACKWARD,nflags)
+  else if(isign.eq.-1 .and. iform.eq.0) then
+     call sfftw_plan_dft_r2c_1d(plan(i),nfft,a,a,nflags)
+  else if(isign.eq.1 .and. iform.eq.-1) then
+     call sfftw_plan_dft_c2r_1d(plan(i),nfft,a,a,nflags)
+  else
+     stop 'Unsupported request in four2a'
+  endif
+  i=nplan
+  if(nfft.le.NSMALL) then
+     jz=nfft
+     if(iform.eq.0) jz=nfft/2
+     do j=1,jz
+        a(j)=aa(j)
+     enddo
+  endif
+
+10 continue
+  call sfftw_execute(plan(i))
+  return
+
+999 do i=1,nplan
+! The test is only to silence a compiler warning:
+     if(ndim.ne.-999) call sfftw_destroy_plan(plan(i))
+  enddo
+
+  return
+end subroutine four2a
diff --git a/lib/gen24.f90 b/lib/gen24.f90
new file mode 100644
index 0000000..e2aaa77
--- /dev/null
+++ b/lib/gen24.f90
@@ -0,0 +1,86 @@
+subroutine gen24(message,mode4,samfac,ntxdf,iwave,nwave,sendingsh,msgsent,nmsg)
+
+! Encode a JT4 message into a wavefile.
+
+  parameter (NMAX=60*11025)     !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,pi,twopi,samfac,tsymbol
+  integer*2 iwave(NMAX)         !Generated wave file
+  integer sendingsh
+  integer dgen(13)
+  integer*1 data0(13),symbol(216)
+  logical first
+  include 'prcom2.f'
+  data first/.true./
+  save
+
+  nsym=207                               !Symbols per transmission
+  if(first) then
+     do i=1,nsym
+        pr2(i)=2*npr2(i)-1
+     enddo
+     pi=4.d0*atan(1.d0)
+     twopi=2.d0*pi
+     first=.false.
+  endif
+
+  call chkmsg(message,cok,nspecial,flip)
+  call packmsg(message,dgen)  !Pack 72-bit message into 12 six-bit symbols
+  call entail(dgen,data0)
+  call unpackmsg(dgen,msgsent)
+
+  nbytes=(72+31+7)/8
+  call encode(data0,nbytes,symbol(2))    !Convolutional encoding
+  symbol(1)=0                            !Reference phase
+  sendingsh=0
+  if(iand(dgen(10),8).ne.0) sendingsh=-1 !Plain text flag
+  call interleave24(symbol(2),1)         !Apply JT4 interleaving
+
+! Set up necessary constants
+  tsymbol=2520.d0/11025.d0
+  dt=1.d0/(samfac*11025.d0)
+  f0=118*11025.d0/1024 + ntxdf
+  dfgen=11025.d0/2520                     !4.375 Hz
+  t=0.d0
+  phi=0.d0
+  j0=0
+  ndata=(nsym*11025.d0*samfac*tsymbol)/2
+  ndata=2*ndata
+  do i=1,ndata
+     t=t+dt
+     j=int(t/tsymbol) + 1   !Symbol number, 1-207
+     if(j.ne.j0) then
+        f=f0 + (npr2(j)+2*symbol(j)-1.5) * dfgen * mode4
+        if(flip.lt.0.0) f=f0+((1-npr2(j))+2*symbol(j)-1.5)*dfgen*mode4
+        dphi=twopi*dt*f
+        j0=j
+     endif
+     phi=phi+dphi
+     iwave(i)=32767.0*sin(phi)
+  enddo
+
+  do j=1,5512                !Put another 0.5 sec of silence at end
+     i=i+1
+     iwave(i)=0
+  enddo
+  nwave=i
+
+  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
+  do i=22,1,-1
+     if(msgsent(i:i).ne.' ') goto 20
+  enddo
+20 nmsg=i
+
+!      write(*,3002) (symbol(i),i=1,207)
+! 3002 format(70i1)
+
+  return
+end subroutine gen24
+
diff --git a/lib/gen65.f90 b/lib/gen65.f90
new file mode 100644
index 0000000..8580238
--- /dev/null
+++ b/lib/gen65.f90
@@ -0,0 +1,65 @@
+subroutine gen65(msg0,ichk,msgsent,itone,itext)
+
+! Encodes a JT65 message to yieild itone(1:126)
+! Temporarily, does not implement EME shorthands
+
+  character*22 msg0
+  character*22 message          !Message to be generated
+  character*22 msgsent          !Message as it will be received
+  integer itone(126)
+!  character*3 cok               !'   ' or 'OOO'
+  integer dgen(13)
+  integer sent(63)
+  logical text
+  integer nprc(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/
+  save
+
+  message=msg0
+  do i=1,22
+     if(ichar(message(i:i)).eq.0) then
+        message(i:)='                      '
+        exit
+     endif
+  enddo
+
+  do i=1,22                               !Strip leading blanks
+     if(message(1:1).ne.' ') exit
+     message=message(i+1:)
+  enddo
+
+  nspecial=0
+!  call chkmsg(message,cok,nspecial,flip)
+  if(nspecial.eq.0) then
+     call packmsg(message,dgen,text)     !Pack message into 72 bits
+     itext=0
+     if(text) itext=1
+     call unpackmsg(dgen,msgsent)        !Unpack to get message sent
+     if(ichk.ne.0) go to 999             !Return if checking only
+
+     call rs_encode(dgen,sent)           !Apply Reed-Solomon code
+     call interleave63(sent,1)           !Apply interleaving
+     call graycode65(sent,63,1)          !Apply Gray code
+     nsym=126                            !Symbols per transmission
+  else
+     nsym=32
+  endif
+
+  k=0
+  do j=1,nsym
+     if(nprc(j).eq.0) then
+        k=k+1
+        itone(j)=sent(k)+2
+     else
+        itone(j)=0
+     endif
+  enddo
+
+999 return
+end subroutine gen65
diff --git a/lib/genjt9.f90 b/lib/genjt9.f90
new file mode 100644
index 0000000..90427e1
--- /dev/null
+++ b/lib/genjt9.f90
@@ -0,0 +1,58 @@
+subroutine genjt9(msg0,ichk,msgsent,i4tone,itext)
+
+! Encodes a JT9 message and returns msgsent, the message as it will
+! be decoded, and an integer array i4tone(85) of 9-FSK tone values 
+! in the range 0-8.  
+
+  character*22 msg0
+  character*22 message                    !Message to be generated
+  character*22 msgsent                    !Message as it will be received
+  integer*4 i4Msg6BitWords(13)            !72-bit message as 6-bit words
+  integer*1 i1Msg8BitBytes(13)            !72 bits and zero tail as 8-bit bytes
+  integer*1 i1EncodedBits(207)            !Encoded information-carrying bits
+  integer*1 i1ScrambledBits(207)          !Encoded bits after interleaving
+  integer*4 i4DataSymbols(69)             !Data symbols (values 0-7)
+  integer*4 i4GrayCodedSymbols(69)        !Gray-coded symbols (values 0-7)
+  integer*4 i4tone(85)                    !Tone #s, data and sync (values 0-8)
+  logical text
+  include 'jt9sync.f90'
+  save
+
+  message=msg0
+  do i=1,22
+     if(ichar(message(i:i)).eq.0) then
+        message(i:)='                      '
+        exit
+     endif
+  enddo
+
+  do i=1,22                               !Strip leading blanks
+     if(message(1:1).ne.' ') exit
+     message=message(i+1:)
+  enddo
+
+  call packmsg(message,i4Msg6BitWords,text)   !Pack message into 12 6-bit bytes
+  itext=0
+  if(text) itext=1
+  call unpackmsg(i4Msg6BitWords,msgsent)      !Unpack to get msgsent
+  if(ichk.ne.0) go to 999
+  call entail(i4Msg6BitWords,i1Msg8BitBytes)  !Add tail, convert to 8-bit bytes
+  nsym2=206
+  call encode232(i1Msg8BitBytes,nsym2,i1EncodedBits)   !Encode K=32, r=1/2
+  call interleave9(i1EncodedBits,1,i1ScrambledBits)    !Interleave the bits
+  call packbits(i1ScrambledBits,nsym2,3,i4DataSymbols) !Pack 3-bits into words
+  call graycode(i4DataSymbols,69,1,i4GrayCodedSymbols) !Apply Gray code
+
+! Insert sync symbols at ntone=0 and add 1 to the data-tone numbers.
+  j=0
+  do i=1,85
+     if(isync(i).eq.1) then
+        i4tone(i)=0
+     else
+        j=j+1
+        i4tone(i)=i4GrayCodedSymbols(j)+1
+     endif
+  enddo
+
+999 return
+end subroutine genjt9
diff --git a/lib/genmet.f90 b/lib/genmet.f90
new file mode 100644
index 0000000..0682bf8
--- /dev/null
+++ b/lib/genmet.f90
@@ -0,0 +1,88 @@
+program genmet
+
+! Generate metric table for M-FSK modulation.
+
+  character*12 arg
+  real*4 r(0:255)
+  integer hist(2,-128:128)
+  data hist/514*0/,idum/-1/
+
+  lim(x)=min(127,max(-128,nint(scale*x)))
+
+  nargs=iargc()
+  if(nargs.ne.5) then
+     print*,'Usage: genmet ncoh nadd m0 snr iters'
+     go to 999
+  endif
+  call getarg(1,arg)
+  read(arg,*) ncoh
+  call getarg(2,arg)
+  read(arg,*) nadd
+  call getarg(3,arg)
+  read(arg,*) m0
+  call getarg(4,arg)
+  read(arg,*) snr
+  call getarg(5,arg)
+  read(arg,*) iters
+
+  ntones=2**m0
+  xm0=m0
+  scale=5.0
+  fac=sqrt(1.0/nadd)
+  s=sqrt(10.0**(0.1*snr))
+  hist=0
+  nerr=0
+
+  do iter=1,iters
+     do i=0,ntones-1
+        r(i)=0.
+        do n=1,nadd
+           x1=0.707*gran()
+           y1=0.707*gran()
+           if(i.eq.0) x1=x1+s
+           if(ncoh.eq.0) r(i)=r(i) + x1*x1 + y1*y1
+           if(ncoh.ne.0) r(i)=r(i) + x1
+        enddo
+        r(i)=fac*r(i)
+     enddo
+     do m=0,m0-1
+        n=2**m
+        r1=0.
+        r2=0.
+        do i=0,ntones-1
+           if(iand(i,n).ne.0) r1=max(r1,r(i))
+           if(iand(i,n).eq.0) r2=max(r2,r(i))
+        enddo
+        don=r2-r1
+        doff=r1-r2
+        if(don.lt.0.0) nerr=nerr+1
+        j1=lim(doff)
+        hist(1,j1)=hist(1,j1)+1
+        j2=lim(don)
+        hist(2,j2)=hist(2,j2)+1
+     enddo
+  enddo
+
+  do i=-128,127
+     write(13,1010) i/scale,hist(1,i)/(xm0*iters),hist(2,i)/(xm0*iters)
+1010 format(f8.3,2f12.9)
+  enddo
+
+  ber=nerr/(xm0*iters)
+  write(*,1020) nadd,m0,snr,ber
+1020 format('nadd:',i3,'   m0:',i2,'   snr: 'f5.1,'   BER:',f8.3)
+      
+  xln2=log(2.0)
+  do i=-128,127
+     p1=hist(2,i)/(xm0*iters)
+     p0=hist(1,i)/(xm0*iters)
+     if(p0+p1.eq.0.0 .and. i.lt.0) p0=1.e-6
+     if(p0+p1.eq.0.0 .and. i.gt.0) p1=1.e-6
+     xlhd0=log(max(0.001,2.0*p0/(p0+p1)))/xln2
+     xlhd1=log(max(0.001,2.0*p1/(p0+p1)))/xln2
+     write(14,1012) i/scale,xlhd0,xlhd1,p0/(p0+p1),p1/(p0+p1)
+1012 format(f7.1,2f8.3,2f9.6)
+  enddo
+      
+999 end program genmet
+
diff --git a/lib/geodist.f90 b/lib/geodist.f90
new file mode 100644
index 0000000..2ca7553
--- /dev/null
+++ b/lib/geodist.f90
@@ -0,0 +1,96 @@
+subroutine geodist(Eplat,Eplon,Stlat,Stlon,Az,Baz,Dist)
+  implicit none
+  real eplat, eplon, stlat, stlon, az, baz, dist
+
+! JHT: In actual fact, I use the first two arguments for "My Location",
+!     the second two for "His location"; West longitude is positive.
+
+!      Taken directly from:
+!      Thomas, P.D., 1970, Spheroidal geodesics, reference systems,
+!      & local geometry, U.S. Naval Oceanographi!Office SP-138,
+!      165 pp.
+!      assumes North Latitude and East Longitude are positive
+
+!      EpLat, EpLon = End point Lat/Long
+!      Stlat, Stlon = Start point lat/long
+!      Az, BAz = direct & reverse azimuith
+!      Dist = Dist (km); Deg = central angle, discarded
+
+  real BOA, F, P1R, P2R, L1R, L2R, DLR, T1R, T2R, TM,          &
+       DTM, STM, CTM, SDTM,CDTM, KL, KK, SDLMR, L,                &
+       CD, DL, SD, T, U, V, D, X, E, Y, A, FF64, TDLPM,           &
+       HAPBR, HAMBR, A1M2, A2M1
+
+  real AL,BL,D2R,Pi2
+
+  data AL/6378206.4/              ! Clarke 1866 ellipsoid
+  data BL/6356583.8/
+!      real pi /3.14159265359/
+  data D2R/0.01745329251994/      ! degrees to radians conversion factor
+  data Pi2/6.28318530718/
+
+  BOA = BL/AL
+  F = 1.0 - BOA
+! Convert st/end pts to radians
+  P1R = Eplat * D2R
+  P2R = Stlat * D2R
+  L1R = Eplon * D2R
+  L2R = StLon * D2R
+  DLR = L2R - L1R                 ! DLR = Delta Long in Rads
+  T1R = ATan(BOA * Tan(P1R))
+  T2R = ATan(BOA * Tan(P2R))
+  TM = (T1R + T2R) / 2.0
+  DTM = (T2R - T1R) / 2.0
+  STM = Sin(TM)
+  CTM = Cos(TM)
+  SDTM = Sin(DTM)
+  CDTM = Cos(DTM)
+  KL = STM * CDTM
+  KK = SDTM * CTM
+  SDLMR = Sin(DLR/2.0)
+  L = SDTM * SDTM + SDLMR * SDLMR * (CDTM * CDTM - STM * STM)
+  CD = 1.0 - 2.0 * L
+  DL = ACos(CD)
+  SD = Sin(DL)
+  T = DL/SD
+  U = 2.0 * KL * KL / (1.0 - L)
+  V = 2.0 * KK * KK / L
+  D = 4.0 * T * T
+  X = U + V
+  E = -2.0 * CD
+  Y = U - V
+  A = -D * E
+  FF64 = F * F / 64.0
+  Dist = AL*SD*(T -(F/4.0)*(T*X-Y)+FF64*(X*(A+(T-(A+E)                 &
+       /2.0)*X)+Y*(-2.0*D+E*Y)+D*X*Y))/1000.0
+  TDLPM = Tan((DLR+(-((E*(4.0-X)+2.0*Y)*((F/2.0)*T+FF64*               &
+       (32.0*T+(A-20.0*T)*X-2.0*(D+2.0)*Y))/4.0)*Tan(DLR)))/2.0)
+  HAPBR = ATan2(SDTM,(CTM*TDLPM))
+  HAMBR = Atan2(CDTM,(STM*TDLPM))
+  A1M2 = Pi2 + HAMBR - HAPBR
+  A2M1 = Pi2 - HAMBR - HAPBR
+
+1 If ((A1M2 .ge. 0.0) .AND. (A1M2 .lt. Pi2)) GOTO 5
+  If (A1M2 .lt. Pi2) GOTO 4
+  A1M2 = A1M2 - Pi2
+  GOTO 1
+4 A1M2 = A1M2 + Pi2
+  GOTO 1
+
+! All of this gens the proper az, baz (forward and back azimuth)
+
+5 If ((A2M1 .ge. 0.0) .AND. (A2M1 .lt. Pi2)) GOTO 9
+  If (A2M1 .lt. Pi2) GOTO 8
+  A2M1 = A2M1 - Pi2
+  GOTO 5
+8 A2M1 = A2M1 + Pi2
+  GOTO 5
+
+9 Az = A1M2 / D2R
+  BAZ = A2M1 / D2R
+
+!Fix the mirrored coords here.
+  
+  az = 360.0 - az
+  baz = 360.0 - baz
+end subroutine geodist
diff --git a/lib/getlags.f90 b/lib/getlags.f90
new file mode 100644
index 0000000..0d1f5d6
--- /dev/null
+++ b/lib/getlags.f90
@@ -0,0 +1,27 @@
+subroutine getlags(nsps8,lag0,lag1,lag2)
+  if(nsps8.eq.864) then
+     lag1=39
+     lag2=291
+     lag0=123
+  else if(nsps8.eq.1920) then
+     lag1=70
+     lag2=184
+     lag0=108
+  else if(nsps8.eq.5120) then
+     lag1=84
+     lag2=129
+     lag0=99
+  else if(nsps8.eq.10368) then
+     lag1=91
+     lag2=112
+     lag0=98
+  else if(nsps8.eq.31500) then
+     lag1=93
+     lag2=102
+     lag0=96
+  else 
+     stop 'Error in getlags'
+  endif
+
+  return
+end subroutine getlags
diff --git a/lib/getmet24.f90 b/lib/getmet24.f90
new file mode 100644
index 0000000..f35a90a
--- /dev/null
+++ b/lib/getmet24.f90
@@ -0,0 +1,52 @@
+subroutine getmet24(mode,mettab)
+
+! Return appropriate metric table for soft-decision convolutional decoder.
+
+! Metric table (RxSymbol,TxSymbol)
+  integer mettab(0:255,0:1)
+  real*4 xx0(0:255)
+  data xx0/                                                      &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000,  &
+        0.988, 1.000, 0.991, 0.993, 1.000, 0.995, 1.000, 0.991,  &
+        1.000, 0.991, 0.992, 0.991, 0.990, 0.990, 0.992, 0.996,  &
+        0.990, 0.994, 0.993, 0.991, 0.992, 0.989, 0.991, 0.987,  &
+        0.985, 0.989, 0.984, 0.983, 0.979, 0.977, 0.971, 0.975,  &
+        0.974, 0.970, 0.970, 0.970, 0.967, 0.962, 0.960, 0.957,  &
+        0.956, 0.953, 0.942, 0.946, 0.937, 0.933, 0.929, 0.920,  &
+        0.917, 0.911, 0.903, 0.895, 0.884, 0.877, 0.869, 0.858,  &
+        0.846, 0.834, 0.821, 0.806, 0.790, 0.775, 0.755, 0.737,  &
+        0.713, 0.691, 0.667, 0.640, 0.612, 0.581, 0.548, 0.510,  &
+        0.472, 0.425, 0.378, 0.328, 0.274, 0.212, 0.146, 0.075,  &
+        0.000,-0.079,-0.163,-0.249,-0.338,-0.425,-0.514,-0.606,  &
+       -0.706,-0.796,-0.895,-0.987,-1.084,-1.181,-1.280,-1.376,  &
+       -1.473,-1.587,-1.678,-1.790,-1.882,-1.992,-2.096,-2.201,  &
+       -2.301,-2.411,-2.531,-2.608,-2.690,-2.829,-2.939,-3.058,  &
+       -3.164,-3.212,-3.377,-3.463,-3.550,-3.768,-3.677,-3.975,  &
+       -4.062,-4.098,-4.186,-4.261,-4.472,-4.621,-4.623,-4.608,  &
+       -4.822,-4.870,-4.652,-4.954,-5.108,-5.377,-5.544,-5.995,  &
+       -5.632,-5.826,-6.304,-6.002,-6.559,-6.369,-6.658,-7.016,  &
+       -6.184,-7.332,-6.534,-6.152,-6.113,-6.288,-6.426,-6.313,  &
+       -9.966,-6.371,-9.966,-7.055,-9.966,-6.629,-6.313,-9.966,  &
+       -5.858,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,  &
+       -9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966/
+  save
+
+  bias=0.5
+  scale=10.0
+  do i=0,255
+     mettab(i,0)=nint(scale*(xx0(i)-bias))
+     if(i.ge.1) mettab(256-i,1)=mettab(i,0)
+  enddo
+
+  return
+end subroutine getmet24
+
diff --git a/lib/getpfx1.f90 b/lib/getpfx1.f90
new file mode 100644
index 0000000..4d4e7aa
--- /dev/null
+++ b/lib/getpfx1.f90
@@ -0,0 +1,97 @@
+subroutine getpfx1(callsign,k,nv2)
+
+  character*12 callsign0,callsign,lof,rof
+  character*8 c
+  character addpfx*8,tpfx*4,tsfx*3
+  logical ispfx,issfx,invalid
+  common/pfxcom/addpfx
+  include 'pfx.f90'
+
+  callsign0=callsign
+  nv2=0
+  iz=index(callsign,' ') - 1
+  if(iz.lt.0) iz=12
+  islash=index(callsign(1:iz),'/')
+  k=0
+  if(k.eq.0) go to 10                             !### Always use JT65v2 ###
+  c='   '
+  if(islash.gt.0 .and. islash.le.(iz-4)) then
+! Add-on prefix
+     c=callsign(1:islash-1)
+     callsign=callsign(islash+1:iz)
+     do i=1,NZ
+        if(pfx(i)(1:4).eq.c) then
+           k=i
+           go to 10
+        endif
+     enddo
+     if(addpfx.eq.c) then
+        k=449
+        go to 10
+     endif
+
+  else if(islash.eq.(iz-1)) then
+! Add-on suffix
+     c=callsign(islash+1:iz)
+     callsign=callsign(1:islash-1)
+     do i=1,NZ2
+        if(sfx(i).eq.c(1:1)) then
+           k=400+i
+           go to 10
+        endif
+     enddo
+  endif
+
+10 if(islash.ne.0 .and.k.eq.0) then
+! Original JT65 would force this compound callsign to be treated as
+! plain text.  In JT65v2, we will encode the prefix or suffix into nc1.
+! The task here is to compute the proper value of k.
+     lof=callsign0(:islash-1)
+     rof=callsign0(islash+1:)
+     llof=len_trim(lof)
+     lrof=len_trim(rof)
+     ispfx=(llof.gt.0 .and. llof.le.4)
+     issfx=(lrof.gt.0 .and. lrof.le.3)
+     invalid=.not.(ispfx.or.issfx)
+     if(ispfx.and.issfx) then
+        if(llof.lt.3) issfx=.false.
+        if(lrof.lt.3) ispfx=.false.
+        if(ispfx.and.issfx) then
+           i=ichar(callsign0(islash-1:islash-1))
+           if(i.ge.ichar('0') .and. i.le.ichar('9')) then
+              issfx=.false.
+           else
+              ispfx=.false.
+           endif
+        endif
+     endif
+
+     if(invalid) then
+        k=-1
+     else
+        if(ispfx) then
+           tpfx=lof(1:4)
+           k=nchar(tpfx(1:1))
+           k=37*k + nchar(tpfx(2:2))
+           k=37*k + nchar(tpfx(3:3))
+           k=37*k + nchar(tpfx(4:4))
+           nv2=1
+           i=index(callsign0,'/')
+           callsign=callsign0(:i-1)
+           callsign=callsign0(i+1:)
+        endif
+        if(issfx) then
+           tsfx=rof(1:3)
+           k=nchar(tsfx(1:1))
+           k=37*k + nchar(tsfx(2:2))
+           k=37*k + nchar(tsfx(3:3))
+           nv2=2
+           i=index(callsign0,'/')
+           callsign=callsign0(:i-1)
+        endif
+     endif
+  endif
+
+  return
+end subroutine getpfx1
+
diff --git a/lib/getpfx2.f90 b/lib/getpfx2.f90
new file mode 100644
index 0000000..d747e7f
--- /dev/null
+++ b/lib/getpfx2.f90
@@ -0,0 +1,24 @@
+subroutine getpfx2(k0,callsign)
+
+  character callsign*12
+  include 'pfx.f90'
+  character addpfx*8
+  common/pfxcom/addpfx
+
+  k=k0
+  if(k.gt.450) k=k-450
+  if(k.ge.1 .and. k.le.NZ) then
+     iz=index(pfx(k),' ') - 1
+     callsign=pfx(k)(1:iz)//'/'//callsign
+  else if(k.ge.401 .and. k.le.400+NZ2) then
+     iz=index(callsign,' ') - 1
+     callsign=callsign(1:iz)//'/'//sfx(k-400)
+  else if(k.eq.449) then
+     iz=index(addpfx,' ') - 1
+     if(iz.lt.1) iz=8
+     callsign=addpfx(1:iz)//'/'//callsign
+  endif
+
+  return
+end subroutine getpfx2
+
diff --git a/lib/gran.c b/lib/gran.c
new file mode 100644
index 0000000..ceeb6da
--- /dev/null
+++ b/lib/gran.c
@@ -0,0 +1,28 @@
+#include <stdlib.h>
+#include <math.h>
+
+/* 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;
+}
diff --git a/lib/graycode.f90 b/lib/graycode.f90
new file mode 100644
index 0000000..21c1f90
--- /dev/null
+++ b/lib/graycode.f90
@@ -0,0 +1,9 @@
+subroutine graycode(ia,n,idir,ib)
+
+  integer ia(n),ib(n)
+  do i=1,n
+     ib(i)=igray(ia(i),idir)
+  enddo
+
+  return
+end subroutine graycode
diff --git a/lib/graycode65.f90 b/lib/graycode65.f90
new file mode 100644
index 0000000..3ee9a42
--- /dev/null
+++ b/lib/graycode65.f90
@@ -0,0 +1,9 @@
+subroutine graycode65(dat,n,idir)
+
+  integer dat(n)
+  do i=1,n
+     dat(i)=igray(dat(i),idir)
+  enddo
+
+  return
+end subroutine graycode65
diff --git a/lib/grid2deg.f90 b/lib/grid2deg.f90
new file mode 100644
index 0000000..843fc84
--- /dev/null
+++ b/lib/grid2deg.f90
@@ -0,0 +1,38 @@
+subroutine grid2deg(grid0,dlong,dlat)
+
+! Converts Maidenhead grid locator to degrees of West longitude
+! and North latitude.
+
+  character*6 grid0,grid
+  character*1 g1,g2,g3,g4,g5,g6
+
+  grid=grid0
+  i=ichar(grid(5:5))
+  if(grid(5:5).eq.' ' .or. i.le.64 .or. i.ge.128) grid(5:6)='mm'
+
+  if(grid(1:1).ge.'a' .and. grid(1:1).le.'z') grid(1:1)=          &
+        char(ichar(grid(1:1))+ichar('A')-ichar('a'))
+  if(grid(2:2).ge.'a' .and. grid(2:2).le.'z') grid(2:2)=          &
+        char(ichar(grid(2:2))+ichar('A')-ichar('a'))
+  if(grid(5:5).ge.'A' .and. grid(5:5).le.'Z') grid(5:5)=          &
+        char(ichar(grid(5:5))-ichar('A')+ichar('a'))
+  if(grid(6:6).ge.'A' .and. grid(6:6).le.'Z') grid(6:6)=          &
+        char(ichar(grid(6:6))-ichar('A')+ichar('a'))
+
+  g1=grid(1:1)
+  g2=grid(2:2)
+  g3=grid(3:3)
+  g4=grid(4:4)
+  g5=grid(5:5)
+  g6=grid(6:6)
+
+  nlong = 180 - 20*(ichar(g1)-ichar('A'))
+  n20d = 2*(ichar(g3)-ichar('0'))
+  xminlong = 5*(ichar(g5)-ichar('a')+0.5)
+  dlong = nlong - n20d - xminlong/60.0
+  nlat = -90+10*(ichar(g2)-ichar('A')) + ichar(g4)-ichar('0')
+  xminlat = 2.5*(ichar(g6)-ichar('a')+0.5)
+  dlat = nlat + xminlat/60.0
+
+  return
+end subroutine grid2deg
diff --git a/lib/grid2k.f90 b/lib/grid2k.f90
new file mode 100644
index 0000000..f68b140
--- /dev/null
+++ b/lib/grid2k.f90
@@ -0,0 +1,12 @@
+subroutine grid2k(grid,k)
+
+  character*6 grid
+
+  call grid2deg(grid,xlong,xlat)
+  nlong=nint(xlong)
+  nlat=nint(xlat)
+  k=0
+  if(nlat.ge.85) k=5*(nlong+179)/2 + nlat-84
+
+  return
+end subroutine grid2k
diff --git a/lib/grid2n.f90 b/lib/grid2n.f90
new file mode 100644
index 0000000..d02d786
--- /dev/null
+++ b/lib/grid2n.f90
@@ -0,0 +1,10 @@
+subroutine grid2n(grid,n)
+  character*4 grid
+
+  i1=ichar(grid(1:1))-ichar('A')
+  i2=ichar(grid(3:3))-ichar('0')
+  i=10*i1 + i2
+  n=-i - 31
+
+  return
+end subroutine grid2n
diff --git a/lib/igray.c b/lib/igray.c
new file mode 100644
index 0000000..4646898
--- /dev/null
+++ b/lib/igray.c
@@ -0,0 +1,18 @@
+int igray_(int *n0, int *idir)
+{
+  int n;
+  unsigned long sh;
+  unsigned long nn;
+  n=*n0;
+
+  if(*idir>0) return (n ^ (n >> 1));
+
+  sh = 1;
+  nn = (n >> sh);
+  while (nn > 0) {
+    n ^= nn;
+    sh <<= 1;
+    nn = (n >> sh);
+  }
+  return (n);
+}
diff --git a/lib/indexx.f90 b/lib/indexx.f90
new file mode 100644
index 0000000..57c1ec0
--- /dev/null
+++ b/lib/indexx.f90
@@ -0,0 +1,19 @@
+subroutine indexx(n,arr,indx)
+
+  parameter (NMAX=3000)
+  integer indx(n)
+  real arr(n)
+  real brr(NMAX)
+  if(n.gt.NMAX) then
+     print*,'n=',n,' too big in indexx.'
+     stop
+  endif
+  do i=1,n
+     brr(i)=arr(i)
+     indx(i)=i
+  enddo
+  call ssort(brr,indx,n,2)
+
+  return
+end subroutine indexx
+
diff --git a/lib/init_rs.c b/lib/init_rs.c
new file mode 100644
index 0000000..eb27119
--- /dev/null
+++ b/lib/init_rs.c
@@ -0,0 +1,126 @@
+/* Initialize a RS codec
+ *
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#include <stdlib.h>
+
+#ifdef CCSDS
+#include "ccsds.h"
+#elif defined(BIGSYM)
+#include "int.h"
+#else
+#include "char.h"
+#endif
+
+//#define NULL ((void *)0)
+
+void FREE_RS(void *p){
+  struct rs *rs = (struct rs *)p;
+
+  free(rs->alpha_to);
+  free(rs->index_of);
+  free(rs->genpoly);
+  free(rs);
+}
+
+/* Initialize a Reed-Solomon codec
+ * symsize = symbol size, bits (1-8)
+ * gfpoly = Field generator polynomial coefficients
+ * 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){
+  struct rs *rs;
+  int i, j, sr,root,iprim;
+
+  /* Check parameter ranges */
+  if(symsize < 0 || symsize > 8*sizeof(DTYPE))
+    return NULL; /* Need version with ints rather than chars */
+
+  if(fcr < 0 || fcr >= (1<<symsize))
+    return NULL;
+  if(prim <= 0 || prim >= (1<<symsize))
+    return NULL;
+  if(nroots < 0 || 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){
+    free(rs);
+    return NULL;
+  }
+  rs->index_of = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
+  if(rs->index_of == NULL){
+    free(rs->alpha_to);
+    free(rs);
+    return NULL;
+  }
+
+  /* Generate Galois field lookup tables */
+  rs->index_of[0] = A0; /* log(zero) = -inf */
+  rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */
+  sr = 1;
+  for(i=0;i<rs->nn;i++){
+    rs->index_of[sr] = i;
+    rs->alpha_to[i] = sr;
+    sr <<= 1;
+    if(sr & (1<<symsize))
+      sr ^= gfpoly;
+    sr &= rs->nn;
+  }
+  if(sr != 1){
+    /* field generator polynomial is not primitive! */
+    free(rs->alpha_to);
+    free(rs->index_of);
+    free(rs);
+    return NULL;
+  }
+
+  /* Form RS code generator polynomial from its roots */
+  rs->genpoly = (DTYPE *)malloc(sizeof(DTYPE)*(nroots+1));
+  if(rs->genpoly == NULL){
+    free(rs->alpha_to);
+    free(rs->index_of);
+    free(rs);
+    return NULL;
+  }
+  rs->fcr = fcr;
+  rs->prim = prim;
+  rs->nroots = nroots;
+
+  /* Find prim-th root of 1, used in decoding */
+  for(iprim=1;(iprim % prim) != 0;iprim += rs->nn)
+    ;
+  rs->iprim = iprim / prim;
+
+  rs->genpoly[0] = 1;
+  for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) {
+    rs->genpoly[i+1] = 1;
+
+    /* Multiply rs->genpoly[] by  @**(root + x) */
+    for (j = i; j > 0; j--){
+      if (rs->genpoly[j] != 0)
+	rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
+      else
+	rs->genpoly[j] = rs->genpoly[j-1];
+    }
+    /* rs->genpoly[0] can never be zero */
+    rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
+  }
+  /* convert rs->genpoly[] to index form for quicker encoding */
+  for (i = 0; i <= nroots; i++)
+    rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
+
+  return rs;
+}
diff --git a/lib/int.h b/lib/int.h
new file mode 100644
index 0000000..056241e
--- /dev/null
+++ b/lib/int.h
@@ -0,0 +1,57 @@
+/* Include file to configure the RS codec for integer symbols
+ *
+ * Copyright 2002, Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define DTYPE int
+
+/* Reed-Solomon codec control block */
+struct rs {
+  int mm;              /* Bits per symbol */
+  int nn;              /* Symbols per block (= (1<<mm)-1) */
+  DTYPE *alpha_to;     /* log lookup table */
+  DTYPE *index_of;     /* Antilog lookup table */
+  DTYPE *genpoly;      /* Generator polynomial */
+  int nroots;     /* Number of generator roots = number of parity symbols */
+  int fcr;        /* First consecutive root, index form */
+  int prim;       /* Primitive element, index form */
+  int iprim;      /* prim-th root of 1, index form */
+  int pad;        /* Padding bytes in shortened block */
+};
+
+static int modnn(struct rs *rs,int x){
+  while (x >= rs->nn) {
+    x -= rs->nn;
+    x = (x >> rs->mm) + (x & rs->nn);
+  }
+  return x;
+}
+#define MODNN(x) modnn(rs,x)
+
+#define MM (rs->mm)
+#define NN (rs->nn)
+#define ALPHA_TO (rs->alpha_to) 
+#define INDEX_OF (rs->index_of)
+#define GENPOLY (rs->genpoly)
+//#define NROOTS (rs->nroots)
+#define NROOTS (51)
+#define FCR (rs->fcr)
+#define PRIM (rs->prim)
+#define IPRIM (rs->iprim)
+#define PAD (rs->pad)
+#define A0 (NN)
+
+#define ENCODE_RS encode_rs_int
+#define DECODE_RS decode_rs_int
+#define INIT_RS init_rs_int
+#define FREE_RS free_rs_int
+
+void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
+int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras);
+void *INIT_RS(int symsize,int gfpoly,int fcr,
+		   int prim,int nroots,int pad);
+void FREE_RS(void *p);
+
+
+
+
diff --git a/lib/interleave24.f90 b/lib/interleave24.f90
new file mode 100644
index 0000000..3cdd9c5
--- /dev/null
+++ b/lib/interleave24.f90
@@ -0,0 +1,43 @@
+subroutine interleave24(id,ndir)
+  integer*1 id(0:205),itmp(0:205)
+  integer j0(0:205)
+  logical first
+  data first/.true./
+  save first,j0
+
+  if(first) then
+     k=-1
+     do i=0,255
+        m=i
+        n=iand(m,1)
+        n=2*n + iand(m/2,1)
+        n=2*n + iand(m/4,1)
+        n=2*n + iand(m/8,1)
+        n=2*n + iand(m/16,1)
+        n=2*n + iand(m/32,1)
+        n=2*n + iand(m/64,1)
+        n=2*n + iand(m/128,1)
+        if(n.le.205) then
+           k=k+1
+           j0(k)=n
+        endif
+     enddo
+     first=.false.
+  endif
+
+  if(ndir.eq.1) then
+     do i=0,205
+        itmp(j0(i))=id(i)
+     enddo
+  else
+     do i=0,205
+        itmp(i)=id(j0(i))
+     enddo
+  endif
+
+  do i=0,205
+     id(i)=itmp(i)
+  enddo
+
+  return
+end subroutine interleave24
diff --git a/lib/interleave63.f90 b/lib/interleave63.f90
new file mode 100644
index 0000000..048244e
--- /dev/null
+++ b/lib/interleave63.f90
@@ -0,0 +1,25 @@
+subroutine interleave63(d1,idir)
+
+! Interleave (idir=1) or de-interleave (idir=-1) the array d1.
+
+  integer d1(0:6,0:8)
+  integer d2(0:8,0:6)
+
+  if(idir.ge.0) then
+     do i=0,6
+        do j=0,8
+           d2(j,i)=d1(i,j)
+        enddo
+     enddo
+     call move(d2,d1,63)
+  else
+     call move(d1,d2,63)
+     do i=0,6
+        do j=0,8
+           d1(i,j)=d2(j,i)
+        enddo
+     enddo
+  endif
+         
+  return
+end subroutine interleave63
diff --git a/lib/interleave8.f90 b/lib/interleave8.f90
new file mode 100644
index 0000000..e13346e
--- /dev/null
+++ b/lib/interleave8.f90
@@ -0,0 +1,17 @@
+subroutine interleave8(idat,jdat)
+
+  integer idat(66),jdat(66)
+  integer ii(66),jj(66)
+  data ii/                                                            &
+       64,32,16,48, 8,40,24,56, 4,36,20,52,12,44,28,60, 2,66,34,18,   &
+       50,10,42,26,58, 6,38,22,54,14,46,30,62, 1,65,33,17,49, 9,41,   &
+       25,57, 5,37,21,53,13,45,29,61, 3,35,19,51,11,43,27,59, 7,39,   &
+       23,55,15,47,31,63/
+  data jj/                                                            &
+       34,17,51, 9,43,26,59, 5,39,22,55,13,47,30,63, 3,37,20,53,11,   &
+       45,28,61, 7,41,24,57,15,49,32,65, 2,36,19,52,10,44,27,60, 6,   &
+       40,23,56,14,48,31,64, 4,38,21,54,12,46,29,62, 8,42,25,58,16,   &
+       50,33,66, 1,35,18/
+
+  return
+end subroutine interleave8
diff --git a/lib/interleave9.f90 b/lib/interleave9.f90
new file mode 100644
index 0000000..e3026a9
--- /dev/null
+++ b/lib/interleave9.f90
@@ -0,0 +1,39 @@
+subroutine interleave9(ia,ndir,ib)
+  integer*1 ia(0:205),ib(0:205)
+  integer j0(0:205)
+  logical first
+  data first/.true./
+  save first,j0                     !Save not working, or j0 overwritten ???
+
+  if(first) then
+     k=-1
+     do i=0,255
+        m=i
+        n=iand(m,1)
+        n=2*n + iand(m/2,1)
+        n=2*n + iand(m/4,1)
+        n=2*n + iand(m/8,1)
+        n=2*n + iand(m/16,1)
+        n=2*n + iand(m/32,1)
+        n=2*n + iand(m/64,1)
+        n=2*n + iand(m/128,1)
+        if(n.le.205) then
+           k=k+1
+           j0(k)=n
+        endif
+     enddo
+!     first=.false.
+  endif
+
+  if(ndir.gt.0) then
+     do i=0,205
+        ib(j0(i))=ia(i)
+     enddo
+  else
+     do i=0,205
+        ib(i)=ia(j0(i))
+     enddo
+  endif
+
+  return
+end subroutine interleave9
diff --git a/lib/ipcomm.cpp b/lib/ipcomm.cpp
new file mode 100644
index 0000000..d845a60
--- /dev/null
+++ b/lib/ipcomm.cpp
@@ -0,0 +1,50 @@
+#include <QDebug>
+#include <QString>
+#include <QSharedMemory>
+#include <QSystemSemaphore>
+
+// Multiple instances: KK1D, 17 Jul 2013
+QSharedMemory mem_jt9;
+
+// Semaphore not changed, as the acquire/release calls do not 
+// appear to be used anywhere.  
+QSystemSemaphore sem_jt9("sem_jt9", 1, QSystemSemaphore::Open);
+
+extern "C" {
+  bool attach_jt9_();
+  bool create_jt9_(int nsize);
+  bool detach_jt9_();
+  bool lock_jt9_();
+  bool unlock_jt9_();
+  char* address_jt9_();
+  int size_jt9_();
+// Multiple instances:  wrapper for QSharedMemory::setKey()
+  bool setkey_jt9_(char* mykey, int mykey_len);
+
+  bool acquire_jt9_();
+  bool release_jt9_();
+
+  extern struct {
+    char c[10];
+  } jt9com_;
+}
+
+bool attach_jt9_() {return mem_jt9.attach();}
+bool create_jt9_(int nsize) {return mem_jt9.create(nsize);}
+bool detach_jt9_() {return mem_jt9.detach();}
+bool lock_jt9_() {return mem_jt9.lock();}
+bool unlock_jt9_() {return mem_jt9.unlock();}
+char* address_jt9_() {return (char*)mem_jt9.constData();}
+int size_jt9_() {return (int)mem_jt9.size();}
+
+// Multiple instances:
+bool setkey_jt9_(char* mykey, int mykey_len) {
+   char *tempstr = (char *)calloc(mykey_len+1,1);
+   memset(tempstr, 0, mykey_len+1);
+   strncpy(tempstr, mykey, mykey_len);
+   QString s1 = QString(QLatin1String(tempstr));
+   mem_jt9.setKey(s1);
+   return true;}
+
+bool acquire_jt9_() {return sem_jt9.acquire();}
+bool release_jt9_() {return sem_jt9.release();}
diff --git a/lib/jt65.f90 b/lib/jt65.f90
new file mode 100644
index 0000000..10f7525
--- /dev/null
+++ b/lib/jt65.f90
@@ -0,0 +1,68 @@
+program jt65
+
+! Test the JT65 decoder for WSJT-X
+
+  parameter (NZMAX=60*12000)
+  integer*4 ihdr(11)
+  integer*2 id2(NZMAX)
+  real*4 dd(NZMAX)
+  character*80 infile
+  integer*2 nfmt2,nchan2,nbitsam2,nbytesam2
+  character*4 ariff,awave,afmt,adata
+  common/hdr/ariff,lenfile,awave,afmt,lenfmt,nfmt2,nchan2, &
+     nsamrate,nbytesec,nbytesam2,nbitsam2,adata,ndata
+  common/tracer/limtrace,lu
+  equivalence (lenfile,ihdr(2))
+
+  nargs=iargc()
+  if(nargs.lt.1) then
+     print*,'Usage: jt65 file1 [file2 ...]'
+     go to 999
+  endif
+  limtrace=0
+  lu=12
+
+  newdat=1
+  ntol=50
+  nfa=2700
+!  nfb=4000
+  nfqso=933
+  nagain=0
+
+  open(12,file='timer.out',status='unknown')
+  open(22,file='kvasd.dat',access='direct',recl=1024,status='unknown')
+
+  call timer('jt65    ',0)
+
+  do ifile=1,nargs
+     call getarg(ifile,infile)
+     open(10,file=infile,access='stream',status='old',err=998)
+
+     call timer('read    ',0)
+     read(10) ihdr
+     nutc=ihdr(1)                           !Silence compiler warning
+     i1=index(infile,'.wav')
+     read(infile(i1-4:i1-1),*,err=10) nutc
+     go to 20
+10    nutc=0
+20    npts=52*12000
+     read(10) id2(1:npts)
+     call timer('read    ',1)
+     dd(1:npts)=id2(1:npts)
+     dd(npts+1:)=0.
+
+     call timer('jt65a   ',0)
+     call jt65a(dd,npts,newdat,nutc,ntol,nfa,nfqso,nagain,ndecoded)
+     call timer('jt65a   ',1)
+  enddo
+
+  call timer('jt65    ',1)
+  call timer('jt65    ',101)
+  call four2a(a,-1,1,1,1)                  !Free the memory used for plans
+  call filbig(a,-1,1,0.0,0,0,0,0,0)        ! (ditto)
+  go to 999
+
+998 print*,'Cannot open file:'
+  print*,infile
+
+999 end program jt65
diff --git a/lib/jt65a.f90 b/lib/jt65a.f90
new file mode 100644
index 0000000..0c061ed
--- /dev/null
+++ b/lib/jt65a.f90
@@ -0,0 +1,85 @@
+subroutine jt65a(dd,npts,newdat,nutc,nfa,nfqso,ntol,nagain,ndecoded)
+
+!  Process dd() data to find and decode JT65 signals.
+
+  parameter (NSZ=3413)
+  parameter (NZMAX=60*12000)
+  parameter (NFFT=8192)
+  real dd(NZMAX)
+  real*4 ss(322,NSZ)
+  real*4 savg(NSZ)
+  logical done(NSZ)
+  real a(5)
+  character decoded*22
+  save
+
+  if(newdat.ne.0) then
+     call timer('symsp65 ',0)
+     call symspec65(dd,npts,ss,nhsym,savg)    !Get normalized symbol spectra
+     call timer('symsp65 ',1)
+  endif
+
+  df=12000.0/NFFT                     !df = 12000.0/16384 = 0.732 Hz
+  ftol=16.0                           !Frequency tolerance (Hz)
+  mode65=1                            !Decoding JT65A only, for now.
+  done=.false.
+  freq0=-999.
+
+  do nqd=1,0,-1
+     if(nqd.eq.1) then                !Quick decode, at fQSO
+        fa=nfqso - ntol
+        fb=nfqso + ntol
+     else                             !Wideband decode at all freqs
+        fa=200
+        fb=nfa
+     endif
+     ia=max(51,nint(fa/df))
+     ib=min(NSZ-51,nint(fb/df))
+     
+     thresh0=1.5
+
+     do i=ia,ib                               !Search over freq range
+        freq=i*df
+        if(savg(i).lt.thresh0 .or. done(i)) cycle
+
+        call timer('ccf65   ',0)
+        call ccf65(ss(1,i),nhsym,savg(i),sync1,dt,flipk,syncshort,snr2,dt2)
+        call timer('ccf65   ',1)
+
+        ftest=abs(freq-freq0)
+        thresh1=1.0
+        if(nqd.eq.1 .and. ntol.le.100) thresh1=0.
+        if(sync1.lt.thresh1 .or. ftest.lt.ftol) cycle
+
+        nflip=nint(flipk)
+        call timer('decod65a',0)
+        call decode65a(dd,npts,newdat,freq,nflip,mode65,sync2,a,dt,   &
+             nbmkv,nhist,decoded)
+        call timer('decod65a',1)
+
+        ftest=abs(freq+a(1)-freq0)
+        if(ftest.lt.ftol) cycle
+
+        if(decoded.ne.'                      ') then
+           ndecoded=1
+           nfreq=nint(freq+a(1))
+           ndrift=nint(2.0*a(2))
+           s2db=10.0*log10(sync2) - 32             !### empirical (was 40) ###
+           nsnr=nint(s2db)
+           if(nsnr.lt.-30) nsnr=-30
+           if(nsnr.gt.-1) nsnr=-1
+           write(*,1010) nutc,nsnr,dt,nfreq,decoded
+1010       format(i4.4,i4,f5.1,i5,1x,'#',1x,a22)
+           write(13,1012) nutc,nint(sync1),nsnr,dt,float(nfreq),ndrift,  &
+                decoded,nbmkv
+1012       format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22,' JT65',i4)
+           freq0=freq+a(1)
+           i2=min(NSZ,i+15)                !### ??? ###
+           done(i:i2)=.true.
+        endif
+     enddo
+     if(nagain.eq.1) exit
+  enddo
+
+  return
+end subroutine jt65a
diff --git a/lib/jt9.f90 b/lib/jt9.f90
new file mode 100644
index 0000000..1f0a619
--- /dev/null
+++ b/lib/jt9.f90
@@ -0,0 +1,111 @@
+program jt9
+
+! Decoder for JT9.  Can run stand-alone, reading data from *.wav files;
+! or as the back end of wsjt-x, with data placed in a shared memory region.
+
+  include 'constants.f90'
+  integer*4 ihdr(11)
+  real*4 s(NSMAX)
+  integer*2 id2
+  character*80 arg,infile
+  common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat,       &
+       ntr,mousefqso,newdat,nfa,nfb,ntol,kin,nzhsym,nsynced,ndecoded
+  common/tracer/limtrace,lu
+
+  nargs=iargc()
+  if(nargs.lt.1) then
+     print*,'Usage: jt9 TRperiod ndepth rxfreq file1 [file2 ...]'
+     print*,'       Reads data from *.wav files.'
+     print*,''
+     print*,'       jt9 -s <key>'
+     print*,'       Gets data from shared memory region with key==<key>'
+     go to 999
+  endif
+  call getarg(1,arg)
+  if(arg(1:2).eq.'-s') then
+! Multiple instances:
+     call getarg(2,arg)
+     i0=len(trim(arg))
+     call jt9a(trim(arg))
+     go to 999
+  endif
+  read(arg,*) ntrperiod
+  call getarg(2,arg)
+  read(arg,*) ndepth
+  call getarg(3,arg)
+  read(arg,*) nrxfreq
+  ifile1=4
+
+  limtrace=0
+  lu=12
+
+  do ifile=ifile1,nargs
+     call getarg(ifile,infile)
+     open(10,file=infile,access='stream',status='old',err=998)
+     read(10) ihdr
+     nutc0=ihdr(1)                           !Silence compiler warning
+     i1=index(infile,'.wav')
+     read(infile(i1-4:i1-1),*,err=1) nutc0
+     go to 2
+1    nutc0=0
+2    nsps=0
+     if(ntrperiod.eq.1)  then
+        nsps=6912
+        nzhsym=173
+     else if(ntrperiod.eq.2)  then
+        nsps=15360
+        nzhsym=178
+     else if(ntrperiod.eq.5)  then
+        nsps=40960
+        nzhsym=172
+     else if(ntrperiod.eq.10) then
+        nsps=82944
+        nzhsym=171
+     else if(ntrperiod.eq.30) then
+        nsps=252000
+        nzhsym=167
+     endif
+     if(nsps.eq.0) stop 'Error: bad TRperiod'
+
+     kstep=nsps/2
+     k=0
+     nhsym0=-999
+     npts=(60*ntrperiod-6)*12000
+     if(ifile.eq.ifile1) then
+        open(12,file='timer.out',status='unknown')
+        call timer('jt9     ',0)
+     endif
+
+     id2=0                               !??? Why is this necessary ???
+
+     do iblk=1,npts/kstep
+        k=iblk*kstep
+        call timer('read_wav',0)
+        read(10,end=10) id2(k-kstep+1:k)
+        call timer('read_wav',1)
+
+        nhsym=(k-2048)/kstep
+        if(nhsym.ge.1 .and. nhsym.ne.nhsym0) then
+! Emit signal readyForFFT
+           ingain=0
+           call timer('symspec ',0)
+           call symspec(k,ntrperiod,nsps,ingain,slope,pxdb,s,df3,ihsym,npts8)
+           call timer('symspec ',1)
+           nhsym0=nhsym
+           if(ihsym.ge.173) go to 10
+        endif
+     enddo
+
+10   close(10)
+     call fillcom(nutc0,ndepth,nrxfreq)
+     call decoder(ss,id2)
+  enddo
+
+  call timer('jt9     ',1)
+  call timer('jt9     ',101)
+  go to 999
+
+998 print*,'Cannot open file:'
+  print*,infile
+
+999 end program jt9
diff --git a/lib/jt9a.f90 b/lib/jt9a.f90
new file mode 100644
index 0000000..113533c
--- /dev/null
+++ b/lib/jt9a.f90
@@ -0,0 +1,72 @@
+subroutine jt9a(thekey)
+
+  character(len=*), intent(in):: thekey
+
+! These routines connect the shared memory region to the decoder.
+  interface
+     function address_jt9()
+     integer*1, pointer :: address_jt9
+     end function address_jt9
+  end interface
+  
+  integer*1 attach_jt9
+!  integer*1 lock_jt9,unlock_jt9
+  integer size_jt9
+  integer*1, pointer :: p_jt9
+  character*80 cwd
+! Multiple instances:
+  character*80 mykey
+  logical fileExists
+  common/tracer/limtrace,lu
+
+! Multiple instances:
+  i0 = len(trim(thekey))
+
+  call getcwd(cwd)
+  open(12,file='timer.out',status='unknown')
+
+  limtrace=0
+!  limtrace=-1                            !Disable all calls to timer()
+  lu=12
+
+! Multiple instances: set the shared memory key before attaching
+  mykey=trim(repeat(thekey,1))
+  i0 = len(mykey)
+  i0=setkey_jt9(trim(mykey))
+
+  i1=attach_jt9()
+
+10 inquire(file=trim(cwd)//'/.lock',exist=fileExists)
+  if(fileExists) then
+     call sleep_msec(100)
+     go to 10
+  endif
+
+  inquire(file=trim(cwd)//'/.quit',exist=fileExists)
+  if(fileExists) then
+!     call ftnquit
+     i1=detach_jt9()
+     go to 999
+  endif
+  if(i1.eq.999999) stop                  !Silence compiler warning
+  
+  nbytes=size_jt9()
+  if(nbytes.le.0) then
+     print*,'jt9a: Shared memory mem_jt9 does not exist.' 
+     print*,"Must start 'jt9 -s <thekey>' from within WSJT-X."
+     go to 999
+  endif
+  p_jt9=>address_jt9()
+  call timer('jt9b    ',0)
+  call jt9b(p_jt9,nbytes)
+  call timer('jt9b    ',1)
+
+100 inquire(file=trim(cwd)//'/.lock',exist=fileExists)
+  if(fileExists) go to 10
+  call sleep_msec(100)
+  go to 100
+
+999 call timer('jt9b    ',101)
+
+  return
+end subroutine jt9a
diff --git a/lib/jt9b.f90 b/lib/jt9b.f90
new file mode 100644
index 0000000..63de536
--- /dev/null
+++ b/lib/jt9b.f90
@@ -0,0 +1,12 @@
+subroutine jt9b(jt9com,nbytes)
+
+  include 'constants.f90'
+  integer*1 jt9com(0:nbytes-1)
+  kss=0
+  ksavg=kss + 4*184*NSMAX
+  kid2=ksavg + 4*NSMAX
+  knutc=kid2 + 2*NTMAX*12000
+  call jt9c(jt9com(kss),jt9com(ksavg),jt9com(kid2),jt9com(knutc))
+
+  return
+end subroutine jt9b
diff --git a/lib/jt9c.f90 b/lib/jt9c.f90
new file mode 100644
index 0000000..57b3cb2
--- /dev/null
+++ b/lib/jt9c.f90
@@ -0,0 +1,21 @@
+subroutine jt9c(ss,savg,id2,nparams0)
+
+  include 'constants.f90'
+  real*4 ss(184*NSMAX),savg(NSMAX)
+  integer*2 id2(NTMAX*12000)
+
+  integer nparams0(21),nparams(21)
+  character*20 datetime
+  common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol,  &
+       kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,datetime
+  equivalence (nparams,nutc)
+
+  nutc=id2(1)+int(savg(1))             !Silence compiler warning
+  nparams=nparams0                     !Copy parameters into common/npar/
+
+  call flush(6)
+!  if(sum(nparams).ne.0) call decoder(ss,id2)
+  call decoder(ss,id2)
+
+  return
+end subroutine jt9c
diff --git a/lib/jt9code.f90 b/lib/jt9code.f90
new file mode 100644
index 0000000..a4f0d3e
--- /dev/null
+++ b/lib/jt9code.f90
@@ -0,0 +1,29 @@
+program jt9code
+
+! Generate simulated data for testing of WSJT-X
+
+  character msg*22,msg0*22,decoded*22
+  integer*4 i4tone(85)                     !Channel symbols (values 0-8)
+  include 'jt9sync.f90'
+
+  nargs=iargc()
+  if(nargs.ne.1) then
+     print*,'Usage: jt9code "message"'
+     go to 999
+  endif
+
+  call getarg(1,msg0)
+  write(*,1000) msg0
+1000 format('Message:',3x,a22)
+  msg=msg0
+  ichk=0
+  itext=0
+  call genjt9(msg,ichk,decoded,i4tone,itext)       !Encode message into tone #s
+  write(*,1002) i4tone
+1002 format('Channel symbols:'/(30i2))
+  if(itext.eq.0) write(*,1004) decoded
+1004 format('Decoded message:',1x,a22)
+  if(itext.ne.0) write(*,1005) decoded
+1005 format('Decoded message:',1x,a22,3x,'(free text)')
+
+999 end program jt9code
diff --git a/lib/jt9sim.f90 b/lib/jt9sim.f90
new file mode 100644
index 0000000..f4f0cf6
--- /dev/null
+++ b/lib/jt9sim.f90
@@ -0,0 +1,166 @@
+program jt9sim
+
+! Generate simulated data for testing of WSJT-X
+
+  parameter (NTMAX=120)
+  parameter (NMAX=NTMAX*12000)
+  integer ihdr(11)
+  integer*2 iwave                  !Generated waveform (no noise)
+  real*8 f0,f,dt,twopi,phi,dphi,baud,fspan,fsample,freq
+  character msg*22,msg0*22,message*22,msgsent*22,arg*8,fname*11
+
+  integer*4 i4tone(85)             !Channel symbols (values 0-8)
+  integer*4 i4DataSymNoGray(69)    !Data Symbols, values 0-7
+  integer*1 i1ScrambledBits(207)   !Unpacked bits, scrambled order
+  integer*1 i1Bits(207)            !Encoded information-carrying bits
+  integer*1 i1SoftSymbols(207)
+  include 'jt9sync.f90'
+  common/acom/dat(NMAX),iwave(NMAX)
+
+  nargs=iargc()
+  if(nargs.ne.6) then
+     print*,'Usage: jt9sim "message" fspan nsigs minutes SNR nfiles'
+     print*,'Example:  "CQ K1ABC FN42" 200  20      2    -28    1'
+     print*,' '
+     print*,'Enter message = "" to use entries in msgs.txt.'
+     print*,'Enter SNR = 0 to generate a range of SNRs.'
+     go to 999
+  endif
+
+  call getarg(1,msg0)
+  message=msg0                       !Transmitted message
+  call getarg(2,arg)
+  read(arg,*) fspan                  !Total freq range (Hz)
+  call getarg(3,arg)
+  read(arg,*) nsigs                  !Number of signals in each file
+  call getarg(4,arg)
+  read(arg,*) minutes                !Length of file (1 2 5 10 30 minutes)
+  call getarg(5,arg)
+  read(arg,*) snrdb                  !S/N in dB (2500 hz reference BW)
+  call getarg(6,arg)
+  read(arg,*) nfiles                 !Number of files
+
+  rmsdb=25.
+  rms=10.0**(0.05*rmsdb)
+  fsample=12000.d0                   !Sample rate (Hz)
+  dt=1.d0/fsample                    !Sample interval (s)
+  twopi=8.d0*atan(1.d0)
+  npts=12000*(60*minutes-6)
+  nsps=0
+  if(minutes.eq.1)  nsps=6912
+  if(minutes.eq.2)  nsps=15360
+  if(minutes.eq.5)  nsps=40960
+  if(minutes.eq.10) nsps=82944
+  if(minutes.eq.30) nsps=252000
+  if(nsps.eq.0) stop 'Bad value for minutes.'
+
+  f0=1400.d0                         !Center frequency (Hz)
+!  f0=1500.0
+!  if(minutes.eq.5)  f0=1100.
+!  if(minutes.eq.10) f0=1050.
+!  if(minutes.eq.30) f0=1025.
+  
+  ihdr=0                             !Temporary ###
+  k=0                                !Silence compiler warning
+
+  if(msg0(1:3).eq.'sin') read(msg0(4:),*) sinfreq
+  
+  open(12,file='msgs.txt',status='old')
+
+  write(*,1000)
+1000 format('File  N    freq      S/N  Message'/    &
+            '---------------------------------------------------')
+
+  do ifile=1,nfiles                            !Loop over all files
+     nmin=(ifile-1)*minutes
+     ihr=nmin/60
+     imin=mod(nmin,60)
+     write(fname,1002) ihr,imin                !Create output filename
+1002 format('000000_',2i2.2)
+     open(10,file=fname//'.wav',access='stream',status='unknown')
+
+     if(snrdb.lt.90) then
+        do i=1,npts
+           dat(i)=gran()
+        enddo
+     else
+        dat(1:npts)=0.
+     endif
+
+     if(msg0.ne.'                      ') then
+        call genjt9(message,msgsent,i4tone) !Encode message into tone #s
+     endif
+
+     rewind 12
+     do isig=1,nsigs                            !Loop over multiple signals
+
+        if(msg0.eq.'                      ') then
+           read(12,1004) message                !Use pre-generated message texts
+1004       format(a22)
+           call genjt9(message,msgsent,i4tone)
+        endif
+
+        f=f0
+        if(nsigs.gt.1) f=f0 - 0.5d0*fspan + fspan*(isig-1.d0)/(nsigs-1.d0)
+        snrdbx=snrdb 
+!        snrdbx=snrdb + (ifile-1)*4.0
+        sig=10.0**(0.05*snrdbx)
+        write(*,1020) ifile,isig,f,snrdbx,msgsent
+1020    format(i3,i4,f10.3,f7.1,2x,a22)
+
+        phi=0.
+        baud=12000.d0/nsps
+        k=12000                             !Start audio at t = 1.0 s
+!        f1=0.0001 * (ifile-1)
+        f1=0.
+!        print*,ifile-1,f1
+        dphi2=0.
+        ddphi2=twopi*f1*dt/60.0
+        do isym=1,85
+           freq=f + i4tone(isym)*baud
+           if(msg0(1:3).eq.'sin') freq=sinfreq
+           dphi=twopi*freq*dt + dphi2
+           do i=1,nsps
+              phi=phi + dphi
+              dphi2=dphi2 + ddphi2
+              if(phi.lt.-twopi) phi=phi+twopi
+              if(phi.gt.twopi) phi=phi-twopi
+              xphi=phi
+              k=k+1
+              dat(k)=dat(k) + sig*sin(xphi)  !Use lookup table for i*2 sin(x) ?
+           enddo
+        enddo
+     enddo
+
+     do i=1,npts
+        iwave(i)=nint(rms*dat(i))
+     enddo
+
+     write(10) ihdr,iwave(1:npts)
+     close(10)
+
+! We're done!  Now decode the data symbols from i4tone, as a test.
+     if(msg0.ne.'                      ') then
+        j=0
+        do i=1,85
+           if(isync(i).eq.1) cycle
+           j=j+1
+           i4DataSymNoGray(j)=igray(i4tone(i)-1,-1)
+        enddo
+        call unpackbits(i4DataSymNoGray,69,3,i1ScrambledBits)
+        call interleave9(i1ScrambledBits,-1,i1Bits)
+ 
+        do i=1,206
+           i4=-10
+           if(i1Bits(i).eq.1) i4=10
+           i4=i4+128
+           if(i4.le.127) i1SoftSymbols(k)=i4
+           if(i4.ge.128) i1SoftSymbols(k)=i4-256
+        enddo
+        limit=1000
+        call decode9(i1SoftSymbols,limit,nlim,msg)
+        if(msg.ne.msg0) print*,'Decode error: ',msg0,' ',msg
+     endif
+  enddo
+
+999 end program jt9sim
diff --git a/lib/jt9sync.f90 b/lib/jt9sync.f90
new file mode 100644
index 0000000..a8e3368
--- /dev/null
+++ b/lib/jt9sync.f90
@@ -0,0 +1,18 @@
+  integer ii(16)                       !Locations of sync symbols
+  data ii/ 1,2,5,10,16,23,33,35,51,52,55,60,66,73,83,85/
+
+  integer ii2(16)                      !Locations of sync half-symbols
+  data ii2/1,3,9,19,31,45,65,69,101,103,109,119,131,145,165,169/
+
+  integer ka(16),kb(16)                !Reference symbols for sync
+  data ka/5,5,11,21,33,47,63,71,97,105,111,121,133,147,159,163/
+  data kb/7,7,13,23,35,49,67,73,99,107,113,123,135,149,161,167/
+
+
+  integer isync(85)                    !Sync vector
+  data isync/                                     &
+       1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,   &
+       0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,   &
+       0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,1,   &
+       0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,   &
+       0,0,1,0,1/
diff --git a/lib/k2grid.f90 b/lib/k2grid.f90
new file mode 100644
index 0000000..aa76315
--- /dev/null
+++ b/lib/k2grid.f90
@@ -0,0 +1,12 @@
+subroutine k2grid(k,grid)
+  character grid*6
+
+  nlong=2*mod((k-1)/5,90)-179
+  if(k.gt.450) nlong=nlong+180
+  nlat=mod(k-1,5)+ 85
+  dlat=nlat
+  dlong=nlong
+  call deg2grid(dlong,dlat,grid)
+
+  return
+end subroutine k2grid
diff --git a/lib/libhamlib.dll.a b/lib/libhamlib.dll.a
new file mode 100644
index 0000000..7bb6d1b
Binary files /dev/null and b/lib/libhamlib.dll.a differ
diff --git a/lib/met8.21 b/lib/met8.21
new file mode 100644
index 0000000..a5d3006
--- /dev/null
+++ b/lib/met8.21
@@ -0,0 +1,256 @@
+  -25.6   1.000  -9.966 1.000000 0.000000
+  -25.4   1.000  -9.966 1.000000 0.000000
+  -25.2   1.000  -9.966 1.000000 0.000000
+  -25.0   1.000  -9.966 1.000000 0.000000
+  -24.8   1.000  -9.966 1.000000 0.000000
+  -24.6   1.000  -9.966 1.000000 0.000000
+  -24.4   1.000  -9.966 1.000000 0.000000
+  -24.2   1.000  -9.966 1.000000 0.000000
+  -24.0   1.000  -9.966 1.000000 0.000000
+  -23.8   1.000  -9.966 1.000000 0.000000
+  -23.6   1.000  -9.966 1.000000 0.000000
+  -23.4   1.000  -9.966 1.000000 0.000000
+  -23.2   1.000  -9.966 1.000000 0.000000
+  -23.0   1.000  -9.966 1.000000 0.000000
+  -22.8   1.000  -9.966 1.000000 0.000000
+  -22.6   1.000  -9.966 1.000000 0.000000
+  -22.4   1.000  -9.966 1.000000 0.000000
+  -22.2   1.000  -9.966 1.000000 0.000000
+  -22.0   1.000  -9.966 1.000000 0.000000
+  -21.8   1.000  -9.966 1.000000 0.000000
+  -21.6   1.000  -9.966 1.000000 0.000000
+  -21.4   1.000  -9.966 1.000000 0.000000
+  -21.2   1.000  -9.966 1.000000 0.000000
+  -21.0   1.000  -9.966 1.000000 0.000000
+  -20.8   1.000  -9.966 1.000000 0.000000
+  -20.6   1.000  -9.966 1.000000 0.000000
+  -20.4   1.000  -9.966 1.000000 0.000000
+  -20.2   1.000  -9.966 1.000000 0.000000
+  -20.0   1.000  -9.966 1.000000 0.000000
+  -19.8   1.000  -9.966 1.000000 0.000000
+  -19.6   1.000  -9.966 1.000000 0.000000
+  -19.4   1.000  -9.966 1.000000 0.000000
+  -19.2   1.000  -9.966 1.000000 0.000000
+  -19.0   1.000  -9.966 1.000000 0.000000
+  -18.8   1.000  -9.966 1.000000 0.000000
+  -18.6   1.000  -9.966 1.000000 0.000000
+  -18.4   1.000  -9.966 1.000000 0.000000
+  -18.2   1.000  -9.966 1.000000 0.000000
+  -18.0   1.000  -9.966 1.000000 0.000000
+  -17.8   1.000  -9.966 1.000000 0.000000
+  -17.6   1.000  -9.966 1.000000 0.000000
+  -17.4   1.000  -9.966 1.000000 0.000000
+  -17.2   1.000  -9.966 1.000000 0.000000
+  -17.0   1.000  -9.966 1.000000 0.000000
+  -16.8   1.000  -9.966 1.000000 0.000000
+  -16.6   1.000  -9.966 1.000000 0.000000
+  -16.4   1.000  -9.966 1.000000 0.000000
+  -16.2   1.000  -9.966 1.000000 0.000000
+  -16.0   0.988  -5.858 0.991379 0.008621
+  -15.8   1.000  -9.966 1.000000 0.000000
+  -15.6   0.991  -6.313 0.993711 0.006289
+  -15.4   0.993  -6.629 0.994950 0.005051
+  -15.2   1.000  -9.966 1.000000 0.000000
+  -15.0   0.995  -7.055 0.996241 0.003759
+  -14.8   1.000  -9.966 1.000000 0.000000
+  -14.6   0.991  -6.371 0.993958 0.006042
+  -14.4   1.000  -9.966 1.000000 0.000000
+  -14.2   0.991  -6.313 0.993711 0.006289
+  -14.0   0.992  -6.426 0.994186 0.005814
+  -13.8   0.991  -6.288 0.993600 0.006400
+  -13.6   0.990  -6.113 0.992775 0.007225
+  -13.4   0.990  -6.152 0.992968 0.007032
+  -13.2   0.992  -6.534 0.994606 0.005394
+  -13.0   0.996  -7.332 0.996898 0.003102
+  -12.8   0.990  -6.184 0.993121 0.006879
+  -12.6   0.994  -7.016 0.996136 0.003864
+  -12.4   0.993  -6.658 0.995049 0.004950
+  -12.2   0.991  -6.369 0.993953 0.006047
+  -12.0   0.992  -6.559 0.994699 0.005301
+  -11.8   0.989  -6.002 0.992197 0.007803
+  -11.6   0.991  -6.304 0.993671 0.006329
+  -11.4   0.987  -5.826 0.991188 0.008812
+  -11.2   0.985  -5.632 0.989919 0.010081
+  -11.0   0.989  -5.995 0.992162 0.007838
+  -10.8   0.984  -5.544 0.989284 0.010717
+  -10.6   0.983  -5.377 0.987966 0.012034
+  -10.4   0.979  -5.108 0.985502 0.014498
+  -10.2   0.977  -4.954 0.983869 0.016131
+  -10.0   0.971  -4.652 0.980118 0.019882
+   -9.8   0.975  -4.870 0.982896 0.017104
+   -9.6   0.974  -4.822 0.982324 0.017676
+   -9.4   0.970  -4.608 0.979490 0.020510
+   -9.2   0.970  -4.623 0.979702 0.020298
+   -9.0   0.970  -4.621 0.979679 0.020321
+   -8.8   0.967  -4.472 0.977465 0.022535
+   -8.6   0.962  -4.261 0.973915 0.026085
+   -8.4   0.960  -4.186 0.972538 0.027462
+   -8.2   0.957  -4.098 0.970806 0.029194
+   -8.0   0.956  -4.062 0.970061 0.029939
+   -7.8   0.953  -3.975 0.968209 0.031791
+   -7.6   0.942  -3.677 0.960918 0.039082
+   -7.4   0.946  -3.768 0.963301 0.036699
+   -7.2   0.937  -3.550 0.957308 0.042692
+   -7.0   0.933  -3.463 0.954652 0.045348
+   -6.8   0.929  -3.377 0.951866 0.048134
+   -6.6   0.920  -3.212 0.946042 0.053958
+   -6.4   0.917  -3.164 0.944202 0.055798
+   -6.2   0.911  -3.058 0.939981 0.060019
+   -6.0   0.903  -2.939 0.934818 0.065182
+   -5.8   0.895  -2.829 0.929642 0.070358
+   -5.6   0.884  -2.690 0.922540 0.077459
+   -5.4   0.877  -2.608 0.917972 0.082028
+   -5.2   0.869  -2.531 0.913509 0.086491
+   -5.0   0.858  -2.411 0.905967 0.094033
+   -4.8   0.846  -2.301 0.898525 0.101475
+   -4.6   0.834  -2.201 0.891269 0.108731
+   -4.4   0.821  -2.096 0.883085 0.116915
+   -4.2   0.806  -1.992 0.874340 0.125660
+   -4.0   0.790  -1.882 0.864307 0.135693
+   -3.8   0.775  -1.790 0.855445 0.144555
+   -3.6   0.755  -1.678 0.843726 0.156274
+   -3.4   0.737  -1.587 0.833538 0.166462
+   -3.2   0.713  -1.473 0.819841 0.180159
+   -3.0   0.691  -1.376 0.807345 0.192655
+   -2.8   0.667  -1.280 0.794093 0.205907
+   -2.6   0.640  -1.181 0.779404 0.220596
+   -2.4   0.612  -1.084 0.764178 0.235822
+   -2.2   0.581  -0.987 0.747708 0.252292
+   -2.0   0.548  -0.895 0.731037 0.268963
+   -1.8   0.510  -0.796 0.712035 0.287965
+   -1.6   0.472  -0.706 0.693474 0.306526
+   -1.4   0.425  -0.606 0.671514 0.328486
+   -1.2   0.378  -0.514 0.649948 0.350053
+   -1.0   0.328  -0.425 0.627452 0.372548
+   -0.8   0.274  -0.338 0.604549 0.395451
+   -0.6   0.212  -0.249 0.579151 0.420849
+   -0.4   0.146  -0.163 0.553389 0.446611
+   -0.2   0.075  -0.079 0.526648 0.473352
+    0.0   0.000   0.000 0.500000 0.500000
+    0.2  -0.079   0.075 0.473352 0.526648
+    0.4  -0.163   0.146 0.446611 0.553389
+    0.6  -0.249   0.212 0.420849 0.579151
+    0.8  -0.338   0.274 0.395451 0.604549
+    1.0  -0.425   0.328 0.372548 0.627452
+    1.2  -0.514   0.378 0.350053 0.649948
+    1.4  -0.606   0.425 0.328486 0.671514
+    1.6  -0.706   0.472 0.306526 0.693474
+    1.8  -0.796   0.510 0.287965 0.712035
+    2.0  -0.895   0.548 0.268963 0.731037
+    2.2  -0.987   0.581 0.252292 0.747708
+    2.4  -1.084   0.612 0.235822 0.764178
+    2.6  -1.181   0.640 0.220596 0.779404
+    2.8  -1.280   0.667 0.205907 0.794093
+    3.0  -1.376   0.691 0.192655 0.807345
+    3.2  -1.473   0.713 0.180159 0.819841
+    3.4  -1.587   0.737 0.166462 0.833538
+    3.6  -1.678   0.755 0.156274 0.843726
+    3.8  -1.790   0.775 0.144555 0.855445
+    4.0  -1.882   0.790 0.135693 0.864307
+    4.2  -1.992   0.806 0.125660 0.874340
+    4.4  -2.096   0.821 0.116915 0.883085
+    4.6  -2.201   0.834 0.108731 0.891269
+    4.8  -2.301   0.846 0.101475 0.898525
+    5.0  -2.411   0.858 0.094033 0.905967
+    5.2  -2.531   0.869 0.086491 0.913509
+    5.4  -2.608   0.877 0.082028 0.917972
+    5.6  -2.690   0.884 0.077459 0.922540
+    5.8  -2.829   0.895 0.070358 0.929642
+    6.0  -2.939   0.903 0.065182 0.934818
+    6.2  -3.058   0.911 0.060019 0.939981
+    6.4  -3.164   0.917 0.055798 0.944202
+    6.6  -3.212   0.920 0.053958 0.946042
+    6.8  -3.377   0.929 0.048134 0.951866
+    7.0  -3.463   0.933 0.045348 0.954652
+    7.2  -3.550   0.937 0.042692 0.957308
+    7.4  -3.768   0.946 0.036699 0.963301
+    7.6  -3.677   0.942 0.039082 0.960918
+    7.8  -3.975   0.953 0.031791 0.968210
+    8.0  -4.062   0.956 0.029939 0.970061
+    8.2  -4.098   0.957 0.029194 0.970806
+    8.4  -4.186   0.960 0.027462 0.972538
+    8.6  -4.261   0.962 0.026085 0.973915
+    8.8  -4.472   0.967 0.022535 0.977465
+    9.0  -4.621   0.970 0.020321 0.979679
+    9.2  -4.623   0.970 0.020298 0.979702
+    9.4  -4.608   0.970 0.020510 0.979490
+    9.6  -4.822   0.974 0.017676 0.982324
+    9.8  -4.870   0.975 0.017104 0.982896
+   10.0  -4.652   0.971 0.019882 0.980118
+   10.2  -4.954   0.977 0.016131 0.983869
+   10.4  -5.108   0.979 0.014498 0.985502
+   10.6  -5.377   0.983 0.012034 0.987966
+   10.8  -5.544   0.984 0.010717 0.989284
+   11.0  -5.995   0.989 0.007838 0.992162
+   11.2  -5.632   0.985 0.010081 0.989919
+   11.4  -5.826   0.987 0.008812 0.991188
+   11.6  -6.304   0.991 0.006329 0.993671
+   11.8  -6.002   0.989 0.007803 0.992197
+   12.0  -6.559   0.992 0.005301 0.994699
+   12.2  -6.369   0.991 0.006047 0.993953
+   12.4  -6.658   0.993 0.004950 0.995049
+   12.6  -7.016   0.994 0.003864 0.996136
+   12.8  -6.184   0.990 0.006879 0.993121
+   13.0  -7.332   0.996 0.003102 0.996898
+   13.2  -6.534   0.992 0.005394 0.994606
+   13.4  -6.152   0.990 0.007032 0.992968
+   13.6  -6.113   0.990 0.007225 0.992775
+   13.8  -6.288   0.991 0.006400 0.993600
+   14.0  -6.426   0.992 0.005814 0.994186
+   14.2  -6.313   0.991 0.006289 0.993711
+   14.4  -9.966   1.000 0.000000 1.000000
+   14.6  -6.371   0.991 0.006042 0.993958
+   14.8  -9.966   1.000 0.000000 1.000000
+   15.0  -7.055   0.995 0.003759 0.996241
+   15.2  -9.966   1.000 0.000000 1.000000
+   15.4  -6.629   0.993 0.005051 0.994949
+   15.6  -6.313   0.991 0.006289 0.993711
+   15.8  -9.966   1.000 0.000000 1.000000
+   16.0  -5.858   0.988 0.008621 0.991379
+   16.2  -9.966   1.000 0.000000 1.000000
+   16.4  -9.966   1.000 0.000000 1.000000
+   16.6  -9.966   1.000 0.000000 1.000000
+   16.8  -9.966   1.000 0.000000 1.000000
+   17.0  -9.966   1.000 0.000000 1.000000
+   17.2  -9.966   1.000 0.000000 1.000000
+   17.4  -9.966   1.000 0.000000 1.000000
+   17.6  -9.966   1.000 0.000000 1.000000
+   17.8  -9.966   1.000 0.000000 1.000000
+   18.0  -9.966   1.000 0.000000 1.000000
+   18.2  -9.966   1.000 0.000000 1.000000
+   18.4  -9.966   1.000 0.000000 1.000000
+   18.6  -9.966   1.000 0.000000 1.000000
+   18.8  -9.966   1.000 0.000000 1.000000
+   19.0  -9.966   1.000 0.000000 1.000000
+   19.2  -9.966   1.000 0.000000 1.000000
+   19.4  -9.966   1.000 0.000000 1.000000
+   19.6  -9.966   1.000 0.000000 1.000000
+   19.8  -9.966   1.000 0.000000 1.000000
+   20.0  -9.966   1.000 0.000000 1.000000
+   20.2  -9.966   1.000 0.000000 1.000000
+   20.4  -9.966   1.000 0.000000 1.000000
+   20.6  -9.966   1.000 0.000000 1.000000
+   20.8  -9.966   1.000 0.000000 1.000000
+   21.0  -9.966   1.000 0.000000 1.000000
+   21.2  -9.966   1.000 0.000000 1.000000
+   21.4  -9.966   1.000 0.000000 1.000000
+   21.6  -9.966   1.000 0.000000 1.000000
+   21.8  -9.966   1.000 0.000000 1.000000
+   22.0  -9.966   1.000 0.000000 1.000000
+   22.2  -9.966   1.000 0.000000 1.000000
+   22.4  -9.966   1.000 0.000000 1.000000
+   22.6  -9.966   1.000 0.000000 1.000000
+   22.8  -9.966   1.000 0.000000 1.000000
+   23.0  -9.966   1.000 0.000000 1.000000
+   23.2  -9.966   1.000 0.000000 1.000000
+   23.4  -9.966   1.000 0.000000 1.000000
+   23.6  -9.966   1.000 0.000000 1.000000
+   23.8  -9.966   1.000 0.000000 1.000000
+   24.0  -9.966   1.000 0.000000 1.000000
+   24.2  -9.966   1.000 0.000000 1.000000
+   24.4  -9.966   1.000 0.000000 1.000000
+   24.6  -9.966   1.000 0.000000 1.000000
+   24.8  -9.966   1.000 0.000000 1.000000
+   25.0  -9.966   1.000 0.000000 1.000000
+   25.2  -9.966   1.000 0.000000 1.000000
+   25.4  -9.966   1.000 0.000000 1.000000
diff --git a/lib/morse.f90 b/lib/morse.f90
new file mode 100644
index 0000000..de5f7a1
--- /dev/null
+++ b/lib/morse.f90
@@ -0,0 +1,86 @@
+subroutine morse(msg,idat,n)
+
+! Convert ascii message to a Morse code bit string.
+!    Dash = 3 dots
+!    Space between dots, dashes = 1 dot
+!    Space between letters = 3 dots
+!    Space between words = 7 dots
+
+  character*(*) msg
+  integer idat(250)
+  integer*1 ic(21,38)
+  data ic/                                        &
+     1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,20,  &
+     1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,18,  &
+     1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,16,  &
+     1,0,1,0,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,14,  &
+     1,0,1,0,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,12,  &
+     1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10,  &
+     1,1,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,12,  &
+     1,1,1,0,1,1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,14,  &
+     1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,0,0,0,0,16,  &
+     1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,0,0,18,  &
+     1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 6,  &
+     1,1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10,  &
+     1,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,12,  &
+     1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8,  &
+     1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2,  &
+     1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10,  &
+     1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10,  &
+     1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8,  &
+     1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 4,  &
+     1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,14,  &
+     1,1,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,10,  &
+     1,0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,10,  &
+     1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8,  &
+     1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 6,  &
+     1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,12,  &
+     1,0,1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,12,  &
+     1,1,1,0,1,1,1,0,1,0,1,1,1,0,0,0,0,0,0,0,14,  &
+     1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8,  &
+     1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 6,  &
+     1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 4,  &
+     1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 8,  &
+     1,0,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,10,  &
+     1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,10,  &
+     1,1,1,0,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,12,  &
+     1,1,1,0,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,14,  &
+     1,1,1,0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,12,  &
+     1,1,1,0,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,14,  &
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 2/     !Incremental word space
+  save
+
+  msglen=len(msg)
+  idat=0
+  n=6
+  do k=1,msglen
+     jj=ichar(msg(k:k))
+     if(jj.ge.97 .and. jj.le.122) jj=jj-32  !Convert lower to upper case
+     if(jj.ge.48 .and. jj.le.57) j=jj-48    !Numbers
+     if(jj.ge.65 .and. jj.le.90) j=jj-55    !Letters
+     if(jj.eq.47) j=36                      !Slash (/)
+     if(jj.eq.32) j=37                      !Word space
+     j=j+1
+
+! Insert this character
+     nmax=ic(21,j)
+     do i=1,nmax
+        n=n+1
+        idat(n)=ic(i,j)
+     enddo
+
+! Insert character space of 2 dit lengths:
+     n=n+1
+     idat(n)=0
+     n=n+1
+     idat(n)=0
+  enddo
+
+! Insert word space at end of message
+  do j=1,4
+     n=n+1
+     idat(n)=0
+  enddo
+
+  return
+end subroutine morse
diff --git a/lib/move.f90 b/lib/move.f90
new file mode 100644
index 0000000..13783dc
--- /dev/null
+++ b/lib/move.f90
@@ -0,0 +1,7 @@
+subroutine move(x,y,n)
+  real x(n),y(n)
+  do i=1,n
+     y(i)=x(i)
+  enddo
+  return
+end subroutine move
diff --git a/lib/msgs.txt b/lib/msgs.txt
new file mode 100644
index 0000000..c38aba9
--- /dev/null
+++ b/lib/msgs.txt
@@ -0,0 +1,60 @@
+W1AAA K2BBB EM00
+W2CCC K3DDD EM01
+W3EEE K4FFF EM02
+W5GGG K6HHH EM03
+W7III K8JJJ EM04
+W9KKK K0LLL EM05
+G0MMM F1NNN JN06
+G2OOO F3PPP JN07
+G4QQQ F5RRR JN08
+G6SSS F7TTT JN09
+W1XAA K2XBB EM10
+W2XCC K3XDD EM11
+W3XEE K4XFF EM12
+W5XGG K6XHH EM13
+W7XII K8XJJ EM14
+W9XKK K0XLL EM15
+G0XMM F1XNN JN16
+G2XOO F3XPP JN17
+G4XQQ F5XRR JN18
+G6XSS F7XTT JN19
+W1YAA K2YBB EM20
+W2YCC K3YDD EM21
+W3YEE K4YFF EM22
+W5YGG K6YHH EM23
+W7YII K8YJJ EM24
+W9YKK K0YLL EM25
+G0YMM F1YNN JN26
+G2YOO F3YPP JN27
+G4YQQ F5YRR JN28
+G6YSS F7YTT JN29
+W1ZAA K2ZBB EM30
+W2ZCC K3ZDD EM31
+W3ZEE K4ZFF EM32
+W5ZGG K6ZHH EM33
+W7ZII K8ZJJ EM34
+W9ZKK K0ZLL EM35
+G0ZMM F1ZNN JN36
+G2ZOO F3ZPP JN37
+G4ZQQ F5ZRR JN38
+G6ZSS F7ZTT JN39
+W1AXA K2BXB EM40
+W2CXC K3DXD EM41
+W3EXE K4FXF EM42
+W5GXG K6HXH EM43
+W7IXI K8JXJ EM44
+W9KXK K0LXL EM45
+G0MXM F1NXN JN46
+G2OXO F3PXP JN47
+G4QXQ F5RXR JN48
+G6SXS F7TXT JN49
+W1AYA K2BYB EM50
+W2CYC K3DYD EM51
+W3EYE K4FYF EM52
+W5GYG K6HYH EM53
+W7IYI K8JYJ EM54
+W9KYK K0LYL EM55
+G0MYM F1NYN JN56
+G2OYO F3PYP JN57
+G4QYQ F5RYR JN58
+G6SYS F7TYT JN59
diff --git a/lib/n2grid.f90 b/lib/n2grid.f90
new file mode 100644
index 0000000..ed22a7d
--- /dev/null
+++ b/lib/n2grid.f90
@@ -0,0 +1,14 @@
+subroutine n2grid(n,grid)
+  character*4 grid
+
+  if(n.gt.-31 .or. n.lt.-70) stop 'Error in n2grid'
+  i=-(n+31)                           !NB: 0 <= i <= 39
+  i1=i/10
+  i2=mod(i,10)
+  grid(1:1)=char(ichar('A')+i1)
+  grid(2:2)='A'
+  grid(3:3)=char(ichar('0')+i2)
+  grid(4:4)='0'
+
+  return
+end subroutine n2grid
diff --git a/lib/nchar.f90 b/lib/nchar.f90
new file mode 100644
index 0000000..167992a
--- /dev/null
+++ b/lib/nchar.f90
@@ -0,0 +1,23 @@
+function nchar(c)
+
+! Convert ascii number, letter, or space to 0-36 for callsign packing.
+
+  character c*1
+
+  n=0                                    !Silence compiler warning
+  if(c.ge.'0' .and. c.le.'9') then
+     n=ichar(c)-ichar('0')
+  else if(c.ge.'A' .and. c.le.'Z') then
+     n=ichar(c)-ichar('A') + 10
+  else if(c.ge.'a' .and. c.le.'z') then
+     n=ichar(c)-ichar('a') + 10
+  else if(c.ge.' ') then
+     n=36
+  else
+     Print*,'Invalid character in callsign ',c,' ',ichar(c)
+     stop
+  endif
+  nchar=n
+
+  return
+end function nchar
diff --git a/lib/noisegen.f90 b/lib/noisegen.f90
new file mode 100644
index 0000000..f92a9df
--- /dev/null
+++ b/lib/noisegen.f90
@@ -0,0 +1,13 @@
+subroutine noisegen(d4,nmax)
+
+  real*4 d4(4,nmax)
+
+  do i=1,nmax
+     d4(1,i)=gran()
+     d4(2,i)=gran()
+     d4(3,i)=gran()
+     d4(4,i)=gran()
+  enddo
+
+  return
+end subroutine noisegen
diff --git a/lib/packbits.f90 b/lib/packbits.f90
new file mode 100644
index 0000000..8885186
--- /dev/null
+++ b/lib/packbits.f90
@@ -0,0 +1,21 @@
+subroutine packbits(dbits,nsymd,m0,sym)
+
+! Pack 0s and 1s from dbits() into sym() with m0 bits per word.
+! NB: nsymd is the number of packed output words.
+
+  integer sym(nsymd)
+  integer*1 dbits(*)
+
+  k=0
+  do i=1,nsymd
+     n=0
+     do j=1,m0
+        k=k+1
+        m=dbits(k)
+        n=ior(ishft(n,1),m)
+     enddo
+     sym(i)=n
+  enddo
+
+  return
+end subroutine packbits
diff --git a/lib/packcall.f90 b/lib/packcall.f90
new file mode 100644
index 0000000..c4de474
--- /dev/null
+++ b/lib/packcall.f90
@@ -0,0 +1,79 @@
+subroutine packcall(callsign,ncall,text)
+
+! Pack a valid callsign into a 28-bit integer.
+
+  parameter (NBASE=37*36*10*27*27*27)
+  character callsign*6,c*1,tmp*6
+  logical text
+
+  text=.false.
+
+! Work-around for Swaziland prefix:
+  if(callsign(1:4).eq.'3DA0') callsign='3D0'//callsign(5:6)
+
+  if(callsign(1:3).eq.'CQ ') then
+     ncall=NBASE + 1
+     if(callsign(4:4).ge.'0' .and. callsign(4:4).le.'9' .and.        &
+          callsign(5:5).ge.'0' .and. callsign(5:5).le.'9' .and.      &
+          callsign(6:6).ge.'0' .and. callsign(6:6).le.'9') then
+        read(callsign(4:6),*) nfreq
+        ncall=NBASE + 3 + nfreq
+     endif
+     return
+  else if(callsign(1:4).eq.'QRZ ') then
+     ncall=NBASE + 2
+     return
+  else if(callsign(1:3).eq.'DE ') then
+     ncall=267796945
+     return
+  endif
+
+  tmp='      '
+  if(callsign(3:3).ge.'0' .and. callsign(3:3).le.'9') then
+     tmp=callsign
+  else if(callsign(2:2).ge.'0' .and. callsign(2:2).le.'9') then
+     if(callsign(6:6).ne.' ') then
+        text=.true.
+        return
+     endif
+     tmp=' '//callsign(:5)
+  else
+     text=.true.
+     return
+  endif
+
+  do i=1,6
+     c=tmp(i:i)
+     if(c.ge.'a' .and. c.le.'z')                                &
+          tmp(i:i)=char(ichar(c)-ichar('a')+ichar('A'))
+  enddo
+
+  n1=0
+  if((tmp(1:1).ge.'A'.and.tmp(1:1).le.'Z').or.tmp(1:1).eq.' ') n1=1
+  if(tmp(1:1).ge.'0' .and. tmp(1:1).le.'9') n1=1
+  n2=0
+  if(tmp(2:2).ge.'A' .and. tmp(2:2).le.'Z') n2=1
+  if(tmp(2:2).ge.'0' .and. tmp(2:2).le.'9') n2=1
+  n3=0
+  if(tmp(3:3).ge.'0' .and. tmp(3:3).le.'9') n3=1
+  n4=0
+  if((tmp(4:4).ge.'A'.and.tmp(4:4).le.'Z').or.tmp(4:4).eq.' ') n4=1
+  n5=0
+  if((tmp(5:5).ge.'A'.and.tmp(5:5).le.'Z').or.tmp(5:5).eq.' ') n5=1
+  n6=0
+  if((tmp(6:6).ge.'A'.and.tmp(6:6).le.'Z').or.tmp(6:6).eq.' ') n6=1
+
+  if(n1+n2+n3+n4+n5+n6 .ne. 6) then
+     text=.true.
+     return 
+  endif
+
+  ncall=nchar(tmp(1:1))
+  ncall=36*ncall+nchar(tmp(2:2))
+  ncall=10*ncall+nchar(tmp(3:3))
+  ncall=27*ncall+nchar(tmp(4:4))-10
+  ncall=27*ncall+nchar(tmp(5:5))-10
+  ncall=27*ncall+nchar(tmp(6:6))-10
+
+  return
+end subroutine packcall
diff --git a/lib/packdxcc.f90 b/lib/packdxcc.f90
new file mode 100644
index 0000000..74f2789
--- /dev/null
+++ b/lib/packdxcc.f90
@@ -0,0 +1,64 @@
+subroutine packdxcc(c,ng,ldxcc)
+
+  character*3 c
+  logical ldxcc
+
+  parameter (NZ=303)
+  character*5 pfx(NZ)
+  data pfx/                                                             &
+       '1A   ','1S   ','3A   ','3B6  ','3B8  ','3B9  ','3C   ','3C0  ', &
+       '3D2  ',                '3DA  ','3V   ','3W   ','3X   ','3Y   ', &
+               '4J   ','4L   ','4S   ','4U1  ',                '4W   ', &
+       '4X   ','5A   ','5B   ','5H   ','5N   ','5R   ','5T   ','5U   ', &
+       '5V   ','5W   ','5X   ','5Z   ','6W   ','6Y   ','7O   ','7P   ', &
+       '7Q   ','7X   ','8P   ','8Q   ','8R   ','9A   ','9G   ','9H   ', &
+       '9J   ','9K   ','9L   ','9M2  ','9M6  ','9N   ','9Q   ','9U   ', &
+       '9V   ','9X   ','9Y   ','A2   ','A3   ','A4   ','A5   ','A6   ', &
+       'A7   ','A9   ','AP   ','BS7  ','BV   ','BV9  ','BY   ','C2   ', &
+       'C3   ','C5   ','C6   ','C9   ','CE   ','CE0  ',                 &
+       'CE9  ','CM   ','CN   ','CP   ','CT   ','CT3  ','CU   ','CX   ', &
+       'CY0  ','CY9  ','D2   ','D4   ','D6   ','DL   ','DU   ','E3   ', &
+       'E4   ','EA   ','EA6  ','EA8  ','EA9  ','EI   ','EK   ','EL   ', &
+       'EP   ','ER   ','ES   ','ET   ','EU   ','EX   ','EY   ','EZ   ', &
+       'F    ','FG   ','FH   ','FJ   ','FK   ',        'FM   ','FO   ', &
+                               'FP   ','FR   ',                         &
+       'FT5  ',                'FW   ','FY   ','M    ','MD   ','MI   ', &
+       'MJ   ','MM   ',        'MU   ','MW   ','H4   ','H40  ','HA   ', &
+       'HB   ','HB0  ','HC   ','HC8  ','HH   ','HI   ','HK   ','HK0  ', &
+               'HL   ','HM   ','HP   ','HR   ','HS   ','HV   ','HZ   ', &
+       'I    ','IG9  ','IS   ','IT9  ','J2   ','J3   ','J5   ','J6   ', &
+       'J7   ','J8   ','JA   ','JD   ',        'JT   ','JW   ',         &
+       'JX   ','JY   ','K    ','KG4  ','KH0  ','KH1  ','KH2  ','KH3  ', &
+       'KH4  ','KH5  ',        'KH6  ','KH7  ','KH8  ','KH9  ','KL   ', &
+       'KP1  ','KP2  ','KP4  ','KP5  ','LA   ','LU   ','LX   ','LY   ', &
+       'LZ   ','OA   ','OD   ','OE   ','OH   ','OH0  ','OJ0  ','OK   ', &
+       'OM   ','ON   ','OX   ','OY   ','OZ   ','P2   ','P4   ','PA   ', &
+       'PJ2  ','PJ7  ','PY   ','PY0  ',                'PZ   ','R1F  ', &
+       'R1M  ','S0   ','S2   ','S5   ','S7   ','S9   ','SM   ','SP   ', &
+       'ST   ','SU   ','SV   ',        'SV5  ','SV9  ','T2   ','T30  ', &
+       'T31  ','T32  ','T33  ','T5   ','T7   ','T8   ','T9   ','TA   ', &
+       'TA1  ','TF   ','TG   ','TI   ','TI9  ','TJ   ','TK   ','TL   ', &
+       'TN   ','TR   ','TT   ','TU   ','TY   ','TZ   ','UA   ','UA2  ', &
+       'UA9  ','UK   ','UN   ','UR   ','V2   ','V3   ','V4   ','V5   ', &
+       'V6   ','V7   ','V8   ','VE   ','VK   ','VK0  ',        'VK9  ', &
+                                               'VP2  ',                 &
+       'VP5  ','VP6  ',        'VP8  ',                                 &
+       'VP9  ','VQ9  ','VR   ','VU   ','VU4  ','VU7  ','XE   ','XF4  ', &
+       'XT   ','XU   ','XW   ','XX9  ','XZ   ','YA   ','YB   ','YI   ', &
+       'YJ   ','YK   ','YL   ','YN   ','YO   ','YS   ','YU   ','YV   ', &
+       'YV0  ','Z2   ','Z3   ','ZA   ','ZB   ','ZC4  ','ZD7  ','ZD8  ', &
+       'ZD9  ','ZF   ','ZK1  ',        'ZK2  ','ZK3  ','ZL   ','ZL7  ', &
+       'ZL8  ','ZL9  ','ZP   ','ZS   ','ZS8  '/
+
+  ldxcc=.false.
+  ng=0
+  do i=1,NZ
+     if(pfx(i)(1:3).eq.c) go to 10
+  enddo
+  go to 20
+
+10 ng=180*180+61+i
+  ldxcc=.true.
+
+20 return
+end subroutine packdxcc
diff --git a/lib/packgrid.f90 b/lib/packgrid.f90
new file mode 100644
index 0000000..1cdb731
--- /dev/null
+++ b/lib/packgrid.f90
@@ -0,0 +1,76 @@
+subroutine packgrid(grid,ng,text)
+
+  parameter (NGBASE=180*180)
+  character*4 grid
+  character*1 c1
+  logical text
+
+  text=.false.
+  if(grid.eq.'    ') go to 90               !Blank grid is OK
+
+! First, handle signal reports in the original range, -01 to -30 dB
+  if(grid(1:1).eq.'-') then
+     read(grid(2:3),*,err=800,end=800) n
+     if(n.ge.1 .and. n.le.30) then
+        ng=NGBASE+1+n
+        go to 900
+     endif
+     go to 10
+  else if(grid(1:2).eq.'R-') then
+     read(grid(3:4),*,err=800,end=800) n
+     if(n.ge.1 .and. n.le.30) then
+        ng=NGBASE+31+n
+        go to 900
+     endif
+     go to 10
+! Now check for RO, RRR, or 73 in the message field normally used for grid
+  else if(grid(1:4).eq.'RO  ') then
+     ng=NGBASE+62
+     go to 900
+  else if(grid(1:4).eq.'RRR ') then
+     ng=NGBASE+63
+     go to 900
+  else if(grid(1:4).eq.'73  ') then
+     ng=NGBASE+64
+     go to 900
+  endif
+
+! Now check for extended-range signal reports: -50 to -31, and 0 to +49.
+10 n=99
+  c1=grid(1:1)
+  read(grid,*,err=20,end=20) n
+  go to 30
+20 read(grid(2:4),*,err=30,end=30) n
+30 if(n.ge.-50 .and. n.le.49) then
+     if(c1.eq.'R') then
+        write(grid,1002) n+50
+1002    format('LA',i2.2)
+     else
+        write(grid,1003) n+50
+1003    format('KA',i2.2)
+     endif
+     go to 40
+  endif
+
+! Maybe it's free text ?
+  if(grid(1:1).lt.'A' .or. grid(1:1).gt.'R') text=.true.
+  if(grid(2:2).lt.'A' .or. grid(2:2).gt.'R') text=.true.
+  if(grid(3:3).lt.'0' .or. grid(3:3).gt.'9') text=.true.
+  if(grid(4:4).lt.'0' .or. grid(4:4).gt.'9') text=.true.
+  if(text) go to 900
+
+! OK, we have a properly formatted grid locator
+40 call grid2deg(grid//'mm',dlong,dlat)
+  long=int(dlong)
+  lat=int(dlat+ 90.0)
+  ng=((long+180)/2)*180 + lat
+  go to 900
+
+90 ng=NGBASE + 1
+  go to 900
+
+800 text=.true.
+900 continue
+
+  return
+end subroutine packgrid
diff --git a/lib/packmsg.f90 b/lib/packmsg.f90
new file mode 100644
index 0000000..6c7619b
--- /dev/null
+++ b/lib/packmsg.f90
@@ -0,0 +1,113 @@
+subroutine packmsg(msg,dat,text)
+
+  parameter (NBASE=37*36*10*27*27*27)
+  parameter (NBASE2=262178562)
+  character*22 msg
+  integer dat(12)
+  character*12 c1,c2
+  character*4 c3
+  character*6 grid6
+  logical text1,text2,text3,text
+
+  text=.false.
+! Convert all letters to upper case
+  iz=22
+  do i=1,22
+     if(msg(i:i).ge.'a' .and. msg(i:i).le.'z')                       &
+          msg(i:i)= char(ichar(msg(i:i))+ichar('A')-ichar('a'))
+     if(msg(i:i).ne.' ') iz=i
+  enddo
+  do iter=1,5                           !Collapse multiple blanks into one
+     ib2=index(msg(1:iz),'  ')
+     if(ib2.lt.1) go to 5
+     msg=msg(1:ib2)//msg(ib2+2:)
+     iz=iz-1
+  enddo
+
+5 if(msg(1:6).eq.'CQ DX ') msg(3:3)='9'
+
+! See if it's a CQ message
+  if(msg(1:3).eq.'CQ ') then
+     i=3
+! ... and if so, does it have a reply frequency?
+     if(msg(4:4).ge.'0' .and. msg(4:4).le.'9' .and.                  &
+          msg(5:5).ge.'0' .and. msg(5:5).le.'9' .and.                &
+          msg(6:6).ge.'0' .and. msg(6:6).le.'9') i=7
+     go to 1
+  endif
+
+  do i=1,22
+     if(msg(i:i).eq.' ') go to 1       !Get 1st blank
+  enddo
+  go to 10                             !Consider msg as plain text
+      
+1 ia=i
+  c1=msg(1:ia-1)
+  do i=ia+1,22
+     if(msg(i:i).eq.' ') go to 2       !Get 2nd blank
+  enddo
+  go to 10                             !Consider msg as plain text
+
+2 ib=i
+  c2=msg(ia+1:ib-1)
+
+  do i=ib+1,22
+     if(msg(i:i).eq.' ') go to 3       !Get 3rd blank
+  enddo
+  go to 10                             !Consider msg as plain text
+
+3 ic=i
+  c3='    '
+  if(ic.ge.ib+1) c3=msg(ib+1:ic)
+  if(c3.eq.'OOO ') c3='    '           !Strip out the OOO flag
+  call getpfx1(c1,k1,junk)
+  call packcall(c1,nc1,text1)
+  call getpfx1(c2,k2,nv2)
+  call packcall(c2,nc2,text2)
+  if(nv2.eq.0) then
+     if(k1.lt.0 .or. k2.lt.0 .or. k1*k2.ne.0) go to 10
+     if(k2.gt.0) k2=k2+450
+     k=max(k1,k2)
+     if(k.gt.0) then
+        call k2grid(k,grid6)
+        c3=grid6(:4)
+     endif
+  endif
+  call packgrid(c3,ng,text3)
+  if(nv2.eq.0 .and. (.not.text1) .and. (.not.text2) .and.           &
+       (.not.text3)) go to 20
+  if(nv2.gt.0) then
+     if(nv2.eq.1) then
+        if(c1(1:3).eq.'CQ ')  nc1=262178563 + k2
+        if(c1(1:4).eq.'QRZ ') nc1=264002072 + k2 
+        if(c1(1:3).eq.'DE ')  nc1=265825581 + k2
+     endif
+     if(nv2.eq.2) then
+        if(c1(1:3).eq.'CQ ')  nc1=267649090 + k2
+        if(c1(1:4).eq.'QRZ ') nc1=267698375 + k2
+        if(c1(1:3).eq.'DE ')  nc1=267747660 + k2
+     endif
+     go to 20
+  endif
+
+! The message will be treated as plain text.
+10 text=.true.
+  call packtext(msg,nc1,nc2,ng)
+  ng=ng+32768
+
+! Encode data into 6-bit words
+20 dat(1)=iand(ishft(nc1,-22),63)               !6 bits
+  dat(2)=iand(ishft(nc1,-16),63)                !6 bits
+  dat(3)=iand(ishft(nc1,-10),63)                !6 bits
+  dat(4)=iand(ishft(nc1, -4),63)                !6 bits
+  dat(5)=4*iand(nc1,15)+iand(ishft(nc2,-26),3)  !4+2 bits
+  dat(6)=iand(ishft(nc2,-20),63)                !6 bits
+  dat(7)=iand(ishft(nc2,-14),63)                !6 bits
+  dat(8)=iand(ishft(nc2, -8),63)                !6 bits
+  dat(9)=iand(ishft(nc2, -2),63)                !6 bits
+  dat(10)=16*iand(nc2,3)+iand(ishft(ng,-12),15) !2+4 bits
+  dat(11)=iand(ishft(ng,-6),63)
+  dat(12)=iand(ng,63)
+
+  return
+end subroutine packmsg
diff --git a/lib/packtext.f90 b/lib/packtext.f90
new file mode 100644
index 0000000..10f3488
--- /dev/null
+++ b/lib/packtext.f90
@@ -0,0 +1,47 @@
+subroutine packtext(msg,nc1,nc2,nc3)
+
+  parameter (MASK28=2**28 - 1)
+  character*13 msg
+  character*42 c
+  data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-./?'/
+
+  nc1=0
+  nc2=0
+  nc3=0
+
+  do i=1,5                                !First 5 characters in nc1
+     do j=1,42                            !Get character code
+        if(msg(i:i).eq.c(j:j)) go to 10
+     enddo
+     j=37
+10   j=j-1                                !Codes should start at zero
+     nc1=42*nc1 + j
+  enddo
+
+  do i=6,10                               !Characters 6-10 in nc2
+     do j=1,42                            !Get character code
+        if(msg(i:i).eq.c(j:j)) go to 20
+     enddo
+     j=37
+20   j=j-1                                !Codes should start at zero
+     nc2=42*nc2 + j
+  enddo
+
+  do i=11,13                              !Characters 11-13 in nc3
+     do j=1,42                            !Get character code
+        if(msg(i:i).eq.c(j:j)) go to 30
+     enddo
+     j=37
+30   j=j-1                                !Codes should start at zero
+     nc3=42*nc3 + j
+  enddo
+
+! We now have used 17 bits in nc3.  Must move one each to nc1 and nc2.
+  nc1=nc1+nc1
+  if(iand(nc3,32768).ne.0) nc1=nc1+1
+  nc2=nc2+nc2
+  if(iand(nc3,65536).ne.0) nc2=nc2+1
+  nc3=iand(nc3,32767)
+
+  return
+end subroutine packtext
diff --git a/lib/pctile.f90 b/lib/pctile.f90
new file mode 100644
index 0000000..35ee3a7
--- /dev/null
+++ b/lib/pctile.f90
@@ -0,0 +1,22 @@
+subroutine pctile(x,npts,npct,xpct)
+
+  parameter (NMAX=32768)
+  real*4 x(npts)
+  real*4 tmp(NMAX)
+
+  if(npts.le.0) then
+     xpct=1.0
+     go to 900
+  endif
+  if(npts.gt.NMAX) stop
+
+  tmp(1:npts)=x      
+  call sort(npts,tmp)
+  j=nint(npts*0.01*npct)
+  if(j.lt.1) j=1
+  if(j.gt.npts) j=npts
+  xpct=tmp(j)
+
+900 continue
+  return
+end subroutine pctile
diff --git a/lib/peakdt9.f90 b/lib/peakdt9.f90
new file mode 100644
index 0000000..eac256e
--- /dev/null
+++ b/lib/peakdt9.f90
@@ -0,0 +1,54 @@
+subroutine peakdt9(c2,nz2,nsps8,nspsd,c3,nz3,xdt)
+
+  complex c2(0:4096-1)
+  complex c3(0:4096-1)
+  complex z
+  real p(0:3300)
+  include 'jt9sync.f90'
+
+  p=0.
+  i0=5*nspsd
+  do i=0,nz2-1
+     z=1.e-3*sum(c2(max(i-(nspsd-1),0):i))
+     p(i0+i)=real(z)**2 + aimag(z)**2      !Integrated symbol power at freq=0
+  enddo
+
+  call getlags(nsps8,lag0,lag1,lag2)
+  tsymbol=nsps8/1500.0
+  dtlag=tsymbol/nspsd
+  smax=0.
+  lagpk=0
+  do lag=lag1,lag2
+     sum0=0.
+     sum1=0.
+     j=-nspsd
+     do i=1,85
+        j=j+nspsd
+        if(isync(i).eq.1) then
+           sum1=sum1+p(j+lag)
+        else
+           sum0=sum0+p(j+lag)
+        endif
+     enddo
+     ss=(sum1/16.0)/(sum0/69.0) - 1.0
+     xdt=(lag-lag0)*dtlag
+     if(ss.gt.smax) then
+        smax=ss
+        lagpk=lag
+     endif
+  enddo
+
+  xdt=(lagpk-lag0)*dtlag
+
+  nz3=nspsd*85
+  do i=0,nz3-1
+     j=i+lagpk-i0-nspsd+1
+     if(j.ge.0 .and. j.le.nz2) then
+        c3(i)=c2(j)
+     else
+        c3(i)=0.
+     endif
+  enddo
+ 
+  return
+end subroutine peakdt9
diff --git a/lib/peakup.f90 b/lib/peakup.f90
new file mode 100644
index 0000000..8e5aeda
--- /dev/null
+++ b/lib/peakup.f90
@@ -0,0 +1,8 @@
+subroutine peakup(ym,y0,yp,dx)
+
+  b=(yp-ym)/2.0
+  c=(yp+ym-2.0*y0)/2.0
+  dx=-b/(2.0*c)
+
+  return
+end subroutine peakup
diff --git a/lib/pfx.f90 b/lib/pfx.f90
new file mode 100644
index 0000000..ca48718
--- /dev/null
+++ b/lib/pfx.f90
@@ -0,0 +1,50 @@
+  parameter (NZ=339)                     !Total number of prefixes
+  parameter (NZ2=12)                     !Total number of suffixes
+  character*1 sfx(NZ2)
+  character*5 pfx(NZ)
+
+  data sfx/'P','0','1','2','3','4','5','6','7','8','9','A'/
+  data pfx/                                                             &
+       '1A   ','1S   ','3A   ','3B6  ','3B8  ','3B9  ','3C   ','3C0  ', &
+       '3D2  ','3D2C ','3D2R ','3DA  ','3V   ','3W   ','3X   ','3Y   ', &
+       '3YB  ','3YP  ','4J   ','4L   ','4S   ','4U1I ','4U1U ','4W   ', &
+       '4X   ','5A   ','5B   ','5H   ','5N   ','5R   ','5T   ','5U   ', &
+       '5V   ','5W   ','5X   ','5Z   ','6W   ','6Y   ','7O   ','7P   ', &
+       '7Q   ','7X   ','8P   ','8Q   ','8R   ','9A   ','9G   ','9H   ', &
+       '9J   ','9K   ','9L   ','9M2  ','9M6  ','9N   ','9Q   ','9U   ', &
+       '9V   ','9X   ','9Y   ','A2   ','A3   ','A4   ','A5   ','A6   ', &
+       'A7   ','A9   ','AP   ','BS7  ','BV   ','BV9  ','BY   ','C2   ', &
+       'C3   ','C5   ','C6   ','C9   ','CE   ','CE0X ','CE0Y ','CE0Z ', &
+       'CE9  ','CM   ','CN   ','CP   ','CT   ','CT3  ','CU   ','CX   ', &
+       'CY0  ','CY9  ','D2   ','D4   ','D6   ','DL   ','DU   ','E3   ', &
+       'E4   ','EA   ','EA6  ','EA8  ','EA9  ','EI   ','EK   ','EL   ', &
+       'EP   ','ER   ','ES   ','ET   ','EU   ','EX   ','EY   ','EZ   ', &
+       'F    ','FG   ','FH   ','FJ   ','FK   ','FKC  ','FM   ','FO   ', &
+       'FOA  ','FOC  ','FOM  ','FP   ','FR   ','FRG  ','FRJ  ','FRT  ', &
+       'FT5W ','FT5X ','FT5Z ','FW   ','FY   ','M    ','MD   ','MI   ', &
+       'MJ   ','MM   ',        'MU   ','MW   ','H4   ','H40  ','HA   ', &
+       'HB   ','HB0  ','HC   ','HC8  ','HH   ','HI   ','HK   ','HK0A ', &
+       'HK0M ','HL   ','HM   ','HP   ','HR   ','HS   ','HV   ','HZ   ', &
+       'I    ','IS   ','IS0  ',        'J2   ','J3   ','J5   ','J6   ', &
+       'J7   ','J8   ','JA   ','JDM  ','JDO  ','JT   ','JW   ',         &
+       'JX   ','JY   ','K    ','KG4  ','KH0  ','KH1  ','KH2  ','KH3  ', &
+       'KH4  ','KH5  ','KH5K ','KH6  ','KH7  ','KH8  ','KH9  ','KL   ', &
+       'KP1  ','KP2  ','KP4  ','KP5  ','LA   ','LU   ','LX   ','LY   ', &
+       'LZ   ','OA   ','OD   ','OE   ','OH   ','OH0  ','OJ0  ','OK   ', &
+       'OM   ','ON   ','OX   ','OY   ','OZ   ','P2   ','P4   ','PA   ', &
+       'PJ2  ','PJ7  ','PY   ','PY0F ','PT0S ','PY0T ','PZ   ','R1F  ', &
+       'R1M  ','S0   ','S2   ','S5   ','S7   ','S9   ','SM   ','SP   ', &
+       'ST   ','SU   ','SV   ','SVA  ','SV5  ','SV9  ','T2   ','T30  ', &
+       'T31  ','T32  ','T33  ','T5   ','T7   ','T8   ','T9   ','TA   ', &
+               'TF   ','TG   ','TI   ','TI9  ','TJ   ','TK   ','TL   ', &
+       'TN   ','TR   ','TT   ','TU   ','TY   ','TZ   ','UA   ','UA2  ', &
+       'UA9  ','UK   ','UN   ','UR   ','V2   ','V3   ','V4   ','V5   ', &
+       'V6   ','V7   ','V8   ','VE   ','VK   ','VK0H ','VK0M ','VK9C ', &
+       'VK9L ','VK9M ','VK9N ','VK9W ','VK9X ','VP2E ','VP2M ','VP2V ', &
+       'VP5  ','VP6  ','VP6D ','VP8  ','VP8G ','VP8H ','VP8O ','VP8S ', &
+       'VP9  ','VQ9  ','VR   ','VU   ','VU4  ','VU7  ','XE   ','XF4  ', &
+       'XT   ','XU   ','XW   ','XX9  ','XZ   ','YA   ','YB   ','YI   ', &
+       'YJ   ','YK   ','YL   ','YN   ','YO   ','YS   ','YU   ','YV   ', &
+       'YV0  ','Z2   ','Z3   ','ZA   ','ZB   ','ZC4  ','ZD7  ','ZD8  ', &
+       'ZD9  ','ZF   ','ZK1N ','ZK1S ','ZK2  ','ZK3  ','ZL   ','ZL7  ', &
+       'ZL8  ','ZL9  ','ZP   ','ZS   ','ZS8  ','KC4  ','E5   '/
diff --git a/lib/pfxdump.f90 b/lib/pfxdump.f90
new file mode 100644
index 0000000..7587dbf
--- /dev/null
+++ b/lib/pfxdump.f90
@@ -0,0 +1,13 @@
+subroutine pfxdump(fname)
+  character*(*) fname
+  include 'pfx.f90'
+
+  open(11,file=fname,status='unknown')
+  write(11,1001) sfx
+1001 format('Supported Suffixes:'/(11('/',a1,2x)))
+  write(11,1002) pfx
+1002 format(/'Supported Add-On DXCC Prefixes:'/(15(a5,1x)))
+  close(11)
+
+  return
+end subroutine pfxdump
diff --git a/lib/ps24.f90 b/lib/ps24.f90
new file mode 100644
index 0000000..241e49f
--- /dev/null
+++ b/lib/ps24.f90
@@ -0,0 +1,27 @@
+subroutine ps24(dat,nfft,s)
+
+  parameter (NMAX=2520+2)
+  parameter (NHMAX=NMAX/2-1)
+  real dat(nfft)
+  real dat2(NMAX)
+  real s(NHMAX)
+  complex c(0:NMAX)
+  equivalence(dat2,c)
+
+  nh=nfft/2
+  do i=1,nh
+     dat2(i)=dat(i)/128.0       !### Why 128 ??
+  enddo
+  do i=nh+1,nfft
+     dat2(i)=0.
+  enddo
+
+  call four2a(c,nfft,1,-1,0)
+  
+  fac=1.0/nfft
+  do i=1,nh
+     s(i)=fac*(real(c(i))**2 + aimag(c(i))**2)
+  enddo
+
+  return
+end subroutine ps24
diff --git a/lib/ptt.c b/lib/ptt.c
new file mode 100644
index 0000000..902193f
--- /dev/null
+++ b/lib/ptt.c
@@ -0,0 +1,50 @@
+#include <windows.h>
+#include <stdio.h>
+
+int ptt_(int *nport, int *ntx, int *iptt)
+{
+  static HANDLE hFile;
+  static int open=0;
+  char s[10];
+  int i3=1,i4=1,i5=1,i6=1,i9=1,i00=1;
+
+  if(*nport==0) {
+    *iptt=*ntx;
+    return(0);
+  }
+
+  if(*ntx && (!open)) {
+    sprintf(s,"\\\\.\\COM%d",*nport);
+    hFile=CreateFile(TEXT(s),GENERIC_WRITE,0,NULL,OPEN_EXISTING,
+		     FILE_ATTRIBUTE_NORMAL,NULL);
+    if(hFile==INVALID_HANDLE_VALUE) {
+      //      printf("PTT: Cannot open COM port %d.\n",*nport);
+      return 1;
+    }
+    open=1;
+  }
+
+  if(*ntx && open) {
+    i3=EscapeCommFunction(hFile,3);
+    i5=EscapeCommFunction(hFile,5);
+    *iptt=1;
+  }
+
+  else {
+    i4=EscapeCommFunction(hFile,4);
+    i6=EscapeCommFunction(hFile,6);
+    i9=EscapeCommFunction(hFile,9);
+    i00=CloseHandle(hFile);
+    *iptt=0;
+    open=0;
+  }
+  /*
+  if(i3==0) return 3;
+  if(i4==0) return 4;
+  if(i5==0) return 5;
+  if(i6==0) return 6;
+  if(i9==0) return 9;
+  if(i00==0) return 10;
+  */
+  return 0;
+}
diff --git a/lib/rig_control.c b/lib/rig_control.c
new file mode 100644
index 0000000..7c8b2f6
--- /dev/null
+++ b/lib/rig_control.c
@@ -0,0 +1,99 @@
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "tstrig.h"
+
+RIG *my_rig;                                       // handle to rig
+
+int set_conf(RIG *my_rig, char *conf_parms);
+
+//------------------------------------------------------------------------
+int set_conf(RIG *my_rig, char *conf_parms)
+{
+  char *p, *q, *n;
+  int iret;
+
+  p = conf_parms;
+  while (p && *p != '\0') {
+    /* FIXME: left hand value of = cannot be null */
+    q = strchr(p, '=');
+    if ( !q )
+      return -RIG_EINVAL;
+    *q++ = '\0';
+    n = strchr(q, ',');
+    if (n) *n++ = '\0';
+    iret = rig_set_conf(my_rig, rig_token_lookup(my_rig, p), q);
+    if (iret != RIG_OK)
+      return iret;
+    p = n;
+  }
+  return RIG_OK;
+}
+
+//------------------------------------------------------------------------
+int rigOpen(int verbose, rig_model_t my_model, const char* rig_file,
+	    int serial_rate, const char* conf_parms2)
+{
+  int iret;		/* generic return code from functions */
+  char *civaddr = NULL;	/* NULL means no need to set conf */
+  //  const char *rig_file;
+  //  const char *conf_parms2;
+  //  int serial_rate;
+
+  rig_set_debug(verbose);
+  my_rig=rig_init(my_model);
+  
+  if (!my_rig) {
+    //    fprintf(stderr, "Unknown rig num %d, or initialization error.\n",my_model);
+    return -1;
+  }
+
+  //  rig_file="COM1";
+  //  serial_rate=4800;
+  //  conf_parms2="data_bits=8,stop_bits=2,serial_handshake=Hardware";
+
+  iret=set_conf(my_rig, conf_parms2);
+  if (iret!=RIG_OK) {
+    //    fprintf(stderr, "Config parameter error: %s\n", rigerror(iret));
+    return -2;
+  }
+
+  if (rig_file)
+    strncpy(my_rig->state.rigport.pathname, rig_file, FILPATHLEN - 1);
+
+  if (serial_rate!=0)
+    my_rig->state.rigport.parm.serial.rate = serial_rate;
+
+  if (civaddr)
+    rig_set_conf(my_rig, rig_token_lookup(my_rig, "civaddr"), civaddr);
+
+  iret = rig_open(my_rig);
+  if(iret!=0) return -3;
+  return 0;
+}
+
+int rigSetFreq(int fHz)
+{
+  return rig_set_freq(my_rig,RIG_VFO_CURR,fHz);
+}
+
+int rigFreq(int *fHz)
+{
+  int iret=0;
+  freq_t freq;
+  iret=rig_get_freq(my_rig, RIG_VFO_CURR, &freq);
+  *fHz=freq;
+  return iret;
+}
+
+int rigSetPTT(int iptt)
+{
+  return rig_set_ptt(my_rig, RIG_VFO_CURR, iptt);
+}
+
+void rigClose()
+{
+  rig_close(my_rig);
+  rig_cleanup(my_rig);
+}
diff --git a/lib/rs.h b/lib/rs.h
new file mode 100644
index 0000000..06cbe34
--- /dev/null
+++ b/lib/rs.h
@@ -0,0 +1,35 @@
+/* User include file for the Reed-Solomon codec
+ * Copyright 2002, Phil Karn KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+
+/* General purpose RS codec, 8-bit symbols */
+void encode_rs_char(void *rs,unsigned char *data,unsigned char *parity);
+int decode_rs_char(void *rs,unsigned char *data,int *eras_pos,
+		   int no_eras);
+void *init_rs_char(int symsize,int gfpoly,
+		   int fcr,int prim,int nroots,
+		   int pad);
+void free_rs_char(void *rs);
+
+/* General purpose RS codec, integer symbols */
+void encode_rs_int(void *rs,int *data,int *parity);
+int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras);
+void *init_rs_int(int symsize,int gfpoly,int fcr,
+		  int prim,int nroots,int pad);
+void free_rs_int(void *rs);
+
+/* CCSDS standard (255,223) RS codec with conventional (*not* dual-basis)
+ * symbol representation
+ */
+void encode_rs_8(unsigned char *data,unsigned char *parity,int pad);
+int decode_rs_8(unsigned char *data,int *eras_pos,int no_eras,int pad);
+
+/* CCSDS standard (255,223) RS codec with dual-basis symbol representation */
+void encode_rs_ccsds(unsigned char *data,unsigned char *parity,int pad);
+int decode_rs_ccsds(unsigned char *data,int *eras_pos,int no_eras,int pad);
+
+/* Tables to map from conventional->dual (Taltab) and
+ * dual->conventional (Tal1tab) bases
+ */
+extern unsigned char Taltab[],Tal1tab[];
diff --git a/lib/s3avg.f90 b/lib/s3avg.f90
new file mode 100644
index 0000000..f8f68ac
--- /dev/null
+++ b/lib/s3avg.f90
@@ -0,0 +1,60 @@
+subroutine s3avg(nsave,mode65,nutc,nhz,xdt,npol,ntol,s3,nsum,nkv,decoded)
+
+! Save the current synchronized spectra, s3(64,63), for possible
+! decoding of average.
+
+  real s3(64,63)                        !Synchronized spectra for 63 symbols
+  real s3a(64,63,64)                    !Saved spectra
+  real s3b(64,63)                       !Average spectra
+  integer iutc(64),ihz(64),ipol(64)
+  real dt(64)
+  character*22 decoded
+  logical ltext,first
+  data first/.true./
+  save
+
+  if(first) then
+     iutc=-1
+     ihz=0
+     ipol=0
+     first=.false.
+     ihzdiff=min(100,ntol)
+     dtdiff=0.2
+  endif
+
+  do i=1,64
+     if(nutc.eq.iutc(i) .and. abs(nhz-ihz(i)).lt.ihzdiff) then
+        nsave=mod(nsave-1+64,64)+1
+        go to 10
+     endif
+  enddo
+  
+  iutc(nsave)=nutc                          !Save UTC
+  ihz(nsave)=nhz                            !Save freq in Hz
+  ipol(nsave)=npol                          !Save pol
+  dt(nsave)=xdt                             !Save DT
+  s3a(1:64,1:63,nsave)=s3                   !Save the spectra
+
+10 s3b=0.
+  do i=1,64                                 !Accumulate avg spectra
+     if(iutc(i).lt.0) cycle
+     if(mod(iutc(i),2).ne.mod(nutc,2)) cycle !Use only same sequence
+     if(abs(nhz-ihz(i)).gt.ihzdiff) cycle   !Freq must match
+     if(abs(xdt-dt(i)).gt.dtdiff) cycle     !DT must match
+     s3b=s3b + s3a(1:64,1:63,i)
+     nsum=nsum+1
+  enddo
+ 
+  decoded='                      '
+  if(nsum.ge.2) then                        !Try decoding the sverage
+     nadd=mode65*nsum
+     call extract(s3b,nadd,ncount,nhist,decoded,ltext)     !Extract the message
+     nkv=nsum
+     if(ncount.lt.0) then 
+        nkv=0
+        decoded='                      '
+     endif
+  endif
+
+  return
+end subroutine s3avg
diff --git a/lib/sec_midn.f90 b/lib/sec_midn.f90
new file mode 100644
index 0000000..0bbe62c
--- /dev/null
+++ b/lib/sec_midn.f90
@@ -0,0 +1,11 @@
+real function sec_midn()
+  sec_midn=secnds(0.0)
+  return
+end function sec_midn
+
+subroutine sleep_msec(n)
+
+  call usleep(1000*n)
+
+  return
+end subroutine sleep_msec
diff --git a/lib/setup65.f90 b/lib/setup65.f90
new file mode 100644
index 0000000..608b41b
--- /dev/null
+++ b/lib/setup65.f90
@@ -0,0 +1,96 @@
+subroutine setup65
+
+! Defines arrays related to the JT65 pseudo-random synchronizing pattern.
+! Executed at program start.
+
+  integer nprc(126)
+  common/prcom/pr(126),mdat(126),mref(126,2),mdat2(126),mref2(126,2)
+
+! JT65
+  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 mr2/0/                !Silence compiler warning
+
+! Put the appropriate pseudo-random sequence into pr
+  nsym=126
+  do i=1,nsym
+     pr(i)=2*nprc(i)-1
+  enddo
+
+! Determine locations of data and reference symbols
+  k=0
+  mr1=0
+  do i=1,nsym
+     if(pr(i).lt.0.0) then
+        k=k+1
+        mdat(k)=i
+     else
+        mr2=i
+        if(mr1.eq.0) mr1=i
+     endif
+  enddo
+  nsig=k
+
+! Determine the reference symbols for each data symbol.
+  do k=1,nsig
+     m=mdat(k)
+     mref(k,1)=mr1
+     do n=1,10                     !Get ref symbol before data
+        if((m-n).gt.0) then
+           if (pr(m-n).gt.0.0) go to 10
+        endif
+     enddo
+     go to 12
+10   mref(k,1)=m-n
+12   mref(k,2)=mr2
+     do n=1,10                     !Get ref symbol after data
+        if((m+n).le.nsym) then
+           if (pr(m+n).gt.0.0) go to 20
+        endif
+     enddo
+     cycle
+20   mref(k,2)=m+n
+  enddo
+
+! Now do it all again, using opposite logic on pr(i)
+  k=0
+  mr1=0
+  do i=1,nsym
+     if(pr(i).gt.0.0) then
+        k=k+1
+        mdat2(k)=i
+     else
+        mr2=i
+        if(mr1.eq.0) mr1=i
+     endif
+  enddo
+  nsig=k
+
+  do k=1,nsig
+     m=mdat2(k)
+     mref2(k,1)=mr1
+     do n=1,10
+        if((m-n).gt.0) then
+           if (pr(m-n).lt.0.0) go to 110
+        endif
+     enddo
+     go to 112
+110  mref2(k,1)=m-n
+112  mref2(k,2)=mr2
+     do n=1,10
+        if((m+n).le.nsym) then
+           if (pr(m+n).lt.0.0) go to 120
+        endif
+     enddo
+     cycle
+120  mref2(k,2)=m+n
+  enddo
+
+  return
+end subroutine setup65
diff --git a/lib/sleep.h b/lib/sleep.h
new file mode 100644
index 0000000..df60bc9
--- /dev/null
+++ b/lib/sleep.h
@@ -0,0 +1,32 @@
+/*
+ * sleep.h  1.0 02/03/10
+ *
+ * Defines cross-platform sleep, usleep, etc.
+ *
+ * By Wu Yongwei
+ *
+ */
+
+#ifndef _SLEEP_H
+#define _SLEEP_H
+
+#ifdef _WIN32
+# if defined(_NEED_SLEEP_ONLY) && (defined(_MSC_VER) || defined(__MINGW32__))
+#  include <stdlib.h>
+#  define sleep(t) _sleep((t) * 1000)
+# else
+#  include <windows.h>
+#  define sleep(t)  Sleep((t) * 1000)
+# endif
+# ifndef _NEED_SLEEP_ONLY
+#  define msleep(t) Sleep(t)
+#  define usleep(t) Sleep((t) / 1000)
+# endif
+#else
+# include <unistd.h>
+# ifndef _NEED_SLEEP_ONLY
+#  define msleep(t) usleep((t) * 1000)
+# endif
+#endif
+
+#endif /* _SLEEP_H */
diff --git a/lib/sleep_msec.f90 b/lib/sleep_msec.f90
new file mode 100644
index 0000000..1a8dbe4
--- /dev/null
+++ b/lib/sleep_msec.f90
@@ -0,0 +1,4 @@
+subroutine sleep_msec(n)
+  call usleep(n*1000)
+  return
+end subroutine sleep_msec
diff --git a/lib/slope.f90 b/lib/slope.f90
new file mode 100644
index 0000000..5581ade
--- /dev/null
+++ b/lib/slope.f90
@@ -0,0 +1,40 @@
+subroutine slope(y,npts,xpk)
+
+! Remove best-fit slope from data in y(i).  When fitting the straight line,
+! ignore the peak around xpk +/- 2.
+
+  real y(npts)
+  real x(100)
+
+  do i=1,npts
+     x(i)=i
+  enddo
+
+  sumw=0.
+  sumx=0.
+  sumy=0.
+  sumx2=0.
+  sumxy=0.
+  sumy2=0.
+
+  do i=1,npts
+     if(abs(i-xpk).gt.2.0) then
+        sumw=sumw + 1.0
+        sumx=sumx + x(i)
+        sumy=sumy + y(i)
+        sumx2=sumx2 + x(i)**2
+        sumxy=sumxy + x(i)*y(i)
+        sumy2=sumy2 + y(i)**2
+     endif
+  enddo
+
+  delta=sumw*sumx2 - sumx**2
+  a=(sumx2*sumy - sumx*sumxy) / delta
+  b=(sumw*sumxy - sumx*sumy) / delta
+
+  do i=1,npts
+     y(i)=y(i)-(a + b*x(i))
+  enddo
+
+  return
+end subroutine slope
diff --git a/lib/smo121.f90 b/lib/smo121.f90
new file mode 100644
index 0000000..7ae30ad
--- /dev/null
+++ b/lib/smo121.f90
@@ -0,0 +1,13 @@
+subroutine smo121(x,nz)
+
+  real x(nz)
+
+  x0=x(1)
+  do i=2,nz-1
+     x1=x(i)
+     x(i)=0.5*x(i) + 0.25*(x0+x(i+1))
+     x0=x1
+  enddo
+
+  return
+end subroutine smo121
diff --git a/lib/softsym.f90 b/lib/softsym.f90
new file mode 100644
index 0000000..8eda5e7
--- /dev/null
+++ b/lib/softsym.f90
@@ -0,0 +1,50 @@
+subroutine softsym(id2,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,        &
+     freq,drift,schk,i1SoftSymbols)
+
+! Compute the soft symbols
+
+  complex c2(0:4096-1)
+  complex c3(0:4096-1)
+  complex c5(0:4096-1)
+  real a(3)
+  integer*1 i1SoftSymbolsScrambled(207)
+  integer*1 i1SoftSymbols(207)
+  include 'jt9sync.f90'
+
+  nspsd=16
+  ndown=nsps8/nspsd
+
+! Mix, low-pass filter, and downsample to 16 samples per symbol
+  call timer('downsam9',0)
+  call downsam9(id2,npts8,nsps8,newdat,nspsd,fpk,c2,nz2)
+  call timer('downsam9',1)
+
+  call timer('peakdt9 ',0)
+  call peakdt9(c2,nz2,nsps8,nspsd,c3,nz3,xdt)  !Find DT
+  call timer('peakdt9 ',1)
+
+  fsample=1500.0/ndown
+  a=0.
+  call timer('afc9    ',0)
+  call afc9(c3,nz3,fsample,a,syncpk)  !Find deltaF, fDot, fDDot
+  call timer('afc9    ',1)
+  freq=fpk - a(1)
+  drift=-2.0*a(2)
+
+  call timer('twkfreq ',0)
+  call twkfreq(c3,c5,nz3,fsample,a)   !Correct for delta f, f1, f2 ==> a(1:3)
+  call timer('twkfreq ',1)
+
+! Compute soft symbols (in scrambled order)
+  call timer('symspec2',0)
+  call symspec2(c5,nz3,nsps8,nspsd,fsample,freq,drift,snrdb,schk,      &
+       i1SoftSymbolsScrambled)
+  call timer('symspec2',1)
+
+! Remove interleaving
+  call timer('interlv9',0)
+  call interleave9(i1SoftSymbolsScrambled,-1,i1SoftSymbols)
+  call timer('interlv9',1)
+
+  return
+end subroutine softsym
diff --git a/lib/sort.f90 b/lib/sort.f90
new file mode 100644
index 0000000..281ce02
--- /dev/null
+++ b/lib/sort.f90
@@ -0,0 +1,4 @@
+subroutine sort(n,arr)
+  call ssort(arr,tmp,n,1)
+  return
+end subroutine sort
diff --git a/lib/ss.bat b/lib/ss.bat
new file mode 100644
index 0000000..37f669a
--- /dev/null
+++ b/lib/ss.bat
@@ -0,0 +1 @@
+svn status | grep -v '?'
diff --git a/lib/ssort.f90 b/lib/ssort.f90
new file mode 100644
index 0000000..7d71238
--- /dev/null
+++ b/lib/ssort.f90
@@ -0,0 +1,264 @@
+subroutine ssort (x,y,n,kflag)
+! Sort an array and optionally make the same interchanges in
+!          an auxiliary array.  the array may be sorted in increasing
+!          or decreasing order.  a slightly modified quicksort
+!          algorithm is used.
+
+! ssort sorts array x and optionally makes the same interchanges in
+! array y.  the array x may be sorted in increasing order or
+! decreasing order.  a slightly modified quicksort algorithm is used.
+
+! Description of parameters
+!    x - array of values to be sorted
+!    y - array to be (optionally) carried along
+!    n - number of values in array x to be sorted
+!    kflag - control parameter
+!          =  2  means sort x in increasing order and carry y along.
+!          =  1  means sort x in increasing order (ignoring y)
+!          = -1  means sort x in decreasing order (ignoring y)
+!          = -2  means sort x in decreasing order and carry y along.
+
+  integer kflag, n
+  integer x(n), y(n)
+  real r
+  integer t, tt, tty, ty
+  integer i, ij, j, k, kk, l, m, nn
+  integer il(21), iu(21)
+
+  nn = n
+  if (nn .lt. 1) then
+!         print*,'ssort: The number of sort elements is not positive.'
+!         print*,'ssort: n = ',nn,'   kflag = ',kflag
+     return
+  endif
+
+  kk = abs(kflag)
+  if (kk.ne.1 .and. kk.ne.2) then
+     print *,'the sort control parameter, k, is not 2, 1, -1, or -2.'
+     return
+  endif
+
+! Alter array x to get decreasing order if needed
+
+  if (kflag .le. -1) then
+     do i=1,nn
+        x(i) = -x(i)
+     enddo
+  endif
+
+  if (kk .eq. 2) go to 100
+
+! Sort x only
+
+  m = 1
+  i = 1
+  j = nn
+  r = 0.375e0
+
+20 if (i .eq. j) go to 60
+  if (r .le. 0.5898437e0) then
+     r = r+3.90625e-2
+  else
+     r = r-0.21875e0
+  endif
+
+30 k = i
+
+! Select a central element of the array and save it in location t
+
+  ij = i + int((j-i)*r)
+  t = x(ij)
+
+! If first element of array is greater than t, interchange with t
+
+  if (x(i) .gt. t) then
+     x(ij) = x(i)
+     x(i) = t
+     t = x(ij)
+  endif
+  l = j
+
+! If last element of array is less than than t, interchange with t
+  if (x(j) .lt. t) then
+     x(ij) = x(j)
+     x(j) = t
+     t = x(ij)
+
+! If first element of array is greater than t, interchange with t
+     if (x(i) .gt. t) then
+        x(ij) = x(i)
+        x(i) = t
+        t = x(ij)
+     endif
+  endif
+
+! Find an element in the second half of the array which is smaller than t
+40 l = l-1
+  if (x(l) .gt. t) go to 40
+
+! Find an element in the first half of the array which is greater than t
+50 k = k+1
+  if (x(k) .lt. t) go to 50
+
+! Interchange these elements
+  if (k .le. l) then
+     tt = x(l)
+     x(l) = x(k)
+     x(k) = tt
+     go to 40
+  endif
+
+! Save upper and lower subscripts of the array yet to be sorted
+  if (l-i .gt. j-k) then
+     il(m) = i
+     iu(m) = l
+     i = k
+     m = m+1
+  else
+     il(m) = k
+     iu(m) = j
+     j = l
+     m = m+1
+  endif
+  go to 70
+
+! Begin again on another portion of the unsorted array
+60 m = m-1
+  if (m .eq. 0) go to 190
+  i = il(m)
+  j = iu(m)
+
+70 if (j-i .ge. 1) go to 30
+  if (i .eq. 1) go to 20
+  i = i-1
+
+80 i = i+1
+  if (i .eq. j) go to 60
+  t = x(i+1)
+  if (x(i) .le. t) go to 80
+  k = i
+
+90 x(k+1) = x(k)
+  k = k-1
+  if (t .lt. x(k)) go to 90
+  x(k+1) = t
+  go to 80
+
+! Sort x and carry y along
+
+100 m = 1
+  i = 1
+  j = nn
+  r = 0.375e0
+
+110 if (i .eq. j) go to 150
+  if (r .le. 0.5898437e0) then
+     r = r+3.90625e-2
+  else
+     r = r-0.21875e0
+  endif
+
+  120 k = i
+! Select a central element of the array and save it in location t
+  ij = i + int((j-i)*r)
+  t = x(ij)
+  ty = y(ij)
+
+! If first element of array is greater than t, interchange with t
+  if (x(i) .gt. t) then
+     x(ij) = x(i)
+     x(i) = t
+     t = x(ij)
+     y(ij) = y(i)
+     y(i) = ty
+     ty = y(ij)
+  endif
+  l = j
+
+! If last element of array is less than t, interchange with t
+  if (x(j) .lt. t) then
+     x(ij) = x(j)
+     x(j) = t
+     t = x(ij)
+     y(ij) = y(j)
+     y(j) = ty
+     ty = y(ij)
+
+! If first element of array is greater than t, interchange with t
+     if (x(i) .gt. t) then
+        x(ij) = x(i)
+        x(i) = t
+        t = x(ij)
+        y(ij) = y(i)
+        y(i) = ty
+        ty = y(ij)
+     endif
+  endif
+
+! Find an element in the second half of the array which is smaller than t
+130 l = l-1
+  if (x(l) .gt. t) go to 130
+
+! Find an element in the first half of the array which is greater than t
+140 k = k+1
+  if (x(k) .lt. t) go to 140
+
+! Interchange these elements
+  if (k .le. l) then
+     tt = x(l)
+     x(l) = x(k)
+     x(k) = tt
+     tty = y(l)
+     y(l) = y(k)
+     y(k) = tty
+     go to 130
+  endif
+
+! Save upper and lower subscripts of the array yet to be sorted
+  if (l-i .gt. j-k) then
+     il(m) = i
+     iu(m) = l
+     i = k
+     m = m+1
+  else
+     il(m) = k
+     iu(m) = j
+     j = l
+     m = m+1
+  endif
+  go to 160
+
+! Begin again on another portion of the unsorted array
+150 m = m-1
+  if (m .eq. 0) go to 190
+  i = il(m)
+  j = iu(m)
+
+160 if (j-i .ge. 1) go to 120
+  if (i .eq. 1) go to 110
+  i = i-1
+
+170 i = i+1
+  if (i .eq. j) go to 150
+  t = x(i+1)
+  ty = y(i+1)
+  if (x(i) .le. t) go to 170
+  k = i
+
+180 x(k+1) = x(k)
+  y(k+1) = y(k)
+  k = k-1
+  if (t .lt. x(k)) go to 180
+  x(k+1) = t
+  y(k+1) = ty
+  go to 170
+
+! Clean up
+190 if (kflag .le. -1) then
+     do i=1,nn
+        x(i) = -x(i)
+     enddo
+  endif
+
+  return
+end subroutine ssort
diff --git a/lib/stdmsg.f90 b/lib/stdmsg.f90
new file mode 100644
index 0000000..bc8d489
--- /dev/null
+++ b/lib/stdmsg.f90
@@ -0,0 +1,12 @@
+logical*1 function stdmsg(msg0)
+
+  character*22 msg0,msg
+  integer dat(12)
+  logical text
+
+  call packmsg(msg0,dat,text)
+  call unpackmsg(dat,msg)
+  stdmsg=msg.eq.msg0 .and. (.not.text)
+
+  return
+end function stdmsg
diff --git a/lib/symspec.f90 b/lib/symspec.f90
new file mode 100644
index 0000000..2facb49
--- /dev/null
+++ b/lib/symspec.f90
@@ -0,0 +1,113 @@
+subroutine symspec(k,ntrperiod,nsps,ingain,slope,pxdb,s,df3,ihsym,npts8)
+
+! Input:
+!  k         pointer to the most recent new data
+!  ntrperiod T/R sequence length, minutes
+!  nsps      samples per symbol, at 12000 Hz
+!  ndiskdat  0/1 to indicate if data from disk
+!  nb        0/1 status of noise blanker (off/on)
+!  nbslider  NB setting, 0-100
+
+! Output:
+!  pxdb      power (0-60 dB)
+!  s()       current spectrum for waterfall display
+!  ihsym     index number of this half-symbol (1-184)
+
+! jt9com
+!  ss()      JT9 symbol spectra at half-symbol steps
+!  savg()    average spectra for waterfall display
+
+  include 'constants.f90'
+  real*4 w3(MAXFFT3)
+  real*4 s(NSMAX)
+  real*4 scale(NSMAX)
+  real*4 ssum(NSMAX)
+  real*4 xc(0:MAXFFT3-1)
+  complex cx(0:MAXFFT3/2)
+  integer*2 id2
+  common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat,         &
+       ntr,mousefqso,newdat,nfa,nfb,ntol,kin,nzhsym,nsynced,ndecoded
+  data rms/999.0/,k0/99999999/,nfft3z/0/,slope0/0.0/
+  equivalence (xc,cx)
+  save
+
+  if(ntrperiod.eq.-999) stop                   !Silence compiler warning
+  nfft3=16384                                  !df=12000.0/16384 = 0.732422
+  jstep=nsps/2                                 !Step size = half-symbol in id2()
+  if(k.gt.NMAX) go to 900
+  if(k.lt.2048) then                !(2048 was nfft3)  (Any need for this ???)
+     ihsym=0
+     go to 900                                 !Wait for enough samples to start
+  endif
+
+  if(nfft3.ne.nfft3z .or. slope.ne.slope0) then    !New nfft3, compute window
+     pi=4.0*atan(1.0)
+     do i=1,nfft3
+        w3(i)=2.0*(sin(i*pi/nfft3))**2         !Window for nfft3 spectrum
+     enddo
+     nfft3z=nfft3
+     nh=NSMAX/2
+     do i=1,NSMAX
+        x=slope*float(i)/nh - 1.0 + 2.6
+        scale(i)=10.0**x
+     enddo
+     slope0=slope
+  endif
+
+  if(k.lt.k0) then                             !Start a new data block
+     ja=0
+     ssum=0.
+     ihsym=0
+     if(ndiskdat.eq.0) id2(k+1:)=0   !Needed to prevent "ghosts". Not sure why.
+  endif
+  gain=10.0**(0.05*ingain)
+  sq=0.
+  do i=k0+1,k
+     x1=id2(i)
+     sq=sq + x1*x1
+  enddo
+  sq=sq * gain**2
+  rms=sqrt(sq/(k-k0))
+  pxdb=0.
+  if(rms.gt.0.0) pxdb=20.0*log10(rms)
+  if(pxdb.gt.60.0) pxdb=60.0
+
+
+  k0=k
+  ja=ja+jstep                         !Index of first sample
+
+  fac0=0.1
+  do i=0,nfft3-1                      !Copy data into cx
+     j=ja+i-(nfft3-1)
+     xc(i)=0.
+     if(j.ge.1) xc(i)=fac0*id2(j)
+  enddo
+
+  if(ihsym.lt.184) ihsym=ihsym+1
+
+  xc(0:nfft3-1)=w3(1:nfft3)*xc(0:nfft3-1)    !Apply window w3
+  call four2a(xc,nfft3,1,-1,0)               !Real-to-complex FFT
+
+  n=min(184,ihsym)
+  df3=12000.0/nfft3                   !JT9-1: 0.732 Hz = 0.42 * tone spacing
+!  i0=nint(1000.0/df3)
+  i0=0
+  iz=min(NSMAX,nint(5000.0/df3))
+  fac=(1.0/nfft3)**2
+  do i=1,iz
+     j=i0+i-1
+     if(j.lt.0) j=j+nfft3
+     sx=fac*(real(cx(j))**2 + aimag(cx(j))**2)
+     ss(n,i)=sx
+     ssum(i)=ssum(i) + sx
+     s(i)=gain*sx
+  enddo
+
+!  s=0.05*s/ref
+  s=scale*s
+  savg=scale*ssum/ihsym
+
+900 npts8=k/8
+
+  return
+end subroutine symspec
diff --git a/lib/symspec2.f90 b/lib/symspec2.f90
new file mode 100644
index 0000000..92dc571
--- /dev/null
+++ b/lib/symspec2.f90
@@ -0,0 +1,88 @@
+subroutine symspec2(c5,nz3,nsps8,nspsd,fsample,freq,drift,snrdb,schk,    &
+     i1SoftSymbolsScrambled)
+
+! Compute soft symbols from the final downsampled data
+
+  complex c5(0:4096-1)
+  complex z
+  integer*1 i1SoftSymbolsScrambled(207)
+  real aa(3)
+  real ss2(0:8,85)
+  real ss3(0:7,69)
+  include 'jt9sync.f90'
+  data scale/10.0/
+
+  aa(1)=-1500.0/nsps8
+  aa(2)=0.
+  aa(3)=0.
+  do i=0,8                                         !Loop over the 9 tones
+     if(i.ge.1) call twkfreq(c5,c5,nz3,fsample,aa)
+     m=0
+     k=-1
+     do j=1,85                                     !Loop over all symbols
+        z=0.
+        do n=1,nspsd                               !Sum over 16 samples
+           k=k+1
+           z=z+c5(k)
+        enddo
+        ss2(i,j)=real(z)**2 + aimag(z)**2        !Symbol speactra, data and sync
+        if(i.ge.1 .and. isync(j).eq.0) then
+           m=m+1
+           ss3(i-1,m)=ss2(i,j)                   !Symbol speactra, data only
+        endif
+     enddo
+  enddo
+
+  call chkss2(ss2,freq,drift,schk)
+  if(schk.lt.2.0) go to 900
+
+  ss=0.
+  sig=0.
+  do j=1,69
+     smax=0.
+     do i=0,7
+        smax=max(smax,ss3(i,j))
+        ss=ss+ss3(i,j)
+     enddo
+     sig=sig+smax
+     ss=ss-smax
+  enddo
+  ave=ss/(69*7)                           !Baseline
+  call pctile(ss2,9*85,35,xmed)
+  ss3=ss3/ave
+  sig=sig/69.                             !Signal
+  t=max(1.0,sig - 1.0)
+  snrdb=db(t) - 61.3
+     
+  m0=3
+  k=0
+  do j=1,69
+        smax=0.
+        do i=0,7
+           if(ss3(i,j).gt.smax) smax=ss3(i,j)
+        enddo
+
+     do m=m0-1,0,-1                   !Get bit-wise soft symbols
+        if(m.eq.2) then
+           r1=max(ss3(4,j),ss3(5,j),ss3(6,j),ss3(7,j))
+           r0=max(ss3(0,j),ss3(1,j),ss3(2,j),ss3(3,j))
+        else if(m.eq.1) then
+           r1=max(ss3(2,j),ss3(3,j),ss3(4,j),ss3(5,j))
+           r0=max(ss3(0,j),ss3(1,j),ss3(6,j),ss3(7,j))
+        else
+           r1=max(ss3(1,j),ss3(2,j),ss3(4,j),ss3(7,j))
+           r0=max(ss3(0,j),ss3(3,j),ss3(5,j),ss3(6,j))
+        endif
+
+        k=k+1
+        i4=nint(scale*(r1-r0))
+        if(i4.lt.-127) i4=-127
+        if(i4.gt.127) i4=127
+        i4=i4+128
+        if(i4.le.127) i1SoftSymbolsScrambled(k)=i4
+        if(i4.ge.128) i1SoftSymbolsScrambled(k)=i4-256
+     enddo
+  enddo
+
+900 return
+end subroutine symspec2
diff --git a/lib/symspec65.f90 b/lib/symspec65.f90
new file mode 100644
index 0000000..5f6da88
--- /dev/null
+++ b/lib/symspec65.f90
@@ -0,0 +1,47 @@
+subroutine symspec65(dd,npts,ss,nhsym,savg)
+
+! Compute JT65 symbol spectra at half-symbol steps
+
+  parameter (NFFT=8192)
+  parameter (NSZ=3413)                         !NFFT*5000/12000
+  parameter (MAXHSYM=322)
+  real*8 hstep
+  real*4 dd(npts)
+  real*4 ss(MAXHSYM,NSZ)
+  real*4 savg(NSZ)
+  real*4 x(NFFT)
+  complex c(0:NFFT/2)
+  common/refspec/dfref,ref(NSZ)
+  equivalence (x,c)
+  save /refspec/
+
+  hstep=2048.d0*12000.d0/11025.d0              !half-symbol = 2229.116 samples
+  nsps=nint(2*hstep)
+  df=12000.0/NFFT
+  nhsym=npts/hstep - 1.0
+  savg=0.
+  fac1=1.e-3
+
+  do j=1,nhsym
+     i0=(j-1)*hstep
+     x(1:nsps)=fac1*dd(i0+1:i0+nsps)
+     x(nsps+1:)=0.
+     call four2a(c,NFFT,1,-1,0)                !r2c forward FFT
+     do i=1,NSZ
+        s=real(c(i))**2 + aimag(c(i))**2
+        ss(j,i)=s
+        savg(i)=savg(i)+s
+     enddo
+  enddo
+  savg=savg/nhsym
+
+  call flat65(ss,nhsym,MAXHSYM,NSZ,ref)  !Flatten the 2d spectrum, saving
+  dfref=df                               ! the reference spectrum ref()
+
+  savg=savg/ref
+  do j=1,nhsym
+     ss(j,1:NSZ)=ss(j,1:NSZ)/ref
+  enddo
+
+  return
+end subroutine symspec65
diff --git a/lib/sync24.f90 b/lib/sync24.f90
new file mode 100644
index 0000000..cf6bf5a
--- /dev/null
+++ b/lib/sync24.f90
@@ -0,0 +1,179 @@
+subroutine sync24(dat,jz,DFTolerance,NFreeze,MouseDF,mode,mode4,    &
+     dtx,dfx,snrx,snrsync,ccfblue,ccfred1,flip,width)
+
+! Synchronizes JT4 data, finding the best-fit DT and DF.  
+
+  parameter (NFFTMAX=2520)         !Max length of FFTs
+  parameter (NHMAX=NFFTMAX/2)      !Max length of power spectra
+  parameter (NSMAX=525)            !Max number of half-symbol steps
+  integer DFTolerance              !Range of DF search
+  real dat(jz)
+  real psavg(NHMAX)                !Average spectrum of whole record
+  real s2(NHMAX,NSMAX)             !2d spectrum, stepped by half-symbols
+  real ccfblue(-5:540)             !CCF with pseudorandom sequence
+  real ccfred(-450:450)            !Peak of ccfblue, as function of freq
+  real ccfred1(-224:224)           !Peak of ccfblue, as function of freq
+  real tmp(1260)
+  save
+
+! Do FFTs of twice symbol length, stepped by half symbols.  Note that 
+! we have already downsampled the data by factor of 2.
+
+  nsym=207
+  nfft=2520
+  nh=nfft/2
+  nq=nfft/4
+  nsteps=jz/nq - 1
+  df=0.5*11025.0/nfft
+  psavg(1:nh)=0.
+
+  do j=1,nsteps                     !Compute spectrum for each step, get average
+     k=(j-1)*nq + 1
+     call ps24(dat(k),nfft,s2(1,j))
+     psavg(1:nh)=psavg(1:nh) + s2(1:nh,j)
+  enddo
+
+  call flat1(psavg,s2,nh,nsteps,NHMAX,NSMAX)        !Flatten spectra
+
+! Set freq and lag ranges
+  famin=200.
+  fbmax=2700.
+  fa=famin
+  fb=fbmax
+  if(NFreeze.eq.1) then
+     fa=max(famin,1270.46+MouseDF-DFTolerance)
+     fb=min(fbmax,1270.46+MouseDF+DFTolerance)
+  else
+     fa=max(famin,1270.46+MouseDF-600)
+     fb=min(fbmax,1270.46+MouseDF+600)
+  endif
+  ia=fa/df
+  ib=fb/df
+  if(mode.eq.7) then
+     ia=ia - 3*mode4
+     ib=ib - 3*mode4
+  endif
+  i0=nint(1270.46/df)
+  lag1=-5
+  lag2=59
+  syncbest=-1.e30
+  syncbest2=-1.e30
+  ccfred=0.
+
+  do i=ia,ib                                !Find best frequency channel for CCF
+
+     call xcor24(s2,i,nsteps,nsym,lag1,lag2,mode4,ccfblue,ccf0,lagpk0,flip)
+     j=i-i0
+     if(mode.eq.7) j=j + 3*mode4
+     if(j.ge.-372 .and. j.le.372) ccfred(j)=ccf0
+
+! Find rms of the CCF, without main peak
+     call slope(ccfblue(lag1),lag2-lag1+1,lagpk0-lag1+1.0)
+     sync=abs(ccfblue(lagpk0))
+     ppmax=psavg(i)-1.0
+
+! Find best sync value
+     if(sync.gt.syncbest2) then
+        ipk2=i
+        lagpk2=lagpk0
+        syncbest2=sync
+     endif
+
+! We are most interested if snrx will be more than -30 dB.
+     if(ppmax.gt.0.2938) then            !Corresponds to snrx.gt.-30.0
+        if(sync.gt.syncbest) then
+           ipk=i
+           lagpk=lagpk0
+           syncbest=sync
+        endif
+     endif
+  enddo
+
+! If we found nothing with snrx > -30 dB, take the best sync that *was* found.
+  if(syncbest.lt.-10.) then
+     ipk=ipk2
+     lagpk=lagpk2
+     syncbest=syncbest2
+  endif
+
+  dfx=(ipk-i0)*df
+  if(mode.eq.7) dfx=dfx + 3*mode4*df
+
+! Peak up in time, at best whole-channel frequency
+  call xcor24(s2,ipk,nsteps,nsym,lag1,lag2,mode4,ccfblue,ccfmax,lagpk,flip)
+  xlag=lagpk
+  if(lagpk.gt.lag1 .and. lagpk.lt.lag2) then
+     call peakup(ccfblue(lagpk-1),ccfmax,ccfblue(lagpk+1),dx2)
+     xlag=lagpk+dx2
+  endif
+
+! Find rms of the CCF, without the main peak
+  call slope(ccfblue(lag1),lag2-lag1+1,xlag-lag1+1.0)
+  sq=0.
+  nsq=0
+  do lag=lag1,lag2
+     if(abs(lag-xlag).gt.2.0) then
+        sq=sq+ccfblue(lag)**2
+        nsq=nsq+1
+     endif
+  enddo
+  rms=sqrt(sq/nsq)
+  snrsync=abs(ccfblue(lagpk))/rms - 1.1                       !Empirical
+
+  dt=2.0/11025.0
+  istart=xlag*nq
+  dtx=istart*dt
+  snrx=-99.0
+  ppmax=psavg(ipk)-1.0
+
+  if(ppmax.gt.0.0001) then
+     snrx=db(ppmax*df/2500.0) + 7.5        !Empirical
+     if(mode.eq.7) snrx=snrx + 3.0         !Empirical
+  endif
+  if(snrx.lt.-33.0) snrx=-33.0
+
+! Compute width of sync tone to outermost -3 dB points
+  i1=max(-450,ia-i0)
+  i2=min(450,ib-i0)
+  call pctile(ccfred(i1),i2-i1+1,45,base)
+
+  jpk=ipk-i0
+  if(abs(jpk).gt.450) then
+     print*,'sync24 a:',jpk,ipk,i0
+     snrsync=0.
+     go to 999
+  else
+     stest=base + 0.5*(ccfred(jpk)-base) ! -3 dB
+  endif
+  do i=-10,0
+     if(jpk+i.ge.-371) then 
+        if(ccfred(jpk+i).gt.stest) go to 30
+     endif
+  enddo
+  i=0
+30 continue
+  if(abs(jpk+i-1).gt.450 .or. abs(jpk+i).gt.450) then
+     print*,'sync24 b:',jpk,i
+  else
+     x1=i-0.5
+  endif
+
+  do i=10,0,-1
+     if(jpk+i.le.371) then
+        if(ccfred(jpk+i).gt.stest) go to 32
+     endif
+  enddo
+  i=0
+32 x2=i+0.5
+  width=x2-x1
+  if(width.gt.1.2) width=sqrt(width**2 - 1.44)
+  width=df*width
+  width=max(0.0,min(99.0,width))
+
+  do i=-224,224
+     ccfred1(i)=ccfred(i)
+  enddo
+
+999 return
+end subroutine sync24
+
diff --git a/lib/sync9.f90 b/lib/sync9.f90
new file mode 100644
index 0000000..433e11f
--- /dev/null
+++ b/lib/sync9.f90
@@ -0,0 +1,101 @@
+subroutine sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipkbest)
+
+  include 'constants.f90'
+!  parameter (NSMAX=1365)             !Max length of saved spectra
+  real ss(184,NSMAX)
+  real ss1(184)
+  real ccfred(NSMAX)
+  real savg(NSMAX)
+  real savg2(NSMAX)
+  real smo(-5:25)
+  real sq(NSMAX)
+  real red2(NSMAX)
+  include 'jt9sync.f90'
+
+  ipk=0
+  ipkbest=0
+  sbest=0.
+  ccfred=0.
+
+  do i=ia,ib                         !Loop over freq range
+     ss1=ss(1:184,i)
+     call pctile(ss1,nzhsym,40,xmed)
+!     xmed=sum(ss1(1:nzhsym))/nzhsym
+
+     ss1=ss1/xmed - 1.0
+     do j=1,nzhsym
+        if(ss1(j).gt.3.0) ss1(j)=3.0
+     enddo
+
+     call pctile(ss1,nzhsym,45,sbase)
+     ss1=ss1-sbase
+     sq0=dot_product(ss1(1:nzhsym),ss1(1:nzhsym))
+     rms=sqrt(sq0/(nzhsym-1))
+
+     smax=0.
+     do lag=lag1,lag2                !DT = 2.5 to 5.0 s
+        sum1=0.
+        sq2=sq0
+        nsum=nzhsym
+        do j=1,16                    !Sum over 16 sync symbols
+           k=ii2(j) + lag
+           if(k.ge.1 .and. k.le.nzhsym) then
+              sum1=sum1 + ss1(k)
+              sq2=sq2 - ss1(k)*ss1(k)
+              nsum=nsum-1
+           endif
+        enddo
+        if(sum1.gt.smax) then
+           smax=sum1
+           ipk=i 
+        endif
+        rms=sqrt(sq2/(nsum-1))
+     enddo
+     ccfred(i)=smax                        !Best at this freq, over all lags
+     if(smax.gt.sbest) then
+        sbest=smax
+        ipkbest=ipk
+     endif
+  enddo
+
+  call pctile(ccfred(ia),ib-ia+1,50,xmed)
+  if(xmed.le.0.0) xmed=1.0
+  ccfred=2.0*ccfred/xmed 
+
+  savg=0.
+  do j=1,nzhsym
+     savg(ia:ib)=savg(ia:ib) + ss(j,ia:ib)
+  enddo
+!  df=1500.0/2048.0                          ! 0.732422
+!  df9=12000.0/6912.0                        ! 1.736111
+  savg(ia:ib)=savg(ia:ib)/nzhsym
+  smo(0:20)=1.0/21.0
+  smo(-5:-1)=-(1.0/21.0)*(21.0/10.0)
+  smo(21:25)=smo(-5)
+
+  do i=ia,ib
+     sm=0.
+     do j=-5,25
+        if(i+j.ge.1 .and. i+j.lt.NSMAX) sm=sm + smo(j)*savg(i+j)
+     enddo
+     savg2(i)=sm
+     sq(i)=sm*sm
+  enddo
+
+  call pctile(sq(ia:ib),ib-ia+1,20,sq0)
+  rms=sqrt(sq0)
+  savg2(ia:ib)=savg2(ia:ib)/(5.0*rms)
+
+  red2=0.
+  do i=ia+11,ib-10
+     ref=max(savg2(i-10),savg2(i+10))
+     red2(i)=savg2(i)-ref
+     if(red2(i).lt.-99.0) red2(i)=-99.0
+     if(red2(i).gt.99.0) red2(i)=99.0
+!     write(30,3001) i,i*df+1000.0,savg2(i),red2(i),ccfred(i)
+!3001 format(i8,4f10.3)
+  enddo
+!  call flush(30)
+
+  return
+end subroutine sync9
diff --git a/lib/tab.c b/lib/tab.c
new file mode 100644
index 0000000..3cd419a
--- /dev/null
+++ b/lib/tab.c
@@ -0,0 +1,36 @@
+/* 8-bit parity lookup table, generated by partab.c */
+unsigned char Partab[] = {
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+};
+
diff --git a/lib/timer.f90 b/lib/timer.f90
new file mode 100644
index 0000000..1637493
--- /dev/null
+++ b/lib/timer.f90
@@ -0,0 +1,112 @@
+subroutine timer(dname,k)
+
+! Times procedure number n between a call with k=0 (tstart) and with
+! k=1 (tstop). Accumulates sums of these times in array ut (user time).
+! Also traces all calls (for debugging purposes) if limtrace.gt.0
+
+  character*8 dname,name(50),space,ename
+  character*16 sname
+  logical on(50)
+  real ut(50),ut0(50),dut(50)
+  integer ncall(50),nlevel(50),nparent(50)
+  integer onlevel(0:10)
+  common/tracer/ limtrace,lu
+  data eps/0.000001/,ntrace/0/
+  data level/0/,nmax/0/,space/'        '/
+  data limtrace/0/,lu/-1/
+  save
+
+  if(limtrace.lt.0) go to 999
+  if(lu.lt.1) lu=6
+  if(k.gt.1) go to 40                        !Check for "all done" (k>1)
+  onlevel(0)=0
+
+  do n=1,nmax                                !Check for existing name
+     if(name(n).eq.dname) go to 20
+  enddo
+
+  nmax=nmax+1                                !This is a new one
+  n=nmax
+  ncall(n)=0
+  on(n)=.false.
+  ut(n)=eps
+  name(n)=dname
+
+20 if(k.eq.0) then                                !Get start times (k=0)
+     if(on(n)) print*,'Error in timer: ',dname,' already on.'
+     level=level+1                                !Increment the level
+     on(n)=.true.
+     call system_clock(icount,irate)
+     ut0(n)=float(icount)/irate
+     ncall(n)=ncall(n)+1
+     if(ncall(n).gt.1.and.nlevel(n).ne.level) then
+        nlevel(n)=-1
+     else
+        nlevel(n)=level
+     endif
+     nparent(n)=onlevel(level-1)
+     onlevel(level)=n
+
+  else if(k.eq.1) then        !Get stop times and accumulate sums. (k=1)
+     if(on(n)) then
+        on(n)=.false.
+        call system_clock(icount,irate)
+        ut1=float(icount)/irate
+        ut(n)=ut(n)+ut1-ut0(n)
+     endif
+     level=level-1
+  endif
+
+  ntrace=ntrace+1
+  if(ntrace.lt.limtrace) write(lu,1020) ntrace,dname,k,level,nparent(n)
+1020 format(i8,': ',a8,3i5)
+  go to 998
+
+! Write out the timer statistics
+
+40 write(lu,1040)
+1040 format(/'     name                 time  frac     dtime',       &
+             ' dfrac  calls level parent'/73('-'))
+
+  if(k.gt.100) then
+     ndiv=k-100
+     do i=1,nmax
+        ncall(i)=ncall(i)/ndiv
+        ut(i)=ut(i)/ndiv
+     enddo
+  endif
+
+  total=ut(1)
+  sum=0.
+  sumf=0.
+  do i=1,nmax
+     dut(i)=ut(i)
+     do j=i,nmax
+        if(nparent(j).eq.i) dut(i)=dut(i)-ut(j)
+     enddo
+     utf=ut(i)/total
+     dutf=dut(i)/total
+     sum=sum+dut(i)
+     sumf=sumf+dutf
+     kk=nlevel(i)
+     sname=space(1:kk)//name(i)//space(1:8-kk)
+     ename=space
+     if(i.ge.2) ename=name(nparent(i))
+     write(lu,1060) float(i),sname,ut(i),utf,dut(i),dutf,           &
+          ncall(i),nlevel(i),ename
+1060 format(f4.0,a16,2(f10.2,f6.2),i7,i5,2x,a8)
+  enddo
+
+  write(lu,1070) sum,sumf
+1070 format(/36x,f10.2,f6.2)
+  nmax=0
+  eps=0.000001
+  ntrace=0
+  level=0
+  space='        '
+  onlevel(0)=0
+
+998 flush(lu)
+
+999 return
+end subroutine timer
diff --git a/lib/timeval.h b/lib/timeval.h
new file mode 100644
index 0000000..100dda5
--- /dev/null
+++ b/lib/timeval.h
@@ -0,0 +1,74 @@
+/*
+ * timeval.h    1.0 01/12/19
+ *
+ * Defines gettimeofday, timeval, etc. for Win32
+ *
+ * By Wu Yongwei
+ *
+ */
+
+#ifndef _TIMEVAL_H
+#define _TIMEVAL_H
+
+#ifdef _WIN32
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <time.h>
+
+#ifndef __GNUC__
+#define EPOCHFILETIME (116444736000000000i64)
+#else
+#define EPOCHFILETIME (116444736000000000LL)
+#endif
+
+//struct timeval {
+//    long tv_sec;        /* seconds */
+//    long tv_usec;  /* microseconds */
+//};
+
+struct timezone {
+    int tz_minuteswest; /* minutes W of Greenwich */
+    int tz_dsttime;     /* type of dst correction */
+};
+
+__inline int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+    FILETIME        ft;
+    LARGE_INTEGER   li;
+    __int64         t;
+    static int      tzflag;
+
+    if (tv)
+    {
+        GetSystemTimeAsFileTime(&ft);
+        li.LowPart  = ft.dwLowDateTime;
+        li.HighPart = ft.dwHighDateTime;
+        t  = li.QuadPart;       /* In 100-nanosecond intervals */
+        t -= EPOCHFILETIME;     /* Offset to the Epoch time */
+        t /= 10;                /* In microseconds */
+        tv->tv_sec  = (long)(t / 1000000);
+        tv->tv_usec = (long)(t % 1000000);
+    }
+
+    if (tz)
+    {
+        if (!tzflag)
+        {
+            _tzset();
+            tzflag++;
+        }
+        tz->tz_minuteswest = _timezone / 60;
+        tz->tz_dsttime = _daylight;
+    }
+
+    return 0;
+}
+
+#else  /* _WIN32 */
+
+#include <sys/time.h>
+
+#endif /* _WIN32 */
+
+#endif /* _TIMEVAL_H */
diff --git a/lib/tstrig.c b/lib/tstrig.c
new file mode 100644
index 0000000..2e77fea
--- /dev/null
+++ b/lib/tstrig.c
@@ -0,0 +1,26 @@
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "tstrig.h"
+
+int set_conf(RIG *my_rig, char *conf_parms);
+
+int rig_control(rig_model_t my_model, int verbose);
+
+int main (int argc, char *argv[])
+{
+  rig_model_t my_model = RIG_MODEL_DUMMY;
+  int verbose=0;
+
+  my_model=214;
+  rig_control(my_model,verbose);
+  return 0;
+}
+
+/*
+gcc -c -Wall -I../include rig_control.c
+gcc -c -Wall -I../include tstrig.c
+gcc -o tstrig.exe -Wl,--enable-auto-import tstrig.o rig_control.o libhamlib.dll.a
+strip tstrig.exe
+*/
diff --git a/lib/tstrig.h b/lib/tstrig.h
new file mode 100644
index 0000000..ce62d3d
--- /dev/null
+++ b/lib/tstrig.h
@@ -0,0 +1,50 @@
+/*
+ * rigctl_parse.h - (C) Stephane Fillod 2000-2010
+ *
+ * This program test/control a radio using Hamlib.
+ * It takes commands in interactive mode as well as
+ * from command line options.
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License along
+ *   with this program; if not, write to the Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef RIGCTL_PARSE_H
+#define RIGCTL_PARSE_H
+
+#include <stdio.h>
+#include <hamlib/rig.h>
+
+/*
+ * external prototype
+ */
+
+int dumpcaps (RIG *, FILE *);
+int dumpconf (RIG *, FILE *);
+
+/*
+ * Prototypes
+ */
+void usage_rig(FILE *);
+void version();
+void list_models();
+int dump_chan(FILE *, RIG*, channel_t*);
+int print_conf_list(const struct confparams *cfp, rig_ptr_t data);
+int set_conf(RIG *my_rig, char *conf_parms);
+
+int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc);
+
+#endif	/* RIGCTL_PARSE_H */
diff --git a/lib/twkfreq.f90 b/lib/twkfreq.f90
new file mode 100644
index 0000000..0a9b34d
--- /dev/null
+++ b/lib/twkfreq.f90
@@ -0,0 +1,28 @@
+subroutine twkfreq(c3,c4,npts,fsample,a)
+
+  complex c3(npts)
+  complex c4(npts)
+  complex w,wstep
+  real a(3)
+  data twopi/6.283185307/
+
+! Mix the complex signal
+  w=1.0
+  wstep=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
+     c4(i)=w*c3(i)
+  enddo
+
+  return
+end subroutine twkfreq
diff --git a/lib/twkfreq65.f90 b/lib/twkfreq65.f90
new file mode 100644
index 0000000..85847c7
--- /dev/null
+++ b/lib/twkfreq65.f90
@@ -0,0 +1,25 @@
+subroutine twkfreq65(c4aa,n5,a)
+
+  complex c4aa(n5)
+  real a(5)
+  complex w,wstep
+  data twopi/6.283185307/
+
+! Apply AFC corrections to the c4aa data
+  w=1.0
+  wstep=1.0
+  x0=0.5*(n5+1)
+  s=2.0/n5
+  do i=1,n5
+     x=s*(i-x0)
+     if(mod(i,100).eq.1) then
+        p2=1.5*x*x - 0.5
+        dphi=(a(1) + x*a(2) + p2*a(3)) * (twopi/1378.125)
+        wstep=cmplx(cos(dphi),sin(dphi))
+     endif
+     w=w*wstep
+     c4aa(i)=w*c4aa(i)
+  enddo
+
+  return
+end subroutine twkfreq65
diff --git a/lib/unpackbits.f90 b/lib/unpackbits.f90
new file mode 100644
index 0000000..a3ff15f
--- /dev/null
+++ b/lib/unpackbits.f90
@@ -0,0 +1,22 @@
+subroutine unpackbits(sym,nsymd,m0,dbits)
+
+! Unpack bits from sym() into dbits(), one bit per byte.
+! NB: nsymd is the number of input words, and m0 their length.
+! there will be m0*nsymd output bytes, each 0 or 1.
+
+  integer sym(nsymd)
+  integer*1 dbits(*)
+
+  k=0
+  do i=1,nsymd
+     mask=ishft(1,m0-1)
+     do j=1,m0
+        k=k+1
+        dbits(k)=0
+        if(iand(mask,sym(i)).ne.0) dbits(k)=1
+        mask=ishft(mask,-1)
+     enddo
+  enddo
+
+  return
+end subroutine unpackbits
diff --git a/lib/unpackcall.f90 b/lib/unpackcall.f90
new file mode 100644
index 0000000..f738926
--- /dev/null
+++ b/lib/unpackcall.f90
@@ -0,0 +1,142 @@
+subroutine unpackcall(ncall,word,iv2,psfx)
+
+  parameter (NBASE=37*36*10*27*27*27)
+  character word*12,c*37,psfx*4
+
+  data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ '/
+
+  n=ncall
+  iv2=0
+  if(n.ge.262177560) go to 20
+  word='......'
+  if(n.ge.262177560) go to 999            !Plain text message ...
+  i=mod(n,27)+11
+  word(6:6)=c(i:i)
+  n=n/27
+  i=mod(n,27)+11
+  word(5:5)=c(i:i)
+  n=n/27
+  i=mod(n,27)+11
+  word(4:4)=c(i:i)
+  n=n/27
+  i=mod(n,10)+1
+  word(3:3)=c(i:i)
+  n=n/10
+  i=mod(n,36)+1
+  word(2:2)=c(i:i)
+  n=n/36
+  i=n+1
+  word(1:1)=c(i:i)
+  do i=1,4
+     if(word(i:i).ne.' ') go to 10
+  enddo
+  go to 999
+10 word=word(i:)
+  go to 999
+
+20 if(n.ge.267796946) go to 999
+
+! We have a JT65v2 message
+  if((n.ge.262178563) .and. (n.le.264002071)) Then
+! CQ with prefix
+     iv2=1
+     n=n-262178563
+     i=mod(n,37)+1
+     psfx(4:4)=c(i:i)
+     n=n/37
+     i=mod(n,37)+1
+     psfx(3:3)=c(i:i)
+     n=n/37
+     i=mod(n,37)+1
+     psfx(2:2)=c(i:i)
+     n=n/37
+     i=n+1
+     psfx(1:1)=c(i:i)
+  endif
+
+  if((n.ge.264002072) .and. (n.le.265825580)) Then
+! QRZ with prefix
+     iv2=2
+     n=n-264002072
+     i=mod(n,37)+1
+     psfx(4:4)=c(i:i)
+     n=n/37
+     i=mod(n,37)+1
+     psfx(3:3)=c(i:i)
+     n=n/37
+     i=mod(n,37)+1
+     psfx(2:2)=c(i:i)
+     n=n/37
+     i=n+1
+     psfx(1:1)=c(i:i)
+  endif
+
+  if((n.ge.265825581) .and. (n.le.267649089)) Then
+! DE with prefix
+     iv2=3
+     n=n-265825581
+     i=mod(n,37)+1
+     psfx(4:4)=c(i:i)
+     n=n/37
+     i=mod(n,37)+1
+     psfx(3:3)=c(i:i)
+     n=n/37
+     i=mod(n,37)+1
+     psfx(2:2)=c(i:i)
+     n=n/37
+     i=n+1
+     psfx(1:1)=c(i:i)
+  endif
+
+  if((n.ge.267649090) .and. (n.le.267698374)) Then
+! CQ with suffix
+     iv2=4
+     n=n-267649090
+     i=mod(n,37)+1
+     psfx(3:3)=c(i:i)
+     n=n/37
+     i=mod(n,37)+1
+     psfx(2:2)=c(i:i)
+     n=n/37
+     i=n+1
+     psfx(1:1)=c(i:i)
+  endif
+
+  if((n.ge.267698375) .and. (n.le.267747659)) Then
+! QRZ with suffix
+     iv2=5
+     n=n-267698375
+     i=mod(n,37)+1
+     psfx(3:3)=c(i:i)
+     n=n/37
+     i=mod(n,37)+1
+     psfx(2:2)=c(i:i)
+     n=n/37
+     i=n+1
+     psfx(1:1)=c(i:i)
+  endif
+
+  if((n.ge.267747660) .and. (n.le.267796944)) Then
+! DE with suffix
+     iv2=6
+     n=n-267747660
+     i=mod(n,37)+1
+     psfx(3:3)=c(i:i)
+     n=n/37
+     i=mod(n,37)+1
+     psfx(2:2)=c(i:i)
+     n=n/37
+     i=n+1
+     psfx(1:1)=c(i:i)
+  endif
+
+  if(n.eq.267796945) Then
+! DE with no prefix or suffix
+     iv2=7
+     psfx = '    '
+  endif
+
+999 if(word(1:3).eq.'3D0') word='3DA0'//word(4:)
+
+  return
+end subroutine unpackcall
diff --git a/lib/unpackgrid.f90 b/lib/unpackgrid.f90
new file mode 100644
index 0000000..84dc744
--- /dev/null
+++ b/lib/unpackgrid.f90
@@ -0,0 +1,45 @@
+subroutine unpackgrid(ng,grid)
+
+  parameter (NGBASE=180*180)
+  character grid*4,grid6*6
+
+  grid='    '
+  if(ng.ge.32400) go to 10
+  dlat=mod(ng,180)-90
+  dlong=(ng/180)*2 - 180 + 2
+  call deg2grid(dlong,dlat,grid6)
+  grid=grid6(:4)
+  if(grid(1:2).eq.'KA') then
+     read(grid(3:4),*) n
+     n=n-50
+     write(grid,1001) n
+1001 format(i3.2)
+     if(grid(1:1).eq.' ') grid(1:1)='+'
+  else if(grid(1:2).eq.'LA') then
+     read(grid(3:4),*) n
+     n=n-50
+     write(grid,1002) n
+1002 format('R',i3.2)
+     if(grid(2:2).eq.' ') grid(2:2)='+'
+  endif
+  go to 900
+
+10 n=ng-NGBASE-1
+  if(n.ge.1 .and.n.le.30) then
+     write(grid,1012) -n
+1012 format(i3.2)
+  else if(n.ge.31 .and.n.le.60) then
+     n=n-30
+     write(grid,1022) -n
+1022 format('R',i3.2)
+  else if(n.eq.61) then
+     grid='RO'
+  else if(n.eq.62) then
+     grid='RRR'
+  else if(n.eq.63) then
+     grid='73'
+  endif
+
+900 return
+end subroutine unpackgrid
+
diff --git a/lib/unpackmsg.f90 b/lib/unpackmsg.f90
new file mode 100644
index 0000000..aca7cfc
--- /dev/null
+++ b/lib/unpackmsg.f90
@@ -0,0 +1,107 @@
+subroutine unpackmsg(dat,msg)
+
+  parameter (NBASE=37*36*10*27*27*27)
+  parameter (NGBASE=180*180)
+  integer dat(12)
+  character c1*12,c2*12,grid*4,msg*22,grid6*6,psfx*4,junk2*4
+  logical cqnnn
+
+  cqnnn=.false.
+  nc1=ishft(dat(1),22) + ishft(dat(2),16) + ishft(dat(3),10)+         &
+       ishft(dat(4),4) + iand(ishft(dat(5),-2),15)
+
+  nc2=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)
+
+  ng=ishft(iand(dat(10),15),12) + ishft(dat(11),6) + dat(12)
+
+  if(ng.ge.32768) then
+     call unpacktext(nc1,nc2,ng,msg)
+     go to 100
+  endif
+
+  call unpackcall(nc1,c1,iv2,psfx)
+  if(iv2.eq.0) then
+! This is an "original JT65" message
+     if(nc1.eq.NBASE+1) c1='CQ    '
+     if(nc1.eq.NBASE+2) c1='QRZ   '
+     nfreq=nc1-NBASE-3
+     if(nfreq.ge.0 .and. nfreq.le.999) then
+        write(c1,1002) nfreq
+1002    format('CQ ',i3.3)
+        cqnnn=.true.
+     endif
+  endif
+
+  call unpackcall(nc2,c2,junk1,junk2)
+  call unpackgrid(ng,grid)
+
+  if(iv2.gt.0) then
+! This is a JT65v2 message
+     do i=1,4
+        if(ichar(psfx(i:i)).eq.0) psfx(i:i)=' '
+     enddo
+
+     n1=len_trim(psfx)
+     n2=len_trim(c2)
+     if(iv2.eq.1) msg='CQ '//psfx(:n1)//'/'//c2(:n2)//' '//grid
+     if(iv2.eq.2) msg='QRZ '//psfx(:n1)//'/'//c2(:n2)//' '//grid
+     if(iv2.eq.3) msg='DE '//psfx(:n1)//'/'//c2(:n2)//' '//grid
+     if(iv2.eq.4) msg='CQ '//c2(:n2)//'/'//psfx(:n1)//' '//grid
+     if(iv2.eq.5) msg='QRZ '//c2(:n2)//'/'//psfx(:n1)//' '//grid
+     if(iv2.eq.6) msg='DE '//c2(:n2)//'/'//psfx(:n1)//' '//grid
+     if(iv2.eq.7) msg='DE '//c2(:n2)//' '//grid
+     go to 100
+  else
+     
+  endif
+
+  grid6=grid//'ma'
+  call grid2k(grid6,k)
+  if(k.ge.1 .and. k.le.450)   call getpfx2(k,c1)
+  if(k.ge.451 .and. k.le.900) call getpfx2(k,c2)
+
+  i=index(c1,char(0))
+  if(i.ge.3) c1=c1(1:i-1)//'            '
+  i=index(c2,char(0))
+  if(i.ge.3) c2=c2(1:i-1)//'            '
+
+  msg='                      '
+  j=0
+  if(cqnnn) then
+     msg=c1//'          '
+     j=7                                  !### ??? ###
+     go to 10
+  endif
+
+  do i=1,12
+     j=j+1
+     msg(j:j)=c1(i:i)
+     if(c1(i:i).eq.' ') go to 10
+  enddo
+  j=j+1
+  msg(j:j)=' '
+
+10 do i=1,12
+     if(j.le.21) j=j+1
+     msg(j:j)=c2(i:i)
+     if(c2(i:i).eq.' ') go to 20
+  enddo
+  if(j.le.21) j=j+1
+  msg(j:j)=' '
+
+20 if(k.eq.0) then
+     do i=1,4
+        if(j.le.21) j=j+1
+        msg(j:j)=grid(i:i)
+     enddo
+     if(j.le.21) j=j+1
+     msg(j:j)=' '
+  endif
+
+100 continue
+  if(msg(1:6).eq.'CQ9DX ') msg(3:3)=' '
+
+  return
+end subroutine unpackmsg
diff --git a/lib/unpacktext.f90 b/lib/unpacktext.f90
new file mode 100644
index 0000000..62451f9
--- /dev/null
+++ b/lib/unpacktext.f90
@@ -0,0 +1,35 @@
+subroutine unpacktext(nc1,nc2,nc3,msg)
+
+  character*22 msg
+  character*44 c
+  data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-./?'/
+
+  nc3=iand(nc3,32767)                      !Remove the "plain text" bit
+  if(iand(nc1,1).ne.0) nc3=nc3+32768
+  nc1=nc1/2
+  if(iand(nc2,1).ne.0) nc3=nc3+65536
+  nc2=nc2/2
+
+  do i=5,1,-1
+     j=mod(nc1,42)+1
+     msg(i:i)=c(j:j)
+     nc1=nc1/42
+  enddo
+
+  do i=10,6,-1
+     j=mod(nc2,42)+1
+     msg(i:i)=c(j:j)
+     nc2=nc2/42
+  enddo
+
+  do i=13,11,-1
+     j=mod(nc3,42)+1
+     msg(i:i)=c(j:j)
+     nc3=nc3/42
+  enddo
+  msg(14:22) = '         '
+
+  return
+end subroutine unpacktext
+
+
diff --git a/lib/vit216.c b/lib/vit216.c
new file mode 100644
index 0000000..38984d2
--- /dev/null
+++ b/lib/vit216.c
@@ -0,0 +1,219 @@
+/* Viterbi decoder for arbitrary convolutional code
+ * viterbi27 and viterbi37 for the r=1/2 and r=1/3 K=7 codes are faster
+ * Copyright 1999 Phil Karn, KA9Q
+ * May be used under the terms of the GNU Public License
+ */
+
+/* Select code here */
+
+#define V216
+
+
+#ifdef V216
+#define	K 16			/* Constraint length */
+#define N 2			/* Number of symbols per data bit */
+#define Polys	Poly216		/* Select polynomials here */
+#endif
+
+/* Rate 1/2 codes */
+unsigned int Poly216[] = {0126723, 0152711};	/* k = 16  */
+
+#include <memory.h>
+#define NULL ((void *)0)
+
+#define LONGBITS 32
+#define LOGLONGBITS 5
+
+#undef max
+#define max(x,y) ((x) > (y) ? (x) : (y))
+#define D       (1 << max(0,K-LOGLONGBITS-1))
+#define MAXNBITS 200            /* Maximum frame size (user bits) */
+
+extern unsigned char Partab[];	/* Parity lookup table */
+
+int Syms[1 << K];
+int VDInit = 0;
+
+int parity(int x)
+{
+  x ^= (x >> 16);
+  x ^= (x >> 8);
+  return Partab[x & 0xff];
+}
+
+// Wrapper for calling "encode" from Fortran:
+//void __stdcall ENCODE(
+void enc216_(
+unsigned char data[],           // User data, 8 bits per byte
+int *nbits,                     // Number of user bits
+unsigned char symbols[],        // Encoded one-bit symbols, 8 per byte
+int *nsymbols,                  // Number of symbols
+int *kk,                        // K
+int *nn)                        // N
+{
+  int nbytes;
+  nbytes=(*nbits+7)/8;          // Always encode multiple of 8 information bits
+  enc216(symbols,data,nbytes,0,0); // Do the encoding
+  *nsymbols=(*nbits+K-1)*N;        // Return number of encoded symbols
+  *kk=K;
+  *nn=N;
+}
+
+/* Convolutionally encode data into binary symbols */
+  enc216(unsigned char symbols[], unsigned char data[],
+       unsigned int nbytes, unsigned int startstate,
+       unsigned int endstate)
+{
+  int i,j,k,n=-1;
+  unsigned int encstate = startstate;
+
+  for(k=0; k<nbytes; k++) {
+    for(i=7;i>=0;i--){
+      encstate = (encstate + encstate) + ((data[k] >> i) & 1);
+      for(j=0;j<N;j++) {
+	n=n+1;
+	symbols[n] = parity(encstate & Polys[j]);
+      }
+    }
+  }
+  // Flush out with zero tail.  (No need, if tail-biting code.)
+  for(i=0; i<K-1;i++){
+    encstate = (encstate << 1) | ((endstate >> i) & 1);
+    for(j=0;j<N;j++) {
+      n=n+1;
+      symbols[n] = parity(encstate & Polys[j]);
+    }
+  }
+  return 0;
+}
+
+// Wrapper for calling "viterbi" from Fortran:
+//void __stdcall VITERBI(
+void vit216_(
+unsigned char symbols[],  /* Raw deinterleaved input symbols */
+unsigned int *Nbits,	  /* Number of decoded information bits */
+int mettab[2][256],	  /* Metric table, [sent sym][rx symbol] */
+unsigned char ddec[],	  /* Decoded output data */
+long *Metric              /* Final path metric (bigger is better) */
+){
+  long metric;
+  vit216(&metric,ddec,symbols,*Nbits,mettab,0,0);
+  *Metric=metric;
+}
+
+/* Viterbi decoder */
+int vit216(
+long *metric,           /* Final path metric (returned value) */
+unsigned char *data,	/* Decoded output data */
+unsigned char *symbols,	/* Raw deinterleaved input symbols */
+unsigned int nbits,	/* Number of output bits */
+int mettab[2][256],	/* Metric table, [sent sym][rx symbol] */
+unsigned int startstate,         /* Encoder starting state */
+unsigned int endstate            /* Encoder ending state */
+){
+  int bitcnt = -(K-1);
+  long m0,m1;
+  int i,j,sym,ipp;
+  int mets[1 << N];
+  unsigned long paths[(MAXNBITS+K-1)*D];
+  unsigned long *pp,mask;
+  long cmetric[1 << (K-1)],nmetric[1 << (K-1)];
+  
+  memset(paths,0,sizeof(paths));
+
+  // Initialize on first time through:
+  if(!VDInit){
+    for(i=0;i<(1<<K);i++){
+      sym = 0;
+      for(j=0;j<N;j++)
+	sym = (sym << 1) + parity(i & Polys[j]);
+      Syms[i] = sym;
+    }
+    VDInit++;
+  }
+
+  // Keep only lower K-1 bits of specified startstate and endstate
+  startstate &= ~((1<<(K-1)) - 1);
+  endstate &=   ~((1<<(K-1)) - 1);
+
+  /* Initialize starting metrics */
+  for(i=0;i< 1<<(K-1);i++)
+    cmetric[i] = -999999;
+  cmetric[startstate] = 0;
+
+  pp = paths;
+  ipp=0;
+  for(;;){ /* For each data bit */
+    /* Read input symbols and compute branch metrics */
+    for(i=0;i< 1<<N;i++){
+      mets[i] = 0;
+      for(j=0;j<N;j++){
+	mets[i] += mettab[(i >> (N-j-1)) & 1][symbols[j]];
+      }
+    }
+    symbols += N;
+    /* Run the add-compare-select operations */
+    mask = 1;
+    for(i=0;i< 1 << (K-1);i+=2){
+      int b1,b2;
+      
+      b1 = mets[Syms[i]];
+      nmetric[i] = m0 = cmetric[i/2] + b1; 
+      b2 = mets[Syms[i+1]];
+      b1 -= b2;
+      m1 = cmetric[(i/2) + (1<<(K-2))] + b2;
+
+      if(m1 > m0){
+	nmetric[i] = m1;
+	*pp |= mask;
+      }
+
+      m0 -= b1;
+      nmetric[i+1] = m0;
+      m1 += b1;
+
+      if(m1 > m0){
+	nmetric[i+1] = m1;
+	*pp |= mask << 1;
+      }
+
+      mask <<= 2;
+      if(mask == 0){
+	mask = 1;
+	pp++;
+	ipp++;
+      }
+    }
+    if(mask != 1){
+      pp++;
+      ipp++;
+    }
+    if(++bitcnt == nbits){
+      *metric = nmetric[endstate];
+      break;
+    }
+    memcpy(cmetric,nmetric,sizeof(cmetric));
+  }
+
+  /* Chain back from terminal state to produce decoded data */
+  if(data == NULL)
+    return 0;/* Discard output */
+  memset(data,0,(nbits+7)/8); /* round up in case nbits % 8 != 0 */
+
+  for(i=nbits-1;i >= 0;i--){
+    //    int a0,a1;
+    pp -= D;
+    ipp -= D;
+    m0=endstate >> LOGLONGBITS;
+    m1=1L << (endstate & (LONGBITS-1));
+    if(pp[m0] & m1) {
+      //      a0=nmetric[endstate];
+      endstate |= (1 << (K-1));
+      //      a1=nmetric[endstate];
+      data[i>>3] |= 0x80 >> (i&7);
+      //      printf("B  %d  %d  %d  %d\n",*metric,i,a0,a1);
+    }
+    endstate >>= 1;
+  }
+  return 0;
+}
diff --git a/lib/wrapkarn.c b/lib/wrapkarn.c
new file mode 100644
index 0000000..1b1a631
--- /dev/null
+++ b/lib/wrapkarn.c
@@ -0,0 +1,70 @@
+#include <math.h>
+#include <stdio.h>
+#include <float.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "rs.h"
+
+static void *rs;
+static int first=1;
+
+void rs_encode_(int *dgen, int *sent)
+// Encode JT65 data dgen[12], producing sent[63].
+{
+  int dat1[12];
+  int b[51];
+  int i;
+
+  if(first) {
+    // Initialize the JT65 codec
+    rs=init_rs_int(6,0x43,3,1,51,0);
+    first=0;
+  }
+
+  // Reverse data order for the Karn codec.
+  for(i=0; i<12; i++) {
+    dat1[i]=dgen[11-i];
+  }
+  // Compute the parity symbols
+  encode_rs_int(rs,dat1,b);
+
+  // Move parity symbols and data into sent[] array, in reverse order.
+  for (i = 0; i < 51; i++) sent[50-i] = b[i];
+  for (i = 0; i < 12; i++) sent[i+51] = dat1[11-i];
+}
+
+void rs_decode_(int *recd0, int *era0, int *numera0, int *decoded, int *nerr)
+// Decode JT65 received data recd0[63], producing decoded[12].
+// Erasures are indicated in era0[numera].  The number of corrected
+// errors is *nerr.  If the data are uncorrectable, *nerr=-1 is returned.
+{
+  int numera;
+  int i;
+  int era_pos[50];
+  int recd[63];
+
+  if(first) {
+    rs=init_rs_int(6,0x43,3,1,51,0);
+    first=0;
+  }
+
+  numera=*numera0;
+  for(i=0; i<12; i++) recd[i]=recd0[62-i];
+  for(i=0; i<51; i++) recd[12+i]=recd0[50-i];
+  if(numera) 
+    for(i=0; i<numera; i++) era_pos[i]=era0[i];
+  *nerr=decode_rs_int(rs,recd,era_pos,numera);
+  for(i=0; i<12; i++) decoded[i]=recd[11-i];
+}
+
+
+void rs_encode__(int *dgen, int *sent)
+{
+  rs_encode_(dgen, sent);
+}
+
+void rs_decode__(int *recd0, int *era0, int *numera0, int *decoded, int *nerr)
+{
+  rs_decode_(recd0, era0, numera0, decoded, nerr);
+}
+
diff --git a/lib/wsjt24.f90 b/lib/wsjt24.f90
new file mode 100644
index 0000000..574f1dd
--- /dev/null
+++ b/lib/wsjt24.f90
@@ -0,0 +1,181 @@
+subroutine wsjt24(dat,npts,cfile6,NClearAve,MinSigdB,                  &
+     DFTolerance,NFreeze,mode,mode4,Nseg,MouseDF,NAgain,               &
+     idf,lumsg,lcum,nspecial,ndf,NSyncOK,ccfblue,ccfred,ndiag)
+
+! Orchestrates the process of decoding JT4 messages, using data that 
+! have been 2x downsampled.  
+! No message averaging and no deep search, at present.
+
+  parameter (MAXAVE=120)
+  real dat(npts)                                     !Raw data
+  real*4 ccfblue(-5:540)                             !CCF in time
+  real*4 ccfred(-224:224)                            !CCF in frequency
+  integer DFTolerance
+  logical first
+  logical lcum
+  character decoded*22,cfile6*6,special*5,cooo*3
+  character*22 avemsg1,avemsg2,deepmsg
+  character*77 line,ave1,ave2
+  character*1 csync,c1
+  character*12 mycall
+  character*12 hiscall
+  character*6 hisgrid
+  character submode*1
+  real*4 ccfbluesum(-5:540),ccfredsum(-224:224)
+  common/ave/ppsave(207,7,MAXAVE),nflag(MAXAVE),nsave,iseg(MAXAVE)
+  data first/.true./,ns10/0/,ns20/0/
+  save
+
+  if(first) then
+     nsave=0
+     first=.false.
+     ave1=' '
+     ave2=' '
+     ccfblue=0.
+     ccfred=0.
+     if(nspecial.eq.999) go to 900        !Silence compiler warning
+  endif
+
+  ndepth=3                                !###
+  naggressive=0
+  if(ndepth.ge.2) naggressive=1
+  nq1=3
+  nq2=6
+  if(naggressive.eq.1) nq1=1
+
+  if(NClearAve.ne.0) then
+     nsave=0                        !Clear the averaging accumulators
+     ns10=0
+     ns20=0
+     ave1=' '
+     ave2=' '
+  endif
+  if(MinSigdB.eq.99 .or. MinSigdB.eq.-99) then
+     ns10=0                         !For Include/Exclude ?
+     ns20=0
+  endif
+
+! Attempt to synchronize: look for sync pattern, get DF and DT.
+  call sync24(dat,npts,DFTolerance,NFreeze,MouseDF,mode,             &
+       mode4,dtx,dfx,snrx,snrsync,ccfblue,ccfred,flip,width)
+
+  csync=' '
+  decoded='                      '
+  deepmsg='                      '
+  special='     '
+  cooo='   '
+  ncount=-1             !Flag for RS decode of current record
+  ncount1=-1            !Flag for RS Decode of ave1
+  ncount2=-1            !Flag for RS Decode of ave2
+  NSyncOK=0
+  nqual1=0
+  nqual2=0
+
+  if(nsave.lt.MAXAVE .and. (NAgain.eq.0 .or. NClearAve.eq.1)) nsave=nsave+1
+  if(nsave.le.0) go to 900          !Prevent bounds error
+  
+  nflag(nsave)=0                    !Clear the "good sync" flag
+  iseg(nsave)=Nseg                  !Set the RX segment to 1 or 2
+  nsync=nint(snrsync-3.0)
+  nsnr=nint(snrx)
+  if(nsnr.lt.-30 .or. nsync.lt.0) nsync=0
+  nsnrlim=-33
+  if(nsync.lt.MinSigdB .or. nsnr.lt.nsnrlim) go to 200
+
+! If we get here, we have achieved sync!
+  NSyncOK=1
+  nflag(nsave)=1            !Mark this RX file as good
+  csync='*'
+  if(flip.lt.0.0) then
+     csync='#'
+     cooo='O ?'
+  endif
+
+  call decode24(dat,npts,dtx,dfx,flip,mode,mode4,decoded,           &
+       ncount,deepmsg,qual,submode)
+
+200 kvqual=0
+  if(ncount.ge.0) kvqual=1
+  nqual=qual
+  if(ndiag.eq.0 .and. nqual.gt.10) nqual=10
+  if(nqual.ge.nq1 .and.kvqual.eq.0) decoded=deepmsg
+
+  ndf=nint(dfx)
+  if(flip.lt.0.0 .and. (kvqual.eq.1 .or. nqual.ge.nq2)) cooo='OOO'
+  if(kvqual.eq.0.and.nqual.ge.nq1.and.nqual.lt.nq2) cooo(2:3)=' ?'
+  if(decoded.eq.'                      ') cooo='   '
+  do i=1,22
+     c1=decoded(i:i)
+     if(c1.ge.'a' .and. c1.le.'z') decoded(i:i)=char(ichar(c1)-32)
+  enddo
+  jdf=ndf+idf
+
+!  call cs_lock('wsjt24')
+  write(line,1010) cfile6,nsync,nsnr,dtx-1.0,jdf,nint(width),         &
+       csync,special,decoded(1:19),cooo,kvqual,nqual,submode
+1010 format(a6,i3,i5,f5.1,i5,i3,1x,a1,1x,a5,a19,1x,a3,i3,i5,1x,a1)
+
+! Blank all end-of-line stuff if no decode
+  if(line(31:40).eq.'          ') line=line(:30)
+
+  if(lcum) write(21,1011) line
+
+! Write decoded msg unless this is an "Exclude" request:
+  if(MinSigdB.lt.99) write(*,1011) line
+1011 format(a77)
+
+  if(nsave.ge.1) call avemsg4(1,mode4,ndepth,                        &
+       avemsg1,nused1,nq1,nq2,neme,mycall,hiscall,hisgrid,qual1,     &
+       ns1,ncount1)
+  if(nsave.ge.1) call avemsg4(2,mode4,ndepth,                        &
+       avemsg2,nused2,nq1,nq2,neme,mycall,hiscall,hisgrid,qual2,     &
+       ns2,ncount2)
+  nqual1=qual1
+  nqual2=qual2
+  if(ndiag.eq.0 .and. nqual1.gt.10) nqual1=10
+  if(ndiag.eq.0 .and. nqual2.gt.10) nqual2=10
+  nc1=0
+  nc2=0
+  if(ncount1.ge.0) nc1=1
+  if(ncount2.ge.0) nc2=1
+
+! Write the average line
+  if(ns1.ge.1) then
+     if(ns1.lt.10) write(ave1,1021) cfile6,1,nused1,ns1,avemsg1,nc1,nqual1
+1021 format(a6,i3,i4,'/',i1,20x,a19,i7,i5)
+     if(ns1.ge.10 .and. nsave.le.99) write(ave1,1022) cfile6,        &
+          1,nused1,ns1,avemsg1,nc1,nqual1
+1022 format(a6,i3,i4,'/',i2,19x,a19,i7,i5)
+     if(ns1.ge.100) write(ave1,1023) cfile6,1,nused1,ns1,            &
+          avemsg1,nc1,nqual1
+1023 format(a6,i3,i4,'/',i3,18x,a19,i7,i5)
+     if(lcum .and. (avemsg1.ne.'                  '))                &
+          write(21,1011) ave1
+     ns10=ns1
+  endif
+
+! If Monitor segment #2 is available, write that line also
+  if(ns2.ge.1) then
+     if(ns2.lt.10) write(ave2,1021) cfile6,2,nused2,ns2,avemsg2,nc2,nqual2
+     if(ns2.ge.10 .and. nsave.le.99) write(ave2,1022) cfile6,       &
+          2,nused2,ns2,avemsg2,nc2,nqual2
+     if(ns2.ge.100) write(ave2,1023) cfile6,2,nused2,ns2,avemsg2,nc2,nqual2
+     if(lcum .and. (avemsg2.ne.'                  '))               &
+          write(21,1011) ave2
+     ns20=ns2
+  endif
+
+  if(ave1(31:40).eq.'          ') ave1=ave1(:30)
+  if(ave2(31:40).eq.'          ') ave2=ave2(:30)
+  write(12,1011) ave1
+  write(12,1011) ave2
+  call flush(12)
+!  call cs_unlock
+  
+900 continue
+
+  ccfbluesum=ccfbluesum + ccfblue
+  ccfredsum=ccfredsum + ccfred
+
+  return
+end subroutine wsjt24
diff --git a/lib/wsjt24d.f90 b/lib/wsjt24d.f90
new file mode 100644
index 0000000..005e809
--- /dev/null
+++ b/lib/wsjt24d.f90
@@ -0,0 +1,43 @@
+program wsjt24d
+
+  real*4 dat(60*11025/2)
+  character*6 cfile6
+  character*12 arg
+  real ccfblue(-5:540)        !X-cor function in JT65 mode (blue line)
+  real ccfred(450)            !Average spectrum of the whole file
+  integer dftolerance
+
+  nargs=iargc()
+  if(nargs.ne.2) then
+     print*,'Usage: wspr24d ifile1 ifile2'
+     go to 999
+  endif
+  call getarg(1,arg)
+  read(arg,*) ifile1
+  call getarg(2,arg)
+  read(arg,*) ifile2
+
+  open(23,file='CALL3.TXT',status='old')
+  open(50,file='vk7mo.dat',form='unformatted',status='old')
+
+  do ifile=1,ifile2
+     read(50,end=999) jz,cfile6,NClearAve,MinSigdB,DFTolerance,NFreeze,  &
+          mode,mode4,Nseg,MouseDF2,NAgain,idf,lumsg,lcum,nspecial,ndf,   &
+          NSyncOK,dat(1:jz)
+     if(ifile.lt.ifile1) cycle
+
+!     write(*,3000) ifile,cfile6,jz,mode,mode4,idf
+!3000 format(i3,2x,a6,i10,3i5)
+
+     dftolerance=100
+     nfreeze=1
+     neme=0
+
+!    call wsjt24(dat(4097),jz-4096,cfile6,NClearAve,MinSigdB,DFTolerance,  &
+    call wsjt24(dat,jz,cfile6,NClearAve,MinSigdB,DFTolerance,             &
+         NFreeze,mode,mode4,Nseg,MouseDF2,NAgain,idf,lumsg,lcum,nspecial, &
+         ndf,NSyncOK,ccfblue,ccfred,ndiag)
+    if(ifile.ge.ifile2) exit
+  enddo
+
+999 end program wsjt24d
diff --git a/lib/xcor24.f90 b/lib/xcor24.f90
new file mode 100644
index 0000000..b76093b
--- /dev/null
+++ b/lib/xcor24.f90
@@ -0,0 +1,94 @@
+subroutine xcor24(s2,ipk,nsteps,nsym,lag1,lag2,mode4,ccf,ccf0,lagpk,flip)
+
+! Computes ccf of a row of s2 and the pseudo-random array pr2.  Returns
+! peak of the CCF and the lag at which peak occurs.  For JT65, the 
+! CCF peak may be either positive or negative, with negative implying
+! the "OOO" message.
+
+  parameter (NHMAX=1260)           !Max length of power spectra
+  parameter (NSMAX=525)            !Max number of half-symbol steps
+  real s2(NHMAX,NSMAX)             !2d spectrum, stepped by half-symbols
+  real a(NSMAX)
+  real ccf(-5:540)
+  integer npr2(207)
+  real pr2(207)
+  logical first
+  data lagmin/0/                    !Silence g77 warning
+  data first/.true./
+  data npr2/                                                        &
+       0,0,0,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,0,1,1,0,0, &
+       0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,0,1,1,1,1,1,0,1,0,0,0, &
+       1,0,0,1,0,0,1,1,1,1,1,0,0,0,1,0,1,0,0,0,1,1,1,1,0,1,1,0,0,1, &
+       0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1,0,1,0,1, &
+       0,1,1,1,0,0,1,0,1,1,0,1,1,1,1,0,0,0,0,1,1,0,1,1,0,0,0,1,1,1, &
+       0,1,1,1,0,1,1,1,0,0,1,0,0,0,1,1,0,1,1,0,0,1,0,0,0,1,1,1,1,1, &
+       1,0,0,1,1,0,0,0,0,1,1,0,0,0,1,0,1,1,0,1,1,1,1,0,1,0,1/
+  save
+
+  if(first) then
+     do i=1,207
+        pr2(i)=2*npr2(i)-1
+     enddo
+     first=.false.
+  endif
+
+  do j=1,nsteps
+     n=2*mode4
+     if(mode4.eq.1) then
+        a(j)=max(s2(ipk+n,j),s2(ipk+3*n,j)) - max(s2(ipk  ,j),s2(ipk+2*n,j))
+     else
+        kz=mode4/2
+        ss0=0.
+        ss1=0.
+        ss2=0.
+        ss3=0.
+        wsum=0.
+        do k=-kz+1,kz-1
+           w=float(kz-iabs(k))/mode4
+           wsum=wsum+w
+           if(ipk+k.lt.1 .or. ipk+3*n+k.gt.1260) then
+              print*,'xcor24:',ipk,n,k
+           else
+              ss0=ss0 + w*s2(ipk    +k,j)
+              ss1=ss1 + w*s2(ipk+  n+k,j)
+              ss2=ss2 + w*s2(ipk+2*n+k,j)
+              ss3=ss3 + w*s2(ipk+3*n+k,j)
+           endif
+        enddo
+        a(j)=(max(ss1,ss3) - max(ss0,ss2))/sqrt(wsum)
+     endif
+  enddo
+
+  ccfmax=0.
+  ccfmin=0.
+  do lag=lag1,lag2
+     x=0.
+     do i=1,nsym
+        j=2*i-1+lag
+        if(j.ge.1 .and. j.le.nsteps) x=x+a(j)*pr2(i)
+     enddo
+     ccf(lag)=2*x                        !The 2 is for plotting scale
+     if(ccf(lag).gt.ccfmax) then
+        ccfmax=ccf(lag)
+        lagpk=lag
+     endif
+
+     if(ccf(lag).lt.ccfmin) then
+        ccfmin=ccf(lag)
+        lagmin=lag
+     endif
+  enddo
+
+  ccf0=ccfmax
+  flip=1.0
+  if(-ccfmin.gt.ccfmax) then
+     do lag=lag1,lag2
+        ccf(lag)=-ccf(lag)
+     enddo
+     lagpk=lagmin
+     ccf0=-ccfmin
+     flip=-1.0
+  endif
+
+  return
+end subroutine xcor24
diff --git a/lib/zplot9.f90 b/lib/zplot9.f90
new file mode 100644
index 0000000..6c56c9f
--- /dev/null
+++ b/lib/zplot9.f90
@@ -0,0 +1,31 @@
+subroutine zplot9(s,freq,drift)
+
+  real s(0:8,85)
+  character*1 line(85),mark(0:6)
+  data mark/' ',' ','.','-','+','X','$'/
+  include 'jt9sync.f90'
+
+  write(32,1000) freq,drift
+1000 format('Freq:',f7.1,'   Drift:',f5.1,'  ',60('-'))
+  do j=8,0,-1
+     do i=1,85
+        n=(s(j,i))
+        if(n.lt.0) n=0
+        if(n.gt.6) n=6
+        line(i)=mark(n)
+     enddo
+     write(32,1010) j,line
+1010 format(i1,1x,85a1)
+  enddo
+  do i=1,85
+     line(i)=' '
+     if(isync(i).eq.1) line(i)='@'
+  enddo
+  write(32,1015)
+1015 format(87('-'))
+  write(32,1020) line
+1020 format(2x,85a1)
+  call flush(32)
+
+  return
+end subroutine zplot9
diff --git a/logqso.cpp b/logqso.cpp
new file mode 100644
index 0000000..f5690a1
--- /dev/null
+++ b/logqso.cpp
@@ -0,0 +1,174 @@
+#include "logqso.h"
+#include "ui_logqso.h"
+#include <QString>
+#include <QDebug>
+
+
+LogQSO::LogQSO(QWidget *parent) :
+  QDialog(parent),
+  ui(new Ui::LogQSO)
+{
+  ui->setupUi(this);
+}
+
+LogQSO::~LogQSO()
+{
+  delete ui;
+}
+
+void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode,
+                        QString rptSent, QString rptRcvd, QDateTime dateTime,
+                        double dialFreq, QString myCall, QString myGrid,
+                        bool noSuffix, bool toRTTY, bool dBtoComments)
+{
+  ui->call->setText(hisCall);
+  ui->grid->setText(hisGrid);
+  ui->txPower->setText("");
+  ui->comments->setText("");
+  if(m_saveTxPower) ui->txPower->setText(m_txPower);
+  if(m_saveComments) ui->comments->setText(m_comments);
+  if(dBtoComments) {
+    QString t=mode;
+    if(rptSent!="") t+="  Sent: " + rptSent;
+    if(rptRcvd!="") t+="  Rcvd: " + rptRcvd;
+    ui->comments->setText(t);
+  }
+  if(noSuffix and mode.mid(0,3)=="JT9") mode="JT9";
+  if(toRTTY and mode.mid(0,3)=="JT9") mode="RTTY";
+  ui->mode->setText(mode);
+  ui->sent->setText(rptSent);
+  ui->rcvd->setText(rptRcvd);
+  m_dateTime=dateTime;
+  QString date=dateTime.toString("yyyy-MM-dd");
+  ui->date->setText(date);
+  QString time=dateTime.toString("hhmm");
+  ui->time->setText(time);
+  m_dialFreq=dialFreq;
+  m_myCall=myCall;
+  m_myGrid=myGrid;
+  QString band="";
+  if(dialFreq>0.135 and dialFreq<0.139) band="2200m";
+  if(dialFreq>0.45 and dialFreq<0.55) band="630m";
+  if(dialFreq>1.8 and dialFreq<2.0) band="160m";
+  if(dialFreq>3.5 and dialFreq<4.0) band="80m";
+  if(dialFreq>5.1 and dialFreq<5.45) band="60m";
+  if(dialFreq>7.0 and dialFreq<7.3) band="40m";
+  if(dialFreq>10.0 and dialFreq<10.15) band="30m";
+  if(dialFreq>14.0 and dialFreq<14.35) band="20m";
+  if(dialFreq>18.068 and dialFreq<18.168) band="17m";
+  if(dialFreq>21.0 and dialFreq<21.45) band="15m";
+  if(dialFreq>24.890 and dialFreq<24.990) band="12m";
+  if(dialFreq>28.0 and dialFreq<29.7) band="10m";
+  if(dialFreq>50.0 and dialFreq<54.0) band="6m";
+  if(dialFreq>70.0 and dialFreq<71.0) band="4m";
+  if(dialFreq>144.0 and dialFreq<148.0) band="2m";
+  if(dialFreq>222.0 and dialFreq<225.0) band="1.25m";
+  if(dialFreq>420.0 and dialFreq<450.0) band="70cm";
+  if(dialFreq>902.0 and dialFreq<928.0) band="33cm";
+  if(dialFreq>1240.0 and dialFreq<1300.0) band="23cm";
+  if(dialFreq>2300.0 and dialFreq<2450.0) band="13cm";
+  if(dialFreq>3300.0 and dialFreq<3500.0) band="9cm";
+  if(dialFreq>5650.0 and dialFreq<5925.0) band="6cm";
+  if(dialFreq>10000.0 and dialFreq<10500.0) band="3cm";
+  if(dialFreq>24000.0 and dialFreq<24250.0) band="1.25cm";
+  if(dialFreq>47000.0 and dialFreq<47200.0) band="6mm";
+  if(dialFreq>75500.0 and dialFreq<81000.0) band="4mm";
+  ui->band->setText(band);
+  ui->cbTxPower->setChecked(m_saveTxPower);
+  ui->cbComments->setChecked(m_saveComments);
+}
+
+void LogQSO::accept()
+{
+  QString hisCall,hisGrid,mode,rptSent,rptRcvd,date,time,band;
+  QString comments,name;
+
+  hisCall=ui->call->text();
+  hisGrid=ui->grid->text();
+  mode=ui->mode->text();
+  rptSent=ui->sent->text();
+  rptRcvd=ui->rcvd->text();
+  date=ui->date->text();
+  date=date.mid(0,4) + date.mid(5,2) + date.mid(8,2);
+  time=ui->time->text();
+  band=ui->band->text();
+  name=ui->name->text();
+  m_txPower=ui->txPower->text();
+  comments=ui->comments->text();
+  m_comments=comments;
+  QString strDialFreq(QString::number(m_dialFreq,'f',6));
+
+//Log this QSO to file "wsjtx_log.adi"
+  QFile f2("wsjtx_log.adi");
+  if(!f2.open(QIODevice::Text | QIODevice::Append)) {
+    QMessageBox m;
+    m.setText("Cannot open file \"wsjtx_log.adi\".");
+    m.exec();
+  } else {
+    QTextStream out(&f2);
+    if(f2.size()==0) out << "WSJT-X ADIF Export<eoh>" << endl;
+
+    QString t;
+    t="<call:" + QString::number(hisCall.length()) + ">" + hisCall;
+    t+=" <gridsquare:" + QString::number(hisGrid.length()) + ">" + hisGrid;
+    t+=" <mode:" + QString::number(mode.length()) + ">" + mode;
+    t+=" <rst_sent:" + QString::number(rptSent.length()) + ">" + rptSent;
+    t+=" <rst_rcvd:" + QString::number(rptRcvd.length()) + ">" + rptRcvd;
+    t+=" <qso_date:8>" + date;
+    t+=" <time_on:4>" + time;
+    t+=" <band:" + QString::number(band.length()) + ">" + band;
+    t+=" <freq:" + QString::number(strDialFreq.length()) + ">" + strDialFreq;
+    t+=" <station_callsign:" + QString::number(m_myCall.length()) + ">" +
+        m_myCall;
+    t+=" <my_gridsquare:" + QString::number(m_myGrid.length()) + ">" +
+        m_myGrid;
+    if(m_txPower!="") t+= " <tx_pwr:" + QString::number(m_txPower.length()) +
+        ">" + m_txPower;
+    if(comments!="") t+=" <comment:" + QString::number(comments.length()) +
+        ">" + comments;
+    if(name!="") t+=" <name:" + QString::number(name.length()) +
+        ">" + name;
+    t+=" <eor>";
+    out << t << endl;
+    f2.close();
+  }
+
+//Log this QSO to file "wsjtx.log"
+  QFile f("wsjtx.log");
+  if(!f.open(QIODevice::Text | QIODevice::Append)) {
+    QMessageBox m;
+    m.setText("Cannot open file \"wsjtx.log\".");
+    m.exec();
+  } else {
+    QString logEntry=m_dateTime.date().toString("yyyy-MMM-dd,") +
+           m_dateTime.time().toString("hh:mm,") + hisCall + "," +
+           hisGrid + "," + strDialFreq + "," + mode +
+               "," + rptSent + "," + rptRcvd;
+       if(m_txPower!="") logEntry += "," + m_txPower;
+       if(comments!="") logEntry += "," + comments;
+       if(name!="") logEntry += "," + name;
+    QTextStream out(&f);
+    out << logEntry << endl;
+    f.close();
+  }
+
+//Clean up and finish logging
+  emit(acceptQSO(true));
+  QDialog::accept();
+}
+
+void LogQSO::reject()
+{
+  emit(acceptQSO(false));
+  QDialog::reject();
+}
+
+void LogQSO::on_cbTxPower_toggled(bool checked)
+{
+  m_saveTxPower=checked;
+}
+
+void LogQSO::on_cbComments_toggled(bool checked)
+{
+  m_saveComments=checked;
+}
diff --git a/logqso.h b/logqso.h
new file mode 100644
index 0000000..06b2edf
--- /dev/null
+++ b/logqso.h
@@ -0,0 +1,53 @@
+#ifndef LogQSO_H
+#define LogQSO_H
+
+#ifdef QT5
+#include <QtWidgets>
+#else
+#include <QtGui>
+#endif
+
+namespace Ui {
+class LogQSO;
+}
+
+class LogQSO : public QDialog
+{
+  Q_OBJECT
+
+public:
+  explicit LogQSO(QWidget *parent = 0);
+  ~LogQSO();
+  void initLogQSO(QString hisCall, QString hisGrid, QString mode,
+                  QString rptSent, QString rptRcvd, QDateTime dateTime,
+                  double dialFreq, QString myCall, QString myGrid,
+                  bool noSuffix, bool toRTTY, bool dBtoComments);
+
+  double m_dialFreq;
+
+  bool m_saveTxPower;
+  bool m_saveComments;
+
+  QString m_myCall;
+  QString m_myGrid;
+  QString m_txPower;
+  QString m_comments;
+
+  QDateTime m_dateTime;
+
+public slots:
+  void accept();
+  void reject();
+
+signals:
+  void acceptQSO(bool accepted);
+
+private slots:
+  void on_cbTxPower_toggled(bool checked);
+  void on_cbComments_toggled(bool checked);
+
+private:
+  Ui::LogQSO *ui;
+};
+
+#endif // LogQSO_H
diff --git a/logqso.ui b/logqso.ui
new file mode 100644
index 0000000..a9c6fe9
--- /dev/null
+++ b/logqso.ui
@@ -0,0 +1,759 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LogQSO</class>
+ <widget class="QDialog" name="LogQSO">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>372</width>
+    <height>305</height>
+   </rect>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>16777215</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Log QSO</string>
+  </property>
+  <layout class="QFormLayout" name="formLayout">
+   <item row="0" column="0">
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <item>
+      <spacer name="verticalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::MinimumExpanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>10</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="font">
+        <font>
+         <pointsize>10</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>Click OK to confirm the following QSO:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="verticalSpacer_4">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::MinimumExpanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>10</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_5">
+       <item>
+        <widget class="QLabel" name="lab1">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>70</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>70</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Call</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="lab2">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>100</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Date</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="lab3">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Time</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="lab4">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Mode</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="lab5">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Band</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_4">
+       <item>
+        <widget class="QLineEdit" name="call">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>70</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>70</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="date">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>100</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="time">
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="mode">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="band">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer name="verticalSpacer">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::MinimumExpanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>10</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_3">
+       <item>
+        <widget class="QLabel" name="lab6">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Rpt Sent</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="lab7">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Rpt Rcvd</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="lab8">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Grid</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="lab9">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>100</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Name</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_2">
+       <item>
+        <widget class="QLineEdit" name="sent">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="rcvd">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="grid">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>50</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="name">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>100</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>100</width>
+           <height>16777215</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer name="verticalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::MinimumExpanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>10</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_6">
+       <item>
+        <widget class="QLabel" name="label_2">
+         <property name="minimumSize">
+          <size>
+           <width>65</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>Tx power</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="txPower"/>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="cbTxPower">
+         <property name="text">
+          <string>Retain</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer name="verticalSpacer_5">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeType">
+        <enum>QSizePolicy::MinimumExpanding</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>10</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QLabel" name="lab10">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>65</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>Comments</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="comments">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="cbComments">
+         <property name="text">
+          <string>Retain</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>call</tabstop>
+  <tabstop>date</tabstop>
+  <tabstop>time</tabstop>
+  <tabstop>mode</tabstop>
+  <tabstop>band</tabstop>
+  <tabstop>sent</tabstop>
+  <tabstop>rcvd</tabstop>
+  <tabstop>grid</tabstop>
+  <tabstop>name</tabstop>
+  <tabstop>txPower</tabstop>
+  <tabstop>cbTxPower</tabstop>
+  <tabstop>comments</tabstop>
+  <tabstop>cbComments</tabstop>
+  <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>LogQSO</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>LogQSO</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..add1ab1
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,60 @@
+#ifdef QT5
+#include <QtWidgets>
+#else
+#include <QtGui>
+#endif
+#include <QApplication>
+#include <portaudio.h>
+#include "mainwindow.h"
+
+// Multiple instances:
+QSharedMemory mem_jt9;
+QUuid         my_uuid;
+QString       my_key;
+
+int main(int argc, char *argv[])
+{
+  QApplication a(argc, argv);
+
+  QFile f("fonts.txt");
+  if(f.open(QIODevice::ReadOnly)) {
+     QTextStream in(&f);                          //Example:
+     QString fontFamily;                          // helvetica
+     qint32 fontSize,fontWeight;                  // 8,50
+     in >> fontFamily >> fontSize >> fontWeight;
+     f.close();
+     QFont font;
+     font=QFont(fontFamily,fontSize,fontWeight);
+     a.setFont(font);
+  }
+
+  // Create and initialize shared memory segment
+  // Multiple instances: generate shared memory keys with UUID
+  my_uuid = QUuid::createUuid();
+  my_key = my_uuid.toString();
+  mem_jt9.setKey(my_key);
+
+  if(!mem_jt9.attach()) {
+    if (!mem_jt9.create(sizeof(jt9com_))) {
+      QMessageBox::critical( 0, "Error", "Unable to create shared memory segment.");
+      exit(1);
+    }
+  }
+  char *to = (char*)mem_jt9.data();
+  int size=sizeof(jt9com_);
+  if(jt9com_.newdat==0) {
+  }
+  memset(to,0,size);         //Zero all decoding params in shared memory
+
+  //Initialize Portaudio
+  PaError paerr=Pa_Initialize();
+  if(paerr!=paNoError) {
+    QMessageBox::critical( 0, "Error", "Unable to initialize PortAudio.");
+    exit(1);
+  }
+
+// Multiple instances:  Call MainWindow() with the UUID key
+  MainWindow w(&mem_jt9, &my_key);
+  w.show();
+  return a.exec();
+}
diff --git a/mainwindow.cpp b/mainwindow.cpp
new file mode 100644
index 0000000..7b50ec8
--- /dev/null
+++ b/mainwindow.cpp
@@ -0,0 +1,3052 @@
+//------------------------------------------------------------- MainWindow
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include "devsetup.h"
+#include "plotter.h"
+#include "about.h"
+#include "widegraph.h"
+#include "sleep.h"
+#include "getfile.h"
+#include <portaudio.h>
+#include "logqso.h"
+
+#ifdef QT5
+#include <QtConcurrent/QtConcurrentMap>
+#include <QtConcurrent/QtConcurrentRun>
+#endif
+
+int itone[126];                       //Audio tones for all Tx symbols
+int icw[250];                         //Dits for CW ID
+int outBufSize;
+int rc;
+qint32  g_COMportOpen;
+qint32  g_iptt;
+static int nc1=1;
+wchar_t buffer[256];
+bool btxok;                           //True if OK to transmit
+bool btxMute;
+double outputLatency;                 //Latency in seconds
+double dFreq[]={0.13613,0.4742,1.838,3.576,5.357,7.076,10.138,14.076,
+           18.102,21.076,24.917,28.076,50.276,70.091,144.489,432.178};
+
+WideGraph* g_pWideGraph = NULL;
+LogQSO* logDlg = NULL;
+Rig* rig = NULL;
+QTextEdit* pShortcuts;
+QTcpSocket* socket = new QTcpSocket(0);
+
+QString rev="$Rev: 3496 $";
+QString Program_Title_Version="  WSJT-X   v1.1, r" + rev.mid(6,4) +
+                              "    by K1JT";
+
+//-------------------------------------------------- MainWindow constructor
+// Multiple instances: new arg *thekey
+MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, QWidget *parent) :
+  QMainWindow(parent),
+  ui(new Ui::MainWindow)
+{
+  ui->setupUi(this);
+  on_EraseButton_clicked();
+  QActionGroup* paletteGroup = new QActionGroup(this);
+  ui->actionCuteSDR->setActionGroup(paletteGroup);
+  ui->actionLinrad->setActionGroup(paletteGroup);
+  ui->actionAFMHot->setActionGroup(paletteGroup);
+  ui->actionBlue->setActionGroup(paletteGroup);
+
+  QActionGroup* modeGroup = new QActionGroup(this);
+  ui->actionJT9_1->setActionGroup(modeGroup);
+  ui->actionJT65->setActionGroup(modeGroup);
+  ui->actionJT9_JT65->setActionGroup(modeGroup);
+
+
+  QActionGroup* saveGroup = new QActionGroup(this);
+  ui->actionNone->setActionGroup(saveGroup);
+  ui->actionSave_decoded->setActionGroup(saveGroup);
+  ui->actionSave_all->setActionGroup(saveGroup);
+
+  QActionGroup* DepthGroup = new QActionGroup(this);
+  ui->actionQuickDecode->setActionGroup(DepthGroup);
+  ui->actionMediumDecode->setActionGroup(DepthGroup);
+  ui->actionDeepestDecode->setActionGroup(DepthGroup);
+
+  QButtonGroup* txMsgButtonGroup = new QButtonGroup;
+  txMsgButtonGroup->addButton(ui->txrb1,1);
+  txMsgButtonGroup->addButton(ui->txrb2,2);
+  txMsgButtonGroup->addButton(ui->txrb3,3);
+  txMsgButtonGroup->addButton(ui->txrb4,4);
+  txMsgButtonGroup->addButton(ui->txrb5,5);
+  txMsgButtonGroup->addButton(ui->txrb6,6);
+  connect(txMsgButtonGroup,SIGNAL(buttonClicked(int)),SLOT(set_ntx(int)));
+  connect(ui->decodedTextBrowser2,SIGNAL(selectCallsign(bool,bool)),this,
+          SLOT(doubleClickOnCall(bool,bool)));
+  connect(ui->decodedTextBrowser,SIGNAL(selectCallsign(bool,bool)),this,
+          SLOT(doubleClickOnCall2(bool,bool)));
+
+  setWindowTitle(Program_Title_Version);
+  connect(&soundInThread, SIGNAL(readyForFFT(int)),
+             this, SLOT(dataSink(int)));
+  connect(&soundInThread, SIGNAL(error(QString)), this,
+          SLOT(showSoundInError(QString)));
+  connect(&soundInThread, SIGNAL(status(QString)), this,
+          SLOT(showStatusMessage(QString)));
+  createStatusBar();
+
+  connect(&proc_jt9, SIGNAL(readyReadStandardOutput()),
+                    this, SLOT(readFromStdout()));
+
+  connect(&proc_jt9, SIGNAL(error(QProcess::ProcessError)),
+          this, SLOT(jt9_error()));
+
+  connect(&proc_jt9, SIGNAL(readyReadStandardError()),
+          this, SLOT(readFromStderr()));
+
+  ui->bandComboBox->setEditable(true);
+  ui->bandComboBox->lineEdit()->setReadOnly(true);
+  ui->bandComboBox->lineEdit()->setAlignment(Qt::AlignCenter);
+  for(int i = 0; i < ui->bandComboBox->count(); i++)
+    ui->bandComboBox->setItemData(i, Qt::AlignCenter, Qt::TextAlignmentRole);
+
+  ui->tx5->setContextMenuPolicy(Qt::CustomContextMenu);
+  connect(ui->tx5, SIGNAL(customContextMenuRequested(const QPoint&)),
+      this, SLOT(showMacros(const QPoint&)));
+
+  ui->freeTextMsg->setContextMenuPolicy(Qt::CustomContextMenu);
+  connect(ui->freeTextMsg, SIGNAL(customContextMenuRequested(const QPoint&)),
+      this, SLOT(showMacros(const QPoint&)));
+
+  QTimer *guiTimer = new QTimer(this);
+  connect(guiTimer, SIGNAL(timeout()), this, SLOT(guiUpdate()));
+  guiTimer->start(100);                            //Don't change the 100 ms!
+  ptt0Timer = new QTimer(this);
+  ptt0Timer->setSingleShot(true);
+  connect(ptt0Timer, SIGNAL(timeout()), this, SLOT(stopTx2()));
+  ptt1Timer = new QTimer(this);
+  ptt1Timer->setSingleShot(true);
+  connect(ptt1Timer, SIGNAL(timeout()), this, SLOT(startTx2()));
+
+  logQSOTimer = new QTimer(this);
+  logQSOTimer->setSingleShot(true);
+  connect(logQSOTimer, SIGNAL(timeout()), this, SLOT(on_logQSOButton_clicked()));
+
+  tuneButtonTimer= new QTimer(this);
+  tuneButtonTimer->setSingleShot(true);
+  connect(tuneButtonTimer, SIGNAL(timeout()), this,
+          SLOT(on_stopTxButton_clicked()));
+
+  killFileTimer = new QTimer(this);
+  killFileTimer->setSingleShot(true);
+  connect(killFileTimer, SIGNAL(timeout()), this, SLOT(killFile()));
+
+  m_auto=false;
+  m_waterfallAvg = 1;
+  m_txFirst=false;
+  btxMute=false;
+  btxok=false;
+  m_restart=false;
+  m_transmitting=false;
+  m_killAll=false;
+  m_widebandDecode=false;
+  m_ntx=1;
+  m_myCall="";
+  m_myGrid="FN20qi";
+  m_appDir = QApplication::applicationDirPath();
+  m_saveDir="/users/joe/wsjtx/install/save";
+  m_rxFreq=1500;
+  m_txFreq=1500;
+  m_setftx=0;
+  m_loopall=false;
+  m_startAnother=false;
+  m_saveDecoded=false;
+  m_saveAll=false;
+  m_sec0=-1;
+  m_palette="Linrad";
+  m_RxLog=1;                     //Write Date and Time to RxLog
+  m_nutc0=9999;
+  m_mode="JT9";
+  m_rpt="-15";
+  m_TRperiod=60;
+  m_inGain=0;
+  m_dataAvailable=false;
+  g_iptt=0;
+  g_COMportOpen=0;
+  m_secID=0;
+  m_promptToLog=false;
+  m_blankLine=false;
+  m_insertBlank=false;
+  m_clearCallGrid=false;
+  m_bMiles=false;
+  m_decodedText2=false;
+  m_freeText=false;
+  m_msErase=0;
+  m_sent73=false;
+  m_watchdogLimit=5;
+  m_tune=false;
+  m_repeatMsg=0;
+  m_bRigOpen=false;
+  m_secBandChanged=0;
+  m_bMultipleOK=false;
+  m_dontReadFreq=false;
+  m_lockTxFreq=false;
+  ui->readFreq->setEnabled(false);
+  m_QSOmsg="";
+  m_CATerror=false;
+  decodeBusy(false);
+
+  signalMeter = new SignalMeter(ui->meterFrame);
+  signalMeter->resize(50, 160);
+
+//  qDebug() << signalMeter->size();
+
+  ui->labAz->setStyleSheet("border: 0px;");
+  ui->labDist->setStyleSheet("border: 0px;");
+
+  mem_jt9 = shdmem;
+// Multiple instances:
+  mykey_jt9 = thekey;
+  readSettings();		             //Restore user's setup params
+  if(m_dFreq.length()<=1) {      //Use the startup default frequencies
+    m_dFreq.clear();
+    for(int i=0; i<16; i++) {
+      QString t;
+      t.sprintf("%f",dFreq[i]);
+      m_dFreq.append(t);
+    }
+  }
+
+#ifdef WIN32
+  if(!m_bMultipleOK) {
+    while(true) {
+      int iret=killbyname("jt9.exe");
+      if(iret == 603) break;
+      if(iret != 0) msgBox("KillByName return code: " +
+                           QString::number(iret));
+    }
+  }
+#endif
+
+  QFile lockFile(m_appDir + "/.lock");     //Create .lock so jt9 will wait
+  lockFile.open(QIODevice::ReadWrite);
+  //QFile quitFile(m_appDir + "/.lock");
+  //quitFile.remove();
+
+// Multiple instances: make the Qstring key into command line arg
+// Multiple instances: start "jt9 -s <thekey>"
+  QByteArray  ba = mykey_jt9->toLocal8Bit();
+  const char *bc = ba.data();
+  proc_jt9.start(QDir::toNativeSeparators('"' + m_appDir + '"' + "/jt9 -s " + bc));
+
+  m_pbdecoding_style1="QPushButton{background-color: cyan; \
+      border-style: outset; border-width: 1px; border-radius: 5px; \
+      border-color: black; min-width: 5em; padding: 3px;}";
+  m_pbmonitor_style="QPushButton{background-color: #00ff00; \
+      border-style: outset; border-width: 1px; border-radius: 5px; \
+      border-color: black; min-width: 5em; padding: 3px;}";
+  m_pbAutoOn_style="QPushButton{background-color: red; \
+      border-style: outset; border-width: 1px; border-radius: 5px; \
+      border-color: black; min-width: 5em; padding: 3px;}";
+  m_pbTune_style="QPushButton{background-color: red; \
+      border-style: outset; border-width: 1px; border-radius: 5px; \
+      border-color: black; min-width: 5em; padding: 3px;}";
+
+  genStdMsgs(m_rpt);
+  if(m_mode!="JT9" and m_mode!="JT65" and m_mode!="JT9+JT65") m_mode="JT9";
+  on_actionWide_Waterfall_triggered();                   //###
+  g_pWideGraph->setRxFreq(m_rxFreq);
+  g_pWideGraph->setTxFreq(m_txFreq);
+  g_pWideGraph->setLockTxFreq(m_lockTxFreq);
+  g_pWideGraph->setFmin(m_fMin);
+  g_pWideGraph->setModeTx(m_mode);
+  g_pWideGraph->setModeTx(m_modeTx);
+  dialFreqChanged2(m_dialFreq);
+
+  connect(g_pWideGraph, SIGNAL(setFreq3(int,int)),this,
+          SLOT(setFreq4(int,int)));
+
+  if(m_mode=="JT9") on_actionJT9_1_triggered();
+  if(m_mode=="JT65") on_actionJT65_triggered();
+  if(m_mode=="JT9+JT65") on_actionJT9_JT65_triggered();
+
+  future1 = new QFuture<void>;
+  watcher1 = new QFutureWatcher<void>;
+  connect(watcher1, SIGNAL(finished()),this,SLOT(diskDat()));
+
+  future2 = new QFuture<void>;
+  watcher2 = new QFutureWatcher<void>;
+  connect(watcher2, SIGNAL(finished()),this,SLOT(diskWriteFinished()));
+
+  soundInThread.setInputDevice(m_paInDevice);
+  soundInThread.start(QThread::HighestPriority);
+  soundOutThread.setOutputDevice(m_paOutDevice);
+  soundOutThread.setTxFreq(m_txFreq);
+  soundOutThread.setTune(false);
+  m_monitoring=!m_monitorStartOFF;           // Start with Monitoring ON/OFF
+  soundInThread.setMonitoring(m_monitoring);
+  m_diskData=false;
+
+// Create "m_worked", a dictionary of all calls in wsjtx.log
+  QFile f("wsjtx.log");
+  f.open(QIODevice::ReadOnly | QIODevice::Text);
+  QTextStream in(&f);
+  QString line,t,callsign;
+  for(int i=0; i<99999; i++) {
+    line=in.readLine();
+    if(line.length()<=0) break;
+    t=line.mid(18,12);
+    callsign=t.mid(0,t.indexOf(","));
+  }
+  f.close();
+
+  if(ui->actionLinrad->isChecked()) on_actionLinrad_triggered();
+  if(ui->actionCuteSDR->isChecked()) on_actionCuteSDR_triggered();
+  if(ui->actionAFMHot->isChecked()) on_actionAFMHot_triggered();
+  if(ui->actionBlue->isChecked()) on_actionBlue_triggered();
+
+  ui->decodedTextLabel->setFont(ui->decodedTextBrowser2->font());
+  ui->decodedTextLabel2->setFont(ui->decodedTextBrowser->font());
+  t="UTC   dB   DT Freq   Message";
+  ui->decodedTextLabel->setText(t);
+  ui->decodedTextLabel2->setText(t);
+
+#ifdef WIN32
+  if(m_pskReporter) {
+    rc=ReporterInitialize(NULL,NULL);
+    if(rc==0) {
+      m_pskReporterInit=true;
+    } else {
+      m_pskReporterInit=false;
+      rc=ReporterGetInformation(buffer,256);
+      msgBox(QString::fromStdWString(buffer));
+    }
+  }
+#endif
+
+#ifdef UNIX
+  psk_Reporter = new PSK_Reporter(this);
+  psk_Reporter->setLocalStation(m_myCall,m_myGrid, "WSJT-X r" + rev.mid(6,4) );
+#endif
+
+  ui->label_9->setStyleSheet("QLabel{background-color: #aabec8}");
+  ui->label_10->setStyleSheet("QLabel{background-color: #aabec8}");
+  ui->labUTC->setStyleSheet( \
+        "QLabel { background-color : black; color : yellow; }");
+  ui->labDialFreq->setStyleSheet( \
+        "QLabel { background-color : black; color : yellow; }");
+
+  QFile f2("ALL.TXT");
+  f2.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
+  QTextStream out(&f2);
+  out << QDateTime::currentDateTimeUtc().toString("yyyy-MMM-dd hh:mm")
+      << "  " << m_dialFreq << " MHz  " << m_mode << endl;
+  f2.close();
+}                                          // End of MainWindow constructor
+
+//--------------------------------------------------- MainWindow destructor
+MainWindow::~MainWindow()
+{
+  writeSettings();
+  if (soundInThread.isRunning()) {
+    soundInThread.quit();
+    soundInThread.wait(3000);
+  }
+  if (soundOutThread.isRunning()) {
+    soundOutThread.quitExecution=true;
+    soundOutThread.wait(3000);
+  }
+  if(!m_decoderBusy) {
+    QFile lockFile(m_appDir + "/.lock");
+    lockFile.remove();
+  }
+  delete ui;
+}
+
+//-------------------------------------------------------- writeSettings()
+void MainWindow::writeSettings()
+{
+  QString inifile = m_appDir + "/wsjtx.ini";
+  QSettings settings(inifile, QSettings::IniFormat);
+
+  settings.beginGroup("MainWindow");
+  settings.setValue("geometry", saveGeometry());
+  settings.setValue("MRUdir", m_path);
+  settings.setValue("TxFirst",m_txFirst);
+  settings.setValue("DXcall",ui->dxCallEntry->text());
+  settings.setValue("DXgrid",ui->dxGridEntry->text());
+  if(g_pWideGraph->isVisible()) {
+    m_wideGraphGeom = g_pWideGraph->geometry();
+    settings.setValue("WideGraphGeom",m_wideGraphGeom);
+    m_fMin=g_pWideGraph->getFmin();
+  }
+  settings.endGroup();
+
+  settings.beginGroup("Common");
+  settings.setValue("MyCall",m_myCall);
+  settings.setValue("MyGrid",m_myGrid);
+  settings.setValue("IDint",m_idInt);
+  settings.setValue("PTTmethod",m_pttMethodIndex);
+  settings.setValue("PTTport",m_pttPort);
+  settings.setValue("SaveDir",m_saveDir);
+  char soundName[128];
+  if (Pa_GetDeviceInfo( m_paInDevice)) {  // store name, number may be different next time
+    snprintf( soundName, sizeof( soundName), "%s:%s",
+      Pa_GetHostApiInfo( Pa_GetDeviceInfo( m_paInDevice)->hostApi)->name,
+      Pa_GetDeviceInfo( m_paInDevice)->name);
+    settings.setValue("SoundInName", soundName);
+  }
+  if (Pa_GetDeviceInfo( m_paOutDevice)) {  // store name, number may be different next time
+    snprintf( soundName, sizeof( soundName), "%s:%s",
+      Pa_GetHostApiInfo( Pa_GetDeviceInfo( m_paOutDevice)->hostApi)->name,
+      Pa_GetDeviceInfo( m_paOutDevice)->name);
+    settings.setValue("SoundOutName", soundName);
+  }
+  settings.setValue("PaletteCuteSDR",ui->actionCuteSDR->isChecked());
+  settings.setValue("PaletteLinrad",ui->actionLinrad->isChecked());
+  settings.setValue("PaletteAFMHot",ui->actionAFMHot->isChecked());
+  settings.setValue("PaletteBlue",ui->actionBlue->isChecked());
+  settings.setValue("Mode",m_mode);
+  settings.setValue("ModeTx",m_modeTx);
+  settings.setValue("SaveNone",ui->actionNone->isChecked());
+  settings.setValue("SaveDecoded",ui->actionSave_decoded->isChecked());
+  settings.setValue("SaveAll",ui->actionSave_all->isChecked());
+  settings.setValue("NDepth",m_ndepth);
+  settings.setValue("MonitorOFF",m_monitorStartOFF);
+  settings.setValue("DialFreq",m_dialFreq);
+  settings.setValue("RxFreq",m_rxFreq);
+  settings.setValue("TxFreq",m_txFreq);
+  settings.setValue("InGain",m_inGain);
+  settings.setValue("PSKReporter",m_pskReporter);
+  settings.setValue("After73",m_After73);
+  settings.setValue("Macros",m_macro);
+  settings.setValue("DefaultFreqs",m_dFreq);
+  settings.setValue("toRTTY",m_toRTTY);
+  settings.setValue("NoSuffix",m_noSuffix);
+  settings.setValue("dBtoComments",m_dBtoComments);
+  settings.setValue("catEnabled",m_catEnabled);
+  settings.setValue("Rig",m_rig);
+  settings.setValue("RigIndex",m_rigIndex);
+  settings.setValue("CATport",m_catPort);
+  settings.setValue("CATportIndex",m_catPortIndex);
+  settings.setValue("SerialRate",m_serialRate);
+  settings.setValue("SerialRateIndex",m_serialRateIndex);
+  settings.setValue("DataBits",m_dataBits);
+  settings.setValue("DataBitsIndex",m_dataBitsIndex);
+  settings.setValue("StopBits",m_stopBits);
+  settings.setValue("StopBitsIndex",m_stopBitsIndex);
+  settings.setValue("Handshake",m_handshake);
+  settings.setValue("HandshakeIndex",m_handshakeIndex);
+  settings.setValue("BandIndex",m_band);
+  settings.setValue("PromptToLog",m_promptToLog);
+  settings.setValue("InsertBlank",m_insertBlank);
+  settings.setValue("ClearCallGrid",m_clearCallGrid);
+  settings.setValue("Miles",m_bMiles);
+  settings.setValue("GUItab",ui->tabWidget->currentIndex());
+  settings.setValue("QuickCall",m_quickCall);
+  settings.setValue("73TxDisable",m_73TxDisable);
+  settings.setValue("Runaway",m_runaway);
+  settings.setValue("Tx2QSO",m_tx2QSO);
+  settings.setValue("MultipleOK",m_bMultipleOK);
+  settings.setValue("DTRoff",m_bDTRoff);
+  settings.setValue("pttData",m_pttData);
+  settings.setValue("LogQSOgeom",m_logQSOgeom);
+  settings.setValue("Polling",m_poll);
+  settings.setValue("OutBufSize",outBufSize);
+  settings.setValue("LockTxFreq",m_lockTxFreq);
+  settings.setValue("SaveTxPower",m_saveTxPower);
+  settings.setValue("SaveComments",m_saveComments);
+  settings.setValue("TxPower",m_txPower);
+  settings.setValue("LogComments",m_logComments);
+  settings.setValue("PSKantenna",m_pskAntenna);
+  settings.setValue("Fmin",m_fMin);
+  settings.setValue("TxSplit",m_bSplit);
+  settings.setValue("UseXIT",m_bXIT);
+  settings.setValue("Plus2kHz",m_plus2kHz);
+  settings.endGroup();
+}
+
+//---------------------------------------------------------- readSettings()
+void MainWindow::readSettings()
+{
+  QString inifile = m_appDir + "/wsjtx.ini";
+  QSettings settings(inifile, QSettings::IniFormat);
+  settings.beginGroup("MainWindow");
+  restoreGeometry(settings.value("geometry").toByteArray());
+  ui->dxCallEntry->setText(settings.value("DXcall","").toString());
+  ui->dxGridEntry->setText(settings.value("DXgrid","").toString());
+  m_wideGraphGeom = settings.value("WideGraphGeom", \
+                                   QRect(45,30,726,301)).toRect();
+  m_path = settings.value("MRUdir", m_appDir + "/save").toString();
+  m_txFirst = settings.value("TxFirst",false).toBool();
+  ui->txFirstCheckBox->setChecked(m_txFirst);
+  settings.endGroup();
+
+  settings.beginGroup("Common");
+  m_myCall=settings.value("MyCall","").toString();
+  morse_(m_myCall.toLatin1().data(),icw,&m_ncw,m_myCall.length());
+  m_myGrid=settings.value("MyGrid","").toString();
+  m_idInt=settings.value("IDint",0).toInt();
+  m_pttMethodIndex=settings.value("PTTmethod",1).toInt();
+  m_pttPort=settings.value("PTTport",0).toInt();
+  m_saveDir=settings.value("SaveDir",m_appDir + "/save").toString();
+
+  char soundName[128];
+  QString savedName = settings.value( "SoundInName", "default").toString();
+  for (m_paInDevice = Pa_GetDeviceCount() - 1; m_paInDevice >= 0; m_paInDevice--) {
+    snprintf( soundName, sizeof( soundName), "%s:%s",
+      Pa_GetHostApiInfo( Pa_GetDeviceInfo( m_paInDevice)->hostApi)->name,
+      Pa_GetDeviceInfo( m_paInDevice)->name);
+    if ((savedName == soundName) && (Pa_GetDeviceInfo(m_paInDevice)->maxInputChannels > 0))
+      break;
+  }
+  if (m_paInDevice < 0) { // no match for device name?
+    m_paInDevice = Pa_GetDefaultInputDevice();
+    if (m_paInDevice == paNoDevice)  // no default input device?
+      m_paInDevice = 0;
+  }
+
+  savedName = settings.value("SoundOutName", "default").toString();
+  for (m_paOutDevice = Pa_GetDeviceCount() - 1; m_paOutDevice >= 0; m_paOutDevice--) {
+    snprintf( soundName, sizeof( soundName), "%s:%s",
+      Pa_GetHostApiInfo( Pa_GetDeviceInfo( m_paOutDevice)->hostApi)->name,
+      Pa_GetDeviceInfo( m_paOutDevice)->name);
+    if ((savedName == soundName) && (Pa_GetDeviceInfo(m_paOutDevice)->maxOutputChannels > 0))
+      break;
+  }
+  if (m_paOutDevice < 0) { // no match for device name?
+    m_paOutDevice = Pa_GetDefaultOutputDevice();
+    if (m_paOutDevice == paNoDevice)  // no default output device?
+      m_paOutDevice = 0;
+  }
+
+  ui->actionCuteSDR->setChecked(settings.value(
+                                  "PaletteCuteSDR",false).toBool());
+  ui->actionLinrad->setChecked(settings.value(
+                                 "PaletteLinrad",true).toBool());
+  ui->actionAFMHot->setChecked(settings.value(
+                                 "PaletteAFMHot",false).toBool());
+  ui->actionBlue->setChecked(settings.value(
+                                 "PaletteBlue",false).toBool());
+  m_mode=settings.value("Mode","JT9").toString();
+  m_modeTx=settings.value("ModeTx","JT9").toString();
+  if(m_modeTx=="JT9") ui->pbTxMode->setText("Tx JT9  @");
+  if(m_modeTx=="JT65") ui->pbTxMode->setText("Tx JT65  #");
+  ui->actionNone->setChecked(settings.value("SaveNone",true).toBool());
+  ui->actionSave_decoded->setChecked(settings.value(
+                                         "SaveDecoded",false).toBool());
+  ui->actionSave_all->setChecked(settings.value("SaveAll",false).toBool());
+  m_dialFreq=settings.value("DialFreq",14.078).toDouble();
+  m_rxFreq=settings.value("RxFreq",1500).toInt();
+  ui->RxFreqSpinBox->setValue(m_rxFreq);
+  m_txFreq=settings.value("TxFreq",1500).toInt();
+  ui->TxFreqSpinBox->setValue(m_txFreq);
+  soundOutThread.setTxFreq(m_txFreq);
+  m_saveDecoded=ui->actionSave_decoded->isChecked();
+  m_saveAll=ui->actionSave_all->isChecked();
+  m_ndepth=settings.value("NDepth",3).toInt();
+  m_inGain=settings.value("InGain",0).toInt();
+  ui->inGain->setValue(m_inGain);
+  m_monitorStartOFF=settings.value("MonitorOFF",false).toBool();
+  ui->actionMonitor_OFF_at_startup->setChecked(m_monitorStartOFF);
+  m_pskReporter=settings.value("PSKReporter",false).toBool();
+  m_After73=settings.value("After73",false).toBool();
+  m_macro=settings.value("Macros","TNX 73 GL").toStringList();
+  m_dFreq=settings.value("DefaultFreqs","").toStringList();
+  m_toRTTY=settings.value("toRTTY",false).toBool();
+  ui->actionConvert_JT9_x_to_RTTY->setChecked(m_toRTTY);
+  m_noSuffix=settings.value("NoSuffix",false).toBool();
+  ui->actionLog_JT9_without_submode->setChecked(m_noSuffix);
+  m_dBtoComments=settings.value("dBtoComments",false).toBool();
+  ui->actionLog_dB_reports_to_Comments->setChecked(m_dBtoComments);
+  m_rig=settings.value("Rig",214).toInt();
+  m_rigIndex=settings.value("RigIndex",100).toInt();
+  m_catPort=settings.value("CATport","None").toString();
+  m_catPortIndex=settings.value("CATportIndex",0).toInt();
+  m_serialRate=settings.value("SerialRate",4800).toInt();
+  m_serialRateIndex=settings.value("SerialRateIndex",1).toInt();
+  m_dataBits=settings.value("DataBits",8).toInt();
+  m_dataBitsIndex=settings.value("DataBitsIndex",1).toInt();
+  m_stopBits=settings.value("StopBits",2).toInt();
+  m_stopBitsIndex=settings.value("StopBitsIndex",1).toInt();
+  m_handshake=settings.value("Handshake","None").toString();
+  m_handshakeIndex=settings.value("HandshakeIndex",0).toInt();
+  m_band=settings.value("BandIndex",7).toInt();
+  ui->bandComboBox->setCurrentIndex(m_band);
+  dialFreqChanged2(m_dialFreq);
+  m_catEnabled=settings.value("catEnabled",false).toBool();
+  m_promptToLog=settings.value("PromptToLog",false).toBool();
+  ui->actionPrompt_to_log_QSO->setChecked(m_promptToLog);
+  m_insertBlank=settings.value("InsertBlank",false).toBool();
+  ui->actionBlank_line_between_decoding_periods->setChecked(m_insertBlank);
+  m_clearCallGrid=settings.value("ClearCallGrid",false).toBool();
+  ui->actionClear_DX_Call_and_Grid_after_logging->setChecked(m_clearCallGrid);
+  m_bMiles=settings.value("Miles",false).toBool();
+  ui->actionDisplay_distance_in_miles->setChecked(m_bMiles);
+  int n=settings.value("GUItab",0).toInt();
+  ui->tabWidget->setCurrentIndex(n);
+  m_quickCall=settings.value("QuickCall",false).toBool();
+  ui->actionDouble_click_on_call_sets_Tx_Enable->setChecked(m_quickCall);
+  m_73TxDisable=settings.value("73TxDisable",false).toBool();
+  ui->action_73TxDisable->setChecked(m_73TxDisable);
+  m_runaway=settings.value("Runaway",false).toBool();
+  ui->actionRunaway_Tx_watchdog->setChecked(m_runaway);
+  m_tx2QSO=settings.value("Tx2QSO",false).toBool();
+  ui->actionTx2QSO->setChecked(m_tx2QSO);
+  m_bMultipleOK=settings.value("MultipleOK",false).toBool();
+  ui->actionAllow_multiple_instances->setChecked(m_bMultipleOK);
+  m_bDTRoff=settings.value("DTRoff",false).toBool();
+  m_pttData=settings.value("pttData",false).toBool();
+  m_poll=settings.value("Polling",0).toInt();
+  m_logQSOgeom=settings.value("LogQSOgeom",QRect(500,400,424,283)).toRect();
+  outBufSize=settings.value("OutBufSize",4096).toInt();
+  m_lockTxFreq=settings.value("LockTxFreq",false).toBool();
+  ui->cbTxLock->setChecked(m_lockTxFreq);
+  m_saveTxPower=settings.value("SaveTxPower",false).toBool();
+  m_saveComments=settings.value("SaveComments",false).toBool();
+  m_txPower=settings.value("TxPower","").toString();
+  m_logComments=settings.value("LogComments","").toString();
+  m_pskAntenna=settings.value("PSKantenna","").toString();
+  m_fMin=settings.value("fMin",2500).toInt();
+  m_bSplit=settings.value("TxSplit",false).toBool();
+  m_bXIT=settings.value("UseXit",false).toBool();
+  m_plus2kHz=settings.value("Plus2kHz",false).toBool();
+  ui->cbPlus2kHz->setChecked(m_plus2kHz);
+  settings.endGroup();
+
+  if(!ui->actionLinrad->isChecked() && !ui->actionCuteSDR->isChecked() &&
+    !ui->actionAFMHot->isChecked() && !ui->actionBlue->isChecked()) {
+    on_actionLinrad_triggered();
+    ui->actionLinrad->setChecked(true);
+  }
+  if(m_ndepth==1) ui->actionQuickDecode->setChecked(true);
+  if(m_ndepth==2) ui->actionMediumDecode->setChecked(true);
+  if(m_ndepth==3) ui->actionDeepestDecode->setChecked(true);
+
+  statusChanged();
+}
+
+//-------------------------------------------------------------- dataSink()
+void MainWindow::dataSink(int k)
+{
+  static float s[NSMAX];
+  static int ihsym=0;
+  static int nzap=0;
+  static int trmin;
+  static int npts8;
+  static float px=0.0;
+  static float df3;
+  static float slope;
+
+  if(m_diskData) {
+    jt9com_.ndiskdat=1;
+  } else {
+    jt9com_.ndiskdat=0;
+  }
+
+// Get power, spectrum, and ihsym
+  trmin=m_TRperiod/60;
+  slope=0.0;
+  if(g_pWideGraph!=NULL) slope=(float)g_pWideGraph->getSlope();
+  symspec_(&k,&trmin,&m_nsps,&m_inGain,&slope,&px,s,&df3,&ihsym,&npts8);
+  if(ihsym <=0) return;
+  QString t;
+  m_pctZap=nzap*100.0/m_nsps;
+  t.sprintf(" Rx noise: %5.1f ",px);
+  signalMeter->setValue(px);                            // Update thermometer
+  if(m_monitoring || m_diskData) {
+    g_pWideGraph->dataSink2(s,df3,ihsym,m_diskData);
+  }
+
+  if(ihsym == m_hsymStop) {
+    m_dataAvailable=true;
+    jt9com_.npts8=(ihsym*m_nsps)/16;
+    jt9com_.newdat=1;
+    jt9com_.nagain=0;
+    jt9com_.nzhsym=m_hsymStop;
+    QDateTime t = QDateTime::currentDateTimeUtc();
+    m_dateTime=t.toString("yyyy-MMM-dd hh:mm");
+    decode();                                                //Start decoder
+    if(!m_diskData) {                        //Always save; may delete later
+      int ihr=t.time().toString("hh").toInt();
+      int imin=t.time().toString("mm").toInt();
+      imin=imin - (imin%(m_TRperiod/60));
+      QString t2;
+      t2.sprintf("%2.2d%2.2d",ihr,imin);
+      m_fname=m_saveDir + "/" + t.date().toString("yyMMdd") + "_" +
+            t2 + ".wav";
+      *future2 = QtConcurrent::run(savewav, m_fname, m_TRperiod);
+      watcher2->setFuture(*future2);
+    }
+  }
+  soundInThread.m_dataSinkBusy=false;
+}
+
+void MainWindow::showSoundInError(const QString& errorMsg)
+ {QMessageBox::critical(this, tr("Error in SoundIn"), errorMsg);}
+
+void MainWindow::showStatusMessage(const QString& statusMsg)
+ {statusBar()->showMessage(statusMsg);}
+
+void MainWindow::on_actionDeviceSetup_triggered()               //Setup Dialog
+{
+  DevSetup dlg(this);
+  dlg.m_myCall=m_myCall;
+  dlg.m_myGrid=m_myGrid;
+  dlg.m_pskAntenna=m_pskAntenna;
+  dlg.m_idInt=m_idInt;
+  dlg.m_pttMethodIndex=m_pttMethodIndex;
+  dlg.m_pttPort=m_pttPort;
+  dlg.m_saveDir=m_saveDir;
+  dlg.m_paInDevice=m_paInDevice;
+  dlg.m_paOutDevice=m_paOutDevice;
+  dlg.m_pskReporter=m_pskReporter;
+  dlg.m_After73=m_After73;
+  dlg.m_macro=m_macro;
+  dlg.m_dFreq=m_dFreq;
+  dlg.m_catEnabled=m_catEnabled;
+  dlg.m_rig=m_rig;
+  dlg.m_rigIndex=m_rigIndex;
+  dlg.m_catPort=m_catPort;
+  dlg.m_catPortIndex=m_catPortIndex;
+  dlg.m_serialRate=m_serialRate;
+  dlg.m_serialRateIndex=m_serialRateIndex;
+  dlg.m_dataBits=m_dataBits;
+  dlg.m_dataBitsIndex=m_dataBitsIndex;
+  dlg.m_stopBits=m_stopBits;
+  dlg.m_stopBitsIndex=m_stopBitsIndex;
+  dlg.m_handshake=m_handshake;
+  dlg.m_handshakeIndex=m_handshakeIndex;
+  dlg.m_bDTRoff=m_bDTRoff;
+  dlg.m_pttData=m_pttData;
+  dlg.m_poll=m_poll;
+  dlg.m_bSplit=m_bSplit;
+  dlg.m_bXIT=m_bXIT;
+
+  if(m_bRigOpen) {
+    rig->close();
+    ui->readFreq->setStyleSheet("");
+    ui->readFreq->setEnabled(false);
+    if(m_rig<9900) delete rig;
+    m_bRigOpen=false;
+    m_catEnabled=false;
+    m_CATerror=false;
+  }
+
+  dlg.initDlg();
+  if(dlg.exec() == QDialog::Accepted) {
+    m_myCall=dlg.m_myCall;
+    m_myGrid=dlg.m_myGrid;
+    m_pskAntenna=dlg.m_pskAntenna;
+    m_idInt=dlg.m_idInt;
+    m_pttMethodIndex=dlg.m_pttMethodIndex;
+    m_pttPort=dlg.m_pttPort;
+    m_saveDir=dlg.m_saveDir;
+    m_paInDevice=dlg.m_paInDevice;
+    m_paOutDevice=dlg.m_paOutDevice;
+    m_macro=dlg.m_macro;
+    m_dFreq=dlg.m_dFreq;
+    m_catEnabled=dlg.m_catEnabled;
+    m_rig=dlg.m_rig;
+    m_rigIndex=dlg.m_rigIndex;
+    m_catPort=dlg.m_catPort;
+    m_catPortIndex=dlg.m_catPortIndex;
+    m_serialRate=dlg.m_serialRate;
+    m_serialRateIndex=dlg.m_serialRateIndex;
+    m_dataBits=dlg.m_dataBits;
+    m_dataBitsIndex=dlg.m_dataBitsIndex;
+    m_stopBits=dlg.m_stopBits;
+    m_stopBitsIndex=dlg.m_stopBitsIndex;
+    m_handshake=dlg.m_handshake;
+    m_handshakeIndex=dlg.m_handshakeIndex;
+    m_bDTRoff=dlg.m_bDTRoff;
+    m_pttData=dlg.m_pttData;
+    m_poll=dlg.m_poll;
+
+#ifdef WIN32
+    if(dlg.m_pskReporter!=m_pskReporter) {
+      if(dlg.m_pskReporter) {
+        int rc=ReporterInitialize(NULL,NULL);
+        if(rc==0) {
+          m_pskReporterInit=true;
+        } else {
+          m_pskReporterInit=false;
+          rc=ReporterGetInformation(buffer,256);
+          msgBox(QString::fromStdWString(buffer));
+        }
+      } else {
+        rc=ReporterUninitialize();
+        m_pskReporterInit=false;
+      }
+    }
+#endif
+    m_pskReporter=dlg.m_pskReporter;
+
+#ifdef UNIX
+    if(m_pskReporter) {
+      psk_Reporter->setLocalStation(m_myCall,m_myGrid, "WSJT-X r" + rev.mid(6,4) );
+    }
+#endif
+
+    m_After73=dlg.m_After73;
+
+    if(dlg.m_restartSoundIn) {
+      soundInThread.quit();
+      soundInThread.wait(1000);
+      soundInThread.setInputDevice(m_paInDevice);
+      soundInThread.start(QThread::HighestPriority);
+    }
+
+    if(dlg.m_restartSoundOut) {
+      soundOutThread.quitExecution=true;
+      soundOutThread.wait(1000);
+      soundOutThread.setOutputDevice(m_paOutDevice);
+    }
+  }
+  m_catEnabled=dlg.m_catEnabled;
+
+  if(m_catEnabled) {
+    rigOpen();
+  } else {
+    ui->readFreq->setStyleSheet("");
+  }
+
+  if(dlg.m_bSplit!=m_bSplit or dlg.m_bXIT!=m_bXIT) {
+    m_bSplit=dlg.m_bSplit;
+    m_bXIT=dlg.m_bXIT;
+    if(m_bSplit or m_bXIT) setXIT(m_txFreq);
+    if(m_bRigOpen and !m_bSplit) {
+      int ret=rig->setSplitFreq(MHz(m_dialFreq),RIG_VFO_B);
+      if(ret!=RIG_OK) {
+        QString rt;
+        rt.sprintf("Setting VFO_B failed:  %d",ret);
+        msgBox(rt);
+      }
+    }
+  }
+}
+
+void MainWindow::on_monitorButton_clicked()                  //Monitor
+{
+  m_monitoring=true;
+  soundInThread.setMonitoring(true);
+  m_diskData=false;
+}
+
+void MainWindow::on_actionLinrad_triggered()                 //Linrad palette
+{
+  if(g_pWideGraph != NULL) g_pWideGraph->setPalette("Linrad");
+}
+
+void MainWindow::on_actionCuteSDR_triggered()                //CuteSDR palette
+{
+  if(g_pWideGraph != NULL) g_pWideGraph->setPalette("CuteSDR");
+}
+
+void MainWindow::on_actionAFMHot_triggered()
+{
+  if(g_pWideGraph != NULL) g_pWideGraph->setPalette("AFMHot");
+}
+
+void MainWindow::on_actionBlue_triggered()
+{
+  if(g_pWideGraph != NULL) g_pWideGraph->setPalette("Blue");
+}
+
+void MainWindow::on_actionAbout_triggered()                  //Display "About"
+{
+  CAboutDlg dlg(this,Program_Title_Version);
+  dlg.exec();
+}
+
+void MainWindow::on_autoButton_clicked()                     //Auto
+{
+  m_auto = !m_auto;
+  if(m_auto) {
+    ui->autoButton->setStyleSheet(m_pbAutoOn_style);
+  } else {
+    btxok=false;
+    ui->autoButton->setStyleSheet("");
+    on_monitorButton_clicked();
+    m_repeatMsg=0;
+  }
+}
+
+void MainWindow::keyPressEvent( QKeyEvent *e )                //keyPressEvent
+{
+  int n;
+  switch(e->key())
+  {
+  case Qt::Key_1:
+    if(e->modifiers() & Qt::AltModifier) {
+      on_txb1_clicked();
+      break;
+    }
+  case Qt::Key_2:
+    if(e->modifiers() & Qt::AltModifier) {
+      on_txb2_clicked();
+      break;
+    }
+  case Qt::Key_3:
+    if(e->modifiers() & Qt::AltModifier) {
+      on_txb3_clicked();
+      break;
+    }
+  case Qt::Key_4:
+    if(e->modifiers() & Qt::AltModifier) {
+      on_txb4_clicked();
+      break;
+    }
+  case Qt::Key_5:
+    if(e->modifiers() & Qt::AltModifier) {
+      on_txb5_clicked();
+      break;
+    }
+  case Qt::Key_6:
+    if(e->modifiers() & Qt::AltModifier) {
+      on_txb6_clicked();
+      break;
+    }
+  case Qt::Key_D:
+    if(e->modifiers() & Qt::ShiftModifier) {
+      if(!m_decoderBusy) {
+        jt9com_.newdat=0;
+        jt9com_.nagain=0;
+        decode();
+        break;
+      }
+    }
+    break;
+  case Qt::Key_F4:
+    ui->dxCallEntry->setText("");
+    ui->dxGridEntry->setText("");
+    genStdMsgs("");
+    m_ntx=6;
+    ui->txrb6->setChecked(true);
+    break;
+  case Qt::Key_F6:
+    if(e->modifiers() & Qt::ShiftModifier) {
+      on_actionDecode_remaining_files_in_directory_triggered();
+    }
+    break;
+  case Qt::Key_F11:
+    n=11;
+    if(e->modifiers() & Qt::ControlModifier) n+=100;
+    bumpFqso(n);
+    break;
+  case Qt::Key_F12:
+    n=12;
+    if(e->modifiers() & Qt::ControlModifier) n+=100;
+    bumpFqso(n);
+    break;
+  case Qt::Key_F:
+    if(e->modifiers() & Qt::ControlModifier) {
+      if(ui->tabWidget->currentIndex()==0) {
+        ui->tx5->clear();
+        ui->tx5->setFocus();
+      } else {
+        ui->freeTextMsg->clear();
+        ui->freeTextMsg->setFocus();
+      }
+      break;
+    }
+  case Qt::Key_G:
+    if(e->modifiers() & Qt::AltModifier) {
+      genStdMsgs(m_rpt);
+      break;
+    }
+  case Qt::Key_H:
+    if(e->modifiers() & Qt::AltModifier) {
+      on_stopTxButton_clicked();
+      break;
+    }
+  case Qt::Key_L:
+    if(e->modifiers() & Qt::ControlModifier) {
+      lookup();
+      genStdMsgs(m_rpt);
+      break;
+    }
+  case Qt::Key_V:
+    if(e->modifiers() & Qt::AltModifier) {
+      m_fileToSave=m_fname;
+      break;
+    }
+  }
+}
+
+void MainWindow::bumpFqso(int n)                                 //bumpFqso()
+{
+  int i;
+  bool ctrl = (n>=100);
+  n=n%100;
+  i=g_pWideGraph->rxFreq();
+  if(n==11) i--;
+  if(n==12) i++;
+  g_pWideGraph->setRxFreq(i);
+  if(ctrl) {
+    ui->TxFreqSpinBox->setValue(i);
+    g_pWideGraph->setTxFreq(i);
+  }
+}
+
+void MainWindow::dialFreqChanged2(double f)
+{
+  m_dialFreq=f;
+  if(m_band<0 or m_band>15 or m_dFreq.length()<=1) return;
+  QString t;
+  t.sprintf("%.6f",m_dialFreq);
+  int n=t.length();
+  t=t.mid(0,n-3) + " " + t.mid(n-3,3);
+  double fBand=m_dFreq[m_band].toDouble();
+  if(qAbs(m_dialFreq-fBand)<0.01) {
+    ui->labDialFreq->setStyleSheet( \
+        "QLabel { background-color : black; color : yellow; }");
+  } else {
+    ui->labDialFreq->setStyleSheet( \
+          "QLabel { background-color : red; color : yellow; }");
+    ui->labDialFreq->setText(t);
+  }
+  ui->labDialFreq->setText(t);
+  statusChanged();
+  if(g_pWideGraph!=NULL) g_pWideGraph->setDialFreq(m_dialFreq);
+}
+
+void MainWindow::statusChanged()
+{
+  QFile f("wsjtx_status.txt");
+  if(f.open(QFile::WriteOnly | QIODevice::Text)) {
+    QTextStream out(&f);
+    out << m_dialFreq << ";" << m_mode << ";" << m_hisCall << ";"
+        << ui->rptSpinBox->value() << ";" << m_modeTx << endl;
+    f.close();
+  } else {
+    msgBox("Cannot open file \"wsjtx_status.txt\".");
+    return;
+  }
+}
+
+bool MainWindow::eventFilter(QObject *object, QEvent *event)  //eventFilter()
+{
+  if (event->type() == QEvent::KeyPress) {
+    QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+    MainWindow::keyPressEvent(keyEvent);
+    return QObject::eventFilter(object, event);
+  }
+  return QObject::eventFilter(object, event);
+}
+
+void MainWindow::createStatusBar()                           //createStatusBar
+{
+  lab1 = new QLabel("Receiving");
+  lab1->setAlignment(Qt::AlignHCenter);
+  lab1->setMinimumSize(QSize(80,18));
+  lab1->setStyleSheet("QLabel{background-color: #00ff00}");
+  lab1->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+  statusBar()->addWidget(lab1);
+
+  lab2 = new QLabel("");
+  lab2->setAlignment(Qt::AlignHCenter);
+  lab2->setMinimumSize(QSize(150,18));
+  lab2->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+  statusBar()->addWidget(lab2);
+
+  lab3 = new QLabel("");
+  lab3->setAlignment(Qt::AlignHCenter);
+  lab3->setMinimumSize(QSize(80,18));
+  lab3->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+  statusBar()->addWidget(lab3);
+}
+
+void MainWindow::on_actionExit_triggered()                     //Exit()
+{
+  OnExit();
+}
+
+void MainWindow::closeEvent(QCloseEvent*)
+{
+  OnExit();
+}
+
+void MainWindow::OnExit()
+{
+  g_pWideGraph->saveSettings();
+  if(m_fname != "") killFile();
+  m_killAll=true;
+  mem_jt9->detach();
+  QFile quitFile(m_appDir + "/.quit");
+  quitFile.open(QIODevice::ReadWrite);
+  QFile lockFile(m_appDir + "/.lock");
+  lockFile.remove();                      // Allow jt9 to terminate
+  bool b=proc_jt9.waitForFinished(1000);
+  if(!b) proc_jt9.kill();
+  quitFile.remove();
+  qApp->exit(0);                                      // Exit the event loop
+}
+
+void MainWindow::on_stopButton_clicked()                       //stopButton
+{
+  m_monitoring=false;
+  soundInThread.setMonitoring(m_monitoring);
+  m_loopall=false;  
+}
+
+void MainWindow::msgBox(QString t)                             //msgBox
+{
+  msgBox0.setText(t);
+  msgBox0.exec();
+}
+
+void MainWindow::on_actionOnline_Users_Guide_triggered()      //Display manual
+{
+  QDesktopServices::openUrl(QUrl(
+  "http://www.physics.princeton.edu/pulsar/K1JT/WSJT-X_Users_Guide_v1.1.pdf",
+                              QUrl::TolerantMode));
+}
+
+void MainWindow::on_actionWide_Waterfall_triggered()      //Display Waterfalls
+{
+  if(g_pWideGraph==NULL) {
+    g_pWideGraph = new WideGraph(0);
+    g_pWideGraph->setWindowTitle("Wide Graph");
+    g_pWideGraph->setGeometry(m_wideGraphGeom);
+    Qt::WindowFlags flags = Qt::WindowCloseButtonHint |
+        Qt::WindowMinimizeButtonHint;
+    g_pWideGraph->setWindowFlags(flags);
+    connect(g_pWideGraph, SIGNAL(freezeDecode2(int)),this,
+            SLOT(freezeDecode(int)));
+    connect(g_pWideGraph, SIGNAL(f11f12(int)),this,
+            SLOT(bumpFqso(int)));
+    connect(g_pWideGraph, SIGNAL(setXIT2(int)),this,
+            SLOT(setXIT(int)));
+//    connect(g_pWideGraph, SIGNAL(dialFreqChanged(double)),this,
+//            SLOT(dialFreqChanged2(double)));
+  }
+  g_pWideGraph->show();
+}
+
+void MainWindow::on_actionOpen_triggered()                     //Open File
+{
+  m_monitoring=false;
+  soundInThread.setMonitoring(m_monitoring);
+  QString fname;
+  fname=QFileDialog::getOpenFileName(this, "Open File", m_path,
+                                       "WSJT Files (*.wav)");
+  if(fname != "") {
+    m_path=fname;
+    int i;
+    i=fname.indexOf(".wav") - 11;
+    if(i>=0) {
+      lab1->setStyleSheet("QLabel{background-color: #66ff66}");
+      lab1->setText(" " + fname.mid(i,15) + " ");
+    }
+    on_stopButton_clicked();
+    m_diskData=true;
+    *future1 = QtConcurrent::run(getfile, fname, m_TRperiod);
+    watcher1->setFuture(*future1);         // call diskDat() when done
+  }
+}
+
+void MainWindow::on_actionOpen_next_in_directory_triggered()   //Open Next
+{
+  int i,len;
+  QFileInfo fi(m_path);
+  QStringList list;
+  list= fi.dir().entryList().filter(".wav");
+  for (i = 0; i < list.size()-1; ++i) {
+    if(i==list.size()-2) m_loopall=false;
+    len=list.at(i).length();
+    if(list.at(i)==m_path.right(len)) {
+      int n=m_path.length();
+      QString fname=m_path.replace(n-len,len,list.at(i+1));
+      m_path=fname;
+      int i;
+      i=fname.indexOf(".wav") - 11;
+      if(i>=0) {
+        lab1->setStyleSheet("QLabel{background-color: #66ff66}");
+        lab1->setText(" " + fname.mid(i,len) + " ");
+      }
+      m_diskData=true;
+      *future1 = QtConcurrent::run(getfile, fname, m_TRperiod);
+      watcher1->setFuture(*future1);
+      return;
+    }
+  }
+}
+                                                   //Open all remaining files
+void MainWindow::on_actionDecode_remaining_files_in_directory_triggered()
+{
+  m_loopall=true;
+  on_actionOpen_next_in_directory_triggered();
+}
+
+void MainWindow::diskDat()                                   //diskDat()
+{
+  int k;
+  int kstep=m_nsps/2;
+  m_diskData=true;
+  for(int n=1; n<=m_hsymStop; n++) {              // Do the half-symbol FFTs
+    k=(n+1)*kstep;
+    jt9com_.npts8=k/8;
+    dataSink(k);
+    if(n%10 == 1 or n == m_hsymStop)
+        qApp->processEvents();                   //Keep GUI responsive
+  }
+}
+
+void MainWindow::diskWriteFinished()                       //diskWriteFinished
+{
+}
+
+//Delete ../save/*.wav
+void MainWindow::on_actionDelete_all_wav_files_in_SaveDir_triggered()
+{
+  int i;
+  QString fname;
+  int ret = QMessageBox::warning(this, "Confirm Delete",
+      "Are you sure you want to delete all *.wav files in\n" +
+       QDir::toNativeSeparators(m_saveDir) + " ?",
+       QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+  if(ret==QMessageBox::Yes) {
+    QDir dir(m_saveDir);
+    QStringList files=dir.entryList(QDir::Files);
+    QList<QString>::iterator f;
+    for(f=files.begin(); f!=files.end(); ++f) {
+      fname=*f;
+      i=(fname.indexOf(".wav"));
+      if(i>10) dir.remove(fname);
+    }
+  }
+}
+
+void MainWindow::on_actionNone_triggered()                    //Save None
+{
+  m_saveDecoded=false;
+  m_saveAll=false;
+  ui->actionNone->setChecked(true);
+}
+
+void MainWindow::on_actionSave_decoded_triggered()
+{
+  m_saveDecoded=true;
+  m_saveAll=false;
+  ui->actionSave_decoded->setChecked(true);
+}
+
+void MainWindow::on_actionSave_all_triggered()                //Save All
+{
+  m_saveDecoded=false;
+  m_saveAll=true;
+  ui->actionSave_all->setChecked(true);
+}
+
+void MainWindow::on_actionKeyboard_shortcuts_triggered()
+{
+  pShortcuts = new QTextEdit(0);
+  pShortcuts->setReadOnly(true);
+  pShortcuts->setFontPointSize(10);
+  pShortcuts->setWindowTitle("Keyboard Shortcuts");
+  pShortcuts->setGeometry(QRect(45,50,430,460));
+  Qt::WindowFlags flags = Qt::WindowCloseButtonHint |
+      Qt::WindowMinimizeButtonHint;
+  pShortcuts->setWindowFlags(flags);
+  QString shortcuts = m_appDir + "/shortcuts.txt";
+  QFile f(shortcuts);
+  if(!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+    msgBox("Cannot open " + shortcuts);
+    return;
+  }
+  QTextStream s(&f);
+  QString t;
+  for(int i=0; i<100; i++) {
+    t=s.readLine();
+    pShortcuts->append(t);
+    if(s.atEnd()) break;
+  }
+  pShortcuts->show();
+}
+
+void MainWindow::on_actionSpecial_mouse_commands_triggered()
+{
+  QTextEdit* pMouseCmnds;
+  pMouseCmnds = new QTextEdit(0);
+  pMouseCmnds->setReadOnly(true);
+  pMouseCmnds->setFontPointSize(10);
+  pMouseCmnds->setWindowTitle("Special Mouse Commands");
+  pMouseCmnds->setGeometry(QRect(45,50,440,300));
+  Qt::WindowFlags flags = Qt::WindowCloseButtonHint |
+      Qt::WindowMinimizeButtonHint;
+  pMouseCmnds->setWindowFlags(flags);
+  QString mouseCmnds = m_appDir + "/mouse_commands.txt";
+  QFile f(mouseCmnds);
+  if(!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+    msgBox("Cannot open " + mouseCmnds);
+    return;
+  }
+  QTextStream s(&f);
+  QString t;
+  for(int i=0; i<100; i++) {
+    t=s.readLine();
+    pMouseCmnds->append(t);
+    if(s.atEnd()) break;
+  }
+  pMouseCmnds->show();
+}
+
+void MainWindow::on_DecodeButton_clicked()                    //Decode request
+{
+  if(!m_decoderBusy) {
+    jt9com_.newdat=0;
+    jt9com_.nagain=1;
+    decode();
+  }
+}
+
+void MainWindow::freezeDecode(int n)                          //freezeDecode()
+{
+  bool ctrl = (n>=100);
+  int i=g_pWideGraph->rxFreq();
+  if(ctrl) {
+    ui->TxFreqSpinBox->setValue(i);
+    g_pWideGraph->setTxFreq(i);
+  }
+  if((n%100)==2) on_DecodeButton_clicked();
+}
+
+void MainWindow::decode()                                       //decode()
+{
+  if(!m_dataAvailable) return;
+  ui->DecodeButton->setStyleSheet(m_pbdecoding_style1);
+  if(jt9com_.newdat==1 && (!m_diskData)) {
+    qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
+    int imin=ms/60000;
+    int ihr=imin/60;
+    imin=imin % 60;
+    imin=imin - (imin % (m_TRperiod/60));
+    jt9com_.nutc=100*ihr + imin;
+  }
+
+  jt9com_.nfqso=g_pWideGraph->rxFreq();
+  jt9com_.ndepth=m_ndepth;
+  jt9com_.ndiskdat=0;
+  if(m_diskData) jt9com_.ndiskdat=1;
+  int nfa=g_pWideGraph->getFmin();
+  int nfb=g_pWideGraph->getFmax();
+  if(m_mode=="JT9") nfa=200;                //decode from 0 to fmax
+  if(m_mode=="JT65") nfa=nfb;               //decode from 0 to fmax
+  jt9com_.nfa=nfa;
+  jt9com_.nfb=nfb;
+  jt9com_.ntol=20;
+  if(jt9com_.nutc < m_nutc0) m_RxLog |= 1;  //Date and Time to all.txt
+  m_nutc0=jt9com_.nutc;
+  jt9com_.ntxmode=9;
+  if(m_modeTx=="JT65") jt9com_.ntxmode=65;
+  jt9com_.nmode=9;
+  if(m_mode=="JT65") jt9com_.nmode=65;
+  if(m_mode=="JT9+JT65") jt9com_.nmode=9+65;
+  jt9com_.ntrperiod=m_TRperiod;
+  m_nsave=0;
+  if(m_saveDecoded) m_nsave=2;
+  jt9com_.nsave=m_nsave;
+  strncpy(jt9com_.datetime, m_dateTime.toLatin1(), 20);
+
+  //newdat=1  ==> this is new data, must do the big FFT
+  //nagain=1  ==> decode only at fQSO +/- Tol
+
+  char *to = (char*)mem_jt9->data();
+  char *from = (char*) jt9com_.ss;
+  int size=sizeof(jt9com_);
+  if(jt9com_.newdat==0) {
+    int noffset = 4*184*NSMAX + 4*NSMAX + 2*NTMAX*12000;
+    to += noffset;
+    from += noffset;
+    size -= noffset;
+  }
+  memcpy(to, from, qMin(mem_jt9->size(), size));
+
+  QFile lockFile(m_appDir + "/.lock");       // Allow jt9 to start
+  lockFile.remove();
+  decodeBusy(true);
+}
+
+void MainWindow::jt9_error()                                     //jt9_error
+{
+  if(!m_killAll) {
+    msgBox("Error starting or running\n" + m_appDir + "/jt9 -s");
+    exit(1);
+  }
+}
+
+void MainWindow::readFromStderr()                             //readFromStderr
+{
+  QByteArray t=proc_jt9.readAllStandardError();
+  msgBox(t);
+}
+
+void MainWindow::readFromStdout()                             //readFromStdout
+{
+  while(proc_jt9.canReadLine()) {
+    QByteArray t=proc_jt9.readLine();
+    if(t.indexOf("<DecodeFinished>") >= 0) {
+      m_bdecoded = (t.mid(23,1).toInt()==1);
+      bool keepFile=m_saveAll or (m_saveDecoded and m_bdecoded);
+      if(!keepFile and !m_diskData) killFileTimer->start(45*1000); //Kill in 45 s
+      jt9com_.nagain=0;
+      jt9com_.ndiskdat=0;
+      QFile lockFile(m_appDir + "/.lock");
+      lockFile.open(QIODevice::ReadWrite);
+      ui->DecodeButton->setStyleSheet("");
+      decodeBusy(false);
+      m_RxLog=0;
+      m_startAnother=m_loopall;
+      m_blankLine=true;
+      return;
+    } else {
+      QFile f("ALL.TXT");
+      f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
+      QTextStream out(&f);
+      if(m_RxLog && 1) {
+        out << QDateTime::currentDateTimeUtc().toString("yyyy-MMM-dd hh:mm")
+            << "  " << m_dialFreq << " MHz  " << m_mode << endl;
+        m_RxLog=0;
+      }
+      int n=t.length();
+      out << t.mid(0,n-2) << endl;
+      f.close();
+
+      QTextCursor cursor;
+      QTextBlockFormat bf;
+      if(m_insertBlank and m_blankLine and jt9com_.nagain==0) {
+        QString bg="#d3d3d3";
+        bf.setBackground(QBrush(QColor(bg)));
+        QString tt="----------------------------------------";
+        QString s = "<table border=0 cellspacing=0 width=100%><tr><td bgcolor=\"" +
+            bg + "\"><pre>" + tt + "</pre></td></tr></table>";
+        cursor = ui->decodedTextBrowser->textCursor();
+        cursor.movePosition(QTextCursor::End);
+        bf = cursor.blockFormat();
+        bf.setBackground(QBrush(QColor(bg)));
+        cursor.insertHtml(s);
+        m_blankLine=false;
+      }
+
+      QString bg="white";
+      if(t.indexOf(" CQ ")>0) bg="#66ff66";                          //green
+      if(m_myCall!="" and t.indexOf(" "+m_myCall+" ")>0) bg="#ff6666"; //red
+      bool bQSO=abs(t.mid(14,4).toInt() - g_pWideGraph->rxFreq()) <= 10;
+      QString t1=t.replace("\n","").mid(0,t.length()-4);
+      QString s = "<table border=0 cellspacing=0 width=100%><tr><td bgcolor=\"" +
+          bg + "\"><pre>" + t1 + "</pre></td></tr></table>";
+      bool b65=t1.indexOf("#")==19;
+      if(bQSO) {
+        cursor = ui->decodedTextBrowser2->textCursor();
+        cursor.movePosition(QTextCursor::End);
+        bf = cursor.blockFormat();
+        bf.setBackground(QBrush(QColor(bg)));
+        cursor.insertHtml(s);
+        ui->decodedTextBrowser2->setTextCursor(cursor);
+        m_QSOmsg=t1;
+        if(b65 and m_modeTx!="JT65") on_pbTxMode_clicked();
+        if(!b65 and m_modeTx=="JT65") on_pbTxMode_clicked();
+      }
+
+      if(jt9com_.nagain==0) {
+        if(t.indexOf(" CQ ")>0) bg="#66ff66";                          //green
+        if(m_myCall!="" and t.indexOf(" "+m_myCall+" ")>0) bg="#ff6666"; //red
+        QString s = "<table border=0 cellspacing=0 width=100%><tr><td bgcolor=\"" +
+            bg + "\"><pre>" + t1 + "</pre></td></tr></table>";
+        cursor = ui->decodedTextBrowser->textCursor();
+        cursor.movePosition(QTextCursor::End);
+        bf = cursor.blockFormat();
+        bf.setBackground(QBrush(QColor(bg)));
+        cursor.insertHtml(s);
+        ui->decodedTextBrowser->setTextCursor(cursor);
+      }
+
+      QString msg=t.mid(21);
+      int i1=msg.indexOf("\r");
+      if(i1>0) msg=msg.mid(0,i1-1) + "                      ";
+      bool b=stdmsg_(msg.mid(0,22).toLatin1().constData(),22);
+      QStringList w=msg.split(" ",QString::SkipEmptyParts);
+      if(b and w[0]==m_myCall) {
+        QString tt="";
+        if(w.length()>=3) tt=w[2];
+        bool ok;
+        i1=tt.toInt(&ok);
+        if(ok and i1>=-50 and i1<50) {
+          m_rptRcvd=tt;
+        } else {
+          if(tt.mid(0,1)=="R") {
+            i1=tt.mid(1).toInt(&ok);
+            if(ok and i1>=-50 and i1<50) {
+              m_rptRcvd=tt.mid(1);
+            }
+          }
+        }
+      }
+
+      int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged;
+      bool okToPost=(nsec>50);
+      QString msgmode="JT9";
+      if(b65) msgmode="JT65";
+      i1=msg.indexOf(" ");
+      QString c2=msg.mid(i1+1);
+      int i2=c2.indexOf(" ");
+      QString g2=c2.mid(i2+1,4);
+      c2=c2.mid(0,i2);
+      QString remote="call," + c2 + ",";
+      if(gridOK(g2)) remote += "gridsquare," + g2 + ",";
+      int nHz=t.mid(14,4).toInt();
+      uint nfreq=1000000.0*m_dialFreq + nHz + 0.5;
+      remote += "freq," + QString::number(nfreq);
+      int nsnr=t.mid(5,3).toInt();
+      remote += ",mode," + msgmode + ",snr," + QString::number(nsnr) + ",,";
+      wchar_t tremote[256];
+      remote.toWCharArray(tremote);
+
+#ifdef WIN32
+      if(m_pskReporterInit and b and !m_diskData and okToPost) {
+
+        QString local="station_callsign#" + m_myCall + "#" +
+            "my_gridsquare#" + m_myGrid + "#";
+        if(m_pskAntenna!="") local += "my_antenna#" + m_pskAntenna + "#";
+        local += "programid#WSJT-X#programversion#" + rev.mid(6,4) + "##";
+        wchar_t tlocal[256];
+        local.toWCharArray(tlocal);
+
+        int flags=REPORTER_SOURCE_AUTOMATIC;
+        rc=ReporterSeenCallsign(tremote,tlocal,flags);
+        if(rc!=0) {
+          ReporterGetInformation(buffer,256);
+        }
+        rc=ReporterTickle();
+        if(rc!=0) {
+          rc=ReporterGetInformation(buffer,256);
+        }
+      }
+#else
+      if(m_pskReporter and b and !m_diskData and okToPost) {
+        QString freq = QString::number(nfreq);
+        QString snr= QString::number(nsnr);
+        if(gridOK(g2)) {
+          psk_Reporter->addRemoteStation(c2,g2,freq,msgmode,snr,
+                   QString::number(QDateTime::currentDateTime().toTime_t()));
+        }
+      }
+#endif
+    }
+  }
+}
+
+void MainWindow::killFile()
+{
+  if(m_fname==m_fileToSave) {
+  } else {
+    QFile savedFile(m_fname);
+    savedFile.remove();
+  }
+}
+
+void MainWindow::on_EraseButton_clicked()                          //Erase
+{
+  qint64 ms=QDateTime::currentMSecsSinceEpoch();
+  ui->decodedTextBrowser2->clear();
+  m_QSOmsg="";
+  if((ms-m_msErase)<500) {
+      ui->decodedTextBrowser->clear();
+      QFile f(m_appDir + "/decoded.txt");
+      if(f.exists()) f.remove();
+  }
+  m_msErase=ms;
+}
+
+void MainWindow::decodeBusy(bool b)                             //decodeBusy()
+{
+  m_decoderBusy=b;
+  ui->DecodeButton->setEnabled(!b);
+  ui->actionOpen->setEnabled(!b);
+  ui->actionOpen_next_in_directory->setEnabled(!b);
+  ui->actionDecode_remaining_files_in_directory->setEnabled(!b);
+}
+
+//------------------------------------------------------------- //guiUpdate()
+void MainWindow::guiUpdate()
+{
+  static int iptt0=0;
+  static bool btxok0=false;
+  static char message[29];
+  static char msgsent[29];
+  static int nsendingsh=0;
+  static int giptt00=-1;
+  static int gcomport00=-1;
+  static double onAirFreq0=0.0;
+  int ret=0;
+  QString rt;
+
+  double tx1=0.0;
+  double tx2=1.0 + 85.0*m_nsps/12000.0 + icw[0]*2560.0/48000.0;
+  if(m_modeTx=="JT65") tx2=1.0 + 126*4096/11025.0 + icw[0]*2560.0/48000.0;
+
+  if(!m_txFirst) {
+    tx1 += m_TRperiod;
+    tx2 += m_TRperiod;
+  }
+  qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
+  int nsec=ms/1000;
+  double tsec=0.001*ms;
+  double t2p=fmod(tsec,2*m_TRperiod);
+  bool bTxTime = ((t2p >= tx1) and (t2p < tx2)) or m_tune;
+
+  if(m_auto or m_tune) {
+    QFile f("txboth");
+    if(f.exists() and fmod(tsec,m_TRperiod) < (1.0 + 85.0*m_nsps/12000.0)) {
+      bTxTime=true;
+    }
+
+    double onAirFreq=m_dialFreq+1.e-6*m_txFreq;
+    if(onAirFreq>10.139900 and onAirFreq<10.140320) {
+      bTxTime=false;
+      if(m_tune) on_tuneButton_clicked();
+      if(onAirFreq!=onAirFreq0) {
+        onAirFreq0=onAirFreq;
+        on_autoButton_clicked();
+        QString t="Please choose another Tx frequency.\n";
+        t+="WSJT-X will not knowingly transmit\n";
+        t+="in the WSPR sub-band on 30 m.";
+        msgBox0.setText(t);
+        msgBox0.show();
+      }
+    }
+
+    float fTR=float((nsec%m_TRperiod))/m_TRperiod;
+    if(g_iptt==0 and ((bTxTime and !btxMute and fTR<0.4) or m_tune )) {
+      icw[0]=m_ncw;
+
+//Raise PTT
+      if(m_catEnabled and m_bRigOpen and  m_pttMethodIndex==0) {
+        g_iptt=1;
+        if(m_pttData) ret=rig->setPTT(RIG_PTT_ON_DATA, RIG_VFO_CURR);
+        if(!m_pttData) ret=rig->setPTT(RIG_PTT_ON_MIC, RIG_VFO_CURR);
+        if(ret!=RIG_OK) {
+          rt.sprintf("CAT control PTT failed:  %d",ret);
+          msgBox(rt);
+        }
+
+      }
+
+      if(m_pttMethodIndex==1 or m_pttMethodIndex==2) {  //DTR or RTS
+        ptt(m_pttPort,1,&g_iptt,&g_COMportOpen);
+      }
+      if(m_pttMethodIndex==3) {                    //VOX
+        g_iptt=1;
+      }
+      ptt1Timer->start(200);                       //Sequencer delay
+    }
+    if(!bTxTime || btxMute) {
+      btxok=false;
+    }
+  }
+
+// Calculate Tx tones when needed
+  if((g_iptt==1 && iptt0==0) || m_restart) {
+    QByteArray ba;
+    if(m_ntx == 1) ba=ui->tx1->text().toLocal8Bit();
+    if(m_ntx == 2) ba=ui->tx2->text().toLocal8Bit();
+    if(m_ntx == 3) ba=ui->tx3->text().toLocal8Bit();
+    if(m_ntx == 4) ba=ui->tx4->text().toLocal8Bit();
+    if(m_ntx == 5) ba=ui->tx5->text().toLocal8Bit();
+    if(m_ntx == 6) ba=ui->tx6->text().toLocal8Bit();
+    if(m_ntx == 7) ba=ui->genMsg->text().toLocal8Bit();
+    if(m_ntx == 8) ba=ui->freeTextMsg->text().toLocal8Bit();
+
+    ba2msg(ba,message);
+//    ba2msg(ba,msgsent);
+    int len1=22;
+    int ichk=0,itext=0;
+    if(m_modeTx=="JT9") genjt9_(message,&ichk,msgsent,itone,&itext,len1,len1);
+    if(m_modeTx=="JT65") gen65_(message,&ichk,msgsent,itone,&itext,len1,len1);
+    msgsent[22]=0;
+    QString t=QString::fromLatin1(msgsent);
+    if(m_tune) t="TUNE";
+    lab2->setText("Last Tx:  " + t);
+    if(m_restart) {
+      QFile f("ALL.TXT");
+      f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
+      QTextStream out(&f);
+      out << QDateTime::currentDateTimeUtc().toString("hhmm")
+          << "  Transmitting " << m_dialFreq << " MHz  " << m_modeTx
+          << ":  " << t << endl;
+      f.close();
+      if(m_tx2QSO) displayTxMsg(t);
+    }
+
+    QStringList w=t.split(" ",QString::SkipEmptyParts);
+    t="";
+    if(w.length()==3) t=w[2];
+    icw[0]=0;
+    m_sent73=(t=="73" or itext!=0);
+    if(m_sent73)  {
+      if(m_After73)  icw[0]=m_ncw;
+      if(m_promptToLog and !m_tune) logQSOTimer->start(200);
+    }
+
+    if(m_idInt>0) {
+      int nmin=(m_sec0-m_secID)/60;
+      if(nmin >= m_idInt) {
+        icw[0]=m_ncw;
+        m_secID=m_sec0;
+      }
+    }
+
+    QString t2=QDateTime::currentDateTimeUtc().toString("hhmm");
+    if(itext==0 and w.length()>=3 and w[1]==m_myCall) {
+      int i1;
+      bool ok;
+      i1=t.toInt(&ok);
+      if(ok and i1>=-50 and i1<50) {
+        m_rptSent=t;
+        m_qsoStart=t2;
+      } else {
+        if(t.mid(0,1)=="R") {
+          i1=t.mid(1).toInt(&ok);
+          if(ok and i1>=-50 and i1<50) {
+            m_rptSent=t.mid(1);
+            m_qsoStart=t2;
+          }
+        }
+      }
+    }
+    if(itext==1 or (w.length()==3 and w[2]=="73")) m_qsoStop=t2;
+    m_restart=false;
+  }
+
+
+// If PTT was just raised, start a countdown for raising TxOK:
+// NB: could be better implemented with a timer
+  if(g_iptt == 1 && iptt0 == 0) {
+      nc1=-9;    // TxDelay = 0.8 s
+  }
+  if(nc1 <= 0) {
+      nc1++;
+  }
+  if(nc1 == 0) {
+    QString t=QString::fromLatin1(msgsent);
+    if(t==m_msgSent0) {
+      m_repeatMsg++;
+    } else {
+      m_repeatMsg=0;
+      m_msgSent0=t;
+    }
+
+    signalMeter->setValue(0);
+    m_monitoring=false;
+    soundInThread.setMonitoring(false);
+    btxok=true;
+    m_transmitting=true;
+    ui->pbTxMode->setEnabled(false);
+    if(!m_tune) {
+      QFile f("ALL.TXT");
+      f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
+      QTextStream out(&f);
+      out << QDateTime::currentDateTimeUtc().toString("hhmm")
+          << "  Transmitting " << m_dialFreq << " MHz  " << m_modeTx
+          << ":  " << t << endl;
+      f.close();
+    }
+    if(m_tx2QSO and !m_tune) displayTxMsg(t);
+  }
+
+  if(!btxok && btxok0 && g_iptt==1) stopTx();
+
+/*
+// If btxok was just lowered, start a countdown for lowering PTT
+  if(!btxok && btxok0 && g_iptt==1) nc0=-11;  //RxDelay = 1.0 s
+  if(nc0 <= 0) {
+    nc0++;
+  }
+*/
+
+  if(m_monitoring) {
+    ui->monitorButton->setStyleSheet(m_pbmonitor_style);
+  } else {
+    ui->monitorButton->setStyleSheet("");
+  }
+
+  if(m_startAnother) {
+    m_startAnother=false;
+    on_actionOpen_next_in_directory_triggered();
+  }
+
+  if(m_catEnabled and !m_bRigOpen) {
+    rigOpen();
+  }
+
+  if(nsec != m_sec0) {                                     //Once per second
+    QDateTime t = QDateTime::currentDateTimeUtc();
+    if(m_transmitting) {
+      if(nsendingsh==1) {
+        lab1->setStyleSheet("QLabel{background-color: #66ffff}");
+      } else if(nsendingsh==-1) {
+        lab1->setStyleSheet("QLabel{background-color: #ffccff}");
+      } else {
+        lab1->setStyleSheet("QLabel{background-color: #ffff33}");
+      }
+      if(m_tune) {
+        lab1->setText("Tx: TUNE");
+      } else {
+          char s[37];
+          sprintf(s,"Tx: %s",msgsent);
+          lab1->setText(s);
+      }
+    } else if(m_monitoring) {
+      lab1->setStyleSheet("QLabel{background-color: #00ff00}");
+      lab1->setText("Receiving ");
+    } else if (!m_diskData) {
+      lab1->setStyleSheet("");
+      lab1->setText("");
+    }
+
+    m_setftx=0;
+    QString utc = t.date().toString("yyyy MMM dd") + "\n " +
+            t.time().toString() + " ";
+    ui->labUTC->setText(utc);
+    if(!m_monitoring and !m_diskData) {
+      signalMeter->setValue(0);
+    }
+
+    if(m_catEnabled and m_poll>0 and (nsec%m_poll)==0 and !m_decoderBusy) {
+      double fMHz;
+      if(m_dontReadFreq) {
+        m_dontReadFreq=false;
+      } else if(!m_transmitting) {
+        for(int iter=0; iter<3; iter++) {
+          fMHz=rig->getFreq(RIG_VFO_CURR)/1000000.0;
+          if(fMHz<0.0 and iter>=2) {
+            rt.sprintf("Rig control error %d\nFailed to read frequency.",
+                       int(1000000.0*fMHz));
+            msgBox(rt);
+            m_catEnabled=false;
+            ui->readFreq->setStyleSheet("QPushButton{background-color: red; \
+                                    border-width: 0px; border-radius: 5px;}");
+        }
+      }
+        int ndiff=1000000.0*(fMHz-m_dialFreq);
+        if(ndiff!=0) dialFreqChanged2(fMHz);
+      }
+    }
+
+    m_sec0=nsec;
+  }
+
+  if(g_iptt!=giptt00 or g_COMportOpen!=gcomport00) {
+    giptt00=g_iptt;
+    gcomport00=g_COMportOpen;
+  }
+
+  iptt0=g_iptt;
+  btxok0=btxok;
+}               //End of GUIupdate
+
+void MainWindow::displayTxMsg(QString t)
+{
+      QString bg="yellow";
+      QTextBlockFormat bf;
+      QTextCursor cursor;
+      QString t1=" @ ";
+      if(m_modeTx=="JT65") t1=" # ";
+      QString t2;
+      t2.sprintf("%4d",m_txFreq);
+      t=QDateTime::currentDateTimeUtc().toString("hhmm") + \
+          "  Tx      " + t2 + t1 + t;
+      QString s = "<table border=0 cellspacing=0 width=100%><tr><td bgcolor=\"" +
+          bg + "\"><pre>" + t + "</pre></td></tr></table>";
+      cursor = ui->decodedTextBrowser2->textCursor();
+      cursor.movePosition(QTextCursor::End);
+      bf = cursor.blockFormat();
+      bf.setBackground(QBrush(QColor(bg)));
+      cursor.insertHtml(s);
+      ui->decodedTextBrowser2->setTextCursor(cursor);
+}
+
+void MainWindow::startTx2()
+{
+  if(!soundOutThread.isRunning()) {
+    QString t=ui->tx6->text();
+    double snr=t.mid(1,5).toDouble();
+    if(snr>0.0 or snr < -50.0) snr=99.0;
+    soundOutThread.setTxSNR(snr);
+    soundOutThread.m_modeTx=m_modeTx;
+    soundOutThread.start(QThread::HighestPriority);
+    signalMeter->setValue(0);
+    m_monitoring=false;
+    soundInThread.setMonitoring(false);
+    btxok=true;
+    m_transmitting=true;
+    ui->pbTxMode->setEnabled(false);
+  }
+}
+
+void MainWindow::stopTx()
+{
+  if (soundOutThread.isRunning()) {
+    soundOutThread.quitExecution=true;
+    soundOutThread.wait(3000);
+  }
+  m_transmitting=false;
+  ui->pbTxMode->setEnabled(true);
+  g_iptt=0;
+  lab1->setStyleSheet("");
+  lab1->setText("");
+  ptt0Timer->start(200);                       //Sequencer delay
+  m_monitoring=true;
+  soundInThread.setMonitoring(true);
+}
+
+void MainWindow::stopTx2()
+{
+  int ret=0;
+  QString rt;
+
+//Lower PTT
+  if(m_catEnabled and m_bRigOpen and  m_pttMethodIndex==0) {
+    ret=rig->setPTT(RIG_PTT_OFF, RIG_VFO_CURR);  //CAT control for PTT=0
+    if(ret!=RIG_OK) {
+      rt.sprintf("CAT control PTT failed:  %d",ret);
+      msgBox(rt);
+    }
+  }
+  if(m_pttMethodIndex==1 or m_pttMethodIndex==2) {
+    ptt(m_pttPort,0,&g_iptt,&g_COMportOpen);
+  }
+  if(m_73TxDisable and m_sent73) on_stopTxButton_clicked();
+
+  if(m_runaway and m_repeatMsg>m_watchdogLimit) {
+    on_stopTxButton_clicked();
+    msgBox0.setText("Runaway Tx watchdog");
+    msgBox0.show();
+    m_repeatMsg=0;
+  }
+}
+
+void MainWindow::ba2msg(QByteArray ba, char message[])             //ba2msg()
+{
+  int iz=ba.length();
+  for(int i=0;i<22; i++) {
+    if(i<iz) {
+      message[i]=ba[i];
+    } else {
+      message[i]=32;
+    }
+  }
+  message[22]=0;
+}
+
+void MainWindow::on_txFirstCheckBox_stateChanged(int nstate)        //TxFirst
+{
+  m_txFirst = (nstate==2);
+}
+
+void MainWindow::set_ntx(int n)                                   //set_ntx()
+{
+  m_ntx=n;
+}
+
+void MainWindow::on_txb1_clicked()                                //txb1
+{
+  m_ntx=1;
+  ui->txrb1->setChecked(true);
+  m_restart=true;
+}
+
+void MainWindow::on_txb2_clicked()                                //txb2
+{
+  m_ntx=2;
+  ui->txrb2->setChecked(true);
+  m_restart=true;
+}
+
+void MainWindow::on_txb3_clicked()                                //txb3
+{
+  m_ntx=3;
+  ui->txrb3->setChecked(true);
+  m_restart=true;
+}
+
+void MainWindow::on_txb4_clicked()                                //txb4
+{
+  m_ntx=4;
+  ui->txrb4->setChecked(true);
+  m_restart=true;
+}
+
+void MainWindow::on_txb5_clicked()                                //txb5
+{
+  m_ntx=5;
+  ui->txrb5->setChecked(true);
+  m_restart=true;
+}
+
+void MainWindow::on_txb6_clicked()                                //txb6
+{
+  m_ntx=6;
+  ui->txrb6->setChecked(true);
+  m_restart=true;
+}
+
+void MainWindow::doubleClickOnCall2(bool shift, bool ctrl)
+{
+
+  m_decodedText2=true;
+  doubleClickOnCall(shift,ctrl);
+  m_decodedText2=false;
+}
+
+void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
+{
+  QTextCursor cursor;
+  if(!m_decodedText2) cursor=ui->decodedTextBrowser2->textCursor();
+  if(m_decodedText2) cursor=ui->decodedTextBrowser->textCursor();
+  cursor.select(QTextCursor::LineUnderCursor);
+  int i2=cursor.position();
+  if(shift and i2==-9999) return;        //Silence compiler warning
+
+  QString t;
+  if(!m_decodedText2) t= ui->decodedTextBrowser2->toPlainText(); //Full contents
+  if(m_decodedText2) t= ui->decodedTextBrowser->toPlainText();
+
+  QString t1 = t.mid(0,i2);              //contents up to \n on selected line
+  int i1=t1.lastIndexOf("\n") + 1;       //points to first char of line
+  QString t2 = t1.mid(i1,i2-i1);         //selected line
+//  if(t2.indexOf("Tx")==6) return;        //Ignore Tx line
+  int i4=t.mid(i1).length();
+  if(i4>55) i4=55;
+  QString t3=t.mid(i1,i4);
+  int i5=t3.indexOf(" CQ DX ");
+  if(i5>0) t3=t3.mid(0,i5+3) + "_" + t3.mid(i5+4);  //Make it "CQ_DX" (one word)
+  QStringList t4=t3.split(" ",QString::SkipEmptyParts);
+  if(t4.length() <5) return;             //Skip the rest if no decoded text
+
+  int i9=m_QSOmsg.indexOf(t2);
+  if(i9<0 and t2.indexOf("Tx")==-1) {
+    QString bg="white";
+    if(t2.indexOf(" CQ ")>0) bg="#66ff66";                           //green
+    if(m_myCall!="" and t2.indexOf(" "+m_myCall+" ")>0) bg="#ff6666"; //red
+    QTextBlockFormat bf;
+    QString s = "<table border=0 cellspacing=0 width=100%><tr><td bgcolor=\"" +
+        bg + "\"><pre>" + t2 + "</pre></td></tr></table>";
+    cursor = ui->decodedTextBrowser2->textCursor();
+    cursor.movePosition(QTextCursor::End);
+    bf = cursor.blockFormat();
+    bf.setBackground(QBrush(QColor(bg)));
+    cursor.insertHtml(s);
+    ui->decodedTextBrowser2->setTextCursor(cursor);
+    m_QSOmsg=t2;
+  }
+
+  int nfreq=t4.at(3).toInt();
+  if(t4.at(1)=="Tx") nfreq=t4.at(2).toInt();
+  g_pWideGraph->setRxFreq(nfreq);                      //Set Rx freq
+  if(t4.at(1)=="Tx") {
+    if(ctrl) ui->TxFreqSpinBox->setValue(nfreq);       //Set Tx freq
+    return;
+  }
+  if(t4.at(4)=="@") {
+    m_modeTx="JT9";
+    ui->pbTxMode->setText("Tx JT9  @");
+    g_pWideGraph->setModeTx(m_modeTx);
+  }
+  if(t4.at(4)=="#") {
+    m_modeTx="JT65";
+    ui->pbTxMode->setText("Tx JT65  #");
+    g_pWideGraph->setModeTx(m_modeTx);
+  }
+  QString firstcall=t4.at(5);
+  // Don't change Tx freq if a station is calling me, unless m_lockTxFreq
+  // is true or CTRL is held down or
+  if((firstcall!=m_myCall) or m_lockTxFreq or ctrl) {
+    ui->TxFreqSpinBox->setValue(nfreq);
+  }
+  QString hiscall=t4.at(6);
+  QString hisgrid="";
+  if(t4.length()>=8) hisgrid=t4.at(7);
+  if(hiscall!=ui->dxCallEntry->text())   ui->dxGridEntry->setText("");
+  ui->dxCallEntry->setText(hiscall);
+  if(gridOK(hisgrid)) ui->dxGridEntry->setText(hisgrid);
+  if(ui->dxGridEntry->text()=="") lookup();
+  m_hisGrid=ui->dxGridEntry->text();
+  int n = 60*t2.mid(0,2).toInt() + t2.mid(2,2).toInt();
+  int nmod=n%(m_TRperiod/30);
+  m_txFirst=(nmod!=0);
+  ui->txFirstCheckBox->setChecked(m_txFirst);
+  QString rpt=t4.at(1);
+  if(rpt.indexOf("  ")==0) rpt="+" + rpt.mid(2,2);
+  if(rpt.indexOf(" -")==0) rpt=rpt.mid(1,2);
+  if(rpt.indexOf(" ")==0) rpt="+" + rpt.mid(1,2);
+  int nr=rpt.toInt();
+  if(nr<-50) rpt="-50";
+  if(nr>49) rpt="+49";
+  if(nr>=-9 and nr<=-1) rpt="-0" + rpt.mid(1);
+  if(nr>=0 and nr<=9) rpt="+0" + rpt;
+  if(nr>=10) rpt="+" + rpt;
+  ui->rptSpinBox->setValue(rpt.toInt());
+  genStdMsgs(rpt);
+  if(t2.indexOf(m_myCall)>=0) {
+    if(t4.length()>=7 and !gridOK(t4.at(7))) {
+      QString r=t4.at(7);
+      if(r.mid(0,3)=="RRR") {
+        m_ntx=5;
+        ui->txrb5->setChecked(true);
+        if(ui->tabWidget->currentIndex()==1) {
+          ui->genMsg->setText(ui->tx5->text());
+          m_ntx=7;
+          ui->rbGenMsg->setChecked(true);
+        }
+      } else if(r.mid(0,1)=="R") {
+        m_ntx=4;
+        ui->txrb4->setChecked(true);
+        if(ui->tabWidget->currentIndex()==1) {
+          ui->genMsg->setText(ui->tx4->text());
+          m_ntx=7;
+          ui->rbGenMsg->setChecked(true);
+        }
+      } else if(r.toInt()>=-50 and r.toInt()<=49) {
+        m_ntx=3;
+        ui->txrb3->setChecked(true);
+        if(ui->tabWidget->currentIndex()==1) {
+          ui->genMsg->setText(ui->tx3->text());
+          m_ntx=7;
+          ui->rbGenMsg->setChecked(true);
+        }
+      } else if(r.toInt()==73) {
+        m_ntx=5;
+        ui->txrb5->setChecked(true);
+        if(ui->tabWidget->currentIndex()==1) {
+          ui->genMsg->setText(ui->tx5->text());
+          m_ntx=7;
+          ui->rbGenMsg->setChecked(true);
+        }
+      }
+    } else {
+      m_ntx=2;
+      ui->txrb2->setChecked(true);
+      if(ui->tabWidget->currentIndex()==1) {
+        ui->genMsg->setText(ui->tx2->text());
+        m_ntx=7;
+        ui->rbGenMsg->setChecked(true);
+      }
+    }
+
+  } else {
+    m_ntx=1;
+    ui->txrb1->setChecked(true);
+    if(ui->tabWidget->currentIndex()==1) {
+      ui->genMsg->setText(ui->tx1->text());
+      m_ntx=7;
+      ui->rbGenMsg->setChecked(true);
+    }
+  }
+  if(m_quickCall) {
+    m_auto=true;
+    ui->autoButton->setStyleSheet(m_pbAutoOn_style);
+  }
+}
+
+void MainWindow::genStdMsgs(QString rpt)                       //genStdMsgs()
+{
+  QString t;
+  QString hisCall=ui->dxCallEntry->text().toUpper().trimmed();
+  ui->dxCallEntry->setText(hisCall);
+  if(hisCall=="") {
+    ui->labAz->setText("");
+    ui->labDist->setText("");
+    ui->tx1->setText("");
+    ui->tx2->setText("");
+    ui->tx3->setText("");
+    ui->tx4->setText("");
+    ui->tx5->setText("");
+    ui->tx6->setText("");
+    if(m_myCall!="" and m_myGrid!="") {
+      t="CQ " + m_myCall + " " + m_myGrid.mid(0,4);
+      msgtype(t, ui->tx6);
+    }
+    ui->genMsg->setText("");
+    ui->freeTextMsg->setText("");
+    return;
+  }
+  QString hisBase=baseCall(hisCall);
+  QString myBase=baseCall(m_myCall);
+  QString t0=hisBase + " " + myBase + " ";
+  t=t0 + m_myGrid.mid(0,4);
+  if(myBase!=m_myCall) t="DE " + m_myCall + " " + m_myGrid.mid(0,4);
+  msgtype(t, ui->tx1);
+  if(rpt == "") {
+    t=t+" OOO";
+    msgtype(t, ui->tx2);
+    msgtype("RO", ui->tx3);
+    msgtype("RRR", ui->tx4);
+    msgtype("73", ui->tx5);
+  } else {
+    t=t0 + rpt;
+    msgtype(t, ui->tx2);
+    t=t0 + "R" + rpt;
+    msgtype(t, ui->tx3);
+    t=t0 + "RRR";
+    msgtype(t, ui->tx4);
+    t=t0 + "73";
+    if(myBase!=m_myCall) t="DE " + m_myCall + " 73";
+    msgtype(t, ui->tx5);
+  }
+
+  t="CQ " + m_myCall + " " + m_myGrid.mid(0,4);
+  msgtype(t, ui->tx6);
+  m_ntx=1;
+  ui->txrb1->setChecked(true);
+  m_rpt=rpt;
+}
+
+QString MainWindow::baseCall(QString t)
+{
+  int n1=t.indexOf("/");
+  if(n1<0) return t;
+  int n2=t.length()-n1-1;
+  if(n2>=n1) return t.mid(n1+1);
+  return t.mid(0,n1);
+}
+
+void MainWindow::lookup()                                       //lookup()
+{
+  QString hisCall=ui->dxCallEntry->text().toUpper().trimmed();
+  ui->dxCallEntry->setText(hisCall);
+  QString call3File = m_appDir + "/CALL3.TXT";
+  QFile f(call3File);
+  if(!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+    msgBox("Cannot open " + call3File);
+    return;
+  }
+  char c[132];
+  qint64 n=0;
+  for(int i=0; i<999999; i++) {
+    n=f.readLine(c,sizeof(c));
+    if(n <= 0) {
+      ui->dxGridEntry->setText("");
+      break;
+     }
+    QString t=QString(c);
+    if(t.indexOf(hisCall)==0) {
+      int i1=t.indexOf(",");
+      QString hisgrid=t.mid(i1+1,6);
+      i1=hisgrid.indexOf(",");
+      if(i1>0) {
+        hisgrid=hisgrid.mid(0,4);
+      } else {
+        hisgrid=hisgrid.mid(0,4) + hisgrid.mid(4,2).toLower();
+      }
+      ui->dxGridEntry->setText(hisgrid);
+      break;
+    }
+  }
+  f.close();
+}
+
+void MainWindow::on_lookupButton_clicked()                    //Lookup button
+{
+  lookup();
+}
+
+void MainWindow::on_addButton_clicked()                       //Add button
+{
+  if(ui->dxGridEntry->text()=="") {
+    msgBox("Please enter a valid grid locator.");
+    return;
+  }
+  m_call3Modified=false;
+  QString hisCall=ui->dxCallEntry->text().toUpper().trimmed();
+  QString hisgrid=ui->dxGridEntry->text().trimmed();
+  QString newEntry=hisCall + "," + hisgrid;
+
+//  int ret = QMessageBox::warning(this, "Add",
+//       newEntry + "\n" + "Is this station known to be active on EME?",
+//       QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+//  if(ret==QMessageBox::Yes) {
+//    newEntry += ",EME,,";
+//  } else {
+    newEntry += ",,,";
+//  }
+
+  QString call3File = m_appDir + "/CALL3.TXT";
+  QFile f1(call3File);
+  if(!f1.open(QIODevice::ReadOnly | QIODevice::Text)) {
+    msgBox("Cannot open " + call3File);
+    return;
+  }
+  if(f1.size()==0) {
+    f1.close();
+    f1.open(QIODevice::WriteOnly | QIODevice::Text);
+    QTextStream out(&f1);
+    out << "ZZZZZZ" << endl;
+    f1.close();
+    f1.open(QIODevice::ReadOnly | QIODevice::Text);
+  }
+  QString tmpFile = m_appDir + "/CALL3.TMP";
+  QFile f2(tmpFile);
+  if(!f2.open(QIODevice::WriteOnly | QIODevice::Text)) {
+    msgBox("Cannot open " + tmpFile);
+    return;
+  }
+  QTextStream in(&f1);
+  QTextStream out(&f2);
+  QString hc=hisCall;
+  QString hc1="";
+  QString hc2="AAAAAA";
+  QString s;
+  do {
+    s=in.readLine();
+    hc1=hc2;
+    if(s.mid(0,2)=="//") {
+      out << s + "\n";
+    } else {
+      int i1=s.indexOf(",");
+      hc2=s.mid(0,i1);
+      if(hc>hc1 && hc<hc2) {
+        out << newEntry + "\n";
+        if(s.mid(0,6)=="ZZZZZZ") {
+          out << s + "\n";
+//          exit;                             //Statement has no effect!
+        }
+        m_call3Modified=true;
+      } else if(hc==hc2) {
+        QString t=s + "\n\n is already in CALL3.TXT\n" +
+            "Do you wish to replace it?";
+        int ret = QMessageBox::warning(this, "Add",t,
+             QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+        if(ret==QMessageBox::Yes) {
+          out << newEntry + "\n";
+          m_call3Modified=true;
+        }
+      } else {
+        if(s!="") out << s + "\n";
+      }
+    }
+  } while(!s.isNull());
+
+  f1.close();
+  if(hc>hc1 && !m_call3Modified) {
+    out << newEntry + "\n";
+  }
+  if(m_call3Modified) {
+    QFile f0(m_appDir + "/CALL3.OLD");
+    if(f0.exists()) f0.remove();
+    QFile f1(m_appDir + "/CALL3.TXT");
+    f1.rename(m_appDir + "/CALL3.OLD");
+    f2.rename(m_appDir + "/CALL3.TXT");
+    f2.close();
+  }
+}
+
+void MainWindow::msgtype(QString t, QLineEdit* tx)               //msgtype()
+{
+  char message[23];
+  char msgsent[23];
+  int len1=22;
+
+  t=t.toUpper();
+  QByteArray s=t.toUpper().toLocal8Bit();
+  ba2msg(s,message);
+  int ichk=1,itext=0;
+  genjt9_(message,&ichk,msgsent,itone,&itext,len1,len1);
+  msgsent[22]=0;
+  bool text=false;
+  if(itext!=0) text=true;
+  QString t1;
+  t1.fromLatin1(msgsent);
+  if(text) t1=t1.mid(0,13);
+  QPalette p(tx->palette());
+  if(text) {
+    p.setColor(QPalette::Base,"#ffccff");
+  } else {
+    p.setColor(QPalette::Base,Qt::white);
+  }
+  tx->setPalette(p);
+  int len=t.length();
+  if(text) {
+    len=qMin(len,13);
+    tx->setText(t.mid(0,len).toUpper());
+  } else {
+    tx->setText(t);
+  }
+}
+
+void MainWindow::on_tx1_editingFinished()                       //tx1 edited
+{
+  QString t=ui->tx1->text();
+  msgtype(t, ui->tx1);
+}
+
+void MainWindow::on_tx2_editingFinished()                       //tx2 edited
+{
+  QString t=ui->tx2->text();
+  msgtype(t, ui->tx2);
+}
+
+void MainWindow::on_tx3_editingFinished()                       //tx3 edited
+{
+  QString t=ui->tx3->text();
+  msgtype(t, ui->tx3);
+}
+
+void MainWindow::on_tx4_editingFinished()                       //tx4 edited
+{
+  QString t=ui->tx4->text();
+  msgtype(t, ui->tx4);
+}
+
+void MainWindow::on_tx5_editingFinished()                       //tx5 edited
+{
+  QString t=ui->tx5->text();
+  msgtype(t, ui->tx5);
+}
+
+void MainWindow::on_tx6_editingFinished()                       //tx6 edited
+{
+  QString t=ui->tx6->text();
+  msgtype(t, ui->tx6);
+  double snr=t.mid(1,5).toDouble();
+  if(snr>0.0 or snr < -50.0) snr=99.0;
+  soundOutThread.setTxSNR(snr);
+}
+
+void MainWindow::on_dxCallEntry_textChanged(const QString &t) //dxCall changed
+{
+  m_hisCall=t.toUpper().trimmed();
+  ui->dxCallEntry->setText(m_hisCall);
+  statusChanged();
+}
+
+void MainWindow::on_dxGridEntry_textChanged(const QString &t) //dxGrid changed
+{
+  int n=t.length();
+  if(n!=4 and n!=6) {
+    ui->labAz->setText("");
+    ui->labDist->setText("");
+    return;
+  }
+  if(!t[0].isLetter() or !t[1].isLetter()) return;
+  if(!t[2].isDigit() or !t[3].isDigit()) return;
+  if(n==4) m_hisGrid=t.mid(0,2).toUpper() + t.mid(2,2);
+  if(n==6) m_hisGrid=t.mid(0,2).toUpper() + t.mid(2,2) +
+      t.mid(4,2).toLower();
+  ui->dxGridEntry->setText(m_hisGrid);
+  if(gridOK(m_hisGrid)) {
+    qint64 nsec = QDateTime::currentMSecsSinceEpoch() % 86400;
+    double utch=nsec/3600.0;
+    int nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter;
+
+    azdist_(m_myGrid.toLatin1().data(),m_hisGrid.toLatin1().data(),&utch,
+           &nAz,&nEl,&nDmiles,&nDkm,&nHotAz,&nHotABetter,6,6);
+    QString t;
+    t.sprintf("Az: %d",nAz);
+    ui->labAz->setText(t);
+    if(m_bMiles) t.sprintf("%d mi",int(0.621371*nDkm));
+    if(!m_bMiles) t.sprintf("%d km",nDkm);
+    ui->labDist->setText(t);
+  } else {
+    ui->labAz->setText("");
+    ui->labDist->setText("");
+  }
+}
+
+void MainWindow::on_genStdMsgsPushButton_clicked()         //genStdMsgs button
+{
+  genStdMsgs(m_rpt);
+}
+
+void MainWindow::on_logQSOButton_clicked()                 //Log QSO button
+{
+  if(m_hisCall=="") return;
+  m_dateTimeQSO=QDateTime::currentDateTimeUtc();
+
+  logDlg = new LogQSO(0);
+  logDlg->m_saveTxPower=m_saveTxPower;
+  logDlg->m_saveComments=m_saveComments;
+  logDlg->m_txPower=m_txPower;
+  logDlg->m_comments=m_logComments;
+  logDlg->initLogQSO(m_hisCall,m_hisGrid,m_modeTx,m_rptSent,m_rptRcvd,
+                     m_dateTimeQSO,m_dialFreq+m_txFreq/1.0e6,
+                     m_myCall,m_myGrid,m_noSuffix,m_toRTTY,m_dBtoComments);
+  connect(logDlg, SIGNAL(acceptQSO(bool)),this,SLOT(acceptQSO2(bool)));
+  if(m_logQSOgeom != QRect(500,400,424,283)) logDlg->setGeometry(m_logQSOgeom);
+  logDlg->show();
+}
+
+void MainWindow::acceptQSO2(bool accepted)
+{
+  if(accepted) {
+    m_logQSOgeom=logDlg->geometry();
+    m_saveTxPower=logDlg->m_saveTxPower;
+    m_saveComments=logDlg->m_saveComments;
+    m_txPower=logDlg->m_txPower;
+    m_logComments=logDlg->m_comments;
+    if(m_clearCallGrid) {
+      m_hisCall="";
+      ui->dxCallEntry->setText("");
+      m_hisGrid="";
+      ui->dxGridEntry->setText("");
+      m_rptSent="";
+      m_rptRcvd="";
+      m_qsoStart="";
+      m_qsoStop="";
+    }
+  }
+}
+
+void MainWindow::on_actionJT9_1_triggered()
+{
+  m_mode="JT9";
+  if(m_modeTx!="JT9") on_pbTxMode_clicked();
+  statusChanged();
+  m_TRperiod=60;
+  m_nsps=6912;
+  m_hsymStop=173;
+  soundInThread.setPeriod(m_TRperiod,m_nsps);
+  soundOutThread.setPeriod(m_TRperiod,m_nsps);
+  lab3->setStyleSheet("QLabel{background-color: #ff6ec7}");
+  lab3->setText(m_mode);
+  ui->actionJT9_1->setChecked(true);
+  g_pWideGraph->setPeriod(m_TRperiod,m_nsps);
+  g_pWideGraph->setMode(m_mode);
+  g_pWideGraph->setModeTx(m_modeTx);
+  ui->pbTxMode->setEnabled(false);
+}
+
+void MainWindow::on_actionJT65_triggered()
+{
+  m_mode="JT65";
+  if(m_modeTx!="JT65") on_pbTxMode_clicked();
+  statusChanged();
+  m_TRperiod=60;
+  m_nsps=6912;                   //For symspec only
+  m_hsymStop=173;
+  soundInThread.setPeriod(m_TRperiod,m_nsps);
+  soundOutThread.setPeriod(m_TRperiod,m_nsps);
+  lab3->setStyleSheet("QLabel{background-color: #ffff00}");
+  lab3->setText(m_mode);
+  ui->actionJT65->setChecked(true);
+  g_pWideGraph->setPeriod(m_TRperiod,m_nsps);
+  g_pWideGraph->setMode(m_mode);
+  g_pWideGraph->setModeTx(m_modeTx);
+  ui->pbTxMode->setEnabled(false);
+}
+
+void MainWindow::on_actionJT9_JT65_triggered()
+{
+  m_mode="JT9+JT65";
+//  if(m_modeTx!="JT9") on_pbTxMode_clicked();
+  statusChanged();
+  m_TRperiod=60;
+  m_nsps=6912;
+  m_hsymStop=173;
+  soundInThread.setPeriod(m_TRperiod,m_nsps);
+  soundOutThread.setPeriod(m_TRperiod,m_nsps);
+  lab3->setStyleSheet("QLabel{background-color: #ffa500}");
+  lab3->setText(m_mode);
+  ui->actionJT9_JT65->setChecked(true);
+  g_pWideGraph->setPeriod(m_TRperiod,m_nsps);
+  g_pWideGraph->setMode(m_mode);
+  g_pWideGraph->setModeTx(m_modeTx);
+  ui->pbTxMode->setEnabled(true);
+}
+
+void MainWindow::on_TxFreqSpinBox_valueChanged(int n)
+{
+  m_txFreq=n;
+  if(g_pWideGraph!=NULL) g_pWideGraph->setTxFreq(n);
+  if(m_lockTxFreq) ui->RxFreqSpinBox->setValue(n);
+  soundOutThread.setTxFreq(n);
+}
+
+void MainWindow::on_RxFreqSpinBox_valueChanged(int n)
+{
+  m_rxFreq=n;
+  if(g_pWideGraph!=NULL) g_pWideGraph->setRxFreq(n);
+  if(m_lockTxFreq) ui->TxFreqSpinBox->setValue(n);
+}
+
+void MainWindow::on_actionQuickDecode_triggered()
+{
+  m_ndepth=1;
+  ui->actionQuickDecode->setChecked(true);
+}
+
+void MainWindow::on_actionMediumDecode_triggered()
+{
+  m_ndepth=2;
+  ui->actionMediumDecode->setChecked(true);
+}
+
+void MainWindow::on_actionDeepestDecode_triggered()
+{
+  m_ndepth=3;
+  ui->actionDeepestDecode->setChecked(true);
+}
+
+void MainWindow::on_inGain_valueChanged(int n)
+{
+  m_inGain=n;
+}
+
+void MainWindow::on_actionMonitor_OFF_at_startup_triggered()
+{
+  m_monitorStartOFF=!m_monitorStartOFF;
+}
+
+void MainWindow::on_actionErase_ALL_TXT_triggered()          //Erase ALL.TXT
+{
+  int ret = QMessageBox::warning(this, "Confirm Erase",
+      "Are you sure you want to erase file ALL.TXT ?",
+       QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+  if(ret==QMessageBox::Yes) {
+    QFile f("ALL.TXT");
+    f.remove();
+    m_RxLog=1;
+  }
+}
+
+void MainWindow::on_actionErase_wsjtx_log_adi_triggered()
+{
+  int ret = QMessageBox::warning(this, "Confirm Erase",
+      "Are you sure you want to erase file wsjtx_log.adi ?",
+       QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+  if(ret==QMessageBox::Yes) {
+    QFile f("wsjtx_log.adi");
+    f.remove();
+  }
+}
+
+void MainWindow::showMacros(const QPoint &pos)
+{
+  if(m_macro.length()<10) return;
+  QPoint globalPos = ui->tx5->mapToGlobal(pos);
+  QMenu popupMenu;
+  QAction* popup1 = new QAction(m_macro[0],ui->tx5);
+  QAction* popup2 = new QAction(m_macro[1],ui->tx5);
+  QAction* popup3 = new QAction(m_macro[2],ui->tx5);
+  QAction* popup4 = new QAction(m_macro[3],ui->tx5);
+  QAction* popup5 = new QAction(m_macro[4],ui->tx5);
+  QAction* popup6 = new QAction(m_macro[5],ui->tx5);
+  QAction* popup7 = new QAction(m_macro[6],ui->tx5);
+  QAction* popup8 = new QAction(m_macro[7],ui->tx5);
+  QAction* popup9 = new QAction(m_macro[8],ui->tx5);
+  QAction* popup10 = new QAction(m_macro[9],ui->tx5);
+
+  if(m_macro[0]!="") popupMenu.addAction(popup1);
+  if(m_macro[1]!="") popupMenu.addAction(popup2);
+  if(m_macro[2]!="") popupMenu.addAction(popup3);
+  if(m_macro[3]!="") popupMenu.addAction(popup4);
+  if(m_macro[4]!="") popupMenu.addAction(popup5);
+  if(m_macro[5]!="") popupMenu.addAction(popup6);
+  if(m_macro[6]!="") popupMenu.addAction(popup7);
+  if(m_macro[7]!="") popupMenu.addAction(popup8);
+  if(m_macro[8]!="") popupMenu.addAction(popup9);
+  if(m_macro[9]!="") popupMenu.addAction(popup10);
+
+  connect(popup1,SIGNAL(triggered()), this, SLOT(onPopup1()));
+  connect(popup2,SIGNAL(triggered()), this, SLOT(onPopup2()));
+  connect(popup3,SIGNAL(triggered()), this, SLOT(onPopup3()));
+  connect(popup4,SIGNAL(triggered()), this, SLOT(onPopup4()));
+  connect(popup5,SIGNAL(triggered()), this, SLOT(onPopup5()));
+  connect(popup6,SIGNAL(triggered()), this, SLOT(onPopup6()));
+  connect(popup7,SIGNAL(triggered()), this, SLOT(onPopup7()));
+  connect(popup8,SIGNAL(triggered()), this, SLOT(onPopup8()));
+  connect(popup9,SIGNAL(triggered()), this, SLOT(onPopup9()));
+  connect(popup10,SIGNAL(triggered()), this, SLOT(onPopup10()));
+  popupMenu.exec(globalPos);
+}
+
+void MainWindow::onPopup1() { ui->tx5->setText(m_macro[0]); freeText(); }
+void MainWindow::onPopup2() { ui->tx5->setText(m_macro[1]); freeText(); }
+void MainWindow::onPopup3() { ui->tx5->setText(m_macro[2]); freeText(); }
+void MainWindow::onPopup4() { ui->tx5->setText(m_macro[3]); freeText(); }
+void MainWindow::onPopup5() { ui->tx5->setText(m_macro[4]); freeText(); }
+void MainWindow::onPopup6() { ui->tx5->setText(m_macro[5]); freeText(); }
+void MainWindow::onPopup7() { ui->tx5->setText(m_macro[6]); freeText(); }
+void MainWindow::onPopup8() { ui->tx5->setText(m_macro[7]); freeText(); }
+void MainWindow::onPopup9() { ui->tx5->setText(m_macro[8]); freeText(); }
+void MainWindow::onPopup10() { ui->tx5->setText(m_macro[9]); freeText(); }
+
+void MainWindow::freeText() { ui->freeTextMsg->setText(ui->tx5->text()); }
+
+bool MainWindow::gridOK(QString g)
+{
+  bool b=g.mid(0,1).compare("A")>=0 and
+      g.mid(0,1).compare("R")<=0 and
+      g.mid(1,1).compare("A")>=0 and
+      g.mid(1,1).compare("R")<=0 and
+      g.mid(2,1).compare("0")>=0 and
+      g.mid(2,1).compare("9")<=0 and
+      g.mid(3,1).compare("0")>=0 and
+      g.mid(3,1).compare("9")<=0;
+  return b;
+}
+
+void MainWindow::on_actionConvert_JT9_x_to_RTTY_triggered(bool checked)
+{
+  m_toRTTY=checked;
+}
+
+void MainWindow::on_actionLog_JT9_without_submode_triggered(bool checked)
+{
+  m_noSuffix=checked;
+}
+
+void MainWindow::on_actionLog_dB_reports_to_Comments_triggered(bool checked)
+{
+  m_dBtoComments=checked;
+}
+
+void MainWindow::on_bandComboBox_activated(int index)
+{
+  int ret=0;
+  QString rt;
+
+  m_band=index;
+  QString t=m_dFreq[index];
+  m_dialFreq=t.toDouble();
+  if(m_plus2kHz) m_dialFreq+=0.002;
+  dialFreqChanged2(m_dialFreq);
+  m_repeatMsg=0;
+  m_secBandChanged=QDateTime::currentMSecsSinceEpoch()/1000;
+  if(m_catEnabled) {
+    if(!m_bRigOpen) {
+      rigOpen();
+    }
+    if(m_bRigOpen) {
+      m_dontReadFreq=true;
+      ret=rig->setFreq(MHz(m_dialFreq));
+      if(m_bSplit or m_bXIT) setXIT(m_txFreq);
+
+      if(g_pWideGraph!=NULL) {
+        bumpFqso(11);
+        bumpFqso(12);
+      }
+      if(ret!=RIG_OK) {
+        rt.sprintf("Set rig frequency failed:  %d",ret);
+        msgBox(rt);
+      }
+    }
+  }
+  QFile f2("ALL.TXT");
+  f2.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
+  QTextStream out(&f2);
+  out << QDateTime::currentDateTimeUtc().toString("yyyy-MMM-dd hh:mm")
+      << "  " << m_dialFreq << " MHz  " << m_mode << endl;
+  f2.close();
+}
+
+void MainWindow::on_actionPrompt_to_log_QSO_triggered(bool checked)
+{
+  m_promptToLog=checked;
+}
+
+void MainWindow::on_actionBlank_line_between_decoding_periods_triggered(bool checked)
+{
+  m_insertBlank=checked;
+}
+
+void MainWindow::on_actionClear_DX_Call_and_Grid_after_logging_triggered(bool checked)
+{
+  m_clearCallGrid=checked;
+}
+
+void MainWindow::on_actionDisplay_distance_in_miles_triggered(bool checked)
+{
+  m_bMiles=checked;
+  on_dxGridEntry_textChanged(m_hisGrid);
+}
+
+void MainWindow::on_pbCallCQ_clicked()
+{
+  genStdMsgs(m_rpt);
+  ui->genMsg->setText(ui->tx6->text());
+  m_ntx=7;
+  ui->rbGenMsg->setChecked(true);
+  if(m_transmitting) m_restart=true;
+}
+
+void MainWindow::on_pbAnswerCaller_clicked()
+{
+  genStdMsgs(m_rpt);
+  ui->genMsg->setText(ui->tx2->text());
+  m_ntx=7;
+  ui->rbGenMsg->setChecked(true);
+  if(m_transmitting) m_restart=true;
+}
+
+void MainWindow::on_pbSendRRR_clicked()
+{
+  genStdMsgs(m_rpt);
+  ui->genMsg->setText(ui->tx4->text());
+  m_ntx=7;
+  ui->rbGenMsg->setChecked(true);
+  if(m_transmitting) m_restart=true;
+}
+
+void MainWindow::on_pbAnswerCQ_clicked()
+{
+  genStdMsgs(m_rpt);
+  ui->genMsg->setText(ui->tx1->text());
+  m_ntx=7;
+  ui->rbGenMsg->setChecked(true);
+  if(m_transmitting) m_restart=true;
+}
+
+void MainWindow::on_pbSendReport_clicked()
+{
+  genStdMsgs(m_rpt);
+  ui->genMsg->setText(ui->tx3->text());
+  m_ntx=7;
+  ui->rbGenMsg->setChecked(true);
+  if(m_transmitting) m_restart=true;
+}
+
+void MainWindow::on_pbSend73_clicked()
+{
+  genStdMsgs(m_rpt);
+  ui->genMsg->setText(ui->tx5->text());
+  m_ntx=7;
+  ui->rbGenMsg->setChecked(true);
+  if(m_transmitting) m_restart=true;
+}
+
+void MainWindow::on_rbGenMsg_toggled(bool checked)
+{
+  m_freeText=!checked;
+  if(!m_freeText) {
+    m_ntx=7;
+    if(m_transmitting) m_restart=true;
+  }
+}
+
+void MainWindow::on_rbFreeText_toggled(bool checked)
+{
+  m_freeText=checked;
+  if(m_freeText) {
+    m_ntx=8;
+    if (m_transmitting) m_restart=true;
+  }
+}
+
+void MainWindow::on_freeTextMsg_editingFinished()
+{
+  QString t=ui->freeTextMsg->text();
+  msgtype(t, ui->freeTextMsg);
+}
+
+void MainWindow::on_actionDouble_click_on_call_sets_Tx_Enable_triggered(bool checked)
+{
+  m_quickCall=checked;
+}
+
+void MainWindow::on_rptSpinBox_valueChanged(int n)
+{
+  m_rpt=QString::number(n);
+  int ntx0=m_ntx;
+  QString t=ui->tx5->text();
+  genStdMsgs(m_rpt);
+  ui->tx5->setText(t);
+  m_ntx=ntx0;
+  if(m_ntx==1) ui->txrb1->setChecked(true);
+  if(m_ntx==2) ui->txrb2->setChecked(true);
+  if(m_ntx==3) ui->txrb3->setChecked(true);
+  if(m_ntx==4) ui->txrb4->setChecked(true);
+  if(m_ntx==5) ui->txrb5->setChecked(true);
+  if(m_ntx==6) ui->txrb6->setChecked(true);
+  statusChanged();
+}
+
+void MainWindow::on_action_73TxDisable_triggered(bool checked)
+{
+  m_73TxDisable=checked;
+}
+
+void MainWindow::on_actionRunaway_Tx_watchdog_triggered(bool checked)
+{
+  m_runaway=checked;
+}
+
+void MainWindow::on_tuneButton_clicked()
+{
+  if(m_tune) {
+    nc1=1;                                 //disable the countdown timer
+    tuneButtonTimer->start(250);
+  } else {
+    m_tune=true;
+    m_sent73=false;
+    soundOutThread.setTune(m_tune);
+    m_repeatMsg=0;
+    ui->tuneButton->setStyleSheet(m_pbTune_style);
+  }
+}
+
+void MainWindow::on_stopTxButton_clicked()                    //Stop Tx
+{
+  if(m_tune) {
+    m_tune=false;
+    soundOutThread.setTune(m_tune);
+  }
+  if(m_auto) on_autoButton_clicked();
+  btxok=false;
+  m_repeatMsg=0;
+  ui->tuneButton->setStyleSheet("");
+}
+
+void MainWindow::rigOpen()
+{
+  QString t;
+  int ret;
+  rig = new Rig();
+
+  if(m_rig<9900) {
+    if (!rig->init(m_rig)) {
+      msgBox("Rig init failure");
+      return;
+    }
+    QString sCATport=m_catPort;
+#ifdef WIN32
+    sCATport="\\\\.\\" + m_catPort;    //Allow COM ports above 9
+#endif
+    rig->setConf("rig_pathname", sCATport.toLatin1().data());
+    char buf[80];
+    sprintf(buf,"%d",m_serialRate);
+    rig->setConf("serial_speed",buf);
+    sprintf(buf,"%d",m_dataBits);
+    rig->setConf("data_bits",buf);
+    sprintf(buf,"%d",m_stopBits);
+    rig->setConf("stop_bits",buf);
+    rig->setConf("serial_handshake",m_handshake.toLatin1().data());
+    if(m_bDTRoff) {
+      rig->setConf("rts_state","OFF");
+      rig->setConf("dtr_state","OFF");
+    }
+  }
+
+  ret=rig->open(m_rig);
+  if(ret==RIG_OK) {
+    m_bRigOpen=true;
+    if(m_poll==0) ui->readFreq->setEnabled(true);
+    m_CATerror=false;
+  } else {
+    t="Open rig failed";
+    msgBox(t);
+    m_catEnabled=false;
+    m_bRigOpen=false;
+    m_CATerror=true;
+  }
+
+  if(m_bRigOpen) {
+    if(m_poll>0) {
+      ui->readFreq->setStyleSheet("QPushButton{background-color: #00ff00; \
+                                  border-width: 0px; border-radius: 5px;}");
+    } else {
+      ui->readFreq->setStyleSheet("QPushButton{background-color: orange; \
+                                border-width: 0px; border-radius: 5px;}");
+    }
+} else {
+if(m_CATerror) ui->readFreq->setStyleSheet("QPushButton{background-color: red; \
+                                   border-width: 0px; border-radius: 5px;}");
+if(!m_CATerror) ui->readFreq->setStyleSheet("");
+  }
+}
+
+void MainWindow::on_actionAllow_multiple_instances_triggered(bool checked)
+{
+  m_bMultipleOK=checked;
+}
+
+void MainWindow::on_pbR2T_clicked()
+{
+  int n=g_pWideGraph->rxFreq();
+  ui->TxFreqSpinBox->setValue(n);
+}
+
+void MainWindow::on_pbT2R_clicked()
+{
+  g_pWideGraph->setRxFreq(m_txFreq);
+}
+
+
+void MainWindow::on_readFreq_clicked()
+{
+  if(m_transmitting) return;
+  m_dontReadFreq=false;
+  double fMHz=rig->getFreq(RIG_VFO_CURR)/1000000.0;
+  if(fMHz<0.0) {
+    QString rt;
+    rt.sprintf("Rig control error %d\nFailed to read frequency.",
+               int(1000000.0*fMHz));
+    msgBox(rt);
+    m_catEnabled=false;
+  }
+  if(fMHz<0.01 or fMHz>1300.0) fMHz=0;
+  int ndiff=1000000.0*(fMHz-m_dialFreq);
+  if(ndiff!=0) dialFreqChanged2(fMHz);
+}
+
+void MainWindow::on_pbTxMode_clicked()
+{
+  if(m_modeTx=="JT9") {
+    m_modeTx="JT65";
+    ui->pbTxMode->setText("Tx JT65  #");
+  } else {
+    m_modeTx="JT9";
+    ui->pbTxMode->setText("Tx JT9  @");
+  }
+  g_pWideGraph->setModeTx(m_modeTx);
+  statusChanged();
+}
+
+void MainWindow::setXIT(int n)
+{
+  int ret;
+  int xit=0;
+  if(m_bRigOpen) {
+    xit=-1000;
+    if(n>1000) xit=0;
+    if(n>2000) xit=1000;
+    if(n>3000) xit=2000;
+    if(n>4000) xit=3000;
+    if(m_bXIT) {
+      ret=rig->setXit((shortfreq_t)xit,RIG_VFO_TX);
+      if(ret!=RIG_OK) {
+        QString rt;
+        rt.sprintf("Setting RIG_VFO_TX failed:  %d",ret);
+        msgBox(rt);
+      }
+    }
+    if(m_bSplit) {
+      ret=rig->setSplitFreq(MHz(m_dialFreq)+xit,RIG_VFO_B);
+    }
+  }
+  if(m_bSplit) soundOutThread.setXIT(xit);
+  if(!m_bSplit) soundOutThread.setXIT(0);
+}
+
+void MainWindow::setFreq4(int rxFreq, int txFreq)
+{
+  m_rxFreq=rxFreq;
+  m_txFreq=txFreq;
+  ui->RxFreqSpinBox->setValue(m_rxFreq);
+  ui->TxFreqSpinBox->setValue(m_txFreq);
+}
+
+void MainWindow::on_cbTxLock_clicked(bool checked)
+{
+  m_lockTxFreq=checked;
+  g_pWideGraph->setLockTxFreq(m_lockTxFreq);
+  if(m_lockTxFreq) on_pbR2T_clicked();
+}
+
+void MainWindow::on_actionTx2QSO_triggered(bool checked)
+{
+  m_tx2QSO=checked;
+}
+
+void MainWindow::on_cbPlus2kHz_toggled(bool checked)
+{
+  m_plus2kHz=checked;
+  on_bandComboBox_activated(m_band);
+}
diff --git a/mainwindow.h b/mainwindow.h
new file mode 100644
index 0000000..51e0b41
--- /dev/null
+++ b/mainwindow.h
@@ -0,0 +1,392 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+#ifdef QT5
+#include <QtWidgets>
+#else
+#include <QtGui>
+#endif
+#include <QTimer>
+#include <QDateTime>
+#include "soundin.h"
+#include "soundout.h"
+#include "commons.h"
+#include "psk_reporter.h"
+#include "rigclass.h"
+#include "signalmeter.h"
+
+#ifdef WIN32
+#include "PSKReporter.h"
+#endif
+
+//--------------------------------------------------------------- MainWindow
+namespace Ui {
+    class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+  Q_OBJECT
+
+// Multiple instances: call MainWindow() with *thekey
+public:
+  explicit MainWindow(QSharedMemory *shdmem, QString *thekey, QWidget *parent = 0);
+  ~MainWindow();
+
+public slots:
+  void showSoundInError(const QString& errorMsg);
+  void showStatusMessage(const QString& statusMsg);
+  void dataSink(int k);
+  void diskDat();
+  void diskWriteFinished();
+  void freezeDecode(int n);
+  void guiUpdate();
+  void doubleClickOnCall(bool shift, bool ctrl);
+  void doubleClickOnCall2(bool shift, bool ctrl);
+  void readFromStdout();
+  void readFromStderr();
+  void jt9_error();
+  void setXIT(int n);
+  void setFreq4(int rxFreq, int txFreq);
+
+protected:
+  virtual void keyPressEvent( QKeyEvent *e );
+  void  closeEvent(QCloseEvent*);
+  virtual bool eventFilter(QObject *object, QEvent *event);
+
+private slots:
+  void on_tx1_editingFinished();
+  void on_tx2_editingFinished();
+  void on_tx3_editingFinished();
+  void on_tx4_editingFinished();
+  void on_tx5_editingFinished();
+  void on_tx6_editingFinished();
+  void on_actionDeviceSetup_triggered();
+  void on_monitorButton_clicked();
+  void on_actionExit_triggered();
+  void on_actionAbout_triggered();
+  void OnExit();
+  void on_actionLinrad_triggered();
+  void on_actionCuteSDR_triggered();
+  void on_autoButton_clicked();
+  void on_stopTxButton_clicked();
+  void on_stopButton_clicked();
+  void on_actionOnline_Users_Guide_triggered();
+  void on_actionWide_Waterfall_triggered();
+  void on_actionOpen_triggered();
+  void on_actionOpen_next_in_directory_triggered();
+  void on_actionDecode_remaining_files_in_directory_triggered();
+  void on_actionDelete_all_wav_files_in_SaveDir_triggered();
+  void on_actionNone_triggered();
+  void on_actionSave_all_triggered();
+  void on_actionKeyboard_shortcuts_triggered();
+  void on_actionSpecial_mouse_commands_triggered();
+  void on_DecodeButton_clicked();
+  void decode();
+  void decodeBusy(bool b);
+  void on_EraseButton_clicked();
+  void on_txb1_clicked();
+  void on_txFirstCheckBox_stateChanged(int arg1);
+  void set_ntx(int n);
+  void on_txb2_clicked();
+  void on_txb3_clicked();
+  void on_txb4_clicked();
+  void on_txb5_clicked();
+  void on_txb6_clicked();
+  void on_lookupButton_clicked();
+  void on_addButton_clicked();
+  void on_dxCallEntry_textChanged(const QString &arg1);
+  void on_dxGridEntry_textChanged(const QString &arg1);
+  void on_genStdMsgsPushButton_clicked();
+  void on_logQSOButton_clicked();
+  void on_actionAFMHot_triggered();
+  void on_actionBlue_triggered();
+  void on_actionJT9_1_triggered();
+  void on_actionJT65_triggered();
+  void on_actionJT9_JT65_triggered();
+  void on_TxFreqSpinBox_valueChanged(int arg1);
+  void on_actionSave_decoded_triggered();
+  void on_actionQuickDecode_triggered();
+  void on_actionMediumDecode_triggered();
+  void on_actionDeepestDecode_triggered();
+  void on_inGain_valueChanged(int n);
+  void bumpFqso(int n);
+  void on_actionMonitor_OFF_at_startup_triggered();
+  void on_actionErase_ALL_TXT_triggered();
+  void on_actionErase_wsjtx_log_adi_triggered();
+  void showMacros(const QPoint& pos);
+  void onPopup1();
+  void onPopup2();
+  void onPopup3();
+  void onPopup4();
+  void onPopup5();
+  void onPopup6();
+  void onPopup7();
+  void onPopup8();
+  void onPopup9();
+  void onPopup10();
+  void on_actionConvert_JT9_x_to_RTTY_triggered(bool checked);
+  void on_actionLog_JT9_without_submode_triggered(bool checked);
+  void on_actionLog_dB_reports_to_Comments_triggered(bool checked);
+  void startTx2();
+  void stopTx();
+  void stopTx2();
+  void on_actionPrompt_to_log_QSO_triggered(bool checked);
+  void on_actionBlank_line_between_decoding_periods_triggered(bool checked);
+  void on_actionClear_DX_Call_and_Grid_after_logging_triggered(bool checked);
+  void on_actionDisplay_distance_in_miles_triggered(bool checked);
+  void on_pbCallCQ_clicked();
+  void on_pbAnswerCaller_clicked();
+  void on_pbSendRRR_clicked();
+  void on_pbAnswerCQ_clicked();
+  void on_pbSendReport_clicked();
+  void on_pbSend73_clicked();
+  void on_rbGenMsg_toggled(bool checked);
+  void on_rbFreeText_toggled(bool checked);
+  void on_freeTextMsg_editingFinished();
+  void on_actionDouble_click_on_call_sets_Tx_Enable_triggered(bool checked);
+  void on_rptSpinBox_valueChanged(int n);
+  void on_action_73TxDisable_triggered(bool checked);
+  void on_actionRunaway_Tx_watchdog_triggered(bool checked);
+  void killFile();
+  void on_tuneButton_clicked();
+  void on_actionAllow_multiple_instances_triggered(bool checked);
+  void on_pbR2T_clicked();
+  void on_pbT2R_clicked();
+  void acceptQSO2(bool accepted);
+  void on_bandComboBox_activated(int index);
+  void on_readFreq_clicked();
+  void on_pbTxMode_clicked();
+  void on_RxFreqSpinBox_valueChanged(int n);
+  void on_cbTxLock_clicked(bool checked);
+  void on_actionTx2QSO_triggered(bool checked);  
+  void on_cbPlus2kHz_toggled(bool checked);
+
+private:
+    Ui::MainWindow *ui;
+
+    double  m_dialFreq;
+
+    qint64  m_msErase;
+    qint64  m_secBandChanged;
+
+    qint32  m_idInt;
+    qint32  m_waterfallAvg;
+    qint32  m_pttMethodIndex;
+    qint32  m_ntx;
+    qint32  m_pttPort;
+    qint32  m_timeout;
+    qint32  m_rxFreq;
+    qint32  m_txFreq;
+    qint32  m_setftx;
+    qint32  m_ndepth;
+    qint32  m_sec0;
+    qint32  m_RxLog;
+    qint32  m_nutc0;
+    qint32  m_nrx;
+    qint32  m_hsym;
+    qint32  m_paInDevice;
+    qint32  m_paOutDevice;
+    qint32  m_TRperiod;
+    qint32  m_nsps;
+    qint32  m_hsymStop;
+    qint32  m_len1;
+    qint32  m_inGain;
+    qint32  m_nsave;
+    qint32  m_catPortIndex;
+    qint32  m_rig;
+    qint32  m_rigIndex;
+    qint32  m_serialRate;
+    qint32  m_serialRateIndex;
+    qint32  m_dataBits;
+    qint32  m_dataBitsIndex;
+    qint32  m_stopBits;
+    qint32  m_stopBitsIndex;
+    qint32  m_handshakeIndex;
+    qint32  m_ncw;
+    qint32  m_secID;
+    qint32  m_band;
+    qint32  m_repeatMsg;
+    qint32  m_watchdogLimit;
+    qint32  m_poll;
+    qint32  m_fMin;
+    qint32  m_fMax;
+
+    bool    m_monitoring;
+    bool    m_transmitting;
+    bool    m_diskData;
+    bool    m_loopall;
+    bool    m_decoderBusy;
+    bool    m_txFirst;
+    bool    m_auto;
+    bool    m_restart;
+    bool    m_startAnother;
+    bool    m_saveDecoded;
+    bool    m_saveAll;
+    bool    m_widebandDecode;
+    bool    m_call3Modified;
+    bool    m_dataAvailable;
+    bool    m_killAll;
+    bool    m_bdecoded;
+    bool    m_monitorStartOFF;
+    bool    m_pskReporter;
+    bool    m_pskReporterInit;
+    bool    m_noSuffix;
+    bool    m_toRTTY;
+    bool    m_dBtoComments;
+    bool    m_catEnabled;
+    bool    m_After73;
+    bool    m_promptToLog;
+    bool    m_blankLine;
+    bool    m_insertBlank;
+    bool    m_clearCallGrid;
+    bool    m_bMiles;
+    bool    m_decodedText2;
+    bool    m_freeText;
+    bool    m_quickCall;
+    bool    m_73TxDisable;
+    bool    m_sent73;
+    bool    m_runaway;
+    bool    m_tune;
+    bool    m_bRigOpen;
+    bool    m_bMultipleOK;
+    bool    m_bDTRoff;
+    bool    m_pttData;
+    bool    m_dontReadFreq;
+    bool    m_lockTxFreq;
+    bool    m_saveTxPower;
+    bool    m_saveComments;
+    bool    m_tx2QSO;
+    bool    m_CATerror;
+    bool    m_bSplit;
+    bool    m_bXIT;
+    bool    m_plus2kHz;
+
+    char    m_decoded[80];
+
+    float   m_pctZap;
+
+    QRect   m_wideGraphGeom;
+    QRect   m_logQSOgeom;
+
+    QLabel* lab1;                            // labels in status bar
+    QLabel* lab2;
+    QLabel* lab3;
+    QLabel* lab4;
+    QLabel* lab5;
+    QLabel* lab6;
+
+    QMessageBox msgBox0;
+
+    QFuture<void>* future1;
+    QFuture<void>* future2;
+    QFuture<void>* future3;
+    QFutureWatcher<void>* watcher1;
+    QFutureWatcher<void>* watcher2;
+    QFutureWatcher<void>* watcher3;
+
+    QProcess proc_jt9;
+
+    QTimer* ptt1Timer;                 //StartTx delay
+    QTimer* ptt0Timer;                 //StopTx delay
+    QTimer* logQSOTimer;
+    QTimer* killFileTimer;
+    QTimer* tuneButtonTimer;
+
+    QString m_path;
+    QString m_pbdecoding_style1;
+    QString m_pbmonitor_style;
+    QString m_pbAutoOn_style;
+    QString m_pbTune_style;
+    QString m_myCall;
+    QString m_myGrid;
+    QString m_baseCall;
+    QString m_hisCall;
+    QString m_hisGrid;
+    QString m_appDir;
+    QString m_saveDir;
+    QString m_dxccPfx;
+    QString m_palette;
+    QString m_dateTime;
+    QString m_mode;
+    QString m_modeTx;
+    QString m_fname;
+    QString m_rpt;
+    QString m_rptSent;
+    QString m_rptRcvd;
+    QString m_qsoStart;
+    QString m_qsoStop;
+    QString m_catPort;
+    QString m_handshake;
+    QString m_cmnd;
+    QString m_msgSent0;
+    QString m_fileToSave;
+    QString m_QSOmsg;
+    QString m_txPower;
+    QString m_logComments;
+    QString m_pskAntenna;
+
+    QStringList m_macro;
+    QStringList m_dFreq;
+
+    QDateTime m_dateTimeQSO;
+
+    SoundInThread soundInThread;             //Instantiate the audio threads
+    SoundOutThread soundOutThread;
+    QSharedMemory *mem_jt9;
+ // Multiple instances:
+    QString       *mykey_jt9;
+    PSK_Reporter *psk_Reporter;
+    SignalMeter *signalMeter;
+
+//---------------------------------------------------- private functions
+    void readSettings();
+    void writeSettings();
+    void createStatusBar();
+    void updateStatusBar();
+    void msgBox(QString t);
+    void genStdMsgs(QString rpt);
+    void lookup();
+    void ba2msg(QByteArray ba, char* message);
+    void msgtype(QString t, QLineEdit* tx);
+    void stub();
+    void statusChanged();
+    void dialFreqChanged2(double f);
+    void freeText();
+    void displayTxMsg(QString t);
+    void rigOpen();
+    bool gridOK(QString g);
+    QString baseCall(QString t);
+};
+
+extern void getfile(QString fname, int ntrperiod);
+extern void savewav(QString fname, int ntrperiod);
+extern int killbyname(const char* progName);
+extern void getDev(int* numDevices,char hostAPI_DeviceName[][50],
+                   int minChan[], int maxChan[],
+                   int minSpeed[], int maxSpeed[]);
+extern int ptt(int nport, int ntx, int* iptt, int* nopen);
+
+extern "C" {
+//----------------------------------------------------- C and Fortran routines
+void symspec_(int* k, int* ntrperiod, int* nsps, int* ingain, float* slope,
+              float* px, float s[], float* df3, int* nhsym, int* npts8);
+
+void genjt9_(char* msg, int* ichk, char* msgsent, int itone[],
+             int* itext, int len1, int len2);
+
+void gen65_(char* msg, int* ichk, char* msgsent, int itone[],
+             int* itext, int len1, int len2);
+
+bool stdmsg_(const char* msg, int len);
+
+void azdist_(char* MyGrid, char* HisGrid, double* utch, int* nAz, int* nEl,
+             int* nDmiles, int* nDkm, int* nHotAz, int* nHotABetter,
+             int len1, int len2);
+
+void morse_(char* msg, int* icw, int* ncw, int len);
+
+int ptt_(int nport, int ntx, int* iptt, int* nopen);
+
+}
+
+#endif // MAINWINDOW_H
diff --git a/mainwindow.ui b/mainwindow.ui
new file mode 100644
index 0000000..5c58f21
--- /dev/null
+++ b/mainwindow.ui
@@ -0,0 +1,2925 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>760</width>
+    <height>552</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>760</width>
+    <height>475</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>936</width>
+    <height>1028</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>SpecJT   by K1JT</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true"/>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <layout class="QGridLayout" name="gridLayout">
+      <property name="horizontalSpacing">
+       <number>3</number>
+      </property>
+      <property name="verticalSpacing">
+       <number>1</number>
+      </property>
+      <item row="4" column="0">
+       <widget class="DisplayText" name="decodedTextBrowser">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>200</width>
+          <height>100</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>500</width>
+          <height>1000</height>
+         </size>
+        </property>
+        <property name="font">
+         <font>
+          <family>Courier New</family>
+          <pointsize>10</pointsize>
+         </font>
+        </property>
+        <property name="frameShape">
+         <enum>QFrame::Panel</enum>
+        </property>
+        <property name="verticalScrollBarPolicy">
+         <enum>Qt::ScrollBarAlwaysOn</enum>
+        </property>
+        <property name="horizontalScrollBarPolicy">
+         <enum>Qt::ScrollBarAlwaysOff</enum>
+        </property>
+        <property name="html">
+         <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Courier New'; font-size:10pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
+        </property>
+        <property name="acceptRichText">
+         <bool>false</bool>
+        </property>
+        <property name="openLinks">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QLabel" name="decodedTextLabel2">
+        <property name="minimumSize">
+         <size>
+          <width>300</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>500</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="palette">
+         <palette>
+          <active>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>252</red>
+              <green>252</green>
+              <blue>252</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>170</red>
+              <green>170</green>
+              <blue>170</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </active>
+          <inactive>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>252</red>
+              <green>252</green>
+              <blue>252</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>170</red>
+              <green>170</green>
+              <blue>170</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </inactive>
+          <disabled>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>170</red>
+              <green>170</green>
+              <blue>170</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>170</red>
+              <green>170</green>
+              <blue>170</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </disabled>
+         </palette>
+        </property>
+        <property name="autoFillBackground">
+         <bool>true</bool>
+        </property>
+        <property name="text">
+         <string>UTC           dB            DT           Freq          Dr </string>
+        </property>
+        <property name="indent">
+         <number>5</number>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="decodedTextLabel">
+        <property name="minimumSize">
+         <size>
+          <width>300</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>500</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="palette">
+         <palette>
+          <active>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>252</red>
+              <green>252</green>
+              <blue>252</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>170</red>
+              <green>170</green>
+              <blue>170</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </active>
+          <inactive>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>252</red>
+              <green>252</green>
+              <blue>252</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>170</red>
+              <green>170</green>
+              <blue>170</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </inactive>
+          <disabled>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>170</red>
+              <green>170</green>
+              <blue>170</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>170</red>
+              <green>170</green>
+              <blue>170</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </disabled>
+         </palette>
+        </property>
+        <property name="autoFillBackground">
+         <bool>true</bool>
+        </property>
+        <property name="text">
+         <string>UTC           dB            DT           Freq          Dr </string>
+        </property>
+        <property name="indent">
+         <number>5</number>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1">
+       <widget class="DisplayText" name="decodedTextBrowser2">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>200</width>
+          <height>100</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>500</width>
+          <height>1000</height>
+         </size>
+        </property>
+        <property name="font">
+         <font>
+          <family>Courier New</family>
+          <pointsize>10</pointsize>
+         </font>
+        </property>
+        <property name="verticalScrollBarPolicy">
+         <enum>Qt::ScrollBarAlwaysOn</enum>
+        </property>
+        <property name="horizontalScrollBarPolicy">
+         <enum>Qt::ScrollBarAlwaysOff</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLabel" name="label_7">
+        <property name="maximumSize">
+         <size>
+          <width>500</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="font">
+         <font>
+          <pointsize>10</pointsize>
+          <weight>50</weight>
+          <bold>false</bold>
+         </font>
+        </property>
+        <property name="text">
+         <string>Rx Frequency</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_6">
+        <property name="maximumSize">
+         <size>
+          <width>500</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="font">
+         <font>
+          <pointsize>10</pointsize>
+          <weight>50</weight>
+          <bold>false</bold>
+         </font>
+        </property>
+        <property name="text">
+         <string>Band Activity</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="Line" name="line">
+        <property name="frameShadow">
+         <enum>QFrame::Plain</enum>
+        </property>
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="Line" name="line_2">
+        <property name="frameShadow">
+         <enum>QFrame::Plain</enum>
+        </property>
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
+      <item>
+       <widget class="QPushButton" name="logQSOButton">
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Enter this QSO in ADIF log</string>
+        </property>
+        <property name="text">
+         <string>Log &QSO</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="stopButton">
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Stop monitoring</string>
+        </property>
+        <property name="text">
+         <string>&Stop</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="monitorButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Start monitoring</string>
+        </property>
+        <property name="text">
+         <string>&Monitor</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="EraseButton">
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Erase QSO Frequency window.  Double-click for both windows</string>
+        </property>
+        <property name="text">
+         <string>&Erase</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="DecodeButton">
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Decode most recent Rx period at QSO Frequency (use shift for all freqs)</string>
+        </property>
+        <property name="text">
+         <string>&Decode</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="autoButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Toggle Tx Enable On/Off</string>
+        </property>
+        <property name="text">
+         <string>E&nable Tx</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="stopTxButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Set Tx Enable OFF</string>
+        </property>
+        <property name="text">
+         <string>&Halt Tx</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="tuneButton">
+        <property name="toolTip">
+         <string>Assert PTT and emit a pure tone</string>
+        </property>
+        <property name="text">
+         <string>&Tune</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <layout class="QGridLayout" name="gridLayout_3">
+      <item row="2" column="0" rowspan="5">
+       <widget class="QFrame" name="meterFrame">
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="frameShape">
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Raised</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="3">
+       <widget class="QLabel" name="labAz">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>23</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>23</height>
+         </size>
+        </property>
+        <property name="autoFillBackground">
+         <bool>true</bool>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+        <property name="indent">
+         <number>4</number>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0" colspan="2">
+       <widget class="QComboBox" name="bandComboBox">
+        <property name="toolTip">
+         <string>Select operating band</string>
+        </property>
+        <property name="currentIndex">
+         <number>7</number>
+        </property>
+        <item>
+         <property name="text">
+          <string>2200 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>630 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>160 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>80 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>60 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>40 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>30 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>20 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>17 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>15 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>12 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>10 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>6 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>4 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>2 m</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Other</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <widget class="QPushButton" name="readFreq">
+        <property name="maximumSize">
+         <size>
+          <width>15</width>
+          <height>15</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>If orange, click to read dial frequency once</string>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="3" colspan="2">
+       <widget class="QLabel" name="labDialFreq">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>140</width>
+          <height>30</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>158</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="font">
+         <font>
+          <pointsize>16</pointsize>
+          <weight>50</weight>
+          <bold>false</bold>
+         </font>
+        </property>
+        <property name="toolTip">
+         <string>USB dial frequency</string>
+        </property>
+        <property name="text">
+         <string>14.078</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="6">
+       <widget class="QCheckBox" name="txFirstCheckBox">
+        <property name="minimumSize">
+         <size>
+          <width>105</width>
+          <height>23</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>105</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Check to Tx in even minutes, uncheck for odd minutes</string>
+        </property>
+        <property name="text">
+         <string>Tx even</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="8" rowspan="7">
+       <widget class="QFrame" name="frame_2">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>283</width>
+          <height>222</height>
+         </size>
+        </property>
+        <property name="frameShape">
+         <enum>QFrame::NoFrame</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Plain</enum>
+        </property>
+        <property name="lineWidth">
+         <number>0</number>
+        </property>
+        <layout class="QVBoxLayout" name="verticalLayout_2">
+         <property name="spacing">
+          <number>0</number>
+         </property>
+         <property name="margin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QTabWidget" name="tabWidget">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>0</width>
+             <height>200</height>
+            </size>
+           </property>
+           <property name="tabPosition">
+            <enum>QTabWidget::West</enum>
+           </property>
+           <property name="tabShape">
+            <enum>QTabWidget::Triangular</enum>
+           </property>
+           <property name="currentIndex">
+            <number>0</number>
+           </property>
+           <widget class="QWidget" name="tab">
+            <attribute name="title">
+             <string>1</string>
+            </attribute>
+            <layout class="QVBoxLayout" name="verticalLayout_4">
+             <property name="spacing">
+              <number>6</number>
+             </property>
+             <property name="leftMargin">
+              <number>4</number>
+             </property>
+             <property name="topMargin">
+              <number>1</number>
+             </property>
+             <property name="rightMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <item>
+              <layout class="QGridLayout" name="gridLayout_2">
+               <property name="horizontalSpacing">
+                <number>6</number>
+               </property>
+               <property name="verticalSpacing">
+                <number>5</number>
+               </property>
+               <item row="1" column="2">
+                <widget class="QPushButton" name="txb1">
+                 <property name="maximumSize">
+                  <size>
+                   <width>40</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Switch to this Tx message NOW</string>
+                 </property>
+                 <property name="layoutDirection">
+                  <enum>Qt::LeftToRight</enum>
+                 </property>
+                 <property name="text">
+                  <string>Tx 1</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="4" column="1">
+                <widget class="QRadioButton" name="txrb4">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                   <horstretch>16</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>0</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>20</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Send this message in next Tx interval</string>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                 <attribute name="buttonGroup">
+                  <string>buttonGroup</string>
+                 </attribute>
+                </widget>
+               </item>
+               <item row="1" column="1">
+                <widget class="QRadioButton" name="txrb1">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                   <horstretch>16</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>0</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>20</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Send this message in next Tx interval</string>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                 <property name="checked">
+                  <bool>true</bool>
+                 </property>
+                 <attribute name="buttonGroup">
+                  <string>buttonGroup</string>
+                 </attribute>
+                </widget>
+               </item>
+               <item row="3" column="1">
+                <widget class="QRadioButton" name="txrb3">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                   <horstretch>16</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>0</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>20</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Send this message in next Tx interval</string>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                 <attribute name="buttonGroup">
+                  <string>buttonGroup</string>
+                 </attribute>
+                </widget>
+               </item>
+               <item row="1" column="0">
+                <widget class="QLineEdit" name="tx1">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                   <horstretch>200</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>150</width>
+                   <height>24</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>150</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="font">
+                  <font>
+                   <family>Droid Sans</family>
+                   <weight>50</weight>
+                   <bold>false</bold>
+                  </font>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                </widget>
+               </item>
+               <item row="3" column="2">
+                <widget class="QPushButton" name="txb3">
+                 <property name="maximumSize">
+                  <size>
+                   <width>40</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Switch to this Tx message NOW</string>
+                 </property>
+                 <property name="text">
+                  <string>Tx 3</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="4" column="2">
+                <widget class="QPushButton" name="txb4">
+                 <property name="maximumSize">
+                  <size>
+                   <width>40</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Switch to this Tx message NOW</string>
+                 </property>
+                 <property name="text">
+                  <string>Tx 4</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="1">
+                <widget class="QLabel" name="label_5">
+                 <property name="toolTip">
+                  <string>Queue up the next Tx message</string>
+                 </property>
+                 <property name="text">
+                  <string>Next</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="6" column="0">
+                <widget class="QLineEdit" name="tx6">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                   <horstretch>200</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>150</width>
+                   <height>24</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>150</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                </widget>
+               </item>
+               <item row="5" column="0">
+                <widget class="QLineEdit" name="tx5">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                   <horstretch>200</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>150</width>
+                   <height>24</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>150</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Right-click to select a macro message</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="5" column="2">
+                <widget class="QPushButton" name="txb5">
+                 <property name="maximumSize">
+                  <size>
+                   <width>40</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Switch to this Tx message NOW</string>
+                 </property>
+                 <property name="text">
+                  <string>Tx 5</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="1">
+                <widget class="QRadioButton" name="txrb2">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                   <horstretch>16</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>0</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>20</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Send this message in next Tx interval</string>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                 <attribute name="buttonGroup">
+                  <string>buttonGroup</string>
+                 </attribute>
+                </widget>
+               </item>
+               <item row="0" column="2">
+                <widget class="QLabel" name="label_2">
+                 <property name="toolTip">
+                  <string>Switch to this Tx message NOW</string>
+                 </property>
+                 <property name="text">
+                  <string>Now</string>
+                 </property>
+                 <property name="alignment">
+                  <set>Qt::AlignCenter</set>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="0">
+                <widget class="QPushButton" name="genStdMsgsPushButton">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                   <horstretch>200</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>150</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>150</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Generate standard messages for minimal QSO</string>
+                 </property>
+                 <property name="text">
+                  <string>Generate Std Msgs</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="0">
+                <widget class="QLineEdit" name="tx2">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                   <horstretch>200</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>150</width>
+                   <height>24</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>150</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                </widget>
+               </item>
+               <item row="3" column="0">
+                <widget class="QLineEdit" name="tx3">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                   <horstretch>200</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>150</width>
+                   <height>24</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>150</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                </widget>
+               </item>
+               <item row="6" column="2">
+                <widget class="QPushButton" name="txb6">
+                 <property name="maximumSize">
+                  <size>
+                   <width>40</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Switch to this Tx message NOW</string>
+                 </property>
+                 <property name="text">
+                  <string>Tx 6</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="2">
+                <widget class="QPushButton" name="txb2">
+                 <property name="maximumSize">
+                  <size>
+                   <width>40</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Switch to this Tx message NOW</string>
+                 </property>
+                 <property name="text">
+                  <string>Tx 2</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="6" column="1">
+                <widget class="QRadioButton" name="txrb6">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                   <horstretch>16</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>0</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>20</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Send this message in next Tx interval</string>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                 <attribute name="buttonGroup">
+                  <string>buttonGroup</string>
+                 </attribute>
+                </widget>
+               </item>
+               <item row="5" column="1">
+                <widget class="QRadioButton" name="txrb5">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                   <horstretch>16</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>0</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>20</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="toolTip">
+                  <string>Send this message in next Tx interval</string>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                 <attribute name="buttonGroup">
+                  <string>buttonGroup</string>
+                 </attribute>
+                </widget>
+               </item>
+               <item row="4" column="0">
+                <widget class="QLineEdit" name="tx4">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                   <horstretch>200</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>150</width>
+                   <height>24</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>150</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+            </layout>
+           </widget>
+           <widget class="QWidget" name="tab_2">
+            <attribute name="title">
+             <string>2</string>
+            </attribute>
+            <layout class="QVBoxLayout" name="verticalLayout_9">
+             <property name="spacing">
+              <number>0</number>
+             </property>
+             <property name="margin">
+              <number>0</number>
+             </property>
+             <item>
+              <layout class="QVBoxLayout" name="verticalLayout_7">
+               <property name="spacing">
+                <number>6</number>
+               </property>
+               <property name="leftMargin">
+                <number>2</number>
+               </property>
+               <property name="rightMargin">
+                <number>2</number>
+               </property>
+               <item>
+                <layout class="QGridLayout" name="gridLayout_4">
+                 <property name="spacing">
+                  <number>2</number>
+                 </property>
+                 <item row="0" column="0">
+                  <widget class="QLabel" name="label_9">
+                   <property name="minimumSize">
+                    <size>
+                     <width>0</width>
+                     <height>30</height>
+                    </size>
+                   </property>
+                   <property name="maximumSize">
+                    <size>
+                     <width>16777215</width>
+                     <height>30</height>
+                    </size>
+                   </property>
+                   <property name="text">
+                    <string>Calling CQ </string>
+                   </property>
+                   <property name="alignment">
+                    <set>Qt::AlignCenter</set>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="1" column="0">
+                  <widget class="QPushButton" name="pbCallCQ">
+                   <property name="toolTip">
+                    <string>Generate a CQ message</string>
+                   </property>
+                   <property name="text">
+                    <string>CQ</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="3" column="0">
+                  <widget class="QPushButton" name="pbSendRRR">
+                   <property name="toolTip">
+                    <string>Generate message with RRR</string>
+                   </property>
+                   <property name="text">
+                    <string>RRR</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="2" column="0">
+                  <widget class="QPushButton" name="pbAnswerCaller">
+                   <property name="toolTip">
+                    <string>Generate message with report</string>
+                   </property>
+                   <property name="text">
+                    <string>dB</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="1">
+                  <widget class="QLabel" name="label_10">
+                   <property name="minimumSize">
+                    <size>
+                     <width>0</width>
+                     <height>30</height>
+                    </size>
+                   </property>
+                   <property name="maximumSize">
+                    <size>
+                     <width>16777215</width>
+                     <height>30</height>
+                    </size>
+                   </property>
+                   <property name="text">
+                    <string>Answering CQ</string>
+                   </property>
+                   <property name="alignment">
+                    <set>Qt::AlignCenter</set>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="1" column="1">
+                  <widget class="QPushButton" name="pbAnswerCQ">
+                   <property name="toolTip">
+                    <string>Generate message for replying to a CQ</string>
+                   </property>
+                   <property name="text">
+                    <string>Grid</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="2" column="1">
+                  <widget class="QPushButton" name="pbSendReport">
+                   <property name="toolTip">
+                    <string>Generate message with R+report</string>
+                   </property>
+                   <property name="text">
+                    <string>R+dB</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="3" column="1">
+                  <widget class="QPushButton" name="pbSend73">
+                   <property name="toolTip">
+                    <string>Generate message with 73</string>
+                   </property>
+                   <property name="text">
+                    <string>73</string>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </item>
+               <item>
+                <layout class="QHBoxLayout" name="horizontalLayout_3">
+                 <item>
+                  <widget class="QLineEdit" name="genMsg">
+                   <property name="sizePolicy">
+                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="minimumSize">
+                    <size>
+                     <width>150</width>
+                     <height>0</height>
+                    </size>
+                   </property>
+                   <property name="readOnly">
+                    <bool>true</bool>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QRadioButton" name="rbGenMsg">
+                   <property name="sizePolicy">
+                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="minimumSize">
+                    <size>
+                     <width>0</width>
+                     <height>26</height>
+                    </size>
+                   </property>
+                   <property name="toolTip">
+                    <string>Send this standard (generated) message</string>
+                   </property>
+                   <property name="text">
+                    <string>Gen msg</string>
+                   </property>
+                   <property name="checked">
+                    <bool>true</bool>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </item>
+               <item>
+                <layout class="QHBoxLayout" name="horizontalLayout">
+                 <item>
+                  <widget class="QLineEdit" name="freeTextMsg">
+                   <property name="sizePolicy">
+                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="minimumSize">
+                    <size>
+                     <width>150</width>
+                     <height>0</height>
+                    </size>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QRadioButton" name="rbFreeText">
+                   <property name="sizePolicy">
+                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="minimumSize">
+                    <size>
+                     <width>0</width>
+                     <height>26</height>
+                    </size>
+                   </property>
+                   <property name="toolTip">
+                    <string>Send this free-text message (max 13 characters)</string>
+                   </property>
+                   <property name="text">
+                    <string>Free msg</string>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </item>
+              </layout>
+             </item>
+            </layout>
+           </widget>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item row="1" column="0" colspan="3">
+       <widget class="QCheckBox" name="cbPlus2kHz">
+        <property name="text">
+         <string>  +2 kHz</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="3">
+       <widget class="QLabel" name="label_3">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>23</height>
+         </size>
+        </property>
+        <property name="palette">
+         <palette>
+          <active>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>252</red>
+              <green>252</green>
+              <blue>252</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>159</red>
+              <green>175</green>
+              <blue>213</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </active>
+          <inactive>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>252</red>
+              <green>252</green>
+              <blue>252</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>159</red>
+              <green>175</green>
+              <blue>213</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </inactive>
+          <disabled>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>159</red>
+              <green>175</green>
+              <blue>213</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>159</red>
+              <green>175</green>
+              <blue>213</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </disabled>
+         </palette>
+        </property>
+        <property name="autoFillBackground">
+         <bool>true</bool>
+        </property>
+        <property name="text">
+         <string>DX Call</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+        <property name="indent">
+         <number>2</number>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="4">
+       <widget class="QLabel" name="label_4">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>23</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="palette">
+         <palette>
+          <active>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>252</red>
+              <green>252</green>
+              <blue>252</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>159</red>
+              <green>175</green>
+              <blue>213</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </active>
+          <inactive>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>252</red>
+              <green>252</green>
+              <blue>252</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>159</red>
+              <green>175</green>
+              <blue>213</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </inactive>
+          <disabled>
+           <colorrole role="Base">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>159</red>
+              <green>175</green>
+              <blue>213</blue>
+             </color>
+            </brush>
+           </colorrole>
+           <colorrole role="Window">
+            <brush brushstyle="SolidPattern">
+             <color alpha="255">
+              <red>159</red>
+              <green>175</green>
+              <blue>213</blue>
+             </color>
+            </brush>
+           </colorrole>
+          </disabled>
+         </palette>
+        </property>
+        <property name="autoFillBackground">
+         <bool>true</bool>
+        </property>
+        <property name="text">
+         <string>DX Grid</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+        <property name="indent">
+         <number>2</number>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="6">
+       <widget class="QPushButton" name="pbTxMode">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>Tx JT9</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1" rowspan="5">
+       <widget class="QSlider" name="inGain">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>160</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>20</width>
+          <height>160</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Digital gain for audio input</string>
+        </property>
+        <property name="minimum">
+         <number>-50</number>
+        </property>
+        <property name="maximum">
+         <number>50</number>
+        </property>
+        <property name="orientation">
+         <enum>Qt::Vertical</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="3">
+       <widget class="QLineEdit" name="dxCallEntry">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>70</width>
+          <height>27</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>74</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Callsign of station to be worked</string>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="4">
+       <widget class="QLineEdit" name="dxGridEntry">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>70</width>
+          <height>27</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>74</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Locator of station to be worked</string>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="6">
+       <widget class="QSpinBox" name="TxFreqSpinBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>113</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>105</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Audio Tx frequency</string>
+        </property>
+        <property name="suffix">
+         <string>  Hz</string>
+        </property>
+        <property name="prefix">
+         <string>Tx  </string>
+        </property>
+        <property name="minimum">
+         <number>200</number>
+        </property>
+        <property name="maximum">
+         <number>5000</number>
+        </property>
+        <property name="value">
+         <number>1500</number>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="4">
+       <widget class="QLabel" name="labDist">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>23</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>23</height>
+         </size>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="5">
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeType">
+         <enum>QSizePolicy::Expanding</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>33</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="3" column="6">
+       <widget class="QSpinBox" name="RxFreqSpinBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>113</width>
+          <height>20</height>
+         </size>
+        </property>
+        <property name="suffix">
+         <string>  Hz</string>
+        </property>
+        <property name="prefix">
+         <string>Rx  </string>
+        </property>
+        <property name="minimum">
+         <number>200</number>
+        </property>
+        <property name="maximum">
+         <number>5000</number>
+        </property>
+        <property name="value">
+         <number>1500</number>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="7">
+       <spacer name="horizontalSpacer_3">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeType">
+         <enum>QSizePolicy::Expanding</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>13</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="4" column="3">
+       <widget class="QPushButton" name="lookupButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>74</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Search for callsign in database</string>
+        </property>
+        <property name="text">
+         <string>&Lookup</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="4">
+       <widget class="QPushButton" name="addButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>74</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Add callsign and locator to database</string>
+        </property>
+        <property name="text">
+         <string>Add</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="6">
+       <layout class="QHBoxLayout" name="horizontalLayout_5">
+        <property name="spacing">
+         <number>5</number>
+        </property>
+        <property name="sizeConstraint">
+         <enum>QLayout::SetFixedSize</enum>
+        </property>
+        <item>
+         <widget class="QPushButton" name="pbR2T">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>48</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Set Tx frequency to Rx Frequency</string>
+          </property>
+          <property name="text">
+           <string>Tx=Rx</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="pbT2R">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>48</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Set Rx frequency to Tx Frequency</string>
+          </property>
+          <property name="text">
+           <string>Rx=Tx</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item row="5" column="3" rowspan="2" colspan="2">
+       <widget class="QLabel" name="labUTC">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>130</width>
+          <height>60</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>158</width>
+          <height>60</height>
+         </size>
+        </property>
+        <property name="font">
+         <font>
+          <pointsize>16</pointsize>
+         </font>
+        </property>
+        <property name="frameShape">
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Sunken</enum>
+        </property>
+        <property name="lineWidth">
+         <number>2</number>
+        </property>
+        <property name="midLineWidth">
+         <number>0</number>
+        </property>
+        <property name="text">
+         <string> 01:23:45 </string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="6">
+       <widget class="QCheckBox" name="cbTxLock">
+        <property name="text">
+         <string>Lock Tx=Rx</string>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="6">
+       <layout class="QHBoxLayout" name="horizontalLayout_4">
+        <property name="spacing">
+         <number>5</number>
+        </property>
+        <item>
+         <widget class="QLabel" name="label_8">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="text">
+           <string>Report</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="rptSpinBox">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>55</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize">
+           <size>
+            <width>55</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Signal report (dB0</string>
+          </property>
+          <property name="minimum">
+           <number>-50</number>
+          </property>
+          <property name="maximum">
+           <number>49</number>
+          </property>
+          <property name="value">
+           <number>-15</number>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menuBar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>760</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
+     <string>File</string>
+    </property>
+    <addaction name="actionOpen"/>
+    <addaction name="actionOpen_next_in_directory"/>
+    <addaction name="actionDecode_remaining_files_in_directory"/>
+    <addaction name="separator"/>
+    <addaction name="actionDelete_all_wav_files_in_SaveDir"/>
+    <addaction name="actionErase_ALL_TXT"/>
+    <addaction name="actionErase_wsjtx_log_adi"/>
+    <addaction name="separator"/>
+    <addaction name="actionExit"/>
+   </widget>
+   <widget class="QMenu" name="menuSetup">
+    <property name="title">
+     <string>Setup</string>
+    </property>
+    <widget class="QMenu" name="menuAdvanced">
+     <property name="enabled">
+      <bool>true</bool>
+     </property>
+     <property name="title">
+      <string>Advanced</string>
+     </property>
+     <addaction name="actionAllow_multiple_instances"/>
+    </widget>
+    <addaction name="actionDeviceSetup"/>
+    <addaction name="separator"/>
+    <addaction name="actionMonitor_OFF_at_startup"/>
+    <addaction name="actionConvert_JT9_x_to_RTTY"/>
+    <addaction name="actionLog_dB_reports_to_Comments"/>
+    <addaction name="actionPrompt_to_log_QSO"/>
+    <addaction name="actionBlank_line_between_decoding_periods"/>
+    <addaction name="actionClear_DX_Call_and_Grid_after_logging"/>
+    <addaction name="actionDisplay_distance_in_miles"/>
+    <addaction name="actionDouble_click_on_call_sets_Tx_Enable"/>
+    <addaction name="action_73TxDisable"/>
+    <addaction name="actionRunaway_Tx_watchdog"/>
+    <addaction name="actionTx2QSO"/>
+    <addaction name="separator"/>
+    <addaction name="menuAdvanced"/>
+   </widget>
+   <widget class="QMenu" name="menuView">
+    <property name="title">
+     <string>View</string>
+    </property>
+    <widget class="QMenu" name="menuWaterfall_palette">
+     <property name="title">
+      <string>Waterfall palette</string>
+     </property>
+     <addaction name="actionLinrad"/>
+     <addaction name="actionCuteSDR"/>
+     <addaction name="actionAFMHot"/>
+     <addaction name="actionBlue"/>
+    </widget>
+    <addaction name="actionWide_Waterfall"/>
+    <addaction name="separator"/>
+    <addaction name="menuWaterfall_palette"/>
+   </widget>
+   <widget class="QMenu" name="menuDecode">
+    <property name="title">
+     <string>Decode</string>
+    </property>
+    <addaction name="actionQuickDecode"/>
+    <addaction name="actionMediumDecode"/>
+    <addaction name="actionDeepestDecode"/>
+   </widget>
+   <widget class="QMenu" name="menuSave">
+    <property name="title">
+     <string>Save</string>
+    </property>
+    <addaction name="actionNone"/>
+    <addaction name="actionSave_decoded"/>
+    <addaction name="actionSave_all"/>
+   </widget>
+   <widget class="QMenu" name="menuHelp">
+    <property name="title">
+     <string>Help</string>
+    </property>
+    <addaction name="actionOnline_Users_Guide"/>
+    <addaction name="actionKeyboard_shortcuts"/>
+    <addaction name="actionSpecial_mouse_commands"/>
+    <addaction name="actionAbout"/>
+   </widget>
+   <widget class="QMenu" name="menuMode">
+    <property name="title">
+     <string>Mode</string>
+    </property>
+    <addaction name="actionJT9_1"/>
+    <addaction name="actionJT65"/>
+    <addaction name="actionJT9_JT65"/>
+   </widget>
+   <addaction name="menuFile"/>
+   <addaction name="menuSetup"/>
+   <addaction name="menuView"/>
+   <addaction name="menuMode"/>
+   <addaction name="menuDecode"/>
+   <addaction name="menuSave"/>
+   <addaction name="menuHelp"/>
+  </widget>
+  <widget class="QStatusBar" name="statusBar"/>
+  <action name="actionExit">
+   <property name="text">
+    <string>Exit</string>
+   </property>
+  </action>
+  <action name="actionDeviceSetup">
+   <property name="checkable">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>Configuration</string>
+   </property>
+   <property name="shortcut">
+    <string>F2</string>
+   </property>
+  </action>
+  <action name="actionAbout">
+   <property name="text">
+    <string> About WSJT-X</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+F1</string>
+   </property>
+  </action>
+  <action name="actionAstro_Data">
+   <property name="text">
+    <string>Astro Data</string>
+   </property>
+   <property name="shortcut">
+    <string>Shift+F10</string>
+   </property>
+  </action>
+  <action name="actionBand_Map">
+   <property name="text">
+    <string>Band Map</string>
+   </property>
+  </action>
+  <action name="actionMessages">
+   <property name="text">
+    <string>Messages</string>
+   </property>
+  </action>
+  <action name="actionWide_Waterfall">
+   <property name="text">
+    <string>Waterfall</string>
+   </property>
+  </action>
+  <action name="actionOpen">
+   <property name="text">
+    <string>Open</string>
+   </property>
+  </action>
+  <action name="actionOpen_next_in_directory">
+   <property name="text">
+    <string>Open next in directory</string>
+   </property>
+   <property name="shortcut">
+    <string>F6</string>
+   </property>
+  </action>
+  <action name="actionDecode_remaining_files_in_directory">
+   <property name="text">
+    <string>Decode remaining files in directory</string>
+   </property>
+   <property name="shortcut">
+    <string>Shift+F6</string>
+   </property>
+  </action>
+  <action name="actionDelete_all_wav_files_in_SaveDir">
+   <property name="text">
+    <string>Delete all *.wav files in SaveDir</string>
+   </property>
+  </action>
+  <action name="actionErase_Band_Map_and_Messages">
+   <property name="text">
+    <string>Erase Band Map and Messages</string>
+   </property>
+  </action>
+  <action name="actionLinrad">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Linrad</string>
+   </property>
+  </action>
+  <action name="actionCuteSDR">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>CuteSDR</string>
+   </property>
+  </action>
+  <action name="actionFind_Delta_Phi">
+   <property name="text">
+    <string>Find Delta Phi</string>
+   </property>
+  </action>
+  <action name="actionF4_sets_Tx6">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>F4 sets Tx6</string>
+   </property>
+  </action>
+  <action name="actionNo_shorthands_if_Tx1">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>No shorthand decodes if Tx1</string>
+   </property>
+  </action>
+  <action name="actionQuickDecode">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>Fast</string>
+   </property>
+  </action>
+  <action name="actionNone">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>None</string>
+   </property>
+  </action>
+  <action name="actionSave_all">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Save all</string>
+   </property>
+  </action>
+  <action name="action50">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>50</string>
+   </property>
+  </action>
+  <action name="action144">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>144</string>
+   </property>
+  </action>
+  <action name="action222">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>222</string>
+   </property>
+  </action>
+  <action name="action432">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>432</string>
+   </property>
+  </action>
+  <action name="action1296">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>1296</string>
+   </property>
+  </action>
+  <action name="action2304">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>2304</string>
+   </property>
+  </action>
+  <action name="actionOnline_Users_Guide">
+   <property name="text">
+    <string>Online User's Guide</string>
+   </property>
+   <property name="shortcut">
+    <string>F1</string>
+   </property>
+  </action>
+  <action name="actionKeyboard_shortcuts">
+   <property name="text">
+    <string>Keyboard shortcuts</string>
+   </property>
+   <property name="shortcut">
+    <string>F3</string>
+   </property>
+  </action>
+  <action name="actionSpecial_mouse_commands">
+   <property name="text">
+    <string>Special mouse commands</string>
+   </property>
+   <property name="shortcut">
+    <string>F5</string>
+   </property>
+  </action>
+  <action name="actionAvailable_suffixes_and_add_on_prefixes">
+   <property name="text">
+    <string>Available suffixes and add-on-prefixes</string>
+   </property>
+  </action>
+  <action name="actionJT65A">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>JT65A</string>
+   </property>
+  </action>
+  <action name="actionJT65B">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>JT65B</string>
+   </property>
+  </action>
+  <action name="actionJT65C">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>JT65C</string>
+   </property>
+  </action>
+  <action name="actionI_Q_Calibration">
+   <property name="text">
+    <string>I/Q Calibration</string>
+   </property>
+   <property name="shortcut">
+    <string>F7</string>
+   </property>
+  </action>
+  <action name="actionAdjust_IQ_Calibration">
+   <property name="text">
+    <string>Adjust I/Q Calibration</string>
+   </property>
+  </action>
+  <action name="actionApply_IQ_Calibration">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Apply I/Q Calibration</string>
+   </property>
+  </action>
+  <action name="actionAFMHot">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>AFMHot</string>
+   </property>
+  </action>
+  <action name="actionBlue">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Blue</string>
+   </property>
+  </action>
+  <action name="actionFUNcube_Dongle">
+   <property name="text">
+    <string>FUNcube Dongle Settings</string>
+   </property>
+  </action>
+  <action name="actionJT9_1">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>JT9</string>
+   </property>
+  </action>
+  <action name="actionJT9_2">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>JT9-2</string>
+   </property>
+  </action>
+  <action name="actionJT9_5">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>JT9-5</string>
+   </property>
+  </action>
+  <action name="actionJT9_10">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>JT9-10</string>
+   </property>
+  </action>
+  <action name="actionJT9_30">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>JT9-30</string>
+   </property>
+  </action>
+  <action name="actionSave_synced">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>Save synced</string>
+   </property>
+  </action>
+  <action name="actionSave_decoded">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="enabled">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Save decoded</string>
+   </property>
+  </action>
+  <action name="actionMediumDecode">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>Normal</string>
+   </property>
+  </action>
+  <action name="actionDeepestDecode">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Deepest</string>
+   </property>
+  </action>
+  <action name="actionMonitor_OFF_at_startup">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Monitor OFF at startup</string>
+   </property>
+  </action>
+  <action name="actionErase_ALL_TXT">
+   <property name="text">
+    <string>Erase ALL.TXT</string>
+   </property>
+  </action>
+  <action name="actionErase_wsjtx_log_adi">
+   <property name="text">
+    <string>Erase wsjtx_log.adi</string>
+   </property>
+  </action>
+  <action name="actionLog_JT9_without_submode">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Log JT9 without submode</string>
+   </property>
+  </action>
+  <action name="actionConvert_JT9_x_to_RTTY">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Convert mode to RTTY for logging</string>
+   </property>
+  </action>
+  <action name="actionLog_dB_reports_to_Comments">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Log dB reports to Comments</string>
+   </property>
+  </action>
+  <action name="actionPrompt_to_log_QSO">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Prompt me to log QSO</string>
+   </property>
+  </action>
+  <action name="actionBlank_line_between_decoding_periods">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Blank line between decoding periods</string>
+   </property>
+  </action>
+  <action name="actionClear_DX_Call_and_Grid_after_logging">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Clear DX Call and Grid after logging</string>
+   </property>
+  </action>
+  <action name="actionDistance_in_miles">
+   <property name="text">
+    <string>Distance in miles</string>
+   </property>
+  </action>
+  <action name="actionDisplay_distance_in_miles">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Display distance in miles</string>
+   </property>
+  </action>
+  <action name="actionDouble_click_on_call_sets_Tx_Enable">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Double-click on call sets Tx Enable</string>
+   </property>
+  </action>
+  <action name="action_73TxDisable">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Tx disabled after sending 73</string>
+   </property>
+  </action>
+  <action name="actionRunaway_Tx_watchdog">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Runaway Tx watchdog</string>
+   </property>
+  </action>
+  <action name="actionAllow_multiple_instances">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Allow multiple instances</string>
+   </property>
+  </action>
+  <action name="actionLockTxFreq">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Tx freq locked to Rx freq</string>
+   </property>
+  </action>
+  <action name="actionJT65">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>JT65</string>
+   </property>
+  </action>
+  <action name="actionJT9_JT65">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>JT9+JT65</string>
+   </property>
+  </action>
+  <action name="actionTx2QSO">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Tx messages to Rx Frequency window</string>
+   </property>
+  </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+  <customwidget>
+   <class>DisplayText</class>
+   <extends>QTextBrowser</extends>
+   <header>displaytext.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>logQSOButton</tabstop>
+  <tabstop>stopButton</tabstop>
+  <tabstop>monitorButton</tabstop>
+  <tabstop>EraseButton</tabstop>
+  <tabstop>DecodeButton</tabstop>
+  <tabstop>autoButton</tabstop>
+  <tabstop>stopTxButton</tabstop>
+  <tabstop>tuneButton</tabstop>
+  <tabstop>bandComboBox</tabstop>
+  <tabstop>readFreq</tabstop>
+  <tabstop>inGain</tabstop>
+  <tabstop>dxCallEntry</tabstop>
+  <tabstop>dxGridEntry</tabstop>
+  <tabstop>txFirstCheckBox</tabstop>
+  <tabstop>TxFreqSpinBox</tabstop>
+  <tabstop>pbR2T</tabstop>
+  <tabstop>pbT2R</tabstop>
+  <tabstop>rptSpinBox</tabstop>
+  <tabstop>tabWidget</tabstop>
+  <tabstop>genStdMsgsPushButton</tabstop>
+  <tabstop>tx1</tabstop>
+  <tabstop>tx2</tabstop>
+  <tabstop>tx3</tabstop>
+  <tabstop>tx4</tabstop>
+  <tabstop>tx5</tabstop>
+  <tabstop>tx6</tabstop>
+  <tabstop>txrb1</tabstop>
+  <tabstop>txrb2</tabstop>
+  <tabstop>txrb3</tabstop>
+  <tabstop>txrb4</tabstop>
+  <tabstop>txrb5</tabstop>
+  <tabstop>txrb6</tabstop>
+  <tabstop>txb1</tabstop>
+  <tabstop>txb2</tabstop>
+  <tabstop>txb3</tabstop>
+  <tabstop>txb4</tabstop>
+  <tabstop>txb5</tabstop>
+  <tabstop>txb6</tabstop>
+  <tabstop>decodedTextBrowser</tabstop>
+  <tabstop>decodedTextBrowser2</tabstop>
+  <tabstop>genMsg</tabstop>
+  <tabstop>pbAnswerCaller</tabstop>
+  <tabstop>rbFreeText</tabstop>
+  <tabstop>pbSendRRR</tabstop>
+  <tabstop>freeTextMsg</tabstop>
+  <tabstop>pbAnswerCQ</tabstop>
+  <tabstop>pbSendReport</tabstop>
+  <tabstop>pbSend73</tabstop>
+  <tabstop>rbGenMsg</tabstop>
+  <tabstop>pbCallCQ</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>monitorButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>MainWindow</receiver>
+   <slot>update()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>264</x>
+     <y>275</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>126</x>
+     <y>515</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+ <buttongroups>
+  <buttongroup name="buttonGroup">
+   <property name="exclusive">
+    <bool>true</bool>
+   </property>
+  </buttongroup>
+ </buttongroups>
+</ui>
diff --git a/meterwidget.cpp b/meterwidget.cpp
new file mode 100644
index 0000000..b48aa65
--- /dev/null
+++ b/meterwidget.cpp
@@ -0,0 +1,51 @@
+// Simple bargraph meter
+// Implemented by Edson Pereira PY2SDR
+
+#include "meterwidget.h"
+
+MeterWidget::MeterWidget(QWidget *parent) :
+    QWidget(parent),
+    m_signal(0)
+{
+    for ( int i = 0; i < 10; i++ ) {
+        signalQueue.enqueue(0);
+    }
+}
+
+void MeterWidget::setValue(int value)
+{
+    m_signal = value;
+    signalQueue.enqueue(value);
+    signalQueue.dequeue();
+
+    // Get signal peak
+    int tmp = 0;
+    for (int i = 0; i < signalQueue.size(); ++i) {
+        if (signalQueue.at(i) > tmp)
+            tmp = signalQueue.at(i);
+    }
+    m_sigPeak = tmp;
+
+    update();
+}
+
+void MeterWidget::paintEvent( QPaintEvent * )
+{
+    int pos;
+    QPainter p;
+
+    p.begin(this);
+
+    // Sanitize
+    m_signal = m_signal < 0 ? 0 : m_signal;
+    m_signal = m_signal > 60 ? 60 : m_signal;
+
+    pos = m_signal * 2;
+    QRect r(0, height() - pos, width(), pos );
+    p.fillRect(r, QColor( 255, 150, 0 ));
+
+    // Draw peak hold indicator
+    p.setPen(Qt::black);
+    pos = m_sigPeak * 2;
+    p.drawLine(0, height() - pos, 10, height() - pos);
+}
diff --git a/meterwidget.h b/meterwidget.h
new file mode 100644
index 0000000..7b51efb
--- /dev/null
+++ b/meterwidget.h
@@ -0,0 +1,30 @@
+#ifndef METERWIDGET_H
+#define METERWIDGET_H
+
+#include <QWidget>
+#include <QtGui>
+#include <QQueue>
+
+class MeterWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit MeterWidget(QWidget *parent = 0);
+    
+signals:
+    
+public slots:
+    void setValue(int value);
+
+private:
+    QQueue<int> signalQueue;
+
+    int m_signal;
+    int m_sigPeak;
+
+protected:
+    void paintEvent( QPaintEvent * );
+    
+};
+
+#endif // METERWIDGET_H
diff --git a/mouse_commands.txt b/mouse_commands.txt
new file mode 100644
index 0000000..8e26589
--- /dev/null
+++ b/mouse_commands.txt
@@ -0,0 +1,18 @@
+Click on	Action
+__________________________________________________________
+
+Waterfall:	 Set Rx frequency
+	 Double-click to set Rx frequency and decode there
+	 Ctrl-click to set Rx and Tx frequencies and decode
+
+Decoded text:	 Double-click to copy second callsign to Dx Call,
+	 locator to Dx Grid; change Rx and Tx frequencies to 
+	 decoded signal's frequency; generate standard messages. 
+	 If first callsign is your own, Tx frequency is not 
+	 changed unless Ctrl is held down when double-clicking.
+
+Erase button:	 Click to erase QSO window
+      	 Double-click to erase QSO and Band Activity windows
+
+Tx5 Entry:	 Right-click to select a macro message
+
diff --git a/paInputDevice.c b/paInputDevice.c
new file mode 100644
index 0000000..641bd85
--- /dev/null
+++ b/paInputDevice.c
@@ -0,0 +1,56 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+void paInputDevice(int id, char* hostAPI_DeviceName, int* minChan, 
+		   int* maxChan, int* minSpeed, int* maxSpeed)
+{
+  int i, j, k;
+  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[50];
+  char *p,*p1;
+  static int iret, numDevices, 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="";
+    p=strstr(pa_device_hostapi,"MME");
+    if(p!=NULL) p1="MME";
+    p=strstr(pa_device_hostapi,"Direct");
+    if(p!=NULL) p1="DirectX";
+    p=strstr(pa_device_hostapi,"WASAPI");
+    if(p!=NULL) p1="WASAPI";
+    p=strstr(pa_device_hostapi,"ASIO");
+    if(p!=NULL) p1="ASIO";
+    p=strstr(pa_device_hostapi,"WDM-KS");
+    if(p!=NULL) p1="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;
+  }
+}
diff --git a/pa_get_device_info.c b/pa_get_device_info.c
new file mode 100644
index 0000000..ac6bc9f
--- /dev/null
+++ b/pa_get_device_info.c
@@ -0,0 +1,172 @@
+#include <portaudio.h>
+#include <stdio.h>
+
+#define MAX_LATENCY 20
+
+PaStream *in_stream;
+//------------------------------------------------------- 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;
+}
diff --git a/plotter.cpp b/plotter.cpp
new file mode 100644
index 0000000..a43bdbf
--- /dev/null
+++ b/plotter.cpp
@@ -0,0 +1,565 @@
+#include "plotter.h"
+#include <math.h>
+#include <QDebug>
+
+#define MAX_SCREENSIZE 2048
+
+
+CPlotter::CPlotter(QWidget *parent) :                  //CPlotter Constructor
+  QFrame(parent)
+{
+  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+  setFocusPolicy(Qt::StrongFocus);
+  setAttribute(Qt::WA_PaintOnScreen,false);
+  setAutoFillBackground(false);
+  setAttribute(Qt::WA_OpaquePaintEvent, false);
+  setAttribute(Qt::WA_NoSystemBackground, true);
+
+  m_StartFreq = 0;
+  m_nSpan=2;                         //used for FFT bins/pixel
+  m_fSpan=(float)m_nSpan;
+  m_hdivs = HORZ_DIVS;
+  m_FreqUnits = 1;
+  m_Running = false;
+  m_paintEventBusy=false;
+  m_WaterfallPixmap = QPixmap(0,0);
+  m_2DPixmap = QPixmap(0,0);
+  m_ScalePixmap = QPixmap(0,0);
+  m_OverlayPixmap = QPixmap(0,0);
+  m_Size = QSize(0,0);
+  m_rxFreq = 1020;
+  m_line = 0;
+  m_fSample = 12000;
+  m_nsps=6912;
+  m_dBStepSize=10;
+  m_Percent2DScreen = 30;	//percent of screen used for 2D display
+  m_txFreq=0;
+}
+
+CPlotter::~CPlotter() { }                                      // Destructor
+
+QSize CPlotter::minimumSizeHint() const
+{
+  return QSize(50, 50);
+}
+
+QSize CPlotter::sizeHint() const
+{
+  return QSize(180, 180);
+}
+
+void CPlotter::resizeEvent(QResizeEvent* )                    //resizeEvent()
+{
+  if(!size().isValid()) return;
+  if( m_Size != size() ) {  //if changed, resize pixmaps to new screensize
+    m_Size = size();
+    m_w = m_Size.width();
+    m_h = m_Size.height();
+    m_h1 = (100-m_Percent2DScreen)*(m_Size.height())/100;
+    m_h2 = (m_Percent2DScreen)*(m_Size.height())/100;
+
+    m_2DPixmap = QPixmap(m_Size.width(), m_h2);
+    m_2DPixmap.fill(Qt::black);
+    m_WaterfallPixmap = QPixmap(m_Size.width(), m_h1);
+    m_OverlayPixmap = QPixmap(m_Size.width(), m_h2);
+    m_OverlayPixmap.fill(Qt::black);
+
+    m_WaterfallPixmap.fill(Qt::black);
+    m_2DPixmap.fill(Qt::black);
+    m_ScalePixmap = QPixmap(m_w,30);
+    m_ScalePixmap.fill(Qt::white);
+  }
+  DrawOverlay();
+}
+
+void CPlotter::paintEvent(QPaintEvent *)                    // paintEvent()
+{
+  if(m_paintEventBusy) return;
+  m_paintEventBusy=true;
+  QPainter painter(this);
+  painter.drawPixmap(0,0,m_ScalePixmap);
+  painter.drawPixmap(0,30,m_WaterfallPixmap);
+  painter.drawPixmap(0,m_h1,m_2DPixmap);
+  m_paintEventBusy=false;
+}
+
+void CPlotter::draw(float swide[], int i0)             //draw()
+{
+  int j,y2;
+  float y;
+
+  m_i0=i0;
+  double gain = pow(10.0,0.05*(m_plotGain+7));
+
+//move current data down one line (must do this before attaching a QPainter object)
+  m_WaterfallPixmap.scroll(0,1,0,0,m_w,m_h1);
+  QPainter painter1(&m_WaterfallPixmap);
+  m_2DPixmap = m_OverlayPixmap.copy(0,0,m_w,m_h2);
+  QPainter painter2D(&m_2DPixmap);
+
+  painter2D.setPen(Qt::green);
+
+  QPoint LineBuf[MAX_SCREENSIZE];
+  j=0;
+
+//  int iz=XfromFreq(2000.0);
+  int iz=XfromFreq(5000.0);
+  m_fMax=FreqfromX(iz);
+  for(int i=0; i<iz; i++) {
+    if(i>iz) swide[i]=0;
+    y=0.0;
+    if(swide[i]>0.0) y = 10.0*log10(swide[i]);
+    int y1 = 5.0*gain*y + 10*(m_plotZero-4);
+    if (y1<0) y1=0;
+    if (y1>254) y1=254;
+    if (swide[i]>1.e29) y1=255;
+    painter1.setPen(m_ColorTbl[y1]);
+    painter1.drawPoint(i,0);
+    y2=0;
+    if(m_bCurrent) y2 = 0.4*gain*y - 15;
+    if(m_bCumulative) {
+      float sum=0.0;
+      int j=m_binsPerPixel*i;
+      for(int k=0; k<m_binsPerPixel; k++) {
+        sum+=jt9com_.savg[j++];
+      }
+      y2=gain*6.0*log10(sum/m_binsPerPixel) - 10.0;
+    }
+    y2 += m_plotZero;
+    if(i==iz-1) painter2D.drawPolyline(LineBuf,j);
+    LineBuf[j].setX(i);
+    LineBuf[j].setY(m_h-(y2+0.8*m_h));
+    j++;
+  }
+
+  if(swide[0]>1.0e29) m_line=0;
+  m_line++;
+  if(m_line == 13) {
+    UTCstr();
+    painter1.setPen(Qt::white);
+    painter1.drawText(5,10,m_sutc);
+  }
+  update();                              //trigger a new paintEvent
+}
+
+void CPlotter::UTCstr()
+{
+  int ihr,imin;
+  if(jt9com_.ndiskdat != 0) {
+    ihr=jt9com_.nutc/100;
+    imin=jt9com_.nutc % 100;
+  } else {
+    qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
+    imin=ms/60000;
+    ihr=imin/60;
+    imin=imin % 60;
+    imin=imin - (imin % (m_TRperiod/60));
+  }
+  sprintf(m_sutc,"%2.2d:%2.2d",ihr,imin);
+}
+
+void CPlotter::DrawOverlay()                                 //DrawOverlay()
+{
+  if(m_OverlayPixmap.isNull()) return;
+  if(m_WaterfallPixmap.isNull()) return;
+  int w = m_WaterfallPixmap.width();
+  int x,y,x1,x2;
+//  int nHzDiv[11]={0,50,100,200,200,200,500,500,500,500,500};
+  float pixperdiv;
+
+  QRect rect;
+  QPainter painter(&m_OverlayPixmap);
+  painter.initFrom(this);
+  QLinearGradient gradient(0, 0, 0 ,m_h2);  //fill background with gradient
+  gradient.setColorAt(1, Qt::black);
+  gradient.setColorAt(0, Qt::darkBlue);
+  painter.setBrush(gradient);
+  painter.drawRect(0, 0, m_w, m_h2);
+  painter.setBrush(Qt::SolidPattern);
+
+  double df = m_binsPerPixel*m_fftBinWidth;
+  pixperdiv = m_freqPerDiv/df;
+  y = m_h2 - m_h2/VERT_DIVS;
+  m_hdivs = w*df/m_freqPerDiv + 0.9999;
+  for( int i=1; i<m_hdivs; i++)                   //draw vertical grids
+  {
+    x = (int)( (float)i*pixperdiv );
+    if(x >= 0 and x<=m_w) {
+      painter.setPen(QPen(Qt::white, 1,Qt::DotLine));
+      painter.drawLine(x, 0, x , y);
+      painter.drawLine(x, m_h2-5, x , m_h2);
+    }
+  }
+
+  pixperdiv = (float)m_h2 / (float)VERT_DIVS;
+  painter.setPen(QPen(Qt::white, 1,Qt::DotLine));
+  for( int i=1; i<VERT_DIVS; i++)                 //draw horizontal grids
+  {
+          y = (int)( (float)i*pixperdiv );
+          painter.drawLine(0, y, w, y);
+  }
+
+  QRect rect0;
+  QPainter painter0(&m_ScalePixmap);
+  painter0.initFrom(this);
+
+  //create Font to use for scales
+  QFont Font("Arial");
+  Font.setPointSize(12);
+  QFontMetrics metrics(Font);
+  Font.setWeight(QFont::Normal);
+  painter0.setFont(Font);
+  painter0.setPen(Qt::black);
+
+  if(m_binsPerPixel < 1) m_binsPerPixel=1;
+  m_fSpan = w*df;
+  int n=m_fSpan/10;
+  m_freqPerDiv=10;
+  if(n>25) m_freqPerDiv=50;
+  if(n>70) m_freqPerDiv=100;
+  if(n>140) m_freqPerDiv=200;
+  if(n>310) m_freqPerDiv=500;
+  m_hdivs = w*df/m_freqPerDiv + 0.9999;
+  m_ScalePixmap.fill(Qt::white);
+  painter0.drawRect(0, 0, w, 30);
+
+//draw tick marks on upper scale
+  pixperdiv = m_freqPerDiv/df;
+  for( int i=1; i<m_hdivs; i++) {     //major ticks
+    x = (int)( (float)i*pixperdiv );
+    painter0.drawLine(x,18,x,30);
+  }
+  int minor=5;
+  if(m_freqPerDiv==200) minor=4;
+  for( int i=1; i<minor*m_hdivs; i++) {   //minor ticks
+    x = i*pixperdiv/minor;
+    painter0.drawLine(x,24,x,30);
+  }
+
+  //draw frequency values
+  MakeFrequencyStrs();
+  for( int i=0; i<=m_hdivs; i++) {
+    if(0==i) {
+      //left justify the leftmost text
+      x = (int)( (float)i*pixperdiv);
+      rect0.setRect(x,0, (int)pixperdiv, 20);
+      painter0.drawText(rect0, Qt::AlignLeft|Qt::AlignVCenter,
+                       m_HDivText[i]);
+    }
+    else if(m_hdivs == i) {
+      //right justify the rightmost text
+      x = (int)( (float)i*pixperdiv - pixperdiv);
+      rect0.setRect(x,0, (int)pixperdiv, 20);
+      painter0.drawText(rect0, Qt::AlignRight|Qt::AlignVCenter,
+                       m_HDivText[i]);
+    } else {
+      //center justify the rest of the text
+      x = (int)( (float)i*pixperdiv - pixperdiv/2);
+      rect0.setRect(x,0, (int)pixperdiv, 20);
+      painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter,
+                       m_HDivText[i]);
+    }
+  }
+
+  float bw=9.0*12000.0/m_nsps;
+  if(m_modeTx=="JT65") bw=66.0*11025.0/4096.0;
+
+  QPen pen0(Qt::green, 3);                 //Mark Rx Freq with green
+  painter0.setPen(pen0);
+  x1=XfromFreq(m_rxFreq);
+  x2=XfromFreq(m_rxFreq+bw);
+  painter0.drawLine(x1,24,x1,30);
+  painter0.drawLine(x1,28,x2,28);
+  painter0.drawLine(x2,24,x2,30);
+
+  if(m_mode=="JT9+JT65") {
+    QPen pen2(Qt::blue, 3);                //Mark the JT65 | JT9 divider
+    painter0.setPen(pen2);
+    x1=XfromFreq(m_fMin);
+    if(x1<2) x1=2;
+    x2=x1+30;
+    painter0.drawLine(x1,8,x1,28);
+  }
+
+  QPen pen1(Qt::red, 3);                   //Mark Tx freq with red
+  painter0.setPen(pen1);
+  x1=XfromFreq(m_txFreq);
+  x2=XfromFreq(m_txFreq+bw);
+  painter0.drawLine(x1,17,x1,21);
+  painter0.drawLine(x1,17,x2,17);
+  painter0.drawLine(x2,17,x2,21);
+
+  if(m_dialFreq>10.13 and m_dialFreq< 10.15) {
+    float f1=1.0e6*(10.1401 - m_dialFreq);
+    float f2=f1+200.0;
+    x1=XfromFreq(f1);
+    x2=XfromFreq(f2);
+    if(x1<=m_w and x2>=0) {
+      QPen pen1(QColor(255,165,0),3);             //Mark WSPR sub-band orange
+      painter0.setPen(pen1);
+      painter0.drawLine(x1,9,x2,9);
+    }
+  }
+}
+
+void CPlotter::MakeFrequencyStrs()                       //MakeFrequencyStrs
+{
+  float freq;
+  for(int i=0; i<=m_hdivs; i++) {
+    freq = m_StartFreq + i*m_freqPerDiv;
+    m_HDivText[i].setNum((int)freq);
+    //      StartFreq += m_freqPerDiv;
+  }
+}
+
+int CPlotter::XfromFreq(float f)                               //XfromFreq()
+{
+//  float w = m_WaterfallPixmap.width();
+  int x = int(m_w * (f - m_StartFreq)/m_fSpan + 0.5);
+  if(x<0 ) return 0;
+  if(x>m_w) return m_w;
+  return x;
+}
+
+float CPlotter::FreqfromX(int x)                               //FreqfromX()
+{
+//  return float(1000.0 + x*m_binsPerPixel*m_fftBinWidth);
+  return float(x*m_binsPerPixel*m_fftBinWidth);
+}
+
+void CPlotter::SetRunningState(bool running)              //SetRunningState()
+{
+  m_Running = running;
+}
+
+void CPlotter::setPlotZero(int plotZero)                  //setPlotZero()
+{
+  m_plotZero=plotZero;
+}
+
+int CPlotter::getPlotZero()                               //getPlotZero()
+{
+  return m_plotZero;
+}
+
+void CPlotter::setPlotGain(int plotGain)                  //setPlotGain()
+{
+  m_plotGain=plotGain;
+}
+
+int CPlotter::getPlotGain()                               //getPlotGain()
+{
+  return m_plotGain;
+}
+
+void CPlotter::SetStartFreq(quint64 f)                    //SetStartFreq()
+{
+  m_StartFreq=f;
+//    resizeEvent(NULL);
+  DrawOverlay();
+}
+
+qint64 CPlotter::startFreq()                              //startFreq()
+{
+  return m_StartFreq;
+}
+
+int CPlotter::plotWidth(){return m_WaterfallPixmap.width();}
+void CPlotter::UpdateOverlay() {DrawOverlay();}
+void CPlotter::setDataFromDisk(bool b) {m_dataFromDisk=b;}
+
+void CPlotter::setRxRange(int fMin)
+{
+  m_fMin=fMin;
+}
+
+void CPlotter::setBinsPerPixel(int n)                       // set nbpp
+{
+  m_binsPerPixel = n;
+  DrawOverlay();                         //Redraw scales and ticks
+  update();                              //trigger a new paintEvent}
+}
+
+int CPlotter::binsPerPixel()                                // get nbpp
+{
+  return m_binsPerPixel;
+}
+
+void CPlotter::setRxFreq(int x, bool bf)                       //setRxFreq()
+{
+  if(bf) {
+    m_rxFreq=x;         // x is freq in Hz
+    m_xClick=XfromFreq(m_rxFreq);
+  } else {
+    if(x<0) x=0;      // x is pixel number
+    if(x>m_Size.width()) x=m_Size.width();
+    m_rxFreq=int(FreqfromX(x)+0.5);
+    m_xClick=x;
+  }
+  emit setFreq1(m_rxFreq,m_txFreq);
+  DrawOverlay();
+  update();
+}
+
+int CPlotter::rxFreq() {return m_rxFreq;}                //get rxFreq
+
+void CPlotter::mousePressEvent(QMouseEvent *event)       //mousePressEvent
+{
+  int x=event->x();
+  setRxFreq(x,false);                               // Wideband waterfall
+  bool ctrl = (event->modifiers() & Qt::ControlModifier);
+  int n=1;
+  if(ctrl) n+=100;
+  emit freezeDecode1(n);
+  if(ctrl or m_lockTxFreq) setTxFreq(m_rxFreq);
+}
+
+void CPlotter::mouseDoubleClickEvent(QMouseEvent *event)  //mouse2click
+{
+//  int x=event->x();
+//  setRxFreq(x,false);
+  bool ctrl = (event->modifiers() & Qt::ControlModifier);
+  int n=2;
+  if(ctrl) n+=100;
+  emit freezeDecode1(n);
+}
+
+void CPlotter::setNSpan(int n)                                  //setNSpan()
+{
+  m_nSpan=n;
+}
+
+void CPlotter::setPalette(QString palette)                      //setPalette()
+{
+  if(palette=="Linrad") {
+    float twopi=6.2831853;
+    float r,g,b,phi,x;
+    for(int i=0; i<256; i++) {
+      r=0.0;
+      if(i>105 and i<=198) {
+        phi=(twopi/4.0) * (i-105.0)/(198.0-105.0);
+        r=sin(phi);
+      } else if(i>=198) {
+          r=1.0;
+      }
+
+      g=0.0;
+      if(i>35 and i<198) {
+        phi=(twopi/4.0) * (i-35.0)/(122.5-35.0);
+        g=0.625*sin(phi);
+      } else if(i>=198) {
+        x=(i-186.0);
+        g=-0.014 + 0.0144*x -0.00007*x*x +0.000002*x*x*x;
+        if(g>1.0) g=1.0;
+      }
+
+      b=0.0;
+      if(i<=117) {
+        phi=(twopi/2.0) * i/117.0;
+        b=0.4531*sin(phi);
+      } else if(i>186) {
+        x=(i-186.0);
+        b=-0.014 + 0.0144*x -0.00007*x*x +0.000002*x*x*x;
+        if(b>1.0) b=1.0;
+      }
+      m_ColorTbl[i].setRgb(int(255.0*r),int(255.0*g),int(255.0*b));
+    }
+    m_ColorTbl[255].setRgb(255,255,100);
+
+  }
+
+  if(palette=="CuteSDR") {
+      for( int i=0; i<256; i++) {
+      if( (i<43) )
+        m_ColorTbl[i].setRgb( 0,0, 255*(i)/43);
+      if( (i>=43) && (i<87) )
+        m_ColorTbl[i].setRgb( 0, 255*(i-43)/43, 255 );
+      if( (i>=87) && (i<120) )
+        m_ColorTbl[i].setRgb( 0,255, 255-(255*(i-87)/32));
+      if( (i>=120) && (i<154) )
+        m_ColorTbl[i].setRgb( (255*(i-120)/33), 255, 0);
+      if( (i>=154) && (i<217) )
+        m_ColorTbl[i].setRgb( 255, 255 - (255*(i-154)/62), 0);
+      if( (i>=217)  )
+        m_ColorTbl[i].setRgb( 255, 0, 128*(i-217)/38);
+    }
+    m_ColorTbl[255].setRgb(255,255,100);
+  }
+
+  if(palette=="Blue") {
+    FILE* fp=fopen("blue.dat","r");
+    int n,r,g,b;
+    float xr,xg,xb;
+    for(int i=0; i<256; i++) {
+      int nn=fscanf(fp,"%d%f%f%f",&n,&xr,&xg,&xb);
+      r=255.0*xr + 0.5;
+      g=255.0*xg + 0.5;
+      b=255.0*xb + 0.5;
+      m_ColorTbl[i].setRgb(r,g,b);
+      if(nn==-999999) i++;                  //Silence compiler warning
+    }
+  }
+
+  if(palette=="AFMHot") {
+    FILE* fp=fopen("afmhot.dat","r");
+    int n,r,g,b;
+    float xr,xg,xb;
+    for(int i=0; i<256; i++) {
+      int nn=fscanf(fp,"%d%f%f%f",&n,&xr,&xg,&xb);
+      r=255.0*xr + 0.5;
+      g=255.0*xg + 0.5;
+      b=255.0*xb + 0.5;
+      m_ColorTbl[i].setRgb(r,g,b);
+      if(nn==-999999) i++;                  //Silence compiler warning
+    }
+  }
+
+}
+
+double CPlotter::fGreen()
+{
+  return m_fGreen;
+}
+
+void CPlotter::setNsps(int ntrperiod, int nsps)                                  //setNSpan()
+{
+  m_TRperiod=ntrperiod;
+  m_nsps=nsps;
+  m_fftBinWidth=1500.0/2048.0;
+  if(m_nsps==15360)  m_fftBinWidth=1500.0/2048.0;
+  if(m_nsps==40960)  m_fftBinWidth=1500.0/6144.0;
+  if(m_nsps==82944)  m_fftBinWidth=1500.0/12288.0;
+  if(m_nsps==252000) m_fftBinWidth=1500.0/32768.0;
+  DrawOverlay();                         //Redraw scales and ticks
+  update();                              //trigger a new paintEvent}
+}
+
+void CPlotter::setTxFreq(int n)                                 //setTol()
+{
+  m_txFreq=n;
+  emit setFreq1(m_rxFreq,m_txFreq);
+  DrawOverlay();
+  update();
+}
+
+void CPlotter::setMode(QString mode)
+{
+  m_mode=mode;
+}
+
+void CPlotter::setModeTx(QString modeTx)
+{
+  m_modeTx=modeTx;
+}
+
+int CPlotter::getFmax()
+{
+  return m_fMax;
+}
+
+void CPlotter::setDialFreq(double d)
+{
+  m_dialFreq=d;
+  DrawOverlay();
+  update();
+}
diff --git a/plotter.h b/plotter.h
new file mode 100644
index 0000000..b491cf9
--- /dev/null
+++ b/plotter.h
@@ -0,0 +1,139 @@
+///////////////////////////////////////////////////////////////////////////
+// Some code in this file and accompanying files is based on work by
+// Moe Wheatley, AE4Y, released under the "Simplified BSD License".
+// For more details see the accompanying file LICENSE_WHEATLEY.TXT
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef PLOTTER_H
+#define PLOTTER_H
+
+#ifdef QT5
+#include <QtWidgets>
+#else
+#include <QtGui>
+#endif
+#include <QFrame>
+#include <QImage>
+#include <cstring>
+#include "commons.h"
+
+#define VERT_DIVS 7	//specify grid screen divisions
+#define HORZ_DIVS 20
+
+class CPlotter : public QFrame
+{
+  Q_OBJECT
+public:
+  explicit CPlotter(QWidget *parent = 0);
+  ~CPlotter();
+
+  QSize minimumSizeHint() const;
+  QSize sizeHint() const;
+  QColor  m_ColorTbl[256];
+
+  bool    m_bCurrent;
+  bool    m_bCumulative;
+  bool    m_lockTxFreq;
+
+  float   m_fSpan;
+
+  qint32  m_plotZero;
+  qint32  m_plotGain;
+  qint32  m_nSpan;
+  qint32  m_binsPerPixel;
+  qint32  m_w;
+
+  void draw(float sw[], int i0);		//Update the waterfall
+  void SetRunningState(bool running);
+  void setPlotZero(int plotZero);
+  int  getPlotZero();
+  void setPlotGain(int plotGain);
+  int  getPlotGain();
+  void SetStartFreq(quint64 f);
+  qint64 startFreq();
+  int  plotWidth();
+  void setNSpan(int n);
+  void UpdateOverlay();
+  void setDataFromDisk(bool b);
+  void setRxRange(int fMin);
+  void setBinsPerPixel(int n);
+  int  binsPerPixel();
+  void setRxFreq(int n, bool bf);
+  void DrawOverlay();
+  int  rxFreq();
+  void setPalette(QString palette);
+  void setFsample(int n);
+  void setNsps(int ntrperiod, int nsps);
+  void setTxFreq(int n);
+  void setMode(QString mode);
+  void setModeTx(QString modeTx);
+  double fGreen();
+  void SetPercent2DScreen(int percent){m_Percent2DScreen=percent;}
+  int getFmax();
+  void setDialFreq(double d);
+
+signals:
+  void freezeDecode1(int n);
+  void setFreq1(int rxFreq, int txFreq);
+
+protected:
+  //re-implemented widget event handlers
+  void paintEvent(QPaintEvent *event);
+  void resizeEvent(QResizeEvent* event);
+
+private:
+
+  void MakeFrequencyStrs();
+  void UTCstr();
+  int XfromFreq(float f);
+  float FreqfromX(int x);
+  qint64 RoundFreq(qint64 freq, int resolution);
+
+  QPixmap m_WaterfallPixmap;
+  QPixmap m_2DPixmap;
+  QPixmap m_ScalePixmap;
+  QPixmap m_OverlayPixmap;
+//  QPixmap m_LowerScalePixmap;
+  QSize   m_Size;
+  QString m_Str;
+  QString m_HDivText[483];
+  QString m_mode;
+  QString m_modeTx;
+
+  bool    m_Running;
+  bool    m_paintEventBusy;
+  bool    m_dataFromDisk;
+
+  double  m_fGreen;
+  double  m_fftBinWidth;
+  double  m_dialFreq;
+
+  qint64  m_StartFreq;
+
+  qint32  m_dBStepSize;
+  qint32  m_FreqUnits;
+  qint32  m_hdivs;
+  qint32  m_line;
+  qint32  m_fSample;
+  qint32  m_i0;
+  qint32  m_xClick;
+  qint32  m_freqPerDiv;
+  qint32  m_nsps;
+  qint32  m_Percent2DScreen;
+  qint32  m_h;
+  qint32  m_h1;
+  qint32  m_h2;
+  qint32  m_TRperiod;
+  qint32  m_rxFreq;
+  qint32  m_txFreq;
+  qint32  m_fMin;
+  qint32  m_fMax;
+
+  char    m_sutc[6];
+
+private slots:
+  void mousePressEvent(QMouseEvent *event);
+  void mouseDoubleClickEvent(QMouseEvent *event);
+};
+
+#endif // PLOTTER_H
diff --git a/psk_reporter.cpp b/psk_reporter.cpp
new file mode 100644
index 0000000..6856d17
--- /dev/null
+++ b/psk_reporter.cpp
@@ -0,0 +1,104 @@
+// KISS Interface for posting spots to PSK Reporter web site
+// Implemented by Edson Pereira PY2SDR
+//
+// Reports will be sent in batch mode every 5 minutes.
+
+#include "psk_reporter.h"
+
+PSK_Reporter::PSK_Reporter(QObject *parent) :
+    QObject(parent),
+    m_sequenceNumber(0)
+{
+    m_header_h = "000Allllttttttttssssssssiiiiiiii";
+
+    // We use 50E2 and 50E3 for link Id
+    m_rxInfoDescriptor_h = "0003002450E200030000"
+                           "8002FFFF0000768F" // 2. Rx Call
+                           "8004FFFF0000768F" // 4. Rx Grid
+                           "8008FFFF0000768F" // 8. Rx Soft
+                           "0000";
+
+    m_txInfoDescriptor_h = "0002003C50E30007"
+                           "8001FFFF0000768F" // 1. Tx Call
+                           "800500040000768F" // 5. Tx Freq
+                           "800600010000768F" // 6. Tx snr
+                           "800AFFFF0000768F" // 10. Tx Mode
+                           "8003FFFF0000768F" // 3. Tx Grid
+                           "800B00010000768F" // 11. Tx info src
+                           "00960004";        // Report time
+
+
+    qsrand(QDateTime::currentDateTime().toTime_t());
+    m_randomId_h = QString("%1").arg(qrand(),8,16,QChar('0'));
+
+    m_udpSocket = new QUdpSocket(this);
+
+    reportTimer = new QTimer(this);
+    connect(reportTimer, SIGNAL(timeout()), this, SLOT(sendReport()));
+}
+
+void PSK_Reporter::setLocalStation(QString call, QString gridSquare, QString programInfo)
+{
+  m_rxCall = call;
+  m_rxGrid = gridSquare;
+  m_progId = programInfo;
+  reportTimer->start(5*60*1000); // 5 minutes;
+}
+
+void PSK_Reporter::addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time )
+{
+    QHash<QString,QString> spot;
+    spot["call"] = call;
+    spot["grid"] = grid;
+    spot["snr"] = snr;
+    spot["freq"] = freq;
+    spot["mode"] = mode;
+    spot["time"] = time;
+    m_spotQueue.enqueue(spot);
+}
+
+void PSK_Reporter::sendReport()
+{
+    if (m_spotQueue.isEmpty())
+        return;
+
+    // Header
+    QString header_h = m_header_h;
+    header_h.replace("tttttttt", QString("%1").arg(QDateTime::currentDateTime().toTime_t(),8,16,QChar('0')));
+    header_h.replace("ssssssss", QString("%1").arg(++m_sequenceNumber,8,16,QChar('0')));
+    header_h.replace("iiiiiiii", m_randomId_h);
+
+    // Receiver information
+    QString rxInfoData_h = "50E2llll";
+    rxInfoData_h += QString("%1").arg(m_rxCall.length(),2,16,QChar('0')) + m_rxCall.toUtf8().toHex();
+    rxInfoData_h += QString("%1").arg(m_rxGrid.length(),2,16,QChar('0')) + m_rxGrid.toUtf8().toHex();
+    rxInfoData_h += QString("%1").arg(m_progId.length(),2,16,QChar('0')) + m_progId.toUtf8().toHex();
+    rxInfoData_h += "0000";
+    rxInfoData_h.replace("50E2llll", "50E2" + QString("%1").arg(rxInfoData_h.length()/2,4,16,QChar('0')));
+
+    // Sender information        
+    QString txInfoData_h = "50E3llll";
+    while (!m_spotQueue.isEmpty()) {
+        QHash<QString,QString> spot = m_spotQueue.dequeue();
+        txInfoData_h += QString("%1").arg(spot["call"].length(),2,16,QChar('0')) + spot["call"].toUtf8().toHex();
+        txInfoData_h += QString("%1").arg(spot["freq"].toLongLong(),8,16,QChar('0'));
+        txInfoData_h += QString("%1").arg(spot["snr"].toInt(),8,16,QChar('0')).right(2);
+        txInfoData_h += QString("%1").arg(spot["mode"].length(),2,16,QChar('0')) + spot["mode"].toUtf8().toHex();
+        txInfoData_h += QString("%1").arg(spot["grid"].length(),2,16,QChar('0')) + spot["grid"].toUtf8().toHex();
+        txInfoData_h += QString("%1").arg(1,2,16,QChar('0')); // REPORTER_SOURCE_AUTOMATIC
+        txInfoData_h += QString("%1").arg(spot["time"].toInt(),8,16,QChar('0'));
+    }
+    txInfoData_h += "0000";
+    txInfoData_h.replace("50E3llll", "50E3" + QString("%1").arg(txInfoData_h.length()/2,4,16,QChar('0')));
+
+    // Build report
+    QString report_h = header_h + m_rxInfoDescriptor_h + m_txInfoDescriptor_h + rxInfoData_h + txInfoData_h;
+    report_h.replace("000Allll", "000A" + QString("%1").arg(report_h.length()/2,4,16,QChar('0')));
+    QByteArray report = QByteArray::fromHex(report_h.toUtf8());
+
+    // Get IP address for pskreporter.info and send report via UDP
+    QHostInfo info = QHostInfo::fromName("report.pskreporter.info");
+    m_udpSocket->writeDatagram(report,info.addresses().at(0),4739);
+}
+
+
diff --git a/psk_reporter.h b/psk_reporter.h
new file mode 100644
index 0000000..abadda1
--- /dev/null
+++ b/psk_reporter.h
@@ -0,0 +1,41 @@
+#ifndef PSK_REPORTER_H
+#define PSK_REPORTER_H
+
+#include <QtCore>
+#include <QUdpSocket>
+#include <QHostInfo>
+
+class PSK_Reporter : public QObject
+{
+    Q_OBJECT
+public:
+    explicit PSK_Reporter(QObject *parent = 0);
+    void setLocalStation(QString call, QString grid, QString programInfo);
+    void addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time);
+    
+signals:
+    
+public slots:
+    void sendReport();
+
+private:
+    QString m_header_h;
+    QString m_rxInfoDescriptor_h;
+    QString m_txInfoDescriptor_h;
+    QString m_randomId_h;
+    QString m_linkId_h;
+
+    QString m_rxCall;
+    QString m_rxGrid;
+    QString m_progId;
+
+    QQueue< QHash<QString,QString> > m_spotQueue;
+
+    QUdpSocket *m_udpSocket;
+
+    QTimer *reportTimer;
+
+    int m_sequenceNumber;
+};
+
+#endif // PSK_REPORTER_H
diff --git a/rigclass.cpp b/rigclass.cpp
new file mode 100644
index 0000000..3f61e03
--- /dev/null
+++ b/rigclass.cpp
@@ -0,0 +1,324 @@
+/**
+ * \file src/rigclass.cc
+ * \brief Ham Radio Control Libraries C++ interface
+ * \author Stephane Fillod
+ * \date 2001-2003
+ *
+ * Hamlib C++ interface is a frontend implementing wrapper functions.
+ */
+
+/**
+ *
+ *  Hamlib C++ bindings - main file
+ *  Copyright (c) 2001-2003 by Stephane Fillod
+ *
+ *
+ *   This library is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Lesser General Public
+ *   License as published by the Free Software Foundation; either
+ *   version 2.1 of the License, or (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public
+ *   License along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <hamlib/rig.h>
+#include "rigclass.h"
+#include <QDebug>
+#include <QHostAddress>
+
+static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg);
+
+static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg)
+{
+  if (!rig || !rig->state.obj)
+    return -RIG_EINVAL;
+
+/* assert rig == ((Rig*)rig->state.obj).theRig */
+  return ((Rig*)rig->state.obj)->FreqEvent(vfo, freq, arg);
+}
+
+Rig::Rig()
+{
+  rig_set_debug_level( RIG_DEBUG_WARN);
+}
+
+Rig::~Rig() {
+  theRig->state.obj = NULL;
+  rig_cleanup(theRig);
+  caps = NULL;
+}
+
+int Rig::init(rig_model_t rig_model)
+{
+    int initOk;
+
+    theRig = rig_init(rig_model);
+    if (!theRig)
+        initOk = false;
+    else
+        initOk = true;
+
+    caps = theRig->caps;
+    theRig->callbacks.freq_event = &hamlibpp_freq_event;
+    theRig->state.obj = (rig_ptr_t)this;
+
+    return initOk;
+}
+
+int Rig::open(int n) {
+  m_hrd=false;
+  m_cmndr=false;
+  if(n<9900) {
+    if(n==-99999) return -1;                      //Silence compiler warning
+    return rig_open(theRig);
+  }
+
+#ifdef WIN32	              // Ham radio Deluxe or Commander (Windows only)
+  if(n==9999) {
+    m_hrd=true;
+    bool bConnect=false;
+    bConnect = HRDInterfaceConnect(L"localhost",7809);
+    if(bConnect) {
+      const wchar_t* context=HRDInterfaceSendMessage(L"Get Context");
+      m_context="[" + QString::fromWCharArray (context,-1) + "] ";
+      HRDInterfaceFreeString(context);
+      return 0;
+    } else {
+      m_hrd=false;
+      return -1;
+    }
+  }
+  if(n==9998) {
+    if(socket->state()==QAbstractSocket::ConnectedState) {
+      socket->abort();
+    }
+
+    if(socket->state()==QAbstractSocket::UnconnectedState) {
+      socket->connectToHost(QHostAddress::LocalHost, 52002);
+      if(!socket->waitForConnected(1000)) {
+        return -1;
+      }
+    }
+    QString t;
+    t="<command:10>CmdGetFreq<parameters:0>";
+    QByteArray ba = t.toLocal8Bit();
+    const char* buf=ba.data();
+    socket->write(buf);
+    socket->waitForReadyRead(1000);
+    QByteArray reply=socket->read(128);
+    if(reply.indexOf("<CmdFreq:")==0) {
+      m_cmndr=true;
+      return 0;
+    }
+  }
+#endif
+  return -1;
+}
+
+int Rig::close(void) {
+#ifdef WIN32	// Ham Radio Deluxe only on Windows
+  if(m_hrd) {
+    HRDInterfaceDisconnect();
+    return 0;
+  } else if(m_cmndr) {
+    socket->close();
+    return 0;
+  } else
+#endif
+    {
+    return rig_close(theRig);
+  }
+}
+
+int Rig::setConf(const char *name, const char *val)
+{
+  return rig_set_conf(theRig, tokenLookup(name), val);
+}
+
+int Rig::setFreq(freq_t freq, vfo_t vfo) {
+#ifdef WIN32	// Ham Radio Deluxe (only on Windows)
+  if(m_hrd) {
+    QString t;
+    int nhz=(int)freq;
+    t=m_context + "Set Frequency-Hz " + QString::number(nhz);
+    const wchar_t* cmnd = (const wchar_t*) t.utf16();
+    const wchar_t* result=HRDInterfaceSendMessage(cmnd);
+    QString t2=QString::fromWCharArray (result,-1);
+    HRDInterfaceFreeString(result);
+    if(t2=="OK") {
+      return 0;
+    } else {
+      return -1;
+    }
+  } else if(m_cmndr) {
+    QString t;
+    double f=0.001*freq;
+    t.sprintf("<command:10>CmdSetFreq<parameters:23><xcvrfreq:10>%10.3f",f);
+    QByteArray ba = t.toLocal8Bit();
+    const char* buf=ba.data();
+    socket->write(buf);
+    socket->waitForBytesWritten(1000);
+    return 0;
+  } else
+#endif
+  {
+    return rig_set_freq(theRig, vfo, freq);
+  }
+}
+
+int Rig::setXit(shortfreq_t xit, vfo_t vfo)
+{
+  return rig_set_xit(theRig, vfo, xit);
+}
+
+int Rig::setVFO(vfo_t vfo)
+{
+  return rig_set_vfo(theRig, vfo);
+}
+
+vfo_t Rig::getVFO()
+{
+  vfo_t vfo;
+  rig_get_vfo(theRig, &vfo);
+  return vfo;
+}
+
+int Rig::setSplitFreq(freq_t tx_freq, vfo_t vfo) {
+#ifdef WIN32	// Ham Radio Deluxe only on Windows
+  if(m_hrd) {
+    QString t;
+    int nhz=(int)tx_freq;
+    t=m_context + "Set Frequency-Hz " + QString::number(nhz);
+    const wchar_t* cmnd = (const wchar_t*) t.utf16();
+    const wchar_t* result=HRDInterfaceSendMessage(cmnd);
+    QString t2=QString::fromWCharArray (result,-1);
+    HRDInterfaceFreeString(result);
+    if(t2=="OK") {
+      return 0;
+    } else {
+      return -1;
+    }
+  } else if(m_cmndr) {
+    QString t;
+    double f=0.001*tx_freq;
+    t.sprintf("<command:12>CmdSetTxFreq<parameters:23><xcvrfreq:10>%10.3f",f);
+    QByteArray ba = t.toLocal8Bit();
+    const char* buf=ba.data();
+    socket->write(buf);
+    socket->waitForBytesWritten(1000);
+    return 0;
+  } else
+#endif
+  {
+    return rig_set_split_freq(theRig, vfo, tx_freq);
+  }
+}
+
+freq_t Rig::getFreq(vfo_t vfo)
+{
+  freq_t freq;
+#ifdef WIN32	// Ham Radio Deluxe (only on Windows)
+  if(m_hrd) {
+    const wchar_t* cmnd = (const wchar_t*) (m_context+"Get Frequency").utf16();
+    const wchar_t* freqString=HRDInterfaceSendMessage(cmnd);
+    QString t2=QString::fromWCharArray (freqString,-1);
+    HRDInterfaceFreeString(freqString);
+    freq=t2.toDouble();
+    return freq;
+  } else if(m_cmndr) {
+    QString t;
+    t="<command:10>CmdGetFreq<parameters:0>";
+    QByteArray ba = t.toLocal8Bit();
+    const char* buf=ba.data();
+    socket->write(buf);
+    socket->waitForReadyRead(1000);
+    QByteArray reply=socket->read(128);
+    QString t2(reply);
+    if(t2.indexOf("<CmdFreq:")==0) {
+      int i1=t2.indexOf(">");
+      t2=t2.mid(i1+1).replace(",","");
+      freq=1000.0*t2.toDouble();
+      return freq;
+    } else {
+      return -1.0;
+    }
+  } else
+#endif
+  {
+    int iret=rig_get_freq(theRig, vfo, &freq);
+// iret should be 0.  Negative values mean rig_get_freq() failed.
+    if(iret<0) freq=-1.0;
+    return freq;
+  }
+}
+
+int Rig::setMode(rmode_t mode, pbwidth_t width, vfo_t vfo) {
+  return rig_set_mode(theRig, vfo, mode, width);
+}
+
+rmode_t Rig::getMode(pbwidth_t& width, vfo_t vfo) {
+  rmode_t mode;
+  rig_get_mode(theRig, vfo, &mode, &width);
+  return mode;
+}
+
+int Rig::setPTT(ptt_t ptt, vfo_t vfo)
+{
+#ifdef WIN32	// Ham Radio Deluxe only on Windows
+  if(m_hrd) {
+    wchar_t* cmnd;
+
+    if(ptt==0) {
+      cmnd = (wchar_t*) (m_context +
+                             "Set Button-Select TX 0").utf16();
+    } else {
+      cmnd = (wchar_t*) (m_context +
+                             "Set Button-Select TX 1").utf16();
+    }
+    const wchar_t* result=HRDInterfaceSendMessage(cmnd);
+    QString t2=QString::fromWCharArray (result,-1);
+    HRDInterfaceFreeString(result);
+    if(t2=="OK") {
+      return 0;
+    } else {
+      return -1;
+    }
+  } else if(m_cmndr) {
+    QString t;
+    if(ptt==0) t="<command:5>CmdRX<parameters:0>";
+    if(ptt>0) t="<command:5>CmdTX<parameters:0>";
+    QByteArray ba = t.toLocal8Bit();
+    const char* buf=ba.data();
+    socket->write(buf);
+    socket->waitForBytesWritten(1000);
+    return 0;
+  } else
+#endif
+    {
+    return rig_set_ptt(theRig, vfo, ptt);
+  }
+}
+
+ptt_t Rig::getPTT(vfo_t vfo)
+{
+  ptt_t ptt;
+  rig_get_ptt(theRig, vfo, &ptt);
+  return ptt;
+}
+
+token_t Rig::tokenLookup(const char *name)
+{
+  return rig_token_lookup(theRig, name);
+}
diff --git a/rigclass.h b/rigclass.h
new file mode 100644
index 0000000..9c933e7
--- /dev/null
+++ b/rigclass.h
@@ -0,0 +1,98 @@
+/*
+ *  Hamlib C++ bindings - API header
+ *  Copyright (c) 2001-2002 by Stephane Fillod
+ *
+ *
+ *   This library is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Lesser General Public
+ *   License as published by the Free Software Foundation; either
+ *   version 2.1 of the License, or (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public
+ *   License along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef _RIGCLASS_H
+#define _RIGCLASS_H 1
+
+#include <hamlib/rig.h>
+#include <iostream>
+#include <QString>
+#include <QTcpSocket>
+
+extern QTcpSocket* socket;
+
+class BACKEND_IMPEXP Rig {
+private:
+  RIG* theRig;  // Global ref. to the rig
+  bool m_hrd;
+  bool m_cmndr;
+  QString m_context;
+
+
+protected:
+public:
+  Rig();
+  virtual ~Rig();
+
+  const struct rig_caps *caps;
+
+  // Initialize rig
+  int init(rig_model_t rig_model);
+
+  // This method open the communication port to the rig
+  int open(int n);
+
+  // This method close the communication port to the rig
+  int close(void);
+
+  int setConf(const char *name, const char *val);
+  token_t tokenLookup(const char *name);
+
+  int setFreq(freq_t freq, vfo_t vfo = RIG_VFO_CURR);
+  freq_t getFreq(vfo_t vfo = RIG_VFO_CURR);
+  int setMode(rmode_t, pbwidth_t width = RIG_PASSBAND_NORMAL, vfo_t vfo = RIG_VFO_CURR);
+  rmode_t getMode(pbwidth_t&, vfo_t vfo = RIG_VFO_CURR);
+  int setVFO(vfo_t);
+  vfo_t getVFO();
+  int setXit(shortfreq_t xit, vfo_t vfo);
+  int setSplitFreq(freq_t tx_freq, vfo_t vfo = RIG_VFO_CURR);
+  int setPTT (ptt_t ptt, vfo_t vfo = RIG_VFO_CURR);
+  ptt_t getPTT (vfo_t vfo = RIG_VFO_CURR);
+
+  // callbacks available in your derived object
+  virtual int FreqEvent(vfo_t, freq_t, rig_ptr_t) const {
+		  return RIG_OK;
+  }
+  virtual int ModeEvent(vfo_t, rmode_t, pbwidth_t, rig_ptr_t) const {
+		  return RIG_OK;
+  }
+  virtual int VFOEvent(vfo_t, rig_ptr_t) const {
+		  return RIG_OK;
+  }
+  virtual int PTTEvent(vfo_t, ptt_t, rig_ptr_t) const {
+		  return RIG_OK;
+  }
+  virtual int DCDEvent(vfo_t, dcd_t, rig_ptr_t) const {
+		  return RIG_OK;
+  }
+};
+
+#ifdef WIN32
+extern "C" {
+  bool HRDInterfaceConnect(const wchar_t *host, const ushort);
+  void HRDInterfaceDisconnect();
+  bool HRDInterfaceIsConnected();
+  wchar_t* HRDInterfaceSendMessage(const wchar_t *msg);
+  void HRDInterfaceFreeString(const wchar_t *lstring);
+}
+#endif
+
+#endif	// _RIGCLASS_H
diff --git a/shortcuts.txt b/shortcuts.txt
new file mode 100644
index 0000000..821ec70
--- /dev/null
+++ b/shortcuts.txt
@@ -0,0 +1,26 @@
+F1	Online User's Guide
+Ctrl+F1	About WSJT-X
+F2	Open configuration window
+F3	Display keyboard shortcuts
+F4	Clear Dx Call and Dx Grid entries
+Alt+F4	Exit program
+F5	Display special mouse commands
+F6	Open next in directory
+F11	Move Rx frequency down 1 Hz
+Ctrl+F11     	Move Rx and Tx frequencies down 1 Hz
+F12	Move Rx frequency up 1 Hz
+Ctrl+F12     	Move Rx and Tx frequencies up 1 Hz
+Shift+F6     	Decode remaining files in directory
+Alt+D	Decode again at QSO frequency
+Shift+D	Full-bandwidth decode (both windows)
+Alt+E	Erase()
+Ctrl+F	Edit the free text message box
+Alt+G	Generate standard messages
+Alt+H	Halt Tx()
+Ctrl+L	Lookup callsign in database, generate standard messages
+Alt M	Monitor()
+Alt+N	Enable Tx()
+Alt+Q	Log QSO()
+Alt+S	Stop()
+Alt+T	Tune
+Alt+V	Save the most recently completed *.wav file
diff --git a/signalmeter.cpp b/signalmeter.cpp
new file mode 100644
index 0000000..537b900
--- /dev/null
+++ b/signalmeter.cpp
@@ -0,0 +1,53 @@
+// Simple bargraph dB meter
+// Implemented by Edson Pereira PY2SDR
+//
+// Limits and geometry are hardcded for now.
+
+#include "signalmeter.h"
+
+SignalMeter::SignalMeter(QWidget *parent) :
+    QWidget(parent)
+{
+    resize(parent->size());
+
+    m_meter = new MeterWidget(this);
+    m_meter->setGeometry(10, 10, 10, 120);
+
+    m_label = new QLabel(this);
+    m_label->setGeometry(10, 135, 20, 20);
+
+    QLabel *dbLabel = new QLabel(this);
+    dbLabel->setText("dB");
+    dbLabel->setGeometry(30, 135, 20, 20);
+}
+
+SignalMeter::~SignalMeter()
+{
+
+}
+
+void SignalMeter::paintEvent( QPaintEvent * )
+{
+    QPainter p;
+    p.begin(this);
+    p.drawLine(22, 10, 22, 130);
+
+    for ( int i = 0; i <= 60; i += 10 ) {
+        p.drawLine(22, i*2 + 10, 25, i*2 + 10);
+    }
+
+    for ( int i = 10; i < 60; i += 10 ) {
+        p.drawText(30, i*2 + 15, QString::number(60 - i));
+    }
+}
+
+void SignalMeter::setValue(int value)
+{
+    m_meter->setValue(value);
+    m_label->setText(QString::number(value));
+}
+
+void SignalMeter::resizeEvent(QResizeEvent *s)
+{
+    resize(s->size());
+}
diff --git a/signalmeter.h b/signalmeter.h
new file mode 100644
index 0000000..ea1aa62
--- /dev/null
+++ b/signalmeter.h
@@ -0,0 +1,32 @@
+#ifndef SIGNALMETER_H
+#define SIGNALMETER_H
+
+#include <QtGui>
+#include <QLabel>
+#include <meterwidget.h>
+
+class SignalMeter : public QWidget
+{
+    Q_OBJECT
+    
+public:
+    explicit SignalMeter(QWidget *parent = 0);
+    ~SignalMeter();
+
+public slots:
+    void setValue(int value);
+
+private:
+    MeterWidget *m_meter;
+
+    QLabel *m_label;
+
+    int m_signal;
+    int m_sigPeak;
+
+protected:
+    void paintEvent( QPaintEvent * );
+    void resizeEvent(QResizeEvent *s);
+};
+
+#endif // SIGNALMETER_H
diff --git a/sleep.h b/sleep.h
new file mode 100644
index 0000000..c11188c
--- /dev/null
+++ b/sleep.h
@@ -0,0 +1,16 @@
+#ifndef SLEEP_H
+#define SLEEP_H
+#include <qthread.h>
+
+class Sleep : public QThread
+{
+public:
+  static void msleep(int ms) {
+    QThread::msleep(ms);
+  }
+  static int idealThreadCount() {
+    return QThread::idealThreadCount();
+  }
+};
+
+#endif // SLEEP_H
diff --git a/soundin.cpp b/soundin.cpp
new file mode 100644
index 0000000..332e5d3
--- /dev/null
+++ b/soundin.cpp
@@ -0,0 +1,208 @@
+#include "soundin.h"
+#include <stdexcept>
+
+#define FRAMES_PER_BUFFER 1024
+//#define NSMAX 1365
+#define NSMAX 6827
+#define NTMAX 120
+
+extern "C" {
+#include <portaudio.h>
+extern struct {
+  float ss[184*NSMAX];              //This is "common/jt9com/..." in fortran
+  float savg[NSMAX];
+//  float c0[2*NTMAX*1500];
+  short int d2[NTMAX*12000];
+  int nutc;                         //UTC as integer, HHMM
+  int ndiskdat;                     //1 ==> data read from *.wav file
+  int ntrperiod;                    //TR period (seconds)
+  int mousefqso;                    //User-selected QSO freq (kHz)
+  int newdat;                       //1 ==> new data, must do long FFT
+  int npts8;                        //npts in c0() array
+  int nfa;                          //Low decode limit (Hz)
+  int nfb;                          //High decode limit (Hz)
+  int ntol;                         //+/- decoding range around fQSO (Hz)
+  int kin;
+  int nzhsym;
+  int nsave;
+  int nagain;
+  int ndepth;
+  int ntxmode;
+  int nmode;
+  char datetime[20];
+} jt9com_;
+}
+
+typedef struct
+{
+  int kin;          //Parameters sent to/from the portaudio callback function
+  int ncall;
+  bool bzero;
+  bool monitoring;
+} paUserData;
+
+//--------------------------------------------------------------- a2dCallback
+extern "C" int a2dCallback( const void *inputBuffer, void *outputBuffer,
+                         unsigned long framesToProcess,
+                         const PaStreamCallbackTimeInfo* timeInfo,
+                         PaStreamCallbackFlags statusFlags,
+                         void *userData )
+
+// This routine called by the PortAudio engine when samples are available.
+// It may be called at interrupt level, so don't do anything
+// that could mess up the system like calling malloc() or free().
+
+{
+  paUserData *udata=(paUserData*)userData;
+  (void) outputBuffer;          //Prevent unused variable warnings.
+  (void) timeInfo;
+  (void) userData;
+  int nbytes,k;
+
+  udata->ncall++;
+  if( (statusFlags&paInputOverflow) != 0) {
+    qDebug() << "Input Overflow in a2dCallback";
+  }
+  if(udata->bzero) {           //Start of a new Rx sequence
+    udata->kin=0;              //Reset buffer pointer
+    udata->bzero=false;
+  }
+
+  nbytes=2*framesToProcess;        //Bytes per frame
+  k=udata->kin;
+  if(udata->monitoring) {
+    memcpy(&jt9com_.d2[k],inputBuffer,nbytes);      //Copy all samples to d2
+  }
+  udata->kin += framesToProcess;
+  jt9com_.kin=udata->kin;
+
+  return paContinue;
+}
+
+void SoundInThread::run()                           //SoundInThread::run()
+{
+  quitExecution = false;
+
+//---------------------------------------------------- Soundcard Setup
+  PaError paerr;
+  PaStreamParameters inParam;
+  PaStream *inStream;
+  paUserData udata;
+
+  udata.kin=0;                              //Buffer pointer
+  udata.ncall=0;                            //Number of callbacks
+  udata.bzero=false;                        //Flag to request reset of kin
+  udata.monitoring=m_monitoring;
+
+  inParam.device=m_nDevIn;                  //### Input Device Number ###
+  inParam.channelCount=1;                   //Number of analog channels
+  inParam.sampleFormat=paInt16;             //Get i*2 from Portaudio
+  inParam.suggestedLatency=0.05;
+  inParam.hostApiSpecificStreamInfo=NULL;
+
+  paerr=Pa_IsFormatSupported(&inParam,NULL,12000.0);
+  if(paerr<0) {
+    emit error("PortAudio says requested soundcard format not supported.");
+//    return;
+  }
+  qDebug() << "";
+  paerr=Pa_OpenStream(&inStream,            //Input stream
+        &inParam,                           //Input parameters
+        NULL,                               //No output parameters
+        12000.0,                            //Sample rate
+        FRAMES_PER_BUFFER,                  //Frames per buffer
+//        paClipOff+paDitherOff,            //No clipping or dithering
+        paClipOff,                          //No clipping
+        a2dCallback,                        //Input callback routine
+        &udata);                            //userdata
+
+  paerr=Pa_StartStream(inStream);
+  if(paerr<0) {
+    emit error("Failed to start audio input stream.");
+    return;
+  }
+
+  bool qe = quitExecution;
+  static int ntr0=99;
+  int k=0;
+  int nsec;
+  int ntr;
+  int nBusy=0;
+  int nstep0=0;
+  int nsps0=0;
+  qint64 ms0 = QDateTime::currentMSecsSinceEpoch();
+
+//---------------------------------------------- Soundcard input loop
+  while (!qe) {
+    qe = quitExecution;
+    if (qe) break;
+    udata.monitoring=m_monitoring;
+    qint64 ms = QDateTime::currentMSecsSinceEpoch();
+    m_SamFacIn=1.0;
+    if(udata.ncall>100) {
+      m_SamFacIn=udata.ncall*FRAMES_PER_BUFFER*1000.0/(12000.0*(ms-ms0-50));
+    }
+    ms=ms % 86400000;
+    nsec = ms/1000;             // Time according to this computer
+    ntr = nsec % m_TRperiod;
+
+// Reset buffer pointer and symbol number at start of minute
+    if(ntr < ntr0 or !m_monitoring or m_nsps!=nsps0) {
+      nstep0=0;
+      nsps0=m_nsps;
+      udata.bzero=true;
+    }
+    k=udata.kin;
+    if(m_monitoring) {
+      int kstep=m_nsps/2;
+//      m_step=k/kstep;
+      m_step=(k-1)/kstep;
+      if(m_step != nstep0) {
+        if(m_dataSinkBusy) {
+          nBusy++;
+        } else {
+//          m_dataSinkBusy=true;
+//          emit readyForFFT(k);         //Signal to compute new FFTs
+          emit readyForFFT(k-1);         //Signal to compute new FFTs
+        }
+        nstep0=m_step;
+      }
+    }
+    msleep(100);
+    ntr0=ntr;
+  }
+  Pa_StopStream(inStream);
+  Pa_CloseStream(inStream);
+}
+
+void SoundInThread::setInputDevice(int n)                  //setInputDevice()
+{
+  if (isRunning()) return;
+  this->m_nDevIn=n;
+}
+
+void SoundInThread::quit()                                       //quit()
+{
+  quitExecution = true;
+}
+
+void SoundInThread::setMonitoring(bool b)                    //setMonitoring()
+{
+  m_monitoring = b;
+}
+
+void SoundInThread::setPeriod(int ntrperiod, int nsps)
+{
+  m_TRperiod=ntrperiod;
+  m_nsps=nsps;
+}
+
+int SoundInThread::mstep()
+{
+  return m_step;
+}
+
+double SoundInThread::samFacIn()
+{
+  return m_SamFacIn;
+}
diff --git a/soundin.h b/soundin.h
new file mode 100644
index 0000000..955f08d
--- /dev/null
+++ b/soundin.h
@@ -0,0 +1,50 @@
+#ifndef SOUNDIN_H
+#define SOUNDIN_H
+
+#include <QtCore>
+#include <QDebug>
+
+
+// Thread gets audio data from soundcard and signals when a buffer of
+// specified size is available.
+class SoundInThread : public QThread
+{
+  Q_OBJECT
+  bool quitExecution;           // if true, thread exits gracefully
+
+protected:
+  virtual void run();
+
+public:
+  bool m_dataSinkBusy;
+
+  SoundInThread():
+    quitExecution(false),
+    m_dataSinkBusy(false)
+  {
+  }
+
+  void setInputDevice(qint32 n);
+  void setMonitoring(bool b);
+  void setPeriod(int ntrperiod, int nsps);
+  int  mstep();
+  double samFacIn();
+
+signals:
+  void readyForFFT(int k);
+  void error(const QString& message);
+  void status(const QString& message);
+
+public slots:
+  void quit();
+
+private:
+  double m_SamFacIn;                    //(Input sample rate)/12000.0
+  qint32 m_step;
+  qint32 m_nDevIn;
+  qint32 m_TRperiod;
+  qint32 m_TRperiod0;
+  qint32 m_nsps;
+  bool   m_monitoring;
+};
+#endif // SOUNDIN_H
diff --git a/soundout.cpp b/soundout.cpp
new file mode 100644
index 0000000..8693237
--- /dev/null
+++ b/soundout.cpp
@@ -0,0 +1,270 @@
+#include "soundout.h"
+
+//#define FRAMES_PER_BUFFER 1024
+
+extern "C" {
+#include <portaudio.h>
+}
+
+extern float gran();                  //Noise generator (for tests only)
+extern int itone[126];                //Audio tones for all Tx symbols
+extern int icw[250];                  //Dits for CW ID
+extern int outBufSize;
+extern bool btxok;
+extern bool btxMute;
+extern double outputLatency;
+
+typedef struct   //Parameters sent to or received from callback function
+{
+  double txsnrdb;
+  double dnsps;
+  int    ntrperiod;
+  int    ntxfreq;
+  int    xit;
+  int    ncall;
+  int    nsym;
+  bool   txMute;
+  bool   bRestart;
+  bool   btune;
+} paUserData;
+
+//--------------------------------------------------------------- d2aCallback
+extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesToProcess,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+  paUserData *udata=(paUserData*)userData;
+  short *wptr = (short*)outputBuffer;
+
+  static double twopi=2.0*3.141592653589793238462;
+  static double baud;
+  static double phi=0.0;
+  static double dphi;
+  static double freq;
+  static double snr;
+  static double fac;
+  static double amp;
+  static int ic=0,j=0;
+  static int isym0=-999;
+  static short int i2;
+  int isym,nspd;
+
+  udata->ncall++;
+  if(udata->bRestart) {
+ // Time according to this computer
+    qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
+    int mstr = ms % (1000*udata->ntrperiod );
+    if(mstr<1000) return paContinue;
+    ic=(mstr-1000)*48;
+    udata->bRestart=false;
+    srand(mstr);                                //Initialize random seed
+  }
+  isym=ic/(4.0*udata->dnsps);                   //Actual fsample=48000
+  if(udata->btune) isym=0;                      //If tuning, send pure tone
+  if(udata->txsnrdb < 0.0) {
+    snr=pow(10.0,0.05*(udata->txsnrdb-6.0));
+    fac=3000.0;
+    if(snr>1.0) fac=3000.0/snr;
+  }
+
+  if(isym>=udata->nsym and icw[0]>0) {              //Output the CW ID
+    freq=udata->ntxfreq - udata->xit;
+    dphi=twopi*freq/48000.0;
+
+//    float wpm=20.0;
+//    int nspd=1.2*48000.0/wpm;
+//    nspd=3072;                           //18.75 WPM
+    nspd=2048 + 512;                       //22.5 WPM
+    int ic0=udata->nsym*4*udata->dnsps;
+    for(uint i=0 ; i<framesToProcess; i++ )  {
+      phi += dphi;
+      if(phi>twopi) phi -= twopi;
+      i2=32767.0*sin(phi);
+      j=(ic-ic0)/nspd + 1;
+      if(icw[j]==0) i2=0;
+      if(udata->txsnrdb < 0.0) {
+        int i4=fac*(gran() + i2*snr/32768.0);
+        if(i4>32767) i4=32767;
+        if(i4<-32767) i4=-32767;
+        i2=i4;
+      }
+      if(!btxok or btxMute)  i2=0;
+      *wptr++ = i2;                   //left
+#ifdef UNIX
+      *wptr++ = i2;                   //right
+#endif
+      ic++;
+    }
+    if(j>icw[0]) return paComplete;
+    if(statusFlags==999999 and timeInfo==NULL and
+       inputBuffer==NULL) return paContinue;   //Silence compiler warning:
+    return paContinue;
+  }
+
+  baud=12000.0/udata->dnsps;
+  amp=32767.0;
+  int i0=(udata->nsym-0.017)*4.0*udata->dnsps;
+  int i1=udata->nsym*4.0*udata->dnsps;
+  if(udata->btune) {                           //If tuning, no ramp down
+    i0=999*udata->dnsps;
+    i1=i0;
+  }
+  for(uint i=0 ; i<framesToProcess; i++ )  {
+    isym=ic/(4.0*udata->dnsps);                   //Actual fsample=48000
+    if(udata->btune) isym=0;                      //If tuning, send pure tone
+    if(isym!=isym0) {
+      freq=udata->ntxfreq + itone[isym]*baud - udata->xit;
+      dphi=twopi*freq/48000.0;
+      isym0=isym;
+    }
+    phi += dphi;
+    if(phi>twopi) phi -= twopi;
+    if(ic>i0) amp=0.98*amp;
+    if(ic>i1) amp=0.0;
+    i2=amp*sin(phi);
+    if(udata->txsnrdb < 0.0) {
+      int i4=fac*(gran() + i2*snr/32768.0);
+      if(i4>32767) i4=32767;
+      if(i4<-32767) i4=-32767;
+      i2=i4;
+    }
+    if(!btxok or btxMute)  i2=0;
+    *wptr++ = i2;                   //left
+#ifdef UNIX
+    *wptr++ = i2;                   //right
+#endif
+    ic++;
+  }
+  if(amp==0.0) {
+    if(icw[0]==0) return paComplete;
+    phi=0.0;
+  }
+  return paContinue;
+}
+
+void SoundOutThread::run()
+{
+  PaError paerr;
+  PaStreamParameters outParam;
+  PaStream *outStream;
+  paUserData udata;
+  quitExecution = false;
+
+  outParam.device=m_nDevOut;                 //Output device number
+  outParam.channelCount=1;                   //Number of analog channels
+#ifdef UNIX
+  outParam.channelCount=2;                   //Number of analog channels
+#endif
+  outParam.sampleFormat=paInt16;             //Send short ints to PortAudio
+  outParam.suggestedLatency=0.05;
+  outParam.hostApiSpecificStreamInfo=NULL;
+
+  paerr=Pa_IsFormatSupported(NULL,&outParam,48000.0);
+  if(paerr<0) {
+    qDebug() << "PortAudio says requested output format not supported.";
+    qDebug() << paerr << m_nDevOut;
+    return;
+  }
+
+  udata.txsnrdb=99.0;
+  udata.dnsps=m_nsps;
+  udata.nsym=85;
+  if(m_modeTx=="JT65") {
+    udata.dnsps=4096.0*12000.0/11025.0;
+    udata.nsym=126;
+  }
+  udata.ntrperiod=m_TRperiod;
+  udata.ntxfreq=m_txFreq;
+  udata.xit=m_xit;
+  udata.ncall=0;
+  udata.txMute=m_txMute;
+  udata.bRestart=true;
+  udata.btune=m_tune;
+
+  paerr=Pa_OpenStream(&outStream,           //Output stream
+        NULL,                               //No input parameters
+        &outParam,                          //Output parameters
+        48000.0,                            //Sample rate
+        outBufSize,                         //Frames per buffer
+        paClipOff,                          //No clipping
+        d2aCallback,                        //output callbeck routine
+        &udata);                            //userdata
+
+  paerr=Pa_StartStream(outStream);
+  if(paerr<0) {
+    qDebug() << "Failed to start audio output stream.";
+    return;
+  }
+  const PaStreamInfo* p=Pa_GetStreamInfo(outStream);
+  outputLatency = p->outputLatency;
+  bool qe = quitExecution;
+  qint64 ms0 = QDateTime::currentMSecsSinceEpoch();
+
+//---------------------------------------------- Soundcard output loop
+  while (!qe) {
+    qe = quitExecution;
+    if (qe) break;
+
+    udata.txsnrdb=m_txsnrdb;
+    udata.dnsps=m_nsps;
+    udata.nsym=85;
+    if(m_modeTx=="JT65") {
+      udata.dnsps=4096.0*12000.0/11025.0;
+      udata.nsym=126;
+    }
+    udata.ntrperiod=m_TRperiod;
+    udata.ntxfreq=m_txFreq;
+    udata.xit=m_xit;
+    udata.txMute=m_txMute;
+    udata.btune=m_tune;
+
+    m_SamFacOut=1.0;
+    if(udata.ncall>400) {
+      qint64 ms = QDateTime::currentMSecsSinceEpoch();
+      m_SamFacOut=udata.ncall*outBufSize*1000.0/(48000.0*(ms-ms0-50));
+    }
+    msleep(100);
+  }
+  Pa_StopStream(outStream);
+  Pa_CloseStream(outStream);
+}
+
+void SoundOutThread::setOutputDevice(int n)      //setOutputDevice()
+{
+  if (isRunning()) return;
+  this->m_nDevOut=n;
+}
+
+void SoundOutThread::setPeriod(int ntrperiod, int nsps)
+{
+  m_TRperiod=ntrperiod;
+  m_nsps=nsps;
+}
+
+void SoundOutThread::setTxFreq(int n)
+{
+  m_txFreq=n;
+}
+
+void SoundOutThread::setXIT(int n)
+{
+  m_xit=n;
+
+}
+
+void SoundOutThread::setTxSNR(double snr)
+{
+  m_txsnrdb=snr;
+}
+
+void SoundOutThread::setTune(bool b)
+{
+  m_tune=b;
+}
+
+double SoundOutThread::samFacOut()
+{
+  return m_SamFacOut;
+}
diff --git a/soundout.h b/soundout.h
new file mode 100644
index 0000000..a289afc
--- /dev/null
+++ b/soundout.h
@@ -0,0 +1,53 @@
+#ifndef SOUNDOUT_H
+#define SOUNDOUT_H
+#include <QtCore>
+#include <QDebug>
+
+// An instance of this thread sends audio data to a specified soundcard.
+// Output can be muted while underway, preserving waveform timing when
+// transmission is resumed.
+
+class SoundOutThread : public QThread
+{
+  Q_OBJECT
+
+protected:
+  virtual void run();
+
+public:
+// Constructs (but does not start) a SoundOutThread
+  SoundOutThread()
+    :   quitExecution(false)           // Initialize some private members
+    ,   m_txOK(false)
+    ,   m_txMute(false)
+  {
+  }
+
+public:
+  void setOutputDevice(qint32 n);
+  void setPeriod(int ntrperiod, int nsps);
+  void setTxFreq(int n);
+  void setXIT(int n);
+  void setTxSNR(double snr);
+  void setTune(bool b);
+  double samFacOut();
+  bool quitExecution;           //If true, thread exits gracefully
+  QString m_modeTx;
+
+// Private members
+private:
+  double  m_txsnrdb;            //if < 0, add noise to Tx audio
+  double  m_SamFacOut;          //(Output sample rate)/48000.0
+
+  qint32  m_nDevOut;            //Output device number
+  qint32  m_TRperiod;           //T/R period (s)
+  qint32  m_nsps;               //Samples per symbol (at 12000 Hz)
+  qint32  m_txFreq;
+  qint32  m_xit;
+
+  bool    m_txOK;               //Enable Tx audio
+  bool    m_txMute;             //Mute temporarily
+  bool    m_tune;
+};
+
+#endif
diff --git a/ss.bat b/ss.bat
new file mode 100644
index 0000000..37f669a
--- /dev/null
+++ b/ss.bat
@@ -0,0 +1 @@
+svn status | grep -v '?'
diff --git a/sss.bat b/sss.bat
new file mode 100644
index 0000000..7b51c8c
--- /dev/null
+++ b/sss.bat
@@ -0,0 +1 @@
+svn status
diff --git a/widegraph.cpp b/widegraph.cpp
new file mode 100644
index 0000000..3efa1f2
--- /dev/null
+++ b/widegraph.cpp
@@ -0,0 +1,314 @@
+#include "widegraph.h"
+#include "ui_widegraph.h"
+#include "commons.h"
+
+WideGraph::WideGraph(QWidget *parent) :
+  QDialog(parent),
+  ui(new Ui::WideGraph)
+{
+  ui->setupUi(this);
+  this->setWindowFlags(Qt::Dialog);
+  this->installEventFilter(parent); //Installing the filter
+  ui->widePlot->setCursor(Qt::CrossCursor);
+  this->setMaximumWidth(2048);
+  this->setMaximumHeight(880);
+  ui->widePlot->setMaximumHeight(800);
+  ui->widePlot->m_bCurrent=false;
+
+  connect(ui->widePlot, SIGNAL(freezeDecode1(int)),this,
+          SLOT(wideFreezeDecode(int)));
+
+  connect(ui->widePlot, SIGNAL(setFreq1(int,int)),this,
+          SLOT(setFreq2(int,int)));
+
+  m_fMin=3000;
+  ui->fMinSpinBox->setValue(m_fMin);
+
+  //Restore user's settings
+  QString inifile(QApplication::applicationDirPath());
+  inifile += "/wsjtx.ini";
+  QSettings settings(inifile, QSettings::IniFormat);
+
+  settings.beginGroup("WideGraph");
+  ui->widePlot->setPlotZero(settings.value("PlotZero", 0).toInt());
+  ui->widePlot->setPlotGain(settings.value("PlotGain", 0).toInt());
+  ui->zeroSpinBox->setValue(ui->widePlot->getPlotZero());
+  ui->gainSpinBox->setValue(ui->widePlot->getPlotGain());
+  int n = settings.value("FreqSpan",2).toInt();
+  int w = settings.value("PlotWidth",1000).toInt();
+  ui->widePlot->m_w=w;
+  ui->freqSpanSpinBox->setValue(n);
+  ui->widePlot->setNSpan(n);
+  m_waterfallAvg = settings.value("WaterfallAvg",5).toInt();
+  ui->waterfallAvgSpinBox->setValue(m_waterfallAvg);
+  ui->widePlot->m_bCurrent=settings.value("Current",false).toBool();
+  ui->widePlot->m_bCumulative=settings.value("Cumulative",true).toBool();
+  if(ui->widePlot->m_bCurrent) ui->spec2dComboBox->setCurrentIndex(0);
+  if(ui->widePlot->m_bCumulative) ui->spec2dComboBox->setCurrentIndex(1);
+  int nbpp=settings.value("BinsPerPixel",2).toInt();
+  ui->widePlot->setBinsPerPixel(nbpp);
+  m_slope=settings.value("Slope",0.0).toDouble();
+  ui->slopeSpinBox->setValue(m_slope);
+  settings.endGroup();
+}
+
+WideGraph::~WideGraph()
+{
+  saveSettings();
+  delete ui;
+}
+
+void WideGraph::saveSettings()
+{
+  //Save user's settings
+  QString inifile(QApplication::applicationDirPath());
+  inifile += "/wsjtx.ini";
+  QSettings settings(inifile, QSettings::IniFormat);
+
+  settings.beginGroup("WideGraph");
+  settings.setValue("PlotZero",ui->widePlot->m_plotZero);
+  settings.setValue("PlotGain",ui->widePlot->m_plotGain);
+  settings.setValue("PlotWidth",ui->widePlot->plotWidth());
+  settings.setValue("FreqSpan",ui->freqSpanSpinBox->value());
+  settings.setValue("WaterfallAvg",ui->waterfallAvgSpinBox->value());
+  settings.setValue("Current",ui->widePlot->m_bCurrent);
+  settings.setValue("Cumulative",ui->widePlot->m_bCumulative);
+  settings.setValue("BinsPerPixel",ui->widePlot->binsPerPixel());
+  settings.setValue("Slope",m_slope);
+  settings.endGroup();
+}
+
+void WideGraph::dataSink2(float s[], float df3, int ihsym,
+                          int ndiskdata)
+{
+  static float splot[NSMAX];
+  static float swide[2048];
+  int nbpp = ui->widePlot->binsPerPixel();
+  static int n=0;
+
+  //Average spectra over specified number, m_waterfallAvg
+  if (n==0) {
+    for (int i=0; i<NSMAX; i++)
+      splot[i]=s[i];
+  } else {
+    for (int i=0; i<NSMAX; i++)
+      splot[i] += s[i];
+  }
+  n++;
+
+  if (n>=m_waterfallAvg) {
+    for (int i=0; i<NSMAX; i++)
+        splot[i] /= n;                       //Normalize the average
+    n=0;
+
+//    int w=ui->widePlot->plotWidth();
+    int i0=-1;                            //###
+    int i=i0;
+    int jz=5000.0/(nbpp*df3);
+    for (int j=0; j<jz; j++) {
+      float sum=0;
+      for (int k=0; k<nbpp; k++) {
+        i++;
+        sum += splot[i];
+      }
+      swide[j]=sum;
+    }
+
+// Time according to this computer
+    qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
+    int ntr = (ms/1000) % m_TRperiod;
+    if((ndiskdata && ihsym <= m_waterfallAvg) || (!ndiskdata && ntr<m_ntr0)) {
+      for (int i=0; i<2048; i++) {
+        swide[i] = 1.e30;
+      }
+    }
+    m_ntr0=ntr;
+    ui->widePlot->draw(swide,i0);
+  }
+}
+
+void WideGraph::on_freqSpanSpinBox_valueChanged(int n)
+{
+  ui->widePlot->setBinsPerPixel(n);
+}
+
+void WideGraph::on_waterfallAvgSpinBox_valueChanged(int n)
+{
+  m_waterfallAvg = n;
+}
+
+void WideGraph::on_zeroSpinBox_valueChanged(int value)
+{
+  ui->widePlot->setPlotZero(value);
+}
+
+void WideGraph::on_gainSpinBox_valueChanged(int value)
+{
+  ui->widePlot->setPlotGain(value);
+}
+
+void WideGraph::keyPressEvent(QKeyEvent *e)
+{  
+  switch(e->key())
+  {
+  int n;
+  case Qt::Key_F11:
+    n=11;
+    if(e->modifiers() & Qt::ControlModifier) n+=100;
+    emit f11f12(n);
+    break;
+  case Qt::Key_F12:
+    n=12;
+    if(e->modifiers() & Qt::ControlModifier) n+=100;
+    emit f11f12(n);
+    break;
+  default:
+    e->ignore();
+  }
+}
+
+void WideGraph::setRxFreq(int n)
+{
+  m_rxFreq=n;
+  ui->widePlot->setRxFreq(m_rxFreq,true);
+  if(m_lockTxFreq) setTxFreq(m_rxFreq);
+}
+
+int WideGraph::rxFreq()
+{
+  return ui->widePlot->rxFreq();
+}
+
+int WideGraph::nSpan()
+{
+  return ui->widePlot->m_nSpan;
+}
+
+float WideGraph::fSpan()
+{
+  return ui->widePlot->m_fSpan;
+}
+
+int WideGraph::nStartFreq()
+{
+  return ui->widePlot->startFreq();
+}
+
+void WideGraph::wideFreezeDecode(int n)
+{
+  emit freezeDecode2(n);
+}
+
+void WideGraph::setRxRange(int fMin)
+{
+  ui->widePlot->setRxRange(fMin);
+  ui->widePlot->DrawOverlay();
+  ui->widePlot->update();
+}
+
+int WideGraph::getFmin()
+{
+  return m_fMin;
+}
+
+int WideGraph::getFmax()
+{
+  int n=ui->widePlot->getFmax();
+  if(n>5000) n=5000;
+  return n;
+}
+
+void WideGraph::setFmin(int n)
+{
+  m_fMin = n;
+  ui->fMinSpinBox->setValue(n);
+  setRxRange(m_fMin);
+}
+
+void WideGraph::setPalette(QString palette)
+{
+  ui->widePlot->setPalette(palette);
+}
+
+double WideGraph::fGreen()
+{
+  return ui->widePlot->fGreen();
+}
+
+void WideGraph::setPeriod(int ntrperiod, int nsps)
+{
+  m_TRperiod=ntrperiod;
+  m_nsps=nsps;
+  ui->widePlot->setNsps(ntrperiod, nsps);
+}
+
+void WideGraph::setTxFreq(int n)
+{
+  emit setXIT2(n);
+  ui->widePlot->setTxFreq(n);
+}
+
+void WideGraph::setMode(QString mode)
+{
+  m_mode=mode;
+  ui->fMinSpinBox->setEnabled(m_mode=="JT9+JT65");
+  ui->widePlot->setMode(mode);
+  ui->widePlot->DrawOverlay();
+  ui->widePlot->update();
+}
+
+void WideGraph::setModeTx(QString modeTx)
+{
+  m_modeTx=modeTx;
+  ui->widePlot->setModeTx(modeTx);
+  ui->widePlot->DrawOverlay();
+  ui->widePlot->update();
+}
+
+void WideGraph::on_spec2dComboBox_currentIndexChanged(const QString &arg1)
+{
+  ui->widePlot->m_bCurrent=false;
+  ui->widePlot->m_bCumulative=false;
+  if(arg1=="Current") ui->widePlot->m_bCurrent=true;
+  if(arg1=="Cumulative") ui->widePlot->m_bCumulative=true;
+}
+
+void WideGraph::on_fMinSpinBox_valueChanged(int n)
+{
+  m_fMin=n;
+  setRxRange(m_fMin);
+}
+
+void WideGraph::on_slopeSpinBox_valueChanged(double d)
+{
+  m_slope=d;
+}
+
+void WideGraph::setSlope(double d)
+{
+  m_slope=d;
+  ui->slopeSpinBox->setValue(d);
+}
+
+void WideGraph::setLockTxFreq(bool b)
+{
+  m_lockTxFreq=b;
+  ui->widePlot->m_lockTxFreq=b;
+}
+double WideGraph::getSlope()
+{
+  return m_slope;
+}
+
+void WideGraph::setFreq2(int rxFreq, int txFreq)
+{
+  m_rxFreq=rxFreq;
+  m_txFreq=txFreq;
+  emit setFreq3(rxFreq,txFreq);
+}
+
+void WideGraph::setDialFreq(double d)
+{
+  m_dialFreq=d;
+  ui->widePlot->setDialFreq(d);
+}
diff --git a/widegraph.h b/widegraph.h
new file mode 100644
index 0000000..194998d
--- /dev/null
+++ b/widegraph.h
@@ -0,0 +1,89 @@
+#ifndef WIDEGRAPH_H
+#define WIDEGRAPH_H
+#include <QDialog>
+
+namespace Ui {
+  class WideGraph;
+}
+
+class WideGraph : public QDialog
+{
+  Q_OBJECT
+
+public:
+  explicit WideGraph(QWidget *parent = 0);
+  ~WideGraph();
+
+  void   dataSink2(float s[], float df3, int ihsym, int ndiskdata);
+  void   setRxFreq(int n);
+  int    rxFreq();
+  int    nSpan();
+  int    nStartFreq();
+  int    getFmin();
+  int    getFmax();
+  float  fSpan();
+  void   saveSettings();
+  void   setRxRange(int fMin);
+  void   setFmin(int n);
+  void   setPalette(QString palette);
+  void   setFsample(int n);
+  void   setPeriod(int ntrperiod, int nsps);
+  void   setTxFreq(int n);
+  void   setMode(QString mode);
+  void   setModeTx(QString modeTx);
+  void   setSlope(double d);
+  void   setLockTxFreq(bool b);
+  double getSlope();
+  double fGreen();
+
+  qint32 m_rxFreq;
+  qint32 m_txFreq;
+
+signals:
+  void freezeDecode2(int n);
+  void f11f12(int n);
+  void setXIT2(int n);
+  void setFreq3(int rxFreq, int txFreq);
+
+public slots:
+  void wideFreezeDecode(int n);
+  void setFreq2(int rxFreq, int txFreq);
+  void setDialFreq(double d);
+
+protected:
+  virtual void keyPressEvent( QKeyEvent *e );
+
+private slots:
+  void on_waterfallAvgSpinBox_valueChanged(int arg1);
+  void on_freqSpanSpinBox_valueChanged(int arg1);
+  void on_zeroSpinBox_valueChanged(int arg1);
+  void on_gainSpinBox_valueChanged(int arg1);
+  void on_spec2dComboBox_currentIndexChanged(const QString &arg1);
+  void on_fMinSpinBox_valueChanged(int n);
+  void on_slopeSpinBox_valueChanged(double d);
+
+private:
+  double m_slope;
+  double m_dialFreq;
+
+  qint32 m_waterfallAvg;
+  qint32 m_fSample;
+  qint32 m_TRperiod;
+  qint32 m_nsps;
+  qint32 m_ntr0;
+  qint32 m_fMin;
+  qint32 m_fMax;
+
+  bool   m_lockTxFreq;
+
+  QString m_mode;
+  QString m_modeTx;
+
+  Ui::WideGraph *ui;
+};
+
+#ifdef WIN32
+extern int set570(double freq_MHz);
+#endif
+
+#endif // WIDEGRAPH_H
diff --git a/widegraph.ui b/widegraph.ui
new file mode 100644
index 0000000..42faba8
--- /dev/null
+++ b/widegraph.ui
@@ -0,0 +1,398 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WideGraph</class>
+ <widget class="QDialog" name="WideGraph">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>799</width>
+    <height>326</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <item>
+      <widget class="CPlotter" name="widePlot">
+       <property name="enabled">
+        <bool>true</bool>
+       </property>
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>400</width>
+         <height>100</height>
+        </size>
+       </property>
+       <property name="frameShape">
+        <enum>QFrame::StyledPanel</enum>
+       </property>
+       <property name="frameShadow">
+        <enum>QFrame::Sunken</enum>
+       </property>
+       <property name="lineWidth">
+        <number>1</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_3">
+       <property name="spacing">
+        <number>0</number>
+       </property>
+       <item>
+        <spacer name="horizontalSpacer_4">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QSpinBox" name="freqSpanSpinBox">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>110</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>38</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="toolTip">
+          <string>Compression factor for frequency scale</string>
+         </property>
+         <property name="suffix">
+          <string/>
+         </property>
+         <property name="prefix">
+          <string>Bins/Pixel </string>
+         </property>
+         <property name="minimum">
+          <number>1</number>
+         </property>
+         <property name="maximum">
+          <number>1000</number>
+         </property>
+         <property name="singleStep">
+          <number>1</number>
+         </property>
+         <property name="value">
+          <number>2</number>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_6">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Minimum</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>8</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QSpinBox" name="waterfallAvgSpinBox">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>80</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>38</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="toolTip">
+          <string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
+         </property>
+         <property name="prefix">
+          <string>N Avg </string>
+         </property>
+         <property name="minimum">
+          <number>1</number>
+         </property>
+         <property name="maximum">
+          <number>20</number>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Minimum</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>8</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QSpinBox" name="gainSpinBox">
+         <property name="minimumSize">
+          <size>
+           <width>80</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>38</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="toolTip">
+          <string>Scaling (dB) applied to spectra before plotting</string>
+         </property>
+         <property name="prefix">
+          <string>Gain </string>
+         </property>
+         <property name="minimum">
+          <number>-20</number>
+         </property>
+         <property name="maximum">
+          <number>20</number>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_7">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Minimum</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>8</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QSpinBox" name="zeroSpinBox">
+         <property name="minimumSize">
+          <size>
+           <width>80</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>38</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="toolTip">
+          <string>Constant offset applied to waterfall data</string>
+         </property>
+         <property name="suffix">
+          <string/>
+         </property>
+         <property name="prefix">
+          <string>Zero </string>
+         </property>
+         <property name="minimum">
+          <number>-100</number>
+         </property>
+         <property name="maximum">
+          <number>100</number>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QDoubleSpinBox" name="slopeSpinBox">
+         <property name="minimumSize">
+          <size>
+           <width>60</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="prefix">
+          <string>Slope </string>
+         </property>
+         <property name="decimals">
+          <number>1</number>
+         </property>
+         <property name="minimum">
+          <double>-2.000000000000000</double>
+         </property>
+         <property name="maximum">
+          <double>2.000000000000000</double>
+         </property>
+         <property name="singleStep">
+          <double>0.100000000000000</double>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Minimum</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>8</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QSpinBox" name="fMinSpinBox">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>110</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="toolTip">
+          <string>Decode JT65 below this frequency, JT9 above</string>
+         </property>
+         <property name="suffix">
+          <string>  JT9</string>
+         </property>
+         <property name="prefix">
+          <string>JT65  </string>
+         </property>
+         <property name="minimum">
+          <number>0</number>
+         </property>
+         <property name="maximum">
+          <number>5000</number>
+         </property>
+         <property name="singleStep">
+          <number>100</number>
+         </property>
+         <property name="value">
+          <number>3000</number>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_8">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Minimum</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>8</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QComboBox" name="spec2dComboBox">
+         <property name="toolTip">
+          <string>Select data for display curve</string>
+         </property>
+         <property name="currentIndex">
+          <number>1</number>
+         </property>
+         <item>
+          <property name="text">
+           <string>Current</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>Cumulative</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>CPlotter</class>
+   <extends>QFrame</extends>
+   <header>plotter.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/wsjt.ico b/wsjt.ico
new file mode 100644
index 0000000..8a55550
Binary files /dev/null and b/wsjt.ico differ
diff --git a/wsjtx.iss b/wsjtx.iss
new file mode 100644
index 0000000..8d550fa
--- /dev/null
+++ b/wsjtx.iss
@@ -0,0 +1,23 @@
+[Setup]
+AppName=wsjtx
+AppVerName=wsjtx Version 1.1.0 r3488
+AppCopyright=Copyright (C) 2001-2013 by Joe Taylor, K1JT
+DefaultDirName=c:\wsjtx2
+DefaultGroupName=wsjtx2
+
+[Files]
+Source: "c:\Users\joe\wsjt\wsjtx_install\*.exe";                         DestDir: "{app}"
+Source: "c:\Users\joe\wsjt\wsjtx_install\*.dll";                         DestDir: "{app}";
+Source: "c:\Users\joe\wsjt\wsjtx_install\*.dat";                         DestDir: "{app}";
+Source: "c:\Users\joe\wsjt\wsjtx_install\wsjt.ico";                      DestDir: "{app}";
+Source: "c:\Users\joe\wsjt\wsjtx_install\CALL3.TXT";                     DestDir: "{app}";  Flags: onlyifdoesntexist
+Source: "c:\Users\joe\wsjt\wsjtx\shortcuts.txt";                         DestDir: "{app}"
+Source: "c:\Users\joe\wsjt\wsjtx\mouse_commands.txt";                    DestDir: "{app}"
+Source: "c:\Users\joe\wsjt\wsjtx\WSJT-X_Users_Guide_v1.1.pdf";           DestDir: "{app}"
+Source: "c:\Users\joe\wsjt\wsjtx_install\save\Samples\130418_1742.wav";  DestDir: "{app}\save\Samples";
+Source: "c:\Users\joe\wsjt\wsjtx_install\save\Samples\130610_2343.wav";  DestDir: "{app}\save\Samples";
+
+[Icons]
+Name: "{group}\wsjtx2";        Filename: "{app}\wsjtx.exe";   WorkingDir: {app}; IconFilename: {app}\wsjt.ico
+Name: "{userdesktop}\wsjtx2";  Filename: "{app}\wsjtx.exe";   WorkingDir: {app}; IconFilename: {app}\wsjt.ico
+
diff --git a/wsjtx.pro b/wsjtx.pro
new file mode 100644
index 0000000..92270a5
--- /dev/null
+++ b/wsjtx.pro
@@ -0,0 +1,81 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2011-07-07T08:39:24
+#
+#-------------------------------------------------
+
+QT       += core gui network
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+CONFIG   += thread
+#CONFIG   += console
+
+TARGET = wsjtx
+DESTDIR = ../wsjtx_install
+VERSION = 1.1
+TEMPLATE = app
+DEFINES = QT4
+
+win32 {
+DEFINES += WIN32
+F90 = g95
+g95.output = ${QMAKE_FILE_BASE}.o
+g95.commands = $$F90 -c -O2 -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+g95.input = F90_SOURCES
+QMAKE_EXTRA_COMPILERS += g95
+}
+
+unix {
+DEFINES += UNIX
+F90 = gfortran
+gfortran.output = ${QMAKE_FILE_BASE}.o
+gfortran.commands = $$F90 -c -O2 -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+gfortran.input = F90_SOURCES
+QMAKE_EXTRA_COMPILERS += gfortran
+}
+
+SOURCES += main.cpp mainwindow.cpp plotter.cpp about.cpp \
+    soundin.cpp soundout.cpp devsetup.cpp widegraph.cpp \
+    getfile.cpp displaytext.cpp getdev.cpp logqso.cpp \
+    psk_reporter.cpp rigclass.cpp \
+    signalmeter.cpp \
+    meterwidget.cpp
+
+win32 {
+SOURCES += killbyname.cpp
+}
+
+HEADERS  += mainwindow.h plotter.h soundin.h soundout.h \
+            about.h devsetup.h widegraph.h getfile.h \
+            commons.h sleep.h displaytext.h logqso.h \
+            psk_reporter.h rigclass.h \
+    signalmeter.h \
+    meterwidget.h
+
+# (Is the following really needed???)
+#DEFINES += __cplusplus
+
+FORMS    += mainwindow.ui about.ui devsetup.ui widegraph.ui \
+    logqso.ui
+
+RC_FILE = wsjtx.rc
+
+unix {
+LIBS += ../wsjtx/lib/libjt9.a
+LIBS += -lhamlib
+LIBS += -lportaudio -lgfortran -lfftw3f
+}
+
+win32 {
+INCLUDEPATH += ../../hamlib-1.2.15.3/include
+LIBS += ../../hamlib-1.2.15.3/src/.libs/libhamlib.dll.a
+#LIBS += ../../hamlib-1.2.15.3/lib/gcc/libhamlib.dll.a
+LIBS += ../wsjtx/lib/libjt9.a
+LIBS += ../wsjtx/libfftw3f_win.a
+LIBS += ../wsjtx/libpskreporter.a
+LIBS += ../wsjtx/libHRDInterface001.a
+#LIBS += ../QtSupport/palir-02.dll
+LIBS += /users/joe/wsjt/QtSupport/palir-02.dll
+LIBS += libwsock32
+LIBS += C:/MinGW/lib/libf95.a
+
+}
diff --git a/wsjtx.rc b/wsjtx.rc
new file mode 100644
index 0000000..9a0de81
--- /dev/null
+++ b/wsjtx.rc
@@ -0,0 +1 @@
+IDI_ICON1       ICON    DISCARDABLE     "wsjt.ico"
diff --git a/wsjtx_changelog.txt b/wsjtx_changelog.txt
new file mode 100644
index 0000000..ea05cf7
--- /dev/null
+++ b/wsjtx_changelog.txt
@@ -0,0 +1,791 @@
+			WSJT-X ChangeLog
+------------------------------------------------------------------
+
+May 30, 2013: Version 1.0, r3323
+--------------------------------
+
+With this release of WSJT-X Version 1.0 we include a few (relatively
+minor) enhancements in response to user requests, as well as some
+program polishing and cleanup.  Active program development will
+continue, but new releases will become less frequent.
+
+1. New option on the Setup menu: "Tx freq locked to Rx freq".
+
+2. Double-click on a decoded "73" message now sets Tx5, rather than Tx6.
+
+3. New keyboard shortcuts: Alt+1 through Alt+6 set the next Tx message 
+   at the corresponding number.
+
+4. PTT control via Ham Radio Deluxe has been imnplemented and tested.
+
+5. "Tool Tips" are now provided for most on-screen controls.
+
+6. Under Linux and OS X, listings of available audio devices and APIs
+   have been corrected.
+
+7. Tab order among GUI controls has been cleaned up.
+
+8. Updates to the WSJT-X User's Guide.
+
+
+May 22, 2013: v0.99, r3297
+--------------------------
+
+1. CAT control via Ham Radio Deluxe is now available.  For setup
+   details see item #5 at the top of page 6 of the updated WSJT-X
+   User's Guide.
+
+2. Submodes JT9-5, JT8-10, JT9-30 have been de-activated.  (As far as I
+   know, nobody was using them.)  This action makes the program smaller 
+   by some 150 MB and able to run effectively on some older computers.
+
+3. Bizarre ordering of COM port numbers on the drop-down list has been
+   corrected, and suitable serial ports added to the list displayed in
+   Linux.
+
+4. Gray bar between decoding periods now contains a dashed line.
+
+5. Corrected a bug that prevented use of Setup | Configuration with
+   no existing wsjtx.ini file.
+
+May 17, 2013: v0.95, r3278
+--------------------------
+1.  Double-clicking on a decoded text line in "Band Activity" window
+    now copies the line into the "QSO Frequency" window if it was not
+    already there.
+
+2.  Option "Color highlighting in left window" removed from Setup
+    menu.  Highlighting is now always done.
+
+3.  Positions of "QSO Frequency" and "Band Activity" windows have been
+    swapped.  
+
+4.  F4 was restored to its previous use; F5 is now used to display
+    Special Mouse Commands
+
+5.  Small square between Band selector and Frequency readout was made
+    a control button.  Orange indicates one-way CAT control from
+    program to radio, red indicates bi-directional control.  Clicking
+    the orange button causes a one-time readout of dial frequency.
+
+6.  If Save=None, the last recorded file is deleted on program exit.
+    This prevents unwanted accumulation of files in the Save
+    directory.
+
+7.  Status-bar messages were re-arranged in a more logical order.
+
+8.  Tx signal report was added to wsjtx_status.txt (for JT-Alert)
+
+9.  More informative labels were placed on the "Tab 2" GUI controls.
+
+10. Better default scaling for the "Cumulative" spectrum.
+
+11. New algorithm for identifying JT9 signals to send to decoder,
+    resulting major improvements in decoder speed.
+
+12. Bug fixes:
+     - Incorrect displayed frequencies for JT9-2 signals
+     - Infinitely repeated "Error rigOpen -1" messages
+     - User tries to open CAT control using busy or nonexistent serial port
+
+13. Many updates to the User's Guide
+
+
+May 2, 2013: v0.95, r3251
+-------------------------
+
+1. The "band change" function is executed whenever the Band combobox
+   is activated, even if the selected band has not changed.
+
+2. The program does not set rig mode.  That task is left to the user.
+
+3. Time interval for polling rig frequency is now a user parameter on
+   the setup screen.  I set mine to 1 second, which works fine with
+   the Kenwood TS-2000.  Set it to 0 if you want no polling for
+   frequency (which means unidirectional CAT control from program to
+   radio).  Choose something like 10 s for the K3.
+
+4. Much new work on the WSJT-X User's Guide, which is approaching its
+   final form for Version 1.0.  Please read it and tell us about
+   anything you find unclear or missing!
+
+These changes address nearly all of the CAT issues found by a few
+users -- those with K3, IC-746, IC-706, in particular.  
+
+One additional piece of advice when running WSJT-X in Windows: connect
+and turn on the radio and any interface equipment before starting
+WSJT-X, and exit the program before turning such equipment off.
+
+April 29, 2013: v0.95, r3243
+----------------------------
+
+1. Now has bi-directionsl CAT control using direct calls to hamlib
+   functions.  Highlights displayed dial frequency with red background
+   if frequency differs from nominal for the selected band by more
+   than 100 kHz.  (Is there a more useful or logical condition to
+   flag?)  Small red square between Band selector and Dial Frequency
+   display to indicate that CAT control is active.  Mode is set to USB
+   on startup.  (Note: CAT control diagnostics are presently rather
+   rudimentary, we're still working on this.  Feedback is welcome!)
+
+2. New controls on Setup | Configuration screen: 
+   - RTS/DTR OFF -- needed by K2 and maybe other radios
+   - Data / Mic -- select CAT-control PTT type
+   - Test CAT Control -- try settings before returning to main screen
+   - Test PTT -- try settings for toggling PTT On/Off
+
+3. Help menu now provides displays of Keyboard Shortcuts (quick access
+   via F3) and Special Mouse Commands (F4).
+
+4. Option "Setup | Advanced | Allow multiple instances" enables the
+   use of more than one instance of WSJT-X for special applications.
+   (The program must be copied into and run from different
+   directories.)
+
+5. No posts to PSK Reporter if band was changed during the reception
+   period.
+
+6. Improved behavior of Tune button.
+
+7. Improved inter-process communication between WSJT-X and JT-Alert-X.
+
+8. Better interaction between "Report" spinner control and Tx messages.
+
+9. Removed the NB checkbox and slider.  (Has anyone found these useful?)
+
+10. New buttons on main window: "Tx=Rx" sets Tx frequency to current
+    Rx frequency; "Rx=Tx" does the opposite.
+
+11. Log QSO confirmation window is now "non-modal": you can keep it 
+    open and still access controls on the main window.
+
+12. Tab-order has been rationalized on most screens.
+
+13. Dial frequency and mode written to file ALL.TXT.
+
+14. Double-click on decoded line sets Tx message #3 if message has
+     the form "MyCall Call2 rpt".
+
+15. Bug causing occasional, seemingly unpredictable program crashes
+    has been fixed.
+
+16. The WSJT-X User's Guide is somewhat closer to being complete.  User
+    feedback on the Guide will be most welcome.  What is unclear?  What
+    is missing?
+
+April 17, 2013: v0.9, r3195
+---------------------------
+1. Sorry, the CAT control changes in r3187/3188 were a dismal failure
+in many stations, and they introduced other bugs as well.  This revision
+goes back to uni-directional CAT control: the program can set the 
+radio's dial frequency and do T/R switching, but that's all.  The band
+setting is not reset on program startup.
+
+2. Logic for the Tune button has been corrected.
+
+3. For Linux compile-it-yourself enthusiasts: the interface to 
+PSK Reporter is now working undel Linux.
+
+April 16, 2013: v0.9, r3188
+---------------------------
+
+1. CAT control now reads and follows changes in radio's dial
+frequency.  Readout gets red highlighting if radio is on wrong band.
+On program restart, band is reset to the last selected band.
+
+2. New "Tune" button generates an unmodulated carrier.  Toggle button
+a second time to turn Tx off.
+
+3. Added labels at top of "Tab 2" and enlarged the text entry fields.
+
+4. Fixed the broken logic for "Runaway Tx watchdog".
+
+5. Fixed "Prompt me to log QSO" so that it no longer requires also
+setting "ID after 73".
+
+6. Additional changes of (eventual) interest to Linux users.  Code for
+sending spots to PSK Reporter now in place.
+
+April 13, 2013: v0.9, r3166
+---------------------------
+1. Option to send Tx messages (highlighted in yellow) to the QSO window.
+
+2. Prevent starting a transmission more than 24 sec into a Tx period.
+
+3. "Setup | Options" changed to "Setup | Configuration".
+
+4. Type Alt-V to save the most recently completed Rx file.
+
+5. Fixed bug that truncated Rx messages to 16 characters.
+
+6. Internal program changes that should provide better user diagnostics
+when necessary at program startup.
+
+April 11, 2013: v0.9, r3157
+---------------------------
+1. Maximum size of several window areas increased to accommodate system 
+fonts set larger than default.
+
+2. New behavior of Erase button: click once to erase the left (QSO) window,
+twice to erase both decoded text windows.
+
+3. Keyboard shortcuts:
+   Alt-D: decode again at QSO frequency (same as clicking the Decode() button)
+   Shift-D: do another full decode in both windows
+   Alt-E: Erase()
+   Ctrl-F: Edit the free text message box
+   Alt-H: Halt Tx()
+   Alt M: Monitor()
+   Alt-N: Enable Tx()
+   Alt-Q: Log QSO()
+   Alt-S: Stop()
+
+4. New Setup options: "Tx disabled after sending 73" and "Runaway Tx 
+watchdog".
+
+5. Fixed bug in saving the "report received" for logging purposes.
+
+6. Corrected the logic for "Runaway Tx watchdog".
+
+7. Fixed bug that truncated characters 17 and 18 of decoded messages.
+
+April 10, 2013: v0.9, r3151
+---------------------------
+1. Blank line between decoding periods is now in the right-hand 
+text window, where it should be.
+2. Decoding range defined by fMin and fMax is now enforced.
+
+April 9, 2013: v0.9, r3143
+--------------------------
+This minor release restores the decoding speed of earlier revisions
+and corrects a bug that prevented sending CW ID.
+
+April 9, 2013: v0.9, r3142
+--------------------------
+
+This version of WSJT-X has a number of significant changes.  Please
+read the following notes carefully.  Also -- even if you are already
+familiar with WSJT-X -- be sure to read the updated WSJT-X User's 
+Guide at 
+http://www.physics.princeton.edu/pulsar/K1JT/WSJT-X_Users_Guide.pdf ,
+especially pages 3 and 4.
+
+Changes since v0.8 r3118 include the following:
+
+1. There are now two scrolling windows for decoded text.  The left
+window contains decodes only from close to the designated QSO
+frequency.  The right window includes signals over the full decoding
+range.
+
+2. An alternative set of controls is now available for generating and
+selecting Tx messages.  Some may find these more convenient to use
+than the Tx1 through Tx6 message boxes.
+
+3. A number of new user options are available on the Setup menu:
+   - Blank line between decoding periods (right window only)
+   - Clear DX Call and DX Grid after logging QSO
+   - Display distances in miles
+   - Runaway Tx watchdog
+   - Background colors for left window
+   - Double-click on decoded message sets Tx Enable
+
+4. New or changed on-screen features
+   - "Tol" replaced by fMin and fMax on waterfall screen (see User's Guide)
+   - Spinner control for signal report
+   - On waterfall scale: green marker for Rx freq, red for Tx. blue
+     for decoding range
+
+5. New behavior
+   - "CQ DX" is now treated properly when decoded line is double-clicked
+   - Message formate for compound callsigns (e.g., PJ4/K1ABC, G4XYZ/P)
+     are now handled correctly.  (Some restrictions apply, and will
+     be spelled out in the completed User's Guide.)
+   - Decode button now causes a decode only at the specified Rx frequency.
+   - Click on waterfall spectrum sets Rx freq; double-click also invokes
+     decoder (as though Decode button had been clicked).  CTRL-click moves
+     both Rx and Tx freqs.
+   - Amplitude at end of transmission is ramped down to prevent a final
+     key click.
+
+6. The following bugs have been fixed:
+   - Logic error in decoder
+   - Certain non-standard Tx messages could cause a program crash.
+   - Certain (rarely used) messages did not pack/unpack correctly
+
+April 2, 2013: v0.8, r3118
+--------------------------
+1. Improved interface to program JT-Alert, by VK3AMA.
+
+2. The LogQSO confirmation dialog no longer blocks the GUI updating
+   process.
+
+3. A blank line with gray background separates the decoded text lines for
+   each new invocation of the decoder.
+
+4. New suggested default frequencies: 5.357, 18.104, and 24.918 MHz.  
+   Be sure to edit these entries on the 'Default Frequencies' tab of the
+   Setup screen.  (When you have done this once, the new values will be
+   remembered.)
+
+5. The LogQSO button now does nothing is the 'DX call' entry field is
+   blank.
+
+6. Several minor bugs were fixed.
+
+
+March 27, 2013: v0.8, r3113
+---------------------------
+1. Bug fix: VOX control of T/R switching now works.
+
+2. Potentially useful error messages now appear when CAT control
+   has failed.
+
+3. Added an instruction on the Log QSO confirmation screen.
+
+4. Clear the DXcall and DXgrid entries after logging a QSO.
+
+March 26, 2013: v0.8, r3112
+---------------------------
+
+Edson Pereira, PY2SDR, recently became an active contributor to this
+open-source project.  Edson and I have been very busy over the past
+few days!  WSJT-X revision 3112 has many changes and new features.
+
+1. The GUI layout has been adjusted and optimized.
+
+2. CAT control is now operational, offering optional control of your
+   radio's dial frequency and T/R status.  Go to the Setup | Options
+   window to select the necessary parameters.
+
+3. CW ID has been implemented.  You can have your ID sent after a fixed 
+   time interval, or automatically when you transmit a "73" or free
+   text message.  
+
+4. Default dial frequencies are available for each band on a new tab
+   on the Setup | Options window.  Please note: some of these
+   frequencies are probably wrong!  You can edit them as needed.  
+   (Please let us know if the original values are inconsistent with
+   actual practice on any band.)
+
+5. Several new options appear on the Setup menu.  Try them!
+
+6. Azimuth and Distance information is displayed whenever a valid grid
+   locator appears in the "Dx Grid" box.
+
+7. The decoder has again been adjusted for better compromise between
+   sensitivity and decoding time.  
+   
+8. The User's Guide is out of date, and needs work.  We hope to get to
+   that task soon.
+
+9. Very important for some would-be users: WSJT-X now runs properly
+   under Linux.  We haven't made a package yet, so for now you must
+   compile your own.  If you don't know how, we hope to be set up
+   to make packages before too long.
+
+10. If you know someone who might be interested in contributing to the
+    development of WSJT-X and related projects, please send him/her
+    our way!  We're especially looking for someone interested in
+    producing packaged Linux distributions -- for example, *.deb or
+    *.rpm packages, but other programming help is also wanted.
+
+As always: please report bugs, and don't be bashful about sending us
+your feature requests!
+
+March 22, 2013: v0.7, r3071
+---------------------------
+1. Correct a bug that (still) allowed display of previous decodes
+when nothing new was decoded.
+
+2. Add a user confirmation screen activated when you click Log QSO.
+This lets you edit or add information before it is written to the
+ADIF file.
+
+3. Tx message macros and now available.  Configure them on the Setup 
+window.  They are invoked as a pop-up menu by right-clicking on the 
+Tx5 message window; then select the desired message by left-clicking 
+on the desired message. 
+
+March 20, 2013: v0.7, r3063
+---------------------------
+1. Add Frequency to the generated ADIF records.
+
+2. Correct a decoder bug that led to duplication of previous output 
+when nothing new was decoded.
+
+March 19, 2013: v0.7, r3061
+---------------------------
+1. Allow Windows COM port numbers up to 99.
+
+2. Replace status files wsjtx_qrg.txt and wsjtx_txcall.txt with
+a single file, wsjtx_status.txt.
+
+3. Combine wsjtx_rx.log and wsjtx_tx.log into a single file ALL.TXT.
+
+4. "Log QSO" now writes a file in ADIF format.
+
+5. Starting to implement popup macros for Tx message #5.
+
+6. Big improvement in decoding speed.
+
+*** More changes to come!  Please report any problems, especially
+*** with the ADIF-format log.
+
+March 12, 2013: v0.6, r3046
+---------------------------
+1. Decoded calls can now be uploaded to the PSK Reporter web site. 
+Check the box "Enable PSK Reporter" on the Setup screen, and go to
+http://pskreporter.info/pskmap.html to see the spots.  Be sure to
+enter your "Dial Frequency (MHz)" at lower right of the Wide Graph
+window.  (Rig control features are yet to come...)
+
+2. Added some interfaces to permit use with the program JT-Alert,
+by VK3AMA.  Look for this capability in the near future. 
+
+March 6, 2013: v0.5, r3038
+--------------------------
+1. Selection of Current/Cumulative/JT9Sync for the 2d spectral display
+changed to a combobox.
+
+2. Double-click on decoded text does not change frequency settings
+if first decoded call is MyCall.
+
+March 1, 2013: v0.5, r3026
+--------------------------
+1. The horizontal scale of 2d spectra (e.g., the "red curve") is now
+correct when the user has selected FFT Bins/Pixel > 1.
+
+2. Double-clicking on a decoded text line now selects the second
+callsign independent of exactly where one has clicked on the line.  
+In addition, it sets the selected frequencies (both Tx and Rx) to
+the frequency of the decoded transmission.
+
+December 11, 2012: v0.5, r2791
+------------------------------
+1. Messages of the form "CQ DX K1ABC" are now supported.
+
+November 30, 2012: v0.5, r2788
+------------------------------
+1. A bug was introduced when support for positive signal reports was
+added.  It could cause a program crash when certain free-text messages
+were composed for transmission.  The bug has been fixed.
+
+2. In the slower JT9 sub-modes, the UTC listed on decoded text lines
+has been changed to the start time of the Rx sequence, rather than the
+time of the final minute.
+
+3. The waterfall's "Auto Zero" button had no function, and has been
+removed.
+
+4. In previous revisions the installer put a number of DLLs into
+the Windows system directory, normally C:\Windows\System32.  This
+revision installs the DLLs to the WSJT-X installation directory.
+
+
+November 29, 2012: v0.5, r2786
+------------------------------
+1. In r2783, the companion program jt9.exe (started automatically when
+you start WSJT-X) was a CPU hog for no good reason.  This was an
+oversight on my part, and the bug has been corrected.
+
+2. The program should now run correctly if installed in a directory
+whose name contains embedded spaces.  (Under Vista and Win7, however,
+it's still not a good idea to install WSJT-X into C:\Program Files,
+because of restricted write permissions there.)
+
+3. In r2783 and earlier, stopping a transmission by toggling to "Auto
+OFF" would terminate Tx audio and release PTT almost simultaneously,
+possibly hot-switching your T/R relay(s).  This has been corrected so
+that proper sequencing takes place.
+
+
+November 28, 2012: v0.5, r2783
+------------------------------
+This revision has an unusually large number of changes relative to the
+previous release, v0.4 r2746.  These changes include:
+
+1. PTT control via COM ports COM10 and higher is enabled.
+
+2. Improved decoder performance: higher speed as well as better
+chances of success.  Moderate amounts of frequency drift are detected
+and compensated.  Computed S/N values are more reliable.  Time offsets
+from -2.5 to +5 s are now supported, which makes JT9 usable for EME.
+(EME tests on 144 MHz have been successful, and performance on that
+propagation mode appears to be good.)
+
+3. Tx Frequency now tracks the selected QSO Frequency (unless you hold
+down the CTRL key when setting QSO Frequency via mouse-clicks or the
+F11/F12 keys).
+
+4. Decoded text containing "CQ " is highlighted with green background;
+text including "MyCall" is highlighted in red.
+
+5. In previous versions, signal reports were required to be in the
+range -30 to -01 dB.  In v0.5 r2782 the range has been extended to -50
+to +49 dB.  There is backward compatibility for the range -30 to -01,
+but reports in the range -50 to -31 and 0 to +49 will NOT be decoded
+correctly by previous program versions.  It is important to upgrade!
+
+6. Items "Save Synced" and "Save Decoded" are now implemented.
+
+7. UTC Date, JT9 submode, and a parameter related to the decoding
+procedure are now included in file wsjtx_rx.log.
+
+8. Editing of Tx messages (in any of the six Tx message boxes) is
+complete when you hit "Tab" or "Return".  The message is then parsed
+and converted to the form in which it will be displayed if decoding is
+successful.  Free-text messages are trimmed to 13 characters and
+highlighted with a pink background.
+
+9. The most recent transmitted message is displayed in the right-most
+label on the status bar.  This can be useful if you have lost track of
+where you were in a QSO.
+
+10. By default, the program now starts with Monitor ON.  An option on
+the Setup menu allows you to select "Monitor OFF at startup".
+
+11. Better scaling is provided for the red "JT9 Sync" curve.  Note
+that JT9 signals in the active sub-mode should appear in this plot as
+a bump of width equal to the total signal bandwidth, with a narrow and
+slightly higher bump at the left edge.  The narrow bump is the
+frequency of the Sync tone, which is defined as the nominal frequency
+of the JT9 signal.
+
+12. Basic QSO information is now written to file wsjt.log when you
+click the "Log QSO" button.
+
+13. The WSJT-X User's Guide has been updated.
+
+14. Other known bugs have been fixed.  There will probably be new
+ones!  When you find one, or if you know of any old ones that have NOT
+been fixed, please send me email.
+
+Summary of Present Status
+----------------------------------------------------------------------
+I believe that WSJT-X is now a stable and very usable program.  Many
+thousands of QSOs have been made with JT9-1, mostly at HF -- I have
+made nearly 100, myself.  Also a number of QSOs have also been
+completed at MF, and successful tests have been made on 2m EME, etc.
+A number of QSOs have also been made with JT9-2.
+
+As far as I know the slower modes (JT9-5, JT9-10, and JT9-30) also
+work correctly.  (Certainly they do in my laboratory test setup.)
+Most people will find these modes too slow for "everyday" use, and
+they require high frequency stability.  It remains to be seen whether
+they will be widely used.
+
+An alternative approach to obtaining improved sensitivity would be to
+give the decoder an ability to average over several successive
+transmissions.  For example, the average of five JT9-1 transmissions
+could reach a decoding threshold around -32 dB, only 2 dB worse than a
+single JT9-5 transmission.  Because of QSB, the shorter transmissions
+may actually succeed in less total time.  Stability requirements would
+be those of JT9-1, much less stringent than those of JT9-5.
+
+Program development is not finished, by any means.  I will be grateful
+for your feedback on performance issues, as well as your "wish-list"
+of features to be added.  As always, example recordings of files that
+you think should have decoded, but did not, will be much appreciated.
+
+November 16, 2012: v0.4, r2746
+------------------------------
+
+Changes from v0.4 r2731 include the following:
+
+1. Valid signal reports are now generated by double-clicking on a
+callsign in the decoded text window.
+
+2. Consecutive spaces in a Tx message are now collapsed into a single
+space.
+
+3. Decoding speed is much improved, especially when strong (possibly
+non-JT9) signals are present and "Tol" is set to a relatively large
+value.
+
+4. Scaling of the "JT9 Sync" plot (red curve) is more reasonable.
+
+5. Layout of widgets on the main window has been improved.
+
+6. Several minor bug fixes. 
+
+November 14, 2012: v0.4, r2731
+------------------------------
+
+A number of known bugs have been fixed, and the JT9 decoder is
+significantly improved.  Among other improvements, the program is now
+much less fussy about timing issues.
+
+November 6, 2012: v0.3, r2717
+------------------------------
+
+Changes from r2713 include the following:
+
+1. A bug in the decoder that led to erratic behavior (failed decodes)
+under certain conditions has been corrected.  Decoding is now much
+more reliable.
+
+2. A valid algorithm is now used to calculate S/N values for received
+JT9 signals.
+
+3. The header format of recorded *.wav files has been corrected.
+These files will now play correctly in Windows programs that expect
+the standard header.
+
+November 6, 2012: v0.2, r2713
+------------------------------
+
+Changes from r2711 include the following:
+
+1. Updates to the Quick-Start User's Guide,
+http://www.physics.princeton.edu/pulsar/K1JT/WSJT-X_Users_Guide.pdf
+
+2. Double-click on waterfall now sets Tol to a reduced
+(mode-dependent) value.
+
+3. Tol is saved and restored on program restart.
+
+4. A "digital gain" slider was added next to the green-bar audio level
+indicator.  With the slider at mid-range, the scale reads correctly in
+dB above the least significant bit of 16-bit audio data.
+
+5. There is now a test that rejects at least one type of data that is
+sufficiently corrupt to cause Eddie's best friend, the message
+"15P6715P67WCV".
+
+6. Several minor tweaks to improve decoder performance.
+
+7. The program now starts with Monitor OFF.  You must click Monitor to
+start accepting audio.  For some types of testing, this may be an
+advantage.  This startup condition may be changed again, in the
+future.
+
+October 31, 2012: v0.2, r2711
+-----------------------------
+
+Three significant changes since r2706:
+
+1. Three options are now provided on the "Decode" menu, controlling
+the "depth" of the decoding process.  For most purposes I suggest you
+should use "Normal", but feel free to experiment with the others.
+
+2. Decoding of multiple signals in one Rx interval has been improved.
+
+3. Handling of strong signals has been improved. 
+
+October 309, 2012: v0.2, r2706
+------------------------------
+
+Changes since r2702 include the following:
+
+1. The problem with "ghost" signals is fixed.
+
+2. A problem causing very long decode times under certain
+circumstances has been fixed.  Please note: decode times on any recent
+PC should no more than a few seconds!
+
+3. I have re-directed the program's fatal error messages so they will
+be sent to the command-prompt window from which you started the
+program. Please send me full reports on any such messages you observe,
+preferably with details on how to reproduce the problem.
+
+#########################################################################
+
+Some additional information ...
+
+1. Yes, the JT9 modes require good stability in all system
+oscillators.  The present JT9 bdecoder does not attempt to track
+frequency drifts. Such capability will be added, however.  We have
+been using digital modes for EME for nearly ten years now, at 144 MHz
+and higher.  There are more than 1000 WSJT users on EME, using all
+kinds of rige.  We have learned how to deal with reasonable rates of
+drift.  Surely if we can do these things at VHF, we can do them much
+more easily at MF and LF.
+
+2. If you're sure that you have seen degraded JT9 performance because
+of frequency stability issues, don't just complain on the LF
+reflector. Document your case and send me an example file with a
+drifting JT9 signal.  Making WSJT-X and JT9 better is partly YOUR
+responsibility!
+
+3. In other ways as well, test files are needed.  I can make many
+tests myself, but I can't foresee all the problems others will have.
+That's what the "Save All" function is for!  In these early tests,
+always run with "Save All" checked, just in case you will want to
+refer back to something that happened.  You may want to send me the
+file in question.  You can always clean out your "Save" directory by
+using "File | Delete all *.wav files in SaveDir".  I need good
+examples of signals that fail to decode for any unknown reason.  Also
+some good examples of atmospheric or other impulsive noise, for
+testing the noise blanker.
+
+4. I have added a page of "Hints for New Users" to the online WSJT-X
+User's Guide,
+http://www.physics.princeton.edu/pulsar/K1JT/WSJT-X_Users_Guide.pdf .
+Please read it! ... and let me know if you find other operational
+details of WSJT-X that need explanation.  This will likely be
+especially true for those not already familiar with older versions of
+WSJT.
+
+5. An operational suggestion: In many ways the different JT9 submodes
+are treated as distinct modes.  If you receive a JT9-x signal in a
+different submode than the one you have selected, you won't decode
+it. For this reason, if JT9 is to become popular we'll probably need
+to choose one or two of the submodes for general use, and perhaps
+assign a narrow slice of the band to each one.  Note that "message
+averaging" in the Rx software can make two or three JT9-2
+transmissions as good as one JT9-5 transmission, with the advantage
+that you will copy sooner if signals are better than required for
+JT9-5.  Message averaging is not yet present in the JT9 decoder... but
+in future it can be.  Again, we have dealt with such issues very
+effectively on EME -- and can do so at MF/LF, for sure.
+
+6. On the topic of CW, Beacons, WSPR, JT9, etc.  I really don't
+understand what all the fuss is about.  Surely there is room for
+everybody?  Maybe I'm just too new here to understand?  (Mal, is this
+mostly just a matter of "Mal being Mal"???)
+
+On the HF bands, the WSPR sub-band is just 200 Hz wide.  If we did the
+same on 630 m, the WSPR sub-band would take up less than 3% of the 7
+kHz band.  If that's too much, we could cut it in half, or even less,
+and still have enough WSPR space.  Moreover, a "slow WSPR", if
+warranted, would require even less bandwidth.  Similar comments apply
+to JT9.  The bandwidth of JT9 signals is significantly less than that
+of CW, for comparable information rates.  There should be enough
+spectrum for both, even in our narrow MF and LF bands.
+
+7. As for performance comparisons between JT9 and WSPR: WSPR is a
+mature program, and its decoder has been optimized and tweaked over a
+period approaching five years.  You are playing with JT9 in infancy.
+With help (as opposed to simple complaints) from users, it will
+improve rapidly.
+
+October 29, 2012: v0.2, r2702
+-----------------------------
+Changes since version 0.1, r2696 include the following:
+
+1. Sample rate for audio output has been changed from 12000 to 48000
+Hz.  Tx audio may now be generated at any frequency from 500 to 20000
+Hz.
+
+2. The Decoder now tries to decode all synchronizable signals in the
+"green zone", that is, within "Tol" Hz of the selected QSO
+frequency. (Before, by default it decoded only the signal producing
+the highest "sync" value.  Other signals could be decoded by manually
+setting the QSO frequency and reducing Tol as needed.)
+
+3. The user's selected QSO Frequency is now saved and restored on
+program restart.
+
+4. The problem with re-initialization after changing sub-modes has
+been fixed.
+
+5. The problem (for some users) of not releasing PTT after end of a
+transmission has been fixed.
+
+6. The program now writes a log of all decodes to a file wsjtx_rx.log
+in the wsjtx directory.
+
+
+October 25, 2012: v0.1, r2695
+-----------------------------
+Initial version of WSJT-X (experimental WSJT) released for testing.
diff --git a/wsjtx_opti.iss b/wsjtx_opti.iss
new file mode 100644
index 0000000..1fbfedc
--- /dev/null
+++ b/wsjtx_opti.iss
@@ -0,0 +1,23 @@
+[Setup]
+AppName=wsjtx
+AppVerName=wsjtx Version 1.1.0 r3478
+AppCopyright=Copyright (C) 2001-2013 by Joe Taylor, K1JT
+DefaultDirName=c:\wsjtx2
+DefaultGroupName=wsjtx2
+
+[Files]
+Source: "c:\Users\joe\wsjt\wsjtx_install\*.exe";                         DestDir: "{app}"
+Source: "c:\Users\joe\wsjt\wsjtx_install\*.dll";                         DestDir: "{app}";
+Source: "c:\Users\joe\wsjt\wsjtx_install\*.dat";                         DestDir: "{app}";
+Source: "c:\Users\joe\wsjt\wsjtx_install\wsjt.ico";                      DestDir: "{app}";
+Source: "c:\Users\joe\wsjt\wsjtx_install\CALL3.TXT";                     DestDir: "{app}";  Flags: onlyifdoesntexist
+Source: "c:\Users\joe\wsjt\wsjtx\shortcuts.txt";                         DestDir: "{app}"
+Source: "c:\Users\joe\wsjt\wsjtx\mouse_commands.txt";                    DestDir: "{app}"
+Source: "c:\Users\joe\wsjt\wsjtx\WSJT-X_Users_Guide_v1.1.pdf";           DestDir: "{app}"
+Source: "c:\Users\joe\wsjt\wsjtx_install\save\Samples\130418_1742.wav";  DestDir: "{app}\save\Samples";
+Source: "c:\Users\joe\wsjt\wsjtx_install\save\Samples\130610_2343.wav";  DestDir: "{app}\save\Samples";
+
+[Icons]
+Name: "{group}\wsjtx2";        Filename: "{app}\wsjtx.exe";   WorkingDir: {app}; IconFilename: {app}\wsjt.ico
+Name: "{userdesktop}\wsjtx2";  Filename: "{app}\wsjtx.exe";   WorkingDir: {app}; IconFilename: {app}\wsjt.ico
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/wsjtx.git



More information about the pkg-hamradio-commits mailing list