mirror of https://github.com/saitohirga/WSJT-X.git
Merging code for v1.1 back into the main wsjtx branch.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@3462 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
ba61cfde6a
commit
3dc6abc0c1
Binary file not shown.
|
@ -1,7 +1,8 @@
|
|||
#ifndef COMMONS_H
|
||||
#define COMMONS_H
|
||||
|
||||
#define NSMAX 1365
|
||||
//#define NSMAX 1365
|
||||
#define NSMAX 6827
|
||||
#define NTMAX 120
|
||||
|
||||
extern "C" {
|
||||
|
@ -9,7 +10,6 @@ extern "C" {
|
|||
extern struct {
|
||||
float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran
|
||||
float savg[NSMAX];
|
||||
float c0[2*NTMAX*1500];
|
||||
short int d2[NTMAX*12000];
|
||||
int nutc; //UTC as integer, HHMM
|
||||
int ndiskdat; //1 ==> data read from *.wav file
|
||||
|
@ -25,8 +25,8 @@ extern struct {
|
|||
int nsave;
|
||||
int nagain;
|
||||
int ndepth;
|
||||
int nrxlog;
|
||||
int nfsample;
|
||||
int ntxmode;
|
||||
int nmode;
|
||||
char datetime[20];
|
||||
} jt9com_;
|
||||
|
||||
|
|
65
devsetup.cpp
65
devsetup.cpp
|
@ -1,10 +1,13 @@
|
|||
#include "devsetup.h"
|
||||
#include <QDebug>
|
||||
#include <QSettings>
|
||||
#include <portaudio.h>
|
||||
|
||||
#define MAXDEVICES 100
|
||||
|
||||
extern double dFreq[16];
|
||||
qint32 g2_iptt;
|
||||
qint32 g2_COMportOpen;
|
||||
|
||||
//----------------------------------------------------------- DevSetup()
|
||||
DevSetup::DevSetup(QWidget *parent) : QDialog(parent)
|
||||
|
@ -13,10 +16,10 @@ DevSetup::DevSetup(QWidget *parent) : QDialog(parent)
|
|||
m_restartSoundIn=false;
|
||||
m_restartSoundOut=false;
|
||||
m_firstCall=true;
|
||||
m_iptt=0;
|
||||
g2_iptt=0;
|
||||
m_test=0;
|
||||
m_bRigOpen=false;
|
||||
m_COMportOpen=0;
|
||||
g2_COMportOpen=0;
|
||||
}
|
||||
|
||||
DevSetup::~DevSetup()
|
||||
|
@ -25,6 +28,13 @@ DevSetup::~DevSetup()
|
|||
|
||||
void DevSetup::initDlg()
|
||||
{
|
||||
QString m_appDir = QApplication::applicationDirPath();
|
||||
QString inifile = m_appDir + "/wsjtx.ini";
|
||||
QSettings settings(inifile, QSettings::IniFormat);
|
||||
settings.beginGroup("Common");
|
||||
QString catPortDriver = settings.value("CATdriver","None").toString();
|
||||
settings.endGroup();
|
||||
|
||||
int k,id;
|
||||
int numDevices=Pa_GetDeviceCount();
|
||||
|
||||
|
@ -40,6 +50,8 @@ void DevSetup::initDlg()
|
|||
nchin=pdi->maxInputChannels;
|
||||
if(nchin>0) {
|
||||
m_inDevList[k]=id;
|
||||
if (id == m_paInDevice)
|
||||
m_nDevIn = k;
|
||||
k++;
|
||||
sprintf((char*)(pa_device_name),"%s",pdi->name);
|
||||
sprintf((char*)(pa_device_hostapi),"%s",
|
||||
|
@ -77,6 +89,8 @@ void DevSetup::initDlg()
|
|||
nchout=pdi->maxOutputChannels;
|
||||
if(nchout>0) {
|
||||
m_outDevList[k]=id;
|
||||
if (id == m_paOutDevice)
|
||||
m_nDevOut = k;
|
||||
k++;
|
||||
sprintf((char*)(pa_device_name),"%s",pdi->name);
|
||||
sprintf((char*)(pa_device_hostapi),"%s",
|
||||
|
@ -115,6 +129,7 @@ void DevSetup::initDlg()
|
|||
this, SLOT(p4Error()));
|
||||
p4.start("rigctl -l");
|
||||
p4.waitForFinished(1000);
|
||||
ui.rigComboBox->addItem(" 9998 Commander");
|
||||
ui.rigComboBox->addItem(" 9999 Ham Radio Deluxe");
|
||||
|
||||
QPalette pal(ui.myCallEntry->palette());
|
||||
|
@ -136,8 +151,9 @@ void DevSetup::initDlg()
|
|||
ui.comboBoxSndOut->setCurrentIndex(m_nDevOut);
|
||||
ui.cbID73->setChecked(m_After73);
|
||||
ui.cbPSKReporter->setChecked(m_pskReporter);
|
||||
m_paInDevice=m_inDevList[m_nDevIn];
|
||||
m_paOutDevice=m_outDevList[m_nDevOut];
|
||||
ui.cbSplit->setChecked(m_bSplit);
|
||||
ui.cbXIT->setChecked(m_bXIT);
|
||||
ui.cbXIT->setVisible(false);
|
||||
|
||||
enableWidgets();
|
||||
|
||||
|
@ -176,6 +192,7 @@ void DevSetup::initDlg()
|
|||
ui.catPortComboBox->addItem("/dev/ttyUSB1");
|
||||
ui.catPortComboBox->addItem("/dev/ttyUSB2");
|
||||
ui.catPortComboBox->addItem("/dev/ttyUSB3");
|
||||
ui.catPortComboBox->addItem(catPortDriver);
|
||||
|
||||
ui.pttComboBox->addItem("/dev/ttyS0");
|
||||
ui.pttComboBox->addItem("/dev/ttyS1");
|
||||
|
@ -280,7 +297,7 @@ void DevSetup::accept()
|
|||
|
||||
if(m_bRigOpen) {
|
||||
rig->close();
|
||||
if(m_rig!=9999) delete rig;
|
||||
if(m_rig<9900) delete rig;
|
||||
m_bRigOpen=false;
|
||||
}
|
||||
|
||||
|
@ -414,18 +431,22 @@ void DevSetup::on_testCATButton_clicked()
|
|||
if(!m_catEnabled) return;
|
||||
if(m_bRigOpen) {
|
||||
rig->close();
|
||||
if(m_rig!=9999) delete rig;
|
||||
if(m_rig<9900) delete rig;
|
||||
m_bRigOpen=false;
|
||||
}
|
||||
|
||||
rig = new Rig();
|
||||
|
||||
if(m_rig != 9999) {
|
||||
if(m_rig<9900) {
|
||||
if (!rig->init(m_rig)) {
|
||||
msgBox("Rig init failure");
|
||||
return;
|
||||
}
|
||||
rig->setConf("rig_pathname", m_catPort.toLatin1().data());
|
||||
QString sCATport=m_catPort;
|
||||
#ifdef WIN32
|
||||
sCATport="\\\\.\\" + m_catPort; //Allow COM ports above 9
|
||||
#endif
|
||||
rig->setConf("rig_pathname", sCATport.toLatin1().data());
|
||||
char buf[80];
|
||||
sprintf(buf,"%d",m_serialRate);
|
||||
rig->setConf("serial_speed",buf);
|
||||
|
@ -470,7 +491,9 @@ void DevSetup::on_testPTTButton_clicked()
|
|||
{
|
||||
m_test=1-m_test;
|
||||
if(m_pttMethodIndex==1 or m_pttMethodIndex==2) {
|
||||
ptt(m_pttPort,m_test,&m_iptt,&m_COMportOpen);
|
||||
// qDebug() << "devsetup line 492:" << m_pttPort << m_test << &g2_iptt << &g2_COMportOpen;
|
||||
ptt(m_pttPort,m_test,&g2_iptt,&g2_COMportOpen);
|
||||
// qDebug() << "devsetup line 494:" << m_pttPort << m_test << &g2_iptt << &g2_COMportOpen;
|
||||
}
|
||||
if(m_pttMethodIndex==0 and !m_bRigOpen) {
|
||||
on_testCATButton_clicked();
|
||||
|
@ -522,8 +545,10 @@ void DevSetup::enableWidgets()
|
|||
ui.testCATButton->setEnabled(m_catEnabled);
|
||||
ui.label_4->setEnabled(m_catEnabled);
|
||||
ui.label_47->setEnabled(m_catEnabled);
|
||||
ui.cbSplit->setEnabled(m_catEnabled);
|
||||
ui.cbXIT->setEnabled(m_catEnabled);
|
||||
|
||||
bool bSerial=m_catEnabled and (m_rig!=9999);
|
||||
bool bSerial=m_catEnabled and (m_rig<9900);
|
||||
ui.catPortComboBox->setEnabled(bSerial);
|
||||
ui.serialRateComboBox->setEnabled(bSerial);
|
||||
ui.dataBitsComboBox->setEnabled(bSerial);
|
||||
|
@ -541,9 +566,21 @@ void DevSetup::enableWidgets()
|
|||
ui.pollSpinBox->setEnabled(m_catEnabled);
|
||||
bool b1=(m_pttMethodIndex==1 or m_pttMethodIndex==2);
|
||||
ui.pttComboBox->setEnabled(b1);
|
||||
bool b2 = (m_catEnabled and m_pttMethodIndex==1 and m_rig!=9999) or
|
||||
(m_catEnabled and m_pttMethodIndex==2 and m_rig!=9999);
|
||||
bool b3 = (m_catEnabled and m_pttMethodIndex==0 and m_rig==9999);
|
||||
bool b2 = (m_catEnabled and m_pttMethodIndex==1 and m_rig<9900) or
|
||||
(m_catEnabled and m_pttMethodIndex==2 and m_rig<9900);
|
||||
bool b3 = (m_catEnabled and m_pttMethodIndex==0 and m_rig>=9900);
|
||||
// ui.testPTTButton->setEnabled(b1 or b2);
|
||||
ui.testPTTButton->setEnabled(b1 or b2 or b3); //Include PTT via HRD
|
||||
ui.testPTTButton->setEnabled(b1 or b2 or b3); //Include PTT via HRD or Commander
|
||||
}
|
||||
|
||||
void DevSetup::on_cbSplit_toggled(bool checked)
|
||||
{
|
||||
m_bSplit=checked;
|
||||
if(m_bSplit and m_bXIT) ui.cbXIT->setChecked(false);
|
||||
}
|
||||
|
||||
void DevSetup::on_cbXIT_toggled(bool checked)
|
||||
{
|
||||
m_bXIT=checked;
|
||||
if(m_bSplit and m_bXIT) ui.cbSplit->setChecked(false);
|
||||
}
|
||||
|
|
|
@ -35,9 +35,7 @@ public:
|
|||
qint32 m_stopBits;
|
||||
qint32 m_stopBitsIndex;
|
||||
qint32 m_handshakeIndex;
|
||||
qint32 m_iptt;
|
||||
qint32 m_test;
|
||||
qint32 m_COMportOpen;
|
||||
qint32 m_poll;
|
||||
qint32 m_tmp;
|
||||
|
||||
|
@ -50,6 +48,8 @@ public:
|
|||
bool m_bRigOpen;
|
||||
bool m_bDTRoff;
|
||||
bool m_pttData;
|
||||
bool m_bSplit;
|
||||
bool m_bXIT;
|
||||
|
||||
QString m_myCall;
|
||||
QString m_myGrid;
|
||||
|
@ -93,6 +93,10 @@ private slots:
|
|||
void on_pttComboBox_currentIndexChanged(int index);
|
||||
void on_pttMethodComboBox_currentIndexChanged(int index);
|
||||
|
||||
void on_cbSplit_toggled(bool checked);
|
||||
|
||||
void on_cbXIT_toggled(bool checked);
|
||||
|
||||
private:
|
||||
Rig* rig;
|
||||
void msgBox(QString t);
|
||||
|
|
114
devsetup.ui
114
devsetup.ui
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>548</width>
|
||||
<width>569</width>
|
||||
<height>493</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -584,6 +584,32 @@
|
|||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbDTRoff">
|
||||
<property name="text">
|
||||
<string>RTS/DTR OFF</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_14">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
|
@ -741,6 +767,9 @@
|
|||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
|
@ -750,9 +779,25 @@
|
|||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbDTRoff">
|
||||
<widget class="QRadioButton" name="rbData">
|
||||
<property name="toolTip">
|
||||
<string>Use special Tx command for "data"</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RTS/DTR OFF</string>
|
||||
<string>Data</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbMic">
|
||||
<property name="toolTip">
|
||||
<string>Use normal Tx command</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mic</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -899,7 +944,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_14">
|
||||
<spacer name="horizontalSpacer_16">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
|
@ -915,25 +960,9 @@
|
|||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbData">
|
||||
<property name="toolTip">
|
||||
<string>Use special Tx command for "data"</string>
|
||||
</property>
|
||||
<widget class="QCheckBox" name="cbSplit">
|
||||
<property name="text">
|
||||
<string>Data</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbMic">
|
||||
<property name="toolTip">
|
||||
<string>Use normal Tx command</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mic</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
<string>Split Tx</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -1010,6 +1039,29 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_17">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbXIT">
|
||||
<property name="text">
|
||||
<string>XIT</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_12">
|
||||
<property name="orientation">
|
||||
|
@ -1313,6 +1365,9 @@
|
|||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>5W DPL 73 GL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
|
@ -1360,6 +1415,9 @@
|
|||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>20W DPL 73 GL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
|
@ -1554,6 +1612,9 @@
|
|||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
|
@ -1576,6 +1637,9 @@
|
|||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TNX 73 GL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
|
@ -1598,6 +1662,9 @@
|
|||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>10W DPL 73 GL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
|
@ -2457,11 +2524,8 @@
|
|||
<tabstop>catPortComboBox</tabstop>
|
||||
<tabstop>dataBitsComboBox</tabstop>
|
||||
<tabstop>serialRateComboBox</tabstop>
|
||||
<tabstop>cbDTRoff</tabstop>
|
||||
<tabstop>stopBitsComboBox</tabstop>
|
||||
<tabstop>handshakeComboBox</tabstop>
|
||||
<tabstop>rbData</tabstop>
|
||||
<tabstop>rbMic</tabstop>
|
||||
<tabstop>testCATButton</tabstop>
|
||||
<tabstop>testPTTButton</tabstop>
|
||||
<tabstop>pollSpinBox</tabstop>
|
||||
|
|
41
getfile.cpp
41
getfile.cpp
|
@ -1,11 +1,19 @@
|
|||
#include "getfile.h"
|
||||
#include <QDir>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#endif
|
||||
|
||||
void getfile(QString fname, int ntrperiod)
|
||||
|
@ -123,6 +131,7 @@ float gran()
|
|||
|
||||
int ptt(int nport, int ntx, int* iptt, int* nopen)
|
||||
{
|
||||
// qDebug() << "getfile ptt(), line 129:" << nport << ntx << *iptt << *nopen;
|
||||
#ifdef WIN32
|
||||
static HANDLE hFile;
|
||||
char s[10];
|
||||
|
@ -130,7 +139,7 @@ int ptt(int nport, int ntx, int* iptt, int* nopen)
|
|||
|
||||
if(nport==0) {
|
||||
*iptt=ntx;
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(ntx && (!(*nopen))) {
|
||||
|
@ -160,6 +169,34 @@ int ptt(int nport, int ntx, int* iptt, int* nopen)
|
|||
*nopen=0;
|
||||
}
|
||||
if((i3+i4+i5+i6+i9+i00)==-999) return 1; //Silence compiler warning
|
||||
// qDebug() << "getfile ptt(), line 167:" << nport << ntx << *iptt << *nopen;
|
||||
return 0;
|
||||
#else
|
||||
// qDebug() << "getfile ptt(), line 170:" << nport << ntx << *iptt << *nopen;
|
||||
// ptt_(nport,ntx, iptt, nopen);
|
||||
|
||||
// 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
|
||||
|
|
|
@ -10,5 +10,4 @@ float gran();
|
|||
//int ptt(int* nport, int* ntx, int* iptt);
|
||||
int ptt(int nport, int ntx, int* iptt, int* nopen);
|
||||
|
||||
|
||||
#endif // GETFILE_H
|
||||
|
|
|
@ -20,7 +20,7 @@ CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
|
|||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libjt9.a jt9sim.exe jt9.exe jt9code.exe test9.exe
|
||||
all: libjt9.a jt9sim.exe jt9.exe jt9code.exe jt65.exe
|
||||
|
||||
OBJS1 = pctile.o graycode.o sort.o ssort.o \
|
||||
unpackmsg.o igray.o unpackcall.o unpackgrid.o \
|
||||
|
@ -30,10 +30,15 @@ OBJS1 = pctile.o graycode.o sort.o ssort.o \
|
|||
symspec.o analytic.o db.o genjt9.o \
|
||||
packbits.o unpackbits.o encode232.o interleave9.o \
|
||||
entail.o fano232.o gran.o sync9.o decode9.o \
|
||||
fil3.o redsync.o decoder.o grid2n.o n2grid.o timer.o \
|
||||
fil3.o decoder.o grid2n.o n2grid.o timer.o \
|
||||
softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
|
||||
peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
|
||||
fillcom.o chkss2.o zplot9.o
|
||||
fillcom.o chkss2.o zplot9.o flat2.o \
|
||||
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
ar cr libjt9.a $(OBJS1)
|
||||
|
@ -54,15 +59,9 @@ OBJS4 = jt9code.o
|
|||
jt9code.exe: $(OBJS4) libjt9.a
|
||||
$(FC) -o jt9code.exe $(OBJS4) libjt9.a
|
||||
|
||||
OBJS5 = test9.o
|
||||
test9.exe: $(OBJS5) libjt9.a
|
||||
$(FC) -o test9.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
|
||||
|
||||
OBJS6 = wsjt24d.o wsjt24.o sync24.o decode24.o ps24.o flat1.o \
|
||||
xcor24.o slope.o peakup.o interleave24.o getmet24.o smo.o \
|
||||
deep24.o encode4.o chkmsg.o avemsg4.o extract4.o
|
||||
wsjt24d.exe: $(OBJS6) libjt9.a
|
||||
$(FC) -o wsjt24d.exe $(OBJS6) libjt9.a ../libfftw3f_win.a
|
||||
OBJS5 = jt65.o
|
||||
jt65.exe: $(OBJS5) libjt9.a
|
||||
$(FC) -o jt65.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
|
||||
|
||||
INCPATH = -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore' \
|
||||
-I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include' \
|
||||
|
@ -75,9 +74,6 @@ sync9.o: sync9.f90 jt9sync.f90
|
|||
spec9.o: spec9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c spec9.f90
|
||||
|
||||
peakdf9.o: peakdf9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c peakdf9.f90
|
||||
|
||||
peakdt9.o: peakdt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c peakdt9.f90
|
||||
|
||||
|
@ -105,7 +101,17 @@ sec_midn.o: sec_midn.f90
|
|||
tstrig.o: tstrig.c
|
||||
$(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
rm -f *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt9test.exe
|
||||
rm -f *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe
|
||||
|
|
|
@ -23,14 +23,19 @@ OBJS1 = pctile.o graycode.o sort.o ssort.o \
|
|||
grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
|
||||
packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
|
||||
nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.o \
|
||||
symspec.o analytic.o db.o genjt9.o ptt_unix.o \
|
||||
symspec.o analytic.o db.o genjt9.o \
|
||||
packbits.o unpackbits.o encode232.o interleave9.o \
|
||||
entail.o fano232.o gran.o sync9.o decode9.o \
|
||||
fil3.o redsync.o decoder.o grid2n.o n2grid.o timer.o \
|
||||
fil3.o decoder.o grid2n.o n2grid.o timer.o \
|
||||
softsym.o peakdt9.o getlags.o afc9.o fchisq.o \
|
||||
twkfreq.o downsam9.o symspec2.o ipcomm.o sleep_msec.o \
|
||||
stdmsg.o sec_midn.o cutil.o azdist.o geodist.o morse.o \
|
||||
fillcom.o chkss2.o
|
||||
fillcom.o chkss2.o zplot9.o flat2.o \
|
||||
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
ar cr libjt9.a $(OBJS1)
|
||||
|
@ -38,7 +43,7 @@ libjt9.a: $(OBJS1)
|
|||
|
||||
OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o
|
||||
|
||||
jt9: $(OBJS2) libjt9.a
|
||||
jt9: $(OBJS2) libjt9.a
|
||||
g++ -o jt9 $(OBJS2) libjt9.a -lfftw3f -lgfortran -lQtCore
|
||||
cp jt9 ../../wsjtx_install
|
||||
|
||||
|
@ -84,6 +89,15 @@ ipcomm.o: ipcomm.cpp
|
|||
sec_midn.o: sec_midn.f90
|
||||
$(FC) -c -fno-second-underscore sec_midn.f90
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
subroutine afc65b(cx,npts,fsample,nflip,a,ccfbest,dtbest)
|
||||
|
||||
! Find delta f, f1, f2 ==> a(1:3)
|
||||
|
||||
complex cx(npts)
|
||||
real a(5),deltaa(5)
|
||||
|
||||
a(1)=0.
|
||||
a(2)=0.
|
||||
a(3)=0.
|
||||
a(4)=0.
|
||||
deltaa(1)=2.0
|
||||
deltaa(2)=2.0
|
||||
deltaa(3)=2.0
|
||||
deltaa(4)=0.05
|
||||
nterms=3 !Maybe 2 is enough?
|
||||
|
||||
! Start the iteration
|
||||
chisqr=0.
|
||||
chisqr0=1.e6
|
||||
do iter=1,3 !One iteration is enough?
|
||||
do j=1,nterms
|
||||
chisq1=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
|
||||
fn=0.
|
||||
delta=deltaa(j)
|
||||
10 a(j)=a(j)+delta
|
||||
chisq2=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
|
||||
if(chisq2.eq.chisq1) go to 10
|
||||
if(chisq2.gt.chisq1) then
|
||||
delta=-delta !Reverse direction
|
||||
a(j)=a(j)+delta
|
||||
tmp=chisq1
|
||||
chisq1=chisq2
|
||||
chisq2=tmp
|
||||
endif
|
||||
20 fn=fn+1.0
|
||||
a(j)=a(j)+delta
|
||||
chisq3=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
|
||||
if(chisq3.lt.chisq2) then
|
||||
chisq1=chisq2
|
||||
chisq2=chisq3
|
||||
go to 20
|
||||
endif
|
||||
|
||||
! Find minimum of parabola defined by last three points
|
||||
delta=delta*(1./(1.+(chisq1-chisq2)/(chisq3-chisq2))+0.5)
|
||||
a(j)=a(j)-delta
|
||||
deltaa(j)=deltaa(j)*fn/3.
|
||||
enddo
|
||||
chisqr=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
|
||||
if(chisqr/chisqr0.gt.0.9999) go to 30
|
||||
chisqr0=chisqr
|
||||
enddo
|
||||
|
||||
30 ccfbest=ccfmax * (1378.125/fsample)**2
|
||||
dtbest=dtmax
|
||||
|
||||
return
|
||||
end subroutine afc65b
|
|
@ -0,0 +1,45 @@
|
|||
subroutine ccf2(ss,nz,nflip,ccfbest,lagpk)
|
||||
|
||||
parameter (LAGMAX=60)
|
||||
! parameter (LAGMAX=200)
|
||||
real ss(nz)
|
||||
real ccf(-LAGMAX:LAGMAX)
|
||||
integer npr(126)
|
||||
|
||||
! The JT65 pseudo-random sync pattern:
|
||||
data npr/ &
|
||||
1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, &
|
||||
0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, &
|
||||
0,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,0,1,1, &
|
||||
0,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,1, &
|
||||
1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1, &
|
||||
0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, &
|
||||
1,1,1,1,1,1/
|
||||
save
|
||||
|
||||
ccfbest=0.
|
||||
lag1=-LAGMAX
|
||||
lag2=LAGMAX
|
||||
do lag=lag1,lag2
|
||||
s0=0.
|
||||
s1=0.
|
||||
do i=1,126
|
||||
j=2*(8*i + 43) + lag
|
||||
if(j.ge.1 .and. j.le.nz-8) then
|
||||
x=ss(j)+ss(j+8) !Add two half-symbol contributions
|
||||
if(npr(i).eq.0) then
|
||||
s0=s0 + x
|
||||
else
|
||||
s1=s1 + x
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
ccf(lag)=nflip*(s1-s0)
|
||||
if(ccf(lag).gt.ccfbest) then
|
||||
ccfbest=ccf(lag)
|
||||
lagpk=lag
|
||||
endif
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine ccf2
|
|
@ -0,0 +1,117 @@
|
|||
subroutine ccf65(ss,nhsym,ssmax,sync1,dt1,flipk,syncshort,snr2,dt2)
|
||||
|
||||
parameter (NFFT=512,NH=NFFT/2)
|
||||
real ss(322) !Input: half-symbol normalized powers
|
||||
real s(NFFT) !CCF = ss*pr
|
||||
complex cs(0:NH) !Complex FT of s
|
||||
real s2(NFFT) !CCF = ss*pr2
|
||||
complex cs2(0:NH) !Complex FT of s2
|
||||
real pr(NFFT) !JT65 pseudo-random sync pattern
|
||||
complex cpr(0:NH) !Complex FT of pr
|
||||
real pr2(NFFT) !JT65 shorthand pattern
|
||||
complex cpr2(0:NH) !Complex FT of pr2
|
||||
real tmp1(322)
|
||||
real ccf(-11:54)
|
||||
logical first
|
||||
integer npr(126)
|
||||
data first/.true./
|
||||
equivalence (s,cs),(pr,cpr),(s2,cs2),(pr2,cpr2)
|
||||
save
|
||||
|
||||
! The JT65 pseudo-random sync pattern:
|
||||
data npr/ &
|
||||
1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, &
|
||||
0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, &
|
||||
0,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,0,1,1, &
|
||||
0,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,1, &
|
||||
1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1, &
|
||||
0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, &
|
||||
1,1,1,1,1,1/
|
||||
|
||||
if(first) then
|
||||
! Initialize pr, pr2; compute cpr, cpr2.
|
||||
fac=1.0/NFFT
|
||||
do i=1,NFFT
|
||||
pr(i)=0.
|
||||
pr2(i)=0.
|
||||
k=2*mod((i-1)/8,2)-1
|
||||
if(i.le.NH) pr2(i)=fac*k
|
||||
enddo
|
||||
do i=1,126
|
||||
j=2*i
|
||||
pr(j)=fac*(2*npr(i)-1)
|
||||
! Not sure why, but it works significantly better without the following line:
|
||||
! pr(j-1)=pr(j)
|
||||
enddo
|
||||
call four2a(cpr,NFFT,1,-1,0)
|
||||
call four2a(cpr2,NFFT,1,-1,0)
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
! Look for JT65 sync pattern and shorthand square-wave pattern.
|
||||
ccfbest=0.
|
||||
ccfbest2=0.
|
||||
do i=1,nhsym-1
|
||||
s(i)=min(ssmax,ss(i)+ss(i+1))
|
||||
! s(i)=ss(i)+ss(i+1)
|
||||
enddo
|
||||
|
||||
call pctile(s,nhsym-1,50,base)
|
||||
s(1:nhsym-1)=s(1:nhsym-1)-base
|
||||
s(nhsym:NFFT)=0.
|
||||
call four2a(cs,NFFT,1,-1,0) !Real-to-complex FFT
|
||||
do i=0,NH
|
||||
! cs2(i)=cs(i)*conjg(cpr2(i)) !Mult by complex FFT of pr2
|
||||
cs(i)=cs(i)*conjg(cpr(i)) !Mult by complex FFT of pr
|
||||
enddo
|
||||
call four2a(cs,NFFT,1,1,-1) !Complex-to-real inv-FFT
|
||||
! call four2a(cs2,NFFT,1,1,-1) !Complex-to-real inv-FFT
|
||||
|
||||
do lag=-11,54 !Check for best JT65 sync
|
||||
j=lag
|
||||
if(j.lt.1) j=j+NFFT
|
||||
ccf(lag)=s(j)
|
||||
! if(abs(ccf(lag)).gt.ccfbest) then
|
||||
if(ccf(lag).gt.ccfbest) then !No inverted sync for use at HF
|
||||
! ccfbest=abs(ccf(lag))
|
||||
ccfbest=ccf(lag)
|
||||
lagpk=lag
|
||||
flipk=1.0
|
||||
! if(ccf(lag).lt.0.0) flipk=-1.0
|
||||
endif
|
||||
enddo
|
||||
|
||||
! do lag=-11,54 !Check for best shorthand
|
||||
! ccf2=s2(lag+28)
|
||||
! if(ccf2.gt.ccfbest2) then
|
||||
! ccfbest2=ccf2
|
||||
! lagpk2=lag
|
||||
! endif
|
||||
! enddo
|
||||
|
||||
! Find rms level on baseline of "ccfblue", for normalization.
|
||||
sum=0.
|
||||
do lag=-11,54
|
||||
if(abs(lag-lagpk).gt.1) sum=sum + ccf(lag)
|
||||
enddo
|
||||
base=sum/50.0
|
||||
sq=0.
|
||||
do lag=-11,54
|
||||
if(abs(lag-lagpk).gt.1) sq=sq + (ccf(lag)-base)**2
|
||||
enddo
|
||||
rms=sqrt(sq/49.0)
|
||||
sync1=ccfbest/rms - 4.0
|
||||
dt1=lagpk*(2048.0/11025.0) - 2.5
|
||||
|
||||
! Find base level for normalizing snr2.
|
||||
do i=1,nhsym
|
||||
tmp1(i)=ss(i)
|
||||
enddo
|
||||
call pctile(tmp1,nhsym,40,base)
|
||||
snr2=0.398107*ccfbest2/base !### empirical
|
||||
syncshort=0.5*ccfbest2/rms - 4.0 !### better normalizer than rms?
|
||||
! dt2=(2.5 + lagpk2*(2048.0/11025.0))
|
||||
dt2=0.
|
||||
|
||||
return
|
||||
end subroutine ccf65
|
|
@ -0,0 +1,57 @@
|
|||
/* Include file to configure the RS codec for character symbols
|
||||
*
|
||||
* Copyright 2002, Phil Karn, KA9Q
|
||||
* May be used under the terms of the GNU General Public License (GPL)
|
||||
*/
|
||||
#define DTYPE unsigned char
|
||||
|
||||
/* Reed-Solomon codec control block */
|
||||
struct rs {
|
||||
int mm; /* Bits per symbol */
|
||||
int nn; /* Symbols per block (= (1<<mm)-1) */
|
||||
DTYPE *alpha_to; /* log lookup table */
|
||||
DTYPE *index_of; /* Antilog lookup table */
|
||||
DTYPE *genpoly; /* Generator polynomial */
|
||||
int nroots; /* Number of generator roots = number of parity symbols */
|
||||
int fcr; /* First consecutive root, index form */
|
||||
int prim; /* Primitive element, index form */
|
||||
int iprim; /* prim-th root of 1, index form */
|
||||
int pad; /* Padding bytes in shortened block */
|
||||
};
|
||||
|
||||
static inline int modnn(struct rs *rs,int x){
|
||||
while (x >= rs->nn) {
|
||||
x -= rs->nn;
|
||||
x = (x >> rs->mm) + (x & rs->nn);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
#define MODNN(x) modnn(rs,x)
|
||||
|
||||
#define MM (rs->mm)
|
||||
#define NN (rs->nn)
|
||||
#define ALPHA_TO (rs->alpha_to)
|
||||
#define INDEX_OF (rs->index_of)
|
||||
#define GENPOLY (rs->genpoly)
|
||||
#define NROOTS (rs->nroots)
|
||||
#define FCR (rs->fcr)
|
||||
#define PRIM (rs->prim)
|
||||
#define IPRIM (rs->iprim)
|
||||
#define PAD (rs->pad)
|
||||
#define A0 (NN)
|
||||
|
||||
#define ENCODE_RS encode_rs_char
|
||||
#define DECODE_RS decode_rs_char
|
||||
#define INIT_RS init_rs_char
|
||||
#define FREE_RS free_rs_char
|
||||
|
||||
void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
|
||||
int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras);
|
||||
void *INIT_RS(int symsize,int gfpoly,int fcr,
|
||||
int prim,int nroots,int pad);
|
||||
void FREE_RS(void *p);
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
subroutine chkhist(mrsym,nmax,ipk)
|
||||
|
||||
integer mrsym(63)
|
||||
integer hist(0:63)
|
||||
|
||||
hist=0
|
||||
do j=1,63
|
||||
i=mrsym(j)
|
||||
hist(i)=hist(i)+1
|
||||
enddo
|
||||
|
||||
nmax=0
|
||||
do i=0,63
|
||||
if(hist(i).gt.nmax) then
|
||||
nmax=hist(i)
|
||||
ipk=i+1
|
||||
endif
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine chkhist
|
|
@ -0,0 +1,5 @@
|
|||
parameter (NTMAX=120)
|
||||
parameter (NMAX=NTMAX*12000) !Total sample intervals per 30 minutes
|
||||
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate
|
||||
parameter (NSMAX=6827) !Max length of saved spectra
|
||||
parameter (MAXFFT3=16384)
|
176
lib/decode24.f90
176
lib/decode24.f90
|
@ -1,176 +0,0 @@
|
|||
subroutine decode24(dat,npts,dtx,dfx,flip,mode,mode4,decoded,ncount, &
|
||||
deepbest,qbest,submode)
|
||||
|
||||
! Decodes JT65 data, assuming that DT and DF have already been determined.
|
||||
|
||||
parameter (MAXAVE=120)
|
||||
real dat(npts) !Raw data
|
||||
character decoded*22,deepmsg*22,deepbest*22
|
||||
character*12 mycall,hiscall
|
||||
character*6 hisgrid
|
||||
character*72 c72
|
||||
character submode*1
|
||||
real*8 dt,df,phi,f0,dphi,twopi,phi1,dphi1
|
||||
complex*16 cz,cz1,c0,c1
|
||||
integer*1 symbol(207)
|
||||
real*4 rsymbol(207,7)
|
||||
real*4 sym(207)
|
||||
integer nsum(7)
|
||||
integer*1 data1(13) !Decoded data (8-bit bytes)
|
||||
integer data4a(9) !Decoded data (8-bit bytes)
|
||||
integer data4(12) !Decoded data (6-bit bytes)
|
||||
integer amp,delta
|
||||
integer mettab(0:255,0:1) !Metric table
|
||||
integer nch(7)
|
||||
integer npr2(207)
|
||||
common/ave/ppsave(207,7,MAXAVE),nflag(MAXAVE),nsave,iseg(MAXAVE)
|
||||
data mode0/-999/
|
||||
data nsum/7*0/,rsymbol/1449*0.0/
|
||||
data npr2/ &
|
||||
0,0,0,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,0,1,1,0,0, &
|
||||
0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,0,1,1,1,1,1,0,1,0,0,0, &
|
||||
1,0,0,1,0,0,1,1,1,1,1,0,0,0,1,0,1,0,0,0,1,1,1,1,0,1,1,0,0,1, &
|
||||
0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1,0,1,0,1, &
|
||||
0,1,1,1,0,0,1,0,1,1,0,1,1,1,1,0,0,0,0,1,1,0,1,1,0,0,0,1,1,1, &
|
||||
0,1,1,1,0,1,1,1,0,0,1,0,0,0,1,1,0,1,1,0,0,1,0,0,0,1,1,1,1,1, &
|
||||
1,0,0,1,1,0,0,0,0,1,1,0,0,0,1,0,1,1,0,1,1,1,1,0,1,0,1/
|
||||
|
||||
data nch/1,2,4,9,18,36,72/
|
||||
save mettab,mode0,nsum,rsymbol
|
||||
|
||||
if(mode.ne.mode0) call getmet24(mode,mettab)
|
||||
mode0=mode
|
||||
twopi=8*atan(1.d0)
|
||||
dt=2.d0/11025 !Sample interval (2x downsampled data)
|
||||
df=11025.d0/2520.d0
|
||||
nsym=206
|
||||
amp=15
|
||||
istart=nint(dtx/dt) !Start index for synced FFTs
|
||||
if(istart.lt.0) istart=0
|
||||
nchips=0
|
||||
ich=0
|
||||
qbest=0.
|
||||
deepmsg=' '
|
||||
ichbest=-1
|
||||
|
||||
! Should amp be adjusted according to signal strength?
|
||||
|
||||
! Compute soft symbols using differential BPSK demodulation
|
||||
c0=0. !### C0=amp ???
|
||||
k=istart
|
||||
phi=0.d0
|
||||
phi1=0.d0
|
||||
|
||||
40 ich=ich+1
|
||||
nchips=nch(ich)
|
||||
nspchip=1260/nchips
|
||||
k=istart
|
||||
phi=0.d0
|
||||
phi1=0.d0
|
||||
fac2=1.e-8 * sqrt(float(mode4))
|
||||
do j=1,nsym+1
|
||||
if(flip.gt.0.0) then
|
||||
f0=1270.46 + dfx + (npr2(j)-1.5)*mode4*df
|
||||
f1=1270.46 + dfx + (2+npr2(j)-1.5)*mode4*df
|
||||
else
|
||||
f0=1270.46 + dfx + (1-npr2(j)-1.5)*mode4*df
|
||||
f1=1270.46 + dfx + (3-npr2(j)-1.5)*mode4*df
|
||||
endif
|
||||
dphi=twopi*dt*f0
|
||||
dphi1=twopi*dt*f1
|
||||
sq0=0.
|
||||
sq1=0.
|
||||
do nc=1,nchips
|
||||
phi=0.d0
|
||||
phi1=0.d0
|
||||
c0=0.
|
||||
c1=0.
|
||||
do i=1,nspchip
|
||||
k=k+1
|
||||
phi=phi+dphi
|
||||
phi1=phi1+dphi1
|
||||
cz=dcmplx(cos(phi),-sin(phi))
|
||||
cz1=dcmplx(cos(phi1),-sin(phi1))
|
||||
if(k.le.npts) then
|
||||
c0=c0 + dat(k)*cz
|
||||
c1=c1 + dat(k)*cz1
|
||||
endif
|
||||
enddo
|
||||
sq0=sq0 + real(c0)**2 + aimag(c0)**2
|
||||
sq1=sq1 + real(c1)**2 + aimag(c1)**2
|
||||
enddo
|
||||
sq0=fac2*sq0
|
||||
sq1=fac2*sq1
|
||||
rsym=amp*(sq1-sq0)
|
||||
r=rsym+128.
|
||||
if(r.gt.255.0) r=255.0
|
||||
if(r.lt.0.0) r=0.0
|
||||
i4=nint(r)
|
||||
if(i4.gt.127) i4=i4-256
|
||||
if(j.ge.1) then
|
||||
symbol(j)=i4
|
||||
! rsymbol(j,ich)=rsymbol(j,ich) + rsym
|
||||
rsymbol(j,ich)=rsym
|
||||
sym(j)=rsym
|
||||
endif
|
||||
enddo
|
||||
|
||||
!### The following does simple message averaging:
|
||||
! nsum(ich)=nsum(ich)+1
|
||||
! do j=1,207
|
||||
! sym(j)=rsymbol(j,ich)/nsum(ich)
|
||||
! r=sym(j) + 128.
|
||||
! if(r.gt.255.0) r=255.0
|
||||
! if(r.lt.0.0) r=0.0
|
||||
! i4=nint(r)
|
||||
! if(i4.gt.127) i4=i4-256
|
||||
! symbol(j)=i4
|
||||
! enddo
|
||||
!###
|
||||
|
||||
call extract4(sym,nadd,ncount,decoded) !Do the KV decode
|
||||
|
||||
qual=0. !Now try deep search
|
||||
neme=1
|
||||
mycall='VK7MO'
|
||||
hiscall='W5LUA'
|
||||
hisgrid='EM13'
|
||||
call deep24(sym(2),neme,flip,mycall,hiscall,hisgrid,deepmsg,qual)
|
||||
if(qual.gt.qbest) then
|
||||
qbest=qual
|
||||
deepbest=deepmsg
|
||||
ichbest=ich
|
||||
endif
|
||||
|
||||
if(ncount.ge.0) go to 100
|
||||
if(mode.eq.7 .and. nchips.lt.mode4) go to 40
|
||||
|
||||
100 continue
|
||||
!100 do i=1,9
|
||||
! i4=data1(i)
|
||||
! if(i4.lt.0) i4=i4+256
|
||||
! data4a(i)=i4
|
||||
! enddo
|
||||
! write(c72,1100) (data4a(i),i=1,9)
|
||||
!1100 format(9b8.8)
|
||||
! read(c72,1102) data4
|
||||
!1102 format(12b6)
|
||||
|
||||
! decoded=' '
|
||||
! submode=' '
|
||||
|
||||
if(ncount.lt.0) then
|
||||
decoded=deepbest
|
||||
submode=char(ichar('A')+ichbest-1)
|
||||
qual=qbest
|
||||
endif
|
||||
! if(decoded(1:6).eq.'000AAA') then
|
||||
! decoded='***WRONG MODE?***'
|
||||
! ncount=-1
|
||||
! endif
|
||||
|
||||
! Save symbol spectra for possible decoding of average.
|
||||
ppsave(1:207,1:7,nsave)=rsymbol(1:207,1:7)
|
||||
|
||||
return
|
||||
end subroutine decode24
|
|
@ -0,0 +1,95 @@
|
|||
subroutine decode65a(dd,npts,newdat,f0,nflip,mode65,sync2,a,dt, &
|
||||
nbmkv,nhist,decoded)
|
||||
|
||||
! Apply AFC corrections to a candidate JT65 signal, then decode it.
|
||||
|
||||
parameter (NMAX=60*12000) !Samples per 60 s
|
||||
real*4 dd(NMAX) !92 MB: raw data from Linrad timf2
|
||||
complex cx(NMAX/8) !Data at 1378.125 samples/s
|
||||
complex c5x(NMAX/32) !Data at 344.53125 Hz
|
||||
complex c5a(512)
|
||||
real s2(66,126)
|
||||
real a(5)
|
||||
logical first
|
||||
character decoded*22
|
||||
data first/.true./,jjjmin/1000/,jjjmax/-1000/
|
||||
data nhz0/-9999999/
|
||||
save
|
||||
|
||||
! Mix sync tone to baseband, low-pass filter, downsample to 1378.125 Hz
|
||||
dt00=dt
|
||||
call timer('filbig ',0)
|
||||
call filbig(dd,npts,f0,newdat,cx,n5,sq0)
|
||||
call timer('filbig ',1)
|
||||
|
||||
! NB: cx has sample rate 12000*77125/672000 = 1378.125 Hz
|
||||
|
||||
! Find best DF, f1, f2, and DT. Start by downsampling to 344.53125 Hz
|
||||
call timer('fil6521 ',0)
|
||||
! Add some zeros at start of c5 arrays -- empirical fix for negative DT's
|
||||
nadd=1089
|
||||
c5x(:nadd)=0.
|
||||
call fil6521(cx,n5,c5x(nadd+1),n6)
|
||||
n6=n6+nadd
|
||||
call timer('fil6521 ',1)
|
||||
|
||||
fsample=1378.125/4.
|
||||
a(5)=dt00
|
||||
i0=nint((a(5)+0.5)*fsample) - 2 + nadd
|
||||
if(i0.lt.1) then
|
||||
! write(23,*) 'i0 too small in decode1a:',i0,f0,a(5),fsample,nadd
|
||||
! flush(23)
|
||||
i0=1
|
||||
endif
|
||||
nz=n6+1-i0
|
||||
|
||||
! We're looking only at sync tone here... so why not downsample by another
|
||||
! factor of 1/8, say? Should be a significant execution speed-up.
|
||||
call timer('afc65b ',0)
|
||||
! Best fit for DF, f1, and f2
|
||||
call afc65b(c5x(i0),nz,fsample,nflip,a,ccfbest,dtbest)
|
||||
call timer('afc65b ',1)
|
||||
|
||||
sync2=3.7e-4*ccfbest/sq0 !Constant is empirical
|
||||
|
||||
! Apply AFC corrections to the time-domain signal
|
||||
! Now we are back to using the 1378.125 Hz sample rate, enough to
|
||||
! accommodate the full JT65C bandwidth.
|
||||
|
||||
call timer('twkfreq ',0)
|
||||
call twkfreq65(cx,n5,a)
|
||||
call timer('twkfreq ',1)
|
||||
|
||||
! Compute spectrum for each half symbol.
|
||||
! Adding or subtracting a small number (e.g., 5) to j may make it decode.\
|
||||
! NB: might want to try computing full-symbol spectra (nfft=512, even for
|
||||
! submodes B and C).
|
||||
|
||||
nsym=126
|
||||
nfft=512
|
||||
j=(dt00+dtbest+2.685)*1378.125
|
||||
if(j.lt.0) j=0
|
||||
|
||||
call timer('sh_ffts ',0)
|
||||
do k=1,nsym
|
||||
do i=1,nfft
|
||||
j=j+1
|
||||
c5a(i)=cx(j)
|
||||
enddo
|
||||
call four2a(c5a,nfft,1,1,1)
|
||||
do i=1,66
|
||||
jj=i
|
||||
if(mode65.eq.2) jj=2*i-1
|
||||
if(mode65.eq.4) jj=4*i-3
|
||||
s2(i,k)=real(c5a(jj))**2 + aimag(c5a(jj))**2
|
||||
enddo
|
||||
enddo
|
||||
call timer('sh_ffts ',1)
|
||||
|
||||
call timer('dec65b ',0)
|
||||
call decode65b(s2,nflip,mode65,nbmkv,nhist,decoded)
|
||||
dt=dt00 + dtbest + 1.7
|
||||
call timer('dec65b ',1)
|
||||
|
||||
return
|
||||
end subroutine decode65a
|
|
@ -0,0 +1,36 @@
|
|||
subroutine decode65b(s2,nflip,mode65,nbmkv,nhist,decoded)
|
||||
|
||||
real s2(66,126)
|
||||
real s3(64,63)
|
||||
logical first,ltext
|
||||
character decoded*22
|
||||
common/prcom/pr(126),mdat(126),mref(126,2),mdat2(126),mref2(126,2)
|
||||
data first/.true./
|
||||
save
|
||||
|
||||
if(first) call setup65
|
||||
first=.false.
|
||||
|
||||
do j=1,63
|
||||
k=mdat(j) !Points to data symbol
|
||||
if(nflip.lt.0) k=mdat2(j)
|
||||
do i=1,64
|
||||
s3(i,j)=s2(i+2,k)
|
||||
enddo
|
||||
k=mdat2(j) !Points to data symbol
|
||||
if(nflip.lt.0) k=mdat(j)
|
||||
enddo
|
||||
|
||||
nadd=mode65
|
||||
call extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv) !Extract the message
|
||||
! Suppress "birdie messages" and other garbage decodes:
|
||||
if(decoded(1:7).eq.'000AAA ') ncount=-1
|
||||
if(decoded(1:7).eq.'0L6MWK ') ncount=-1
|
||||
if(nflip.lt.0 .and. ltext) ncount=-1
|
||||
if(ncount.lt.0) then
|
||||
nbmkv=0
|
||||
decoded=' '
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine decode65b
|
|
@ -16,7 +16,7 @@ subroutine decode9(i1SoftSymbols,limit,nlim,msg)
|
|||
logical first
|
||||
integer*4 mettab(0:255,0:1)
|
||||
data first/.true./
|
||||
data xx0/ &
|
||||
data xx0/ & !Metric table
|
||||
1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, &
|
||||
1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, &
|
||||
1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, &
|
||||
|
@ -53,9 +53,8 @@ subroutine decode9(i1SoftSymbols,limit,nlim,msg)
|
|||
|
||||
if(first) then
|
||||
! Get the metric table
|
||||
! bias=0.37 !To be optimized, in decoder program
|
||||
bias=0.5
|
||||
scale=10 ! ... ditto ...
|
||||
scale=10
|
||||
do i=0,255
|
||||
mettab(i,0)=nint(scale*(xx0(i)-bias))
|
||||
if(i.ge.1) mettab(256-i,1)=mettab(i,0)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#define NULL ((void *)0)
|
||||
//#define NULL ((void *)0)
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#ifdef FIXED
|
||||
|
|
116
lib/decoder.f90
116
lib/decoder.f90
|
@ -1,23 +1,21 @@
|
|||
subroutine decoder(ss,c0,nstandalone)
|
||||
subroutine decoder(ss,id2)
|
||||
|
||||
! Decoder for JT9.
|
||||
|
||||
parameter (NTMAX=120)
|
||||
parameter (NMAX=NTMAX*12000) !Total sample intervals per 30 minutes
|
||||
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate
|
||||
parameter (NSMAX=1365) !Max length of saved spectra
|
||||
include 'constants.f90'
|
||||
real ss(184,NSMAX)
|
||||
character*22 msg
|
||||
character*80 fmt
|
||||
character*20 datetime
|
||||
real*4 ccfred(NSMAX)
|
||||
real*4 red2(NSMAX)
|
||||
logical ccfok(NSMAX)
|
||||
logical done(NSMAX)
|
||||
logical done65
|
||||
integer*2 id2(NTMAX*12000)
|
||||
real*4 dd(NTMAX*12000)
|
||||
integer*1 i1SoftSymbols(207)
|
||||
complex c0(NDMAX)
|
||||
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol, &
|
||||
kin,nzhsym,nsave,nagain,ndepth,nrxlog,nfsample,datetime
|
||||
kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,datetime
|
||||
common/tracer/limtrace,lu
|
||||
save
|
||||
|
||||
|
@ -27,48 +25,40 @@ subroutine decoder(ss,c0,nstandalone)
|
|||
ndecodes0=0
|
||||
ndecodes1=0
|
||||
|
||||
call timer('decoder ',0)
|
||||
|
||||
open(13,file='decoded.txt',status='unknown')
|
||||
ntrMinutes=ntrperiod/60
|
||||
newdat=1
|
||||
open(22,file='kvasd.dat',access='direct',recl=1024,status='unknown')
|
||||
|
||||
npts65=52*12000
|
||||
ntol65=20
|
||||
done65=.false.
|
||||
if(nmode.ge.65 .and. ntxmode.eq.65) then
|
||||
if(newdat.ne.0) dd(1:npts65)=id2(1:npts65)
|
||||
call jt65a(dd,npts65,newdat,nutc,nfa,nfqso,ntol65,nagain,ndecoded)
|
||||
done65=.true.
|
||||
endif
|
||||
|
||||
if(nmode.eq.65) go to 800
|
||||
|
||||
nsynced=0
|
||||
ndecoded=0
|
||||
nsps=0
|
||||
|
||||
if(ntrMinutes.eq.1) then
|
||||
nsps=6912
|
||||
df3=1500.0/2048.0
|
||||
fmt='(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22)'
|
||||
else if(ntrMinutes.eq.2) then
|
||||
nsps=15360
|
||||
df3=1500.0/2048.0
|
||||
fmt='(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22)'
|
||||
else if(ntrMinutes.eq.5) then
|
||||
nsps=40960
|
||||
df3=1500.0/6144.0
|
||||
fmt='(i4.4,i4,i5,f6.1,f8.1,i4,3x,a22)'
|
||||
else if(ntrMinutes.eq.10) then
|
||||
nsps=82944
|
||||
df3=1500.0/12288.0
|
||||
fmt='(i4.4,i4,i5,f6.1,f8.2,i4,3x,a22)'
|
||||
else if(ntrMinutes.eq.30) then
|
||||
nsps=252000
|
||||
df3=1500.0/32768.0
|
||||
fmt='(i4.4,i4,i5,f6.1,f8.2,i4,3x,a22)'
|
||||
endif
|
||||
if(nsps.eq.0) stop 'Error: bad TRperiod' !Better: return an error code###
|
||||
nsps=6912 !Params for JT9-1
|
||||
df3=1500.0/2048.0
|
||||
|
||||
tstep=0.5*nsps/12000.0 !Half-symbol step (seconds)
|
||||
done=.false.
|
||||
|
||||
ia=max(1,nint((nfa-1000)/df3))
|
||||
ib=min(NSMAX,nint((nfb-1000)/df3))
|
||||
nf0=0
|
||||
ia=max(1,nint((nfa-nf0)/df3))
|
||||
ib=min(NSMAX,nint((nfb-nf0)/df3))
|
||||
lag1=-(2.5/tstep + 0.9999)
|
||||
lag2=5.0/tstep + 0.9999
|
||||
call timer('sync9 ',0)
|
||||
call sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipk)
|
||||
call timer('sync9 ',1)
|
||||
if(newdat.ne.0) then
|
||||
call timer('sync9 ',0)
|
||||
call sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipk)
|
||||
call timer('sync9 ',1)
|
||||
endif
|
||||
|
||||
nsps8=nsps/8
|
||||
df8=1500.0/nsps8
|
||||
|
@ -94,24 +84,22 @@ subroutine decoder(ss,c0,nstandalone)
|
|||
ccfok(ia:ib)=.true.
|
||||
nfa1=nfqso-ntol
|
||||
nfb1=nfqso+ntol
|
||||
ia=max(1,nint((nfa1-1000)/df3))
|
||||
ib=min(NSMAX,nint((nfb1-1000)/df3))
|
||||
ia=max(1,nint((nfa1-nf0)/df3))
|
||||
ib=min(NSMAX,nint((nfb1-nf0)/df3))
|
||||
ia1=ia
|
||||
ib1=ib
|
||||
else
|
||||
nfa1=nfa
|
||||
nfb1=nfb
|
||||
ia=max(1,nint((nfa1-1000)/df3))
|
||||
ib=min(NSMAX,nint((nfb1-1000)/df3))
|
||||
ia=max(1,nint((nfa1-nf0)/df3))
|
||||
ib=min(NSMAX,nint((nfb1-nf0)/df3))
|
||||
do i=ia,ib
|
||||
ccfok(i)=ccfred(i).gt.ccflim .and. red2(i).gt.red2lim
|
||||
enddo
|
||||
ccfok(ia1:ib1)=.false.
|
||||
endif
|
||||
|
||||
nRxLog=0
|
||||
fgood=0.
|
||||
|
||||
do i=ia,ib
|
||||
f=(i-1)*df3
|
||||
if(done(i) .or. (.not.ccfok(i)) .or. (ccfred(i).lt.ccflim-1.0)) cycle
|
||||
|
@ -122,9 +110,9 @@ subroutine decoder(ss,c0,nstandalone)
|
|||
if(nqd.eq.1) nfreqs1=nfreqs1+1
|
||||
|
||||
call timer('softsym ',0)
|
||||
fpk=1000.0 + df3*(i-1)
|
||||
call softsym(c0,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,freq, &
|
||||
drift,schk,i1SoftSymbols)
|
||||
fpk=nf0 + df3*(i-1)
|
||||
call softsym(id2,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt, &
|
||||
freq,drift,schk,i1SoftSymbols)
|
||||
call timer('softsym ',1)
|
||||
|
||||
if(schk.ge.schklim) then
|
||||
|
@ -140,16 +128,14 @@ subroutine decoder(ss,c0,nstandalone)
|
|||
nsnr=nint(snrdb)
|
||||
ndrift=nint(drift/df3)
|
||||
|
||||
! write(38,3002) nutc,nqd,nsnr,i,freq,ndrift,ccfred(i), &
|
||||
! red2(i),schk,nlim,msg
|
||||
!3002 format(i4.4,i2,i4,i5,f7.1,i4,f5.1,f6.1,f5.1,i8,1x,a22)
|
||||
|
||||
if(msg.ne.' ') then
|
||||
if(nqd.eq.0) ndecodes0=ndecodes0+1
|
||||
if(nqd.eq.1) ndecodes1=ndecodes1+1
|
||||
|
||||
write(*,fmt) nutc,nsync,nsnr,xdt,freq,ndrift,msg
|
||||
write(13,fmt) nutc,nsync,nsnr,xdt,freq,ndrift,msg
|
||||
write(*,1000) nutc,nsnr,xdt,nint(freq),msg
|
||||
1000 format(i4.4,i4,f5.1,i5,1x,'@',1x,a22)
|
||||
write(13,1002) nutc,nsync,nsnr,xdt,freq,ndrift,msg
|
||||
1002 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22,' JT9')
|
||||
|
||||
iaa=max(1,i-1)
|
||||
ibb=min(NSMAX,i+22)
|
||||
|
@ -160,8 +146,6 @@ subroutine decoder(ss,c0,nstandalone)
|
|||
done(iaa:ibb)=.true.
|
||||
call flush(6)
|
||||
endif
|
||||
else
|
||||
! write(38,3002) nutc,nqd,-99,i,freq,ndrift,ccfred(i),red2(i),schk,0
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
@ -169,21 +153,17 @@ subroutine decoder(ss,c0,nstandalone)
|
|||
if(nagain.ne.0) exit
|
||||
enddo
|
||||
|
||||
write(*,1010) nsynced,ndecoded
|
||||
if(nmode.ge.65 .and. (.not.done65)) then
|
||||
if(newdat.ne.0) dd(1:npts65)=id2(1:npts65)
|
||||
call jt65a(dd,npts65,newdat,nutc,nfa,nfqso,ntol65,nagain,ndecoded)
|
||||
endif
|
||||
|
||||
!### JT65 is not yet producing info for nsynced, ndecoded.
|
||||
800 write(*,1010) nsynced,ndecoded
|
||||
1010 format('<DecodeFinished>',2i4)
|
||||
call flush(6)
|
||||
close(13)
|
||||
! call flush(14)
|
||||
|
||||
call timer('decoder ',1)
|
||||
if(nstandalone.eq.0) call timer('decoder ',101)
|
||||
|
||||
call system_clock(iclock,iclock_rate,iclock_max)
|
||||
! write(39,3001) nutc,nfreqs1,nfreqs0,ndecodes1,ndecodes0, &
|
||||
! float(iclock-iclock0)/iclock_rate
|
||||
!3001 format(5i8,f10.3)
|
||||
! call flush(38)
|
||||
! call flush(39)
|
||||
close(22)
|
||||
|
||||
return
|
||||
end subroutine decoder
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
subroutine demod64a(s3,nadd,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
|
||||
|
||||
! Demodulate the 64-bin spectra for each of 63 symbols in a frame.
|
||||
|
||||
! Parameters
|
||||
! nadd number of spectra already summed
|
||||
! mrsym most reliable symbol value
|
||||
! mr2sym second most likely symbol value
|
||||
! mrprob probability that mrsym was the transmitted value
|
||||
! mr2prob probability that mr2sym was the transmitted value
|
||||
|
||||
implicit real*8 (a-h,o-z)
|
||||
real*4 s3(64,63)
|
||||
real*8 fs(64)
|
||||
integer mrsym(63),mrprob(63),mr2sym(63),mr2prob(63)
|
||||
! common/mrscom/ mrs(63),mrs2(63)
|
||||
|
||||
if(nadd.eq.-999) return
|
||||
afac=1.1 * float(nadd)**0.64
|
||||
scale=255.999
|
||||
|
||||
! Compute average spectral value
|
||||
sum=0.
|
||||
do j=1,63
|
||||
do i=1,64
|
||||
sum=sum+s3(i,j)
|
||||
enddo
|
||||
enddo
|
||||
ave=sum/(64.*63.)
|
||||
i1=1 !Silence warning
|
||||
i2=1
|
||||
|
||||
! Compute probabilities for most reliable symbol values
|
||||
do j=1,63
|
||||
s1=-1.e30
|
||||
fsum=0.
|
||||
do i=1,64
|
||||
x=min(afac*s3(i,j)/ave,50.d0)
|
||||
fs(i)=exp(x)
|
||||
fsum=fsum+fs(i)
|
||||
if(s3(i,j).gt.s1) then
|
||||
s1=s3(i,j)
|
||||
i1=i !Most reliable
|
||||
endif
|
||||
enddo
|
||||
|
||||
s2=-1.e30
|
||||
do i=1,64
|
||||
if(i.ne.i1 .and. s3(i,j).gt.s2) then
|
||||
s2=s3(i,j)
|
||||
i2=i !Second most reliable
|
||||
endif
|
||||
enddo
|
||||
p1=fs(i1)/fsum !Normalized probabilities
|
||||
p2=fs(i2)/fsum
|
||||
mrsym(j)=i1-1
|
||||
mr2sym(j)=i2-1
|
||||
mrprob(j)=scale*p1
|
||||
mr2prob(j)=scale*p2
|
||||
! mrs(j)=i1
|
||||
! mrs2(j)=i2
|
||||
enddo
|
||||
|
||||
sum=0.
|
||||
nlow=0
|
||||
do j=1,63
|
||||
sum=sum+mrprob(j)
|
||||
if(mrprob(j).le.5) nlow=nlow+1
|
||||
enddo
|
||||
ntest=sum/63
|
||||
|
||||
return
|
||||
end subroutine demod64a
|
|
@ -1,58 +1,60 @@
|
|||
subroutine downsam9(c0,npts8,nsps8,newdat,nspsd,fpk,c2,nz2)
|
||||
subroutine downsam9(id2,npts8,nsps8,newdat,nspsd,fpk,c2,nz2)
|
||||
|
||||
!Downsample to nspsd samples per symbol, info centered at fpk
|
||||
!Downsample from id2() into C2() so as to yield nspsd samples per symbol,
|
||||
!mixing from fpk down to zero frequency.
|
||||
|
||||
parameter (NMAX=128*31500)
|
||||
complex c0(0:npts8-1)
|
||||
complex c1(0:NMAX-1)
|
||||
include 'constants.f90'
|
||||
parameter (NMAX1=1024*1920)
|
||||
integer*2 id2(0:8*npts8-1)
|
||||
real*4 x1(0:NMAX1-1)
|
||||
complex c1(0:NMAX1/2)
|
||||
complex c2(0:4096-1)
|
||||
real s(1000)
|
||||
real s(5000)
|
||||
equivalence (c1,x1)
|
||||
save
|
||||
|
||||
nfft1=128*nsps8 !Forward FFT length
|
||||
nh1=nfft1/2
|
||||
df1=1500.0/nfft1
|
||||
nfft1=1024*nsps8 !Forward FFT length
|
||||
df1=12000.0/nfft1
|
||||
npts=8*npts8
|
||||
|
||||
if(newdat.eq.1) then
|
||||
fac=1.e-4
|
||||
do i=0,npts8-1,2
|
||||
c1(i)=fac*conjg(c0(i))
|
||||
c1(i+1)=-fac*conjg(c0(i+1))
|
||||
fac=6.963e-6 !Why this weird constant?
|
||||
do i=0,npts-1
|
||||
x1(i)=fac*id2(i)
|
||||
enddo
|
||||
c1(npts8:)=0. !Zero the rest of c1
|
||||
call four2a(c1,nfft1,1,-1,1) !Forward FFT
|
||||
|
||||
x1(npts:nfft1-1)=0. !Zero the rest of x1
|
||||
call four2a(c1,nfft1,1,-1,0) !Forward FFT, r2c
|
||||
|
||||
nadd=1.0/df1
|
||||
j=250/df1
|
||||
s=0.
|
||||
do i=1,1000
|
||||
do i=1,5000
|
||||
j=(i-1)/df1
|
||||
do n=1,nadd
|
||||
j=j+1
|
||||
s(i)=s(i)+real(c1(j))**2 + aimag(c1(j))**2
|
||||
enddo
|
||||
! write(37,3001) i+1000,s(i),db(s(i)),nadd
|
||||
!3001 format(i5,2f12.3,i8)
|
||||
enddo
|
||||
call pctile(s,1000,40,avenoise)
|
||||
endif
|
||||
|
||||
ndown=nsps8/16 !Downsample factor
|
||||
ndown=8*nsps8/nspsd !Downsample factor
|
||||
nfft2=nfft1/ndown !Backward FFT length
|
||||
nh2=nfft2/2
|
||||
|
||||
fshift=fpk-1500.0
|
||||
i0=nh1 + fshift/df1
|
||||
nf=nint(fpk)
|
||||
i0=fpk/df1
|
||||
|
||||
nw=100
|
||||
ia=max(1,nf-nw)
|
||||
ib=min(5000,nf+nw)
|
||||
call pctile(s(ia),ib-ia+1,40,avenoise)
|
||||
|
||||
fac=sqrt(1.0/avenoise)
|
||||
do i=0,nfft2-1
|
||||
j=i0+i
|
||||
if(i.gt.nh2) j=j-nfft2
|
||||
c2(i)=fac*c1(j)
|
||||
enddo
|
||||
|
||||
call four2a(c2,nfft2,1,1,1) !Backward FFT
|
||||
|
||||
nspsd=nsps8/ndown
|
||||
nz2=npts8/ndown
|
||||
call four2a(c2,nfft2,1,1,1) !FFT back to time domain
|
||||
nz2=8*npts8/ndown
|
||||
|
||||
return
|
||||
end subroutine downsam9
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
subroutine extract(s3,nadd,ncount,nhist,decoded,ltext,nbmkv)
|
||||
|
||||
real s3(64,63)
|
||||
character decoded*22
|
||||
integer era(51),dat4(12),indx(64)
|
||||
integer mrsym(63),mr2sym(63),mrprob(63),mr2prob(63)
|
||||
logical nokv,ltext
|
||||
data nokv/.false./,nsec1/0/
|
||||
save
|
||||
|
||||
nbmkv=0
|
||||
nfail=0
|
||||
1 continue
|
||||
call demod64a(s3,nadd,mrsym,mrprob,mr2sym,mr2prob,ntest,nlow)
|
||||
if(ntest.lt.50 .or. nlow.gt.20) then
|
||||
ncount=-999 !Flag bad data
|
||||
go to 900
|
||||
endif
|
||||
call chkhist(mrsym,nhist,ipk)
|
||||
|
||||
if(nhist.ge.20) then
|
||||
nfail=nfail+1
|
||||
call pctile(s3,4032,50,base) ! ### or, use ave from demod64a
|
||||
do j=1,63
|
||||
s3(ipk,j)=base
|
||||
enddo
|
||||
if(nfail.gt.30) then
|
||||
decoded=' '
|
||||
ncount=-1
|
||||
go to 900
|
||||
endif
|
||||
go to 1
|
||||
endif
|
||||
|
||||
call graycode65(mrsym,63,-1)
|
||||
call interleave63(mrsym,-1)
|
||||
call interleave63(mrprob,-1)
|
||||
|
||||
! Decode using Berlekamp-Massey algorithm
|
||||
nemax=30 !Max BM erasures
|
||||
call indexx(63,mrprob,indx)
|
||||
do i=1,nemax
|
||||
j=indx(i)
|
||||
if(mrprob(j).gt.120) then
|
||||
ne2=i-1
|
||||
go to 2
|
||||
endif
|
||||
era(i)=j-1
|
||||
enddo
|
||||
ne2=nemax
|
||||
2 decoded=' '
|
||||
do nerase=0,ne2,2
|
||||
call rs_decode(mrsym,era,nerase,dat4,ncount)
|
||||
if(ncount.ge.0) then
|
||||
call unpackmsg(dat4,decoded)
|
||||
if(iand(dat4(10),8).ne.0) ltext=.true.
|
||||
nbmkv=1
|
||||
go to 900
|
||||
endif
|
||||
enddo
|
||||
|
||||
! Berlekamp-Massey algorithm failed, try Koetter-Vardy
|
||||
|
||||
if(nokv) go to 900
|
||||
|
||||
maxe=8 !Max KV errors in 12 most reliable symbols
|
||||
xlambda=10.0
|
||||
call graycode65(mr2sym,63,-1)
|
||||
call interleave63(mr2sym,-1)
|
||||
call interleave63(mr2prob,-1)
|
||||
|
||||
nsec1=nsec1+1
|
||||
write(22,rec=1) nsec1,xlambda,maxe,200,mrsym,mrprob,mr2sym,mr2prob
|
||||
call flush(22)
|
||||
call timer('kvasd ',0)
|
||||
#ifdef UNIX
|
||||
iret=system('./kvasd -q > dev_null')
|
||||
#else
|
||||
iret=system('kvasd -q > dev_null')
|
||||
#endif
|
||||
call timer('kvasd ',1)
|
||||
if(iret.ne.0) then
|
||||
if(.not.nokv) write(*,1000)
|
||||
1000 format('Error in KV decoder, or no KV decoder present.')
|
||||
nokv=.true.
|
||||
go to 900
|
||||
endif
|
||||
|
||||
read(22,rec=2,err=900) nsec2,ncount,dat4
|
||||
j=nsec2 !Silence compiler warning
|
||||
decoded=' '
|
||||
ltext=.false.
|
||||
if(ncount.ge.0) then
|
||||
call unpackmsg(dat4,decoded) !Unpack the user message
|
||||
if(iand(dat4(10),8).ne.0) ltext=.true.
|
||||
nbmkv=2
|
||||
endif
|
||||
|
||||
900 continue
|
||||
|
||||
return
|
||||
end subroutine extract
|
|
@ -0,0 +1,68 @@
|
|||
real function fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
|
||||
|
||||
parameter (NMAX=60*12000) !Samples per 60 s
|
||||
complex cx(npts)
|
||||
real a(5)
|
||||
complex w,wstep,z
|
||||
real ss(3000)
|
||||
complex csx(0:NMAX/8)
|
||||
data twopi/6.283185307/a1,a2,a3/99.,99.,99./
|
||||
save
|
||||
|
||||
call timer('fchisq65',0)
|
||||
baud=11025.0/4096.0
|
||||
nsps=nint(fsample/baud) !Samples per symbol
|
||||
nsph=nsps/2 !Samples per half-symbol
|
||||
ndiv=16 !Output ss() steps per symbol
|
||||
nout=ndiv*npts/nsps
|
||||
dtstep=1.0/(ndiv*baud) !Time per output step
|
||||
|
||||
if(a(1).ne.a1 .or. a(2).ne.a2 .or. a(3).ne.a3) then
|
||||
a1=a(1)
|
||||
a2=a(2)
|
||||
a3=a(3)
|
||||
|
||||
! Mix and integrate the complex signal
|
||||
csx(0)=0.
|
||||
w=1.0
|
||||
x0=0.5*(npts+1)
|
||||
s=2.0/npts
|
||||
do i=1,npts
|
||||
x=s*(i-x0)
|
||||
if(mod(i,100).eq.1) then
|
||||
p2=1.5*x*x - 0.5
|
||||
dphi=(a(1) + x*a(2) + p2*a(3)) * (twopi/fsample)
|
||||
wstep=cmplx(cos(dphi),sin(dphi))
|
||||
endif
|
||||
w=w*wstep
|
||||
csx(i)=csx(i-1) + w*cx(i)
|
||||
enddo
|
||||
endif
|
||||
|
||||
! Compute 1/2-symbol powers at 1/16-symbol steps.
|
||||
fac=1.e-4
|
||||
|
||||
do i=1,nout
|
||||
j=i*nsps/ndiv
|
||||
k=j-nsph
|
||||
ss(i)=0.
|
||||
if(k.ge.1) then
|
||||
z=csx(j)-csx(k)
|
||||
ss(i)=fac*(real(z)**2 + aimag(z)**2)
|
||||
endif
|
||||
enddo
|
||||
|
||||
ccfmax=0.
|
||||
call timer('ccf2 ',0)
|
||||
call ccf2(ss,nout,nflip,ccf,lagpk)
|
||||
call timer('ccf2 ',1)
|
||||
if(ccf.gt.ccfmax) then
|
||||
ccfmax=ccf
|
||||
dtmax=lagpk*dtstep
|
||||
endif
|
||||
fchisq65=-ccfmax
|
||||
|
||||
call timer('fchisq65',1)
|
||||
|
||||
return
|
||||
end function fchisq65
|
|
@ -0,0 +1,44 @@
|
|||
subroutine fil6521(c1,n1,c2,n2)
|
||||
|
||||
! FIR lowpass filter designed using ScopeFIR
|
||||
|
||||
! Pass #1 Pass #2
|
||||
! -----------------------------------------------
|
||||
! fsample (Hz) 1378.125 Input sample rate
|
||||
! Ntaps 21 Number of filter taps
|
||||
! fc (Hz) 40 Cutoff frequency
|
||||
! fstop (Hz) 172.266 Lower limit of stopband
|
||||
! Ripple (dB) 0.1 Ripple in passband
|
||||
! Stop Atten (dB) 38 Stopband attenuation
|
||||
! fout (Hz) 344.531 Output sample rate
|
||||
|
||||
parameter (NTAPS=21)
|
||||
parameter (NH=NTAPS/2)
|
||||
parameter (NDOWN=4) !Downsample ratio = 1/4
|
||||
complex c1(n1)
|
||||
complex c2(n1/NDOWN)
|
||||
|
||||
! Filter coefficients:
|
||||
real a(-NH:NH)
|
||||
data a/ &
|
||||
-0.011958606980,-0.013888627387,-0.015601306443,-0.010602249570, &
|
||||
0.003804023436, 0.028320058273, 0.060903935217, 0.096841904411, &
|
||||
0.129639871228, 0.152644580853, 0.160917511283, 0.152644580853, &
|
||||
0.129639871228, 0.096841904411, 0.060903935217, 0.028320058273, &
|
||||
0.003804023436,-0.010602249570,-0.015601306443,-0.013888627387, &
|
||||
-0.011958606980/
|
||||
|
||||
n2=(n1-NTAPS+NDOWN)/NDOWN
|
||||
k0=NH-NDOWN+1
|
||||
|
||||
! Loop over all output samples
|
||||
do i=1,n2
|
||||
c2(i)=0.
|
||||
k=k0 + NDOWN*i
|
||||
do j=-NH,NH
|
||||
c2(i)=c2(i) + c1(j+k)*a(j)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine fil6521
|
|
@ -0,0 +1,127 @@
|
|||
subroutine filbig(dd,npts,f0,newdat,c4a,n4,sq0)
|
||||
|
||||
! Filter and downsample the real data in array dd(npts), sampled at 12000 Hz.
|
||||
! Output is complex, sampled at 1378.125 Hz.
|
||||
|
||||
parameter (NSZ=3413)
|
||||
parameter (NFFT1=672000,NFFT2=77175)
|
||||
parameter (NZ2=1000)
|
||||
real*4 dd(npts) !Input data
|
||||
complex ca(NFFT1) !FFT of input
|
||||
complex c4a(NFFT2) !Output data
|
||||
real*4 s(NZ2)
|
||||
real*8 df
|
||||
real halfpulse(8) !Impulse response of filter (one sided)
|
||||
complex cfilt(NFFT2) !Filter (complex; imag = 0)
|
||||
real rfilt(NFFT2) !Filter (real)
|
||||
integer*8 plan1,plan2,plan3
|
||||
logical first
|
||||
include 'fftw3.f90'
|
||||
equivalence (rfilt,cfilt)
|
||||
data first/.true./,npatience/0/
|
||||
data halfpulse/114.97547150,36.57879257,-20.93789101, &
|
||||
5.89886379,1.59355187,-2.49138308,0.60910773,-0.04248129/
|
||||
common/refspec/dfref,ref(NSZ)
|
||||
save
|
||||
|
||||
if(npts.lt.0) go to 900 !Clean up at end of program
|
||||
|
||||
if(first) then
|
||||
nflags=FFTW_ESTIMATE
|
||||
if(npatience.eq.1) nflags=FFTW_ESTIMATE_PATIENT
|
||||
if(npatience.eq.2) nflags=FFTW_MEASURE
|
||||
if(npatience.eq.3) nflags=FFTW_PATIENT
|
||||
if(npatience.eq.4) nflags=FFTW_EXHAUSTIVE
|
||||
! Plan the FFTs just once
|
||||
call timer('FFTplans ',0)
|
||||
call sfftw_plan_dft_1d(plan1,nfft1,ca,ca,FFTW_BACKWARD,nflags)
|
||||
call sfftw_plan_dft_1d(plan2,nfft2,c4a,c4a,FFTW_FORWARD,nflags)
|
||||
call sfftw_plan_dft_1d(plan3,nfft2,cfilt,cfilt,FFTW_BACKWARD,nflags)
|
||||
call timer('FFTplans ',1)
|
||||
|
||||
! Convert impulse response to filter function
|
||||
do i=1,nfft2
|
||||
cfilt(i)=0.
|
||||
enddo
|
||||
fac=0.00625/nfft1
|
||||
cfilt(1)=fac*halfpulse(1)
|
||||
do i=2,8
|
||||
cfilt(i)=fac*halfpulse(i)
|
||||
cfilt(nfft2+2-i)=fac*halfpulse(i)
|
||||
enddo
|
||||
call timer('FFTfilt ',0)
|
||||
call sfftw_execute(plan3)
|
||||
call timer('FFTfilt ',1)
|
||||
|
||||
base=cfilt(nfft2/2+1)
|
||||
do i=1,nfft2
|
||||
rfilt(i)=real(cfilt(i))-base
|
||||
enddo
|
||||
|
||||
df=12000.d0/nfft1
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
! When new data comes along, we need to compute a new "big FFT"
|
||||
! If we just have a new f0, continue with the existing data in ca.
|
||||
|
||||
if(newdat.ne.0) then
|
||||
nz=min(npts,nfft1)
|
||||
ca(1:nz)=dd(1:nz)
|
||||
ca(nz+1:)=0. !### Should change this to r2c FFT ###
|
||||
call timer('FFTbig ',0)
|
||||
call sfftw_execute(plan1)
|
||||
call timer('FFTbig ',1)
|
||||
|
||||
do i=1,NFFT1/2 !Flatten the spectrum
|
||||
j=nint(i*df/dfref)
|
||||
if(j.lt.1) j=1
|
||||
if(j.gt.NSZ) j=NSZ
|
||||
fac=sqrt(min(30.0,1.0/ref(j)))
|
||||
ca(i)=fac * ca(i)
|
||||
enddo
|
||||
endif
|
||||
|
||||
! NB: f0 is the frequency at which we want our filter centered.
|
||||
! i0 is the bin number in ca closest to f0.
|
||||
|
||||
i0=nint(f0/df) + 1
|
||||
nh=nfft2/2
|
||||
do i=1,nh !Copy data into c4a and apply
|
||||
j=i0+i-1 !the filter function
|
||||
if(j.ge.1 .and. j.le.nfft1) then
|
||||
c4a(i)=rfilt(i)*ca(j)
|
||||
else
|
||||
c4a(i)=0.
|
||||
endif
|
||||
enddo
|
||||
do i=nh+1,nfft2
|
||||
j=i0+i-1-nfft2
|
||||
if(j.lt.1) j=j+nfft1 !nfft1 was nfft2
|
||||
c4a(i)=rfilt(i)*ca(j)
|
||||
enddo
|
||||
|
||||
nadd=nfft2/NZ2
|
||||
i=0
|
||||
do j=1,NZ2
|
||||
s(j)=0.
|
||||
do n=1,nadd
|
||||
i=i+1
|
||||
s(j)=s(j) + real(c4a(i))**2 + aimag(c4a(i))**2
|
||||
enddo
|
||||
enddo
|
||||
call pctile(s,NZ2,30,sq0)
|
||||
|
||||
! Do the short reverse transform, to go back to time domain.
|
||||
call timer('FFTsmall',0)
|
||||
call sfftw_execute(plan2)
|
||||
call timer('FFTsmall',1)
|
||||
n4=min(npts/8,nfft2)
|
||||
return
|
||||
|
||||
900 call sfftw_destroy_plan(plan1)
|
||||
call sfftw_destroy_plan(plan2)
|
||||
call sfftw_destroy_plan(plan3)
|
||||
|
||||
return
|
||||
end subroutine filbig
|
|
@ -1,24 +1,24 @@
|
|||
subroutine fillcom(nutc0,ndepth0)
|
||||
character*20 datetime
|
||||
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol, &
|
||||
kin,nzhsym,nsave,nagain,ndepth,nrxlog,nfsample,datetime
|
||||
kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,datetime
|
||||
save
|
||||
|
||||
nutc=nutc0
|
||||
ndiskdat=1
|
||||
ntrperiod=60
|
||||
nfqso=1500
|
||||
nfqso=1197
|
||||
newdat=1
|
||||
npts8=74736
|
||||
nfa=1000
|
||||
nfb=2000
|
||||
nfa=2700
|
||||
nfb=4007
|
||||
ntol=3
|
||||
kin=1024
|
||||
nzhsym=173
|
||||
nsave=0
|
||||
ndepth=ndepth0
|
||||
nrxlog=1
|
||||
nfsample=12000
|
||||
ntxmode=9
|
||||
nmode=9+65
|
||||
datetime="2013-Apr-16 15:13"
|
||||
|
||||
return
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
subroutine flat2(s,nz,ref)
|
||||
|
||||
parameter (NSMAX=6827)
|
||||
real s(NSMAX)
|
||||
real ref(NSMAX)
|
||||
|
||||
nsmo=10
|
||||
ia=nsmo+1
|
||||
ib=nz-nsmo-1
|
||||
do i=ia,ib
|
||||
call pctile(s(i-nsmo),2*nsmo+1,5,ref(i))
|
||||
enddo
|
||||
|
||||
ref(:ia-1)=ref(ia)
|
||||
ref(ib+1:)=ref(ib)
|
||||
|
||||
return
|
||||
end subroutine flat2
|
|
@ -0,0 +1,25 @@
|
|||
subroutine flat65(ss,nhsym,maxhsym,nsz,ref)
|
||||
|
||||
real stmp(nsz)
|
||||
real ss(maxhsym,nsz)
|
||||
real ref(nsz)
|
||||
|
||||
npct=28 !Somewhat arbitrary
|
||||
do i=1,nsz
|
||||
call pctile(ss(1,i),nhsym,npct,stmp(i))
|
||||
enddo
|
||||
|
||||
nsmo=33
|
||||
ia=nsmo/2 + 1
|
||||
ib=nsz - nsmo/2 - 1
|
||||
do i=ia,ib
|
||||
call pctile(stmp(i-nsmo/2),nsmo,npct,ref(i))
|
||||
enddo
|
||||
ref(:ia-1)=ref(ia)
|
||||
ref(ib+1:)=ref(ib)
|
||||
ref=4.0*ref
|
||||
|
||||
return
|
||||
end subroutine flat65
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
subroutine gen65(msg0,ichk,msgsent,itone,itext)
|
||||
|
||||
! Encodes a JT65 message to yieild itone(1:126)
|
||||
! Temporarily, does not implement EME shorthands
|
||||
|
||||
character*22 msg0
|
||||
character*22 message !Message to be generated
|
||||
character*22 msgsent !Message as it will be received
|
||||
integer itone(126)
|
||||
! character*3 cok !' ' or 'OOO'
|
||||
integer dgen(13)
|
||||
integer sent(63)
|
||||
logical text
|
||||
integer nprc(126)
|
||||
data nprc/1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, &
|
||||
0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, &
|
||||
0,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,0,1,1, &
|
||||
0,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,1, &
|
||||
1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1, &
|
||||
0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, &
|
||||
1,1,1,1,1,1/
|
||||
save
|
||||
|
||||
message=msg0
|
||||
do i=1,22
|
||||
if(ichar(message(i:i)).eq.0) then
|
||||
message(i:)=' '
|
||||
exit
|
||||
endif
|
||||
enddo
|
||||
|
||||
do i=1,22 !Strip leading blanks
|
||||
if(message(1:1).ne.' ') exit
|
||||
message=message(i+1:)
|
||||
enddo
|
||||
|
||||
nspecial=0
|
||||
! call chkmsg(message,cok,nspecial,flip)
|
||||
if(nspecial.eq.0) then
|
||||
call packmsg(message,dgen,text) !Pack message into 72 bits
|
||||
itext=0
|
||||
if(text) itext=1
|
||||
call unpackmsg(dgen,msgsent) !Unpack to get message sent
|
||||
if(ichk.ne.0) go to 999 !Return if checking only
|
||||
|
||||
call rs_encode(dgen,sent) !Apply Reed-Solomon code
|
||||
call interleave63(sent,1) !Apply interleaving
|
||||
call graycode65(sent,63,1) !Apply Gray code
|
||||
nsym=126 !Symbols per transmission
|
||||
else
|
||||
nsym=32
|
||||
endif
|
||||
|
||||
k=0
|
||||
do j=1,nsym
|
||||
if(nprc(j).eq.0) then
|
||||
k=k+1
|
||||
itone(j)=sent(k)+2
|
||||
else
|
||||
itone(j)=0
|
||||
endif
|
||||
enddo
|
||||
|
||||
999 return
|
||||
end subroutine gen65
|
|
@ -26,7 +26,7 @@ subroutine genjt9(msg0,ichk,msgsent,i4tone,itext)
|
|||
endif
|
||||
enddo
|
||||
|
||||
do i=1,22 !Omit leading blanks
|
||||
do i=1,22 !Strip leading blanks
|
||||
if(message(1:1).ne.' ') exit
|
||||
message=message(i+1:)
|
||||
enddo
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
subroutine graycode65(dat,n,idir)
|
||||
|
||||
integer dat(n)
|
||||
do i=1,n
|
||||
dat(i)=igray(dat(i),idir)
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine graycode65
|
|
@ -13,7 +13,7 @@
|
|||
#include "char.h"
|
||||
#endif
|
||||
|
||||
#define NULL ((void *)0)
|
||||
//#define NULL ((void *)0)
|
||||
|
||||
void FREE_RS(void *p){
|
||||
struct rs *rs = (struct rs *)p;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
subroutine interleave63(d1,idir)
|
||||
|
||||
! Interleave (idir=1) or de-interleave (idir=-1) the array d1.
|
||||
|
||||
integer d1(0:6,0:8)
|
||||
integer d2(0:8,0:6)
|
||||
|
||||
if(idir.ge.0) then
|
||||
do i=0,6
|
||||
do j=0,8
|
||||
d2(j,i)=d1(i,j)
|
||||
enddo
|
||||
enddo
|
||||
call move(d2,d1,63)
|
||||
else
|
||||
call move(d1,d2,63)
|
||||
do i=0,6
|
||||
do j=0,8
|
||||
d1(i,j)=d2(j,i)
|
||||
enddo
|
||||
enddo
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine interleave63
|
|
@ -0,0 +1,68 @@
|
|||
program jt65
|
||||
|
||||
! Test the JT65 decoder for WSJT-X
|
||||
|
||||
parameter (NZMAX=60*12000)
|
||||
integer*4 ihdr(11)
|
||||
integer*2 id2(NZMAX)
|
||||
real*4 dd(NZMAX)
|
||||
character*80 infile
|
||||
integer*2 nfmt2,nchan2,nbitsam2,nbytesam2
|
||||
character*4 ariff,awave,afmt,adata
|
||||
common/hdr/ariff,lenfile,awave,afmt,lenfmt,nfmt2,nchan2, &
|
||||
nsamrate,nbytesec,nbytesam2,nbitsam2,adata,ndata
|
||||
common/tracer/limtrace,lu
|
||||
equivalence (ariff,ihdr)
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.lt.1) then
|
||||
print*,'Usage: jt65 file1 [file2 ...]'
|
||||
go to 999
|
||||
endif
|
||||
limtrace=0
|
||||
lu=12
|
||||
|
||||
newdat=1
|
||||
ntol=50
|
||||
nfa=2700
|
||||
! nfb=4000
|
||||
nfqso=933
|
||||
nagain=0
|
||||
|
||||
open(12,file='timer.out',status='unknown')
|
||||
open(22,file='kvasd.dat',access='direct',recl=1024,status='unknown')
|
||||
|
||||
call timer('jt65 ',0)
|
||||
|
||||
do ifile=1,nargs
|
||||
call getarg(ifile,infile)
|
||||
open(10,file=infile,access='stream',status='old',err=998)
|
||||
|
||||
call timer('read ',0)
|
||||
read(10) ihdr
|
||||
nutc=ihdr(1) !Silence compiler warning
|
||||
i1=index(infile,'.wav')
|
||||
read(infile(i1-4:i1-1),*,err=10) nutc
|
||||
go to 20
|
||||
10 nutc=0
|
||||
20 npts=52*12000
|
||||
read(10) id2(1:npts)
|
||||
call timer('read ',1)
|
||||
dd(1:npts)=id2(1:npts)
|
||||
dd(npts+1:)=0.
|
||||
|
||||
call timer('jt65a ',0)
|
||||
call jt65a(dd,npts,newdat,nutc,ntol,nfa,nfqso,nagain,ndecoded)
|
||||
call timer('jt65a ',1)
|
||||
enddo
|
||||
|
||||
call timer('jt65 ',1)
|
||||
call timer('jt65 ',101)
|
||||
call four2a(a,-1,1,1,1) !Free the memory used for plans
|
||||
call filbig(a,-1,1,0.0,0,0,0,0,0) ! (ditto)
|
||||
go to 999
|
||||
|
||||
998 print*,'Cannot open file:'
|
||||
print*,infile
|
||||
|
||||
999 end program jt65
|
|
@ -0,0 +1,91 @@
|
|||
subroutine jt65a(dd,npts,newdat,nutc,nfa,nfqso,ntol,nagain,ndecoded)
|
||||
|
||||
! Process dd() data to find and decode JT65 signals.
|
||||
|
||||
parameter (NSZ=3413)
|
||||
parameter (NZMAX=60*12000)
|
||||
parameter (NFFT=8192)
|
||||
real dd(NZMAX)
|
||||
real*4 ss(322,NSZ)
|
||||
real*4 savg(NSZ)
|
||||
logical done(NSZ)
|
||||
real a(5)
|
||||
character decoded*22
|
||||
save
|
||||
|
||||
if(newdat.ne.0) then
|
||||
call timer('symsp65 ',0)
|
||||
call symspec65(dd,npts,ss,nhsym,savg) !Get normalized symbol spectra
|
||||
call timer('symsp65 ',1)
|
||||
endif
|
||||
|
||||
df=12000.0/NFFT !df = 12000.0/16384 = 0.732 Hz
|
||||
ftol=15.0 !Frequency tolerance (Hz)
|
||||
mode65=1 !Decoding JT65A only, for now.
|
||||
done=.false.
|
||||
|
||||
do nqd=1,0,-1
|
||||
if(nqd.eq.1) then !Quick decode, at fQSO
|
||||
fa=nfqso - ntol
|
||||
fb=nfqso + ntol
|
||||
else !Wideband decode at all freqs
|
||||
fa=200
|
||||
fb=nfa
|
||||
endif
|
||||
ia=max(51,nint(fa/df))
|
||||
ib=min(NSZ-51,nint(fb/df))
|
||||
|
||||
freq0=-999.
|
||||
thresh0=1.5
|
||||
|
||||
do i=ia,ib !Search over freq range
|
||||
if(savg(i).lt.thresh0 .or. done(i)) cycle
|
||||
freq=i*df
|
||||
|
||||
call timer('ccf65 ',0)
|
||||
call ccf65(ss(1,i),nhsym,savg(i),sync1,dt,flipk,syncshort,snr2,dt2)
|
||||
call timer('ccf65 ',1)
|
||||
|
||||
! ########################### Search for Shorthand Messages #################
|
||||
! include 'shorthand1.f90'
|
||||
|
||||
! ########################### Search for Normal Messages ###########
|
||||
thresh1=1.0
|
||||
! Use lower thresh1 at fQSO
|
||||
if(nqd.eq.1 .and. ntol.le.100) thresh1=0.
|
||||
|
||||
! Is sync1 above threshold?
|
||||
if(sync1.lt.thresh1) cycle
|
||||
|
||||
! Keep only the best candidate within ftol.
|
||||
if(freq-freq0.lt.ftol) cycle
|
||||
|
||||
nflip=nint(flipk)
|
||||
call timer('decod65a',0)
|
||||
call decode65a(dd,npts,newdat,freq,nflip,mode65,sync2,a,dt, &
|
||||
nbmkv,nhist,decoded)
|
||||
call timer('decod65a',1)
|
||||
|
||||
if(decoded.ne.' ') then
|
||||
ndecoded=1
|
||||
nfreq=nint(freq+a(1))
|
||||
ndrift=nint(2.0*a(2))
|
||||
s2db=10.0*log10(sync2) - 32 !### empirical (was 40) ###
|
||||
nsnr=nint(s2db)
|
||||
if(nsnr.lt.-30) nsnr=-30
|
||||
if(nsnr.gt.-1) nsnr=-1
|
||||
write(*,1010) nutc,nsnr,dt,nfreq,decoded
|
||||
1010 format(i4.4,i4,f5.1,i5,1x,'#',1x,a22)
|
||||
write(13,1012) nutc,nint(sync1),nsnr,dt,float(nfreq),ndrift, &
|
||||
decoded,nbmkv
|
||||
1012 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22,' JT65',i4)
|
||||
freq0=freq
|
||||
i2=min(NSZ,i+15) !### ??? ###
|
||||
done(i:i2)=.true.
|
||||
endif
|
||||
enddo
|
||||
if(nagain.eq.1) exit
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine jt65a
|
24
lib/jt9.f90
24
lib/jt9.f90
|
@ -3,18 +3,12 @@ program jt9
|
|||
! Decoder for JT9. Can run stand-alone, reading data from *.wav files;
|
||||
! or as the back end of wsjt-x, with data placed in a shared memory region.
|
||||
|
||||
parameter (NTMAX=120)
|
||||
parameter (NMAX=NTMAX*12000) !Total sample intervals per 30 minutes
|
||||
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate
|
||||
parameter (NSMAX=1365) !Max length of saved spectra
|
||||
include 'constants.f90'
|
||||
integer*4 ihdr(11)
|
||||
real*4 s(NSMAX)
|
||||
real*4 ccfred(NSMAX)
|
||||
logical*1 lstrong(0:1023)
|
||||
integer*2 id2
|
||||
complex c0
|
||||
character*80 arg,infile
|
||||
common/jt9com/ss(184,NSMAX),savg(NSMAX),c0(NDMAX),id2(NMAX),nutc,ndiskdat, &
|
||||
common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
|
||||
ntr,mousefqso,newdat,nfa,nfb,ntol,kin,nzhsym,nsynced,ndecoded
|
||||
common/tracer/limtrace,lu
|
||||
|
||||
|
@ -39,11 +33,6 @@ program jt9
|
|||
|
||||
limtrace=0
|
||||
lu=12
|
||||
nfa=1000
|
||||
nfb=2000
|
||||
mousefqso=1500
|
||||
newdat=1
|
||||
ndiskdat=1
|
||||
|
||||
do ifile=ifile1,nargs
|
||||
call getarg(ifile,infile)
|
||||
|
@ -82,10 +71,6 @@ program jt9
|
|||
call timer('jt9 ',0)
|
||||
endif
|
||||
|
||||
! do i=1,npts
|
||||
! id2(i)=100.0*sin(6.283185307*1600.0*i/12000.0)
|
||||
! enddo
|
||||
|
||||
id2=0 !??? Why is this necessary ???
|
||||
|
||||
do iblk=1,npts/kstep
|
||||
|
@ -99,8 +84,7 @@ program jt9
|
|||
! Emit signal readyForFFT
|
||||
ingain=0
|
||||
call timer('symspec ',0)
|
||||
call symspec(k,ntrperiod,nsps,ingain,pxdb,s,ccfred,df3, &
|
||||
ihsym,nzap,slimit,lstrong,npts8)
|
||||
call symspec(k,ntrperiod,nsps,ingain,slope,pxdb,s,df3,ihsym,npts8)
|
||||
call timer('symspec ',1)
|
||||
nhsym0=nhsym
|
||||
if(ihsym.ge.173) go to 10
|
||||
|
@ -109,7 +93,7 @@ program jt9
|
|||
|
||||
10 close(10)
|
||||
call fillcom(nutc0,ndepth)
|
||||
call decoder(ss,c0,1)
|
||||
call decoder(ss,id2)
|
||||
enddo
|
||||
|
||||
call timer('jt9 ',1)
|
||||
|
|
|
@ -20,6 +20,7 @@ subroutine jt9a
|
|||
open(12,file='timer.out',status='unknown')
|
||||
|
||||
limtrace=0
|
||||
! limtrace=-1 !Disable all calls to timer()
|
||||
lu=12
|
||||
i1=attach_jt9()
|
||||
|
||||
|
@ -44,12 +45,16 @@ subroutine jt9a
|
|||
go to 999
|
||||
endif
|
||||
p_jt9=>address_jt9()
|
||||
call timer('jt9b ',0)
|
||||
call jt9b(p_jt9,nbytes)
|
||||
call timer('jt9b ',1)
|
||||
|
||||
100 inquire(file=trim(cwd)//'/.lock',exist=fileExists)
|
||||
if(fileExists) go to 10
|
||||
call sleep_msec(100)
|
||||
go to 100
|
||||
|
||||
999 return
|
||||
999 call timer('jt9b ',101)
|
||||
|
||||
return
|
||||
end subroutine jt9a
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
subroutine jt9b(jt9com,nbytes)
|
||||
|
||||
parameter (NTMAX=120)
|
||||
parameter (NSMAX=1365)
|
||||
include 'constants.f90'
|
||||
integer*1 jt9com(0:nbytes-1)
|
||||
kss=0
|
||||
ksavg=kss + 4*184*NSMAX
|
||||
kc0=ksavg + 4*NSMAX
|
||||
kid2=kc0 + 2*4*NTMAX*1500
|
||||
kid2=ksavg + 4*NSMAX
|
||||
knutc=kid2 + 2*NTMAX*12000
|
||||
call jt9c(jt9com(kss),jt9com(ksavg),jt9com(kc0),jt9com(kid2),jt9com(knutc))
|
||||
call jt9c(jt9com(kss),jt9com(ksavg),jt9com(kid2),jt9com(knutc))
|
||||
|
||||
return
|
||||
end subroutine jt9b
|
||||
|
|
12
lib/jt9c.f90
12
lib/jt9c.f90
|
@ -1,21 +1,21 @@
|
|||
subroutine jt9c(ss,savg,c0,id2,nparams0)
|
||||
subroutine jt9c(ss,savg,id2,nparams0)
|
||||
|
||||
parameter (NSMAX=22000)
|
||||
include 'constants.f90'
|
||||
real*4 ss(184*NSMAX),savg(NSMAX)
|
||||
complex c0(1800*1500)
|
||||
integer*2 id2(1800*12000)
|
||||
integer*2 id2(NTMAX*12000)
|
||||
|
||||
integer nparams0(21),nparams(21)
|
||||
character*20 datetime
|
||||
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol, &
|
||||
kin,nzhsym,nsave,nagain,ndepth,nrxlog,nfsample,datetime
|
||||
kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,datetime
|
||||
equivalence (nparams,nutc)
|
||||
|
||||
nutc=id2(1)+int(savg(1)) !Silence compiler warning
|
||||
nparams=nparams0 !Copy parameters into common/npar/
|
||||
|
||||
call flush(6)
|
||||
if(sum(nparams).ne.0) call decoder(ss,c0,0)
|
||||
! if(sum(nparams).ne.0) call decoder(ss,id2)
|
||||
call decoder(ss,id2)
|
||||
|
||||
return
|
||||
end subroutine jt9c
|
||||
|
|
183
lib/jt9test.f90
183
lib/jt9test.f90
|
@ -1,183 +0,0 @@
|
|||
program jt9test
|
||||
|
||||
! Decoder for JT9. Can run stand-alone, reading data from *.wav files;
|
||||
! or as the back end of wsjt-x, with data placed in a shared memory region.
|
||||
|
||||
! NB: For unknown reason, ***MUST*** be compiled by g95 with -O0 !!!
|
||||
|
||||
parameter (NTMAX=120)
|
||||
parameter (NMAX=NTMAX*12000) !Total sample intervals per 30 minutes
|
||||
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate
|
||||
parameter (NSMAX=1365) !Max length of saved spectra
|
||||
integer*4 ihdr(11)
|
||||
real*4 s(NSMAX)
|
||||
real*4 ccfred(NSMAX)
|
||||
logical*1 lstrong(0:1023)
|
||||
integer*1 i1SoftSymbols(207)
|
||||
character*22 msg
|
||||
character*33 line
|
||||
character*80 arg,infile
|
||||
integer*2 id2
|
||||
complex c0
|
||||
complex c1(0:2700000)
|
||||
common/jt9com/ss(184,NSMAX),savg(NSMAX),c0(NDMAX),id2(NMAX),nutc,ndiskdat, &
|
||||
ntr,mousefqso,newdat,nfa,nfb,ntol,kin,nzhsym,nsynced,ndecoded
|
||||
common/tracer/limtrace,lu
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.lt.1) then
|
||||
print*,'Usage: jt9 TRperiod file1 [file2 ...]'
|
||||
print*,' Reads data from *.wav files.'
|
||||
print*,''
|
||||
print*,' jt9 -s'
|
||||
print*,' Gets data from shared memory region.'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,arg)
|
||||
if(arg(1:2).eq.'-s') then
|
||||
! call jt9a
|
||||
! call ftnquit
|
||||
go to 999
|
||||
endif
|
||||
read(arg,*) ntrperiod
|
||||
|
||||
ifile1=2
|
||||
|
||||
limtrace=0
|
||||
lu=12
|
||||
nfa=1000
|
||||
nfb=2000
|
||||
ntol=500
|
||||
nfqso=1500
|
||||
newdat=1
|
||||
nb=0
|
||||
nbslider=100
|
||||
limit=20000
|
||||
ndiskdat=1
|
||||
|
||||
do ifile=ifile1,nargs
|
||||
call getarg(ifile,infile)
|
||||
open(10,file=infile,access='stream',status='old',err=998)
|
||||
read(10) ihdr
|
||||
i1=index(infile,'.wav')
|
||||
read(infile(i1-4:i1-1),*,err=1) nutc0
|
||||
go to 2
|
||||
1 nutc0=0
|
||||
2 nsps=0
|
||||
if(ntrperiod.eq.1) then
|
||||
nsps=6912
|
||||
nzhsym=181
|
||||
else if(ntrperiod.eq.2) then
|
||||
nsps=15360
|
||||
nzhsym=178
|
||||
else if(ntrperiod.eq.5) then
|
||||
nsps=40960
|
||||
nzhsym=172
|
||||
else if(ntrperiod.eq.10) then
|
||||
nsps=82944
|
||||
nzhsym=171
|
||||
else if(ntrperiod.eq.30) then
|
||||
nsps=252000
|
||||
nzhsym=167
|
||||
endif
|
||||
if(nsps.eq.0) stop 'Error: bad TRperiod'
|
||||
|
||||
kstep=nsps/2
|
||||
tstep=kstep/12000.0
|
||||
k=0
|
||||
nhsym0=-999
|
||||
npts=(60*ntrperiod-6)*12000
|
||||
if(ifile.eq.ifile1) then
|
||||
open(12,file='timer.out',status='unknown')
|
||||
call timer('jt9 ',0)
|
||||
endif
|
||||
|
||||
! do i=1,npts
|
||||
! id2(i)=100.0*sin(6.283185307*1600.0*i/12000.0)
|
||||
! enddo
|
||||
|
||||
do iblk=1,npts/kstep
|
||||
k=iblk*kstep
|
||||
call timer('read_wav',0)
|
||||
read(10,end=10) id2(k-kstep+1:k)
|
||||
call timer('read_wav',1)
|
||||
|
||||
nhsym=(k-2048)/kstep
|
||||
if(nhsym.ge.1 .and. nhsym.ne.nhsym0) then
|
||||
! Emit signal readyForFFT
|
||||
ingain=0
|
||||
call timer('symspec ',0)
|
||||
call symspec(k,ntrperiod,nsps,ingain,nb,nbslider,pxdb, &
|
||||
s,ccfred,df3,ihsym,nzap,slimit,lstrong,npts8)
|
||||
call timer('symspec ',1)
|
||||
nhsym0=nhsym
|
||||
if(ihsym.ge.184) go to 10
|
||||
endif
|
||||
enddo
|
||||
10 close(10)
|
||||
|
||||
nsps8=nsps/8
|
||||
iz=1000.0/df3
|
||||
nutc=nutc0
|
||||
|
||||
call timer('sync9 ',0)
|
||||
call sync9(ss,nzhsym,tstep,df3,ccfred,ia,ib,ipk) !Get sync, freq
|
||||
call timer('sync9 ',1)
|
||||
|
||||
fgood=0.
|
||||
df8=1500.0/(nsps/8)
|
||||
sbest=0.
|
||||
do i=ia,ib
|
||||
f=(i-1)*df3
|
||||
if((i.eq.ipk .or. ccfred(i).ge.3.0) .and. f.gt.fgood+10.0*df8) then
|
||||
|
||||
call timer('test9 ',0)
|
||||
fpk=1000.0 + df3*(i-1)
|
||||
c1(0:npts8-1)=conjg(c0(1:npts8))
|
||||
call test9(c1,npts8,nsps8,fpk,syncpk,snrdb,xdt,freq,drift, &
|
||||
i1SoftSymbols)
|
||||
call timer('test9 ',1)
|
||||
|
||||
call timer('decode9 ',0)
|
||||
call decode9(i1SoftSymbols,limit,nlim,msg)
|
||||
call timer('decode9 ',1)
|
||||
snr=snrdb
|
||||
sync=syncpk - 2.0
|
||||
if(sync.lt.0.0) sync=0.0
|
||||
nsync=sync
|
||||
if(nsync.gt.10) nsync=10
|
||||
nsnr=nint(snr)
|
||||
width=0.0
|
||||
|
||||
if(sync.gt.sbest .and. fgood.eq.0.0) then
|
||||
sbest=sync
|
||||
write(line,1010) nutc,nsync,nsnr,xdt,1000.0+fpk,width
|
||||
if(nsync.gt.0) nsynced=1
|
||||
endif
|
||||
|
||||
if(msg.ne.' ') then
|
||||
write(*,1010) nutc,nsync,nsnr,xdt,freq,drift,msg
|
||||
1010 format(i4.4,i4,i5,f6.1,f8.2,f6.2,3x,a22)
|
||||
fgood=f
|
||||
nsynced=1
|
||||
ndecoded=1
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
||||
if(fgood.eq.0.0) then
|
||||
write(*,1020) line
|
||||
1020 format(a33)
|
||||
endif
|
||||
|
||||
enddo
|
||||
|
||||
call timer('jt9 ',1)
|
||||
call timer('jt9 ',101)
|
||||
! call ftnquit
|
||||
go to 999
|
||||
|
||||
998 print*,'Cannot open file:'
|
||||
print*,infile
|
||||
|
||||
999 end program jt9test
|
|
@ -0,0 +1,7 @@
|
|||
subroutine move(x,y,n)
|
||||
real x(n),y(n)
|
||||
do i=1,n
|
||||
y(i)=x(i)
|
||||
enddo
|
||||
return
|
||||
end subroutine move
|
|
@ -1,32 +0,0 @@
|
|||
subroutine peakdf9(c0,npts8,nsps8,istart,foffset,idfpk)
|
||||
|
||||
complex c0(0:npts8-1)
|
||||
complex zsum
|
||||
include 'jt9sync.f90'
|
||||
|
||||
twopi=8.0*atan(1.0)
|
||||
df=1500.0/nsps8
|
||||
smax=0.
|
||||
do idf=-5,5
|
||||
f0=foffset + 0.1*df*idf
|
||||
dphi=twopi*f0/1500.0
|
||||
sum=0.
|
||||
do j=1,16
|
||||
i1=(ii(j)-1)*nsps8 + istart
|
||||
phi=0.
|
||||
zsum=0.
|
||||
do i=i1,i1+nsps8-1
|
||||
if(i.lt.0 .or. i.gt.npts8-1) cycle
|
||||
phi=phi + dphi
|
||||
zsum=zsum + c0(i) * cmplx(cos(phi),-sin(phi))
|
||||
enddo
|
||||
sum=sum + real(zsum)**2 + aimag(zsum)**2
|
||||
enddo
|
||||
if(sum.gt.smax) then
|
||||
idfpk=idf
|
||||
smax=sum
|
||||
endif
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine peakdf9
|
|
@ -9,11 +9,8 @@ subroutine peakdt9(c2,nz2,nsps8,nspsd,c3,nz3,xdt)
|
|||
p=0.
|
||||
i0=5*nspsd
|
||||
do i=0,nz2-1
|
||||
z=1.e-3*sum(c2(max(i-(nspsd-1),0):i)) !Integrate
|
||||
p(i0+i)=real(z)**2 + aimag(z)**2 !Symbol power at freq=0
|
||||
! Option here for coherent processing ?
|
||||
! write(53,3301) i,z,p(i0+i),atan2(aimag(z),real(z))
|
||||
!3301 format(i6,4e12.3)
|
||||
z=1.e-3*sum(c2(max(i-(nspsd-1),0):i))
|
||||
p(i0+i)=real(z)**2 + aimag(z)**2 !Integrated symbol power at freq=0
|
||||
enddo
|
||||
|
||||
call getlags(nsps8,lag0,lag1,lag2)
|
||||
|
@ -35,8 +32,6 @@ subroutine peakdt9(c2,nz2,nsps8,nspsd,c3,nz3,xdt)
|
|||
enddo
|
||||
ss=(sum1/16.0)/(sum0/69.0) - 1.0
|
||||
xdt=(lag-lag0)*dtlag
|
||||
! write(52,3001) lag,xdt,ss
|
||||
!3001 format(i5,2f12.3)
|
||||
if(ss.gt.smax) then
|
||||
smax=ss
|
||||
lagpk=lag
|
||||
|
|
|
@ -68,7 +68,7 @@ int lp_ptt (int fd, int onoff);
|
|||
/* parport functions */
|
||||
|
||||
int dev_is_parport(int fd);
|
||||
int ptt_parallel(int fd, int *ntx, int *iptt);
|
||||
int ptt_parallel(int fd, int ntx, int *iptt);
|
||||
int ptt_serial(int fd, int *ntx, int *iptt);
|
||||
|
||||
int fd=-1; /* Used for both serial and parallel */
|
||||
|
@ -91,53 +91,42 @@ int fd=-1; /* Used for both serial and parallel */
|
|||
#define STATE_PORT_OPEN_PARALLEL 1
|
||||
#define STATE_PORT_OPEN_SERIAL 2
|
||||
|
||||
//int ptt_(int *unused, char *ptt_port, int *ntx, int *iptt)
|
||||
int ptt_(int *unused, int *ntx, int *iptt)
|
||||
//int ptt_(int *unused, int *ntx, int *iptt)
|
||||
int ptt_(int nport, int ntx, int *iptt, int *nopen)
|
||||
{
|
||||
static int state=0;
|
||||
char *p;
|
||||
char ptt_port[]="/dev/ttyUSB0";
|
||||
fflush(stdout);
|
||||
|
||||
// ### Temporary:
|
||||
char* ptt_port;
|
||||
if(*unused != -99) {
|
||||
*iptt=*ntx;
|
||||
return 0;
|
||||
}
|
||||
// ###
|
||||
|
||||
/* In the very unlikely event of a NULL pointer, just return.
|
||||
* Yes, I realise this should not be possible in WSJT.
|
||||
*/
|
||||
// In the very unlikely event of a NULL pointer, just return.
|
||||
if (ptt_port == NULL) {
|
||||
*iptt = *ntx;
|
||||
*iptt = ntx;
|
||||
return (0);
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case STATE_PORT_CLOSED:
|
||||
|
||||
/* Remove trailing ' ' */
|
||||
|
||||
// Remove trailing ' '
|
||||
if ((p = strchr(ptt_port, ' ')) != NULL)
|
||||
*p = '\0';
|
||||
|
||||
/* If all that is left is a '\0' then also just return */
|
||||
// If all that is left is a '\0' then also just return
|
||||
if (*ptt_port == '\0') {
|
||||
*iptt = *ntx;
|
||||
*iptt = ntx;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if ((fd = open(ptt_port, O_RDWR|O_NONBLOCK)) < 0) {
|
||||
fprintf(stderr, "Can't open %s.\n", ptt_port);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (dev_is_parport(fd)) {
|
||||
state = STATE_PORT_OPEN_PARALLEL;
|
||||
lp_reset(fd);
|
||||
ptt_parallel(fd, ntx, iptt);
|
||||
} else {
|
||||
state = STATE_PORT_OPEN_SERIAL;
|
||||
ptt_serial(fd, ntx, iptt);
|
||||
ptt_serial(fd, &ntx, iptt);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -146,7 +135,7 @@ int ptt_(int *unused, int *ntx, int *iptt)
|
|||
break;
|
||||
|
||||
case STATE_PORT_OPEN_SERIAL:
|
||||
ptt_serial(fd, ntx, iptt);
|
||||
ptt_serial(fd, &ntx, iptt);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -155,9 +144,11 @@ int ptt_(int *unused, int *ntx, int *iptt)
|
|||
state = STATE_PORT_CLOSED;
|
||||
break;
|
||||
}
|
||||
*iptt=ntx;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ptt_serial
|
||||
*
|
||||
|
@ -180,6 +171,8 @@ ptt_serial(int fd, int *ntx, int *iptt)
|
|||
ioctl(fd, TIOCMBIC, &control);
|
||||
*iptt = 0;
|
||||
}
|
||||
printf("ptt_serial: %d %d",*ntx,*iptt);
|
||||
fflush(stdout);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -379,10 +372,9 @@ lp_ptt (int fd, int onoff)
|
|||
* iptt - pointer to fortran command status on or off
|
||||
*/
|
||||
|
||||
int
|
||||
ptt_parallel(int fd, int *ntx, int *iptt)
|
||||
int ptt_parallel(int fd, int ntx, int *iptt)
|
||||
{
|
||||
if(*ntx) {
|
||||
if(ntx) {
|
||||
lp_ptt(fd, 1);
|
||||
*iptt=1;
|
||||
} else {
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
subroutine redsync(ss,ntrperiod,ihsym,iz,red)
|
||||
|
||||
! Compute the red curve (approx JT9 sync amplitude).
|
||||
! NB: red() is used for real-time display only. A better ccfred() is
|
||||
! computed during the decode procedure.
|
||||
|
||||
Parameter (NSMAX=1365)
|
||||
real*4 ss(184,NSMAX)
|
||||
real*4 red(NSMAX)
|
||||
include 'jt9sync.f90'
|
||||
|
||||
lagmax=9
|
||||
if(ntrperiod.eq.2) lagmax=5
|
||||
if(ntrperiod.eq.5) lagmax=2
|
||||
if(ntrperiod.eq.10) lagmax=1
|
||||
if(ntrperiod.eq.30) lagmax=1
|
||||
|
||||
do i=1,iz !Loop over frequency range
|
||||
smax=0.
|
||||
do lag=-lagmax,lagmax !Loop over DT lags
|
||||
sig=0.
|
||||
do j=1,16
|
||||
k=ii2(j)+lag
|
||||
if(k.ge.5 .and. k.le.ihsym) then
|
||||
sig=sig + ss(k,i) - 0.5*(ss(k-2,i)+ss(k-4,i))
|
||||
endif
|
||||
enddo
|
||||
if(sig.gt.smax) smax=sig
|
||||
enddo
|
||||
red(i)=smax
|
||||
enddo
|
||||
call pctile(red,iz,40,xmed)
|
||||
if(xmed.le.0.0) xmed=1.0
|
||||
red=red/xmed
|
||||
smax=0.
|
||||
do i=1,iz
|
||||
red(i)=0.2*db(red(i))
|
||||
smax=max(smax,red(i))
|
||||
enddo
|
||||
h=10.
|
||||
if(smax.gt.h) red=red*(h/smax)
|
||||
|
||||
return
|
||||
end subroutine redsync
|
|
@ -0,0 +1,60 @@
|
|||
subroutine s3avg(nsave,mode65,nutc,nhz,xdt,npol,ntol,s3,nsum,nkv,decoded)
|
||||
|
||||
! Save the current synchronized spectra, s3(64,63), for possible
|
||||
! decoding of average.
|
||||
|
||||
real s3(64,63) !Synchronized spectra for 63 symbols
|
||||
real s3a(64,63,64) !Saved spectra
|
||||
real s3b(64,63) !Average spectra
|
||||
integer iutc(64),ihz(64),ipol(64)
|
||||
real dt(64)
|
||||
character*22 decoded
|
||||
logical ltext,first
|
||||
data first/.true./
|
||||
save
|
||||
|
||||
if(first) then
|
||||
iutc=-1
|
||||
ihz=0
|
||||
ipol=0
|
||||
first=.false.
|
||||
ihzdiff=min(100,ntol)
|
||||
dtdiff=0.2
|
||||
endif
|
||||
|
||||
do i=1,64
|
||||
if(nutc.eq.iutc(i) .and. abs(nhz-ihz(i)).lt.ihzdiff) then
|
||||
nsave=mod(nsave-1+64,64)+1
|
||||
go to 10
|
||||
endif
|
||||
enddo
|
||||
|
||||
iutc(nsave)=nutc !Save UTC
|
||||
ihz(nsave)=nhz !Save freq in Hz
|
||||
ipol(nsave)=npol !Save pol
|
||||
dt(nsave)=xdt !Save DT
|
||||
s3a(1:64,1:63,nsave)=s3 !Save the spectra
|
||||
|
||||
10 s3b=0.
|
||||
do i=1,64 !Accumulate avg spectra
|
||||
if(iutc(i).lt.0) cycle
|
||||
if(mod(iutc(i),2).ne.mod(nutc,2)) cycle !Use only same sequence
|
||||
if(abs(nhz-ihz(i)).gt.ihzdiff) cycle !Freq must match
|
||||
if(abs(xdt-dt(i)).gt.dtdiff) cycle !DT must match
|
||||
s3b=s3b + s3a(1:64,1:63,i)
|
||||
nsum=nsum+1
|
||||
enddo
|
||||
|
||||
decoded=' '
|
||||
if(nsum.ge.2) then !Try decoding the sverage
|
||||
nadd=mode65*nsum
|
||||
call extract(s3b,nadd,ncount,nhist,decoded,ltext) !Extract the message
|
||||
nkv=nsum
|
||||
if(ncount.lt.0) then
|
||||
nkv=0
|
||||
decoded=' '
|
||||
endif
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine s3avg
|
|
@ -0,0 +1,96 @@
|
|||
subroutine setup65
|
||||
|
||||
! Defines arrays related to the JT65 pseudo-random synchronizing pattern.
|
||||
! Executed at program start.
|
||||
|
||||
integer nprc(126)
|
||||
common/prcom/pr(126),mdat(126),mref(126,2),mdat2(126),mref2(126,2)
|
||||
|
||||
! JT65
|
||||
data nprc/ &
|
||||
1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, &
|
||||
0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, &
|
||||
0,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,0,1,1, &
|
||||
0,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,1, &
|
||||
1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1, &
|
||||
0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, &
|
||||
1,1,1,1,1,1/
|
||||
data mr2/0/ !Silence compiler warning
|
||||
|
||||
! Put the appropriate pseudo-random sequence into pr
|
||||
nsym=126
|
||||
do i=1,nsym
|
||||
pr(i)=2*nprc(i)-1
|
||||
enddo
|
||||
|
||||
! Determine locations of data and reference symbols
|
||||
k=0
|
||||
mr1=0
|
||||
do i=1,nsym
|
||||
if(pr(i).lt.0.0) then
|
||||
k=k+1
|
||||
mdat(k)=i
|
||||
else
|
||||
mr2=i
|
||||
if(mr1.eq.0) mr1=i
|
||||
endif
|
||||
enddo
|
||||
nsig=k
|
||||
|
||||
! Determine the reference symbols for each data symbol.
|
||||
do k=1,nsig
|
||||
m=mdat(k)
|
||||
mref(k,1)=mr1
|
||||
do n=1,10 !Get ref symbol before data
|
||||
if((m-n).gt.0) then
|
||||
if (pr(m-n).gt.0.0) go to 10
|
||||
endif
|
||||
enddo
|
||||
go to 12
|
||||
10 mref(k,1)=m-n
|
||||
12 mref(k,2)=mr2
|
||||
do n=1,10 !Get ref symbol after data
|
||||
if((m+n).le.nsym) then
|
||||
if (pr(m+n).gt.0.0) go to 20
|
||||
endif
|
||||
enddo
|
||||
cycle
|
||||
20 mref(k,2)=m+n
|
||||
enddo
|
||||
|
||||
! Now do it all again, using opposite logic on pr(i)
|
||||
k=0
|
||||
mr1=0
|
||||
do i=1,nsym
|
||||
if(pr(i).gt.0.0) then
|
||||
k=k+1
|
||||
mdat2(k)=i
|
||||
else
|
||||
mr2=i
|
||||
if(mr1.eq.0) mr1=i
|
||||
endif
|
||||
enddo
|
||||
nsig=k
|
||||
|
||||
do k=1,nsig
|
||||
m=mdat2(k)
|
||||
mref2(k,1)=mr1
|
||||
do n=1,10
|
||||
if((m-n).gt.0) then
|
||||
if (pr(m-n).lt.0.0) go to 110
|
||||
endif
|
||||
enddo
|
||||
go to 112
|
||||
110 mref2(k,1)=m-n
|
||||
112 mref2(k,2)=mr2
|
||||
do n=1,10
|
||||
if((m+n).le.nsym) then
|
||||
if (pr(m+n).lt.0.0) go to 120
|
||||
endif
|
||||
enddo
|
||||
cycle
|
||||
120 mref2(k,2)=m+n
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine setup65
|
|
@ -0,0 +1,13 @@
|
|||
subroutine smo121(x,nz)
|
||||
|
||||
real x(nz)
|
||||
|
||||
x0=x(1)
|
||||
do i=2,nz-1
|
||||
x1=x(i)
|
||||
x(i)=0.5*x(i) + 0.25*(x0+x(i+1))
|
||||
x0=x1
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine smo121
|
|
@ -1,9 +1,8 @@
|
|||
subroutine softsym(c0,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,freq,drift, &
|
||||
schk,i1SoftSymbols)
|
||||
subroutine softsym(id2,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt, &
|
||||
freq,drift,schk,i1SoftSymbols)
|
||||
|
||||
! Compute the soft symbols
|
||||
|
||||
complex c0(0:npts8-1)
|
||||
complex c2(0:4096-1)
|
||||
complex c3(0:4096-1)
|
||||
complex c5(0:4096-1)
|
||||
|
@ -16,7 +15,7 @@ subroutine softsym(c0,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,freq,drift, &
|
|||
ndown=nsps8/nspsd
|
||||
|
||||
! Mix, low-pass filter, and downsample to 16 samples per symbol
|
||||
call downsam9(c0,npts8,nsps8,newdat,nspsd,fpk,c2,nz2)
|
||||
call downsam9(id2,npts8,nsps8,newdat,nspsd,fpk,c2,nz2)
|
||||
|
||||
call peakdt9(c2,nz2,nsps8,nspsd,c3,nz3,xdt) !Find DT
|
||||
|
||||
|
@ -26,7 +25,7 @@ subroutine softsym(c0,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,freq,drift, &
|
|||
freq=fpk - a(1)
|
||||
drift=-2.0*a(2)
|
||||
|
||||
call twkfreq(c3,c5,nz3,fsample,a) !Correct for deltaF, fDot, fDDot
|
||||
call twkfreq(c3,c5,nz3,fsample,a) !Correct for delta f, f1, f2 ==> a(1:3)
|
||||
|
||||
! Compute soft symbols (in scrambled order)
|
||||
call symspec2(c5,nz3,nsps8,nspsd,fsample,freq,drift,snrdb,schk, &
|
||||
|
|
141
lib/symspec.f90
141
lib/symspec.f90
|
@ -1,4 +1,4 @@
|
|||
subroutine symspec(k,ntrperiod,nsps,ingain,pxdb,s,red,df3,ihsym,npts8)
|
||||
subroutine symspec(k,ntrperiod,nsps,ingain,slope,pxdb,s,df3,ihsym,npts8)
|
||||
|
||||
! Input:
|
||||
! k pointer to the most recent new data
|
||||
|
@ -10,111 +10,89 @@ subroutine symspec(k,ntrperiod,nsps,ingain,pxdb,s,red,df3,ihsym,npts8)
|
|||
|
||||
! Output:
|
||||
! pxdb power (0-60 dB)
|
||||
! s() spectrum for waterfall display
|
||||
! red() first cut at JT9 sync amplitude
|
||||
! s() current spectrum for waterfall display
|
||||
! ihsym index number of this half-symbol (1-184)
|
||||
|
||||
parameter (NTMAX=120)
|
||||
parameter (NMAX=NTMAX*12000) !Total sample intervals per 30 minutes
|
||||
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate
|
||||
parameter (NSMAX=1365) !Max length of saved spectra
|
||||
parameter (NFFT1=1024)
|
||||
parameter (NFFT2=1024,NFFT2A=NFFT2/8)
|
||||
parameter (MAXFFT3=32768)
|
||||
real*4 s(NSMAX),w3(MAXFFT3)
|
||||
real*4 x1(NFFT1)
|
||||
real*4 x2(NFFT1+105)
|
||||
! jt9com
|
||||
! ss() JT9 symbol spectra at half-symbol steps
|
||||
! savg() average spectra for waterfall display
|
||||
|
||||
include 'constants.f90'
|
||||
real*4 w3(MAXFFT3)
|
||||
real*4 s(NSMAX)
|
||||
real*4 scale(NSMAX)
|
||||
real*4 ssum(NSMAX)
|
||||
real*4 red(NSMAX)
|
||||
complex cx(0:MAXFFT3-1)
|
||||
real*4 xc(0:MAXFFT3-1)
|
||||
complex cx(0:MAXFFT3/2)
|
||||
integer*2 id2
|
||||
complex c0
|
||||
common/jt9com/ss(184,NSMAX),savg(NSMAX),c0(NDMAX),id2(NMAX),nutc,ndiskdat, &
|
||||
common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
|
||||
ntr,mousefqso,newdat,nfa,nfb,ntol,kin,nzhsym,nsynced,ndecoded
|
||||
data rms/999.0/,k0/99999999/,ntrperiod0/0/,nfft3z/0/
|
||||
data rms/999.0/,k0/99999999/,nfft3z/0/,slope0/0.0/
|
||||
equivalence (xc,cx)
|
||||
save
|
||||
|
||||
if(ntrperiod.eq.1) nfft3=2048
|
||||
if(ntrperiod.eq.2) nfft3=2048
|
||||
if(ntrperiod.eq.5) nfft3=6144
|
||||
if(ntrperiod.eq.10) nfft3=12288
|
||||
if(ntrperiod.eq.30) nfft3=32768
|
||||
|
||||
jstep=nsps/16 !Step size = half-symbol in c0()
|
||||
if(k.gt.NMAX) go to 999
|
||||
if(k.lt.nfft3) then
|
||||
if(ntrperiod.eq.-999) stop !Silence compiler warning
|
||||
nfft3=16384 !df=12000.0/16384 = 0.732422
|
||||
jstep=nsps/2 !Step size = half-symbol in id2()
|
||||
if(k.gt.NMAX) go to 900
|
||||
if(k.lt.2048) then !(2048 was nfft3) (Any need for this ???)
|
||||
ihsym=0
|
||||
go to 999 !Wait for enough samples to start
|
||||
go to 900 !Wait for enough samples to start
|
||||
endif
|
||||
if(nfft3.ne.nfft3z) then !New nfft3, compute window
|
||||
|
||||
if(nfft3.ne.nfft3z .or. slope.ne.slope0) then !New nfft3, compute window
|
||||
pi=4.0*atan(1.0)
|
||||
if(ntrperiod.eq.1) then !Compute window for nfft3 spectrun
|
||||
do i=1,nfft3
|
||||
xx=float(i-1)/(nfft3-1)
|
||||
w3(i)=0.40897 -0.5*cos(2.0*pi*xx) + 0.09103*cos(4.0*pi*xx)
|
||||
! w3(i)=0.355768 - 0.487306*cos(2.0*pi*xx) + 0.144232*cos(4.0*pi*xx) &
|
||||
! - 0.012604*cos(6.0*pi*xx)
|
||||
enddo
|
||||
else
|
||||
do i=1,nfft3
|
||||
w3(i)=2.0*(sin(i*pi/nfft3))**2 !Window for nfft3 spectrum
|
||||
enddo
|
||||
endif
|
||||
do i=1,nfft3
|
||||
w3(i)=2.0*(sin(i*pi/nfft3))**2 !Window for nfft3 spectrum
|
||||
enddo
|
||||
nfft3z=nfft3
|
||||
nh=NSMAX/2
|
||||
do i=1,NSMAX
|
||||
x=slope*float(i)/nh - 1.0 + 2.6
|
||||
scale(i)=10.0**x
|
||||
enddo
|
||||
slope0=slope
|
||||
endif
|
||||
|
||||
if(k.lt.k0) then !Start a new data block
|
||||
ja=0
|
||||
ssum=0.
|
||||
ihsym=0
|
||||
k1=0
|
||||
k8=0
|
||||
x2=0.
|
||||
if(ndiskdat.eq.0) then
|
||||
id2(k+1:)=0
|
||||
c0=0. !This is necessary to prevent "ghosts". Not sure why.
|
||||
endif
|
||||
if(ndiskdat.eq.0) id2(k+1:)=0 !Needed to prevent "ghosts". Not sure why.
|
||||
endif
|
||||
k0=k
|
||||
kstep1=NFFT1
|
||||
fac=2.0/NFFT1
|
||||
nblks=(k-k1)/kstep1
|
||||
gain=10.0**(0.05*ingain)
|
||||
sq=0.
|
||||
do nblk=1,nblks
|
||||
do i=1,NFFT1
|
||||
x1(i)=gain*id2(k1+i)
|
||||
enddo
|
||||
sq=sq + dot_product(x1,x1)
|
||||
! Mix at 1500 Hz, lowpass at +/-750 Hz, and downsample to 1500 Hz complex.
|
||||
x2(106:105+kstep1)=x1(1:kstep1)
|
||||
call fil3(x2,kstep1+105,c0(k8+1),n2)
|
||||
x2(1:105)=x1(kstep1-104:kstep1) !Save 105 trailing samples
|
||||
k1=k1+kstep1
|
||||
k8=k8+kstep1/8
|
||||
do i=k0+1,k
|
||||
x1=id2(i)
|
||||
sq=sq + x1*x1
|
||||
enddo
|
||||
|
||||
npts8=k8
|
||||
ja=ja+jstep !Index of first sample
|
||||
rms=sqrt(sq/(nblks*NFFT1))
|
||||
sq=sq * gain**2
|
||||
rms=sqrt(sq/(k-k0))
|
||||
pxdb=0.
|
||||
if(rms.gt.0.0) pxdb=20.0*log10(rms)
|
||||
if(pxdb.gt.60.0) pxdb=60.0
|
||||
|
||||
|
||||
k0=k
|
||||
ja=ja+jstep !Index of first sample
|
||||
|
||||
fac0=0.1
|
||||
do i=0,nfft3-1 !Copy data into cx
|
||||
j=ja+i-(nfft3-1)
|
||||
cx(i)=0.
|
||||
if(j.ge.1 .and. j.le.NDMAX) cx(i)=c0(j)
|
||||
xc(i)=0.
|
||||
if(j.ge.1) xc(i)=fac0*id2(j)
|
||||
enddo
|
||||
|
||||
if(ihsym.lt.184) ihsym=ihsym+1
|
||||
cx(0:nfft3-1)=w3(1:nfft3)*cx(0:nfft3-1) !Apply window w3
|
||||
call four2a(cx,nfft3,1,1,1) !Third FFT (forward)
|
||||
|
||||
xc(0:nfft3-1)=w3(1:nfft3)*xc(0:nfft3-1) !Apply window w3
|
||||
call four2a(xc,nfft3,1,-1,0) !Real-to-complex FFT
|
||||
|
||||
n=min(184,ihsym)
|
||||
df3=1500.0/nfft3 !JT9-a: 0.732 Hz = 0.42 * tone spacing
|
||||
i0=nint(-500.0/df3)
|
||||
iz=min(NSMAX,nint(1000.0/df3))
|
||||
df3=12000.0/nfft3 !JT9-1: 0.732 Hz = 0.42 * tone spacing
|
||||
! i0=nint(1000.0/df3)
|
||||
i0=0
|
||||
iz=min(NSMAX,nint(5000.0/df3))
|
||||
fac=(1.0/nfft3)**2
|
||||
do i=1,iz
|
||||
j=i0+i-1
|
||||
|
@ -125,18 +103,11 @@ subroutine symspec(k,ntrperiod,nsps,ingain,pxdb,s,red,df3,ihsym,npts8)
|
|||
s(i)=sx
|
||||
enddo
|
||||
|
||||
999 continue
|
||||
! s=0.05*s/ref
|
||||
s=scale*s
|
||||
savg=scale*ssum/ihsym
|
||||
|
||||
fac00=0.35
|
||||
npct=20
|
||||
call pctile(s,iz,npct,xmed0)
|
||||
fac0=fac00/max(xmed0,0.006)
|
||||
s(1:iz)=fac0*s(1:iz)
|
||||
call pctile(ssum,iz,npct,xmed1)
|
||||
fac1=fac00/max(xmed1,0.006*ihsym)
|
||||
savg(1:iz)=fac1*ssum(1:iz)
|
||||
! savg(iz+1:iz+20)=savg(iz)
|
||||
call redsync(ss,ntrperiod,ihsym,iz,red)
|
||||
900 npts8=k/8
|
||||
|
||||
return
|
||||
end subroutine symspec
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
subroutine symspec65(dd,npts,ss,nhsym,savg)
|
||||
|
||||
! Compute JT65 symbol spectra at half-symbol steps
|
||||
|
||||
parameter (NFFT=8192)
|
||||
parameter (NSZ=3413) !NFFT*5000/12000
|
||||
parameter (MAXHSYM=322)
|
||||
real*8 hstep
|
||||
real*4 dd(npts)
|
||||
real*4 ss(MAXHSYM,NSZ)
|
||||
real*4 savg(NSZ)
|
||||
real*4 x(NFFT)
|
||||
complex c(0:NFFT/2)
|
||||
common/refspec/dfref,ref(NSZ)
|
||||
equivalence (x,c)
|
||||
save /refspec/
|
||||
|
||||
hstep=2048.d0*12000.d0/11025.d0 !half-symbol = 2229.116 samples
|
||||
nsps=nint(2*hstep)
|
||||
df=12000.0/NFFT
|
||||
nhsym=npts/hstep - 1.0
|
||||
savg=0.
|
||||
fac1=1.e-3
|
||||
|
||||
do j=1,nhsym
|
||||
i0=(j-1)*hstep
|
||||
x(1:nsps)=fac1*dd(i0+1:i0+nsps)
|
||||
x(nsps+1:)=0.
|
||||
call four2a(c,NFFT,1,-1,0) !r2c forward FFT
|
||||
do i=1,NSZ
|
||||
s=real(c(i))**2 + aimag(c(i))**2
|
||||
ss(j,i)=s
|
||||
savg(i)=savg(i)+s
|
||||
enddo
|
||||
enddo
|
||||
savg=savg/nhsym
|
||||
|
||||
call flat65(ss,nhsym,MAXHSYM,NSZ,ref) !Flatten the 2d spectrum, saving
|
||||
dfref=df ! the reference spectrum ref()
|
||||
|
||||
savg=savg/ref
|
||||
do j=1,nhsym
|
||||
ss(j,1:NSZ)=ss(j,1:NSZ)/ref
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine symspec65
|
|
@ -1,6 +1,7 @@
|
|||
subroutine sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipkbest)
|
||||
|
||||
parameter (NSMAX=1365) !Max length of saved spectra
|
||||
include 'constants.f90'
|
||||
! parameter (NSMAX=1365) !Max length of saved spectra
|
||||
real ss(184,NSMAX)
|
||||
real ss1(184)
|
||||
real ccfred(NSMAX)
|
||||
|
|
|
@ -7,7 +7,7 @@ subroutine timer(dname,k)
|
|||
character*8 dname,name(50),space,ename
|
||||
character*16 sname
|
||||
logical on(50)
|
||||
real ut(50),ut0(50),dut(50),tt(2)
|
||||
real ut(50),ut0(50),dut(50)
|
||||
integer ncall(50),nlevel(50),nparent(50)
|
||||
integer onlevel(0:10)
|
||||
common/tracer/ limtrace,lu
|
||||
|
@ -36,7 +36,8 @@ subroutine timer(dname,k)
|
|||
if(on(n)) print*,'Error in timer: ',dname,' already on.'
|
||||
level=level+1 !Increment the level
|
||||
on(n)=.true.
|
||||
ut0(n)=etime(tt)
|
||||
call system_clock(icount,irate)
|
||||
ut0(n)=float(icount)/irate
|
||||
ncall(n)=ncall(n)+1
|
||||
if(ncall(n).gt.1.and.nlevel(n).ne.level) then
|
||||
nlevel(n)=-1
|
||||
|
@ -49,7 +50,8 @@ subroutine timer(dname,k)
|
|||
else if(k.eq.1) then !Get stop times and accumulate sums. (k=1)
|
||||
if(on(n)) then
|
||||
on(n)=.false.
|
||||
ut1=etime(tt)
|
||||
call system_clock(icount,irate)
|
||||
ut1=float(icount)/irate
|
||||
ut(n)=ut(n)+ut1-ut0(n)
|
||||
endif
|
||||
level=level-1
|
||||
|
|
|
@ -13,13 +13,13 @@ subroutine twkfreq(c3,c4,npts,fsample,a)
|
|||
s=2.0/npts
|
||||
do i=1,npts
|
||||
x=s*(i-x0)
|
||||
! if(mod(i,100).eq.1) then
|
||||
if(mod(i,100).eq.1) then
|
||||
p2=1.5*x*x - 0.5
|
||||
! p3=2.5*(x**3) - 1.5*x
|
||||
! p4=4.375*(x**4) - 3.75*(x**2) + 0.375
|
||||
dphi=(a(1) + x*a(2) + p2*a(3)) * (twopi/fsample)
|
||||
wstep=cmplx(cos(dphi),sin(dphi))
|
||||
! endif
|
||||
endif
|
||||
w=w*wstep
|
||||
c4(i)=w*c3(i)
|
||||
enddo
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
subroutine twkfreq65(c4aa,n5,a)
|
||||
|
||||
complex c4aa(n5)
|
||||
real a(5)
|
||||
complex w,wstep
|
||||
data twopi/6.283185307/
|
||||
|
||||
! Apply AFC corrections to the c4aa data
|
||||
w=1.0
|
||||
wstep=1.0
|
||||
x0=0.5*(n5+1)
|
||||
s=2.0/n5
|
||||
do i=1,n5
|
||||
x=s*(i-x0)
|
||||
if(mod(i,100).eq.1) then
|
||||
p2=1.5*x*x - 0.5
|
||||
dphi=(a(1) + x*a(2) + p2*a(3)) * (twopi/1378.125)
|
||||
wstep=cmplx(cos(dphi),sin(dphi))
|
||||
endif
|
||||
w=w*wstep
|
||||
c4aa(i)=w*c4aa(i)
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine twkfreq65
|
|
@ -0,0 +1,70 @@
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include "rs.h"
|
||||
|
||||
static void *rs;
|
||||
static int first=1;
|
||||
|
||||
void rs_encode_(int *dgen, int *sent)
|
||||
// Encode JT65 data dgen[12], producing sent[63].
|
||||
{
|
||||
int dat1[12];
|
||||
int b[51];
|
||||
int i;
|
||||
|
||||
if(first) {
|
||||
// Initialize the JT65 codec
|
||||
rs=init_rs_int(6,0x43,3,1,51,0);
|
||||
first=0;
|
||||
}
|
||||
|
||||
// Reverse data order for the Karn codec.
|
||||
for(i=0; i<12; i++) {
|
||||
dat1[i]=dgen[11-i];
|
||||
}
|
||||
// Compute the parity symbols
|
||||
encode_rs_int(rs,dat1,b);
|
||||
|
||||
// Move parity symbols and data into sent[] array, in reverse order.
|
||||
for (i = 0; i < 51; i++) sent[50-i] = b[i];
|
||||
for (i = 0; i < 12; i++) sent[i+51] = dat1[11-i];
|
||||
}
|
||||
|
||||
void rs_decode_(int *recd0, int *era0, int *numera0, int *decoded, int *nerr)
|
||||
// Decode JT65 received data recd0[63], producing decoded[12].
|
||||
// Erasures are indicated in era0[numera]. The number of corrected
|
||||
// errors is *nerr. If the data are uncorrectable, *nerr=-1 is returned.
|
||||
{
|
||||
int numera;
|
||||
int i;
|
||||
int era_pos[50];
|
||||
int recd[63];
|
||||
|
||||
if(first) {
|
||||
rs=init_rs_int(6,0x43,3,1,51,0);
|
||||
first=0;
|
||||
}
|
||||
|
||||
numera=*numera0;
|
||||
for(i=0; i<12; i++) recd[i]=recd0[62-i];
|
||||
for(i=0; i<51; i++) recd[12+i]=recd0[50-i];
|
||||
if(numera)
|
||||
for(i=0; i<numera; i++) era_pos[i]=era0[i];
|
||||
*nerr=decode_rs_int(rs,recd,era_pos,numera);
|
||||
for(i=0; i<12; i++) decoded[i]=recd[11-i];
|
||||
}
|
||||
|
||||
|
||||
void rs_encode__(int *dgen, int *sent)
|
||||
{
|
||||
rs_encode_(dgen, sent);
|
||||
}
|
||||
|
||||
void rs_decode__(int *recd0, int *era0, int *numera0, int *decoded, int *nerr)
|
||||
{
|
||||
rs_decode_(recd0, era0, numera0, decoded, nerr);
|
||||
}
|
||||
|
|
@ -141,9 +141,12 @@ void LogQSO::accept()
|
|||
m.exec();
|
||||
} else {
|
||||
QString logEntry=m_dateTime.date().toString("yyyy-MMM-dd,") +
|
||||
m_dateTime.time().toString("hh:mm,") + hisCall + "," +
|
||||
hisGrid + "," + strDialFreq + "," + mode +
|
||||
"," + rptSent + "," + rptRcvd + "," + comments;
|
||||
m_dateTime.time().toString("hh:mm,") + hisCall + "," +
|
||||
hisGrid + "," + strDialFreq + "," + mode +
|
||||
"," + rptSent + "," + rptRcvd;
|
||||
if(m_txPower!="") logEntry += "," + m_txPower;
|
||||
if(comments!="") logEntry += "," + comments;
|
||||
if(name!="") logEntry += "," + name;
|
||||
QTextStream out(&f);
|
||||
out << logEntry << endl;
|
||||
f.close();
|
||||
|
|
622
mainwindow.cpp
622
mainwindow.cpp
File diff suppressed because it is too large
Load Diff
45
mainwindow.h
45
mainwindow.h
|
@ -43,6 +43,8 @@ public slots:
|
|||
void readFromStdout();
|
||||
void readFromStderr();
|
||||
void jt9_error();
|
||||
void setXIT(int n);
|
||||
void setFreq4(int rxFreq, int txFreq);
|
||||
|
||||
protected:
|
||||
virtual void keyPressEvent( QKeyEvent *e );
|
||||
|
@ -72,7 +74,6 @@ private slots:
|
|||
void on_actionOpen_next_in_directory_triggered();
|
||||
void on_actionDecode_remaining_files_in_directory_triggered();
|
||||
void on_actionDelete_all_wav_files_in_SaveDir_triggered();
|
||||
void on_actionF4_sets_Tx6_triggered();
|
||||
void on_actionNone_triggered();
|
||||
void on_actionSave_all_triggered();
|
||||
void on_actionKeyboard_shortcuts_triggered();
|
||||
|
@ -97,13 +98,10 @@ private slots:
|
|||
void on_logQSOButton_clicked();
|
||||
void on_actionAFMHot_triggered();
|
||||
void on_actionBlue_triggered();
|
||||
void on_actionJT9_2_triggered();
|
||||
void on_actionJT9_1_triggered();
|
||||
void on_actionJT9_5_triggered();
|
||||
void on_actionJT9_30_triggered();
|
||||
void on_actionJT9_10_triggered();
|
||||
void on_actionJT65_triggered();
|
||||
void on_actionJT9_JT65_triggered();
|
||||
void on_TxFreqSpinBox_valueChanged(int arg1);
|
||||
void on_actionSave_synced_triggered();
|
||||
void on_actionSave_decoded_triggered();
|
||||
void on_actionQuickDecode_triggered();
|
||||
void on_actionMediumDecode_triggered();
|
||||
|
@ -147,7 +145,6 @@ private slots:
|
|||
void on_rptSpinBox_valueChanged(int n);
|
||||
void on_action_73TxDisable_triggered(bool checked);
|
||||
void on_actionRunaway_Tx_watchdog_triggered(bool checked);
|
||||
void on_actionTx2QSO_triggered(bool checked);
|
||||
void killFile();
|
||||
void on_tuneButton_clicked();
|
||||
void on_actionAllow_multiple_instances_triggered(bool checked);
|
||||
|
@ -155,10 +152,11 @@ private slots:
|
|||
void on_pbT2R_clicked();
|
||||
void acceptQSO2(bool accepted);
|
||||
void on_bandComboBox_activated(int index);
|
||||
|
||||
void on_readFreq_clicked();
|
||||
|
||||
void on_actionLockTxFreq_triggered(bool checked);
|
||||
void on_pbTxMode_clicked();
|
||||
void on_RxFreqSpinBox_valueChanged(int n);
|
||||
void on_cbTxLock_clicked(bool checked);
|
||||
void on_actionTx2QSO_triggered(bool checked);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
|
@ -168,15 +166,13 @@ private:
|
|||
qint64 m_msErase;
|
||||
qint64 m_secBandChanged;
|
||||
|
||||
qint32 m_nDevIn;
|
||||
qint32 m_nDevOut;
|
||||
qint32 m_idInt;
|
||||
qint32 m_waterfallAvg;
|
||||
qint32 m_pttMethodIndex;
|
||||
qint32 m_QSOfreq0;
|
||||
qint32 m_ntx;
|
||||
qint32 m_pttPort;
|
||||
qint32 m_timeout;
|
||||
qint32 m_rxFreq;
|
||||
qint32 m_txFreq;
|
||||
qint32 m_setftx;
|
||||
qint32 m_ndepth;
|
||||
|
@ -184,7 +180,7 @@ private:
|
|||
qint32 m_RxLog;
|
||||
qint32 m_nutc0;
|
||||
qint32 m_nrx;
|
||||
qint32 m_hsym0;
|
||||
qint32 m_hsym;
|
||||
qint32 m_paInDevice;
|
||||
qint32 m_paOutDevice;
|
||||
qint32 m_TRperiod;
|
||||
|
@ -205,12 +201,12 @@ private:
|
|||
qint32 m_handshakeIndex;
|
||||
qint32 m_ncw;
|
||||
qint32 m_secID;
|
||||
qint32 m_COMportOpen;
|
||||
qint32 m_iptt;
|
||||
qint32 m_band;
|
||||
qint32 m_repeatMsg;
|
||||
qint32 m_watchdogLimit;
|
||||
qint32 m_poll;
|
||||
qint32 m_fMin;
|
||||
qint32 m_fMax;
|
||||
|
||||
bool m_monitoring;
|
||||
bool m_transmitting;
|
||||
|
@ -221,15 +217,12 @@ private:
|
|||
bool m_auto;
|
||||
bool m_restart;
|
||||
bool m_startAnother;
|
||||
bool m_saveSynced;
|
||||
bool m_saveDecoded;
|
||||
bool m_saveAll;
|
||||
bool m_widebandDecode;
|
||||
bool m_kb8rq;
|
||||
bool m_call3Modified;
|
||||
bool m_dataAvailable;
|
||||
bool m_killAll;
|
||||
bool m_bsynced;
|
||||
bool m_bdecoded;
|
||||
bool m_monitorStartOFF;
|
||||
bool m_pskReporter;
|
||||
|
@ -250,7 +243,6 @@ private:
|
|||
bool m_73TxDisable;
|
||||
bool m_sent73;
|
||||
bool m_runaway;
|
||||
bool m_tx2QSO;
|
||||
bool m_tune;
|
||||
bool m_bRigOpen;
|
||||
bool m_bMultipleOK;
|
||||
|
@ -260,6 +252,10 @@ private:
|
|||
bool m_lockTxFreq;
|
||||
bool m_saveTxPower;
|
||||
bool m_saveComments;
|
||||
bool m_tx2QSO;
|
||||
bool m_CATerror;
|
||||
bool m_bSplit;
|
||||
bool m_bXIT;
|
||||
|
||||
char m_decoded[80];
|
||||
|
||||
|
@ -308,6 +304,7 @@ private:
|
|||
QString m_palette;
|
||||
QString m_dateTime;
|
||||
QString m_mode;
|
||||
QString m_modeTx;
|
||||
QString m_fname;
|
||||
QString m_rpt;
|
||||
QString m_rptSent;
|
||||
|
@ -366,13 +363,15 @@ extern int ptt(int nport, int ntx, int* iptt, int* nopen);
|
|||
|
||||
extern "C" {
|
||||
//----------------------------------------------------- C and Fortran routines
|
||||
void symspec_(int* k, int* ntrperiod, int* nsps, int* ingain,
|
||||
float* px, float s[], float red[],
|
||||
float* df3, int* nhsym, int* npts8);
|
||||
void symspec_(int* k, int* ntrperiod, int* nsps, int* ingain, float* slope,
|
||||
float* px, float s[], float* df3, int* nhsym, int* npts8);
|
||||
|
||||
void genjt9_(char* msg, int* ichk, char* msgsent, int itone[],
|
||||
int* itext, int len1, int len2);
|
||||
|
||||
void gen65_(char* msg, int* ichk, char* msgsent, int itone[],
|
||||
int* itext, int len1, int len2);
|
||||
|
||||
bool stdmsg_(const char* msg, int len);
|
||||
|
||||
void azdist_(char* MyGrid, char* HisGrid, double* utch, int* nAz, int* nEl,
|
||||
|
|
4144
mainwindow.ui
4144
mainwindow.ui
File diff suppressed because it is too large
Load Diff
111
plotter.cpp
111
plotter.cpp
|
@ -15,8 +15,8 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
|
|||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||
|
||||
m_StartFreq = 1000;
|
||||
m_nSpan=1000; //Units: Hz
|
||||
m_StartFreq = 0;
|
||||
m_nSpan=2; //used for FFT bins/pixel
|
||||
m_fSpan=(float)m_nSpan;
|
||||
m_hdivs = HORZ_DIVS;
|
||||
m_FreqUnits = 1;
|
||||
|
@ -27,7 +27,7 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
|
|||
m_ScalePixmap = QPixmap(0,0);
|
||||
m_OverlayPixmap = QPixmap(0,0);
|
||||
m_Size = QSize(0,0);
|
||||
m_fQSO = 1020;
|
||||
m_rxFreq = 1020;
|
||||
m_line = 0;
|
||||
m_fSample = 12000;
|
||||
m_nsps=6912;
|
||||
|
@ -83,7 +83,7 @@ void CPlotter::paintEvent(QPaintEvent *) // paintEvent()
|
|||
m_paintEventBusy=false;
|
||||
}
|
||||
|
||||
void CPlotter::draw(float swide[], float red[], int i0) //draw()
|
||||
void CPlotter::draw(float swide[], int i0) //draw()
|
||||
{
|
||||
int j,y2;
|
||||
float y;
|
||||
|
@ -98,18 +98,18 @@ void CPlotter::draw(float swide[], float red[], int i0) //draw()
|
|||
QPainter painter2D(&m_2DPixmap);
|
||||
|
||||
painter2D.setPen(Qt::green);
|
||||
if(m_bJT9Sync) painter2D.setPen(Qt::red);
|
||||
|
||||
QPoint LineBuf[MAX_SCREENSIZE];
|
||||
j=0;
|
||||
|
||||
int iz=XfromFreq(2000.0);
|
||||
// for(int i=0; i<m_w; i++) {
|
||||
// int iz=XfromFreq(2000.0);
|
||||
int iz=XfromFreq(5000.0);
|
||||
m_fMax=FreqfromX(iz);
|
||||
for(int i=0; i<iz; i++) {
|
||||
if(i>iz) swide[i]=0;
|
||||
y=0.0;
|
||||
if(swide[i]>0.0) y = 10.0*log10(swide[i]);
|
||||
int y1 = 5.0*gain*y + 10*m_plotZero;
|
||||
int y1 = 5.0*gain*y + 10*(m_plotZero-4);
|
||||
if (y1<0) y1=0;
|
||||
if (y1>254) y1=254;
|
||||
if (swide[i]>1.e29) y1=255;
|
||||
|
@ -125,7 +125,7 @@ void CPlotter::draw(float swide[], float red[], int i0) //draw()
|
|||
}
|
||||
y2=gain*6.0*log10(sum/m_binsPerPixel) - 10.0;
|
||||
}
|
||||
if(m_bJT9Sync) y2=3.0*gain*red[i] - 15;
|
||||
y2 += m_plotZero;
|
||||
if(i==iz-1) painter2D.drawPolyline(LineBuf,j);
|
||||
LineBuf[j].setX(i);
|
||||
LineBuf[j].setY(m_h-(y2+0.8*m_h));
|
||||
|
@ -163,7 +163,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||
if(m_OverlayPixmap.isNull()) return;
|
||||
if(m_WaterfallPixmap.isNull()) return;
|
||||
int w = m_WaterfallPixmap.width();
|
||||
int x,y,x1,x2,dx;
|
||||
int x,y,x1,x2;
|
||||
// int nHzDiv[11]={0,50,100,200,200,200,500,500,500,500,500};
|
||||
float pixperdiv;
|
||||
|
||||
|
@ -180,12 +180,15 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||
double df = m_binsPerPixel*m_fftBinWidth;
|
||||
pixperdiv = m_freqPerDiv/df;
|
||||
y = m_h2 - m_h2/VERT_DIVS;
|
||||
m_hdivs = w*df/m_freqPerDiv + 0.9999;
|
||||
for( int i=1; i<m_hdivs; i++) //draw vertical grids
|
||||
{
|
||||
x = (int)( (float)i*pixperdiv );
|
||||
painter.setPen(QPen(Qt::white, 1,Qt::DotLine));
|
||||
painter.drawLine(x, 0, x , y);
|
||||
painter.drawLine(x, m_h2-5, x , m_h2);
|
||||
if(x >= 0 and x<=m_w) {
|
||||
painter.setPen(QPen(Qt::white, 1,Qt::DotLine));
|
||||
painter.drawLine(x, 0, x , y);
|
||||
painter.drawLine(x, m_h2-5, x , m_h2);
|
||||
}
|
||||
}
|
||||
|
||||
pixperdiv = (float)m_h2 / (float)VERT_DIVS;
|
||||
|
@ -258,40 +261,30 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||
}
|
||||
}
|
||||
|
||||
x1=XfromFreq(m_fMin);
|
||||
int bw=9.0*12000.0/m_nsps;
|
||||
dx=XfromFreq(m_fMin+bw) - x1;
|
||||
float bw=9.0*12000.0/m_nsps;
|
||||
if(m_modeTx=="JT65") bw=66.0*11025.0/4096.0;
|
||||
|
||||
QPen pen0(Qt::green, 3); //Mark Rx Freq with green
|
||||
painter0.setPen(pen0);
|
||||
x1=XfromFreq(m_fQSO);
|
||||
x2=x1+dx;
|
||||
x1=XfromFreq(m_rxFreq);
|
||||
x2=XfromFreq(m_rxFreq+bw);
|
||||
painter0.drawLine(x1,24,x1,30);
|
||||
painter0.drawLine(x1,28,x2,28);
|
||||
painter0.drawLine(x2,24,x2,30);
|
||||
|
||||
QPen pen2(Qt::blue, 3); //Mark the decoding range
|
||||
painter0.setPen(pen2);
|
||||
x1=XfromFreq(m_fMin);
|
||||
if(x1<2) x1=2;
|
||||
x2=x1+30;
|
||||
// pen2.setWidth(6);
|
||||
painter0.drawLine(x1,18,x1,28);
|
||||
painter0.drawLine(x1,23,x2,23);
|
||||
painter0.drawLine(x2,23,x2-5,18);
|
||||
painter0.drawLine(x2,23,x2-5,28);
|
||||
x2=XfromFreq(m_fMax);
|
||||
x1=x2-30;
|
||||
// pen2.setWidth(6);
|
||||
painter0.drawLine(x2,18,x2,28);
|
||||
painter0.drawLine(x1,23,x2,23);
|
||||
painter0.drawLine(x1,23,x1+5,18);
|
||||
painter0.drawLine(x1,23,x1+5,28);
|
||||
if(m_mode=="JT9+JT65") {
|
||||
QPen pen2(Qt::blue, 3); //Mark the JT65 | JT9 divider
|
||||
painter0.setPen(pen2);
|
||||
x1=XfromFreq(m_fMin);
|
||||
if(x1<2) x1=2;
|
||||
x2=x1+30;
|
||||
painter0.drawLine(x1,8,x1,28);
|
||||
}
|
||||
|
||||
QPen pen1(Qt::red, 3); //Mark Tx freq with red
|
||||
painter0.setPen(pen1);
|
||||
x1=XfromFreq(m_txFreq);
|
||||
x2=x1+dx;
|
||||
x2=XfromFreq(m_txFreq+bw);
|
||||
painter0.drawLine(x1,17,x1,21);
|
||||
painter0.drawLine(x1,17,x2,17);
|
||||
painter0.drawLine(x2,17,x2,21);
|
||||
|
@ -310,7 +303,7 @@ void CPlotter::MakeFrequencyStrs() //MakeFrequencyStrs
|
|||
int CPlotter::XfromFreq(float f) //XfromFreq()
|
||||
{
|
||||
// float w = m_WaterfallPixmap.width();
|
||||
int x = (int) m_w * (f - m_StartFreq)/m_fSpan;
|
||||
int x = int(m_w * (f - m_StartFreq)/m_fSpan + 0.5);
|
||||
if(x<0 ) return 0;
|
||||
if(x>m_w) return m_w;
|
||||
return x;
|
||||
|
@ -318,7 +311,8 @@ int CPlotter::XfromFreq(float f) //XfromFreq()
|
|||
|
||||
float CPlotter::FreqfromX(int x) //FreqfromX()
|
||||
{
|
||||
return float(1000.0 + x*m_binsPerPixel*m_fftBinWidth);
|
||||
// return float(1000.0 + x*m_binsPerPixel*m_fftBinWidth);
|
||||
return float(x*m_binsPerPixel*m_fftBinWidth);
|
||||
}
|
||||
|
||||
void CPlotter::SetRunningState(bool running) //SetRunningState()
|
||||
|
@ -362,10 +356,9 @@ int CPlotter::plotWidth(){return m_WaterfallPixmap.width();}
|
|||
void CPlotter::UpdateOverlay() {DrawOverlay();}
|
||||
void CPlotter::setDataFromDisk(bool b) {m_dataFromDisk=b;}
|
||||
|
||||
void CPlotter::setRxRange(int fMin, int fMax)
|
||||
void CPlotter::setRxRange(int fMin)
|
||||
{
|
||||
m_fMin=fMin;
|
||||
m_fMax=fMax;
|
||||
}
|
||||
|
||||
void CPlotter::setBinsPerPixel(int n) // set nbpp
|
||||
|
@ -380,43 +373,39 @@ int CPlotter::binsPerPixel() // get nbpp
|
|||
return m_binsPerPixel;
|
||||
}
|
||||
|
||||
void CPlotter::setFQSO(int x, bool bf) //setFQSO()
|
||||
void CPlotter::setRxFreq(int x, bool bf) //setRxFreq()
|
||||
{
|
||||
if(bf) {
|
||||
m_fQSO=x; // x is freq in Hz
|
||||
m_xClick=XfromFreq(m_fQSO);
|
||||
m_rxFreq=x; // x is freq in Hz
|
||||
m_xClick=XfromFreq(m_rxFreq);
|
||||
} else {
|
||||
if(x<0) x=0; // x is pixel number
|
||||
if(x>m_Size.width()) x=m_Size.width();
|
||||
m_fQSO = int(FreqfromX(x)+0.5);
|
||||
m_rxFreq=int(FreqfromX(x)+0.5);
|
||||
m_xClick=x;
|
||||
}
|
||||
emit setFreq1(m_rxFreq,m_txFreq);
|
||||
DrawOverlay();
|
||||
update();
|
||||
}
|
||||
|
||||
void CPlotter::setFcal(int n) //setFcal()
|
||||
{
|
||||
m_fCal=n;
|
||||
}
|
||||
|
||||
int CPlotter::fQSO() {return m_fQSO;} //get fQSO
|
||||
int CPlotter::rxFreq() {return m_rxFreq;} //get rxFreq
|
||||
|
||||
void CPlotter::mousePressEvent(QMouseEvent *event) //mousePressEvent
|
||||
{
|
||||
int x=event->x();
|
||||
setFQSO(x,false); // Wideband waterfall
|
||||
setRxFreq(x,false); // Wideband waterfall
|
||||
bool ctrl = (event->modifiers() & Qt::ControlModifier);
|
||||
int n=1;
|
||||
if(ctrl) n+=100;
|
||||
emit freezeDecode1(n);
|
||||
if(ctrl) setTxFreq(m_fQSO);
|
||||
if(ctrl or m_lockTxFreq) setTxFreq(m_rxFreq);
|
||||
}
|
||||
|
||||
void CPlotter::mouseDoubleClickEvent(QMouseEvent *event) //mouse2click
|
||||
{
|
||||
// int x=event->x();
|
||||
// setFQSO(x,false);
|
||||
// setRxFreq(x,false);
|
||||
bool ctrl = (event->modifiers() & Qt::ControlModifier);
|
||||
int n=2;
|
||||
if(ctrl) n+=100;
|
||||
|
@ -536,6 +525,22 @@ void CPlotter::setNsps(int ntrperiod, int nsps)
|
|||
void CPlotter::setTxFreq(int n) //setTol()
|
||||
{
|
||||
m_txFreq=n;
|
||||
emit setFreq1(m_rxFreq,m_txFreq);
|
||||
DrawOverlay();
|
||||
update();
|
||||
}
|
||||
|
||||
void CPlotter::setMode(QString mode)
|
||||
{
|
||||
m_mode=mode;
|
||||
}
|
||||
|
||||
void CPlotter::setModeTx(QString modeTx)
|
||||
{
|
||||
m_modeTx=modeTx;
|
||||
}
|
||||
|
||||
int CPlotter::getFmax()
|
||||
{
|
||||
return m_fMax;
|
||||
}
|
||||
|
|
36
plotter.h
36
plotter.h
|
@ -30,19 +30,20 @@ public:
|
|||
QSize minimumSizeHint() const;
|
||||
QSize sizeHint() const;
|
||||
QColor m_ColorTbl[256];
|
||||
|
||||
bool m_bCurrent;
|
||||
bool m_bCumulative;
|
||||
bool m_bJT9Sync;
|
||||
int m_plotZero;
|
||||
int m_plotGain;
|
||||
bool m_lockTxFreq;
|
||||
|
||||
float m_fSpan;
|
||||
|
||||
qint32 m_plotZero;
|
||||
qint32 m_plotGain;
|
||||
qint32 m_nSpan;
|
||||
qint32 m_binsPerPixel;
|
||||
qint32 m_fQSO;
|
||||
qint32 m_fCal;
|
||||
qint32 m_w;
|
||||
|
||||
void draw(float sw[], float red[], int i0); //Update the waterfall
|
||||
void draw(float sw[], int i0); //Update the waterfall
|
||||
void SetRunningState(bool running);
|
||||
void setPlotZero(int plotZero);
|
||||
int getPlotZero();
|
||||
|
@ -54,22 +55,25 @@ public:
|
|||
void setNSpan(int n);
|
||||
void UpdateOverlay();
|
||||
void setDataFromDisk(bool b);
|
||||
void setRxRange(int fMin, int fMax);
|
||||
void setRxRange(int fMin);
|
||||
void setBinsPerPixel(int n);
|
||||
int binsPerPixel();
|
||||
void setFQSO(int n, bool bf);
|
||||
void setFcal(int n);
|
||||
void setRxFreq(int n, bool bf);
|
||||
void DrawOverlay();
|
||||
int fQSO();
|
||||
int rxFreq();
|
||||
void setPalette(QString palette);
|
||||
void setFsample(int n);
|
||||
void setNsps(int ntrperiod, int nsps);
|
||||
void setTxFreq(int n);
|
||||
void setMode(QString mode);
|
||||
void setModeTx(QString modeTx);
|
||||
double fGreen();
|
||||
void SetPercent2DScreen(int percent){m_Percent2DScreen=percent;}
|
||||
int getFmax();
|
||||
|
||||
signals:
|
||||
void freezeDecode1(int n);
|
||||
void setFreq1(int rxFreq, int txFreq);
|
||||
|
||||
protected:
|
||||
//re-implemented widget event handlers
|
||||
|
@ -92,16 +96,21 @@ private:
|
|||
QSize m_Size;
|
||||
QString m_Str;
|
||||
QString m_HDivText[483];
|
||||
QString m_mode;
|
||||
QString m_modeTx;
|
||||
|
||||
bool m_Running;
|
||||
bool m_paintEventBusy;
|
||||
bool m_dataFromDisk;
|
||||
|
||||
double m_fGreen;
|
||||
double m_fftBinWidth;
|
||||
|
||||
qint64 m_StartFreq;
|
||||
|
||||
qint32 m_dBStepSize;
|
||||
qint32 m_FreqUnits;
|
||||
qint32 m_hdivs;
|
||||
bool m_dataFromDisk;
|
||||
char m_sutc[6];
|
||||
qint32 m_line;
|
||||
qint32 m_fSample;
|
||||
qint32 m_i0;
|
||||
|
@ -113,10 +122,13 @@ private:
|
|||
qint32 m_h1;
|
||||
qint32 m_h2;
|
||||
qint32 m_TRperiod;
|
||||
qint32 m_rxFreq;
|
||||
qint32 m_txFreq;
|
||||
qint32 m_fMin;
|
||||
qint32 m_fMax;
|
||||
|
||||
char m_sutc[6];
|
||||
|
||||
private slots:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseDoubleClickEvent(QMouseEvent *event);
|
||||
|
|
|
@ -39,10 +39,10 @@ PSK_Reporter::PSK_Reporter(QObject *parent) :
|
|||
|
||||
void PSK_Reporter::setLocalStation(QString call, QString gridSquare, QString programInfo)
|
||||
{
|
||||
m_rxCall = call;
|
||||
m_rxGrid = gridSquare;
|
||||
m_progId = programInfo;
|
||||
reportTimer->start(5*60*1000); // 5 minutes;
|
||||
m_rxCall = call;
|
||||
m_rxGrid = gridSquare;
|
||||
m_progId = programInfo;
|
||||
reportTimer->start(5*60*1000); // 5 minutes;
|
||||
}
|
||||
|
||||
void PSK_Reporter::addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time )
|
||||
|
@ -99,15 +99,6 @@ void PSK_Reporter::sendReport()
|
|||
// Get IP address for pskreporter.info and send report via UDP
|
||||
QHostInfo info = QHostInfo::fromName("report.pskreporter.info");
|
||||
m_udpSocket->writeDatagram(report,info.addresses().at(0),4739);
|
||||
|
||||
/*
|
||||
qDebug() << header_h;
|
||||
qDebug() << m_rxInfoDescriptor_h;
|
||||
qDebug() << m_txInfoDescriptor_h;
|
||||
qDebug() << rxInfoData_h;
|
||||
qDebug() << txInfoData_h;
|
||||
qDebug() << report.toHex();
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
152
rigclass.cpp
152
rigclass.cpp
|
@ -7,7 +7,7 @@
|
|||
* Hamlib C++ interface is a frontend implementing wrapper functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
/**
|
||||
*
|
||||
* Hamlib C++ bindings - main file
|
||||
* Copyright (c) 2001-2003 by Stephane Fillod
|
||||
|
@ -36,7 +36,7 @@
|
|||
#include <hamlib/rig.h>
|
||||
#include "rigclass.h"
|
||||
#include <QDebug>
|
||||
|
||||
#include <QHostAddress>
|
||||
|
||||
static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg);
|
||||
|
||||
|
@ -78,9 +78,16 @@ int Rig::init(rig_model_t rig_model)
|
|||
}
|
||||
|
||||
int Rig::open(int n) {
|
||||
#ifdef WIN32 // Ham radio Deluxe only on Windows
|
||||
m_hrd=(n==9999);
|
||||
if(m_hrd) {
|
||||
m_hrd=false;
|
||||
m_cmndr=false;
|
||||
if(n<9900) {
|
||||
if(n==-99999) return -1; //Silence compiler warning
|
||||
return rig_open(theRig);
|
||||
}
|
||||
|
||||
#ifdef WIN32 // Ham radio Deluxe or Commander (Windows only)
|
||||
if(n==9999) {
|
||||
m_hrd=true;
|
||||
bool bConnect=false;
|
||||
bConnect = HRDInterfaceConnect(L"localhost",7809);
|
||||
if(bConnect) {
|
||||
|
@ -92,12 +99,30 @@ int Rig::open(int n) {
|
|||
m_hrd=false;
|
||||
return -1;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if(n==-99999) return -1; //Silence compiler warning
|
||||
return rig_open(theRig);
|
||||
}
|
||||
if(n==9998) {
|
||||
socket->connectToHost(QHostAddress::LocalHost, 52002);
|
||||
if(!socket->waitForConnected(1000)) {
|
||||
return -1;
|
||||
}
|
||||
QString t;
|
||||
// qint32 nkHz=14076;
|
||||
// t.sprintf("<command:10>CmdSetFreq<parameters:17><xcvrfreq:5>%5d",nkHz);
|
||||
t="<command:10>CmdGetFreq<parameters:0>";
|
||||
QByteArray ba = t.toLocal8Bit();
|
||||
const char* buf=ba.data();
|
||||
socket->write(buf);
|
||||
socket->waitForReadyRead(1000);
|
||||
QByteArray reply=socket->read(128);
|
||||
if(reply.indexOf("<CmdFreq:10>")==0) {
|
||||
// qDebug() << "Freq:" << reply;
|
||||
// qDebug() << "Connected to Commander";
|
||||
m_cmndr=true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Rig::close(void) {
|
||||
|
@ -105,6 +130,9 @@ int Rig::close(void) {
|
|||
if(m_hrd) {
|
||||
HRDInterfaceDisconnect();
|
||||
return 0;
|
||||
} else if(m_cmndr) {
|
||||
socket->close();
|
||||
return 0;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -132,13 +160,70 @@ int Rig::setFreq(freq_t freq, vfo_t vfo) {
|
|||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if(m_cmndr) {
|
||||
QString t;
|
||||
qint32 nkHz=int(0.001*freq);
|
||||
t.sprintf("<command:10>CmdSetFreq<parameters:17><xcvrfreq:5>%5d",nkHz);
|
||||
QByteArray ba = t.toLocal8Bit();
|
||||
const char* buf=ba.data();
|
||||
socket->write(buf);
|
||||
socket->waitForBytesWritten(1000);
|
||||
return 0;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
{
|
||||
return rig_set_freq(theRig, vfo, freq);
|
||||
}
|
||||
}
|
||||
|
||||
int Rig::setXit(shortfreq_t xit, vfo_t vfo)
|
||||
{
|
||||
return rig_set_xit(theRig, vfo, xit);
|
||||
}
|
||||
|
||||
int Rig::setVFO(vfo_t vfo)
|
||||
{
|
||||
return rig_set_vfo(theRig, vfo);
|
||||
}
|
||||
|
||||
vfo_t Rig::getVFO()
|
||||
{
|
||||
vfo_t vfo;
|
||||
rig_get_vfo(theRig, &vfo);
|
||||
return vfo;
|
||||
}
|
||||
|
||||
int Rig::setSplitFreq(freq_t tx_freq, vfo_t vfo) {
|
||||
#ifdef WIN32 // Ham Radio Deluxe only on Windows
|
||||
if(m_hrd) {
|
||||
QString t;
|
||||
int nhz=(int)tx_freq;
|
||||
t=m_context + "Set Frequency-Hz " + QString::number(nhz);
|
||||
const wchar_t* cmnd = (const wchar_t*) t.utf16();
|
||||
const wchar_t* result=HRDInterfaceSendMessage(cmnd);
|
||||
QString t2=QString::fromWCharArray (result,-1);
|
||||
HRDInterfaceFreeString(result);
|
||||
if(t2=="OK") {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if(m_cmndr) {
|
||||
QString t;
|
||||
qint32 nkHz=int(0.001*tx_freq);
|
||||
t.sprintf("<command:12>CmdSetTxFreq<parameters:17><xcvrfreq:5>%5d",nkHz);
|
||||
QByteArray ba = t.toLocal8Bit();
|
||||
const char* buf=ba.data();
|
||||
socket->write(buf);
|
||||
socket->waitForBytesWritten(1000);
|
||||
return 0;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
return rig_set_split_freq(theRig, vfo, tx_freq);
|
||||
}
|
||||
}
|
||||
|
||||
freq_t Rig::getFreq(vfo_t vfo)
|
||||
{
|
||||
freq_t freq;
|
||||
|
@ -150,10 +235,29 @@ freq_t Rig::getFreq(vfo_t vfo)
|
|||
HRDInterfaceFreeString(freqString);
|
||||
freq=t2.toDouble();
|
||||
return freq;
|
||||
} else if(m_cmndr) {
|
||||
QString t;
|
||||
t="<command:10>CmdGetFreq<parameters:0>";
|
||||
QByteArray ba = t.toLocal8Bit();
|
||||
const char* buf=ba.data();
|
||||
socket->write(buf);
|
||||
socket->waitForReadyRead(1000);
|
||||
QByteArray reply=socket->read(128);
|
||||
QString t2(reply);
|
||||
if(t2.indexOf("<CmdFreq:")==0) {
|
||||
int i1=t2.indexOf(">");
|
||||
t2=t2.mid(i1+1).replace(",","");
|
||||
freq=1000.0*t2.toDouble();
|
||||
return freq;
|
||||
} else {
|
||||
return -1.0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
rig_get_freq(theRig, vfo, &freq);
|
||||
{
|
||||
int iret=rig_get_freq(theRig, vfo, &freq);
|
||||
// iret should be 0. Negative values mean rig_get_freq() failed.
|
||||
if(iret<0) freq=-1.0;
|
||||
return freq;
|
||||
}
|
||||
}
|
||||
|
@ -168,18 +272,6 @@ rmode_t Rig::getMode(pbwidth_t& width, vfo_t vfo) {
|
|||
return mode;
|
||||
}
|
||||
|
||||
int Rig::setVFO(vfo_t vfo)
|
||||
{
|
||||
return rig_set_vfo(theRig, vfo);
|
||||
}
|
||||
|
||||
vfo_t Rig::getVFO()
|
||||
{
|
||||
vfo_t vfo;
|
||||
rig_get_vfo(theRig, &vfo);
|
||||
return vfo;
|
||||
}
|
||||
|
||||
int Rig::setPTT(ptt_t ptt, vfo_t vfo)
|
||||
{
|
||||
#ifdef WIN32 // Ham Radio Deluxe only on Windows
|
||||
|
@ -201,6 +293,16 @@ int Rig::setPTT(ptt_t ptt, vfo_t vfo)
|
|||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if(m_cmndr) {
|
||||
QString t;
|
||||
if(ptt==0) t="<command:5>CmdRX<parameters:0>";
|
||||
if(ptt>0) t="<command:5>CmdTX<parameters:0>";
|
||||
QByteArray ba = t.toLocal8Bit();
|
||||
const char* buf=ba.data();
|
||||
socket->write(buf);
|
||||
socket->waitForBytesWritten(1000);
|
||||
// qDebug() << ptt << buf;
|
||||
return 0;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
|
10
rigclass.h
10
rigclass.h
|
@ -25,15 +25,18 @@
|
|||
#include <hamlib/rig.h>
|
||||
#include <iostream>
|
||||
#include <QString>
|
||||
#include <QTcpSocket>
|
||||
|
||||
extern QTcpSocket* socket;
|
||||
|
||||
class BACKEND_IMPEXP Rig {
|
||||
private:
|
||||
RIG* theRig; // Global ref. to the rig
|
||||
#ifdef WIN32 // Ham Radio Deluxe only on Windows
|
||||
bool m_hrd;
|
||||
#endif
|
||||
bool m_cmndr;
|
||||
QString m_context;
|
||||
|
||||
|
||||
protected:
|
||||
public:
|
||||
Rig();
|
||||
|
@ -59,7 +62,8 @@ public:
|
|||
rmode_t getMode(pbwidth_t&, vfo_t vfo = RIG_VFO_CURR);
|
||||
int setVFO(vfo_t);
|
||||
vfo_t getVFO();
|
||||
|
||||
int setXit(shortfreq_t xit, vfo_t vfo);
|
||||
int setSplitFreq(freq_t tx_freq, vfo_t vfo = RIG_VFO_CURR);
|
||||
int setPTT (ptt_t ptt, vfo_t vfo = RIG_VFO_CURR);
|
||||
ptt_t getPTT (vfo_t vfo = RIG_VFO_CURR);
|
||||
|
||||
|
|
11
soundin.cpp
11
soundin.cpp
|
@ -2,7 +2,8 @@
|
|||
#include <stdexcept>
|
||||
|
||||
#define FRAMES_PER_BUFFER 1024
|
||||
#define NSMAX 1365
|
||||
//#define NSMAX 1365
|
||||
#define NSMAX 6827
|
||||
#define NTMAX 120
|
||||
|
||||
extern "C" {
|
||||
|
@ -10,7 +11,7 @@ extern "C" {
|
|||
extern struct {
|
||||
float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran
|
||||
float savg[NSMAX];
|
||||
float c0[2*NTMAX*1500];
|
||||
// float c0[2*NTMAX*1500];
|
||||
short int d2[NTMAX*12000];
|
||||
int nutc; //UTC as integer, HHMM
|
||||
int ndiskdat; //1 ==> data read from *.wav file
|
||||
|
@ -26,8 +27,8 @@ extern struct {
|
|||
int nsave;
|
||||
int nagain;
|
||||
int ndepth;
|
||||
int nrxlog;
|
||||
int nfsample;
|
||||
int ntxmode;
|
||||
int nmode;
|
||||
char datetime[20];
|
||||
} jt9com_;
|
||||
}
|
||||
|
@ -60,7 +61,7 @@ extern "C" int a2dCallback( const void *inputBuffer, void *outputBuffer,
|
|||
|
||||
udata->ncall++;
|
||||
if( (statusFlags&paInputOverflow) != 0) {
|
||||
qDebug() << "Input Overflow";
|
||||
qDebug() << "Input Overflow in a2dCallback";
|
||||
}
|
||||
if(udata->bzero) { //Start of a new Rx sequence
|
||||
udata->kin=0; //Reset buffer pointer
|
||||
|
|
52
soundout.cpp
52
soundout.cpp
|
@ -7,7 +7,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
extern float gran(); //Noise generator (for tests only)
|
||||
extern int itone[85]; //Tx audio tones for 85 symbols
|
||||
extern int itone[126]; //Audio tones for all Tx symbols
|
||||
extern int icw[250]; //Dits for CW ID
|
||||
extern int outBufSize;
|
||||
extern bool btxok;
|
||||
|
@ -17,10 +17,12 @@ extern double outputLatency;
|
|||
typedef struct //Parameters sent to or received from callback function
|
||||
{
|
||||
double txsnrdb;
|
||||
int nsps;
|
||||
double dnsps;
|
||||
int ntrperiod;
|
||||
int ntxfreq;
|
||||
int xit;
|
||||
int ncall;
|
||||
int nsym;
|
||||
bool txMute;
|
||||
bool bRestart;
|
||||
bool btune;
|
||||
|
@ -45,6 +47,7 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
|
|||
static double fac;
|
||||
static double amp;
|
||||
static int ic=0,j=0;
|
||||
static int isym0=-999;
|
||||
static short int i2;
|
||||
int isym,nspd;
|
||||
|
||||
|
@ -58,7 +61,7 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
|
|||
udata->bRestart=false;
|
||||
srand(mstr); //Initialize random seed
|
||||
}
|
||||
isym=ic/(4*udata->nsps); //Actual fsample=48000
|
||||
isym=ic/(4.0*udata->dnsps); //Actual fsample=48000
|
||||
if(udata->btune) isym=0; //If tuning, send pure tone
|
||||
if(udata->txsnrdb < 0.0) {
|
||||
snr=pow(10.0,0.05*(udata->txsnrdb-6.0));
|
||||
|
@ -66,14 +69,15 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
|
|||
if(snr>1.0) fac=3000.0/snr;
|
||||
}
|
||||
|
||||
if(isym>=85 and icw[0]>0) { //Output the CW ID
|
||||
freq=udata->ntxfreq;
|
||||
if(isym>=udata->nsym and icw[0]>0) { //Output the CW ID
|
||||
freq=udata->ntxfreq - udata->xit;
|
||||
dphi=twopi*freq/48000.0;
|
||||
|
||||
// float wpm=20.0;
|
||||
// int nspd=1.2*48000.0/wpm;
|
||||
// nspd=3072; //18.75 WPM
|
||||
nspd=2048 + 512; //22.5 WPM
|
||||
int ic0=85*4*udata->nsps;
|
||||
int ic0=udata->nsym*4*udata->dnsps;
|
||||
for(uint i=0 ; i<framesToProcess; i++ ) {
|
||||
phi += dphi;
|
||||
if(phi>twopi) phi -= twopi;
|
||||
|
@ -99,17 +103,22 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
|
|||
return paContinue;
|
||||
}
|
||||
|
||||
baud=12000.0/udata->nsps;
|
||||
freq=udata->ntxfreq + itone[isym]*baud;
|
||||
dphi=twopi*freq/48000.0;
|
||||
baud=12000.0/udata->dnsps;
|
||||
amp=32767.0;
|
||||
int i0=84.983*4.0*udata->nsps;
|
||||
int i1=85*4*udata->nsps;
|
||||
int i0=(udata->nsym-0.017)*4.0*udata->dnsps;
|
||||
int i1=udata->nsym*4.0*udata->dnsps;
|
||||
if(udata->btune) { //If tuning, no ramp down
|
||||
i0=999*udata->nsps;
|
||||
i0=999*udata->dnsps;
|
||||
i1=i0;
|
||||
}
|
||||
for(uint i=0 ; i<framesToProcess; i++ ) {
|
||||
isym=ic/(4.0*udata->dnsps); //Actual fsample=48000
|
||||
if(udata->btune) isym=0; //If tuning, send pure tone
|
||||
if(isym!=isym0) {
|
||||
freq=udata->ntxfreq + itone[isym]*baud - udata->xit;
|
||||
dphi=twopi*freq/48000.0;
|
||||
isym0=isym;
|
||||
}
|
||||
phi += dphi;
|
||||
if(phi>twopi) phi -= twopi;
|
||||
if(ic>i0) amp=0.98*amp;
|
||||
|
@ -160,9 +169,15 @@ void SoundOutThread::run()
|
|||
}
|
||||
|
||||
udata.txsnrdb=99.0;
|
||||
udata.nsps=m_nsps;
|
||||
udata.dnsps=m_nsps;
|
||||
udata.nsym=85;
|
||||
if(m_modeTx=="JT65") {
|
||||
udata.dnsps=4096.0*12000.0/11025.0;
|
||||
udata.nsym=126;
|
||||
}
|
||||
udata.ntrperiod=m_TRperiod;
|
||||
udata.ntxfreq=m_txFreq;
|
||||
udata.xit=m_xit;
|
||||
udata.ncall=0;
|
||||
udata.txMute=m_txMute;
|
||||
udata.bRestart=true;
|
||||
|
@ -193,7 +208,12 @@ void SoundOutThread::run()
|
|||
if (qe) break;
|
||||
|
||||
udata.txsnrdb=m_txsnrdb;
|
||||
udata.nsps=m_nsps;
|
||||
udata.dnsps=m_nsps;
|
||||
udata.nsym=85;
|
||||
if(m_modeTx=="JT65") {
|
||||
udata.dnsps=4096.0*12000.0/11025.0;
|
||||
udata.nsym=126;
|
||||
}
|
||||
udata.ntrperiod=m_TRperiod;
|
||||
udata.ntxfreq=m_txFreq;
|
||||
udata.txMute=m_txMute;
|
||||
|
@ -227,6 +247,10 @@ void SoundOutThread::setTxFreq(int n)
|
|||
m_txFreq=n;
|
||||
}
|
||||
|
||||
void SoundOutThread::setXIT(int n)
|
||||
{
|
||||
m_xit=n;
|
||||
}
|
||||
|
||||
void SoundOutThread::setTxSNR(double snr)
|
||||
{
|
||||
|
|
|
@ -27,19 +27,24 @@ public:
|
|||
void setOutputDevice(qint32 n);
|
||||
void setPeriod(int ntrperiod, int nsps);
|
||||
void setTxFreq(int n);
|
||||
void setXIT(int n);
|
||||
void setTxSNR(double snr);
|
||||
void setTune(bool b);
|
||||
double samFacOut();
|
||||
bool quitExecution; //If true, thread exits gracefully
|
||||
QString m_modeTx;
|
||||
|
||||
// Private members
|
||||
private:
|
||||
double m_txsnrdb; //if < 0, add noise to Tx audio
|
||||
double m_SamFacOut; //(Output sample rate)/48000.0
|
||||
|
||||
qint32 m_nDevOut; //Output device number
|
||||
qint32 m_TRperiod; //T/R period (s)
|
||||
qint32 m_nsps; //Samples per symbol (at 12000 Hz)
|
||||
qint32 m_txFreq;
|
||||
qint32 m_xit;
|
||||
|
||||
bool m_txOK; //Enable Tx audio
|
||||
bool m_txMute; //Mute temporarily
|
||||
bool m_tune;
|
||||
|
|
109
widegraph.cpp
109
widegraph.cpp
|
@ -18,7 +18,10 @@ WideGraph::WideGraph(QWidget *parent) :
|
|||
connect(ui->widePlot, SIGNAL(freezeDecode1(int)),this,
|
||||
SLOT(wideFreezeDecode(int)));
|
||||
|
||||
m_fMin=1000;
|
||||
connect(ui->widePlot, SIGNAL(setFreq1(int,int)),this,
|
||||
SLOT(setFreq2(int,int)));
|
||||
|
||||
m_fMin=3000;
|
||||
ui->fMinSpinBox->setValue(m_fMin);
|
||||
|
||||
//Restore user's settings
|
||||
|
@ -39,15 +42,13 @@ WideGraph::WideGraph(QWidget *parent) :
|
|||
m_waterfallAvg = settings.value("WaterfallAvg",5).toInt();
|
||||
ui->waterfallAvgSpinBox->setValue(m_waterfallAvg);
|
||||
ui->widePlot->m_bCurrent=settings.value("Current",false).toBool();
|
||||
ui->widePlot->m_bCumulative=settings.value("Cumulative",false).toBool();
|
||||
ui->widePlot->m_bJT9Sync=settings.value("JT9Sync",true).toBool();
|
||||
ui->widePlot->m_bCumulative=settings.value("Cumulative",true).toBool();
|
||||
if(ui->widePlot->m_bCurrent) ui->spec2dComboBox->setCurrentIndex(0);
|
||||
if(ui->widePlot->m_bCumulative) ui->spec2dComboBox->setCurrentIndex(1);
|
||||
if(ui->widePlot->m_bJT9Sync) ui->spec2dComboBox->setCurrentIndex(2);
|
||||
int nbpp=settings.value("BinsPerPixel",2).toInt();
|
||||
ui->widePlot->setBinsPerPixel(nbpp);
|
||||
m_qsoFreq=settings.value("QSOfreq",1500).toInt();
|
||||
ui->widePlot->setFQSO(m_qsoFreq,true);
|
||||
m_slope=settings.value("Slope",0.0).toDouble();
|
||||
ui->slopeSpinBox->setValue(m_slope);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
|
@ -72,18 +73,16 @@ void WideGraph::saveSettings()
|
|||
settings.setValue("WaterfallAvg",ui->waterfallAvgSpinBox->value());
|
||||
settings.setValue("Current",ui->widePlot->m_bCurrent);
|
||||
settings.setValue("Cumulative",ui->widePlot->m_bCumulative);
|
||||
settings.setValue("JT9Sync",ui->widePlot->m_bJT9Sync);
|
||||
settings.setValue("BinsPerPixel",ui->widePlot->binsPerPixel());
|
||||
settings.setValue("QSOfreq",ui->widePlot->fQSO());
|
||||
settings.setValue("Slope",m_slope);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void WideGraph::dataSink2(float s[], float red[], float df3, int ihsym,
|
||||
void WideGraph::dataSink2(float s[], float df3, int ihsym,
|
||||
int ndiskdata)
|
||||
{
|
||||
static float splot[NSMAX];
|
||||
static float swide[2048];
|
||||
static float rwide[2048];
|
||||
int nbpp = ui->widePlot->binsPerPixel();
|
||||
static int n=0;
|
||||
|
||||
|
@ -105,18 +104,14 @@ void WideGraph::dataSink2(float s[], float red[], float df3, int ihsym,
|
|||
// int w=ui->widePlot->plotWidth();
|
||||
int i0=-1; //###
|
||||
int i=i0;
|
||||
int jz=1000.0/df3;
|
||||
int jz=5000.0/(nbpp*df3);
|
||||
for (int j=0; j<jz; j++) {
|
||||
float sum=0;
|
||||
float rsum=0;
|
||||
for (int k=0; k<nbpp; k++) {
|
||||
i++;
|
||||
sum += splot[i];
|
||||
rsum += red[i];
|
||||
}
|
||||
swide[j]=sum;
|
||||
rwide[j]=rsum/nbpp;
|
||||
// if(lstrong[1 + i/32]!=0) swide[j]=-smax; //Tag strong signals
|
||||
}
|
||||
|
||||
// Time according to this computer
|
||||
|
@ -128,7 +123,7 @@ void WideGraph::dataSink2(float s[], float red[], float df3, int ihsym,
|
|||
}
|
||||
}
|
||||
m_ntr0=ntr;
|
||||
ui->widePlot->draw(swide,rwide,i0);
|
||||
ui->widePlot->draw(swide,i0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,16 +167,16 @@ void WideGraph::keyPressEvent(QKeyEvent *e)
|
|||
}
|
||||
}
|
||||
|
||||
void WideGraph::setQSOfreq(int n)
|
||||
void WideGraph::setRxFreq(int n)
|
||||
{
|
||||
m_qsoFreq=n;
|
||||
ui->widePlot->setFQSO(m_qsoFreq,true);
|
||||
if(m_lockTxFreq) setTxFreq(m_qsoFreq);
|
||||
m_rxFreq=n;
|
||||
ui->widePlot->setRxFreq(m_rxFreq,true);
|
||||
if(m_lockTxFreq) setTxFreq(m_rxFreq);
|
||||
}
|
||||
|
||||
int WideGraph::QSOfreq()
|
||||
int WideGraph::rxFreq()
|
||||
{
|
||||
return ui->widePlot->fQSO();
|
||||
return ui->widePlot->rxFreq();
|
||||
}
|
||||
|
||||
int WideGraph::nSpan()
|
||||
|
@ -204,9 +199,9 @@ void WideGraph::wideFreezeDecode(int n)
|
|||
emit freezeDecode2(n);
|
||||
}
|
||||
|
||||
void WideGraph::setRxRange(int fMin, int fMax)
|
||||
void WideGraph::setRxRange(int fMin)
|
||||
{
|
||||
ui->widePlot->setRxRange(fMin,fMax);
|
||||
ui->widePlot->setRxRange(fMin);
|
||||
ui->widePlot->DrawOverlay();
|
||||
ui->widePlot->update();
|
||||
}
|
||||
|
@ -218,19 +213,16 @@ int WideGraph::getFmin()
|
|||
|
||||
int WideGraph::getFmax()
|
||||
{
|
||||
return m_fMax;
|
||||
int n=ui->widePlot->getFmax();
|
||||
if(n>5000) n=5000;
|
||||
return n;
|
||||
}
|
||||
|
||||
void WideGraph::setfMax(int n)
|
||||
void WideGraph::setFmin(int n)
|
||||
{
|
||||
m_fMax = n;
|
||||
setRxRange(m_fMin,m_fMax);
|
||||
}
|
||||
|
||||
void WideGraph::setFcal(int n)
|
||||
{
|
||||
m_fCal=n;
|
||||
ui->widePlot->setFcal(n);
|
||||
m_fMin = n;
|
||||
ui->fMinSpinBox->setValue(n);
|
||||
setRxRange(m_fMin);
|
||||
}
|
||||
|
||||
void WideGraph::setPalette(QString palette)
|
||||
|
@ -252,28 +244,65 @@ void WideGraph::setPeriod(int ntrperiod, int nsps)
|
|||
|
||||
void WideGraph::setTxFreq(int n)
|
||||
{
|
||||
emit setXIT2(n);
|
||||
ui->widePlot->setTxFreq(n);
|
||||
}
|
||||
|
||||
void WideGraph::setMode(QString mode)
|
||||
{
|
||||
m_mode=mode;
|
||||
ui->fMinSpinBox->setEnabled(m_mode=="JT9+JT65");
|
||||
ui->widePlot->setMode(mode);
|
||||
ui->widePlot->DrawOverlay();
|
||||
ui->widePlot->update();
|
||||
}
|
||||
|
||||
void WideGraph::setModeTx(QString modeTx)
|
||||
{
|
||||
m_modeTx=modeTx;
|
||||
ui->widePlot->setModeTx(modeTx);
|
||||
ui->widePlot->DrawOverlay();
|
||||
ui->widePlot->update();
|
||||
}
|
||||
|
||||
void WideGraph::on_spec2dComboBox_currentIndexChanged(const QString &arg1)
|
||||
{
|
||||
ui->widePlot->m_bCurrent=false;
|
||||
ui->widePlot->m_bCumulative=false;
|
||||
ui->widePlot->m_bJT9Sync=false;
|
||||
if(arg1=="Current") ui->widePlot->m_bCurrent=true;
|
||||
if(arg1=="Cumulative") ui->widePlot->m_bCumulative=true;
|
||||
if(arg1=="JT9 Sync") ui->widePlot->m_bJT9Sync=true;
|
||||
}
|
||||
|
||||
void WideGraph::on_fMinSpinBox_valueChanged(int n)
|
||||
{
|
||||
m_fMin=n;
|
||||
setRxRange(m_fMin,m_fMax);
|
||||
setRxRange(m_fMin);
|
||||
}
|
||||
|
||||
void WideGraph::on_fMaxSpinBox_valueChanged(int n)
|
||||
void WideGraph::on_slopeSpinBox_valueChanged(double d)
|
||||
{
|
||||
m_fMax=n;
|
||||
setRxRange(m_fMin,m_fMax);
|
||||
m_slope=d;
|
||||
}
|
||||
|
||||
void WideGraph::setSlope(double d)
|
||||
{
|
||||
m_slope=d;
|
||||
ui->slopeSpinBox->setValue(d);
|
||||
}
|
||||
|
||||
void WideGraph::setLockTxFreq(bool b)
|
||||
{
|
||||
m_lockTxFreq=b;
|
||||
ui->widePlot->m_lockTxFreq=b;
|
||||
}
|
||||
double WideGraph::getSlope()
|
||||
{
|
||||
return m_slope;
|
||||
}
|
||||
|
||||
void WideGraph::setFreq2(int rxFreq, int txFreq)
|
||||
{
|
||||
m_rxFreq=rxFreq;
|
||||
m_txFreq=txFreq;
|
||||
emit setFreq3(rxFreq,txFreq);
|
||||
}
|
||||
|
|
34
widegraph.h
34
widegraph.h
|
@ -14,34 +14,40 @@ public:
|
|||
explicit WideGraph(QWidget *parent = 0);
|
||||
~WideGraph();
|
||||
|
||||
void dataSink2(float s[], float red[], float df3, int ihsym,
|
||||
int ndiskdata);
|
||||
void setQSOfreq(int n);
|
||||
int QSOfreq();
|
||||
void dataSink2(float s[], float df3, int ihsym, int ndiskdata);
|
||||
void setRxFreq(int n);
|
||||
int rxFreq();
|
||||
int nSpan();
|
||||
int nStartFreq();
|
||||
int getFmin();
|
||||
int getFmax();
|
||||
float fSpan();
|
||||
void saveSettings();
|
||||
void setRxRange(int fMin, int fMax);
|
||||
void setfMax(int n);
|
||||
void setFcal(int n);
|
||||
void setRxRange(int fMin);
|
||||
void setFmin(int n);
|
||||
void setPalette(QString palette);
|
||||
void setFsample(int n);
|
||||
void setPeriod(int ntrperiod, int nsps);
|
||||
void setTxFreq(int n);
|
||||
void setMode(QString mode);
|
||||
void setModeTx(QString modeTx);
|
||||
void setSlope(double d);
|
||||
void setLockTxFreq(bool b);
|
||||
double getSlope();
|
||||
double fGreen();
|
||||
|
||||
qint32 m_qsoFreq;
|
||||
bool m_lockTxFreq;
|
||||
qint32 m_rxFreq;
|
||||
qint32 m_txFreq;
|
||||
|
||||
signals:
|
||||
void freezeDecode2(int n);
|
||||
void f11f12(int n);
|
||||
void setXIT2(int n);
|
||||
void setFreq3(int rxFreq, int txFreq);
|
||||
|
||||
public slots:
|
||||
void wideFreezeDecode(int n);
|
||||
void setFreq2(int rxFreq, int txFreq);
|
||||
|
||||
protected:
|
||||
virtual void keyPressEvent( QKeyEvent *e );
|
||||
|
@ -53,11 +59,12 @@ private slots:
|
|||
void on_gainSpinBox_valueChanged(int arg1);
|
||||
void on_spec2dComboBox_currentIndexChanged(const QString &arg1);
|
||||
void on_fMinSpinBox_valueChanged(int n);
|
||||
void on_fMaxSpinBox_valueChanged(int n);
|
||||
void on_slopeSpinBox_valueChanged(double d);
|
||||
|
||||
private:
|
||||
double m_slope;
|
||||
|
||||
qint32 m_waterfallAvg;
|
||||
qint32 m_fCal;
|
||||
qint32 m_fSample;
|
||||
qint32 m_TRperiod;
|
||||
qint32 m_nsps;
|
||||
|
@ -65,6 +72,11 @@ private:
|
|||
qint32 m_fMin;
|
||||
qint32 m_fMax;
|
||||
|
||||
bool m_lockTxFreq;
|
||||
|
||||
QString m_mode;
|
||||
QString m_modeTx;
|
||||
|
||||
Ui::WideGraph *ui;
|
||||
};
|
||||
|
||||
|
|
233
widegraph.ui
233
widegraph.ui
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>712</width>
|
||||
<width>799</width>
|
||||
<height>326</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -68,25 +68,6 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>FFT Bins/Pixel</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="freqSpanSpinBox">
|
||||
<property name="sizePolicy">
|
||||
|
@ -97,7 +78,7 @@
|
|||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<width>110</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
|
@ -113,6 +94,9 @@
|
|||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Bins/Pixel </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
|
@ -143,25 +127,6 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N Avg</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="waterfallAvgSpinBox">
|
||||
<property name="sizePolicy">
|
||||
|
@ -172,7 +137,7 @@
|
|||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
|
@ -185,6 +150,9 @@
|
|||
<property name="toolTip">
|
||||
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>N Avg </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
|
@ -210,26 +178,13 @@
|
|||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="maximumSize">
|
||||
<widget class="QSpinBox" name="gainSpinBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>25</height>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Gain</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="gainSpinBox">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>38</width>
|
||||
|
@ -239,6 +194,9 @@
|
|||
<property name="toolTip">
|
||||
<string>Scaling (dB) applied to spectra before plotting</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Gain </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-20</number>
|
||||
</property>
|
||||
|
@ -264,26 +222,13 @@
|
|||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="maximumSize">
|
||||
<widget class="QSpinBox" name="zeroSpinBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>25</height>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Zero</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="zeroSpinBox">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>38</width>
|
||||
|
@ -293,6 +238,12 @@
|
|||
<property name="toolTip">
|
||||
<string>Constant offset applied to waterfall data</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Zero </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-100</number>
|
||||
</property>
|
||||
|
@ -301,6 +252,31 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="slopeSpinBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Slope </string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-2.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>2.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
@ -317,25 +293,6 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>f Min</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="fMinSpinBox">
|
||||
<property name="sizePolicy">
|
||||
|
@ -344,17 +301,32 @@
|
|||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>110</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Minimum frequency for wideband decodes</string>
|
||||
<string>Decode JT65 below this frequency, JT9 above</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> JT9</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>JT65 </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1000</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2000</number>
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>50</number>
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -374,66 +346,6 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>f Max</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="fMaxSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Maximum frequency for wideband decodes</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>8</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="spec2dComboBox">
|
||||
<property name="toolTip">
|
||||
|
@ -452,11 +364,6 @@
|
|||
<string>Cumulative</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>JT9 Sync</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
39
wsjtx.iss
39
wsjtx.iss
|
@ -1,26 +1,29 @@
|
|||
[Setup]
|
||||
AppName=wsjtx
|
||||
AppVerName=wsjtx Version 1.0.0 r3323
|
||||
AppVerName=wsjtx Version 1.0.0 r3461
|
||||
AppCopyright=Copyright (C) 2001-2013 by Joe Taylor, K1JT
|
||||
DefaultDirName=c:\wsjtx
|
||||
DefaultGroupName=wsjtx
|
||||
DefaultDirName=c:\wsjtx2
|
||||
DefaultGroupName=wsjtx2
|
||||
|
||||
[Files]
|
||||
Source: "c:\Users\joe\wsjt\wsjtx_install\wsjtx.exe"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt\wsjtx_install\jt9.exe"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt\wsjtx\lib\jt9code.exe"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt\wsjtx_install\rigctl.exe"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt\wsjtx_install\wsjt.ico"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt\wsjtx_install\afmhot.dat"; DestDir: "{app}";
|
||||
Source: "c:\Users\joe\wsjt\wsjtx_install\blue.dat"; DestDir: "{app}";
|
||||
Source: "c:\Users\joe\wsjt\wsjtx_install\CALL3.TXT"; DestDir: "{app}"; Flags: onlyifdoesntexist
|
||||
Source: "c:\Users\joe\wsjt\QtSupport\*.dll"; DestDir: "{app}";
|
||||
Source: "c:\Users\joe\wsjt\wsjtx\shortcuts.txt"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt\wsjtx\mouse_commands.txt"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt\wsjtx\WSJT-X_Users_Guide.pdf"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt\wsjtx_install\save\Samples\130418_1742.wav"; DestDir: "{app}\save\Samples";
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\wsjtx.exe"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\jt9.exe"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx\lib\jt9code.exe"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\rigctl.exe"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\kvasd.exe"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\wsjt.ico"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\afmhot.dat"; DestDir: "{app}";
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\blue.dat"; DestDir: "{app}";
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\CALL3.TXT"; DestDir: "{app}"; Flags: onlyifdoesntexist
|
||||
Source: "c:\Users\joe\wsjt\QtSupport\*.dll"; DestDir: "{app}";
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx\shortcuts.txt"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx\mouse_commands.txt"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt\wsjtx\WSJT-X_Users_Guide.pdf"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx\WSJT-X_1.1_Quick_Start.pdf"; DestDir: "{app}"
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\save\Samples\130418_1742.wav"; DestDir: "{app}\save\Samples";
|
||||
Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\save\Samples\130610_2343.wav"; DestDir: "{app}\save\Samples";
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\wsjtx"; Filename: "{app}\wsjtx.exe"; WorkingDir: {app}; IconFilename: {app}\wsjt.ico
|
||||
Name: "{userdesktop}\wsjtx"; Filename: "{app}\wsjtx.exe"; WorkingDir: {app}; IconFilename: {app}\wsjt.ico
|
||||
Name: "{group}\wsjtx2"; Filename: "{app}\wsjtx.exe"; WorkingDir: {app}; IconFilename: {app}\wsjt.ico
|
||||
Name: "{userdesktop}\wsjtx2"; Filename: "{app}\wsjtx.exe"; WorkingDir: {app}; IconFilename: {app}\wsjt.ico
|
||||
|
||||
|
|
20
wsjtx.pro
20
wsjtx.pro
|
@ -6,13 +6,12 @@
|
|||
|
||||
QT += core gui network
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
CONFIG += qwt thread
|
||||
CONFIG += thread
|
||||
#CONFIG += console
|
||||
|
||||
TARGET = wsjtx
|
||||
DESTDIR = ../wsjtx_install
|
||||
#DESTDIR = ../qt5_install
|
||||
VERSION = 0.99
|
||||
VERSION = 1.1
|
||||
TEMPLATE = app
|
||||
DEFINES = QT4
|
||||
|
||||
|
@ -57,27 +56,22 @@ FORMS += mainwindow.ui about.ui devsetup.ui widegraph.ui \
|
|||
RC_FILE = wsjtx.rc
|
||||
|
||||
unix {
|
||||
INCLUDEPATH += $$quote(/usr/include/qwt-qt4)
|
||||
LIBS += ../wsjtx/lib/libjt9.a
|
||||
LIBS += -lhamlib
|
||||
LIBS += -lportaudio -lgfortran -lfftw3f -lqwt-qt4
|
||||
LIBS += -lportaudio -lgfortran -lfftw3f
|
||||
}
|
||||
|
||||
win32 {
|
||||
INCLUDEPATH += c:/qwt-6.0.1/include
|
||||
INCLUDEPATH += ../../hamlib-1.2.15.3/include
|
||||
LIBS += ../../hamlib-1.2.15.3/src/.libs/libhamlib.dll.a
|
||||
#LIBS += ../../hamlib-1.2.15.3/lib/gcc/libhamlib.dll.a
|
||||
LIBS += ../wsjtx/lib/libjt9.a
|
||||
LIBS += ../wsjtx/libfftw3f_win.a
|
||||
LIBS += ../wsjtx/libpskreporter.a
|
||||
LIBS += ../wsjtx/libHRDInterface001.a
|
||||
LIBS += ../QtSupport/palir-02.dll
|
||||
#LIBS += ../QtSupport/palir-02.dll
|
||||
LIBS += /users/joe/wsjt/QtSupport/palir-02.dll
|
||||
LIBS += libwsock32
|
||||
LIBS += C:/MinGW/lib/libf95.a
|
||||
CONFIG(release) {
|
||||
LIBS += C:/qwt-6.0.1/lib/qwt.dll
|
||||
} else {
|
||||
LIBS += C:/qwt-6.0.1/lib/qwtd.dll
|
||||
LIBS += -lusb
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue