mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-22 12:23:37 -05:00
Merge branch 'release-2.5.0'
This commit is contained in:
commit
2c07d5af3e
@ -71,7 +71,7 @@ message (STATUS "******************************************************")
|
||||
|
||||
include (set_build_type)
|
||||
# RC 0 or omitted is a development build, GA is a General Availability release build
|
||||
set_build_type (RC 1)
|
||||
set_build_type (RC 2)
|
||||
set (wsjtx_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
|
||||
|
||||
#
|
||||
@ -169,6 +169,7 @@ set (fort_qt_CXXSRCS
|
||||
)
|
||||
|
||||
set (wsjt_qt_CXXSRCS
|
||||
helper_functions.cpp
|
||||
qt_helpers.cpp
|
||||
widgets/MessageBox.cpp
|
||||
MetaDataRegistry.cpp
|
||||
@ -237,6 +238,7 @@ set (wsjt_qt_CXXSRCS
|
||||
Network/NetworkAccessManager.cpp
|
||||
widgets/LazyFillComboBox.cpp
|
||||
widgets/CheckableItemComboBox.cpp
|
||||
widgets/BandComboBox.cpp
|
||||
)
|
||||
|
||||
set (wsjt_qtmm_CXXSRCS
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include <boost/log/core.hpp>
|
||||
#include "Logger.hpp"
|
||||
|
||||
class QObject;
|
||||
@ -12,8 +13,8 @@ class QEvent;
|
||||
// We can't use the GUI after QApplication::exit() is called so
|
||||
// uncaught exceptions can get lost on Windows systems where there is
|
||||
// no console terminal, so here we override QApplication::notify() and
|
||||
// wrap the base class call with a try block to catch and display
|
||||
// exceptions in a message box.
|
||||
// wrap the base class call with a try block to catch and log any
|
||||
// uncaught exceptions.
|
||||
//
|
||||
class ExceptionCatchingApplication
|
||||
: public QApplication
|
||||
@ -31,12 +32,16 @@ public:
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
LOG_FATAL (e.what ());
|
||||
LOG_FATAL ("Unexpected exception caught in event loop: " << e.what ());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_FATAL ("Unexpected fatal error");
|
||||
LOG_FATAL ("Unexpected unknown exception caught in event loop");
|
||||
}
|
||||
// There's nowhere to go from here as Qt will not pass exceptions
|
||||
// through the event loop, so we must abort.
|
||||
boost::log::core::get ()->flush ();
|
||||
qFatal ("Aborting");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
40
NEWS
40
NEWS
@ -12,6 +12,46 @@
|
||||
Copyright 2001 - 2021 by Joe Taylor, K1JT.
|
||||
|
||||
|
||||
Release: WSJT-X 2.5.0-rc2
|
||||
Jun 28, 2021
|
||||
-------------------------
|
||||
|
||||
Remember that the WSJT-X 2.5.0 package includes MAP65 3.0.0. Changes
|
||||
in the package since WSJT-X 2.5.0-rc1 include the following
|
||||
enhancements and defect repairs:
|
||||
|
||||
MAP65:
|
||||
- Compute polarization angle for Xpol systems and display to nearest
|
||||
degree
|
||||
- Compute and display the recommended Tx polarization
|
||||
- Protect against Fortran bounds errors in several places
|
||||
- Insert leading 0 when needed in UTC hours and minutes on waterfall
|
||||
- Wideband Q65 synchronization corrected to include single-polarization
|
||||
mode
|
||||
- Corrected a one-symbol (0.6 s) delay in Q65 Tx audio
|
||||
- Basic instruction document for building an MS Windows portaudio DLL
|
||||
for MAP65 users who are unable to use WDM/KS drivers for their
|
||||
multi-channel sound cards.
|
||||
|
||||
WSJT-X (including the decoder for Q65 used by MAP65):
|
||||
- Increase maximum DT to 5.5 s when EME decoding is enabled in Q65
|
||||
- Fix generation of Tx5 message when "hiscall" has suffix /P or /R.
|
||||
- Improve width management of GUI's band-selection combo box
|
||||
- Restore plotting of Q65 sync curve after a q3 decode
|
||||
- Disable selection of "View | Message Averaging F7" for modes
|
||||
other than JT4 and JT65
|
||||
- Switching to Q65 mode now defaults to "Decode | Fast"
|
||||
- Repair a long standing regression with message generation for
|
||||
72-bit modes when using a compound callsign.
|
||||
- Repair a defect in diagnostic logging that could cause crashes on
|
||||
some platforms.
|
||||
- Repair a defect which failed to strip leading and trailing spaces
|
||||
on input of callsigns during validation.
|
||||
- Hamlib updates including repair of defects with PTT handling on a
|
||||
separate serial port via rigctld, delayed PTT with Elecraft K3
|
||||
series rigs, and support for the Icom IC-575 rig.
|
||||
- Updated CTY.DAT database
|
||||
|
||||
Release: WSJT-X 2.5.0-rc1
|
||||
Jun 3, 2021
|
||||
-------------------------
|
||||
|
@ -12,6 +12,46 @@
|
||||
Copyright 2001 - 2021 by Joe Taylor, K1JT.
|
||||
|
||||
|
||||
Release: WSJT-X 2.5.0-rc2
|
||||
Jun 28, 2021
|
||||
-------------------------
|
||||
|
||||
Remember that the WSJT-X 2.5.0 package includes MAP65 3.0.0. Changes
|
||||
in the package since WSJT-X 2.5.0-rc1 include the following
|
||||
enhancements and defect repairs:
|
||||
|
||||
MAP65:
|
||||
- Compute polarization angle for Xpol systems and display to nearest
|
||||
degree
|
||||
- Compute and display the recommended Tx polarization
|
||||
- Protect against Fortran bounds errors in several places
|
||||
- Insert leading 0 when needed in UTC hours and minutes on waterfall
|
||||
- Wideband Q65 synchronization corrected to include single-polarization
|
||||
mode
|
||||
- Corrected a one-symbol (0.6 s) delay in Q65 Tx audio
|
||||
- Basic instruction document for building an MS Windows portaudio DLL
|
||||
for MAP65 users who are unable to use WDM/KS drivers for their
|
||||
multi-channel sound cards.
|
||||
|
||||
WSJT-X (including the decoder for Q65 used by MAP65):
|
||||
- Increase maximum DT to 5.5 s when EME decoding is enabled in Q65
|
||||
- Fix generation of Tx5 message when "hiscall" has suffix /P or /R.
|
||||
- Improve width management of GUI's band-selection combo box
|
||||
- Restore plotting of Q65 sync curve after a q3 decode
|
||||
- Disable selection of "View | Message Averaging F7" for modes
|
||||
other than JT4 and JT65
|
||||
- Switching to Q65 mode now defaults to "Decode | Fast"
|
||||
- Repair a long standing regression with message generation for
|
||||
72-bit modes when using a compound callsign.
|
||||
- Repair a defect in diagnostic logging that could cause crashes on
|
||||
some platforms.
|
||||
- Repair a defect which failed to strip leading and trailing spaces
|
||||
on input of callsigns during validation.
|
||||
- Hamlib updates including repair of defects with PTT handling on a
|
||||
separate serial port via rigctld, delayed PTT with Elecraft K3
|
||||
series rigs, and support for the Icom IC-575 rig.
|
||||
- Updated CTY.DAT database
|
||||
|
||||
Release: WSJT-X 2.5.0-rc1
|
||||
Jun 3, 2021
|
||||
-------------------------
|
||||
|
@ -93,7 +93,7 @@ namespace
|
||||
<< boost::log::add_value ("Line", context.line)
|
||||
<< boost::log::add_value ("File", file)
|
||||
<< boost::log::add_value ("Function", function)
|
||||
<< msg.toStdWString ();
|
||||
<< msg.toStdString ();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -101,7 +101,7 @@ namespace
|
||||
<< boost::log::add_value ("Line", context.line)
|
||||
<< boost::log::add_value ("File", file)
|
||||
<< boost::log::add_value ("Function", function)
|
||||
<< context.category << ": " << msg.toStdWString ();
|
||||
<< context.category << ": " << msg.toStdString ();
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ namespace
|
||||
#else
|
||||
, keywords::file_name =
|
||||
#endif
|
||||
app_data.absoluteFilePath ("logs/wsjtx_syslog_%Y-%m.log").toStdString ()
|
||||
app_data.absoluteFilePath ("logs/wsjtx_syslog_%Y-%m.log").toStdWString ()
|
||||
, keywords::time_based_rotation = sinks::file::rotation_at_time_point (gregorian::greg_day (1), 0, 0, 0)
|
||||
, keywords::open_mode = std::ios_base::out | std::ios_base::app
|
||||
#if BOOST_VERSION / 100 >= 1063
|
||||
|
@ -214,7 +214,7 @@ a suitable location like ~/build and change working directory to it:
|
||||
Configure and build and install the library in a suitable place (I use
|
||||
~/local as a root directory for installed packages.
|
||||
|
||||
~/src/portaudio/configure --prefix=$(HOME)/local/portaudio/mingw64 \
|
||||
~/src/portaudio/configure --prefix=$HOME/local/portaudio/mingw64 \
|
||||
--with-winapi=wmme,directx,wdmks --disable-static --enable-shared CFLAGS=-DNDEBUG
|
||||
make && make install
|
||||
|
||||
|
76
doc/building portaudio on Windows with ASIO support.txt
Normal file
76
doc/building portaudio on Windows with ASIO support.txt
Normal file
@ -0,0 +1,76 @@
|
||||
Building the MS Windows portaudio DLL with ASIO Support
|
||||
=======================================================
|
||||
|
||||
Some MAP65 users may not be able to use WDM/KS hosted audio devices
|
||||
due to sharing issues with other applications, to circumvent this they
|
||||
can build a version of the portaudio DLL with ASIO support. We cannot
|
||||
provide a portaudio DLL with ASIO support as the Steinberg ASIO SDK
|
||||
license prevents redistribution of drivers or hosting applications
|
||||
without a commercial license agreement, nor is the Steinberg ASIO SDK
|
||||
license compatible with the GPL v3 license that MAP65 is released
|
||||
under. Users may build a portaudio DLL themselves, strictly for
|
||||
personal use, under the terms of the Steinberg ASIO license.
|
||||
|
||||
Building portaudio on MS Windows is done most easily using the MinGW
|
||||
(GNU) tool-chain which can be installed on MS Windows using the MSYS2
|
||||
unix like environment which in turn includes a package manager
|
||||
(pacman) that allows simple installation of necessary prerequisite
|
||||
packages like the MinGW 64-bit tool-chain. To install MSYS2 download
|
||||
the latest 64-bit installer from the MSYS2 project web site. This page
|
||||
contains links to the installer download and detailed instructions to
|
||||
install and bring up-to-date the base MSYS2 packages.
|
||||
|
||||
https://www.msys2.org/wiki/MSYS2-installation/
|
||||
|
||||
Take particular care to restart the MSYS2 shell window when directed
|
||||
to.
|
||||
|
||||
Once MSYS2 is installed you will find a start menu entry labelled
|
||||
"MSYS2 MinGW 64-bit", use that to start a fresh MSYS2 shell window for
|
||||
the rest of these instructions.
|
||||
|
||||
The first step is to install some prerequisite packages which contain
|
||||
the tools needed to prepare and build the portaudio DLL. Execute the
|
||||
following command to do that:
|
||||
|
||||
pacman -S make diffutils unzip mingw-w64-x86_64-gcc sed tar curl
|
||||
|
||||
Then make directories to put downloaded sources in and for building:
|
||||
|
||||
mkdir -p ~/src ~/build/portaudio
|
||||
|
||||
Fetch and unpack the Steinberg ASIO SDK (note the ASIO SDK license
|
||||
document included, particularly that it strictly disallows
|
||||
redistribution of the DLL we will be building here), and portaudio
|
||||
sources:
|
||||
|
||||
curl -Lo ~/src/asiosdk.zip https://www.steinberg.net/asiosdk
|
||||
(cd ~/src ; unzip asiosdk.zip)
|
||||
curl -O --output-dir ~/src \
|
||||
http://files.portaudio.com/archives/pa_stable_v190700_20210406.tgz
|
||||
tar -C ~/src -xf ~/src/pa_stable_v190700_20210406.tgz
|
||||
|
||||
Patch and build the portaudio library:
|
||||
|
||||
sed -i -e 's/-luuid//g' ~/src/portaudio/configure
|
||||
cd ~/build/portaudio
|
||||
~/src/portaudio/configure --with-winapi=wmme,directx,wdmks,asio \
|
||||
--with-asiodir=$HOME/src/asiosdk_2.3.3_2019-06-14 \
|
||||
--disable-static --enable-shared
|
||||
make -j
|
||||
|
||||
You can check the library build is working by running a test program
|
||||
that was also built:
|
||||
|
||||
bin/pa_devs
|
||||
|
||||
which should list every audio device on your system by every host API,
|
||||
if all is well that should include the audio devices on your system
|
||||
with ASIO drivers.
|
||||
|
||||
Copy the new portaudio DLL to your WSJT-X/MAP65 installation directory:
|
||||
|
||||
cp lib/.libs/libportaudio-2.dll /c/WSJT/wsjtx/bin/
|
||||
|
||||
Note that if you upgrade WSJT-X you will need to copy this DLL again
|
||||
since it will be overwritten by one with no ASIO support.
|
@ -141,7 +141,7 @@ C:\Tools\boost-build\MinGW32\bin\b2 -j8 toolset=gcc ^
|
||||
--build-dir=%USERPROFILE%\build\boost ^
|
||||
address-model=32 architecture=x86 variant=debug,release ^
|
||||
link=shared threading=multi ^
|
||||
--with-log --with-stacktrace --prefix=C:\Tools\boost install
|
||||
--with-log --with-stacktrace --with-timer --prefix=C:\Tools\boost install
|
||||
|
||||
If all is well you should see the following line about a 1/3 of the
|
||||
way through the initial configuration steps.
|
||||
@ -188,7 +188,7 @@ cd ..\..
|
||||
C:\Tools\boost-build\MinGW64\bin\b2 -j8 toolset=gcc-8~64 ^
|
||||
address-model=64 architecture=x86 variant=debug,release ^
|
||||
link=shared threading=multi ^
|
||||
--with-log --with-stacktrace ^
|
||||
--with-log --with-stacktrace --with-timer ^
|
||||
--build-dir=%USERPROFILE%\build\boost ^
|
||||
--prefix=C:\Tools\boost install
|
||||
|
||||
@ -206,9 +206,11 @@ After some time it should complete with something like:
|
||||
warnings can usually be ignored. If successful; you can release some
|
||||
space by cleaning the build tree:
|
||||
|
||||
C:\Tools\boost-build\MinGW32\bin\b2 toolset=gcc-8~64 ^
|
||||
C:\Tools\boost-build\MinGW64\bin\b2 toolset=gcc-8~64 ^
|
||||
address-model=64 --build-dir=%USERPROFILE%\build\boost ^
|
||||
--build-type=complete clean
|
||||
|
||||
|
||||
Run-time Environment
|
||||
--------------------
|
||||
|
||||
|
220
getfile.cpp
220
getfile.cpp
@ -1,9 +1,9 @@
|
||||
#include "getfile.h"
|
||||
#include <QDir>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
#include <QRandomGenerator>
|
||||
#include <random>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@ -22,155 +22,6 @@
|
||||
#include <err.h>
|
||||
#endif
|
||||
|
||||
#include "commons.h"
|
||||
|
||||
extern dec_data dec_data;
|
||||
|
||||
void getfile(QString fname, int ntrperiod)
|
||||
{
|
||||
// struct WAVHDR {
|
||||
// char ariff[4];
|
||||
// int lenfile;
|
||||
// char awave[4];
|
||||
// char afmt[4];
|
||||
// int lenfmt;
|
||||
// short nfmt2;
|
||||
// short nchan2;
|
||||
// int nsamrate;
|
||||
// int nbytesec;
|
||||
// short nbytesam2;
|
||||
// short nbitsam2;
|
||||
// char adata[4];
|
||||
// int ndata;
|
||||
// } hdr;
|
||||
|
||||
char name[512];
|
||||
strncpy(name,fname.toLatin1(), sizeof (name) - 1);
|
||||
name[sizeof (name) - 1] = '\0';
|
||||
|
||||
FILE* fp=fopen(name,"rb");
|
||||
|
||||
int i1=fname.lastIndexOf("/");
|
||||
QString baseName=fname.mid(i1+1);
|
||||
|
||||
i1=fname.indexOf(".wav",0,Qt::CaseInsensitive);
|
||||
dec_data.params.nutc=0;
|
||||
if(i1>0) {
|
||||
int i0=fname.indexOf("_",-11);
|
||||
if(i1==i0+7) {
|
||||
dec_data.params.nutc=fname.mid(i1-6,6).toInt();
|
||||
} else {
|
||||
dec_data.params.nutc=100*fname.mid(i1-4,4).toInt();
|
||||
}
|
||||
}
|
||||
if(ntrperiod > 120 or ntrperiod <0) ntrperiod=120;
|
||||
int npts=ntrperiod*12000;
|
||||
memset(dec_data.d2,0,2*npts);
|
||||
|
||||
if(fp != NULL) {
|
||||
struct
|
||||
{
|
||||
char id[4];
|
||||
uint32_t size;
|
||||
} desc;
|
||||
char type[4];
|
||||
struct
|
||||
{
|
||||
uint16_t nfmt2;
|
||||
uint16_t nchan2;
|
||||
uint32_t nsamrate;
|
||||
uint32_t nbytesec;
|
||||
uint16_t nbytesam2;
|
||||
uint16_t nbitsam2;
|
||||
} fmt;
|
||||
|
||||
// read header
|
||||
if (fread(&desc, sizeof desc, 1, fp) < 1) return; // RIFF
|
||||
if (fread(type, sizeof type, 1, fp) < 1) return; // WAVE
|
||||
do
|
||||
{
|
||||
if (fread(&desc, sizeof desc, 1, fp) < 1) return; // WAVE component
|
||||
if (!memcmp(desc.id,"fmt ",4)) {
|
||||
fpos_t pos;
|
||||
fgetpos(fp,&pos);
|
||||
if (fread(&fmt,sizeof fmt,1,fp) < 1) return;
|
||||
fsetpos(fp,&pos);
|
||||
}
|
||||
if (!memcmp(desc.id,"data",sizeof desc.id)) break;
|
||||
} while (!fseek(fp,(desc.size + 1) / 2 * 2,SEEK_CUR));
|
||||
|
||||
// Read (and ignore) a 44-byte WAV header; then read data
|
||||
// int n=fread(&hdr,1,44,fp);
|
||||
int n=fread(dec_data.d2,2,npts,fp);
|
||||
if(fmt.nsamrate==11025) wav12_(dec_data.d2,dec_data.d2,&n,(short*)&fmt.nbitsam2);
|
||||
fclose(fp);
|
||||
dec_data.params.newdat=1;
|
||||
dec_data.params.kin=n;
|
||||
}
|
||||
}
|
||||
|
||||
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[512];
|
||||
strncpy(name,fname.toLatin1(),sizeof (name) - 1);
|
||||
name[sizeof (name) - 1] = '\0';
|
||||
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(dec_data.d2,buf,2*npts);
|
||||
// fwrite(buf,2,npts,fp);
|
||||
fwrite(dec_data.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()
|
||||
@ -202,72 +53,3 @@ float gran()
|
||||
return v2*fac;
|
||||
#endif
|
||||
}
|
||||
|
||||
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 = t.asprintf("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;
|
||||
}
|
||||
|
11
getfile.h
11
getfile.h
@ -1,19 +1,8 @@
|
||||
// -*- Mode: C++ -*-
|
||||
#ifndef GETFILE_H
|
||||
#define GETFILE_H
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
|
||||
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);
|
||||
void wav12_(short d2[], short d1[], int* nbytes, short* nbitsam2);
|
||||
}
|
||||
|
||||
|
||||
#endif // GETFILE_H
|
||||
|
33
helper_functions.cpp
Normal file
33
helper_functions.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "helper_functions.h"
|
||||
|
||||
double tx_duration(QString mode, double trPeriod, int nsps, bool bFast9)
|
||||
{
|
||||
double txt=0.0;
|
||||
if(mode=="FT4") txt=1.0 + 105*576/12000.0; // FT4
|
||||
if(mode=="FT8") txt=1.0 + 79*1920/12000.0; // FT8
|
||||
if(mode=="JT4") txt=1.0 + 207.0*2520/11025.0; // JT4
|
||||
if(mode=="JT9") txt=1.0 + 85.0*nsps/12000.0; // JT9
|
||||
if(mode=="JT65") txt=1.0 + 126*4096/11025.0; // JT65
|
||||
if(mode=="Q65") { // Q65
|
||||
if(trPeriod==15) txt=0.5 + 85*1800/12000.0;
|
||||
if(trPeriod==30) txt=0.5 + 85*3600/12000.0;
|
||||
if(trPeriod==60) txt=1.0 + 85*7200/12000.0;
|
||||
if(trPeriod==120) txt=1.0 + 85*16000/12000.0;
|
||||
if(trPeriod==300) txt=1.0 + 85*41472/12000.0;
|
||||
}
|
||||
if(mode=="WSPR") txt=2.0 + 162*8192/12000.0; // WSPR
|
||||
if(mode=="FST4" or mode=="FST4W") { //FST4, FST4W
|
||||
if(trPeriod==15) txt=1.0 + 160*720/12000.0;
|
||||
if(trPeriod==30) txt=1.0 + 160*1680/12000.0;
|
||||
if(trPeriod==60) txt=1.0 + 160*3888/12000.0;
|
||||
if(trPeriod==120) txt=1.0 + 160*8200/12000.0;
|
||||
if(trPeriod==300) txt=1.0 + 160*21504/12000.0;
|
||||
if(trPeriod==900) txt=1.0 + 160*66560/12000.0;
|
||||
if(trPeriod==1800) txt=1.0 + 160*134400/12000.0;
|
||||
}
|
||||
if(mode=="MSK144" or bFast9) {
|
||||
txt=trPeriod-0.25; // JT9-fast, MSK144
|
||||
}
|
||||
if(mode=="Echo") txt=2.4;
|
||||
return txt;
|
||||
}
|
7
helper_functions.h
Normal file
7
helper_functions.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef HELPER_FUNCTIONS_H
|
||||
#define HELPER_FUNCTIONS_H
|
||||
#include <QString>
|
||||
|
||||
double tx_duration(QString mode, double trPeriod, int nsps, bool bFast9);
|
||||
|
||||
#endif // HELPER_FUNCTIONS_H
|
@ -148,13 +148,16 @@ contains
|
||||
nused=1
|
||||
iavg=0
|
||||
call timer('q65_dec0',0)
|
||||
! Call top-level routine in q65 module: establish sync and try for a q3 decode.
|
||||
! Call top-level routine in q65 module: establish sync and try for a
|
||||
! q3 or q0 decode.
|
||||
call q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
emedelay,xdt,f0,snr1,width,dat4,snr2,idec)
|
||||
call timer('q65_dec0',1)
|
||||
! write(*,3001) '=a',sum(abs(float(iwave))),nfqso,ntol,ndepth,xdt,f0,idec
|
||||
!3001 format(a2,f15.0,3i5,f7.2,f7.1,i5)
|
||||
|
||||
if(idec.ge.0) then
|
||||
dtdec=xdt !We have a list-decode result at nfqso
|
||||
dtdec=xdt !We have a q3 or q0 decode at nfqso
|
||||
f0dec=f0
|
||||
go to 100
|
||||
endif
|
||||
@ -207,6 +210,7 @@ contains
|
||||
call q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
emedelay,xdt,f0,snr1,width,dat4,snr2,idec)
|
||||
call timer('list_avg',1)
|
||||
|
||||
if(idec.ge.0) then
|
||||
dtdec=xdt !We have a list-decode result from averaged data
|
||||
f0dec=f0
|
||||
|
@ -124,7 +124,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
dtstep=nsps/(NSTEP*12000.0) !Step size in seconds
|
||||
lag1=-1.0/dtstep
|
||||
lag2=1.0/dtstep + 0.9999
|
||||
if(nsps.ge.3600 .and. emedelay.gt.0) lag2=4.0/dtstep + 0.9999 !Include EME
|
||||
if(nsps.ge.3600 .and. emedelay.gt.0) lag2=5.5/dtstep + 0.9999 !Include EME
|
||||
j0=0.5/dtstep
|
||||
if(nsps.ge.7200) j0=1.0/dtstep !Nominal start-signal index
|
||||
|
||||
@ -139,16 +139,17 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
endif
|
||||
|
||||
i0=nint(nfqso/df) !Target QSO frequency
|
||||
if(i0-64.lt.1 .or. i0-65+LL.gt.iz) go to 900 !Frequency out of range
|
||||
call pctile(s1(i0-64:i0-65+LL,1:jz),LL*jz,45,base)
|
||||
ii1=max(1,i0-64)
|
||||
ii2=i0-65+LL
|
||||
call pctile(s1(ii1:ii2,1:jz),ii2-ii1+1*jz,45,base)
|
||||
s1=s1/base
|
||||
s1raw=s1
|
||||
|
||||
! Apply fast AGC to the symbol spectra
|
||||
s1max=20.0 !Empirical choice
|
||||
do j=1,jz !### Maybe wrong way? ###
|
||||
smax=maxval(s1(i0-64:i0-65+LL,j))
|
||||
if(smax.gt.s1max) s1(i0-64:i0-65+LL,j)=s1(i0-64:i0-65+LL,j)*s1max/smax
|
||||
smax=maxval(s1(ii1:ii2,j))
|
||||
if(smax.gt.s1max) s1(ii1:ii2,j)=s1(ii1:ii2,j)*s1max/smax
|
||||
enddo
|
||||
|
||||
dat4=0
|
||||
@ -162,9 +163,10 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
call timer('list_dec',0)
|
||||
call q65_dec_q3(s1,iz,jz,s3,LL,ipk,jpk,snr2,dat4,idec,decoded)
|
||||
call timer('list_dec',1)
|
||||
if(idec.eq.3) go to 900 !Good q3 decode, we're done
|
||||
! If idec=3 we have a q3 decode. Continue to compute sync curve for plotting.
|
||||
endif
|
||||
|
||||
! Get 2d CCF and ccf2 using sync symbols only
|
||||
if(iavg.eq.0) then
|
||||
call timer('ccf_22a ',0)
|
||||
call q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
@ -172,7 +174,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
call timer('ccf_22a ',1)
|
||||
endif
|
||||
|
||||
! Get 2d CCF and ccf2 using sync symbols only
|
||||
! Get 2d CCF and ccf2_avg using sync symbols only
|
||||
if(iavg.ge.1) then
|
||||
call timer('ccf_22b ',0)
|
||||
call q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
@ -211,7 +213,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
|
||||
call q65_write_red(iz,xdt,ccf2_avg,ccf2)
|
||||
|
||||
if(iavg.eq.0 .or. iavg.eq.2) then
|
||||
if(idec.lt.0 .and. (iavg.eq.0 .or. iavg.eq.2)) then
|
||||
call q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
|
||||
endif
|
||||
|
||||
@ -439,8 +441,8 @@ subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
ib=min(nfb,4900)/df
|
||||
if(nqd.ne.1 .or. iavg.ne.0) max_drift=0
|
||||
if(max_drift.ne.0) then
|
||||
ia=nint((nfqso-ntol)/df)
|
||||
ib=nint((nfqso+ntol)/df)
|
||||
ia=max(nint(100/df),nint((nfqso-ntol)/df))
|
||||
ib=min(nint(4900/df),nint((nfqso+ntol)/df))
|
||||
endif
|
||||
|
||||
do i=ia,ib
|
||||
|
@ -73,7 +73,7 @@ program test_q65
|
||||
! 1 2 3 4 5 6 7
|
||||
! 1234567890123456789012345678901234567890123456789012345678901234567890123456'
|
||||
cmd1='q65sim "K1ABC W9XYZ EN37 " A 1500 5.0 0.0 0.0 1 60 100 -10.0 > junk0'
|
||||
cmd2='jt9 -3 -p 15 -L 300 -H 3000 -d 3 -b A -Q 3 -f 1500 *.wav > junk'
|
||||
cmd2='jt9 -3 -p 15 -L 300 -H 3000 -d 3 -b A -Q 3 -f 1500 -X 32 *.wav > junk'
|
||||
|
||||
write(cmd1(10:33),'(a)') '"'//msg//'"'
|
||||
cmd1(35:35)=csubmode
|
||||
|
@ -60,8 +60,8 @@ set (libm65_FSRCS
|
||||
nchar.f90
|
||||
noisegen.f90
|
||||
packjt.f90
|
||||
# pctile.f90
|
||||
pfxdump.f90
|
||||
polfit.f90
|
||||
recvpkt.f90
|
||||
rfile3a.f90
|
||||
s3avg.f90
|
||||
@ -80,6 +80,7 @@ set (libm65_FSRCS
|
||||
trimlist.f90
|
||||
twkfreq.f90
|
||||
twkfreq_xy.f90
|
||||
txpol.f90
|
||||
wavhdr.f90
|
||||
|
||||
f77_wisdom.f
|
||||
|
@ -36,7 +36,7 @@ subroutine gen_q65_wave(msg,ntxfreq,mode65,msgsent,iwave,nwave)
|
||||
j0=0
|
||||
do i=1,iz
|
||||
t=t+dt
|
||||
j=t/tsym
|
||||
j=t/tsym + 1.0
|
||||
if(j.ne.j0) then
|
||||
f=f0 + itone(j)*dfgen
|
||||
dphi=twopi*dt*f
|
||||
|
@ -19,7 +19,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
real*8 fcenter
|
||||
character*22 msg(MAXMSG)
|
||||
character*3 shmsg0(4)
|
||||
character mycall*12,hiscall*12,mygrid*6,hisgrid*6,grid*6,cp*1,cm*1
|
||||
character mycall*12,hiscall*12,mygrid*6,hisgrid*6,cp*1,cm*1
|
||||
integer indx(MAXMSG),nsiz(MAXMSG)
|
||||
logical done(MAXMSG)
|
||||
logical xpol,bq65,q65b_called
|
||||
@ -43,12 +43,13 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
mode65=mod(nmode,10)
|
||||
if(mode65.eq.3) mode65=4
|
||||
mode_q65=nmode/10
|
||||
xpol=(nxpol.ne.0)
|
||||
|
||||
nts_jt65=2**(mode65-1) !JT65 tone separation factor
|
||||
nts_q65=2**(mode_q65) !Q65 tone separation factor
|
||||
if(nagain.eq.0) then
|
||||
call timer('get_cand',0)
|
||||
call get_candidates(ss,savg,mfa,mfb,nts_jt65,nts_q65,cand,ncand)
|
||||
call get_candidates(ss,savg,xpol,mfa,mfb,nts_jt65,nts_q65,cand,ncand)
|
||||
call timer('get_cand',1)
|
||||
candec=.false.
|
||||
endif
|
||||
@ -66,7 +67,6 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
|
||||
mcall3a=mcall3b
|
||||
mousefqso0=mousefqso
|
||||
xpol=(nxpol.ne.0)
|
||||
if(.not.xpol) ndphi=0
|
||||
nsum=0
|
||||
|
||||
@ -318,28 +318,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
if(npol.lt.0) npol=npol+180
|
||||
endif
|
||||
|
||||
! If Tx station's grid is in decoded message, compute optimum TxPol
|
||||
i1=index(decoded,' ')
|
||||
i2=index(decoded(i1+1:),' ') + i1
|
||||
grid=' '
|
||||
if(i2.ge.8 .and. i2.le.18) grid=decoded(i2+1:i2+4)//'mm'
|
||||
ntxpol=0
|
||||
cp=' '
|
||||
if(xpol) then
|
||||
if(grid(1:1).ge.'A' .and. grid(1:1).le.'R' .and. &
|
||||
grid(2:2).ge.'A' .and. grid(2:2).le.'R' .and. &
|
||||
grid(3:3).ge.'0' .and. grid(3:3).le.'9' .and. &
|
||||
grid(4:4).ge.'0' .and. grid(4:4).le.'9') then
|
||||
ntxpol=mod(npol-nint(2.0*dpol(mygrid,grid))+720,180)
|
||||
if(nxant.eq.0) then
|
||||
cp='H'
|
||||
if(ntxpol.gt.45 .and. ntxpol.le.135) cp='V'
|
||||
else
|
||||
cp='/'
|
||||
if(ntxpol.ge.90 .and. ntxpol.lt.180) cp='\'
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
call txpol(xpol,decoded,mygrid,npol,nxant,ntxpol,cp)
|
||||
|
||||
if(ndphi.eq.0) then
|
||||
write(*,1010) nkHz,ndf,npol,nutc,dt,nsync2, &
|
||||
@ -368,9 +347,9 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
q65b_called=.true.
|
||||
f0=cand(icand)%f
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
xpol,mycall,hiscall,hisgrid,mode_q65,f0,fqso,newdat, &
|
||||
nagain,max_drift,idec)
|
||||
call q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf, &
|
||||
ntol,xpol,mycall,mygrid, hiscall,hisgrid,mode_q65,f0,fqso, &
|
||||
newdat,nagain,max_drift,idec)
|
||||
call timer('q65b ',1)
|
||||
if(idec.ge.0) candec(icand)=.true.
|
||||
enddo
|
||||
@ -379,9 +358,9 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
ikhz=mousefqso
|
||||
f0=freq - (nkhz_center-48.0-1.27046) !### ??? ###
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
xpol,mycall,hiscall,hisgrid,mode_q65,f0,fqso,newdat, &
|
||||
nagain,max_drift,idec)
|
||||
call q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf, &
|
||||
ntol,xpol,mycall,mygrid,hiscall,hisgrid,mode_q65,f0,fqso, &
|
||||
newdat,nagain,max_drift,idec)
|
||||
call timer('q65b ',1)
|
||||
endif
|
||||
endif
|
||||
@ -416,8 +395,8 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
ikhz=nint(freq)
|
||||
f0=cand(icand)%f
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
xpol,mycall,hiscall,hisgrid,mode_q65,f0,fqso,newdat, &
|
||||
call q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
xpol,mycall,mygrid,hiscall,hisgrid,mode_q65,f0,fqso,newdat, &
|
||||
nagain,max_drift,idec)
|
||||
call timer('q65b ',1)
|
||||
if(idec.ge.0) candec(icand)=.true.
|
||||
@ -494,28 +473,8 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
if(npol.lt.0) npol=npol+180
|
||||
endif
|
||||
|
||||
! If Tx station's grid is in decoded message, compute optimum TxPol
|
||||
i1=index(decoded,' ')
|
||||
i2=index(decoded(i1+1:),' ') + i1
|
||||
grid=' '
|
||||
if(i2.ge.8 .and. i2.le.18) grid=decoded(i2+1:i2+4)//'mm'
|
||||
ntxpol=0
|
||||
cp=' '
|
||||
if(xpol) then
|
||||
if(grid(1:1).ge.'A' .and. grid(1:1).le.'R' .and. &
|
||||
grid(2:2).ge.'A' .and. grid(2:2).le.'R' .and. &
|
||||
grid(3:3).ge.'0' .and. grid(3:3).le.'9' .and. &
|
||||
grid(4:4).ge.'0' .and. grid(4:4).le.'9') then
|
||||
ntxpol=mod(npol-nint(2.0*dpol(mygrid,grid))+720,180)
|
||||
if(nxant.eq.0) then
|
||||
cp='H'
|
||||
if(ntxpol.gt.45 .and. ntxpol.le.135) cp='V'
|
||||
else
|
||||
cp='/'
|
||||
if(ntxpol.ge.90 .and. ntxpol.lt.180) cp='\'
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
call txpol(xpol,decoded,mygrid,npol,nxant,ntxpol,cp)
|
||||
|
||||
cmode='#A'
|
||||
if(mode65.eq.2) cmode='#B'
|
||||
if(mode65.eq.4) cmode='#C'
|
||||
|
86
map65/libm65/polfit.f90
Normal file
86
map65/libm65/polfit.f90
Normal file
@ -0,0 +1,86 @@
|
||||
subroutine polfit(y,npts,a)
|
||||
|
||||
! Input: y(npts) !Expect npts=4
|
||||
! Output: a(1) = baseline
|
||||
! a(2) = amplitude
|
||||
! a(3) = theta (deg)
|
||||
|
||||
real y(npts)
|
||||
real a(3)
|
||||
real deltaa(3)
|
||||
integer ipk(1)
|
||||
save
|
||||
|
||||
! Set starting values:
|
||||
a(1)=minval(y)
|
||||
a(2)=maxval(y)-a(1)
|
||||
ipk=maxloc(y)
|
||||
a(3)=(ipk(1)-1)*45.0
|
||||
|
||||
deltaa(1:2)=0.1*(a(2)-a(1))
|
||||
deltaa(3)=10.0
|
||||
nterms=3
|
||||
|
||||
! Start the iteration
|
||||
chisqr=0.
|
||||
chisqr0=1.e6
|
||||
iters=10
|
||||
|
||||
do iter=1,iters
|
||||
do j=1,nterms
|
||||
chisq1=fchisq_pol(y,npts,a)
|
||||
fn=0.
|
||||
delta=deltaa(j)
|
||||
10 a(j)=a(j)+delta
|
||||
chisq2=fchisq_pol(y,npts,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_pol(y,npts,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(2i2,2(2x,3f8.2),f12.5)
|
||||
enddo
|
||||
chisqr=fchisq_pol(y,npts,a)
|
||||
! write(*,4000) 0,0,a,chisqr
|
||||
if(deltaa(1).lt.0.01*(a(2)-a(1)) .and. deltaa(2).lt.0.01*(a(2)-a(1)) &
|
||||
.and. deltaa(3).lt.1.0) exit
|
||||
if(chisqr/chisqr0.gt.0.99) exit
|
||||
a(3)=mod(a(3)+360.0,180.0)
|
||||
chisqr0=chisqr
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine polfit
|
||||
|
||||
real function fchisq_pol(y,npts,a)
|
||||
|
||||
real y(npts),a(3)
|
||||
data rad/57.2957795/
|
||||
|
||||
chisq = 0.
|
||||
do i=1,npts
|
||||
theta=(i-1)*45.0
|
||||
yfit=a(1) + a(2)*cos((theta-a(3))/rad)**2
|
||||
chisq=chisq + (y(i) - yfit)**2
|
||||
enddo
|
||||
fchisq_pol=chisq
|
||||
|
||||
return
|
||||
end function fchisq_pol
|
@ -1,5 +1,6 @@
|
||||
subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
mycall0,hiscall0,hisgrid,mode_q65,f0,fqso,newdat,nagain,max_drift,idec)
|
||||
subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
mycall0,mygrid,hiscall0,hisgrid,mode_q65,f0,fqso,newdat,nagain, &
|
||||
max_drift,idec)
|
||||
|
||||
! This routine provides an interface between MAP65 and the Q65 decoder
|
||||
! in WSJT-X. All arguments are input data obtained from the MAP65 GUI.
|
||||
@ -16,6 +17,7 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
parameter (MAXFFT1=5376000) !56*96000
|
||||
parameter (MAXFFT2=336000) !56*6000 (downsampled by 1/16)
|
||||
parameter (NMAX=60*12000)
|
||||
parameter (RAD=57.2957795)
|
||||
! type(hdr) h !Header for the .wav file
|
||||
integer*2 iwave(60*12000)
|
||||
complex ca(MAXFFT1),cb(MAXFFT1) !FFTs of raw x,y data
|
||||
@ -25,10 +27,11 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
real*8 fcenter,freq0
|
||||
character*12 mycall0,hiscall0
|
||||
character*12 mycall,hiscall
|
||||
character*6 hisgrid
|
||||
character*6 mygrid,hisgrid
|
||||
character*4 grid4
|
||||
character*80 line
|
||||
character*80 wsjtx_dir
|
||||
character*1 cp,cmode*2
|
||||
common/cacb/ca,cb
|
||||
save
|
||||
|
||||
@ -88,10 +91,14 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
! 96000 5376000 0.017857143 336000 6000.000
|
||||
! 95238 5120000 0.018601172 322560 5999.994
|
||||
|
||||
if(ipol.eq.1) cz(0:MAXFFT2-1)=cx
|
||||
if(ipol.eq.2) cz(0:MAXFFT2-1)=0.707*(cx+cy)
|
||||
if(ipol.eq.3) cz(0:MAXFFT2-1)=cy
|
||||
if(ipol.eq.4) cz(0:MAXFFT2-1)=0.707*(cx-cy)
|
||||
poldeg=0.
|
||||
if(xpol) then
|
||||
poldeg=sync(ipk)%pol
|
||||
cz(0:MAXFFT2-1)=cos(poldeg/RAD)*cx + sin(poldeg/RAD)*cy
|
||||
else
|
||||
cz(0:MAXFFT2-1)=cx
|
||||
endif
|
||||
|
||||
cz(MAXFFT2)=0.
|
||||
! Roll off below 500 Hz and above 2500 Hz.
|
||||
ja=nint(500.0/df)
|
||||
@ -136,21 +143,30 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
if(nsnr0.gt.-99) then
|
||||
nq65df=nint(1000*(0.001*k0*df+nkhz_center-48.0+1.000-1.27046-ikhz))-nfcal
|
||||
nq65df=nq65df + nfreq0 - 1000
|
||||
|
||||
npol=nint(poldeg)
|
||||
if(nxant.ne.0) then
|
||||
npol=npol-45
|
||||
if(npol.lt.0) npol=npol+180
|
||||
endif
|
||||
call txpol(xpol,msg0(1:22),mygrid,npol,nxant,ntxpol,cp)
|
||||
if(nqd.eq.1 .and. abs(nq65df-mousedf).lt.ntol) then
|
||||
write(line,1020) ikhz,nq65df,45*(ipol-1),nutc,xdt0,nsnr0,msg0(1:27),cq0
|
||||
1020 format('!',i3.3,i5,i4,i6.4,f5.1,i5,' : ',a27,a3)
|
||||
write(line,1020) ikhz,nq65df,npol,nutc,xdt0,nsnr0,msg0(1:27),cq0, &
|
||||
ntxpol,cp
|
||||
1020 format('!',i3.3,i5,i4,i6.4,f5.1,i5,' : ',a27,a3,i4,1x,a1)
|
||||
write(*,1100) trim(line)
|
||||
1100 format(a)
|
||||
endif
|
||||
|
||||
! Write to lu 26, for Messages and Band Map windows
|
||||
write(26,1014) freq0,nq65df,0,0,0,xdt0,45*(ipol-1),0, &
|
||||
nsnr0,nutc,msg0(1:22),':',char(ichar('A') + mode_q65-1)
|
||||
1014 format(f8.3,i5,3i3,f5.1,i4,i3,i4,i5.4,4x,a22,2x,a1,3x,':',a1)
|
||||
|
||||
cmode=': '
|
||||
cmode(2:2)=char(ichar('A') + mode_q65-1)
|
||||
write(26,1014) freq0,nq65df,0,0,0,xdt0,npol,0, &
|
||||
nsnr0,nutc,msg0(1:22),':',cp,cmode
|
||||
1014 format(f8.3,i5,3i3,f5.1,i4,i3,i4,i5.4,4x,a22,1x,2a1,2x,a2)
|
||||
|
||||
! Write to file map65_rx.log:
|
||||
write(21,1110) freq0,nq65df,xdt0,45*(ipol-1),nsnr0,nutc,msg0(1:28),cq0
|
||||
write(21,1110) freq0,nq65df,xdt0,npol,nsnr0,nutc,msg0(1:28),cq0
|
||||
1110 format(f8.3,i5,f5.1,2i4,i5.4,2x,a28,': A',2x,a3)
|
||||
endif
|
||||
|
||||
|
@ -41,7 +41,7 @@ program synctest
|
||||
call timer('synctest',0)
|
||||
|
||||
call timer('get_cand',0)
|
||||
call get_candidates(ss,savg,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
call get_candidates(ss,savg,.true.,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
call timer('get_cand',1)
|
||||
|
||||
do k=1,ncand
|
||||
|
33
map65/libm65/txpol.f90
Normal file
33
map65/libm65/txpol.f90
Normal file
@ -0,0 +1,33 @@
|
||||
subroutine txpol(xpol,decoded,mygrid,npol,nxant,ntxpol,cp)
|
||||
|
||||
! If Tx station's grid is in decoded message, compute optimum TxPol
|
||||
character*22 decoded
|
||||
character*6 mygrid,grid
|
||||
character*1 cp
|
||||
logical xpol
|
||||
|
||||
ntxpol=0
|
||||
i1=index(decoded,' ')
|
||||
i2=index(decoded(i1+1:),' ') + i1
|
||||
grid=' '
|
||||
if(i2.ge.8 .and. i2.le.18) grid=decoded(i2+1:i2+4)//'mm'
|
||||
ntxpol=0
|
||||
cp=' '
|
||||
if(xpol .and.grid(1:4).ne.'RR73') then
|
||||
if(grid(1:1).ge.'A' .and. grid(1:1).le.'R' .and. &
|
||||
grid(2:2).ge.'A' .and. grid(2:2).le.'R' .and. &
|
||||
grid(3:3).ge.'0' .and. grid(3:3).le.'9' .and. &
|
||||
grid(4:4).ge.'0' .and. grid(4:4).le.'9') then
|
||||
ntxpol=mod(npol-nint(2.0*dpol(mygrid,grid))+720,180)
|
||||
if(nxant.eq.0) then
|
||||
cp='H'
|
||||
if(ntxpol.gt.45 .and. ntxpol.le.135) cp='V'
|
||||
else
|
||||
cp='/'
|
||||
if(ntxpol.ge.90 .and. ntxpol.lt.180) cp='\'
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine txpol
|
@ -4,12 +4,14 @@ module wideband_sync
|
||||
real :: snr !Relative S/N of sync detection
|
||||
real :: f !Freq of sync tone, 0 to 96000 Hz
|
||||
real :: xdt !DT of matching sync pattern, -1.0 to +4.0 s
|
||||
real :: pol !Polarization angle, degrees
|
||||
integer :: ipol !Polarization angle, 1 to 4 ==> 0, 45, 90, 135 deg
|
||||
integer :: iflip !Sync type: JT65 = +/- 1, Q65 = 0
|
||||
end type candidate
|
||||
type sync_dat
|
||||
real :: ccfmax
|
||||
real :: xdt
|
||||
real :: pol
|
||||
integer :: ipol
|
||||
integer :: iflip
|
||||
logical :: birdie
|
||||
@ -17,12 +19,13 @@ module wideband_sync
|
||||
|
||||
parameter (NFFT=32768)
|
||||
parameter (MAX_CANDIDATES=50)
|
||||
parameter (SNR1_THRESHOLD=4.5)
|
||||
type(sync_dat) :: sync(NFFT)
|
||||
integer nkhz_center
|
||||
|
||||
contains
|
||||
|
||||
subroutine get_candidates(ss,savg,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
subroutine get_candidates(ss,savg,xpol,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
|
||||
! Search symbol spectra ss() over frequency range nfa to nfb (in kHz) for
|
||||
! JT65 and Q65 sync patterns. The nts_* variables are the submode tone
|
||||
@ -33,7 +36,7 @@ subroutine get_candidates(ss,savg,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
real ss(4,322,NFFT),savg(4,NFFT)
|
||||
real pavg(-20:20)
|
||||
integer indx(NFFT)
|
||||
logical skip
|
||||
logical xpol,skip
|
||||
type(candidate) :: cand(MAX_CANDIDATES)
|
||||
|
||||
do j=322,1,-1 !Find end of data in ss()
|
||||
@ -41,7 +44,7 @@ subroutine get_candidates(ss,savg,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
enddo
|
||||
jz=j
|
||||
|
||||
call wb_sync(ss,savg,jz,nfa,nfb)
|
||||
call wb_sync(ss,savg,xpol,jz,nfa,nfb)
|
||||
|
||||
tstep=2048.0/11025.0 !0.185760 s: 0.5*tsym_jt65, 0.3096*tsym_q65
|
||||
df3=96000.0/NFFT
|
||||
@ -56,8 +59,7 @@ call wb_sync(ss,savg,jz,nfa,nfb)
|
||||
n=indx(iz+1-i) + ia - 1
|
||||
f0=0.001*(n-1)*df3
|
||||
snr1=sync(n)%ccfmax
|
||||
! print*,'=A',f0,snr1
|
||||
if(snr1.lt.4.5) exit
|
||||
if(snr1.lt.SNR1_THRESHOLD) exit
|
||||
flip=sync(n)%iflip
|
||||
if(flip.ne.0.0 .and. nts_jt65.eq.0) cycle
|
||||
if(flip.eq.0.0 .and. nts_q65.eq.0) cycle
|
||||
@ -94,6 +96,7 @@ call wb_sync(ss,savg,jz,nfa,nfb)
|
||||
cand(k)%snr=snr1
|
||||
cand(k)%f=f0
|
||||
cand(k)%xdt=sync(n)%xdt
|
||||
cand(k)%pol=sync(n)%pol
|
||||
cand(k)%ipol=sync(n)%ipol
|
||||
cand(k)%iflip=nint(flip)
|
||||
if(k.ge.MAX_CANDIDATES) exit
|
||||
@ -103,18 +106,21 @@ call wb_sync(ss,savg,jz,nfa,nfb)
|
||||
return
|
||||
end subroutine get_candidates
|
||||
|
||||
subroutine wb_sync(ss,savg,jz,nfa,nfb)
|
||||
subroutine wb_sync(ss,savg,xpol,jz,nfa,nfb)
|
||||
|
||||
! Compute "orange sync curve" using the Q65 sync pattern
|
||||
|
||||
use timer_module, only: timer
|
||||
parameter (NFFT=32768)
|
||||
parameter (LAGMAX=30)
|
||||
real ss(4,322,NFFT)
|
||||
real savg(4,NFFT)
|
||||
real savg_med(4)
|
||||
logical first
|
||||
real ccf4(4),ccf4best(4),a(3)
|
||||
logical first,xpol
|
||||
integer isync(22)
|
||||
integer jsync0(63),jsync1(63)
|
||||
integer ip(1)
|
||||
|
||||
! Q65 sync symbols
|
||||
data isync/1,9,12,13,15,22,23,26,27,33,35,38,46,50,55,60,62,66,69,74,76,85/
|
||||
@ -147,12 +153,14 @@ subroutine wb_sync(ss,savg,jz,nfa,nfb)
|
||||
df3=96000.0/NFFT
|
||||
ia=nint(1000*nfa/df3) + 1 !Flat frequency range for WSE converters
|
||||
ib=nint(1000*nfb/df3) + 1
|
||||
npol=1
|
||||
if(xpol) npol=4
|
||||
|
||||
do i=1,4
|
||||
do i=1,npol
|
||||
call pctile(savg(i,ia:ib),ib-ia+1,50,savg_med(i))
|
||||
enddo
|
||||
! do i=ia,ib
|
||||
! write(14,3014) 0.001*(i-1)*df3,savg(1:4,i)
|
||||
! write(14,3014) 0.001*(i-1)*df3,savg(1:npol,i)
|
||||
!3014 format(5f10.3)
|
||||
! enddo
|
||||
|
||||
@ -162,57 +170,83 @@ subroutine wb_sync(ss,savg,jz,nfa,nfb)
|
||||
|
||||
do i=ia,ib
|
||||
ccfmax=0.
|
||||
do ipol=1,4
|
||||
do lag=0,LAGMAX
|
||||
do lag=0,LAGMAX
|
||||
|
||||
ccf=0.
|
||||
do j=1,22
|
||||
k=isync(j) + lag
|
||||
ccf=ccf + ss(ipol,k,i+1) + ss(ipol,k+1,i+1) + ss(ipol,k+2,i+1)
|
||||
enddo
|
||||
ccf=ccf - savg(ipol,i+1)*3*22/float(jz)
|
||||
if(ccf.gt.ccfmax) then
|
||||
ipolbest=ipol
|
||||
lagbest=lag
|
||||
ccfmax=ccf
|
||||
flip=0.
|
||||
endif
|
||||
ccf=0.
|
||||
ccf4=0.
|
||||
do j=1,22 !Test for Q65 sync
|
||||
k=isync(j) + lag
|
||||
ccf4(1:npol)=ccf4(1:npol) + ss(1:npol,k,i+1) + &
|
||||
ss(1:npol,k+1,i+1) + ss(1:npol,k+2,i+1)
|
||||
enddo
|
||||
ccf4(1:npol)=ccf4(1:npol) - savg(1:npol,i+1)*3*22/float(jz)
|
||||
ccf=maxval(ccf4)
|
||||
ip=maxloc(ccf4)
|
||||
ipol=ip(1)
|
||||
if(ccf.gt.ccfmax) then
|
||||
ipolbest=ipol
|
||||
lagbest=lag
|
||||
ccfmax=ccf
|
||||
ccf4best=ccf4
|
||||
flip=0.
|
||||
endif
|
||||
|
||||
ccf=0.
|
||||
do j=1,63
|
||||
k=jsync0(j) + lag
|
||||
ccf=ccf + ss(ipol,k,i+1) + ss(ipol,k+1,i+1)
|
||||
enddo
|
||||
ccf=ccf - savg(ipol,i+1)*2*63/float(jz)
|
||||
if(ccf.gt.ccfmax) then
|
||||
ipolbest=ipol
|
||||
lagbest=lag
|
||||
ccfmax=ccf
|
||||
flip=1.0
|
||||
endif
|
||||
ccf=0.
|
||||
ccf4=0.
|
||||
do j=1,63 !Test for JT65 sync, std msg
|
||||
k=jsync0(j) + lag
|
||||
ccf4(1:npol)=ccf4(1:npol) + ss(1:npol,k,i+1) + ss(1:npol,k+1,i+1)
|
||||
enddo
|
||||
ccf4(1:npol)=ccf4(1:npol) - savg(1:npol,i+1)*2*63/float(jz)
|
||||
ccf=maxval(ccf4)
|
||||
ip=maxloc(ccf4)
|
||||
ipol=ip(1)
|
||||
if(ccf.gt.ccfmax) then
|
||||
ipolbest=ipol
|
||||
lagbest=lag
|
||||
ccfmax=ccf
|
||||
ccf4best=ccf4
|
||||
flip=1.0
|
||||
endif
|
||||
|
||||
ccf=0.
|
||||
do j=1,63
|
||||
k=jsync1(j) + lag
|
||||
ccf=ccf + ss(ipol,k,i+1) + ss(ipol,k+1,i+1)
|
||||
enddo
|
||||
ccf=ccf - savg(ipol,i+1)*2*63/float(jz)
|
||||
if(ccf.gt.ccfmax) then
|
||||
ipolbest=ipol
|
||||
lagbest=lag
|
||||
ccfmax=ccf
|
||||
flip=-1.0
|
||||
endif
|
||||
ccf=0.
|
||||
ccf4=0.
|
||||
do j=1,63 !Test for JT65 sync, OOO msg
|
||||
k=jsync1(j) + lag
|
||||
ccf4(1:npol)=ccf4(1:npol) + ss(1:npol,k,i+1) + ss(1:npol,k+1,i+1)
|
||||
enddo
|
||||
ccf4(1:npol)=ccf4(1:npol) - savg(1:npol,i+1)*2*63/float(jz)
|
||||
ccf=maxval(ccf4)
|
||||
ip=maxloc(ccf4)
|
||||
ipol=ip(1)
|
||||
if(ccf.gt.ccfmax) then
|
||||
ipolbest=ipol
|
||||
lagbest=lag
|
||||
ccfmax=ccf
|
||||
ccf4best=ccf4
|
||||
flip=-1.0
|
||||
endif
|
||||
|
||||
enddo ! lag
|
||||
enddo !ipol
|
||||
enddo ! lag
|
||||
|
||||
poldeg=0.
|
||||
if(xpol .and. ccfmax.ge.SNR1_THRESHOLD) then
|
||||
call polfit(ccf4best,4,a)
|
||||
poldeg=a(3)
|
||||
endif
|
||||
sync(i)%ccfmax=ccfmax
|
||||
sync(i)%xdt=lagbest*tstep-1.0
|
||||
sync(i)%pol=poldeg
|
||||
sync(i)%ipol=ipolbest
|
||||
sync(i)%iflip=flip
|
||||
sync(i)%birdie=.false.
|
||||
if(ccfmax/(savg(ipolbest,i)/savg_med(ipolbest)).lt.3.0) sync(i)%birdie=.true.
|
||||
! if(sync(i)%iflip.eq.0 .and. sync(i)%ccfmax .gt. 20.0) then
|
||||
! write(50,3050) i,lagbest,sync(i)%ccfmax,sync(i)%xdt,sync(i)%ipol, &
|
||||
! sync(i)%birdie,ccf4best
|
||||
!3050 format(2i5,f10.3,f8.2,i5,1x,L3,4f7.1)
|
||||
! endif
|
||||
|
||||
enddo ! i (frequency bin)
|
||||
|
||||
! do i=ia,ib
|
||||
@ -223,7 +257,6 @@ subroutine wb_sync(ss,savg,jz,nfa,nfb)
|
||||
|
||||
call pctile(sync(ia:ib)%ccfmax,ib-ia+1,50,base)
|
||||
sync(ia:ib)%ccfmax=sync(ia:ib)%ccfmax/base
|
||||
! print*,base
|
||||
|
||||
return
|
||||
end subroutine wb_sync
|
||||
|
@ -19,7 +19,7 @@ int main(int argc, char *argv[])
|
||||
QApplication a {argc, argv};
|
||||
// Override programs executable basename as application name.
|
||||
a.setApplicationName ("MAP65");
|
||||
a.setApplicationVersion ("3.0.0-rc1");
|
||||
a.setApplicationVersion ("3.0.0-rc2");
|
||||
// switch off as we share an Info.plist file with WSJT-X
|
||||
a.setAttribute (Qt::AA_DontUseNativeMenuBar);
|
||||
MainWindow w;
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#define NFFT 32768
|
||||
|
||||
short int iwave[2*60*11025]; //Wave file for Tx audio
|
||||
short int iwave[2*60*12000]; //Wave file for Tx audio
|
||||
int nwave; //Length of Tx waveform
|
||||
bool btxok; //True if OK to transmit
|
||||
bool bTune;
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>635</width>
|
||||
<height>512</height>
|
||||
<height>523</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -1704,7 +1704,7 @@ p, li { white-space: pre-wrap; }
|
||||
<customwidget>
|
||||
<class>DisplayText</class>
|
||||
<extends>QTextBrowser</extends>
|
||||
<header>displaytext.h</header>
|
||||
<header>widgets/displaytext.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
|
@ -274,7 +274,7 @@ void CPlotter::UTCstr()
|
||||
ihr=imin/60;
|
||||
imin=imin % 60;
|
||||
}
|
||||
m_sutc = QString {"%1:%2"}.arg (ihr, 2).arg (imin, 2);
|
||||
m_sutc = QString {"%1:%2"}.arg (ihr,2,10,QLatin1Char('0')).arg (imin,2,10,QLatin1Char('0'));
|
||||
}
|
||||
|
||||
void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
|
@ -1,45 +1,52 @@
|
||||
#include "soundin.h"
|
||||
#include <stdexcept>
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#define NFFT 32768
|
||||
#define FRAMES_PER_BUFFER 1024
|
||||
|
||||
extern "C" {
|
||||
#include <portaudio.h>
|
||||
extern struct {
|
||||
double d8[2*60*96000]; //This is "common/datcom/..." in fortran
|
||||
float ss[4*322*NFFT];
|
||||
float savg[4*NFFT];
|
||||
double fcenter;
|
||||
int nutc;
|
||||
int idphi; //Phase correction for Y pol'n, degrees
|
||||
int mousedf; //User-selected DF
|
||||
int mousefqso; //User-selected QSO freq (kHz)
|
||||
int nagain; //1 ==> decode only at fQSO +/- Tol
|
||||
int ndepth; //How much hinted decoding to do?
|
||||
int ndiskdat; //1 ==> data read from *.tf2 or *.iq file
|
||||
int neme; //Hinted decoding tries only for EME calls
|
||||
int newdat; //1 ==> new data, must do long FFT
|
||||
int nfa; //Low decode limit (kHz)
|
||||
int nfb; //High decode limit (kHz)
|
||||
int nfcal; //Frequency correction, for calibration (Hz)
|
||||
int nfshift; //Shift of displayed center freq (kHz)
|
||||
int mcall3; //1 ==> CALL3.TXT has been modified
|
||||
int ntimeout; //Max for timeouts in Messages and BandMap
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int nxant; //1 ==> add 45 deg to measured pol angle
|
||||
int map65RxLog; //Flags to control log files
|
||||
int nfsample; //Input sample rate
|
||||
int nxpol; //1 if using xpol antennas, 0 otherwise
|
||||
int mode65; //JT65 sub-mode: A=1, B=2, C=4
|
||||
int nfast; //1No longer used
|
||||
int nsave; //Number of s3(64,63) spectra saved
|
||||
char mycall[12];
|
||||
char mygrid[6];
|
||||
char hiscall[12];
|
||||
char hisgrid[6];
|
||||
char datetime[20];
|
||||
} datcom_;
|
||||
extern "C"
|
||||
{
|
||||
struct
|
||||
{
|
||||
double d8[2*60*96000]; //This is "common/datcom/..." in fortran
|
||||
float ss[4*322*NFFT];
|
||||
float savg[4*NFFT];
|
||||
double fcenter;
|
||||
int nutc;
|
||||
int idphi; //Phase correction for Y pol'n, degrees
|
||||
int mousedf; //User-selected DF
|
||||
int mousefqso; //User-selected QSO freq (kHz)
|
||||
int nagain; //1 ==> decode only at fQSO +/- Tol
|
||||
int ndepth; //How much hinted decoding to do?
|
||||
int ndiskdat; //1 ==> data read from *.tf2 or *.iq file
|
||||
int neme; //Hinted decoding tries only for EME calls
|
||||
int newdat; //1 ==> new data, must do long FFT
|
||||
int nfa; //Low decode limit (kHz)
|
||||
int nfb; //High decode limit (kHz)
|
||||
int nfcal; //Frequency correction, for calibration (Hz)
|
||||
int nfshift; //Shift of displayed center freq (kHz)
|
||||
int mcall3; //1 ==> CALL3.TXT has been modified
|
||||
int ntimeout; //Max for timeouts in Messages and BandMap
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int nxant; //1 ==> add 45 deg to measured pol angle
|
||||
int map65RxLog; //Flags to control log files
|
||||
int nfsample; //Input sample rate
|
||||
int nxpol; //1 if using xpol antennas, 0 otherwise
|
||||
int mode65; //JT65 sub-mode: A=1, B=2, C=4
|
||||
int nfast; //1No longer used
|
||||
int nsave; //Number of s3(64,63) spectra saved
|
||||
char mycall[12];
|
||||
char mygrid[6];
|
||||
char hiscall[12];
|
||||
char hisgrid[6];
|
||||
char datetime[20];
|
||||
} datcom_;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
@ -133,6 +140,26 @@ extern "C" int a2dCallback( const void *inputBuffer, void *outputBuffer,
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct COMWrapper
|
||||
{
|
||||
explicit COMWrapper ()
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
// required because Qt only does this for GUI thread
|
||||
CoInitializeEx (nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
#endif
|
||||
}
|
||||
~COMWrapper ()
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
CoUninitialize ();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void SoundInThread::run() //SoundInThread::run()
|
||||
{
|
||||
quitExecution = false;
|
||||
@ -144,8 +171,10 @@ void SoundInThread::run() //SoundInThread::run()
|
||||
return;
|
||||
}
|
||||
|
||||
//---------------------------------------------------- Soundcard Setup
|
||||
// qDebug() << "Start souncard input";
|
||||
COMWrapper c;
|
||||
|
||||
//---------------------------------------------------- Soundcard Setup
|
||||
// qDebug() << "Start souncard input";
|
||||
|
||||
PaError paerr;
|
||||
PaStreamParameters inParam;
|
||||
@ -158,15 +187,27 @@ void SoundInThread::run() //SoundInThread::run()
|
||||
udata.iqswap=m_IQswap;
|
||||
udata.b10db=m_10db;
|
||||
|
||||
auto device_info = Pa_GetDeviceInfo (m_nDevIn);
|
||||
|
||||
inParam.device=m_nDevIn; //### Input Device Number ###
|
||||
inParam.channelCount=2*m_nrx; //Number of analog channels
|
||||
inParam.sampleFormat=paFloat32; //Get floats from Portaudio
|
||||
inParam.suggestedLatency=0.05;
|
||||
inParam.suggestedLatency=device_info->defaultHighInputLatency;
|
||||
inParam.hostApiSpecificStreamInfo=NULL;
|
||||
|
||||
paerr=Pa_IsFormatSupported(&inParam,NULL,96000.0);
|
||||
if(paerr<0) {
|
||||
emit error("PortAudio says requested soundcard format not supported.");
|
||||
QString error_message;
|
||||
if (paUnanticipatedHostError == paerr)
|
||||
{
|
||||
auto const * last_host_error = Pa_GetLastHostErrorInfo ();
|
||||
error_message = QString {"PortAudio Host API error: %1"}.arg (last_host_error->errorText);
|
||||
}
|
||||
else
|
||||
{
|
||||
error_message = "PortAudio says requested soundcard format not supported.";
|
||||
}
|
||||
emit error(error_message);
|
||||
// return;
|
||||
}
|
||||
paerr=Pa_OpenStream(&inStream, //Input stream
|
||||
|
@ -6,12 +6,6 @@
|
||||
#include <QDebug>
|
||||
#include <valarray>
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#endif //Q_OS_WIN32
|
||||
|
||||
// Thread gets audio data from soundcard and signals when a buffer of
|
||||
// specified size is available.
|
||||
class SoundInThread : public QThread
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "soundout.h"
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define FRAMES_PER_BUFFER 256
|
||||
|
||||
extern "C" {
|
||||
#include <portaudio.h>
|
||||
}
|
||||
|
||||
extern float gran(); //Noise generator (for tests only)
|
||||
|
||||
@ -120,18 +122,42 @@ extern "C" int d2aCallback(const void * /*inputBuffer*/, void *outputBuffer,
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct COMWrapper
|
||||
{
|
||||
explicit COMWrapper ()
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
// required because Qt only does this for GUI thread
|
||||
CoInitializeEx (nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
#endif
|
||||
}
|
||||
~COMWrapper ()
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
CoUninitialize ();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void SoundOutThread::run()
|
||||
{
|
||||
COMWrapper c;
|
||||
|
||||
PaError paerr;
|
||||
PaStreamParameters outParam;
|
||||
PaStream *outStream;
|
||||
paUserData udata;
|
||||
quitExecution = false;
|
||||
|
||||
auto device_info = Pa_GetDeviceInfo (m_nDevOut);
|
||||
|
||||
outParam.device=m_nDevOut; //Output device number
|
||||
outParam.channelCount=2; //Number of analog channels
|
||||
outParam.sampleFormat=paInt16; //Send short ints to PortAudio
|
||||
outParam.suggestedLatency=0.05;
|
||||
outParam.suggestedLatency=device_info->defaultLowOutputLatency;
|
||||
outParam.hostApiSpecificStreamInfo=NULL;
|
||||
|
||||
udata.nTRperiod=m_TRperiod;
|
||||
|
@ -14,7 +14,7 @@ auto CallsignValidator::validate (QString& input, int& pos) const -> State
|
||||
input.remove (0, 1);
|
||||
if (pos > 0) --pos;
|
||||
}
|
||||
while (input.size () && input[input.size ()].isSpace ())
|
||||
while (input.size () && input[input.size () - 1].isSpace ())
|
||||
{
|
||||
if (pos > input.size ()) --pos;
|
||||
input.chop (1);
|
||||
|
27
widgets/BandComboBox.cpp
Normal file
27
widgets/BandComboBox.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "BandComboBox.hpp"
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QScrollBar>
|
||||
#include <QDebug>
|
||||
#include "models/FrequencyList.hpp"
|
||||
|
||||
BandComboBox::BandComboBox (QWidget * parent)
|
||||
: QComboBox {parent}
|
||||
{
|
||||
}
|
||||
|
||||
// Fix up broken QComboBox item view rendering which doesn't allow for
|
||||
// a vertical scroll bar in width calculations and ends up eliding the
|
||||
// item text.
|
||||
void BandComboBox::showPopup ()
|
||||
{
|
||||
auto minimum_width = view ()->sizeHintForColumn (FrequencyList_v2::frequency_mhz_column);
|
||||
if (count () > maxVisibleItems ())
|
||||
{
|
||||
// for some as yet unknown reason, in FT8 mode the scrollbar
|
||||
// width is oversize on the first call here
|
||||
minimum_width += view ()->verticalScrollBar ()->width ();
|
||||
}
|
||||
view ()->setMinimumWidth (minimum_width);
|
||||
QComboBox::showPopup ();
|
||||
}
|
16
widgets/BandComboBox.hpp
Normal file
16
widgets/BandComboBox.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef BAND_COMBO_BOX_HPP__
|
||||
#define BAND_COMBO_BOX_HPP__
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
class BandComboBox
|
||||
: public QComboBox
|
||||
{
|
||||
public:
|
||||
explicit BandComboBox (QWidget * = nullptr);
|
||||
|
||||
private:
|
||||
void showPopup () override;
|
||||
};
|
||||
|
||||
#endif
|
@ -45,6 +45,7 @@
|
||||
#include <QRandomGenerator>
|
||||
#endif
|
||||
|
||||
#include "helper_functions.h"
|
||||
#include "revision_utils.hpp"
|
||||
#include "qt_helpers.hpp"
|
||||
#include "Network/NetworkAccessManager.hpp"
|
||||
@ -274,7 +275,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
m_freqNominal {0},
|
||||
m_freqTxNominal {0},
|
||||
m_reverse_Doppler {"1" == env.value ("WSJT_REVERSE_DOPPLER", "0")},
|
||||
m_s6 {0.},
|
||||
m_tRemaining {0.},
|
||||
m_TRperiod {60.0},
|
||||
m_DTtol {3.0},
|
||||
@ -293,7 +293,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
m_idleMinutes {0},
|
||||
m_nSubMode {0},
|
||||
m_nclearave {1},
|
||||
m_nseq {0},
|
||||
m_nWSPRdecodes {0},
|
||||
m_k0 {9999999},
|
||||
m_nPick {0},
|
||||
@ -755,10 +754,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
ui->bandComboBox->setModel (m_config.frequencies ());
|
||||
ui->bandComboBox->setModelColumn (FrequencyList_v2::frequency_mhz_column);
|
||||
|
||||
// combo box drop down width defaults to the line edit + decorator width,
|
||||
// here we change that to the column width size hint of the model column
|
||||
ui->bandComboBox->view ()->setMinimumWidth (ui->bandComboBox->view ()->sizeHintForColumn (FrequencyList_v2::frequency_mhz_column));
|
||||
|
||||
// Enable live band combo box entry validation and action.
|
||||
auto band_validator = new LiveFrequencyValidator {ui->bandComboBox
|
||||
, m_config.bands ()
|
||||
@ -928,7 +923,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
QByteArray cfname=fname.toLocal8Bit();
|
||||
fftwf_import_wisdom_from_filename(cfname);
|
||||
|
||||
//genStdMsgs(m_rpt);
|
||||
m_ntx = 6;
|
||||
ui->txrb6->setChecked(true);
|
||||
|
||||
@ -1008,7 +1002,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
|
||||
m_fastGraph->setMode(m_mode);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
|
||||
connect (&minuteTimer, &QTimer::timeout, this, &MainWindow::on_the_minute);
|
||||
minuteTimer.setSingleShot (true);
|
||||
@ -1031,6 +1024,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
|
||||
void MainWindow::not_GA_warning_message ()
|
||||
{
|
||||
|
||||
MessageBox::critical_message (this,
|
||||
"This is a pre-release version of WSJT-X 2.5.0 made\n"
|
||||
"available for testing purposes. By design it will\n"
|
||||
@ -1139,7 +1133,6 @@ void MainWindow::writeSettings()
|
||||
|
||||
m_settings->beginGroup("Common");
|
||||
m_settings->setValue("Mode",m_mode);
|
||||
m_settings->setValue("ModeTx",m_modeTx);
|
||||
m_settings->setValue("SaveNone",ui->actionNone->isChecked());
|
||||
m_settings->setValue("SaveDecoded",ui->actionSave_decoded->isChecked());
|
||||
m_settings->setValue("SaveAll",ui->actionSave_all->isChecked());
|
||||
@ -1238,7 +1231,6 @@ void MainWindow::readSettings()
|
||||
|
||||
m_settings->beginGroup("Common");
|
||||
m_mode=m_settings->value("Mode","JT9").toString();
|
||||
m_modeTx=m_settings->value("ModeTx","JT9").toString();
|
||||
ui->actionNone->setChecked(m_settings->value("SaveNone",true).toBool());
|
||||
ui->actionSave_decoded->setChecked(m_settings->value("SaveDecoded",false).toBool());
|
||||
ui->actionSave_all->setChecked(m_settings->value("SaveAll",false).toBool());
|
||||
@ -2201,17 +2193,13 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Z: //### Recover from hung decode() ?? ###
|
||||
if(e->modifiers() & Qt::AltModifier) {
|
||||
decodeDone();
|
||||
return;
|
||||
}
|
||||
break; case Qt::Key_PageUp:
|
||||
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
band_changed(m_freqNominal-2000);
|
||||
break; }
|
||||
case Qt::Key_X:
|
||||
if(e->modifiers() & Qt::AltModifier) {
|
||||
// qDebug() << "Alt-X" << m_mode << m_TRperiod << m_nsps << m_bFast9
|
||||
// << tx_duration(m_mode,m_TRperiod,m_nsps,m_bFast9);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QMainWindow::keyPressEvent (e);
|
||||
}
|
||||
@ -2289,7 +2277,7 @@ void MainWindow::statusChanged()
|
||||
if (!tmpGrid.size ()) tmpGrid="n/a"; // Not Available
|
||||
out << qSetRealNumberPrecision (12) << (m_freqNominal / 1.e6)
|
||||
<< ";" << m_mode << ";" << m_hisCall << ";"
|
||||
<< ui->rptSpinBox->value() << ";" << m_modeTx << ";" << tmpGrid
|
||||
<< ui->rptSpinBox->value() << ";" << m_mode << ";" << tmpGrid
|
||||
#if QT_VERSION >= QT_VERSION_CHECK (5, 15, 0)
|
||||
<< Qt::endl
|
||||
#else
|
||||
@ -3142,7 +3130,6 @@ void MainWindow::decode() //decode()
|
||||
if(dec_data.params.nutc < m_nutc0) m_RxLog = 1; //Date and Time to file "ALL.TXT".
|
||||
if(dec_data.params.newdat==1 and !m_diskData) m_nutc0=dec_data.params.nutc;
|
||||
dec_data.params.ntxmode=9;
|
||||
if(m_modeTx=="JT65") dec_data.params.ntxmode=65;
|
||||
dec_data.params.nmode=9;
|
||||
if(m_mode=="JT65") dec_data.params.nmode=65;
|
||||
if(m_mode=="JT65") dec_data.params.ljt65apon = ui->actionEnable_AP_JT65->isVisible () &&
|
||||
@ -3163,6 +3150,7 @@ void MainWindow::decode() //decode()
|
||||
}
|
||||
if(m_mode=="FST4") dec_data.params.nmode=240;
|
||||
if(m_mode=="FST4W") dec_data.params.nmode=241;
|
||||
dec_data.params.ntxmode=dec_data.params.nmode; // Is this used any more?
|
||||
dec_data.params.ntrperiod=m_TRperiod;
|
||||
dec_data.params.nsubmode=m_nSubMode;
|
||||
dec_data.params.minw=0;
|
||||
@ -3807,42 +3795,14 @@ void MainWindow::guiUpdate()
|
||||
static char message[38];
|
||||
static char msgsent[38];
|
||||
double txDuration;
|
||||
QString rt;
|
||||
|
||||
if(m_TRperiod==0) m_TRperiod=60.0;
|
||||
txDuration=0.0;
|
||||
if(m_modeTx=="FT4") txDuration=1.0 + 105*576/12000.0; // FT4
|
||||
if(m_modeTx=="FT8") txDuration=1.0 + 79*1920/12000.0; // FT8
|
||||
if(m_modeTx=="JT4") txDuration=1.0 + 207.0*2520/11025.0; // JT4
|
||||
if(m_modeTx=="JT9") txDuration=1.0 + 85.0*m_nsps/12000.0; // JT9
|
||||
if(m_modeTx=="JT65") txDuration=1.0 + 126*4096/11025.0; // JT65
|
||||
if(m_modeTx=="Q65") { // Q65
|
||||
if(m_TRperiod==15) txDuration=0.5 + 85*1800/12000.0;
|
||||
if(m_TRperiod==30) txDuration=0.5 + 85*3600/12000.0;
|
||||
if(m_TRperiod==60) txDuration=1.0 + 85*7200/12000.0;
|
||||
if(m_TRperiod==120) txDuration=1.0 + 85*16000/12000.0;
|
||||
if(m_TRperiod==300) txDuration=1.0 + 85*41472/12000.0;
|
||||
}
|
||||
if(m_modeTx=="WSPR") txDuration=2.0 + 162*8192/12000.0; // WSPR
|
||||
if(m_modeTx=="FST4" or m_mode=="FST4W") { //FST4, FST4W
|
||||
if(m_TRperiod==15) txDuration=1.0 + 160*720/12000.0;
|
||||
if(m_TRperiod==30) txDuration=1.0 + 160*1680/12000.0;
|
||||
if(m_TRperiod==60) txDuration=1.0 + 160*3888/12000.0;
|
||||
if(m_TRperiod==120) txDuration=1.0 + 160*8200/12000.0;
|
||||
if(m_TRperiod==300) txDuration=1.0 + 160*21504/12000.0;
|
||||
if(m_TRperiod==900) txDuration=1.0 + 160*66560/12000.0;
|
||||
if(m_TRperiod==1800) txDuration=1.0 + 160*134400/12000.0;
|
||||
}
|
||||
if(m_mode=="MSK144" or m_bFast9) {
|
||||
txDuration=m_TRperiod-0.25; // JT9-fast, MSK144
|
||||
}
|
||||
|
||||
txDuration=tx_duration(m_mode,m_TRperiod,m_nsps,m_bFast9);
|
||||
double tx1=0.0;
|
||||
double tx2=txDuration;
|
||||
if(m_mode=="FT8" or m_mode=="FT4") icw[0]=0; //No CW ID in FT4 or FT8 mode
|
||||
if((icw[0]>0) and (!m_bFast9)) tx2 += icw[0]*2560.0/48000.0; //Full length including CW ID
|
||||
if(tx2>m_TRperiod) tx2=m_TRperiod;
|
||||
|
||||
if(!m_txFirst and m_mode!="WSPR" and m_mode!="FST4W") {
|
||||
tx1 += m_TRperiod;
|
||||
tx2 += m_TRperiod;
|
||||
@ -3852,20 +3812,19 @@ void MainWindow::guiUpdate()
|
||||
int nsec=ms/1000;
|
||||
double tsec=0.001*ms;
|
||||
double t2p=fmod(tsec,2*m_TRperiod);
|
||||
m_s6=fmod(tsec,6.0);
|
||||
m_nseq = fmod(double(nsec),m_TRperiod);
|
||||
double s6=fmod(tsec,6.0);
|
||||
int nseq = fmod(double(nsec),m_TRperiod);
|
||||
m_tRemaining=m_TRperiod - fmod(tsec,m_TRperiod);
|
||||
|
||||
if(m_mode=="Echo") {
|
||||
txDuration=2.4;
|
||||
tx1=0.0;
|
||||
tx2=txDuration;
|
||||
if(m_auto and m_s6>4.0) m_bEchoTxOK=true;
|
||||
if(m_auto and s6>4.0) m_bEchoTxOK=true;
|
||||
if(m_transmitting) m_bEchoTxed=true;
|
||||
}
|
||||
|
||||
if(m_mode=="WSPR" or m_mode=="FST4W") {
|
||||
if(m_nseq==0 and m_ntr==0) { //Decide whether to Tx or Rx
|
||||
if(nseq==0 and m_ntr==0) { //Decide whether to Tx or Rx
|
||||
m_tuneup=false; //This is not an ATU tuneup
|
||||
bool btx = m_auto && m_WSPR_tx_next; // To Tx, we need m_auto and
|
||||
// scheduled transmit
|
||||
@ -3940,7 +3899,7 @@ void MainWindow::guiUpdate()
|
||||
tx_watchdog (true); // disable transmit
|
||||
}
|
||||
|
||||
float fTR=float((ms%int(1000.0*m_TRperiod)))/int(1000.0*m_TRperiod);
|
||||
double fTR=float((ms%int(1000.0*m_TRperiod)))/int(1000.0*m_TRperiod);
|
||||
|
||||
QString txMsg;
|
||||
if(m_ntx == 1) txMsg=ui->tx1->text();
|
||||
@ -3952,7 +3911,7 @@ void MainWindow::guiUpdate()
|
||||
int msgLength=txMsg.trimmed().length();
|
||||
if(msgLength==0 and !m_tune) on_stopTxButton_clicked();
|
||||
|
||||
if(g_iptt==0 and ((m_bTxTime and fTR<0.75 and msgLength>0) or m_tune)) {
|
||||
if(g_iptt==0 and ((m_bTxTime and (fTR < 0.75) and (msgLength>0)) or m_tune)) {
|
||||
//### Allow late starts
|
||||
icw[0]=m_ncw;
|
||||
g_iptt = 1;
|
||||
@ -4006,7 +3965,7 @@ void MainWindow::guiUpdate()
|
||||
}
|
||||
|
||||
if((m_mode=="WSPR" or m_mode=="FST4W") and
|
||||
((m_ntr==1 and m_rxDone) or (m_ntr==-1 and m_nseq>tx2))) {
|
||||
((m_ntr==1 and m_rxDone) or (m_ntr==-1 and nseq>tx2))) {
|
||||
if(m_monitoring) {
|
||||
m_rxDone=false;
|
||||
}
|
||||
@ -4064,13 +4023,13 @@ void MainWindow::guiUpdate()
|
||||
} else {
|
||||
if(m_QSOProgress==REPORT || m_QSOProgress==ROGER_REPORT) m_bSentReport=true;
|
||||
if(m_bSentReport and (m_QSOProgress<REPORT or m_QSOProgress>ROGER_REPORT)) m_bSentReport=false;
|
||||
if(m_modeTx=="JT4") gen4_(message, &ichk , msgsent, const_cast<int *> (itone),
|
||||
if(m_mode=="JT4") gen4_(message, &ichk , msgsent, const_cast<int *> (itone),
|
||||
&m_currentMessageType, 22, 22);
|
||||
if(m_modeTx=="JT9") gen9_(message, &ichk, msgsent, const_cast<int *> (itone),
|
||||
if(m_mode=="JT9") gen9_(message, &ichk, msgsent, const_cast<int *> (itone),
|
||||
&m_currentMessageType, 22, 22);
|
||||
if(m_modeTx=="JT65") gen65_(message, &ichk, msgsent, const_cast<int *> (itone),
|
||||
if(m_mode=="JT65") gen65_(message, &ichk, msgsent, const_cast<int *> (itone),
|
||||
&m_currentMessageType, 22, 22);
|
||||
if(m_modeTx=="Q65") {
|
||||
if(m_mode=="Q65") {
|
||||
int i3=-1;
|
||||
int n3=-1;
|
||||
genq65_(message,&ichk,msgsent,const_cast<int *>(itone),&i3,&n3,37,37);
|
||||
@ -4089,15 +4048,15 @@ void MainWindow::guiUpdate()
|
||||
genwave_(const_cast<int *>(itone),&nsym,&nsps4,&nwave,
|
||||
&fsample,&hmod,&f0,&icmplx,foxcom_.wave,foxcom_.wave);
|
||||
}
|
||||
if(m_modeTx=="WSPR") genwspr_(message, msgsent, const_cast<int *> (itone),
|
||||
if(m_mode=="WSPR") genwspr_(message, msgsent, const_cast<int *> (itone),
|
||||
22, 22);
|
||||
if(m_modeTx=="MSK144" or m_modeTx=="FT8" or m_modeTx=="FT4"
|
||||
or m_modeTx=="FST4" or m_modeTx=="FST4W") {
|
||||
if(m_mode=="MSK144" or m_mode=="FT8" or m_mode=="FT4"
|
||||
or m_mode=="FST4" or m_mode=="FST4W") {
|
||||
char MyCall[6];
|
||||
char MyGrid[6];
|
||||
::memcpy(MyCall, (m_config.my_callsign()+" ").toLatin1(), sizeof MyCall);
|
||||
::memcpy(MyGrid, (m_config.my_grid()+" ").toLatin1(), sizeof MyGrid);
|
||||
if(m_modeTx=="MSK144") {
|
||||
if(m_mode=="MSK144") {
|
||||
genmsk_128_90_(message, &ichk, msgsent, const_cast<int *> (itone),
|
||||
&m_currentMessageType, 37, 37);
|
||||
if(m_restart) {
|
||||
@ -4107,7 +4066,7 @@ void MainWindow::guiUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
if(m_modeTx=="FT8") {
|
||||
if(m_mode=="FT8") {
|
||||
if(SpecOp::FOX==m_config.special_op_id() and ui->tabWidget->currentIndex()==1) {
|
||||
foxTxSequencer();
|
||||
} else {
|
||||
@ -4138,7 +4097,7 @@ void MainWindow::guiUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_modeTx=="FT4") {
|
||||
if(m_mode=="FT4") {
|
||||
int ichk=0;
|
||||
char ft4msgbits[77];
|
||||
genft4_(message, &ichk, msgsent, const_cast<char *> (ft4msgbits),
|
||||
@ -4152,7 +4111,7 @@ void MainWindow::guiUpdate()
|
||||
gen_ft4wave_(const_cast<int *>(itone),&nsym,&nsps,&fsample,&f0,foxcom_.wave,
|
||||
foxcom_.wave,&icmplx,&nwave);
|
||||
}
|
||||
if(m_modeTx=="FST4" or m_modeTx=="FST4W") {
|
||||
if(m_mode=="FST4" or m_mode=="FST4W") {
|
||||
int ichk=0;
|
||||
int iwspr=0;
|
||||
char fst4msgbits[101];
|
||||
@ -4230,7 +4189,7 @@ void MainWindow::guiUpdate()
|
||||
if(m_restart) {
|
||||
write_all("Tx",m_currentMessage);
|
||||
if (m_config.TX_messages ()) {
|
||||
ui->decodedTextBrowser2->displayTransmittedText(m_currentMessage.trimmed(),m_modeTx,
|
||||
ui->decodedTextBrowser2->displayTransmittedText(m_currentMessage.trimmed(),m_mode,
|
||||
ui->TxFreqSpinBox->value(),m_bFastMode,m_TRperiod);
|
||||
}
|
||||
}
|
||||
@ -4314,6 +4273,7 @@ void MainWindow::guiUpdate()
|
||||
m_sentFirst73 = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_iptt == 1 && m_iptt0 == 0) {
|
||||
auto const& current_message = QString::fromLatin1 (msgsent);
|
||||
if(m_config.watchdog () && m_mode!="WSPR" && m_mode!="FST4W"
|
||||
@ -4328,7 +4288,7 @@ void MainWindow::guiUpdate()
|
||||
if (m_config.TX_messages () && !m_tune && SpecOp::FOX!=m_config.special_op_id())
|
||||
{
|
||||
ui->decodedTextBrowser2->displayTransmittedText(current_message.trimmed(),
|
||||
m_modeTx,ui->TxFreqSpinBox->value(),m_bFastMode,m_TRperiod);
|
||||
m_mode,ui->TxFreqSpinBox->value(),m_bFastMode,m_TRperiod);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4346,15 +4306,14 @@ void MainWindow::guiUpdate()
|
||||
transmitDisplay (true);
|
||||
statusUpdate ();
|
||||
}
|
||||
if(!m_btxok && m_btxok0 && g_iptt==1)
|
||||
{
|
||||
stopTx();
|
||||
if ("1" == m_env.value ("WSJT_TX_BOTH", "0"))
|
||||
{
|
||||
m_txFirst = !m_txFirst;
|
||||
ui->txFirstCheckBox->setChecked (m_txFirst);
|
||||
}
|
||||
|
||||
if(!m_btxok && m_btxok0 && g_iptt==1) {
|
||||
stopTx();
|
||||
if ("1" == m_env.value ("WSJT_TX_BOTH", "0")) {
|
||||
m_txFirst = !m_txFirst;
|
||||
ui->txFirstCheckBox->setChecked (m_txFirst);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_startAnother) {
|
||||
if(m_mode=="MSK144") {
|
||||
@ -4368,16 +4327,16 @@ void MainWindow::guiUpdate()
|
||||
}
|
||||
|
||||
if(m_mode=="FT8" or m_mode=="MSK144" or m_mode=="FT4") {
|
||||
if(ui->txrb1->isEnabled() and
|
||||
(SpecOp::NA_VHF==m_config.special_op_id() or
|
||||
SpecOp::FIELD_DAY==m_config.special_op_id() or
|
||||
SpecOp::RTTY==m_config.special_op_id() or
|
||||
SpecOp::WW_DIGI==m_config.special_op_id()) ) {
|
||||
if(ui->txrb1->isEnabled() and
|
||||
(SpecOp::NA_VHF==m_config.special_op_id() or
|
||||
SpecOp::FIELD_DAY==m_config.special_op_id() or
|
||||
SpecOp::RTTY==m_config.special_op_id() or
|
||||
SpecOp::WW_DIGI==m_config.special_op_id()) ) {
|
||||
//We're in a contest-like mode other than EU_VHF: start QSO with Tx2.
|
||||
ui->tx1->setEnabled(false);
|
||||
ui->txb1->setEnabled(false);
|
||||
}
|
||||
if(!ui->tx1->isEnabled() and SpecOp::EU_VHF==m_config.special_op_id()) {
|
||||
if(!ui->tx1->isEnabled() and SpecOp::EU_VHF==m_config.special_op_id()) {
|
||||
//We're in EU_VHF mode: start QSO with Tx1.
|
||||
ui->tx1->setEnabled(true);
|
||||
ui->txb1->setEnabled(true);
|
||||
@ -4387,6 +4346,7 @@ void MainWindow::guiUpdate()
|
||||
//Once per second (onesec)
|
||||
if(nsec != m_sec0) {
|
||||
// qDebug() << "AAA" << nsec;
|
||||
|
||||
if(m_mode=="FST4") chk_FST4_freq_range();
|
||||
m_currentBand=m_config.bands()->find(m_freqNominal);
|
||||
if( SpecOp::HOUND == m_config.special_op_id() ) {
|
||||
@ -4399,7 +4359,7 @@ void MainWindow::guiUpdate()
|
||||
progressBar.setFormat ("%v/%m");
|
||||
if(m_auto and m_mode=="Echo" and m_bEchoTxOK) {
|
||||
progressBar.setMaximum(3);
|
||||
progressBar.setValue(int(m_s6));
|
||||
progressBar.setValue(int(s6));
|
||||
}
|
||||
if(m_mode!="Echo") {
|
||||
if(m_monitoring or m_transmitting) {
|
||||
@ -4890,8 +4850,8 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
return;
|
||||
}
|
||||
|
||||
if ((message.isJT9 () and m_modeTx != "JT9" and m_mode != "JT4") or
|
||||
(message.isJT65 () and m_modeTx != "JT65" and m_mode != "JT4")) {
|
||||
if ((message.isJT9 () and m_mode != "JT9" and m_mode != "JT4") or
|
||||
(message.isJT65 () and m_mode != "JT65" and m_mode != "JT4")) {
|
||||
// We are not allowing mode change, so don't process decode
|
||||
return;
|
||||
}
|
||||
@ -5279,27 +5239,32 @@ void MainWindow::setTxMsg(int n)
|
||||
|
||||
void MainWindow::genCQMsg ()
|
||||
{
|
||||
if(m_config.my_callsign().size () && m_config.my_grid().size ()) {
|
||||
QString grid{m_config.my_grid()};
|
||||
auto const& my_callsign = m_config.my_callsign ();
|
||||
auto is_compound = my_callsign != m_baseCall;
|
||||
auto is_type_two = !is77BitMode () && is_compound && stdCall (m_baseCall) && !shortList (my_callsign);
|
||||
if(my_callsign.size () && m_config.my_grid().size ()) {
|
||||
auto const& grid = m_config.my_grid ();
|
||||
if (ui->cbCQTx->isEnabled () && ui->cbCQTx->isVisible () && ui->cbCQTx->isChecked ()) {
|
||||
if(stdCall(m_config.my_callsign())) {
|
||||
if(stdCall (my_callsign)
|
||||
|| is_type_two) {
|
||||
msgtype (QString {"CQ %1 %2 %3"}
|
||||
.arg (m_freqNominal / 1000 - m_freqNominal / 1000000 * 1000, 3, 10, QChar {'0'})
|
||||
.arg (m_config.my_callsign())
|
||||
.arg (my_callsign)
|
||||
.arg (grid.left (4)),
|
||||
ui->tx6);
|
||||
} else {
|
||||
msgtype (QString {"CQ %1 %2"}
|
||||
.arg (m_freqNominal / 1000 - m_freqNominal / 1000000 * 1000, 3, 10, QChar {'0'})
|
||||
.arg (m_config.my_callsign()),
|
||||
.arg (my_callsign),
|
||||
ui->tx6);
|
||||
}
|
||||
} else {
|
||||
if(stdCall(m_config.my_callsign())) {
|
||||
msgtype (QString {"%1 %2 %3"}.arg(m_CQtype).arg(m_config.my_callsign())
|
||||
if (stdCall (my_callsign)
|
||||
|| is_type_two) {
|
||||
msgtype (QString {"%1 %2 %3"}.arg(m_CQtype).arg(my_callsign)
|
||||
.arg(grid.left(4)),ui->tx6);
|
||||
} else {
|
||||
msgtype (QString {"%1 %2"}.arg(m_CQtype).arg(m_config.my_callsign()),ui->tx6);
|
||||
msgtype (QString {"%1 %2"}.arg(m_CQtype).arg(my_callsign),ui->tx6);
|
||||
}
|
||||
}
|
||||
if ((m_mode=="JT4" or m_mode=="Q65") and ui->cbShMsgs->isChecked()) {
|
||||
@ -5314,15 +5279,15 @@ void MainWindow::genCQMsg ()
|
||||
QStringList tlist=t.split(" ");
|
||||
if((m_mode=="FT4" or m_mode=="FT8" or m_mode=="MSK144") and
|
||||
SpecOp::NONE != m_config.special_op_id() and
|
||||
( tlist.at(1)==m_config.my_callsign() or
|
||||
tlist.at(2)==m_config.my_callsign() ) and
|
||||
stdCall(m_config.my_callsign())) {
|
||||
( tlist.at(1)==my_callsign or
|
||||
tlist.at(2)==my_callsign ) and
|
||||
stdCall(my_callsign)) {
|
||||
if(SpecOp::NA_VHF == m_config.special_op_id()) m_cqStr="TEST";
|
||||
if(SpecOp::EU_VHF == m_config.special_op_id()) m_cqStr="TEST";
|
||||
if(SpecOp::FIELD_DAY == m_config.special_op_id()) m_cqStr="FD";
|
||||
if(SpecOp::RTTY == m_config.special_op_id()) m_cqStr="RU";
|
||||
if(SpecOp::WW_DIGI == m_config.special_op_id()) m_cqStr="WW";
|
||||
if( tlist.at(1)==m_config.my_callsign() ) {
|
||||
if( tlist.at(1)==my_callsign ) {
|
||||
t="CQ " + m_cqStr + " " + tlist.at(1) + " " + tlist.at(2);
|
||||
} else {
|
||||
t="CQ " + m_cqStr + " " + tlist.at(2) + " " + tlist.at(3);
|
||||
@ -5355,6 +5320,12 @@ bool MainWindow::stdCall(QString const& w)
|
||||
return standard_call_re.match (w).hasMatch ();
|
||||
}
|
||||
|
||||
bool MainWindow::is77BitMode () const
|
||||
{
|
||||
return "FT8" == m_mode || "FT4" == m_mode || "MSK144" == m_mode
|
||||
|| "FST4" == m_mode || "Q65" == m_mode;
|
||||
}
|
||||
|
||||
void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
{
|
||||
genCQMsg ();
|
||||
@ -5371,7 +5342,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
}
|
||||
auto const& my_callsign = m_config.my_callsign ();
|
||||
auto is_compound = my_callsign != m_baseCall;
|
||||
auto is_type_one = is_compound && shortList (my_callsign);
|
||||
auto is_type_one = !is77BitMode () && is_compound && shortList (my_callsign);
|
||||
auto const& my_grid = m_config.my_grid ().left (4);
|
||||
auto const& hisBase = Radio::base_callsign (hisCall);
|
||||
auto eme_short_codes = m_config.enable_VHF_features () && ui->cbShMsgs->isChecked ()
|
||||
@ -5384,7 +5355,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
QString t0s=hisCall + " " + my_callsign + " ";
|
||||
QString t0a,t0b;
|
||||
|
||||
if(bHisCall and bMyCall) t0=hisCall + " " + my_callsign + " ";
|
||||
if (is77BitMode () && bHisCall && bMyCall) t0=hisCall + " " + my_callsign + " ";
|
||||
t0a="<"+hisCall + "> " + my_callsign + " ";
|
||||
t0b=hisCall + " <" + my_callsign + "> ";
|
||||
|
||||
@ -5402,7 +5373,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
int n=rpt.toInt();
|
||||
rpt = rpt.asprintf("%+2.2d",n);
|
||||
|
||||
if(m_mode=="MSK144" or m_mode=="FT8" or m_mode=="FT4" || m_mode=="FST4") {
|
||||
if (is77BitMode ()) {
|
||||
QString t2,t3;
|
||||
QString sent=rpt;
|
||||
QString rs,rst;
|
||||
@ -5466,8 +5437,8 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
}
|
||||
}
|
||||
|
||||
if((m_mode!="MSK144" and m_mode!="FT8" and m_mode!="FT4" && m_mode != "FST4")) {
|
||||
t=t00 + rpt;
|
||||
if (!is77BitMode ()) {
|
||||
t=(is_type_one ? t0 : t00) + rpt;
|
||||
msgtype(t, ui->tx2);
|
||||
t=t0 + "R" + rpt;
|
||||
msgtype(t, ui->tx3);
|
||||
@ -5506,7 +5477,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
}
|
||||
}
|
||||
|
||||
if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="MSK144" || m_mode == "FST4") return;
|
||||
if (is77BitMode ()) return;
|
||||
|
||||
if (is_compound) {
|
||||
if (is_type_one) {
|
||||
@ -5519,8 +5490,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
case Configuration::type_2_msg_1_full:
|
||||
msgtype(t + my_grid, ui->tx1);
|
||||
if (!eme_short_codes) {
|
||||
if((m_mode=="MSK144" || m_mode=="FT8" || m_mode=="FT4" || m_mode == "FST4") &&
|
||||
SpecOp::NA_VHF == m_config.special_op_id()) {
|
||||
if(is77BitMode () && SpecOp::NA_VHF == m_config.special_op_id()) {
|
||||
msgtype(t + "R " + my_grid, ui->tx3); // #### Unreachable code
|
||||
} else {
|
||||
msgtype(t + "R" + rpt, ui->tx3);
|
||||
@ -5532,8 +5502,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
break;
|
||||
|
||||
case Configuration::type_2_msg_3_full:
|
||||
if ((m_mode=="MSK144" || m_mode=="FT8" || m_mode=="FT4" || m_mode == "FST4") &&
|
||||
SpecOp::NA_VHF == m_config.special_op_id()) {
|
||||
if (is77BitMode () && SpecOp::NA_VHF == m_config.special_op_id()) {
|
||||
msgtype(t + "R " + my_grid, ui->tx3);
|
||||
msgtype(t + "RRR", ui->tx4);
|
||||
} else {
|
||||
@ -5548,8 +5517,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
case Configuration::type_2_msg_5_only:
|
||||
msgtype(t00 + my_grid, ui->tx1);
|
||||
if (!eme_short_codes) {
|
||||
if ((m_mode=="MSK144" || m_mode=="FT8" || m_mode=="FT4" || m_mode == "FST4") &&
|
||||
SpecOp::NA_VHF == m_config.special_op_id()) {
|
||||
if (is77BitMode () && SpecOp::NA_VHF == m_config.special_op_id()) {
|
||||
msgtype(t + "R " + my_grid, ui->tx3); // #### Unreachable code
|
||||
msgtype(t + "RRR", ui->tx4);
|
||||
} else {
|
||||
@ -5584,7 +5552,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
}
|
||||
}
|
||||
m_rpt=rpt;
|
||||
if(SpecOp::HOUND == m_config.special_op_id() and is_compound) ui->tx1->setText("DE " + m_config.my_callsign());
|
||||
if(SpecOp::HOUND == m_config.special_op_id() and is_compound) ui->tx1->setText("DE " + my_callsign);
|
||||
}
|
||||
|
||||
void MainWindow::TxAgain()
|
||||
@ -5948,7 +5916,7 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button
|
||||
default: break;
|
||||
}
|
||||
|
||||
m_logDlg->initLogQSO (m_hisCall, grid, m_modeTx, m_rptSent, m_rptRcvd,
|
||||
m_logDlg->initLogQSO (m_hisCall, grid, m_mode, m_rptSent, m_rptRcvd,
|
||||
m_dateTimeQSOOn, dateTimeQSOOff, m_freqNominal +
|
||||
ui->TxFreqSpinBox->value(), m_noSuffix, m_xSent, m_xRcvd);
|
||||
m_inQSOwith="";
|
||||
@ -6087,7 +6055,7 @@ void MainWindow::displayWidgets(qint64 n)
|
||||
void MainWindow::on_actionFST4_triggered()
|
||||
{
|
||||
m_mode="FST4";
|
||||
m_modeTx="FST4";
|
||||
m_mode="FST4";
|
||||
ui->actionFST4->setChecked(true);
|
||||
m_bFast9=false;
|
||||
m_bFastMode=false;
|
||||
@ -6111,7 +6079,6 @@ void MainWindow::on_actionFST4_triggered()
|
||||
setup_status_bar(false);
|
||||
ui->cbAutoSeq->setChecked(true);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
m_wideGraph->setPeriod(m_TRperiod,6912);
|
||||
m_wideGraph->setRxFreq(ui->RxFreqSpinBox->value());
|
||||
m_wideGraph->setTol(ui->sbFtol->value());
|
||||
@ -6130,7 +6097,6 @@ void MainWindow::on_actionFST4_triggered()
|
||||
void MainWindow::on_actionFST4W_triggered()
|
||||
{
|
||||
m_mode="FST4W";
|
||||
m_modeTx="FST4W";
|
||||
ui->actionFST4W->setChecked(true);
|
||||
m_bFast9=false;
|
||||
m_bFastMode=false;
|
||||
@ -6149,7 +6115,6 @@ void MainWindow::on_actionFST4W_triggered()
|
||||
ui->WSPRfreqSpinBox->setMinimum(100);
|
||||
ui->WSPRfreqSpinBox->setMaximum(5000);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
m_wideGraph->setPeriod(m_TRperiod,6912);
|
||||
m_wideGraph->setTxFreq(ui->WSPRfreqSpinBox->value());
|
||||
m_wideGraph->setRxFreq(ui->sbFST4W_RxFreq->value());
|
||||
@ -6162,7 +6127,6 @@ void MainWindow::on_actionFST4W_triggered()
|
||||
void MainWindow::on_actionFT4_triggered()
|
||||
{
|
||||
m_mode="FT4";
|
||||
m_modeTx="FT4";
|
||||
m_TRperiod=7.5;
|
||||
bool bVHF=m_config.enable_VHF_features();
|
||||
m_bFast9=false;
|
||||
@ -6177,7 +6141,6 @@ void MainWindow::on_actionFT4_triggered()
|
||||
m_toneSpacing=12000.0/576.0;
|
||||
ui->actionFT4->setChecked(true);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
m_send_RR73=true;
|
||||
VHF_features_enabled(bVHF);
|
||||
m_fastGraph->hide();
|
||||
@ -6212,7 +6175,6 @@ void MainWindow::on_actionFT8_triggered()
|
||||
m_bFastMode=false;
|
||||
WSPR_config(false);
|
||||
switch_mode (Modes::FT8);
|
||||
m_modeTx="FT8";
|
||||
m_nsps=6912;
|
||||
m_FFTSize = m_nsps / 2;
|
||||
Q_EMIT FFTSize (m_FFTSize);
|
||||
@ -6221,7 +6183,6 @@ void MainWindow::on_actionFT8_triggered()
|
||||
m_toneSpacing=0.0; //???
|
||||
ui->actionFT8->setChecked(true); //???
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
VHF_features_enabled(bVHF);
|
||||
ui->cbAutoSeq->setChecked(true);
|
||||
m_TRperiod=15.0;
|
||||
@ -6316,7 +6277,6 @@ void MainWindow::on_actionJT4_triggered()
|
||||
bool bVHF=m_config.enable_VHF_features();
|
||||
WSPR_config(false);
|
||||
switch_mode (Modes::JT4);
|
||||
m_modeTx="JT4";
|
||||
m_TRperiod=60.0;
|
||||
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||
@ -6330,7 +6290,6 @@ void MainWindow::on_actionJT4_triggered()
|
||||
VHF_features_enabled(true);
|
||||
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
m_bFastMode=false;
|
||||
m_bFast9=false;
|
||||
setup_status_bar (bVHF);
|
||||
@ -6362,7 +6321,6 @@ void MainWindow::on_actionJT9_triggered()
|
||||
m_bFastMode=m_bFast9;
|
||||
WSPR_config(false);
|
||||
switch_mode (Modes::JT9);
|
||||
m_modeTx="JT9";
|
||||
m_nsps=6912;
|
||||
m_FFTSize = m_nsps / 2;
|
||||
Q_EMIT FFTSize (m_FFTSize);
|
||||
@ -6372,7 +6330,6 @@ void MainWindow::on_actionJT9_triggered()
|
||||
m_toneSpacing=0.0;
|
||||
ui->actionJT9->setChecked(true);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
VHF_features_enabled(bVHF);
|
||||
if(m_nSubMode>=4 and bVHF) {
|
||||
ui->cbFast9->setEnabled(true);
|
||||
@ -6419,7 +6376,6 @@ void MainWindow::on_actionJT65_triggered()
|
||||
{
|
||||
on_actionJT9_triggered();
|
||||
m_mode="JT65";
|
||||
m_modeTx="JT65";
|
||||
bool bVHF=m_config.enable_VHF_features();
|
||||
WSPR_config(false);
|
||||
switch_mode (Modes::JT65);
|
||||
@ -6436,7 +6392,6 @@ void MainWindow::on_actionJT65_triggered()
|
||||
VHF_features_enabled(bVHF);
|
||||
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
m_wideGraph->setRxFreq(ui->RxFreqSpinBox->value());
|
||||
m_wideGraph->setTol(ui->sbFtol->value());
|
||||
m_wideGraph->setTxFreq(ui->TxFreqSpinBox->value());
|
||||
@ -6470,12 +6425,12 @@ void MainWindow::on_actionJT65_triggered()
|
||||
void MainWindow::on_actionQ65_triggered()
|
||||
{
|
||||
m_mode="Q65";
|
||||
m_modeTx="Q65";
|
||||
ui->actionQ65->setChecked(true);
|
||||
switch_mode(Modes::Q65);
|
||||
fast_config(false);
|
||||
WSPR_config(false);
|
||||
setup_status_bar(true);
|
||||
ui->actionQuickDecode->setChecked(true);
|
||||
m_nsps=6912; //For symspec only
|
||||
m_FFTSize = m_nsps / 2;
|
||||
Q_EMIT FFTSize(m_FFTSize);
|
||||
@ -6486,7 +6441,6 @@ void MainWindow::on_actionQ65_triggered()
|
||||
QString fname {QDir::toNativeSeparators(m_config.temp_dir().absoluteFilePath ("red.dat"))};
|
||||
m_wideGraph->setRedFile(fname);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
m_wideGraph->setPeriod(m_TRperiod,6912);
|
||||
m_wideGraph->setTol(ui->sbFtol->value());
|
||||
m_wideGraph->setRxFreq(ui->RxFreqSpinBox->value());
|
||||
@ -6530,7 +6484,6 @@ void MainWindow::on_actionMSK144_triggered()
|
||||
return;
|
||||
}
|
||||
m_mode="MSK144";
|
||||
m_modeTx="MSK144";
|
||||
ui->actionMSK144->setChecked(true);
|
||||
switch_mode (Modes::MSK144);
|
||||
m_nsps=6;
|
||||
@ -6586,7 +6539,6 @@ void MainWindow::on_actionWSPR_triggered()
|
||||
m_mode="WSPR";
|
||||
WSPR_config(true);
|
||||
switch_mode (Modes::WSPR);
|
||||
m_modeTx="WSPR";
|
||||
m_TRperiod=120.0;
|
||||
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||
@ -6602,7 +6554,6 @@ void MainWindow::on_actionWSPR_triggered()
|
||||
ui->WSPRfreqSpinBox->setMaximum(1600);
|
||||
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
m_bFastMode=false;
|
||||
m_bFast9=false;
|
||||
ui->TxFreqSpinBox->setValue(ui->WSPRfreqSpinBox->value());
|
||||
@ -6626,10 +6577,8 @@ void MainWindow::on_actionEcho_triggered()
|
||||
m_hsymStop=9;
|
||||
m_toneSpacing=1.0;
|
||||
switch_mode(Modes::Echo);
|
||||
m_modeTx="Echo";
|
||||
setup_status_bar (true);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
m_wideGraph->setModeTx(m_modeTx);
|
||||
ui->TxFreqSpinBox->setValue(1500);
|
||||
ui->TxFreqSpinBox->setEnabled (false);
|
||||
if(!m_echoGraph->isVisible()) m_echoGraph->show();
|
||||
@ -7315,7 +7264,7 @@ void MainWindow::rigFailure (QString const& reason)
|
||||
void MainWindow::transmit (double snr)
|
||||
{
|
||||
double toneSpacing=0.0;
|
||||
if (m_modeTx == "JT65") {
|
||||
if (m_mode == "JT65") {
|
||||
if(m_nSubMode==0) toneSpacing=11025.0/4096.0;
|
||||
if(m_nSubMode==1) toneSpacing=2*11025.0/4096.0;
|
||||
if(m_nSubMode==2) toneSpacing=4*11025.0/4096.0;
|
||||
@ -7325,7 +7274,7 @@ void MainWindow::transmit (double snr)
|
||||
true, false, snr, m_TRperiod);
|
||||
}
|
||||
|
||||
if (m_modeTx == "FT8") {
|
||||
if (m_mode == "FT8") {
|
||||
// toneSpacing=12000.0/1920.0;
|
||||
toneSpacing=-3;
|
||||
if(m_config.x2ToneSpacing()) toneSpacing=2*12000.0/1920.0;
|
||||
@ -7337,7 +7286,7 @@ void MainWindow::transmit (double snr)
|
||||
true, false, snr, m_TRperiod);
|
||||
}
|
||||
|
||||
if (m_modeTx == "FT4") {
|
||||
if (m_mode == "FT4") {
|
||||
m_dateTimeSentTx3=QDateTime::currentDateTimeUtc();
|
||||
toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform.
|
||||
Q_EMIT sendMessage (m_mode, NUM_FT4_SYMBOLS,
|
||||
@ -7346,7 +7295,7 @@ void MainWindow::transmit (double snr)
|
||||
true, false, snr, m_TRperiod);
|
||||
}
|
||||
|
||||
if (m_modeTx == "FST4" or m_modeTx == "FST4W") {
|
||||
if (m_mode == "FST4" or m_mode == "FST4W") {
|
||||
m_dateTimeSentTx3=QDateTime::currentDateTimeUtc();
|
||||
toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform.
|
||||
int nsps=720;
|
||||
@ -7368,7 +7317,7 @@ void MainWindow::transmit (double snr)
|
||||
true, false, snr, m_TRperiod);
|
||||
}
|
||||
|
||||
if (m_modeTx == "Q65") {
|
||||
if (m_mode == "Q65") {
|
||||
int nsps=1800;
|
||||
if(m_TRperiod==30) nsps=3600;
|
||||
if(m_TRperiod==60) nsps=7200;
|
||||
@ -7383,7 +7332,7 @@ void MainWindow::transmit (double snr)
|
||||
true, false, snr, m_TRperiod);
|
||||
}
|
||||
|
||||
if (m_modeTx == "JT9") {
|
||||
if (m_mode == "JT9") {
|
||||
int nsub=pow(2,m_nSubMode);
|
||||
int nsps[]={480,240,120,60};
|
||||
double sps=m_nsps;
|
||||
@ -7402,7 +7351,7 @@ void MainWindow::transmit (double snr)
|
||||
true, fastmode, snr, m_TRperiod);
|
||||
}
|
||||
|
||||
if (m_modeTx == "MSK144") {
|
||||
if (m_mode == "MSK144") {
|
||||
m_nsps=6;
|
||||
double f0=1000.0;
|
||||
if(!m_bFastMode) {
|
||||
@ -7420,7 +7369,7 @@ void MainWindow::transmit (double snr)
|
||||
true, true, snr, m_TRperiod);
|
||||
}
|
||||
|
||||
if (m_modeTx == "JT4") {
|
||||
if (m_mode == "JT4") {
|
||||
if(m_nSubMode==0) toneSpacing=4.375;
|
||||
if(m_nSubMode==1) toneSpacing=2*4.375;
|
||||
if(m_nSubMode==2) toneSpacing=4*4.375;
|
||||
@ -7599,7 +7548,7 @@ void::MainWindow::VHF_features_enabled(bool b)
|
||||
}
|
||||
ui->actionInclude_averaging->setVisible (b);
|
||||
ui->actionInclude_correlation->setVisible (b && m_mode!="Q65");
|
||||
ui->actionMessage_averaging->setEnabled(b);
|
||||
ui->actionMessage_averaging->setEnabled(b && (m_mode=="JT4" or m_mode=="JT65"));
|
||||
ui->actionEnable_AP_JT65->setVisible (b && m_mode=="JT65");
|
||||
|
||||
if(!b && m_msgAvgWidget and (SpecOp::FOX != m_config.special_op_id()) and !m_config.autoLog()) {
|
||||
@ -8423,7 +8372,7 @@ void MainWindow::statusUpdate () const
|
||||
}
|
||||
m_messageClient->status_update (m_freqNominal, m_mode, m_hisCall,
|
||||
QString::number (ui->rptSpinBox->value ()),
|
||||
m_modeTx, ui->autoButton->isChecked (),
|
||||
m_mode, ui->autoButton->isChecked (),
|
||||
m_transmitting, m_decoderBusy,
|
||||
rx_frequency, ui->TxFreqSpinBox->value (),
|
||||
m_config.my_callsign (), m_config.my_grid (),
|
||||
@ -8556,7 +8505,7 @@ void MainWindow::write_transmit_entry (QString const& file_name)
|
||||
time = time.addSecs (-fmod(double(time.time().second()),m_TRperiod));
|
||||
out << time.toString("yyMMdd_hhmmss")
|
||||
<< " Transmitting " << qSetRealNumberPrecision (12) << (m_freqNominal / 1.e6)
|
||||
<< " MHz " << m_modeTx
|
||||
<< " MHz " << m_mode
|
||||
<< ": " << m_currentMessage
|
||||
#if QT_VERSION >= QT_VERSION_CHECK (5, 15, 0)
|
||||
<< Qt::endl
|
||||
|
@ -419,7 +419,6 @@ private:
|
||||
Astro::Correction m_astroCorrection;
|
||||
bool m_reverse_Doppler;
|
||||
|
||||
double m_s6;
|
||||
double m_tRemaining;
|
||||
double m_TRperiod;
|
||||
|
||||
@ -454,7 +453,6 @@ private:
|
||||
qint32 m_nclearave;
|
||||
qint32 m_minSync;
|
||||
qint32 m_dBm;
|
||||
qint32 m_nseq;
|
||||
qint32 m_nWSPRdecodes;
|
||||
qint32 m_k0;
|
||||
qint32 m_kdone;
|
||||
@ -612,7 +610,6 @@ private:
|
||||
QString m_palette;
|
||||
QString m_dateTime;
|
||||
QString m_mode;
|
||||
QString m_modeTx;
|
||||
QString m_fnameWE; // save path without extension
|
||||
QString m_rpt;
|
||||
QString m_nextRpt;
|
||||
@ -781,6 +778,7 @@ private:
|
||||
void foxGenWaveform(int i,QString fm);
|
||||
void writeFoxQSO (QString const& msg);
|
||||
void to_jt9(qint32 n, qint32 istart, qint32 idone);
|
||||
bool is77BitMode () const;
|
||||
};
|
||||
|
||||
extern int killbyname(const char* progName);
|
||||
|
@ -644,7 +644,7 @@ QPushButton[state="ok"] {
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="bandComboBox">
|
||||
<widget class="BandComboBox" name="bandComboBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html></string>
|
||||
</property>
|
||||
@ -661,7 +661,7 @@ QPushButton[state="ok"] {
|
||||
<enum>QComboBox::NoInsert</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
|
||||
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -3434,7 +3434,7 @@ Double-click to reset to the standard 73 message</string>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DisplayText</class>
|
||||
<extends>QTextEdit</extends>
|
||||
<extends>QTextBrowser</extends>
|
||||
<header>widgets/displaytext.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
@ -3468,6 +3468,11 @@ Double-click to reset to the standard 73 message</string>
|
||||
<extends>QPushButton</extends>
|
||||
<header>widgets/DoubleClickablePushButton.hpp</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>BandComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>widgets/BandComboBox.hpp</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>decodedTextBrowser</tabstop>
|
||||
|
@ -479,7 +479,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
if(m_modeTx=="JT9" and m_nSubMode>0) { //JT9
|
||||
if(m_mode=="JT9" and m_nSubMode>0) { //JT9
|
||||
bw=8.0*12000.0/m_nsps;
|
||||
if(m_nSubMode==1) bw=2*bw; //B
|
||||
if(m_nSubMode==2) bw=4*bw; //C
|
||||
@ -500,7 +500,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
float baud=12000.0/nsps;
|
||||
bw=65.0*h*baud;
|
||||
}
|
||||
if(m_modeTx=="JT65") { //JT65
|
||||
if(m_mode=="JT65") { //JT65
|
||||
bw=65.0*11025.0/4096.0;
|
||||
if(m_nSubMode==1) bw=2*bw; //B
|
||||
if(m_nSubMode==2) bw=4*bw; //C
|
||||
@ -817,11 +817,6 @@ void CPlotter::setSubMode(int n) //setSubMode
|
||||
m_nSubMode=n;
|
||||
}
|
||||
|
||||
void CPlotter::setModeTx(QString modeTx) //setModeTx
|
||||
{
|
||||
m_modeTx=modeTx;
|
||||
}
|
||||
|
||||
int CPlotter::Fmax()
|
||||
{
|
||||
return m_fMax;
|
||||
|
@ -61,7 +61,6 @@ public:
|
||||
void setTxFreq(int n);
|
||||
void setMode(QString mode);
|
||||
void setSubMode(int n);
|
||||
void setModeTx(QString modeTx);
|
||||
void SetPercent2DScreen(int percent);
|
||||
int Fmax();
|
||||
void setDialFreq(double d);
|
||||
@ -149,7 +148,6 @@ private:
|
||||
QString m_HDivText[483];
|
||||
QString m_mode;
|
||||
QString m_mode0;
|
||||
QString m_modeTx;
|
||||
QString m_rxBand;
|
||||
QString m_redFile;
|
||||
|
||||
|
@ -305,13 +305,6 @@ void WideGraph::setSubMode(int n) //setSubMode
|
||||
ui->widePlot->DrawOverlay();
|
||||
ui->widePlot->update();
|
||||
}
|
||||
void WideGraph::setModeTx(QString modeTx) //setModeTx
|
||||
{
|
||||
m_modeTx=modeTx;
|
||||
ui->widePlot->setModeTx(modeTx);
|
||||
ui->widePlot->DrawOverlay();
|
||||
ui->widePlot->update();
|
||||
}
|
||||
|
||||
void WideGraph::on_spec2dComboBox_currentIndexChanged(int index)
|
||||
{
|
||||
|
@ -39,7 +39,6 @@ public:
|
||||
void setTxFreq(int n);
|
||||
void setMode(QString mode);
|
||||
void setSubMode(int n);
|
||||
void setModeTx(QString modeTx);
|
||||
bool flatten();
|
||||
bool useRef();
|
||||
void setTol(int n);
|
||||
@ -116,7 +115,6 @@ private:
|
||||
|
||||
QString m_rxBand;
|
||||
QString m_mode;
|
||||
QString m_modeTx;
|
||||
QString m_waterfallPalette;
|
||||
float m_swide[MAX_SCREENSIZE];
|
||||
QString m_user_defined;
|
||||
|
@ -65,6 +65,7 @@ SOURCES += \
|
||||
getfile.cpp \
|
||||
WFPalette.cpp \
|
||||
WsprTxScheduler.cpp \
|
||||
helper_functions.cpp \
|
||||
main.cpp decodedtext.cpp wsprnet.cpp \
|
||||
WSPRBandHopping.cpp MessageAggregator.cpp SampleDownloader.cpp qt_helpers.cpp\
|
||||
MultiSettings.cpp PhaseEqualizationDialog.cpp \
|
||||
@ -72,6 +73,7 @@ SOURCES += \
|
||||
LotWUsers.cpp TraceFile.cpp
|
||||
|
||||
HEADERS += qt_helpers.hpp qt_db_helpers.hpp \
|
||||
helper_functions.h \
|
||||
pimpl_h.hpp pimpl_impl.hpp \
|
||||
ExceptionCatchingApplication.hpp Logger.hpp WSJTXLogging.hpp \
|
||||
Radio.hpp NetworkServerLookup.hpp revision_utils.hpp \
|
||||
|
Loading…
Reference in New Issue
Block a user