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:
Joe Taylor 2013-07-08 13:17:22 +00:00
parent ba61cfde6a
commit 3dc6abc0c1
75 changed files with 4807 additions and 3514 deletions

Binary file not shown.

View File

@ -1,7 +1,8 @@
#ifndef COMMONS_H #ifndef COMMONS_H
#define COMMONS_H #define COMMONS_H
#define NSMAX 1365 //#define NSMAX 1365
#define NSMAX 6827
#define NTMAX 120 #define NTMAX 120
extern "C" { extern "C" {
@ -9,7 +10,6 @@ extern "C" {
extern struct { extern struct {
float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran
float savg[NSMAX]; float savg[NSMAX];
float c0[2*NTMAX*1500];
short int d2[NTMAX*12000]; short int d2[NTMAX*12000];
int nutc; //UTC as integer, HHMM int nutc; //UTC as integer, HHMM
int ndiskdat; //1 ==> data read from *.wav file int ndiskdat; //1 ==> data read from *.wav file
@ -25,8 +25,8 @@ extern struct {
int nsave; int nsave;
int nagain; int nagain;
int ndepth; int ndepth;
int nrxlog; int ntxmode;
int nfsample; int nmode;
char datetime[20]; char datetime[20];
} jt9com_; } jt9com_;

View File

@ -1,10 +1,13 @@
#include "devsetup.h" #include "devsetup.h"
#include <QDebug> #include <QDebug>
#include <QSettings>
#include <portaudio.h> #include <portaudio.h>
#define MAXDEVICES 100 #define MAXDEVICES 100
extern double dFreq[16]; extern double dFreq[16];
qint32 g2_iptt;
qint32 g2_COMportOpen;
//----------------------------------------------------------- DevSetup() //----------------------------------------------------------- DevSetup()
DevSetup::DevSetup(QWidget *parent) : QDialog(parent) DevSetup::DevSetup(QWidget *parent) : QDialog(parent)
@ -13,10 +16,10 @@ DevSetup::DevSetup(QWidget *parent) : QDialog(parent)
m_restartSoundIn=false; m_restartSoundIn=false;
m_restartSoundOut=false; m_restartSoundOut=false;
m_firstCall=true; m_firstCall=true;
m_iptt=0; g2_iptt=0;
m_test=0; m_test=0;
m_bRigOpen=false; m_bRigOpen=false;
m_COMportOpen=0; g2_COMportOpen=0;
} }
DevSetup::~DevSetup() DevSetup::~DevSetup()
@ -25,6 +28,13 @@ DevSetup::~DevSetup()
void DevSetup::initDlg() 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 k,id;
int numDevices=Pa_GetDeviceCount(); int numDevices=Pa_GetDeviceCount();
@ -40,6 +50,8 @@ void DevSetup::initDlg()
nchin=pdi->maxInputChannels; nchin=pdi->maxInputChannels;
if(nchin>0) { if(nchin>0) {
m_inDevList[k]=id; m_inDevList[k]=id;
if (id == m_paInDevice)
m_nDevIn = k;
k++; k++;
sprintf((char*)(pa_device_name),"%s",pdi->name); sprintf((char*)(pa_device_name),"%s",pdi->name);
sprintf((char*)(pa_device_hostapi),"%s", sprintf((char*)(pa_device_hostapi),"%s",
@ -77,6 +89,8 @@ void DevSetup::initDlg()
nchout=pdi->maxOutputChannels; nchout=pdi->maxOutputChannels;
if(nchout>0) { if(nchout>0) {
m_outDevList[k]=id; m_outDevList[k]=id;
if (id == m_paOutDevice)
m_nDevOut = k;
k++; k++;
sprintf((char*)(pa_device_name),"%s",pdi->name); sprintf((char*)(pa_device_name),"%s",pdi->name);
sprintf((char*)(pa_device_hostapi),"%s", sprintf((char*)(pa_device_hostapi),"%s",
@ -115,6 +129,7 @@ void DevSetup::initDlg()
this, SLOT(p4Error())); this, SLOT(p4Error()));
p4.start("rigctl -l"); p4.start("rigctl -l");
p4.waitForFinished(1000); p4.waitForFinished(1000);
ui.rigComboBox->addItem(" 9998 Commander");
ui.rigComboBox->addItem(" 9999 Ham Radio Deluxe"); ui.rigComboBox->addItem(" 9999 Ham Radio Deluxe");
QPalette pal(ui.myCallEntry->palette()); QPalette pal(ui.myCallEntry->palette());
@ -136,8 +151,9 @@ void DevSetup::initDlg()
ui.comboBoxSndOut->setCurrentIndex(m_nDevOut); ui.comboBoxSndOut->setCurrentIndex(m_nDevOut);
ui.cbID73->setChecked(m_After73); ui.cbID73->setChecked(m_After73);
ui.cbPSKReporter->setChecked(m_pskReporter); ui.cbPSKReporter->setChecked(m_pskReporter);
m_paInDevice=m_inDevList[m_nDevIn]; ui.cbSplit->setChecked(m_bSplit);
m_paOutDevice=m_outDevList[m_nDevOut]; ui.cbXIT->setChecked(m_bXIT);
ui.cbXIT->setVisible(false);
enableWidgets(); enableWidgets();
@ -176,6 +192,7 @@ void DevSetup::initDlg()
ui.catPortComboBox->addItem("/dev/ttyUSB1"); ui.catPortComboBox->addItem("/dev/ttyUSB1");
ui.catPortComboBox->addItem("/dev/ttyUSB2"); ui.catPortComboBox->addItem("/dev/ttyUSB2");
ui.catPortComboBox->addItem("/dev/ttyUSB3"); ui.catPortComboBox->addItem("/dev/ttyUSB3");
ui.catPortComboBox->addItem(catPortDriver);
ui.pttComboBox->addItem("/dev/ttyS0"); ui.pttComboBox->addItem("/dev/ttyS0");
ui.pttComboBox->addItem("/dev/ttyS1"); ui.pttComboBox->addItem("/dev/ttyS1");
@ -280,7 +297,7 @@ void DevSetup::accept()
if(m_bRigOpen) { if(m_bRigOpen) {
rig->close(); rig->close();
if(m_rig!=9999) delete rig; if(m_rig<9900) delete rig;
m_bRigOpen=false; m_bRigOpen=false;
} }
@ -414,18 +431,22 @@ void DevSetup::on_testCATButton_clicked()
if(!m_catEnabled) return; if(!m_catEnabled) return;
if(m_bRigOpen) { if(m_bRigOpen) {
rig->close(); rig->close();
if(m_rig!=9999) delete rig; if(m_rig<9900) delete rig;
m_bRigOpen=false; m_bRigOpen=false;
} }
rig = new Rig(); rig = new Rig();
if(m_rig != 9999) { if(m_rig<9900) {
if (!rig->init(m_rig)) { if (!rig->init(m_rig)) {
msgBox("Rig init failure"); msgBox("Rig init failure");
return; 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]; char buf[80];
sprintf(buf,"%d",m_serialRate); sprintf(buf,"%d",m_serialRate);
rig->setConf("serial_speed",buf); rig->setConf("serial_speed",buf);
@ -470,7 +491,9 @@ void DevSetup::on_testPTTButton_clicked()
{ {
m_test=1-m_test; m_test=1-m_test;
if(m_pttMethodIndex==1 or m_pttMethodIndex==2) { 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) { if(m_pttMethodIndex==0 and !m_bRigOpen) {
on_testCATButton_clicked(); on_testCATButton_clicked();
@ -522,8 +545,10 @@ void DevSetup::enableWidgets()
ui.testCATButton->setEnabled(m_catEnabled); ui.testCATButton->setEnabled(m_catEnabled);
ui.label_4->setEnabled(m_catEnabled); ui.label_4->setEnabled(m_catEnabled);
ui.label_47->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.catPortComboBox->setEnabled(bSerial);
ui.serialRateComboBox->setEnabled(bSerial); ui.serialRateComboBox->setEnabled(bSerial);
ui.dataBitsComboBox->setEnabled(bSerial); ui.dataBitsComboBox->setEnabled(bSerial);
@ -541,9 +566,21 @@ void DevSetup::enableWidgets()
ui.pollSpinBox->setEnabled(m_catEnabled); ui.pollSpinBox->setEnabled(m_catEnabled);
bool b1=(m_pttMethodIndex==1 or m_pttMethodIndex==2); bool b1=(m_pttMethodIndex==1 or m_pttMethodIndex==2);
ui.pttComboBox->setEnabled(b1); ui.pttComboBox->setEnabled(b1);
bool b2 = (m_catEnabled and m_pttMethodIndex==1 and m_rig!=9999) or bool b2 = (m_catEnabled and m_pttMethodIndex==1 and m_rig<9900) or
(m_catEnabled and m_pttMethodIndex==2 and m_rig!=9999); (m_catEnabled and m_pttMethodIndex==2 and m_rig<9900);
bool b3 = (m_catEnabled and m_pttMethodIndex==0 and m_rig==9999); bool b3 = (m_catEnabled and m_pttMethodIndex==0 and m_rig>=9900);
// ui.testPTTButton->setEnabled(b1 or b2); // 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);
} }

View File

@ -35,9 +35,7 @@ public:
qint32 m_stopBits; qint32 m_stopBits;
qint32 m_stopBitsIndex; qint32 m_stopBitsIndex;
qint32 m_handshakeIndex; qint32 m_handshakeIndex;
qint32 m_iptt;
qint32 m_test; qint32 m_test;
qint32 m_COMportOpen;
qint32 m_poll; qint32 m_poll;
qint32 m_tmp; qint32 m_tmp;
@ -50,6 +48,8 @@ public:
bool m_bRigOpen; bool m_bRigOpen;
bool m_bDTRoff; bool m_bDTRoff;
bool m_pttData; bool m_pttData;
bool m_bSplit;
bool m_bXIT;
QString m_myCall; QString m_myCall;
QString m_myGrid; QString m_myGrid;
@ -93,6 +93,10 @@ private slots:
void on_pttComboBox_currentIndexChanged(int index); void on_pttComboBox_currentIndexChanged(int index);
void on_pttMethodComboBox_currentIndexChanged(int index); void on_pttMethodComboBox_currentIndexChanged(int index);
void on_cbSplit_toggled(bool checked);
void on_cbXIT_toggled(bool checked);
private: private:
Rig* rig; Rig* rig;
void msgBox(QString t); void msgBox(QString t);

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>548</width> <width>569</width>
<height>493</height> <height>493</height>
</rect> </rect>
</property> </property>
@ -584,6 +584,32 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </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"> <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>40</width>
@ -741,6 +767,9 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>40</width>
@ -750,9 +779,25 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="cbDTRoff"> <widget class="QRadioButton" name="rbData">
<property name="toolTip">
<string>Use special Tx command for &quot;data&quot;</string>
</property>
<property name="text"> <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> </property>
</widget> </widget>
</item> </item>
@ -899,7 +944,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_14"> <spacer name="horizontalSpacer_16">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -915,25 +960,9 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QRadioButton" name="rbData"> <widget class="QCheckBox" name="cbSplit">
<property name="toolTip">
<string>Use special Tx command for &quot;data&quot;</string>
</property>
<property name="text"> <property name="text">
<string>Data</string> <string>Split Tx</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> </property>
</widget> </widget>
</item> </item>
@ -1010,6 +1039,29 @@
</property> </property>
</widget> </widget>
</item> </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> <item>
<spacer name="horizontalSpacer_12"> <spacer name="horizontalSpacer_12">
<property name="orientation"> <property name="orientation">
@ -1313,6 +1365,9 @@
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="text">
<string>5W DPL 73 GL</string>
</property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
@ -1360,6 +1415,9 @@
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="text">
<string>20W DPL 73 GL</string>
</property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="4" column="1">
@ -1554,6 +1612,9 @@
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="text">
<string/>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="2"> <item row="3" column="2">
@ -1576,6 +1637,9 @@
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="text">
<string>TNX 73 GL</string>
</property>
</widget> </widget>
</item> </item>
<item row="1" column="2"> <item row="1" column="2">
@ -1598,6 +1662,9 @@
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="text">
<string>10W DPL 73 GL</string>
</property>
</widget> </widget>
</item> </item>
<item row="8" column="2"> <item row="8" column="2">
@ -2457,11 +2524,8 @@
<tabstop>catPortComboBox</tabstop> <tabstop>catPortComboBox</tabstop>
<tabstop>dataBitsComboBox</tabstop> <tabstop>dataBitsComboBox</tabstop>
<tabstop>serialRateComboBox</tabstop> <tabstop>serialRateComboBox</tabstop>
<tabstop>cbDTRoff</tabstop>
<tabstop>stopBitsComboBox</tabstop> <tabstop>stopBitsComboBox</tabstop>
<tabstop>handshakeComboBox</tabstop> <tabstop>handshakeComboBox</tabstop>
<tabstop>rbData</tabstop>
<tabstop>rbMic</tabstop>
<tabstop>testCATButton</tabstop> <tabstop>testCATButton</tabstop>
<tabstop>testPTTButton</tabstop> <tabstop>testPTTButton</tabstop>
<tabstop>pollSpinBox</tabstop> <tabstop>pollSpinBox</tabstop>

View File

@ -1,11 +1,19 @@
#include "getfile.h" #include "getfile.h"
#include <QDir> #include <QDir>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #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 #endif
void getfile(QString fname, int ntrperiod) void getfile(QString fname, int ntrperiod)
@ -123,6 +131,7 @@ float gran()
int ptt(int nport, int ntx, int* iptt, int* nopen) int ptt(int nport, int ntx, int* iptt, int* nopen)
{ {
// qDebug() << "getfile ptt(), line 129:" << nport << ntx << *iptt << *nopen;
#ifdef WIN32 #ifdef WIN32
static HANDLE hFile; static HANDLE hFile;
char s[10]; char s[10];
@ -130,7 +139,7 @@ int ptt(int nport, int ntx, int* iptt, int* nopen)
if(nport==0) { if(nport==0) {
*iptt=ntx; *iptt=ntx;
return(0); return 0;
} }
if(ntx && (!(*nopen))) { if(ntx && (!(*nopen))) {
@ -160,6 +169,34 @@ int ptt(int nport, int ntx, int* iptt, int* nopen)
*nopen=0; *nopen=0;
} }
if((i3+i4+i5+i6+i9+i00)==-999) return 1; //Silence compiler warning 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; return 0;
#endif #endif
if((nport+ntx+(*iptt)==-99999)) *nopen=0; //Silence compiler warning if((nport+ntx+(*iptt)==-99999)) *nopen=0; //Silence compiler warning

View File

@ -10,5 +10,4 @@ float gran();
//int ptt(int* nport, int* ntx, int* iptt); //int ptt(int* nport, int* ntx, int* iptt);
int ptt(int nport, int ntx, int* iptt, int* nopen); int ptt(int nport, int ntx, int* iptt, int* nopen);
#endif // GETFILE_H #endif // GETFILE_H

View File

@ -20,7 +20,7 @@ CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
%.o: %.F90 %.o: %.F90
${FC} ${FFLAGS} -c $< ${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 \ OBJS1 = pctile.o graycode.o sort.o ssort.o \
unpackmsg.o igray.o unpackcall.o unpackgrid.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 \ symspec.o analytic.o db.o genjt9.o \
packbits.o unpackbits.o encode232.o interleave9.o \ packbits.o unpackbits.o encode232.o interleave9.o \
entail.o fano232.o gran.o sync9.o decode9.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 \ softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.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) libjt9.a: $(OBJS1)
ar cr libjt9.a $(OBJS1) ar cr libjt9.a $(OBJS1)
@ -54,15 +59,9 @@ OBJS4 = jt9code.o
jt9code.exe: $(OBJS4) libjt9.a jt9code.exe: $(OBJS4) libjt9.a
$(FC) -o jt9code.exe $(OBJS4) libjt9.a $(FC) -o jt9code.exe $(OBJS4) libjt9.a
OBJS5 = test9.o OBJS5 = jt65.o
test9.exe: $(OBJS5) libjt9.a jt65.exe: $(OBJS5) libjt9.a
$(FC) -o test9.exe $(OBJS5) libjt9.a ../libfftw3f_win.a $(FC) -o jt65.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
INCPATH = -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore' \ INCPATH = -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore' \
-I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include' \ -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include' \
@ -75,9 +74,6 @@ sync9.o: sync9.f90 jt9sync.f90
spec9.o: spec9.f90 jt9sync.f90 spec9.o: spec9.f90 jt9sync.f90
$(FC) $(FFLAGS) -c spec9.f90 $(FC) $(FFLAGS) -c spec9.f90
peakdf9.o: peakdf9.f90 jt9sync.f90
$(FC) $(FFLAGS) -c peakdf9.f90
peakdt9.o: peakdt9.f90 jt9sync.f90 peakdt9.o: peakdt9.f90 jt9sync.f90
$(FC) $(FFLAGS) -c peakdt9.f90 $(FC) $(FFLAGS) -c peakdt9.f90
@ -105,7 +101,17 @@ sec_midn.o: sec_midn.f90
tstrig.o: tstrig.c tstrig.o: tstrig.c
$(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include 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 .PHONY : clean
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

View File

@ -23,14 +23,19 @@ OBJS1 = pctile.o graycode.o sort.o ssort.o \
grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \ grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \ packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.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 \ packbits.o unpackbits.o encode232.o interleave9.o \
entail.o fano232.o gran.o sync9.o decode9.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 \ softsym.o peakdt9.o getlags.o afc9.o fchisq.o \
twkfreq.o downsam9.o symspec2.o ipcomm.o sleep_msec.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 \ 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) libjt9.a: $(OBJS1)
ar cr libjt9.a $(OBJS1) ar cr libjt9.a $(OBJS1)
@ -38,7 +43,7 @@ libjt9.a: $(OBJS1)
OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o 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 g++ -o jt9 $(OBJS2) libjt9.a -lfftw3f -lgfortran -lQtCore
cp jt9 ../../wsjtx_install cp jt9 ../../wsjtx_install
@ -84,6 +89,15 @@ ipcomm.o: ipcomm.cpp
sec_midn.o: sec_midn.f90 sec_midn.o: sec_midn.f90
$(FC) -c -fno-second-underscore 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 .PHONY : clean
clean: clean:

59
lib/afc65b.f90 Normal file
View File

@ -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

45
lib/ccf2.f90 Normal file
View File

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

117
lib/ccf65.f90 Normal file
View File

@ -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

57
lib/char.h Normal file
View File

@ -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);

21
lib/chkhist.f90 Normal file
View File

@ -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

5
lib/constants.f90 Normal file
View File

@ -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)

View File

@ -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

95
lib/decode65a.f90 Normal file
View File

@ -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

36
lib/decode65b.f90 Normal file
View File

@ -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

View File

@ -16,7 +16,7 @@ subroutine decode9(i1SoftSymbols,limit,nlim,msg)
logical first logical first
integer*4 mettab(0:255,0:1) integer*4 mettab(0:255,0:1)
data first/.true./ 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, & 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 if(first) then
! Get the metric table ! Get the metric table
! bias=0.37 !To be optimized, in decoder program
bias=0.5 bias=0.5
scale=10 ! ... ditto ... scale=10
do i=0,255 do i=0,255
mettab(i,0)=nint(scale*(xx0(i)-bias)) mettab(i,0)=nint(scale*(xx0(i)-bias))
if(i.ge.1) mettab(256-i,1)=mettab(i,0) if(i.ge.1) mettab(256-i,1)=mettab(i,0)

View File

@ -9,7 +9,7 @@
#include <string.h> #include <string.h>
#define NULL ((void *)0) //#define NULL ((void *)0)
#define min(a,b) ((a) < (b) ? (a) : (b)) #define min(a,b) ((a) < (b) ? (a) : (b))
#ifdef FIXED #ifdef FIXED

View File

@ -1,23 +1,21 @@
subroutine decoder(ss,c0,nstandalone) subroutine decoder(ss,id2)
! Decoder for JT9. ! Decoder for JT9.
parameter (NTMAX=120) include 'constants.f90'
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
real ss(184,NSMAX) real ss(184,NSMAX)
character*22 msg character*22 msg
character*80 fmt
character*20 datetime character*20 datetime
real*4 ccfred(NSMAX) real*4 ccfred(NSMAX)
real*4 red2(NSMAX) real*4 red2(NSMAX)
logical ccfok(NSMAX) logical ccfok(NSMAX)
logical done(NSMAX) logical done(NSMAX)
logical done65
integer*2 id2(NTMAX*12000)
real*4 dd(NTMAX*12000)
integer*1 i1SoftSymbols(207) integer*1 i1SoftSymbols(207)
complex c0(NDMAX)
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol, & 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 common/tracer/limtrace,lu
save save
@ -27,48 +25,40 @@ subroutine decoder(ss,c0,nstandalone)
ndecodes0=0 ndecodes0=0
ndecodes1=0 ndecodes1=0
call timer('decoder ',0)
open(13,file='decoded.txt',status='unknown') open(13,file='decoded.txt',status='unknown')
ntrMinutes=ntrperiod/60 open(22,file='kvasd.dat',access='direct',recl=1024,status='unknown')
newdat=1
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 nsynced=0
ndecoded=0 ndecoded=0
nsps=0 nsps=0
if(ntrMinutes.eq.1) then nsps=6912 !Params for JT9-1
nsps=6912 df3=1500.0/2048.0
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###
tstep=0.5*nsps/12000.0 !Half-symbol step (seconds) tstep=0.5*nsps/12000.0 !Half-symbol step (seconds)
done=.false. done=.false.
ia=max(1,nint((nfa-1000)/df3)) nf0=0
ib=min(NSMAX,nint((nfb-1000)/df3)) ia=max(1,nint((nfa-nf0)/df3))
ib=min(NSMAX,nint((nfb-nf0)/df3))
lag1=-(2.5/tstep + 0.9999) lag1=-(2.5/tstep + 0.9999)
lag2=5.0/tstep + 0.9999 lag2=5.0/tstep + 0.9999
call timer('sync9 ',0) if(newdat.ne.0) then
call sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipk) call timer('sync9 ',0)
call timer('sync9 ',1) call sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipk)
call timer('sync9 ',1)
endif
nsps8=nsps/8 nsps8=nsps/8
df8=1500.0/nsps8 df8=1500.0/nsps8
@ -94,24 +84,22 @@ subroutine decoder(ss,c0,nstandalone)
ccfok(ia:ib)=.true. ccfok(ia:ib)=.true.
nfa1=nfqso-ntol nfa1=nfqso-ntol
nfb1=nfqso+ntol nfb1=nfqso+ntol
ia=max(1,nint((nfa1-1000)/df3)) ia=max(1,nint((nfa1-nf0)/df3))
ib=min(NSMAX,nint((nfb1-1000)/df3)) ib=min(NSMAX,nint((nfb1-nf0)/df3))
ia1=ia ia1=ia
ib1=ib ib1=ib
else else
nfa1=nfa nfa1=nfa
nfb1=nfb nfb1=nfb
ia=max(1,nint((nfa1-1000)/df3)) ia=max(1,nint((nfa1-nf0)/df3))
ib=min(NSMAX,nint((nfb1-1000)/df3)) ib=min(NSMAX,nint((nfb1-nf0)/df3))
do i=ia,ib do i=ia,ib
ccfok(i)=ccfred(i).gt.ccflim .and. red2(i).gt.red2lim ccfok(i)=ccfred(i).gt.ccflim .and. red2(i).gt.red2lim
enddo enddo
ccfok(ia1:ib1)=.false. ccfok(ia1:ib1)=.false.
endif endif
nRxLog=0
fgood=0. fgood=0.
do i=ia,ib do i=ia,ib
f=(i-1)*df3 f=(i-1)*df3
if(done(i) .or. (.not.ccfok(i)) .or. (ccfred(i).lt.ccflim-1.0)) cycle 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 if(nqd.eq.1) nfreqs1=nfreqs1+1
call timer('softsym ',0) call timer('softsym ',0)
fpk=1000.0 + df3*(i-1) fpk=nf0 + df3*(i-1)
call softsym(c0,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,freq, & call softsym(id2,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt, &
drift,schk,i1SoftSymbols) freq,drift,schk,i1SoftSymbols)
call timer('softsym ',1) call timer('softsym ',1)
if(schk.ge.schklim) then if(schk.ge.schklim) then
@ -140,16 +128,14 @@ subroutine decoder(ss,c0,nstandalone)
nsnr=nint(snrdb) nsnr=nint(snrdb)
ndrift=nint(drift/df3) 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(msg.ne.' ') then
if(nqd.eq.0) ndecodes0=ndecodes0+1 if(nqd.eq.0) ndecodes0=ndecodes0+1
if(nqd.eq.1) ndecodes1=ndecodes1+1 if(nqd.eq.1) ndecodes1=ndecodes1+1
write(*,fmt) nutc,nsync,nsnr,xdt,freq,ndrift,msg write(*,1000) nutc,nsnr,xdt,nint(freq),msg
write(13,fmt) nutc,nsync,nsnr,xdt,freq,ndrift,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) iaa=max(1,i-1)
ibb=min(NSMAX,i+22) ibb=min(NSMAX,i+22)
@ -160,8 +146,6 @@ subroutine decoder(ss,c0,nstandalone)
done(iaa:ibb)=.true. done(iaa:ibb)=.true.
call flush(6) call flush(6)
endif endif
else
! write(38,3002) nutc,nqd,-99,i,freq,ndrift,ccfred(i),red2(i),schk,0
endif endif
endif endif
enddo enddo
@ -169,21 +153,17 @@ subroutine decoder(ss,c0,nstandalone)
if(nagain.ne.0) exit if(nagain.ne.0) exit
enddo 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) 1010 format('<DecodeFinished>',2i4)
call flush(6) call flush(6)
close(13) close(13)
! call flush(14) close(22)
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)
return return
end subroutine decoder end subroutine decoder

73
lib/demod64a.f90 Normal file
View File

@ -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

View File

@ -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) include 'constants.f90'
complex c0(0:npts8-1) parameter (NMAX1=1024*1920)
complex c1(0:NMAX-1) integer*2 id2(0:8*npts8-1)
real*4 x1(0:NMAX1-1)
complex c1(0:NMAX1/2)
complex c2(0:4096-1) complex c2(0:4096-1)
real s(1000) real s(5000)
equivalence (c1,x1)
save save
nfft1=128*nsps8 !Forward FFT length nfft1=1024*nsps8 !Forward FFT length
nh1=nfft1/2 df1=12000.0/nfft1
df1=1500.0/nfft1 npts=8*npts8
if(newdat.eq.1) then if(newdat.eq.1) then
fac=1.e-4 fac=6.963e-6 !Why this weird constant?
do i=0,npts8-1,2 do i=0,npts-1
c1(i)=fac*conjg(c0(i)) x1(i)=fac*id2(i)
c1(i+1)=-fac*conjg(c0(i+1))
enddo enddo
c1(npts8:)=0. !Zero the rest of c1 x1(npts:nfft1-1)=0. !Zero the rest of x1
call four2a(c1,nfft1,1,-1,1) !Forward FFT call four2a(c1,nfft1,1,-1,0) !Forward FFT, r2c
nadd=1.0/df1 nadd=1.0/df1
j=250/df1
s=0. s=0.
do i=1,1000 do i=1,5000
j=(i-1)/df1
do n=1,nadd do n=1,nadd
j=j+1 j=j+1
s(i)=s(i)+real(c1(j))**2 + aimag(c1(j))**2 s(i)=s(i)+real(c1(j))**2 + aimag(c1(j))**2
enddo enddo
! write(37,3001) i+1000,s(i),db(s(i)),nadd
!3001 format(i5,2f12.3,i8)
enddo enddo
call pctile(s,1000,40,avenoise)
endif endif
ndown=nsps8/16 !Downsample factor ndown=8*nsps8/nspsd !Downsample factor
nfft2=nfft1/ndown !Backward FFT length nfft2=nfft1/ndown !Backward FFT length
nh2=nfft2/2 nh2=nfft2/2
nf=nint(fpk)
fshift=fpk-1500.0 i0=fpk/df1
i0=nh1 + fshift/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) fac=sqrt(1.0/avenoise)
do i=0,nfft2-1 do i=0,nfft2-1
j=i0+i j=i0+i
if(i.gt.nh2) j=j-nfft2 if(i.gt.nh2) j=j-nfft2
c2(i)=fac*c1(j) c2(i)=fac*c1(j)
enddo enddo
call four2a(c2,nfft2,1,1,1) !FFT back to time domain
call four2a(c2,nfft2,1,1,1) !Backward FFT nz2=8*npts8/ndown
nspsd=nsps8/ndown
nz2=npts8/ndown
return return
end subroutine downsam9 end subroutine downsam9

102
lib/extract.F90 Normal file
View File

@ -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

68
lib/fchisq65.f90 Normal file
View File

@ -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

44
lib/fil6521.f90 Normal file
View File

@ -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

127
lib/filbig.f90 Normal file
View File

@ -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

View File

@ -1,24 +1,24 @@
subroutine fillcom(nutc0,ndepth0) subroutine fillcom(nutc0,ndepth0)
character*20 datetime character*20 datetime
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol, & 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 save
nutc=nutc0 nutc=nutc0
ndiskdat=1 ndiskdat=1
ntrperiod=60 ntrperiod=60
nfqso=1500 nfqso=1197
newdat=1 newdat=1
npts8=74736 npts8=74736
nfa=1000 nfa=2700
nfb=2000 nfb=4007
ntol=3 ntol=3
kin=1024 kin=1024
nzhsym=173 nzhsym=173
nsave=0 nsave=0
ndepth=ndepth0 ndepth=ndepth0
nrxlog=1 ntxmode=9
nfsample=12000 nmode=9+65
datetime="2013-Apr-16 15:13" datetime="2013-Apr-16 15:13"
return return

18
lib/flat2.f90 Normal file
View File

@ -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

25
lib/flat65.f90 Normal file
View File

@ -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

65
lib/gen65.f90 Normal file
View File

@ -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

View File

@ -26,7 +26,7 @@ subroutine genjt9(msg0,ichk,msgsent,i4tone,itext)
endif endif
enddo enddo
do i=1,22 !Omit leading blanks do i=1,22 !Strip leading blanks
if(message(1:1).ne.' ') exit if(message(1:1).ne.' ') exit
message=message(i+1:) message=message(i+1:)
enddo enddo

9
lib/graycode65.f90 Normal file
View File

@ -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

View File

@ -13,7 +13,7 @@
#include "char.h" #include "char.h"
#endif #endif
#define NULL ((void *)0) //#define NULL ((void *)0)
void FREE_RS(void *p){ void FREE_RS(void *p){
struct rs *rs = (struct rs *)p; struct rs *rs = (struct rs *)p;

25
lib/interleave63.f90 Normal file
View File

@ -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

68
lib/jt65.f90 Normal file
View File

@ -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

91
lib/jt65a.f90 Normal file
View File

@ -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

View File

@ -3,18 +3,12 @@ program jt9
! Decoder for JT9. Can run stand-alone, reading data from *.wav files; ! 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. ! or as the back end of wsjt-x, with data placed in a shared memory region.
parameter (NTMAX=120) include 'constants.f90'
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) integer*4 ihdr(11)
real*4 s(NSMAX) real*4 s(NSMAX)
real*4 ccfred(NSMAX)
logical*1 lstrong(0:1023)
integer*2 id2 integer*2 id2
complex c0
character*80 arg,infile 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 ntr,mousefqso,newdat,nfa,nfb,ntol,kin,nzhsym,nsynced,ndecoded
common/tracer/limtrace,lu common/tracer/limtrace,lu
@ -39,11 +33,6 @@ program jt9
limtrace=0 limtrace=0
lu=12 lu=12
nfa=1000
nfb=2000
mousefqso=1500
newdat=1
ndiskdat=1
do ifile=ifile1,nargs do ifile=ifile1,nargs
call getarg(ifile,infile) call getarg(ifile,infile)
@ -82,10 +71,6 @@ program jt9
call timer('jt9 ',0) call timer('jt9 ',0)
endif endif
! do i=1,npts
! id2(i)=100.0*sin(6.283185307*1600.0*i/12000.0)
! enddo
id2=0 !??? Why is this necessary ??? id2=0 !??? Why is this necessary ???
do iblk=1,npts/kstep do iblk=1,npts/kstep
@ -99,8 +84,7 @@ program jt9
! Emit signal readyForFFT ! Emit signal readyForFFT
ingain=0 ingain=0
call timer('symspec ',0) call timer('symspec ',0)
call symspec(k,ntrperiod,nsps,ingain,pxdb,s,ccfred,df3, & call symspec(k,ntrperiod,nsps,ingain,slope,pxdb,s,df3,ihsym,npts8)
ihsym,nzap,slimit,lstrong,npts8)
call timer('symspec ',1) call timer('symspec ',1)
nhsym0=nhsym nhsym0=nhsym
if(ihsym.ge.173) go to 10 if(ihsym.ge.173) go to 10
@ -109,7 +93,7 @@ program jt9
10 close(10) 10 close(10)
call fillcom(nutc0,ndepth) call fillcom(nutc0,ndepth)
call decoder(ss,c0,1) call decoder(ss,id2)
enddo enddo
call timer('jt9 ',1) call timer('jt9 ',1)

View File

@ -20,6 +20,7 @@ subroutine jt9a
open(12,file='timer.out',status='unknown') open(12,file='timer.out',status='unknown')
limtrace=0 limtrace=0
! limtrace=-1 !Disable all calls to timer()
lu=12 lu=12
i1=attach_jt9() i1=attach_jt9()
@ -44,12 +45,16 @@ subroutine jt9a
go to 999 go to 999
endif endif
p_jt9=>address_jt9() p_jt9=>address_jt9()
call timer('jt9b ',0)
call jt9b(p_jt9,nbytes) call jt9b(p_jt9,nbytes)
call timer('jt9b ',1)
100 inquire(file=trim(cwd)//'/.lock',exist=fileExists) 100 inquire(file=trim(cwd)//'/.lock',exist=fileExists)
if(fileExists) go to 10 if(fileExists) go to 10
call sleep_msec(100) call sleep_msec(100)
go to 100 go to 100
999 return 999 call timer('jt9b ',101)
return
end subroutine jt9a end subroutine jt9a

View File

@ -1,14 +1,12 @@
subroutine jt9b(jt9com,nbytes) subroutine jt9b(jt9com,nbytes)
parameter (NTMAX=120) include 'constants.f90'
parameter (NSMAX=1365)
integer*1 jt9com(0:nbytes-1) integer*1 jt9com(0:nbytes-1)
kss=0 kss=0
ksavg=kss + 4*184*NSMAX ksavg=kss + 4*184*NSMAX
kc0=ksavg + 4*NSMAX kid2=ksavg + 4*NSMAX
kid2=kc0 + 2*4*NTMAX*1500
knutc=kid2 + 2*NTMAX*12000 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 return
end subroutine jt9b end subroutine jt9b

View File

@ -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) real*4 ss(184*NSMAX),savg(NSMAX)
complex c0(1800*1500) integer*2 id2(NTMAX*12000)
integer*2 id2(1800*12000)
integer nparams0(21),nparams(21) integer nparams0(21),nparams(21)
character*20 datetime character*20 datetime
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol, & 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) equivalence (nparams,nutc)
nutc=id2(1)+int(savg(1)) !Silence compiler warning nutc=id2(1)+int(savg(1)) !Silence compiler warning
nparams=nparams0 !Copy parameters into common/npar/ nparams=nparams0 !Copy parameters into common/npar/
call flush(6) 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 return
end subroutine jt9c end subroutine jt9c

View File

@ -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

7
lib/move.f90 Normal file
View File

@ -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

View File

@ -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

View File

@ -9,11 +9,8 @@ subroutine peakdt9(c2,nz2,nsps8,nspsd,c3,nz3,xdt)
p=0. p=0.
i0=5*nspsd i0=5*nspsd
do i=0,nz2-1 do i=0,nz2-1
z=1.e-3*sum(c2(max(i-(nspsd-1),0):i)) !Integrate z=1.e-3*sum(c2(max(i-(nspsd-1),0):i))
p(i0+i)=real(z)**2 + aimag(z)**2 !Symbol power at freq=0 p(i0+i)=real(z)**2 + aimag(z)**2 !Integrated 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)
enddo enddo
call getlags(nsps8,lag0,lag1,lag2) call getlags(nsps8,lag0,lag1,lag2)
@ -35,8 +32,6 @@ subroutine peakdt9(c2,nz2,nsps8,nspsd,c3,nz3,xdt)
enddo enddo
ss=(sum1/16.0)/(sum0/69.0) - 1.0 ss=(sum1/16.0)/(sum0/69.0) - 1.0
xdt=(lag-lag0)*dtlag xdt=(lag-lag0)*dtlag
! write(52,3001) lag,xdt,ss
!3001 format(i5,2f12.3)
if(ss.gt.smax) then if(ss.gt.smax) then
smax=ss smax=ss
lagpk=lag lagpk=lag

View File

@ -68,7 +68,7 @@ int lp_ptt (int fd, int onoff);
/* parport functions */ /* parport functions */
int dev_is_parport(int fd); 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 ptt_serial(int fd, int *ntx, int *iptt);
int fd=-1; /* Used for both serial and parallel */ 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_PARALLEL 1
#define STATE_PORT_OPEN_SERIAL 2 #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; static int state=0;
char *p; char *p;
char ptt_port[]="/dev/ttyUSB0";
fflush(stdout);
// ### Temporary: // In the very unlikely event of a NULL pointer, just return.
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.
*/
if (ptt_port == NULL) { if (ptt_port == NULL) {
*iptt = *ntx; *iptt = ntx;
return (0); return (0);
} }
switch (state) { switch (state) {
case STATE_PORT_CLOSED: case STATE_PORT_CLOSED:
/* Remove trailing ' ' */ // Remove trailing ' '
if ((p = strchr(ptt_port, ' ')) != NULL) if ((p = strchr(ptt_port, ' ')) != NULL)
*p = '\0'; *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') { if (*ptt_port == '\0') {
*iptt = *ntx; *iptt = ntx;
return(0); return(0);
} }
if ((fd = open(ptt_port, O_RDWR|O_NONBLOCK)) < 0) { if ((fd = open(ptt_port, O_RDWR|O_NONBLOCK)) < 0) {
fprintf(stderr, "Can't open %s.\n", ptt_port); fprintf(stderr, "Can't open %s.\n", ptt_port);
return (1); return (1);
} }
if (dev_is_parport(fd)) { if (dev_is_parport(fd)) {
state = STATE_PORT_OPEN_PARALLEL; state = STATE_PORT_OPEN_PARALLEL;
lp_reset(fd); lp_reset(fd);
ptt_parallel(fd, ntx, iptt); ptt_parallel(fd, ntx, iptt);
} else { } else {
state = STATE_PORT_OPEN_SERIAL; state = STATE_PORT_OPEN_SERIAL;
ptt_serial(fd, ntx, iptt); ptt_serial(fd, &ntx, iptt);
} }
break; break;
@ -146,7 +135,7 @@ int ptt_(int *unused, int *ntx, int *iptt)
break; break;
case STATE_PORT_OPEN_SERIAL: case STATE_PORT_OPEN_SERIAL:
ptt_serial(fd, ntx, iptt); ptt_serial(fd, &ntx, iptt);
break; break;
default: default:
@ -155,9 +144,11 @@ int ptt_(int *unused, int *ntx, int *iptt)
state = STATE_PORT_CLOSED; state = STATE_PORT_CLOSED;
break; break;
} }
*iptt=ntx;
return(0); return(0);
} }
/* /*
* ptt_serial * ptt_serial
* *
@ -180,6 +171,8 @@ ptt_serial(int fd, int *ntx, int *iptt)
ioctl(fd, TIOCMBIC, &control); ioctl(fd, TIOCMBIC, &control);
*iptt = 0; *iptt = 0;
} }
printf("ptt_serial: %d %d",*ntx,*iptt);
fflush(stdout);
return(0); return(0);
} }
@ -379,10 +372,9 @@ lp_ptt (int fd, int onoff)
* iptt - pointer to fortran command status on or off * iptt - pointer to fortran command status on or off
*/ */
int int ptt_parallel(int fd, int ntx, int *iptt)
ptt_parallel(int fd, int *ntx, int *iptt)
{ {
if(*ntx) { if(ntx) {
lp_ptt(fd, 1); lp_ptt(fd, 1);
*iptt=1; *iptt=1;
} else { } else {

View File

@ -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

60
lib/s3avg.f90 Normal file
View File

@ -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

96
lib/setup65.f90 Normal file
View File

@ -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

13
lib/smo121.f90 Normal file
View File

@ -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

View File

@ -1,9 +1,8 @@
subroutine softsym(c0,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,freq,drift, & subroutine softsym(id2,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt, &
schk,i1SoftSymbols) freq,drift,schk,i1SoftSymbols)
! Compute the soft symbols ! Compute the soft symbols
complex c0(0:npts8-1)
complex c2(0:4096-1) complex c2(0:4096-1)
complex c3(0:4096-1) complex c3(0:4096-1)
complex c5(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 ndown=nsps8/nspsd
! Mix, low-pass filter, and downsample to 16 samples per symbol ! 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 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) freq=fpk - a(1)
drift=-2.0*a(2) 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) ! Compute soft symbols (in scrambled order)
call symspec2(c5,nz3,nsps8,nspsd,fsample,freq,drift,snrdb,schk, & call symspec2(c5,nz3,nsps8,nspsd,fsample,freq,drift,snrdb,schk, &

View File

@ -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: ! Input:
! k pointer to the most recent new data ! 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: ! Output:
! pxdb power (0-60 dB) ! pxdb power (0-60 dB)
! s() spectrum for waterfall display ! s() current spectrum for waterfall display
! red() first cut at JT9 sync amplitude
! ihsym index number of this half-symbol (1-184) ! ihsym index number of this half-symbol (1-184)
parameter (NTMAX=120) ! jt9com
parameter (NMAX=NTMAX*12000) !Total sample intervals per 30 minutes ! ss() JT9 symbol spectra at half-symbol steps
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate ! savg() average spectra for waterfall display
parameter (NSMAX=1365) !Max length of saved spectra
parameter (NFFT1=1024) include 'constants.f90'
parameter (NFFT2=1024,NFFT2A=NFFT2/8) real*4 w3(MAXFFT3)
parameter (MAXFFT3=32768) real*4 s(NSMAX)
real*4 s(NSMAX),w3(MAXFFT3) real*4 scale(NSMAX)
real*4 x1(NFFT1)
real*4 x2(NFFT1+105)
real*4 ssum(NSMAX) real*4 ssum(NSMAX)
real*4 red(NSMAX) real*4 xc(0:MAXFFT3-1)
complex cx(0:MAXFFT3-1) complex cx(0:MAXFFT3/2)
integer*2 id2 integer*2 id2
complex c0 common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
common/jt9com/ss(184,NSMAX),savg(NSMAX),c0(NDMAX),id2(NMAX),nutc,ndiskdat, &
ntr,mousefqso,newdat,nfa,nfb,ntol,kin,nzhsym,nsynced,ndecoded 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 save
if(ntrperiod.eq.1) nfft3=2048 if(ntrperiod.eq.-999) stop !Silence compiler warning
if(ntrperiod.eq.2) nfft3=2048 nfft3=16384 !df=12000.0/16384 = 0.732422
if(ntrperiod.eq.5) nfft3=6144 jstep=nsps/2 !Step size = half-symbol in id2()
if(ntrperiod.eq.10) nfft3=12288 if(k.gt.NMAX) go to 900
if(ntrperiod.eq.30) nfft3=32768 if(k.lt.2048) then !(2048 was nfft3) (Any need for this ???)
jstep=nsps/16 !Step size = half-symbol in c0()
if(k.gt.NMAX) go to 999
if(k.lt.nfft3) then
ihsym=0 ihsym=0
go to 999 !Wait for enough samples to start go to 900 !Wait for enough samples to start
endif 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) pi=4.0*atan(1.0)
if(ntrperiod.eq.1) then !Compute window for nfft3 spectrun do i=1,nfft3
do i=1,nfft3 w3(i)=2.0*(sin(i*pi/nfft3))**2 !Window for nfft3 spectrum
xx=float(i-1)/(nfft3-1) enddo
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
nfft3z=nfft3 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 endif
if(k.lt.k0) then !Start a new data block if(k.lt.k0) then !Start a new data block
ja=0 ja=0
ssum=0. ssum=0.
ihsym=0 ihsym=0
k1=0 if(ndiskdat.eq.0) id2(k+1:)=0 !Needed to prevent "ghosts". Not sure why.
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
endif endif
k0=k
kstep1=NFFT1
fac=2.0/NFFT1
nblks=(k-k1)/kstep1
gain=10.0**(0.05*ingain) gain=10.0**(0.05*ingain)
sq=0. sq=0.
do nblk=1,nblks do i=k0+1,k
do i=1,NFFT1 x1=id2(i)
x1(i)=gain*id2(k1+i) sq=sq + x1*x1
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
enddo enddo
sq=sq * gain**2
npts8=k8 rms=sqrt(sq/(k-k0))
ja=ja+jstep !Index of first sample
rms=sqrt(sq/(nblks*NFFT1))
pxdb=0. pxdb=0.
if(rms.gt.0.0) pxdb=20.0*log10(rms) if(rms.gt.0.0) pxdb=20.0*log10(rms)
if(pxdb.gt.60.0) pxdb=60.0 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 do i=0,nfft3-1 !Copy data into cx
j=ja+i-(nfft3-1) j=ja+i-(nfft3-1)
cx(i)=0. xc(i)=0.
if(j.ge.1 .and. j.le.NDMAX) cx(i)=c0(j) if(j.ge.1) xc(i)=fac0*id2(j)
enddo enddo
if(ihsym.lt.184) ihsym=ihsym+1 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) n=min(184,ihsym)
df3=1500.0/nfft3 !JT9-a: 0.732 Hz = 0.42 * tone spacing df3=12000.0/nfft3 !JT9-1: 0.732 Hz = 0.42 * tone spacing
i0=nint(-500.0/df3) ! i0=nint(1000.0/df3)
iz=min(NSMAX,nint(1000.0/df3)) i0=0
iz=min(NSMAX,nint(5000.0/df3))
fac=(1.0/nfft3)**2 fac=(1.0/nfft3)**2
do i=1,iz do i=1,iz
j=i0+i-1 j=i0+i-1
@ -125,18 +103,11 @@ subroutine symspec(k,ntrperiod,nsps,ingain,pxdb,s,red,df3,ihsym,npts8)
s(i)=sx s(i)=sx
enddo enddo
999 continue ! s=0.05*s/ref
s=scale*s
savg=scale*ssum/ihsym
fac00=0.35 900 npts8=k/8
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)
return return
end subroutine symspec end subroutine symspec

47
lib/symspec65.f90 Normal file
View File

@ -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

View File

@ -1,6 +1,7 @@
subroutine sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipkbest) 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 ss(184,NSMAX)
real ss1(184) real ss1(184)
real ccfred(NSMAX) real ccfred(NSMAX)

View File

@ -7,7 +7,7 @@ subroutine timer(dname,k)
character*8 dname,name(50),space,ename character*8 dname,name(50),space,ename
character*16 sname character*16 sname
logical on(50) 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 ncall(50),nlevel(50),nparent(50)
integer onlevel(0:10) integer onlevel(0:10)
common/tracer/ limtrace,lu common/tracer/ limtrace,lu
@ -36,7 +36,8 @@ subroutine timer(dname,k)
if(on(n)) print*,'Error in timer: ',dname,' already on.' if(on(n)) print*,'Error in timer: ',dname,' already on.'
level=level+1 !Increment the level level=level+1 !Increment the level
on(n)=.true. on(n)=.true.
ut0(n)=etime(tt) call system_clock(icount,irate)
ut0(n)=float(icount)/irate
ncall(n)=ncall(n)+1 ncall(n)=ncall(n)+1
if(ncall(n).gt.1.and.nlevel(n).ne.level) then if(ncall(n).gt.1.and.nlevel(n).ne.level) then
nlevel(n)=-1 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) else if(k.eq.1) then !Get stop times and accumulate sums. (k=1)
if(on(n)) then if(on(n)) then
on(n)=.false. on(n)=.false.
ut1=etime(tt) call system_clock(icount,irate)
ut1=float(icount)/irate
ut(n)=ut(n)+ut1-ut0(n) ut(n)=ut(n)+ut1-ut0(n)
endif endif
level=level-1 level=level-1

View File

@ -13,13 +13,13 @@ subroutine twkfreq(c3,c4,npts,fsample,a)
s=2.0/npts s=2.0/npts
do i=1,npts do i=1,npts
x=s*(i-x0) 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 p2=1.5*x*x - 0.5
! p3=2.5*(x**3) - 1.5*x ! p3=2.5*(x**3) - 1.5*x
! p4=4.375*(x**4) - 3.75*(x**2) + 0.375 ! p4=4.375*(x**4) - 3.75*(x**2) + 0.375
dphi=(a(1) + x*a(2) + p2*a(3)) * (twopi/fsample) dphi=(a(1) + x*a(2) + p2*a(3)) * (twopi/fsample)
wstep=cmplx(cos(dphi),sin(dphi)) wstep=cmplx(cos(dphi),sin(dphi))
! endif endif
w=w*wstep w=w*wstep
c4(i)=w*c3(i) c4(i)=w*c3(i)
enddo enddo

25
lib/twkfreq65.f90 Normal file
View File

@ -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

70
lib/wrapkarn.c Normal file
View File

@ -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);
}

View File

@ -141,9 +141,12 @@ void LogQSO::accept()
m.exec(); m.exec();
} else { } else {
QString logEntry=m_dateTime.date().toString("yyyy-MMM-dd,") + QString logEntry=m_dateTime.date().toString("yyyy-MMM-dd,") +
m_dateTime.time().toString("hh:mm,") + hisCall + "," + m_dateTime.time().toString("hh:mm,") + hisCall + "," +
hisGrid + "," + strDialFreq + "," + mode + hisGrid + "," + strDialFreq + "," + mode +
"," + rptSent + "," + rptRcvd + "," + comments; "," + rptSent + "," + rptRcvd;
if(m_txPower!="") logEntry += "," + m_txPower;
if(comments!="") logEntry += "," + comments;
if(name!="") logEntry += "," + name;
QTextStream out(&f); QTextStream out(&f);
out << logEntry << endl; out << logEntry << endl;
f.close(); f.close();

File diff suppressed because it is too large Load Diff

View File

@ -43,6 +43,8 @@ public slots:
void readFromStdout(); void readFromStdout();
void readFromStderr(); void readFromStderr();
void jt9_error(); void jt9_error();
void setXIT(int n);
void setFreq4(int rxFreq, int txFreq);
protected: protected:
virtual void keyPressEvent( QKeyEvent *e ); virtual void keyPressEvent( QKeyEvent *e );
@ -72,7 +74,6 @@ private slots:
void on_actionOpen_next_in_directory_triggered(); void on_actionOpen_next_in_directory_triggered();
void on_actionDecode_remaining_files_in_directory_triggered(); void on_actionDecode_remaining_files_in_directory_triggered();
void on_actionDelete_all_wav_files_in_SaveDir_triggered(); void on_actionDelete_all_wav_files_in_SaveDir_triggered();
void on_actionF4_sets_Tx6_triggered();
void on_actionNone_triggered(); void on_actionNone_triggered();
void on_actionSave_all_triggered(); void on_actionSave_all_triggered();
void on_actionKeyboard_shortcuts_triggered(); void on_actionKeyboard_shortcuts_triggered();
@ -97,13 +98,10 @@ private slots:
void on_logQSOButton_clicked(); void on_logQSOButton_clicked();
void on_actionAFMHot_triggered(); void on_actionAFMHot_triggered();
void on_actionBlue_triggered(); void on_actionBlue_triggered();
void on_actionJT9_2_triggered();
void on_actionJT9_1_triggered(); void on_actionJT9_1_triggered();
void on_actionJT9_5_triggered(); void on_actionJT65_triggered();
void on_actionJT9_30_triggered(); void on_actionJT9_JT65_triggered();
void on_actionJT9_10_triggered();
void on_TxFreqSpinBox_valueChanged(int arg1); void on_TxFreqSpinBox_valueChanged(int arg1);
void on_actionSave_synced_triggered();
void on_actionSave_decoded_triggered(); void on_actionSave_decoded_triggered();
void on_actionQuickDecode_triggered(); void on_actionQuickDecode_triggered();
void on_actionMediumDecode_triggered(); void on_actionMediumDecode_triggered();
@ -147,7 +145,6 @@ private slots:
void on_rptSpinBox_valueChanged(int n); void on_rptSpinBox_valueChanged(int n);
void on_action_73TxDisable_triggered(bool checked); void on_action_73TxDisable_triggered(bool checked);
void on_actionRunaway_Tx_watchdog_triggered(bool checked); void on_actionRunaway_Tx_watchdog_triggered(bool checked);
void on_actionTx2QSO_triggered(bool checked);
void killFile(); void killFile();
void on_tuneButton_clicked(); void on_tuneButton_clicked();
void on_actionAllow_multiple_instances_triggered(bool checked); void on_actionAllow_multiple_instances_triggered(bool checked);
@ -155,10 +152,11 @@ private slots:
void on_pbT2R_clicked(); void on_pbT2R_clicked();
void acceptQSO2(bool accepted); void acceptQSO2(bool accepted);
void on_bandComboBox_activated(int index); void on_bandComboBox_activated(int index);
void on_readFreq_clicked(); void on_readFreq_clicked();
void on_pbTxMode_clicked();
void on_actionLockTxFreq_triggered(bool checked); void on_RxFreqSpinBox_valueChanged(int n);
void on_cbTxLock_clicked(bool checked);
void on_actionTx2QSO_triggered(bool checked);
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
@ -168,15 +166,13 @@ private:
qint64 m_msErase; qint64 m_msErase;
qint64 m_secBandChanged; qint64 m_secBandChanged;
qint32 m_nDevIn;
qint32 m_nDevOut;
qint32 m_idInt; qint32 m_idInt;
qint32 m_waterfallAvg; qint32 m_waterfallAvg;
qint32 m_pttMethodIndex; qint32 m_pttMethodIndex;
qint32 m_QSOfreq0;
qint32 m_ntx; qint32 m_ntx;
qint32 m_pttPort; qint32 m_pttPort;
qint32 m_timeout; qint32 m_timeout;
qint32 m_rxFreq;
qint32 m_txFreq; qint32 m_txFreq;
qint32 m_setftx; qint32 m_setftx;
qint32 m_ndepth; qint32 m_ndepth;
@ -184,7 +180,7 @@ private:
qint32 m_RxLog; qint32 m_RxLog;
qint32 m_nutc0; qint32 m_nutc0;
qint32 m_nrx; qint32 m_nrx;
qint32 m_hsym0; qint32 m_hsym;
qint32 m_paInDevice; qint32 m_paInDevice;
qint32 m_paOutDevice; qint32 m_paOutDevice;
qint32 m_TRperiod; qint32 m_TRperiod;
@ -205,12 +201,12 @@ private:
qint32 m_handshakeIndex; qint32 m_handshakeIndex;
qint32 m_ncw; qint32 m_ncw;
qint32 m_secID; qint32 m_secID;
qint32 m_COMportOpen;
qint32 m_iptt;
qint32 m_band; qint32 m_band;
qint32 m_repeatMsg; qint32 m_repeatMsg;
qint32 m_watchdogLimit; qint32 m_watchdogLimit;
qint32 m_poll; qint32 m_poll;
qint32 m_fMin;
qint32 m_fMax;
bool m_monitoring; bool m_monitoring;
bool m_transmitting; bool m_transmitting;
@ -221,15 +217,12 @@ private:
bool m_auto; bool m_auto;
bool m_restart; bool m_restart;
bool m_startAnother; bool m_startAnother;
bool m_saveSynced;
bool m_saveDecoded; bool m_saveDecoded;
bool m_saveAll; bool m_saveAll;
bool m_widebandDecode; bool m_widebandDecode;
bool m_kb8rq;
bool m_call3Modified; bool m_call3Modified;
bool m_dataAvailable; bool m_dataAvailable;
bool m_killAll; bool m_killAll;
bool m_bsynced;
bool m_bdecoded; bool m_bdecoded;
bool m_monitorStartOFF; bool m_monitorStartOFF;
bool m_pskReporter; bool m_pskReporter;
@ -250,7 +243,6 @@ private:
bool m_73TxDisable; bool m_73TxDisable;
bool m_sent73; bool m_sent73;
bool m_runaway; bool m_runaway;
bool m_tx2QSO;
bool m_tune; bool m_tune;
bool m_bRigOpen; bool m_bRigOpen;
bool m_bMultipleOK; bool m_bMultipleOK;
@ -260,6 +252,10 @@ private:
bool m_lockTxFreq; bool m_lockTxFreq;
bool m_saveTxPower; bool m_saveTxPower;
bool m_saveComments; bool m_saveComments;
bool m_tx2QSO;
bool m_CATerror;
bool m_bSplit;
bool m_bXIT;
char m_decoded[80]; char m_decoded[80];
@ -308,6 +304,7 @@ private:
QString m_palette; QString m_palette;
QString m_dateTime; QString m_dateTime;
QString m_mode; QString m_mode;
QString m_modeTx;
QString m_fname; QString m_fname;
QString m_rpt; QString m_rpt;
QString m_rptSent; QString m_rptSent;
@ -366,13 +363,15 @@ extern int ptt(int nport, int ntx, int* iptt, int* nopen);
extern "C" { extern "C" {
//----------------------------------------------------- C and Fortran routines //----------------------------------------------------- C and Fortran routines
void symspec_(int* k, int* ntrperiod, int* nsps, int* ingain, void symspec_(int* k, int* ntrperiod, int* nsps, int* ingain, float* slope,
float* px, float s[], float red[], float* px, float s[], float* df3, int* nhsym, int* npts8);
float* df3, int* nhsym, int* npts8);
void genjt9_(char* msg, int* ichk, char* msgsent, int itone[], void genjt9_(char* msg, int* ichk, char* msgsent, int itone[],
int* itext, int len1, int len2); 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); bool stdmsg_(const char* msg, int len);
void azdist_(char* MyGrid, char* HisGrid, double* utch, int* nAz, int* nEl, void azdist_(char* MyGrid, char* HisGrid, double* utch, int* nAz, int* nEl,

File diff suppressed because it is too large Load Diff

View File

@ -15,8 +15,8 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
setAttribute(Qt::WA_OpaquePaintEvent, false); setAttribute(Qt::WA_OpaquePaintEvent, false);
setAttribute(Qt::WA_NoSystemBackground, true); setAttribute(Qt::WA_NoSystemBackground, true);
m_StartFreq = 1000; m_StartFreq = 0;
m_nSpan=1000; //Units: Hz m_nSpan=2; //used for FFT bins/pixel
m_fSpan=(float)m_nSpan; m_fSpan=(float)m_nSpan;
m_hdivs = HORZ_DIVS; m_hdivs = HORZ_DIVS;
m_FreqUnits = 1; m_FreqUnits = 1;
@ -27,7 +27,7 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
m_ScalePixmap = QPixmap(0,0); m_ScalePixmap = QPixmap(0,0);
m_OverlayPixmap = QPixmap(0,0); m_OverlayPixmap = QPixmap(0,0);
m_Size = QSize(0,0); m_Size = QSize(0,0);
m_fQSO = 1020; m_rxFreq = 1020;
m_line = 0; m_line = 0;
m_fSample = 12000; m_fSample = 12000;
m_nsps=6912; m_nsps=6912;
@ -83,7 +83,7 @@ void CPlotter::paintEvent(QPaintEvent *) // paintEvent()
m_paintEventBusy=false; m_paintEventBusy=false;
} }
void CPlotter::draw(float swide[], float red[], int i0) //draw() void CPlotter::draw(float swide[], int i0) //draw()
{ {
int j,y2; int j,y2;
float y; float y;
@ -98,18 +98,18 @@ void CPlotter::draw(float swide[], float red[], int i0) //draw()
QPainter painter2D(&m_2DPixmap); QPainter painter2D(&m_2DPixmap);
painter2D.setPen(Qt::green); painter2D.setPen(Qt::green);
if(m_bJT9Sync) painter2D.setPen(Qt::red);
QPoint LineBuf[MAX_SCREENSIZE]; QPoint LineBuf[MAX_SCREENSIZE];
j=0; j=0;
int iz=XfromFreq(2000.0); // int iz=XfromFreq(2000.0);
// for(int i=0; i<m_w; i++) { int iz=XfromFreq(5000.0);
m_fMax=FreqfromX(iz);
for(int i=0; i<iz; i++) { for(int i=0; i<iz; i++) {
if(i>iz) swide[i]=0; if(i>iz) swide[i]=0;
y=0.0; y=0.0;
if(swide[i]>0.0) y = 10.0*log10(swide[i]); 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<0) y1=0;
if (y1>254) y1=254; if (y1>254) y1=254;
if (swide[i]>1.e29) y1=255; 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; 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); if(i==iz-1) painter2D.drawPolyline(LineBuf,j);
LineBuf[j].setX(i); LineBuf[j].setX(i);
LineBuf[j].setY(m_h-(y2+0.8*m_h)); 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_OverlayPixmap.isNull()) return;
if(m_WaterfallPixmap.isNull()) return; if(m_WaterfallPixmap.isNull()) return;
int w = m_WaterfallPixmap.width(); 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}; // int nHzDiv[11]={0,50,100,200,200,200,500,500,500,500,500};
float pixperdiv; float pixperdiv;
@ -180,12 +180,15 @@ void CPlotter::DrawOverlay() //DrawOverlay()
double df = m_binsPerPixel*m_fftBinWidth; double df = m_binsPerPixel*m_fftBinWidth;
pixperdiv = m_freqPerDiv/df; pixperdiv = m_freqPerDiv/df;
y = m_h2 - m_h2/VERT_DIVS; 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 for( int i=1; i<m_hdivs; i++) //draw vertical grids
{ {
x = (int)( (float)i*pixperdiv ); x = (int)( (float)i*pixperdiv );
painter.setPen(QPen(Qt::white, 1,Qt::DotLine)); if(x >= 0 and x<=m_w) {
painter.drawLine(x, 0, x , y); painter.setPen(QPen(Qt::white, 1,Qt::DotLine));
painter.drawLine(x, m_h2-5, x , m_h2); painter.drawLine(x, 0, x , y);
painter.drawLine(x, m_h2-5, x , m_h2);
}
} }
pixperdiv = (float)m_h2 / (float)VERT_DIVS; pixperdiv = (float)m_h2 / (float)VERT_DIVS;
@ -258,40 +261,30 @@ void CPlotter::DrawOverlay() //DrawOverlay()
} }
} }
x1=XfromFreq(m_fMin); float bw=9.0*12000.0/m_nsps;
int bw=9.0*12000.0/m_nsps; if(m_modeTx=="JT65") bw=66.0*11025.0/4096.0;
dx=XfromFreq(m_fMin+bw) - x1;
QPen pen0(Qt::green, 3); //Mark Rx Freq with green QPen pen0(Qt::green, 3); //Mark Rx Freq with green
painter0.setPen(pen0); painter0.setPen(pen0);
x1=XfromFreq(m_fQSO); x1=XfromFreq(m_rxFreq);
x2=x1+dx; x2=XfromFreq(m_rxFreq+bw);
painter0.drawLine(x1,24,x1,30); painter0.drawLine(x1,24,x1,30);
painter0.drawLine(x1,28,x2,28); painter0.drawLine(x1,28,x2,28);
painter0.drawLine(x2,24,x2,30); painter0.drawLine(x2,24,x2,30);
QPen pen2(Qt::blue, 3); //Mark the decoding range if(m_mode=="JT9+JT65") {
painter0.setPen(pen2); QPen pen2(Qt::blue, 3); //Mark the JT65 | JT9 divider
x1=XfromFreq(m_fMin); painter0.setPen(pen2);
if(x1<2) x1=2; x1=XfromFreq(m_fMin);
x2=x1+30; if(x1<2) x1=2;
// pen2.setWidth(6); x2=x1+30;
painter0.drawLine(x1,18,x1,28); painter0.drawLine(x1,8,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);
QPen pen1(Qt::red, 3); //Mark Tx freq with red QPen pen1(Qt::red, 3); //Mark Tx freq with red
painter0.setPen(pen1); painter0.setPen(pen1);
x1=XfromFreq(m_txFreq); x1=XfromFreq(m_txFreq);
x2=x1+dx; x2=XfromFreq(m_txFreq+bw);
painter0.drawLine(x1,17,x1,21); painter0.drawLine(x1,17,x1,21);
painter0.drawLine(x1,17,x2,17); painter0.drawLine(x1,17,x2,17);
painter0.drawLine(x2,17,x2,21); painter0.drawLine(x2,17,x2,21);
@ -310,7 +303,7 @@ void CPlotter::MakeFrequencyStrs() //MakeFrequencyStrs
int CPlotter::XfromFreq(float f) //XfromFreq() int CPlotter::XfromFreq(float f) //XfromFreq()
{ {
// float w = m_WaterfallPixmap.width(); // 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<0 ) return 0;
if(x>m_w) return m_w; if(x>m_w) return m_w;
return x; return x;
@ -318,7 +311,8 @@ int CPlotter::XfromFreq(float f) //XfromFreq()
float CPlotter::FreqfromX(int x) //FreqfromX() 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() void CPlotter::SetRunningState(bool running) //SetRunningState()
@ -362,10 +356,9 @@ int CPlotter::plotWidth(){return m_WaterfallPixmap.width();}
void CPlotter::UpdateOverlay() {DrawOverlay();} void CPlotter::UpdateOverlay() {DrawOverlay();}
void CPlotter::setDataFromDisk(bool b) {m_dataFromDisk=b;} void CPlotter::setDataFromDisk(bool b) {m_dataFromDisk=b;}
void CPlotter::setRxRange(int fMin, int fMax) void CPlotter::setRxRange(int fMin)
{ {
m_fMin=fMin; m_fMin=fMin;
m_fMax=fMax;
} }
void CPlotter::setBinsPerPixel(int n) // set nbpp void CPlotter::setBinsPerPixel(int n) // set nbpp
@ -380,43 +373,39 @@ int CPlotter::binsPerPixel() // get nbpp
return m_binsPerPixel; return m_binsPerPixel;
} }
void CPlotter::setFQSO(int x, bool bf) //setFQSO() void CPlotter::setRxFreq(int x, bool bf) //setRxFreq()
{ {
if(bf) { if(bf) {
m_fQSO=x; // x is freq in Hz m_rxFreq=x; // x is freq in Hz
m_xClick=XfromFreq(m_fQSO); m_xClick=XfromFreq(m_rxFreq);
} else { } else {
if(x<0) x=0; // x is pixel number if(x<0) x=0; // x is pixel number
if(x>m_Size.width()) x=m_Size.width(); 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; m_xClick=x;
} }
emit setFreq1(m_rxFreq,m_txFreq);
DrawOverlay(); DrawOverlay();
update(); update();
} }
void CPlotter::setFcal(int n) //setFcal() int CPlotter::rxFreq() {return m_rxFreq;} //get rxFreq
{
m_fCal=n;
}
int CPlotter::fQSO() {return m_fQSO;} //get fQSO
void CPlotter::mousePressEvent(QMouseEvent *event) //mousePressEvent void CPlotter::mousePressEvent(QMouseEvent *event) //mousePressEvent
{ {
int x=event->x(); int x=event->x();
setFQSO(x,false); // Wideband waterfall setRxFreq(x,false); // Wideband waterfall
bool ctrl = (event->modifiers() & Qt::ControlModifier); bool ctrl = (event->modifiers() & Qt::ControlModifier);
int n=1; int n=1;
if(ctrl) n+=100; if(ctrl) n+=100;
emit freezeDecode1(n); emit freezeDecode1(n);
if(ctrl) setTxFreq(m_fQSO); if(ctrl or m_lockTxFreq) setTxFreq(m_rxFreq);
} }
void CPlotter::mouseDoubleClickEvent(QMouseEvent *event) //mouse2click void CPlotter::mouseDoubleClickEvent(QMouseEvent *event) //mouse2click
{ {
// int x=event->x(); // int x=event->x();
// setFQSO(x,false); // setRxFreq(x,false);
bool ctrl = (event->modifiers() & Qt::ControlModifier); bool ctrl = (event->modifiers() & Qt::ControlModifier);
int n=2; int n=2;
if(ctrl) n+=100; if(ctrl) n+=100;
@ -536,6 +525,22 @@ void CPlotter::setNsps(int ntrperiod, int nsps)
void CPlotter::setTxFreq(int n) //setTol() void CPlotter::setTxFreq(int n) //setTol()
{ {
m_txFreq=n; m_txFreq=n;
emit setFreq1(m_rxFreq,m_txFreq);
DrawOverlay(); DrawOverlay();
update(); update();
} }
void CPlotter::setMode(QString mode)
{
m_mode=mode;
}
void CPlotter::setModeTx(QString modeTx)
{
m_modeTx=modeTx;
}
int CPlotter::getFmax()
{
return m_fMax;
}

View File

@ -30,19 +30,20 @@ public:
QSize minimumSizeHint() const; QSize minimumSizeHint() const;
QSize sizeHint() const; QSize sizeHint() const;
QColor m_ColorTbl[256]; QColor m_ColorTbl[256];
bool m_bCurrent; bool m_bCurrent;
bool m_bCumulative; bool m_bCumulative;
bool m_bJT9Sync; bool m_lockTxFreq;
int m_plotZero;
int m_plotGain;
float m_fSpan; float m_fSpan;
qint32 m_plotZero;
qint32 m_plotGain;
qint32 m_nSpan; qint32 m_nSpan;
qint32 m_binsPerPixel; qint32 m_binsPerPixel;
qint32 m_fQSO;
qint32 m_fCal;
qint32 m_w; 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 SetRunningState(bool running);
void setPlotZero(int plotZero); void setPlotZero(int plotZero);
int getPlotZero(); int getPlotZero();
@ -54,22 +55,25 @@ public:
void setNSpan(int n); void setNSpan(int n);
void UpdateOverlay(); void UpdateOverlay();
void setDataFromDisk(bool b); void setDataFromDisk(bool b);
void setRxRange(int fMin, int fMax); void setRxRange(int fMin);
void setBinsPerPixel(int n); void setBinsPerPixel(int n);
int binsPerPixel(); int binsPerPixel();
void setFQSO(int n, bool bf); void setRxFreq(int n, bool bf);
void setFcal(int n);
void DrawOverlay(); void DrawOverlay();
int fQSO(); int rxFreq();
void setPalette(QString palette); void setPalette(QString palette);
void setFsample(int n); void setFsample(int n);
void setNsps(int ntrperiod, int nsps); void setNsps(int ntrperiod, int nsps);
void setTxFreq(int n); void setTxFreq(int n);
void setMode(QString mode);
void setModeTx(QString modeTx);
double fGreen(); double fGreen();
void SetPercent2DScreen(int percent){m_Percent2DScreen=percent;} void SetPercent2DScreen(int percent){m_Percent2DScreen=percent;}
int getFmax();
signals: signals:
void freezeDecode1(int n); void freezeDecode1(int n);
void setFreq1(int rxFreq, int txFreq);
protected: protected:
//re-implemented widget event handlers //re-implemented widget event handlers
@ -92,16 +96,21 @@ private:
QSize m_Size; QSize m_Size;
QString m_Str; QString m_Str;
QString m_HDivText[483]; QString m_HDivText[483];
QString m_mode;
QString m_modeTx;
bool m_Running; bool m_Running;
bool m_paintEventBusy; bool m_paintEventBusy;
bool m_dataFromDisk;
double m_fGreen; double m_fGreen;
double m_fftBinWidth; double m_fftBinWidth;
qint64 m_StartFreq; qint64 m_StartFreq;
qint32 m_dBStepSize; qint32 m_dBStepSize;
qint32 m_FreqUnits; qint32 m_FreqUnits;
qint32 m_hdivs; qint32 m_hdivs;
bool m_dataFromDisk;
char m_sutc[6];
qint32 m_line; qint32 m_line;
qint32 m_fSample; qint32 m_fSample;
qint32 m_i0; qint32 m_i0;
@ -113,10 +122,13 @@ private:
qint32 m_h1; qint32 m_h1;
qint32 m_h2; qint32 m_h2;
qint32 m_TRperiod; qint32 m_TRperiod;
qint32 m_rxFreq;
qint32 m_txFreq; qint32 m_txFreq;
qint32 m_fMin; qint32 m_fMin;
qint32 m_fMax; qint32 m_fMax;
char m_sutc[6];
private slots: private slots:
void mousePressEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent *event);

View File

@ -39,10 +39,10 @@ PSK_Reporter::PSK_Reporter(QObject *parent) :
void PSK_Reporter::setLocalStation(QString call, QString gridSquare, QString programInfo) void PSK_Reporter::setLocalStation(QString call, QString gridSquare, QString programInfo)
{ {
m_rxCall = call; m_rxCall = call;
m_rxGrid = gridSquare; m_rxGrid = gridSquare;
m_progId = programInfo; m_progId = programInfo;
reportTimer->start(5*60*1000); // 5 minutes; reportTimer->start(5*60*1000); // 5 minutes;
} }
void PSK_Reporter::addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time ) 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 // Get IP address for pskreporter.info and send report via UDP
QHostInfo info = QHostInfo::fromName("report.pskreporter.info"); QHostInfo info = QHostInfo::fromName("report.pskreporter.info");
m_udpSocket->writeDatagram(report,info.addresses().at(0),4739); 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();
*/
} }

