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

View File

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

View File

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

View File

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

View File

@ -1,11 +1,19 @@
#include "getfile.h"
#include <QDir>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifdef WIN32
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <err.h>
#endif
void getfile(QString fname, int ntrperiod)
@ -123,6 +131,7 @@ float gran()
int ptt(int nport, int ntx, int* iptt, int* nopen)
{
// qDebug() << "getfile ptt(), line 129:" << nport << ntx << *iptt << *nopen;
#ifdef WIN32
static HANDLE hFile;
char s[10];
@ -130,7 +139,7 @@ int ptt(int nport, int ntx, int* iptt, int* nopen)
if(nport==0) {
*iptt=ntx;
return(0);
return 0;
}
if(ntx && (!(*nopen))) {
@ -160,6 +169,34 @@ int ptt(int nport, int ntx, int* iptt, int* nopen)
*nopen=0;
}
if((i3+i4+i5+i6+i9+i00)==-999) return 1; //Silence compiler warning
// qDebug() << "getfile ptt(), line 167:" << nport << ntx << *iptt << *nopen;
return 0;
#else
// qDebug() << "getfile ptt(), line 170:" << nport << ntx << *iptt << *nopen;
// ptt_(nport,ntx, iptt, nopen);
// int control=TIOCM_RTS | TIOCM_DTR;
int control = TIOCM_RTS;
static int fd;
if(*nopen==0) {
fd=open("/dev/ttyUSB0",O_RDWR | O_NONBLOCK);
if(fd<0) {
return -1;
}
*nopen=1;
}
if(ntx) {
ioctl(fd, TIOCMBIS, &control);
*iptt=1;
*nopen=1;
} else {
ioctl(fd, TIOCMBIC, &control);
close(fd);
*iptt=0;
*nopen=0;
}
return 0;
#endif
if((nport+ntx+(*iptt)==-99999)) *nopen=0; //Silence compiler warning

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* nopen);
#endif // GETFILE_H

View File

@ -20,7 +20,7 @@ CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
%.o: %.F90
${FC} ${FFLAGS} -c $<
all: libjt9.a jt9sim.exe jt9.exe jt9code.exe test9.exe
all: libjt9.a jt9sim.exe jt9.exe jt9code.exe jt65.exe
OBJS1 = pctile.o graycode.o sort.o ssort.o \
unpackmsg.o igray.o unpackcall.o unpackgrid.o \
@ -30,10 +30,15 @@ OBJS1 = pctile.o graycode.o sort.o ssort.o \
symspec.o analytic.o db.o genjt9.o \
packbits.o unpackbits.o encode232.o interleave9.o \
entail.o fano232.o gran.o sync9.o decode9.o \
fil3.o redsync.o decoder.o grid2n.o n2grid.o timer.o \
fil3.o decoder.o grid2n.o n2grid.o timer.o \
softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
fillcom.o chkss2.o zplot9.o
fillcom.o chkss2.o zplot9.o flat2.o \
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
move.o indexx.o graycode65.o twkfreq65.o smo121.o \
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o
libjt9.a: $(OBJS1)
ar cr libjt9.a $(OBJS1)
@ -54,15 +59,9 @@ OBJS4 = jt9code.o
jt9code.exe: $(OBJS4) libjt9.a
$(FC) -o jt9code.exe $(OBJS4) libjt9.a
OBJS5 = test9.o
test9.exe: $(OBJS5) libjt9.a
$(FC) -o test9.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
OBJS6 = wsjt24d.o wsjt24.o sync24.o decode24.o ps24.o flat1.o \
xcor24.o slope.o peakup.o interleave24.o getmet24.o smo.o \
deep24.o encode4.o chkmsg.o avemsg4.o extract4.o
wsjt24d.exe: $(OBJS6) libjt9.a
$(FC) -o wsjt24d.exe $(OBJS6) libjt9.a ../libfftw3f_win.a
OBJS5 = jt65.o
jt65.exe: $(OBJS5) libjt9.a
$(FC) -o jt65.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
INCPATH = -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore' \
-I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include' \
@ -75,9 +74,6 @@ sync9.o: sync9.f90 jt9sync.f90
spec9.o: spec9.f90 jt9sync.f90
$(FC) $(FFLAGS) -c spec9.f90
peakdf9.o: peakdf9.f90 jt9sync.f90
$(FC) $(FFLAGS) -c peakdf9.f90
peakdt9.o: peakdt9.f90 jt9sync.f90
$(FC) $(FFLAGS) -c peakdt9.f90
@ -105,7 +101,17 @@ sec_midn.o: sec_midn.f90
tstrig.o: tstrig.c
$(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
init_rs.o: init_rs.c
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
encode_rs.o: encode_rs.c
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
decode_rs.o: decode_rs.c
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
.PHONY : clean
clean:
rm -f *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt9test.exe
rm -f *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe

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 \
packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.o \
symspec.o analytic.o db.o genjt9.o ptt_unix.o \
symspec.o analytic.o db.o genjt9.o \
packbits.o unpackbits.o encode232.o interleave9.o \
entail.o fano232.o gran.o sync9.o decode9.o \
fil3.o redsync.o decoder.o grid2n.o n2grid.o timer.o \
fil3.o decoder.o grid2n.o n2grid.o timer.o \
softsym.o peakdt9.o getlags.o afc9.o fchisq.o \
twkfreq.o downsam9.o symspec2.o ipcomm.o sleep_msec.o \
stdmsg.o sec_midn.o cutil.o azdist.o geodist.o morse.o \
fillcom.o chkss2.o
fillcom.o chkss2.o zplot9.o flat2.o \
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
move.o indexx.o graycode65.o twkfreq65.o smo121.o \
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o
libjt9.a: $(OBJS1)
ar cr libjt9.a $(OBJS1)
@ -38,7 +43,7 @@ libjt9.a: $(OBJS1)
OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o
jt9: $(OBJS2) libjt9.a
jt9: $(OBJS2) libjt9.a
g++ -o jt9 $(OBJS2) libjt9.a -lfftw3f -lgfortran -lQtCore
cp jt9 ../../wsjtx_install
@ -84,6 +89,15 @@ ipcomm.o: ipcomm.cpp
sec_midn.o: sec_midn.f90
$(FC) -c -fno-second-underscore sec_midn.f90
init_rs.o: init_rs.c
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
encode_rs.o: encode_rs.c
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
decode_rs.o: decode_rs.c
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
.PHONY : clean
clean:

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

View File

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

View File

@ -1,23 +1,21 @@
subroutine decoder(ss,c0,nstandalone)
subroutine decoder(ss,id2)
! Decoder for JT9.
parameter (NTMAX=120)
parameter (NMAX=NTMAX*12000) !Total sample intervals per 30 minutes
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate
parameter (NSMAX=1365) !Max length of saved spectra
include 'constants.f90'
real ss(184,NSMAX)
character*22 msg
character*80 fmt
character*20 datetime
real*4 ccfred(NSMAX)
real*4 red2(NSMAX)
logical ccfok(NSMAX)
logical done(NSMAX)
logical done65
integer*2 id2(NTMAX*12000)
real*4 dd(NTMAX*12000)
integer*1 i1SoftSymbols(207)
complex c0(NDMAX)
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol, &
kin,nzhsym,nsave,nagain,ndepth,nrxlog,nfsample,datetime
kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,datetime
common/tracer/limtrace,lu
save
@ -27,48 +25,40 @@ subroutine decoder(ss,c0,nstandalone)
ndecodes0=0
ndecodes1=0
call timer('decoder ',0)
open(13,file='decoded.txt',status='unknown')
ntrMinutes=ntrperiod/60
newdat=1
open(22,file='kvasd.dat',access='direct',recl=1024,status='unknown')
npts65=52*12000
ntol65=20
done65=.false.
if(nmode.ge.65 .and. ntxmode.eq.65) then
if(newdat.ne.0) dd(1:npts65)=id2(1:npts65)
call jt65a(dd,npts65,newdat,nutc,nfa,nfqso,ntol65,nagain,ndecoded)
done65=.true.
endif
if(nmode.eq.65) go to 800
nsynced=0
ndecoded=0
nsps=0
if(ntrMinutes.eq.1) then
nsps=6912
df3=1500.0/2048.0
fmt='(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22)'
else if(ntrMinutes.eq.2) then
nsps=15360
df3=1500.0/2048.0
fmt='(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22)'
else if(ntrMinutes.eq.5) then
nsps=40960
df3=1500.0/6144.0
fmt='(i4.4,i4,i5,f6.1,f8.1,i4,3x,a22)'
else if(ntrMinutes.eq.10) then
nsps=82944
df3=1500.0/12288.0
fmt='(i4.4,i4,i5,f6.1,f8.2,i4,3x,a22)'
else if(ntrMinutes.eq.30) then
nsps=252000
df3=1500.0/32768.0
fmt='(i4.4,i4,i5,f6.1,f8.2,i4,3x,a22)'
endif
if(nsps.eq.0) stop 'Error: bad TRperiod' !Better: return an error code###
nsps=6912 !Params for JT9-1
df3=1500.0/2048.0
tstep=0.5*nsps/12000.0 !Half-symbol step (seconds)
done=.false.
ia=max(1,nint((nfa-1000)/df3))
ib=min(NSMAX,nint((nfb-1000)/df3))
nf0=0
ia=max(1,nint((nfa-nf0)/df3))
ib=min(NSMAX,nint((nfb-nf0)/df3))
lag1=-(2.5/tstep + 0.9999)
lag2=5.0/tstep + 0.9999
call timer('sync9 ',0)
call sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipk)
call timer('sync9 ',1)
if(newdat.ne.0) then
call timer('sync9 ',0)
call sync9(ss,nzhsym,lag1,lag2,ia,ib,ccfred,red2,ipk)
call timer('sync9 ',1)
endif
nsps8=nsps/8
df8=1500.0/nsps8
@ -94,24 +84,22 @@ subroutine decoder(ss,c0,nstandalone)
ccfok(ia:ib)=.true.
nfa1=nfqso-ntol
nfb1=nfqso+ntol
ia=max(1,nint((nfa1-1000)/df3))
ib=min(NSMAX,nint((nfb1-1000)/df3))
ia=max(1,nint((nfa1-nf0)/df3))
ib=min(NSMAX,nint((nfb1-nf0)/df3))
ia1=ia
ib1=ib
else
nfa1=nfa
nfb1=nfb
ia=max(1,nint((nfa1-1000)/df3))
ib=min(NSMAX,nint((nfb1-1000)/df3))
ia=max(1,nint((nfa1-nf0)/df3))
ib=min(NSMAX,nint((nfb1-nf0)/df3))
do i=ia,ib
ccfok(i)=ccfred(i).gt.ccflim .and. red2(i).gt.red2lim
enddo
ccfok(ia1:ib1)=.false.
endif
nRxLog=0
fgood=0.
do i=ia,ib
f=(i-1)*df3
if(done(i) .or. (.not.ccfok(i)) .or. (ccfred(i).lt.ccflim-1.0)) cycle
@ -122,9 +110,9 @@ subroutine decoder(ss,c0,nstandalone)
if(nqd.eq.1) nfreqs1=nfreqs1+1
call timer('softsym ',0)
fpk=1000.0 + df3*(i-1)
call softsym(c0,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,freq, &
drift,schk,i1SoftSymbols)
fpk=nf0 + df3*(i-1)
call softsym(id2,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt, &
freq,drift,schk,i1SoftSymbols)
call timer('softsym ',1)
if(schk.ge.schklim) then
@ -140,16 +128,14 @@ subroutine decoder(ss,c0,nstandalone)
nsnr=nint(snrdb)
ndrift=nint(drift/df3)
! write(38,3002) nutc,nqd,nsnr,i,freq,ndrift,ccfred(i), &
! red2(i),schk,nlim,msg
!3002 format(i4.4,i2,i4,i5,f7.1,i4,f5.1,f6.1,f5.1,i8,1x,a22)
if(msg.ne.' ') then
if(nqd.eq.0) ndecodes0=ndecodes0+1
if(nqd.eq.1) ndecodes1=ndecodes1+1
write(*,fmt) nutc,nsync,nsnr,xdt,freq,ndrift,msg
write(13,fmt) nutc,nsync,nsnr,xdt,freq,ndrift,msg
write(*,1000) nutc,nsnr,xdt,nint(freq),msg
1000 format(i4.4,i4,f5.1,i5,1x,'@',1x,a22)
write(13,1002) nutc,nsync,nsnr,xdt,freq,ndrift,msg
1002 format(i4.4,i4,i5,f6.1,f8.0,i4,3x,a22,' JT9')
iaa=max(1,i-1)
ibb=min(NSMAX,i+22)
@ -160,8 +146,6 @@ subroutine decoder(ss,c0,nstandalone)
done(iaa:ibb)=.true.
call flush(6)
endif
else
! write(38,3002) nutc,nqd,-99,i,freq,ndrift,ccfred(i),red2(i),schk,0
endif
endif
enddo
@ -169,21 +153,17 @@ subroutine decoder(ss,c0,nstandalone)
if(nagain.ne.0) exit
enddo
write(*,1010) nsynced,ndecoded
if(nmode.ge.65 .and. (.not.done65)) then
if(newdat.ne.0) dd(1:npts65)=id2(1:npts65)
call jt65a(dd,npts65,newdat,nutc,nfa,nfqso,ntol65,nagain,ndecoded)
endif
!### JT65 is not yet producing info for nsynced, ndecoded.
800 write(*,1010) nsynced,ndecoded
1010 format('<DecodeFinished>',2i4)
call flush(6)
close(13)
! call flush(14)
call timer('decoder ',1)
if(nstandalone.eq.0) call timer('decoder ',101)
call system_clock(iclock,iclock_rate,iclock_max)
! write(39,3001) nutc,nfreqs1,nfreqs0,ndecodes1,ndecodes0, &
! float(iclock-iclock0)/iclock_rate
!3001 format(5i8,f10.3)
! call flush(38)
! call flush(39)
close(22)
return
end subroutine decoder

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

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

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
enddo
do i=1,22 !Omit leading blanks
do i=1,22 !Strip leading blanks
if(message(1:1).ne.' ') exit
message=message(i+1:)
enddo

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"
#endif
#define NULL ((void *)0)
//#define NULL ((void *)0)
void FREE_RS(void *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;
! or as the back end of wsjt-x, with data placed in a shared memory region.
parameter (NTMAX=120)
parameter (NMAX=NTMAX*12000) !Total sample intervals per 30 minutes
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate
parameter (NSMAX=1365) !Max length of saved spectra
include 'constants.f90'
integer*4 ihdr(11)
real*4 s(NSMAX)
real*4 ccfred(NSMAX)
logical*1 lstrong(0:1023)
integer*2 id2
complex c0
character*80 arg,infile
common/jt9com/ss(184,NSMAX),savg(NSMAX),c0(NDMAX),id2(NMAX),nutc,ndiskdat, &
common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
ntr,mousefqso,newdat,nfa,nfb,ntol,kin,nzhsym,nsynced,ndecoded
common/tracer/limtrace,lu
@ -39,11 +33,6 @@ program jt9
limtrace=0
lu=12
nfa=1000
nfb=2000
mousefqso=1500
newdat=1
ndiskdat=1
do ifile=ifile1,nargs
call getarg(ifile,infile)
@ -82,10 +71,6 @@ program jt9
call timer('jt9 ',0)
endif
! do i=1,npts
! id2(i)=100.0*sin(6.283185307*1600.0*i/12000.0)
! enddo
id2=0 !??? Why is this necessary ???
do iblk=1,npts/kstep
@ -99,8 +84,7 @@ program jt9
! Emit signal readyForFFT
ingain=0
call timer('symspec ',0)
call symspec(k,ntrperiod,nsps,ingain,pxdb,s,ccfred,df3, &
ihsym,nzap,slimit,lstrong,npts8)
call symspec(k,ntrperiod,nsps,ingain,slope,pxdb,s,df3,ihsym,npts8)
call timer('symspec ',1)
nhsym0=nhsym
if(ihsym.ge.173) go to 10
@ -109,7 +93,7 @@ program jt9
10 close(10)
call fillcom(nutc0,ndepth)
call decoder(ss,c0,1)
call decoder(ss,id2)
enddo
call timer('jt9 ',1)

View File

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

View File

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

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)
complex c0(1800*1500)
integer*2 id2(1800*12000)
integer*2 id2(NTMAX*12000)
integer nparams0(21),nparams(21)
character*20 datetime
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfb,ntol, &
kin,nzhsym,nsave,nagain,ndepth,nrxlog,nfsample,datetime
kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,datetime
equivalence (nparams,nutc)
nutc=id2(1)+int(savg(1)) !Silence compiler warning
nparams=nparams0 !Copy parameters into common/npar/
call flush(6)
if(sum(nparams).ne.0) call decoder(ss,c0,0)
! if(sum(nparams).ne.0) call decoder(ss,id2)
call decoder(ss,id2)
return
end subroutine jt9c

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

View File

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

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, &
schk,i1SoftSymbols)
subroutine softsym(id2,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt, &
freq,drift,schk,i1SoftSymbols)
! Compute the soft symbols
complex c0(0:npts8-1)
complex c2(0:4096-1)
complex c3(0:4096-1)
complex c5(0:4096-1)
@ -16,7 +15,7 @@ subroutine softsym(c0,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,freq,drift, &
ndown=nsps8/nspsd
! Mix, low-pass filter, and downsample to 16 samples per symbol
call downsam9(c0,npts8,nsps8,newdat,nspsd,fpk,c2,nz2)
call downsam9(id2,npts8,nsps8,newdat,nspsd,fpk,c2,nz2)
call peakdt9(c2,nz2,nsps8,nspsd,c3,nz3,xdt) !Find DT
@ -26,7 +25,7 @@ subroutine softsym(c0,npts8,nsps8,newdat,fpk,syncpk,snrdb,xdt,freq,drift, &
freq=fpk - a(1)
drift=-2.0*a(2)
call twkfreq(c3,c5,nz3,fsample,a) !Correct for deltaF, fDot, fDDot
call twkfreq(c3,c5,nz3,fsample,a) !Correct for delta f, f1, f2 ==> a(1:3)
! Compute soft symbols (in scrambled order)
call symspec2(c5,nz3,nsps8,nspsd,fsample,freq,drift,snrdb,schk, &

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

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)
parameter (NSMAX=1365) !Max length of saved spectra
include 'constants.f90'
! parameter (NSMAX=1365) !Max length of saved spectra
real ss(184,NSMAX)
real ss1(184)
real ccfred(NSMAX)

View File

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

View File

@ -13,13 +13,13 @@ subroutine twkfreq(c3,c4,npts,fsample,a)
s=2.0/npts
do i=1,npts
x=s*(i-x0)
! if(mod(i,100).eq.1) then
if(mod(i,100).eq.1) then
p2=1.5*x*x - 0.5
! p3=2.5*(x**3) - 1.5*x
! p4=4.375*(x**4) - 3.75*(x**2) + 0.375
dphi=(a(1) + x*a(2) + p2*a(3)) * (twopi/fsample)
wstep=cmplx(cos(dphi),sin(dphi))
! endif
endif
w=w*wstep
c4(i)=w*c3(i)
enddo

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();
} else {
QString logEntry=m_dateTime.date().toString("yyyy-MMM-dd,") +
m_dateTime.time().toString("hh:mm,") + hisCall + "," +
hisGrid + "," + strDialFreq + "," + mode +
"," + rptSent + "," + rptRcvd + "," + comments;
m_dateTime.time().toString("hh:mm,") + hisCall + "," +
hisGrid + "," + strDialFreq + "," + mode +
"," + rptSent + "," + rptRcvd;
if(m_txPower!="") logEntry += "," + m_txPower;
if(comments!="") logEntry += "," + comments;
if(name!="") logEntry += "," + name;
QTextStream out(&f);
out << logEntry << endl;
f.close();

File diff suppressed because it is too large Load Diff

View File

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

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

View File

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

View File

@ -39,10 +39,10 @@ PSK_Reporter::PSK_Reporter(QObject *parent) :
void PSK_Reporter::setLocalStation(QString call, QString gridSquare, QString programInfo)
{
m_rxCall = call;
m_rxGrid = gridSquare;
m_progId = programInfo;
reportTimer->start(5*60*1000); // 5 minutes;
m_rxCall = call;
m_rxGrid = gridSquare;
m_progId = programInfo;
reportTimer->start(5*60*1000); // 5 minutes;
}
void PSK_Reporter::addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time )
@ -99,15 +99,6 @@ void PSK_Reporter::sendReport()
// Get IP address for pskreporter.info and send report via UDP
QHostInfo info = QHostInfo::fromName("report.pskreporter.info");
m_udpSocket->writeDatagram(report,info.addresses().at(0),4739);
/*
qDebug() << header_h;
qDebug() << m_rxInfoDescriptor_h;
qDebug() << m_txInfoDescriptor_h;
qDebug() << rxInfoData_h;
qDebug() << txInfoData_h;
qDebug() << report.toHex();
*/
}

View File

@ -7,7 +7,7 @@
* Hamlib C++ interface is a frontend implementing wrapper functions.
*/
/*
/**
*
* Hamlib C++ bindings - main file
* Copyright (c) 2001-2003 by Stephane Fillod
@ -36,7 +36,7 @@
#include <hamlib/rig.h>
#include "rigclass.h"
#include <QDebug>
#include <QHostAddress>
static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg);
@ -78,9 +78,16 @@ int Rig::init(rig_model_t rig_model)
}
int Rig::open(int n) {
#ifdef WIN32 // Ham radio Deluxe only on Windows
m_hrd=(n==9999);
if(m_hrd) {
m_hrd=false;
m_cmndr=false;
if(n<9900) {
if(n==-99999) return -1; //Silence compiler warning
return rig_open(theRig);
}
#ifdef WIN32 // Ham radio Deluxe or Commander (Windows only)
if(n==9999) {
m_hrd=true;
bool bConnect=false;
bConnect = HRDInterfaceConnect(L"localhost",7809);
if(bConnect) {
@ -92,12 +99,30 @@ int Rig::open(int n) {
m_hrd=false;
return -1;
}
} else
#endif
{
if(n==-99999) return -1; //Silence compiler warning
return rig_open(theRig);
}
if(n==9998) {
socket->connectToHost(QHostAddress::LocalHost, 52002);
if(!socket->waitForConnected(1000)) {
return -1;
}
QString t;
// qint32 nkHz=14076;
// t.sprintf("<command:10>CmdSetFreq<parameters:17><xcvrfreq:5>%5d",nkHz);
t="<command:10>CmdGetFreq<parameters:0>";
QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data();
socket->write(buf);
socket->waitForReadyRead(1000);
QByteArray reply=socket->read(128);
if(reply.indexOf("<CmdFreq:10>")==0) {
// qDebug() << "Freq:" << reply;
// qDebug() << "Connected to Commander";
m_cmndr=true;
return 0;
}
}
#endif
return -1;
}
int Rig::close(void) {
@ -105,6 +130,9 @@ int Rig::close(void) {
if(m_hrd) {
HRDInterfaceDisconnect();
return 0;
} else if(m_cmndr) {
socket->close();
return 0;
} else
#endif
{
@ -132,13 +160,70 @@ int Rig::setFreq(freq_t freq, vfo_t vfo) {
} else {
return -1;
}
} else if(m_cmndr) {
QString t;
qint32 nkHz=int(0.001*freq);
t.sprintf("<command:10>CmdSetFreq<parameters:17><xcvrfreq:5>%5d",nkHz);
QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data();
socket->write(buf);
socket->waitForBytesWritten(1000);
return 0;
} else
#endif
{
{
return rig_set_freq(theRig, vfo, freq);
}
}
int Rig::setXit(shortfreq_t xit, vfo_t vfo)
{
return rig_set_xit(theRig, vfo, xit);
}
int Rig::setVFO(vfo_t vfo)
{
return rig_set_vfo(theRig, vfo);
}
vfo_t Rig::getVFO()
{
vfo_t vfo;
rig_get_vfo(theRig, &vfo);
return vfo;
}
int Rig::setSplitFreq(freq_t tx_freq, vfo_t vfo) {
#ifdef WIN32 // Ham Radio Deluxe only on Windows
if(m_hrd) {
QString t;
int nhz=(int)tx_freq;
t=m_context + "Set Frequency-Hz " + QString::number(nhz);
const wchar_t* cmnd = (const wchar_t*) t.utf16();
const wchar_t* result=HRDInterfaceSendMessage(cmnd);
QString t2=QString::fromWCharArray (result,-1);
HRDInterfaceFreeString(result);
if(t2=="OK") {
return 0;
} else {
return -1;
}
} else if(m_cmndr) {
QString t;
qint32 nkHz=int(0.001*tx_freq);
t.sprintf("<command:12>CmdSetTxFreq<parameters:17><xcvrfreq:5>%5d",nkHz);
QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data();
socket->write(buf);
socket->waitForBytesWritten(1000);
return 0;
} else
#endif
{
return rig_set_split_freq(theRig, vfo, tx_freq);
}
}
freq_t Rig::getFreq(vfo_t vfo)
{
freq_t freq;
@ -150,10 +235,29 @@ freq_t Rig::getFreq(vfo_t vfo)
HRDInterfaceFreeString(freqString);
freq=t2.toDouble();
return freq;
} else if(m_cmndr) {
QString t;
t="<command:10>CmdGetFreq<parameters:0>";
QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data();
socket->write(buf);
socket->waitForReadyRead(1000);
QByteArray reply=socket->read(128);
QString t2(reply);
if(t2.indexOf("<CmdFreq:")==0) {
int i1=t2.indexOf(">");
t2=t2.mid(i1+1).replace(",","");
freq=1000.0*t2.toDouble();
return freq;
} else {
return -1.0;
}
} else
#endif
{
rig_get_freq(theRig, vfo, &freq);
{
int iret=rig_get_freq(theRig, vfo, &freq);
// iret should be 0. Negative values mean rig_get_freq() failed.
if(iret<0) freq=-1.0;
return freq;
}
}
@ -168,18 +272,6 @@ rmode_t Rig::getMode(pbwidth_t& width, vfo_t vfo) {
return mode;
}
int Rig::setVFO(vfo_t vfo)
{
return rig_set_vfo(theRig, vfo);
}
vfo_t Rig::getVFO()
{
vfo_t vfo;
rig_get_vfo(theRig, &vfo);
return vfo;
}
int Rig::setPTT(ptt_t ptt, vfo_t vfo)
{
#ifdef WIN32 // Ham Radio Deluxe only on Windows
@ -201,6 +293,16 @@ int Rig::setPTT(ptt_t ptt, vfo_t vfo)
} else {
return -1;
}
} else if(m_cmndr) {
QString t;
if(ptt==0) t="<command:5>CmdRX<parameters:0>";
if(ptt>0) t="<command:5>CmdTX<parameters:0>";
QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data();
socket->write(buf);
socket->waitForBytesWritten(1000);
// qDebug() << ptt << buf;
return 0;
} else
#endif
{

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,10 @@ WideGraph::WideGraph(QWidget *parent) :
connect(ui->widePlot, SIGNAL(freezeDecode1(int)),this,
SLOT(wideFreezeDecode(int)));
m_fMin=1000;
connect(ui->widePlot, SIGNAL(setFreq1(int,int)),this,
SLOT(setFreq2(int,int)));
m_fMin=3000;
ui->fMinSpinBox->setValue(m_fMin);
//Restore user's settings
@ -39,15 +42,13 @@ WideGraph::WideGraph(QWidget *parent) :
m_waterfallAvg = settings.value("WaterfallAvg",5).toInt();
ui->waterfallAvgSpinBox->setValue(m_waterfallAvg);
ui->widePlot->m_bCurrent=settings.value("Current",false).toBool();
ui->widePlot->m_bCumulative=settings.value("Cumulative",false).toBool();
ui->widePlot->m_bJT9Sync=settings.value("JT9Sync",true).toBool();
ui->widePlot->m_bCumulative=settings.value("Cumulative",true).toBool();
if(ui->widePlot->m_bCurrent) ui->spec2dComboBox->setCurrentIndex(0);
if(ui->widePlot->m_bCumulative) ui->spec2dComboBox->setCurrentIndex(1);
if(ui->widePlot->m_bJT9Sync) ui->spec2dComboBox->setCurrentIndex(2);
int nbpp=settings.value("BinsPerPixel",2).toInt();
ui->widePlot->setBinsPerPixel(nbpp);
m_qsoFreq=settings.value("QSOfreq",1500).toInt();
ui->widePlot->setFQSO(m_qsoFreq,true);
m_slope=settings.value("Slope",0.0).toDouble();
ui->slopeSpinBox->setValue(m_slope);
settings.endGroup();
}
@ -72,18 +73,16 @@ void WideGraph::saveSettings()
settings.setValue("WaterfallAvg",ui->waterfallAvgSpinBox->value());
settings.setValue("Current",ui->widePlot->m_bCurrent);
settings.setValue("Cumulative",ui->widePlot->m_bCumulative);
settings.setValue("JT9Sync",ui->widePlot->m_bJT9Sync);
settings.setValue("BinsPerPixel",ui->widePlot->binsPerPixel());
settings.setValue("QSOfreq",ui->widePlot->fQSO());
settings.setValue("Slope",m_slope);
settings.endGroup();
}
void WideGraph::dataSink2(float s[], float red[], float df3, int ihsym,
void WideGraph::dataSink2(float s[], float df3, int ihsym,
int ndiskdata)
{
static float splot[NSMAX];
static float swide[2048];
static float rwide[2048];
int nbpp = ui->widePlot->binsPerPixel();
static int n=0;
@ -105,18 +104,14 @@ void WideGraph::dataSink2(float s[], float red[], float df3, int ihsym,
// int w=ui->widePlot->plotWidth();
int i0=-1; //###
int i=i0;
int jz=1000.0/df3;
int jz=5000.0/(nbpp*df3);
for (int j=0; j<jz; j++) {
float sum=0;
float rsum=0;
for (int k=0; k<nbpp; k++) {
i++;
sum += splot[i];
rsum += red[i];
}
swide[j]=sum;
rwide[j]=rsum/nbpp;
// if(lstrong[1 + i/32]!=0) swide[j]=-smax; //Tag strong signals
}
// Time according to this computer
@ -128,7 +123,7 @@ void WideGraph::dataSink2(float s[], float red[], float df3, int ihsym,
}
}
m_ntr0=ntr;
ui->widePlot->draw(swide,rwide,i0);
ui->widePlot->draw(swide,i0);
}
}
@ -172,16 +167,16 @@ void WideGraph::keyPressEvent(QKeyEvent *e)
}
}
void WideGraph::setQSOfreq(int n)
void WideGraph::setRxFreq(int n)
{
m_qsoFreq=n;
ui->widePlot->setFQSO(m_qsoFreq,true);
if(m_lockTxFreq) setTxFreq(m_qsoFreq);
m_rxFreq=n;
ui->widePlot->setRxFreq(m_rxFreq,true);
if(m_lockTxFreq) setTxFreq(m_rxFreq);
}
int WideGraph::QSOfreq()
int WideGraph::rxFreq()
{
return ui->widePlot->fQSO();
return ui->widePlot->rxFreq();
}
int WideGraph::nSpan()
@ -204,9 +199,9 @@ void WideGraph::wideFreezeDecode(int n)
emit freezeDecode2(n);
}
void WideGraph::setRxRange(int fMin, int fMax)
void WideGraph::setRxRange(int fMin)
{
ui->widePlot->setRxRange(fMin,fMax);
ui->widePlot->setRxRange(fMin);
ui->widePlot->DrawOverlay();
ui->widePlot->update();
}
@ -218,19 +213,16 @@ int WideGraph::getFmin()
int WideGraph::getFmax()
{
return m_fMax;
int n=ui->widePlot->getFmax();
if(n>5000) n=5000;
return n;
}
void WideGraph::setfMax(int n)
void WideGraph::setFmin(int n)
{
m_fMax = n;
setRxRange(m_fMin,m_fMax);
}
void WideGraph::setFcal(int n)
{
m_fCal=n;
ui->widePlot->setFcal(n);
m_fMin = n;
ui->fMinSpinBox->setValue(n);
setRxRange(m_fMin);
}
void WideGraph::setPalette(QString palette)
@ -252,28 +244,65 @@ void WideGraph::setPeriod(int ntrperiod, int nsps)
void WideGraph::setTxFreq(int n)
{
emit setXIT2(n);
ui->widePlot->setTxFreq(n);
}
void WideGraph::setMode(QString mode)
{
m_mode=mode;
ui->fMinSpinBox->setEnabled(m_mode=="JT9+JT65");
ui->widePlot->setMode(mode);
ui->widePlot->DrawOverlay();
ui->widePlot->update();
}
void WideGraph::setModeTx(QString modeTx)
{
m_modeTx=modeTx;
ui->widePlot->setModeTx(modeTx);
ui->widePlot->DrawOverlay();
ui->widePlot->update();
}
void WideGraph::on_spec2dComboBox_currentIndexChanged(const QString &arg1)
{
ui->widePlot->m_bCurrent=false;
ui->widePlot->m_bCumulative=false;
ui->widePlot->m_bJT9Sync=false;
if(arg1=="Current") ui->widePlot->m_bCurrent=true;
if(arg1=="Cumulative") ui->widePlot->m_bCumulative=true;
if(arg1=="JT9 Sync") ui->widePlot->m_bJT9Sync=true;
}
void WideGraph::on_fMinSpinBox_valueChanged(int n)
{
m_fMin=n;
setRxRange(m_fMin,m_fMax);
setRxRange(m_fMin);
}
void WideGraph::on_fMaxSpinBox_valueChanged(int n)
void WideGraph::on_slopeSpinBox_valueChanged(double d)
{
m_fMax=n;
setRxRange(m_fMin,m_fMax);
m_slope=d;
}
void WideGraph::setSlope(double d)
{
m_slope=d;
ui->slopeSpinBox->setValue(d);
}
void WideGraph::setLockTxFreq(bool b)
{
m_lockTxFreq=b;
ui->widePlot->m_lockTxFreq=b;
}
double WideGraph::getSlope()
{
return m_slope;
}
void WideGraph::setFreq2(int rxFreq, int txFreq)
{
m_rxFreq=rxFreq;
m_txFreq=txFreq;
emit setFreq3(rxFreq,txFreq);
}

View File

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

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>712</width>
<width>799</width>
<height>326</height>
</rect>
</property>
@ -68,25 +68,6 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>25</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="text">
<string>FFT Bins/Pixel</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="freqSpanSpinBox">
<property name="sizePolicy">
@ -97,7 +78,7 @@
</property>
<property name="minimumSize">
<size>
<width>40</width>
<width>110</width>
<height>0</height>
</size>
</property>
@ -113,6 +94,9 @@
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Bins/Pixel </string>
</property>
<property name="minimum">
<number>1</number>
</property>
@ -143,25 +127,6 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>25</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="text">
<string>N Avg</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="waterfallAvgSpinBox">
<property name="sizePolicy">
@ -172,7 +137,7 @@
</property>
<property name="minimumSize">
<size>
<width>0</width>
<width>80</width>
<height>0</height>
</size>
</property>
@ -185,6 +150,9 @@
<property name="toolTip">
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
</property>
<property name="prefix">
<string>N Avg </string>
</property>
<property name="minimum">
<number>1</number>
</property>
@ -210,26 +178,13 @@
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="maximumSize">
<widget class="QSpinBox" name="gainSpinBox">
<property name="minimumSize">
<size>
<width>16777215</width>
<height>25</height>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="text">
<string>Gain</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="gainSpinBox">
<property name="maximumSize">
<size>
<width>38</width>
@ -239,6 +194,9 @@
<property name="toolTip">
<string>Scaling (dB) applied to spectra before plotting</string>
</property>
<property name="prefix">
<string>Gain </string>
</property>
<property name="minimum">
<number>-20</number>
</property>
@ -264,26 +222,13 @@
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="maximumSize">
<widget class="QSpinBox" name="zeroSpinBox">
<property name="minimumSize">
<size>
<width>16777215</width>
<height>25</height>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="text">
<string>Zero</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="zeroSpinBox">
<property name="maximumSize">
<size>
<width>38</width>
@ -293,6 +238,12 @@
<property name="toolTip">
<string>Constant offset applied to waterfall data</string>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Zero </string>
</property>
<property name="minimum">
<number>-100</number>
</property>
@ -301,6 +252,31 @@
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="slopeSpinBox">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="prefix">
<string>Slope </string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-2.000000000000000</double>
</property>
<property name="maximum">
<double>2.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@ -317,25 +293,6 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>25</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="text">
<string>f Min</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="fMinSpinBox">
<property name="sizePolicy">
@ -344,17 +301,32 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Minimum frequency for wideband decodes</string>
<string>Decode JT65 below this frequency, JT9 above</string>
</property>
<property name="suffix">
<string> JT9</string>
</property>
<property name="prefix">
<string>JT65 </string>
</property>
<property name="minimum">
<number>1000</number>
<number>0</number>
</property>
<property name="maximum">
<number>2000</number>
<number>5000</number>
</property>
<property name="singleStep">
<number>50</number>
<number>100</number>
</property>
<property name="value">
<number>3000</number>
</property>
</widget>
</item>
@ -374,66 +346,6 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>25</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="text">
<string>f Max</string>
</property>
<property name="margin">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="fMaxSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Maximum frequency for wideband decodes</string>
</property>
<property name="minimum">
<number>1000</number>
</property>
<property name="maximum">
<number>2000</number>
</property>
<property name="singleStep">
<number>50</number>
</property>
<property name="value">
<number>2000</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>8</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QComboBox" name="spec2dComboBox">
<property name="toolTip">
@ -452,11 +364,6 @@
<string>Cumulative</string>
</property>
</item>
<item>
<property name="text">
<string>JT9 Sync</string>
</property>
</item>
</widget>
</item>
<item>

View File

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

View File

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