View File

@ -7,7 +7,7 @@
* Hamlib C++ interface is a frontend implementing wrapper functions. * Hamlib C++ interface is a frontend implementing wrapper functions.
*/ */
/* /**
* *
* Hamlib C++ bindings - main file * Hamlib C++ bindings - main file
* Copyright (c) 2001-2003 by Stephane Fillod * Copyright (c) 2001-2003 by Stephane Fillod
@ -36,7 +36,7 @@
#include <hamlib/rig.h> #include <hamlib/rig.h>
#include "rigclass.h" #include "rigclass.h"
#include <QDebug> #include <QDebug>
#include <QHostAddress>
static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg); static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg);
@ -78,9 +78,16 @@ int Rig::init(rig_model_t rig_model)
} }
int Rig::open(int n) { int Rig::open(int n) {
#ifdef WIN32 // Ham radio Deluxe only on Windows m_hrd=false;
m_hrd=(n==9999); m_cmndr=false;
if(m_hrd) { 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; bool bConnect=false;
bConnect = HRDInterfaceConnect(L"localhost",7809); bConnect = HRDInterfaceConnect(L"localhost",7809);
if(bConnect) { if(bConnect) {
@ -92,12 +99,30 @@ int Rig::open(int n) {
m_hrd=false; m_hrd=false;
return -1; 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) { int Rig::close(void) {
@ -105,6 +130,9 @@ int Rig::close(void) {
if(m_hrd) { if(m_hrd) {
HRDInterfaceDisconnect(); HRDInterfaceDisconnect();
return 0; return 0;
} else if(m_cmndr) {
socket->close();
return 0;
} else } else
#endif #endif
{ {
@ -132,13 +160,70 @@ int Rig::setFreq(freq_t freq, vfo_t vfo) {
} else { } else {
return -1; 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 } else
#endif #endif
{ {
return rig_set_freq(theRig, vfo, freq); 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 Rig::getFreq(vfo_t vfo)
{ {
freq_t freq; freq_t freq;
@ -150,10 +235,29 @@ freq_t Rig::getFreq(vfo_t vfo)
HRDInterfaceFreeString(freqString); HRDInterfaceFreeString(freqString);
freq=t2.toDouble(); freq=t2.toDouble();
return freq; 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 } else
#endif #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; return freq;
} }
} }
@ -168,18 +272,6 @@ rmode_t Rig::getMode(pbwidth_t& width, vfo_t vfo) {
return mode; 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) int Rig::setPTT(ptt_t ptt, vfo_t vfo)
{ {
#ifdef WIN32 // Ham Radio Deluxe only on Windows #ifdef WIN32 // Ham Radio Deluxe only on Windows
@ -201,6 +293,16 @@ int Rig::setPTT(ptt_t ptt, vfo_t vfo)
} else { } else {
return -1; 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 } else
#endif #endif
{ {

View File

@ -25,15 +25,18 @@
#include <hamlib/rig.h> #include <hamlib/rig.h>
#include <iostream> #include <iostream>
#include <QString> #include <QString>
#include <QTcpSocket>
extern QTcpSocket* socket;
class BACKEND_IMPEXP Rig { class BACKEND_IMPEXP Rig {
private: private:
RIG* theRig; // Global ref. to the rig RIG* theRig; // Global ref. to the rig
#ifdef WIN32 // Ham Radio Deluxe only on Windows
bool m_hrd; bool m_hrd;
#endif bool m_cmndr;
QString m_context; QString m_context;
protected: protected:
public: public:
Rig(); Rig();
@ -59,7 +62,8 @@ public:
rmode_t getMode(pbwidth_t&, vfo_t vfo = RIG_VFO_CURR); rmode_t getMode(pbwidth_t&, vfo_t vfo = RIG_VFO_CURR);
int setVFO(vfo_t); int setVFO(vfo_t);
vfo_t getVFO(); 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); int setPTT (ptt_t ptt, vfo_t vfo = RIG_VFO_CURR);
ptt_t getPTT (vfo_t vfo = RIG_VFO_CURR); ptt_t getPTT (vfo_t vfo = RIG_VFO_CURR);

View File

@ -2,7 +2,8 @@
#include <stdexcept> #include <stdexcept>
#define FRAMES_PER_BUFFER 1024 #define FRAMES_PER_BUFFER 1024
#define NSMAX 1365 //#define NSMAX 1365
#define NSMAX 6827
#define NTMAX 120 #define NTMAX 120
extern "C" { extern "C" {
@ -10,7 +11,7 @@ extern "C" {
extern struct { extern struct {
float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran
float savg[NSMAX]; float savg[NSMAX];
float c0[2*NTMAX*1500]; // float c0[2*NTMAX*1500];
short int d2[NTMAX*12000]; short int d2[NTMAX*12000];
int nutc; //UTC as integer, HHMM int nutc; //UTC as integer, HHMM
int ndiskdat; //1 ==> data read from *.wav file int ndiskdat; //1 ==> data read from *.wav file
@ -26,8 +27,8 @@ extern struct {
int nsave; int nsave;
int nagain; int nagain;
int ndepth; int ndepth;
int nrxlog; int ntxmode;
int nfsample; int nmode;
char datetime[20]; char datetime[20];
} jt9com_; } jt9com_;
} }
@ -60,7 +61,7 @@ extern "C" int a2dCallback( const void *inputBuffer, void *outputBuffer,
udata->ncall++; udata->ncall++;
if( (statusFlags&paInputOverflow) != 0) { if( (statusFlags&paInputOverflow) != 0) {
qDebug() << "Input Overflow"; qDebug() << "Input Overflow in a2dCallback";
} }
if(udata->bzero) { //Start of a new Rx sequence if(udata->bzero) { //Start of a new Rx sequence
udata->kin=0; //Reset buffer pointer udata->kin=0; //Reset buffer pointer

View File

@ -7,7 +7,7 @@ extern "C" {
} }
extern float gran(); //Noise generator (for tests only) 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 icw[250]; //Dits for CW ID
extern int outBufSize; extern int outBufSize;
extern bool btxok; extern bool btxok;
@ -17,10 +17,12 @@ extern double outputLatency;
typedef struct //Parameters sent to or received from callback function typedef struct //Parameters sent to or received from callback function
{ {
double txsnrdb; double txsnrdb;
int nsps; double dnsps;
int ntrperiod; int ntrperiod;
int ntxfreq; int ntxfreq;
int xit;
int ncall; int ncall;
int nsym;
bool txMute; bool txMute;
bool bRestart; bool bRestart;
bool btune; bool btune;
@ -45,6 +47,7 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
static double fac; static double fac;
static double amp; static double amp;
static int ic=0,j=0; static int ic=0,j=0;
static int isym0=-999;
static short int i2; static short int i2;
int isym,nspd; int isym,nspd;
@ -58,7 +61,7 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
udata->bRestart=false; udata->bRestart=false;
srand(mstr); //Initialize random seed 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->btune) isym=0; //If tuning, send pure tone
if(udata->txsnrdb < 0.0) { if(udata->txsnrdb < 0.0) {
snr=pow(10.0,0.05*(udata->txsnrdb-6.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(snr>1.0) fac=3000.0/snr;
} }
if(isym>=85 and icw[0]>0) { //Output the CW ID if(isym>=udata->nsym and icw[0]>0) { //Output the CW ID
freq=udata->ntxfreq; freq=udata->ntxfreq - udata->xit;
dphi=twopi*freq/48000.0; dphi=twopi*freq/48000.0;
// float wpm=20.0; // float wpm=20.0;
// int nspd=1.2*48000.0/wpm; // int nspd=1.2*48000.0/wpm;
// nspd=3072; //18.75 WPM // nspd=3072; //18.75 WPM
nspd=2048 + 512; //22.5 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++ ) { for(uint i=0 ; i<framesToProcess; i++ ) {
phi += dphi; phi += dphi;
if(phi>twopi) phi -= twopi; if(phi>twopi) phi -= twopi;
@ -99,17 +103,22 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
return paContinue; return paContinue;
} }
baud=12000.0/udata->nsps; baud=12000.0/udata->dnsps;
freq=udata->ntxfreq + itone[isym]*baud;
dphi=twopi*freq/48000.0;
amp=32767.0; amp=32767.0;
int i0=84.983*4.0*udata->nsps; int i0=(udata->nsym-0.017)*4.0*udata->dnsps;
int i1=85*4*udata->nsps; int i1=udata->nsym*4.0*udata->dnsps;
if(udata->btune) { //If tuning, no ramp down if(udata->btune) { //If tuning, no ramp down
i0=999*udata->nsps; i0=999*udata->dnsps;
i1=i0; i1=i0;
} }
for(uint i=0 ; i<framesToProcess; i++ ) { 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; phi += dphi;
if(phi>twopi) phi -= twopi; if(phi>twopi) phi -= twopi;
if(ic>i0) amp=0.98*amp; if(ic>i0) amp=0.98*amp;
@ -160,9 +169,15 @@ void SoundOutThread::run()
} }
udata.txsnrdb=99.0; 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.ntrperiod=m_TRperiod;
udata.ntxfreq=m_txFreq; udata.ntxfreq=m_txFreq;
udata.xit=m_xit;
udata.ncall=0; udata.ncall=0;
udata.txMute=m_txMute; udata.txMute=m_txMute;
udata.bRestart=true; udata.bRestart=true;
@ -193,7 +208,12 @@ void SoundOutThread::run()
if (qe) break; if (qe) break;
udata.txsnrdb=m_txsnrdb; 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.ntrperiod=m_TRperiod;
udata.ntxfreq=m_txFreq; udata.ntxfreq=m_txFreq;
udata.txMute=m_txMute; udata.txMute=m_txMute;
@ -227,6 +247,10 @@ void SoundOutThread::setTxFreq(int n)
m_txFreq=n; m_txFreq=n;
} }
void SoundOutThread::setXIT(int n)
{
m_xit=n;
}
void SoundOutThread::setTxSNR(double snr) void SoundOutThread::setTxSNR(double snr)
{ {

View File

@ -27,19 +27,24 @@ public:
void setOutputDevice(qint32 n); void setOutputDevice(qint32 n);
void setPeriod(int ntrperiod, int nsps); void setPeriod(int ntrperiod, int nsps);
void setTxFreq(int n); void setTxFreq(int n);
void setXIT(int n);
void setTxSNR(double snr); void setTxSNR(double snr);
void setTune(bool b); void setTune(bool b);
double samFacOut(); double samFacOut();
bool quitExecution; //If true, thread exits gracefully bool quitExecution; //If true, thread exits gracefully
QString m_modeTx;
// Private members // Private members
private: private:
double m_txsnrdb; //if < 0, add noise to Tx audio double m_txsnrdb; //if < 0, add noise to Tx audio
double m_SamFacOut; //(Output sample rate)/48000.0 double m_SamFacOut; //(Output sample rate)/48000.0
qint32 m_nDevOut; //Output device number qint32 m_nDevOut; //Output device number
qint32 m_TRperiod; //T/R period (s) qint32 m_TRperiod; //T/R period (s)
qint32 m_nsps; //Samples per symbol (at 12000 Hz) qint32 m_nsps; //Samples per symbol (at 12000 Hz)
qint32 m_txFreq; qint32 m_txFreq;
qint32 m_xit;
bool m_txOK; //Enable Tx audio bool m_txOK; //Enable Tx audio
bool m_txMute; //Mute temporarily bool m_txMute; //Mute temporarily
bool m_tune; bool m_tune;

View File

@ -18,7 +18,10 @@ WideGraph::WideGraph(QWidget *parent) :
connect(ui->widePlot, SIGNAL(freezeDecode1(int)),this, connect(ui->widePlot, SIGNAL(freezeDecode1(int)),this,
SLOT(wideFreezeDecode(int))); 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); ui->fMinSpinBox->setValue(m_fMin);
//Restore user's settings //Restore user's settings
@ -39,15 +42,13 @@ WideGraph::WideGraph(QWidget *parent) :
m_waterfallAvg = settings.value("WaterfallAvg",5).toInt(); m_waterfallAvg = settings.value("WaterfallAvg",5).toInt();
ui->waterfallAvgSpinBox->setValue(m_waterfallAvg); ui->waterfallAvgSpinBox->setValue(m_waterfallAvg);
ui->widePlot->m_bCurrent=settings.value("Current",false).toBool(); ui->widePlot->m_bCurrent=settings.value("Current",false).toBool();
ui->widePlot->m_bCumulative=settings.value("Cumulative",false).toBool(); ui->widePlot->m_bCumulative=settings.value("Cumulative",true).toBool();
ui->widePlot->m_bJT9Sync=settings.value("JT9Sync",true).toBool();
if(ui->widePlot->m_bCurrent) ui->spec2dComboBox->setCurrentIndex(0); if(ui->widePlot->m_bCurrent) ui->spec2dComboBox->setCurrentIndex(0);
if(ui->widePlot->m_bCumulative) ui->spec2dComboBox->setCurrentIndex(1); 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(); int nbpp=settings.value("BinsPerPixel",2).toInt();
ui->widePlot->setBinsPerPixel(nbpp); ui->widePlot->setBinsPerPixel(nbpp);
m_qsoFreq=settings.value("QSOfreq",1500).toInt(); m_slope=settings.value("Slope",0.0).toDouble();
ui->widePlot->setFQSO(m_qsoFreq,true); ui->slopeSpinBox->setValue(m_slope);
settings.endGroup(); settings.endGroup();
} }
@ -72,18 +73,16 @@ void WideGraph::saveSettings()
settings.setValue("WaterfallAvg",ui->waterfallAvgSpinBox->value()); settings.setValue("WaterfallAvg",ui->waterfallAvgSpinBox->value());
settings.setValue("Current",ui->widePlot->m_bCurrent); settings.setValue("Current",ui->widePlot->m_bCurrent);
settings.setValue("Cumulative",ui->widePlot->m_bCumulative); settings.setValue("Cumulative",ui->widePlot->m_bCumulative);
settings.setValue("JT9Sync",ui->widePlot->m_bJT9Sync);
settings.setValue("BinsPerPixel",ui->widePlot->binsPerPixel()); settings.setValue("BinsPerPixel",ui->widePlot->binsPerPixel());
settings.setValue("QSOfreq",ui->widePlot->fQSO()); settings.setValue("Slope",m_slope);
settings.endGroup(); settings.endGroup();
} }
void WideGraph::dataSink2(float s[], float red[], float df3, int ihsym, void WideGraph::dataSink2(float s[], float df3, int ihsym,
int ndiskdata) int ndiskdata)
{ {
static float splot[NSMAX]; static float splot[NSMAX];
static float swide[2048]; static float swide[2048];
static float rwide[2048];
int nbpp = ui->widePlot->binsPerPixel(); int nbpp = ui->widePlot->binsPerPixel();
static int n=0; 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 w=ui->widePlot->plotWidth();
int i0=-1; //### int i0=-1; //###
int i=i0; int i=i0;
int jz=1000.0/df3; int jz=5000.0/(nbpp*df3);
for (int j=0; j<jz; j++) { for (int j=0; j<jz; j++) {
float sum=0; float sum=0;
float rsum=0;
for (int k=0; k<nbpp; k++) { for (int k=0; k<nbpp; k++) {
i++; i++;
sum += splot[i]; sum += splot[i];
rsum += red[i];
} }
swide[j]=sum; swide[j]=sum;
rwide[j]=rsum/nbpp;
// if(lstrong[1 + i/32]!=0) swide[j]=-smax; //Tag strong signals
} }
// Time according to this computer // Time according to this computer
@ -128,7 +123,7 @@ void WideGraph::dataSink2(float s[], float red[], float df3, int ihsym,
} }
} }
m_ntr0=ntr; 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; m_rxFreq=n;
ui->widePlot->setFQSO(m_qsoFreq,true); ui->widePlot->setRxFreq(m_rxFreq,true);
if(m_lockTxFreq) setTxFreq(m_qsoFreq); if(m_lockTxFreq) setTxFreq(m_rxFreq);
} }
int WideGraph::QSOfreq() int WideGraph::rxFreq()
{ {
return ui->widePlot->fQSO(); return ui->widePlot->rxFreq();
} }
int WideGraph::nSpan() int WideGraph::nSpan()
@ -204,9 +199,9 @@ void WideGraph::wideFreezeDecode(int n)
emit freezeDecode2(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->DrawOverlay();
ui->widePlot->update(); ui->widePlot->update();
} }
@ -218,19 +213,16 @@ int WideGraph::getFmin()
int WideGraph::getFmax() 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; m_fMin = n;
setRxRange(m_fMin,m_fMax); ui->fMinSpinBox->setValue(n);
} setRxRange(m_fMin);
void WideGraph::setFcal(int n)
{
m_fCal=n;
ui->widePlot->setFcal(n);
} }
void WideGraph::setPalette(QString palette) void WideGraph::setPalette(QString palette)
@ -252,28 +244,65 @@ void WideGraph::setPeriod(int ntrperiod, int nsps)
void WideGraph::setTxFreq(int n) void WideGraph::setTxFreq(int n)
{ {
emit setXIT2(n);
ui->widePlot->setTxFreq(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) void WideGraph::on_spec2dComboBox_currentIndexChanged(const QString &arg1)
{ {
ui->widePlot->m_bCurrent=false; ui->widePlot->m_bCurrent=false;
ui->widePlot->m_bCumulative=false; ui->widePlot->m_bCumulative=false;
ui->widePlot->m_bJT9Sync=false;
if(arg1=="Current") ui->widePlot->m_bCurrent=true; if(arg1=="Current") ui->widePlot->m_bCurrent=true;
if(arg1=="Cumulative") ui->widePlot->m_bCumulative=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) void WideGraph::on_fMinSpinBox_valueChanged(int n)
{ {
m_fMin=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; m_slope=d;
setRxRange(m_fMin,m_fMax);
} }
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);
}

View File

@ -14,34 +14,40 @@ public:
explicit WideGraph(QWidget *parent = 0); explicit WideGraph(QWidget *parent = 0);
~WideGraph(); ~WideGraph();
void dataSink2(float s[], float red[], float df3, int ihsym, void dataSink2(float s[], float df3, int ihsym, int ndiskdata);
int ndiskdata); void setRxFreq(int n);
void setQSOfreq(int n); int rxFreq();
int QSOfreq();
int nSpan(); int nSpan();
int nStartFreq(); int nStartFreq();
int getFmin(); int getFmin();
int getFmax(); int getFmax();
float fSpan(); float fSpan();
void saveSettings(); void saveSettings();
void setRxRange(int fMin, int fMax); void setRxRange(int fMin);
void setfMax(int n); void setFmin(int n);
void setFcal(int n);
void setPalette(QString palette); void setPalette(QString palette);
void setFsample(int n); void setFsample(int n);
void setPeriod(int ntrperiod, int nsps); void setPeriod(int ntrperiod, int nsps);
void setTxFreq(int n); void setTxFreq(int n);
void setMode(QString mode);
void setModeTx(QString modeTx);
void setSlope(double d);
void setLockTxFreq(bool b);
double getSlope();
double fGreen(); double fGreen();
qint32 m_qsoFreq; qint32 m_rxFreq;
bool m_lockTxFreq; qint32 m_txFreq;
signals: signals:
void freezeDecode2(int n); void freezeDecode2(int n);
void f11f12(int n); void f11f12(int n);
void setXIT2(int n);
void setFreq3(int rxFreq, int txFreq);
public slots: public slots:
void wideFreezeDecode(int n); void wideFreezeDecode(int n);
void setFreq2(int rxFreq, int txFreq);
protected: protected:
virtual void keyPressEvent( QKeyEvent *e ); virtual void keyPressEvent( QKeyEvent *e );
@ -53,11 +59,12 @@ private slots:
void on_gainSpinBox_valueChanged(int arg1); void on_gainSpinBox_valueChanged(int arg1);
void on_spec2dComboBox_currentIndexChanged(const QString &arg1); void on_spec2dComboBox_currentIndexChanged(const QString &arg1);
void on_fMinSpinBox_valueChanged(int n); void on_fMinSpinBox_valueChanged(int n);
void on_fMaxSpinBox_valueChanged(int n); void on_slopeSpinBox_valueChanged(double d);
private: private:
double m_slope;
qint32 m_waterfallAvg; qint32 m_waterfallAvg;
qint32 m_fCal;
qint32 m_fSample; qint32 m_fSample;
qint32 m_TRperiod; qint32 m_TRperiod;
qint32 m_nsps; qint32 m_nsps;
@ -65,6 +72,11 @@ private:
qint32 m_fMin; qint32 m_fMin;
qint32 m_fMax; qint32 m_fMax;
bool m_lockTxFreq;
QString m_mode;
QString m_modeTx;
Ui::WideGraph *ui; Ui::WideGraph *ui;
}; };

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>712</width> <width>799</width>
<height>326</height> <height>326</height>
</rect> </rect>
</property> </property>
@ -68,25 +68,6 @@
</property> </property>
</spacer> </spacer>
</item> </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> <item>
<widget class="QSpinBox" name="freqSpanSpinBox"> <widget class="QSpinBox" name="freqSpanSpinBox">
<property name="sizePolicy"> <property name="sizePolicy">
@ -97,7 +78,7 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>40</width> <width>110</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -113,6 +94,9 @@
<property name="suffix"> <property name="suffix">
<string/> <string/>
</property> </property>
<property name="prefix">
<string>Bins/Pixel </string>
</property>
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
</property> </property>
@ -143,25 +127,6 @@
</property> </property>
</spacer> </spacer>
</item> </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> <item>
<widget class="QSpinBox" name="waterfallAvgSpinBox"> <widget class="QSpinBox" name="waterfallAvgSpinBox">
<property name="sizePolicy"> <property name="sizePolicy">
@ -172,7 +137,7 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>80</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -185,6 +150,9 @@
<property name="toolTip"> <property name="toolTip">
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string> <string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
</property> </property>
<property name="prefix">
<string>N Avg </string>
</property>
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
</property> </property>
@ -210,26 +178,13 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_4"> <widget class="QSpinBox" name="gainSpinBox">
<property name="maximumSize"> <property name="minimumSize">
<size> <size>
<width>16777215</width> <width>80</width>
<height>25</height> <height>0</height>
</size> </size>
</property> </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"> <property name="maximumSize">
<size> <size>
<width>38</width> <width>38</width>
@ -239,6 +194,9 @@
<property name="toolTip"> <property name="toolTip">
<string>Scaling (dB) applied to spectra before plotting</string> <string>Scaling (dB) applied to spectra before plotting</string>
</property> </property>
<property name="prefix">
<string>Gain </string>
</property>
<property name="minimum"> <property name="minimum">
<number>-20</number> <number>-20</number>
</property> </property>
@ -264,26 +222,13 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QLabel" name="label"> <widget class="QSpinBox" name="zeroSpinBox">
<property name="maximumSize"> <property name="minimumSize">
<size> <size>
<width>16777215</width> <width>80</width>
<height>25</height> <height>0</height>
</size> </size>
</property> </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"> <property name="maximumSize">
<size> <size>
<width>38</width> <width>38</width>
@ -293,6 +238,12 @@
<property name="toolTip"> <property name="toolTip">
<string>Constant offset applied to waterfall data</string> <string>Constant offset applied to waterfall data</string>
</property> </property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Zero </string>
</property>
<property name="minimum"> <property name="minimum">
<number>-100</number> <number>-100</number>
</property> </property>
@ -301,6 +252,31 @@
</property> </property>
</widget> </widget>
</item> </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> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
@ -317,25 +293,6 @@
</property> </property>
</spacer> </spacer>
</item> </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> <item>
<widget class="QSpinBox" name="fMinSpinBox"> <widget class="QSpinBox" name="fMinSpinBox">
<property name="sizePolicy"> <property name="sizePolicy">
@ -344,17 +301,32 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="toolTip"> <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>
<property name="minimum"> <property name="minimum">
<number>1000</number> <number>0</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>2000</number> <number>5000</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<number>50</number> <number>100</number>
</property>
<property name="value">
<number>3000</number>
</property> </property>
</widget> </widget>
</item> </item>
@ -374,66 +346,6 @@
</property> </property>
</spacer> </spacer>
</item> </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> <item>
<widget class="QComboBox" name="spec2dComboBox"> <widget class="QComboBox" name="spec2dComboBox">
<property name="toolTip"> <property name="toolTip">
@ -452,11 +364,6 @@
<string>Cumulative</string> <string>Cumulative</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>JT9 Sync</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item> <item>

View File

@ -1,26 +1,29 @@
[Setup] [Setup]
AppName=wsjtx 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 AppCopyright=Copyright (C) 2001-2013 by Joe Taylor, K1JT
DefaultDirName=c:\wsjtx DefaultDirName=c:\wsjtx2
DefaultGroupName=wsjtx DefaultGroupName=wsjtx2
[Files] [Files]
Source: "c:\Users\joe\wsjt\wsjtx_install\wsjtx.exe"; DestDir: "{app}" Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\wsjtx.exe"; DestDir: "{app}"
Source: "c:\Users\joe\wsjt\wsjtx_install\jt9.exe"; DestDir: "{app}" Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\jt9.exe"; DestDir: "{app}"
Source: "c:\Users\joe\wsjt\wsjtx\lib\jt9code.exe"; DestDir: "{app}" Source: "c:\Users\joe\wsjt_k1jt\wsjtx\lib\jt9code.exe"; DestDir: "{app}"
Source: "c:\Users\joe\wsjt\wsjtx_install\rigctl.exe"; DestDir: "{app}" Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\rigctl.exe"; DestDir: "{app}"
Source: "c:\Users\joe\wsjt\wsjtx_install\wsjt.ico"; DestDir: "{app}" Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\kvasd.exe"; DestDir: "{app}"
Source: "c:\Users\joe\wsjt\wsjtx_install\afmhot.dat"; DestDir: "{app}"; Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\wsjt.ico"; DestDir: "{app}"
Source: "c:\Users\joe\wsjt\wsjtx_install\blue.dat"; DestDir: "{app}"; Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\afmhot.dat"; DestDir: "{app}";
Source: "c:\Users\joe\wsjt\wsjtx_install\CALL3.TXT"; DestDir: "{app}"; Flags: onlyifdoesntexist Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\blue.dat"; DestDir: "{app}";
Source: "c:\Users\joe\wsjt\QtSupport\*.dll"; DestDir: "{app}"; Source: "c:\Users\joe\wsjt_k1jt\wsjtx_install\CALL3.TXT"; DestDir: "{app}"; Flags: onlyifdoesntexist
Source: "c:\Users\joe\wsjt\wsjtx\shortcuts.txt"; DestDir: "{app}" Source: "c:\Users\joe\wsjt\QtSupport\*.dll"; DestDir: "{app}";
Source: "c:\Users\joe\wsjt\wsjtx\mouse_commands.txt"; DestDir: "{app}" Source: "c:\Users\joe\wsjt_k1jt\wsjtx\shortcuts.txt"; DestDir: "{app}"
Source: "c:\Users\joe\wsjt\wsjtx\WSJT-X_Users_Guide.pdf"; DestDir: "{app}" Source: "c:\Users\joe\wsjt_k1jt\wsjtx\mouse_commands.txt"; DestDir: "{app}"
Source: "c:\Users\joe\wsjt\wsjtx_install\save\Samples\130418_1742.wav"; DestDir: "{app}\save\Samples"; 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] [Icons]
Name: "{group}\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}\wsjtx"; Filename: "{app}\wsjtx.exe"; WorkingDir: {app}; IconFilename: {app}\wsjt.ico Name: "{userdesktop}\wsjtx2"; Filename: "{app}\wsjtx.exe"; WorkingDir: {app}; IconFilename: {app}\wsjt.ico

View File

@ -6,13 +6,12 @@
QT += core gui network QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += qwt thread CONFIG += thread
#CONFIG += console #CONFIG += console
TARGET = wsjtx TARGET = wsjtx
DESTDIR = ../wsjtx_install DESTDIR = ../wsjtx_install
#DESTDIR = ../qt5_install VERSION = 1.1
VERSION = 0.99
TEMPLATE = app TEMPLATE = app
DEFINES = QT4 DEFINES = QT4
@ -57,27 +56,22 @@ FORMS += mainwindow.ui about.ui devsetup.ui widegraph.ui \
RC_FILE = wsjtx.rc RC_FILE = wsjtx.rc
unix { unix {
INCLUDEPATH += $$quote(/usr/include/qwt-qt4)
LIBS += ../wsjtx/lib/libjt9.a LIBS += ../wsjtx/lib/libjt9.a
LIBS += -lhamlib LIBS += -lhamlib
LIBS += -lportaudio -lgfortran -lfftw3f -lqwt-qt4 LIBS += -lportaudio -lgfortran -lfftw3f
} }
win32 { win32 {
INCLUDEPATH += c:/qwt-6.0.1/include
INCLUDEPATH += ../../hamlib-1.2.15.3/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/src/.libs/libhamlib.dll.a
#LIBS += ../../hamlib-1.2.15.3/lib/gcc/libhamlib.dll.a
LIBS += ../wsjtx/lib/libjt9.a LIBS += ../wsjtx/lib/libjt9.a
LIBS += ../wsjtx/libfftw3f_win.a LIBS += ../wsjtx/libfftw3f_win.a
LIBS += ../wsjtx/libpskreporter.a LIBS += ../wsjtx/libpskreporter.a
LIBS += ../wsjtx/libHRDInterface001.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 += libwsock32
LIBS += C:/MinGW/lib/libf95.a 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
}
} }