mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-23 12:48:40 -05:00
Reintegrate the wsjtx_exp branch into the trunk
This merge brings the WSPR feature development into the main line ready for release in a future v1.6 release. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5424 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
eb295e86e0
commit
f9d0a1863a
@ -232,6 +232,7 @@ set (wsjtx_CXXSRCS
|
|||||||
mainwindow.cpp
|
mainwindow.cpp
|
||||||
Configuration.cpp
|
Configuration.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
|
wsprnet.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
@ -288,6 +289,7 @@ set (wsjt_FSRCS
|
|||||||
lib/fchisq.f90
|
lib/fchisq.f90
|
||||||
lib/fchisq65.f90
|
lib/fchisq65.f90
|
||||||
lib/fil3.f90
|
lib/fil3.f90
|
||||||
|
lib/fil3c.f90
|
||||||
lib/fil4.f90
|
lib/fil4.f90
|
||||||
lib/fil6521.f90
|
lib/fil6521.f90
|
||||||
lib/filbig.f90
|
lib/filbig.f90
|
||||||
@ -302,20 +304,26 @@ set (wsjt_FSRCS
|
|||||||
lib/gen4.f90
|
lib/gen4.f90
|
||||||
lib/gen65.f90
|
lib/gen65.f90
|
||||||
lib/gen9.f90
|
lib/gen9.f90
|
||||||
|
lib/genwspr.f90
|
||||||
lib/geodist.f90
|
lib/geodist.f90
|
||||||
lib/getlags.f90
|
lib/getlags.f90
|
||||||
lib/graycode.f90
|
lib/graycode.f90
|
||||||
lib/graycode65.f90
|
lib/graycode65.f90
|
||||||
|
lib/grayline.f90
|
||||||
lib/grid2deg.f90
|
lib/grid2deg.f90
|
||||||
|
lib/hash.f90
|
||||||
|
lib/hopping.f90
|
||||||
lib/image.f90
|
lib/image.f90
|
||||||
lib/indexx.f90
|
lib/indexx.f90
|
||||||
lib/interleave4.f90
|
lib/interleave4.f90
|
||||||
lib/interleave63.f90
|
lib/interleave63.f90
|
||||||
lib/interleave9.f90
|
lib/interleave9.f90
|
||||||
|
lib/inter_wspr.f90
|
||||||
lib/jt4.f90
|
lib/jt4.f90
|
||||||
lib/jt4a.f90
|
lib/jt4a.f90
|
||||||
lib/jt65a.f90
|
lib/jt65a.f90
|
||||||
lib/lpf1.f90
|
lib/lpf1.f90
|
||||||
|
lib/mixlpf.f90
|
||||||
lib/moon2.f90
|
lib/moon2.f90
|
||||||
lib/moondop.f90
|
lib/moondop.f90
|
||||||
lib/morse.f90
|
lib/morse.f90
|
||||||
@ -328,6 +336,7 @@ set (wsjt_FSRCS
|
|||||||
lib/polyfit.f90
|
lib/polyfit.f90
|
||||||
lib/prog_args.f90
|
lib/prog_args.f90
|
||||||
lib/ps4.f90
|
lib/ps4.f90
|
||||||
|
lib/savec2.f90
|
||||||
lib/sec_midn.f90
|
lib/sec_midn.f90
|
||||||
lib/setup65.f90
|
lib/setup65.f90
|
||||||
lib/sleep_msec.f90
|
lib/sleep_msec.f90
|
||||||
@ -344,6 +353,7 @@ set (wsjt_FSRCS
|
|||||||
lib/sync4.f90
|
lib/sync4.f90
|
||||||
lib/sync9.f90
|
lib/sync9.f90
|
||||||
lib/timer.f90
|
lib/timer.f90
|
||||||
|
lib/timf2.f90
|
||||||
lib/tm2.f90
|
lib/tm2.f90
|
||||||
lib/toxyz.f90
|
lib/toxyz.f90
|
||||||
lib/twkfreq.f90
|
lib/twkfreq.f90
|
||||||
@ -355,6 +365,8 @@ set (wsjt_FSRCS
|
|||||||
lib/xcor4.f90
|
lib/xcor4.f90
|
||||||
lib/zplt.f90
|
lib/zplt.f90
|
||||||
lib/wavhdr.f90
|
lib/wavhdr.f90
|
||||||
|
lib/wqencode.f90
|
||||||
|
lib/wspr_downsample.f90
|
||||||
lib/zplot9.f90
|
lib/zplot9.f90
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -364,6 +376,7 @@ set (wsjt_CSRCS
|
|||||||
lib/gran.c
|
lib/gran.c
|
||||||
lib/igray.c
|
lib/igray.c
|
||||||
lib/init_rs.c
|
lib/init_rs.c
|
||||||
|
lib/wsprd/nhash.c
|
||||||
lib/tmoonsub.c
|
lib/tmoonsub.c
|
||||||
lib/usleep.c
|
lib/usleep.c
|
||||||
lib/wisdom.c
|
lib/wisdom.c
|
||||||
@ -657,7 +670,6 @@ if (NOT "${QT_LIBRARY_DIR}" STREQUAL "/lib" AND NOT "${QT_LIBRARY_DIR}" STREQUAL
|
|||||||
set (QT_NEED_RPATH TRUE)
|
set (QT_NEED_RPATH TRUE)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# OpenMP
|
# OpenMP
|
||||||
#
|
#
|
||||||
@ -666,10 +678,9 @@ find_package (OpenMP)
|
|||||||
#
|
#
|
||||||
# fftw3 single precsion library
|
# fftw3 single precsion library
|
||||||
#
|
#
|
||||||
find_package (FFTW3 COMPONENTS single threads REQUIRED)
|
find_package (FFTW3 COMPONENTS double single threads REQUIRED)
|
||||||
include_directories (${FFTW3_INCLUDE_DIRS})
|
include_directories (${FFTW3_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# libhamlib setup
|
# libhamlib setup
|
||||||
#
|
#
|
||||||
@ -838,6 +849,9 @@ target_link_libraries (jt65code wsjt_fort wsjt_cxx)
|
|||||||
add_executable (jt9code lib/jt9code.f90 wsjtx.rc)
|
add_executable (jt9code lib/jt9code.f90 wsjtx.rc)
|
||||||
target_link_libraries (jt9code wsjt_fort wsjt_cxx)
|
target_link_libraries (jt9code wsjt_fort wsjt_cxx)
|
||||||
|
|
||||||
|
add_executable (wsprd lib/wsprd/wsprd.c lib/wsprd/wsprd_utils.c lib/wsprd/fano.c lib/wsprd/tab.c lib/wsprd/nhash.c)
|
||||||
|
target_link_libraries (wsprd ${FFTW3_LIBRARIES})
|
||||||
|
|
||||||
add_executable (jt4code lib/jt4code.f90 wsjtx.rc)
|
add_executable (jt4code lib/jt4code.f90 wsjtx.rc)
|
||||||
target_link_libraries (jt4code wsjt_fort wsjt_cxx)
|
target_link_libraries (jt4code wsjt_fort wsjt_cxx)
|
||||||
|
|
||||||
@ -946,7 +960,7 @@ install (TARGETS wsjtx
|
|||||||
BUNDLE DESTINATION . COMPONENT runtime
|
BUNDLE DESTINATION . COMPONENT runtime
|
||||||
)
|
)
|
||||||
|
|
||||||
install (TARGETS jt9 jt65code jt9code jt4code message_aggregator
|
install (TARGETS jt9 jt65code jt9code jt4code wsprd message_aggregator
|
||||||
RUNTIME DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime
|
RUNTIME DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime
|
||||||
BUNDLE DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime
|
BUNDLE DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime
|
||||||
)
|
)
|
||||||
|
@ -615,7 +615,8 @@ bool Configuration::enable_VHF_features () const {return m_->enable_VHF_features
|
|||||||
bool Configuration::decode_at_52s () const {return m_->decode_at_52s_;}
|
bool Configuration::decode_at_52s () const {return m_->decode_at_52s_;}
|
||||||
bool Configuration::split_mode () const
|
bool Configuration::split_mode () const
|
||||||
{
|
{
|
||||||
return !m_->rig_is_dummy_ && m_->rig_params_.split_mode != TransceiverFactory::split_mode_none;
|
return !m_->rig_is_dummy_ and
|
||||||
|
(m_->rig_params_.split_mode != TransceiverFactory::split_mode_none);
|
||||||
}
|
}
|
||||||
QString Configuration::udp_server_name () const {return m_->udp_server_name_;}
|
QString Configuration::udp_server_name () const {return m_->udp_server_name_;}
|
||||||
auto Configuration::udp_server_port () const -> port_type {return m_->udp_server_port_;}
|
auto Configuration::udp_server_port () const -> port_type {return m_->udp_server_port_;}
|
||||||
@ -704,9 +705,11 @@ Configuration::impl::impl (Configuration * self, QSettings * settings, QWidget *
|
|||||||
, settings_ {settings}
|
, settings_ {settings}
|
||||||
, doc_dir_ {QApplication::applicationDirPath ()}
|
, doc_dir_ {QApplication::applicationDirPath ()}
|
||||||
, frequencies_ {
|
, frequencies_ {
|
||||||
{ 136130, 474200, 1838000, 3576000, 5357000, 7076000, 10138000, 14076000, 18102000,
|
{ 136000, 136130, 474200, 1836600, 1838000, 3576000, 3592600, 5287200, 5357000,
|
||||||
21076000, 24917000, 28076000, 50276000, 70091000, 144000000, 144489000, 222000000,
|
7038600, 7076000, 10138000, 10138700, 14076000, 14095600, 18102000, 18104600,
|
||||||
432000000, 902000000, 1296000000, 2301000000, 2304000000, 2320000000, 3400000000,
|
21076000, 21094600, 24917000, 24924600, 28076000, 28124600, 50276000, 50293000,
|
||||||
|
70091000, 144000000, 144489000, 222000000, 432000000, 432300000,
|
||||||
|
902000000, 1296000000, 1296500000, 2301000000, 2304000000, 2320000000, 3400000000,
|
||||||
3456000000, 5760000000,10368000000, 24048000000 }
|
3456000000, 5760000000,10368000000, 24048000000 }
|
||||||
}
|
}
|
||||||
, stations_ {&bands_}
|
, stations_ {&bands_}
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned samplesPerFFT, unsigned downSampleFactor = 4u, QObject * parent = 0);
|
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned samplesPerFFT, unsigned downSampleFactor = 4u, QObject * parent = 0);
|
||||||
|
|
||||||
Q_SIGNAL void framesWritten (qint64) const;
|
Q_SIGNAL void framesWritten (qint64) const;
|
||||||
|
void setPeriod(unsigned p) {m_period=p;}
|
||||||
bool reset () override;
|
bool reset () override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -24,7 +24,8 @@ double const Modulator::m_twoPi = 2.0 * 3.141592653589793238462;
|
|||||||
// m_nspd=3072; //18.75 WPM
|
// m_nspd=3072; //18.75 WPM
|
||||||
unsigned const Modulator::m_nspd = 2048 + 512; // 22.5 WPM
|
unsigned const Modulator::m_nspd = 2048 + 512; // 22.5 WPM
|
||||||
|
|
||||||
Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObject * parent)
|
Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds,
|
||||||
|
QObject * parent)
|
||||||
: AudioDevice {parent}
|
: AudioDevice {parent}
|
||||||
, m_stream {nullptr}
|
, m_stream {nullptr}
|
||||||
, m_quickClose {false}
|
, m_quickClose {false}
|
||||||
@ -41,7 +42,10 @@ Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObjec
|
|||||||
m_itone0=0;
|
m_itone0=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modulator::start (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, double toneSpacing, SoundOutput * stream, Channel channel, bool synchronize, double dBSNR)
|
void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
|
||||||
|
unsigned frequency, double toneSpacing,
|
||||||
|
SoundOutput * stream, Channel channel,
|
||||||
|
bool synchronize, double dBSNR)
|
||||||
{
|
{
|
||||||
Q_ASSERT (stream);
|
Q_ASSERT (stream);
|
||||||
|
|
||||||
@ -264,6 +268,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
|
|||||||
m_itone0=itone[0];
|
m_itone0=itone[0];
|
||||||
*/
|
*/
|
||||||
m_frequency0 = m_frequency;
|
m_frequency0 = m_frequency;
|
||||||
|
// qDebug() << "a" << m_frequency << m_nsps << m_toneSpacing << toneFrequency0 << baud << isym;
|
||||||
|
|
||||||
// done for this chunk - continue on next call
|
// done for this chunk - continue on next call
|
||||||
return framesGenerated * bytesPerFrame ();
|
return framesGenerated * bytesPerFrame ();
|
||||||
|
@ -30,6 +30,7 @@ public:
|
|||||||
unsigned frequency () const {return m_frequency;}
|
unsigned frequency () const {return m_frequency;}
|
||||||
bool isActive () const {return m_state != Idle;}
|
bool isActive () const {return m_state != Idle;}
|
||||||
void setSpread(double s) {m_fSpread=s;}
|
void setSpread(double s) {m_fSpread=s;}
|
||||||
|
void setPeriod(unsigned p) {m_period=p;}
|
||||||
|
|
||||||
Q_SLOT void start (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, double toneSpacing, SoundOutput *, Channel = Mono, bool synchronize = true, double dBSNR = 99.);
|
Q_SLOT void start (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, double toneSpacing, SoundOutput *, Channel = Mono, bool synchronize = true, double dBSNR = 99.);
|
||||||
Q_SLOT void stop (bool quick = false);
|
Q_SLOT void stop (bool quick = false);
|
||||||
|
@ -23,8 +23,9 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
|||||||
"Amateur Radio communication. <br><br>"
|
"Amateur Radio communication. <br><br>"
|
||||||
"© 2001-2015 by Joe Taylor, K1JT, with grateful <br>"
|
"© 2001-2015 by Joe Taylor, K1JT, with grateful <br>"
|
||||||
"acknowledgment for contributions from AC6SL, AE4JY, <br>"
|
"acknowledgment for contributions from AC6SL, AE4JY, <br>"
|
||||||
"DJ0OT, G4KLA, G4WJS, K3WYC, KA6MAL, KA9Q, KB1ZMX, <br>"
|
"DJ0OT, G4KLA, G4WJS, K3WYC, K9AN, KA6MAL, KA9Q, <br>"
|
||||||
"KI7MT, KK1D, PY2SDR, VK3ACF, VK4BDJ, W4TI, W4TV, and W9MDB.<br>");
|
"KB1ZMX, KD6EKQ, KI7MT, KK1D, ND0B, PY2SDR, <br>"
|
||||||
|
"VK3ACF, VK4BDJ, W4TI, W4TV, and W9MDB.<br>");
|
||||||
}
|
}
|
||||||
|
|
||||||
CAboutDlg::~CAboutDlg()
|
CAboutDlg::~CAboutDlg()
|
||||||
|
36
astro.cpp
36
astro.cpp
@ -29,6 +29,7 @@ Astro::Astro(QSettings * settings, QWidget * parent)
|
|||||||
setWindowTitle(QApplication::applicationName () + " - " + tr ("Astronomical Data"));
|
setWindowTitle(QApplication::applicationName () + " - " + tr ("Astronomical Data"));
|
||||||
setStyleSheet ("QWidget {background: white;}");
|
setStyleSheet ("QWidget {background: white;}");
|
||||||
read_settings ();
|
read_settings ();
|
||||||
|
m_Hz=0;
|
||||||
ui_->text_label->clear();
|
ui_->text_label->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,9 +61,8 @@ void Astro::read_settings ()
|
|||||||
m_kHz=settings_->value("kHzAdd",100).toInt();
|
m_kHz=settings_->value("kHzAdd",100).toInt();
|
||||||
ui_->kHzSpinBox->setValue(m_kHz);
|
ui_->kHzSpinBox->setValue(m_kHz);
|
||||||
m_bRxAudioTrack=settings_->value("RxAudioTrack",false).toBool();
|
m_bRxAudioTrack=settings_->value("RxAudioTrack",false).toBool();
|
||||||
ui_->cbRxTrack->setChecked(m_bRxAudioTrack);
|
|
||||||
m_bTxAudioTrack=settings_->value("TxAudioTrack",false).toBool();
|
m_bTxAudioTrack=settings_->value("TxAudioTrack",false).toBool();
|
||||||
ui_->cbTxTrack->setChecked(m_bTxAudioTrack);
|
ui_->cbTxAudioTrack->setChecked(m_bTxAudioTrack);
|
||||||
move (settings_->value ("window/pos", pos ()).toPoint ());
|
move (settings_->value ("window/pos", pos ()).toPoint ());
|
||||||
settings_->endGroup ();
|
settings_->endGroup ();
|
||||||
}
|
}
|
||||||
@ -82,10 +82,10 @@ void Astro::write_settings ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid, qint64 freqMoon,
|
void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid, qint64 freqMoon,
|
||||||
qint32* ndop, qint32* ndop00)
|
qint32* ndop, qint32* ndop00, bool bTx)
|
||||||
{
|
{
|
||||||
double azsun,elsun,azmoon,elmoon,azmoondx,elmoondx;
|
double azsun,elsun,azmoon,elmoon,azmoondx,elmoondx;
|
||||||
double ramoon,decmoon,dgrd,poloffset,xnr,techo;
|
double ramoon,decmoon,dgrd,poloffset,xnr,techo,width1,width2;
|
||||||
int ntsky;
|
int ntsky;
|
||||||
QString date = t.date().toString("yyyy MMM dd").trimmed ();
|
QString date = t.date().toString("yyyy MMM dd").trimmed ();
|
||||||
QString utc = t.time().toString().trimmed ();
|
QString utc = t.time().toString().trimmed ();
|
||||||
@ -95,16 +95,19 @@ void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid, qint64 fre
|
|||||||
int nhr=t.time().hour();
|
int nhr=t.time().hour();
|
||||||
int nmin=t.time().minute();
|
int nmin=t.time().minute();
|
||||||
double sec=t.time().second() + 0.001*t.time().msec();
|
double sec=t.time().second() + 0.001*t.time().msec();
|
||||||
int isec=sec;
|
|
||||||
double uth=nhr + nmin/60.0 + sec/3600.0;
|
double uth=nhr + nmin/60.0 + sec/3600.0;
|
||||||
if(freqMoon < 1) freqMoon=144000000;
|
if(freqMoon < 1) freqMoon=144000000;
|
||||||
int nfreq=freqMoon/1000000;
|
int nfreq=freqMoon/1000000;
|
||||||
double freq8=(double)freqMoon;
|
double freq8=(double)freqMoon;
|
||||||
|
|
||||||
|
QDir dataDir = QStandardPaths::writableLocation (QStandardPaths::DataLocation);
|
||||||
|
QString fname = QDir::toNativeSeparators(dataDir.absoluteFilePath ("azel.dat"));
|
||||||
|
|
||||||
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid.toLatin1(),
|
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid.toLatin1(),
|
||||||
hisgrid.toLatin1(), &azsun, &elsun, &azmoon, &elmoon,
|
hisgrid.toLatin1(), &azsun, &elsun, &azmoon, &elmoon,
|
||||||
&azmoondx, &elmoondx, &ntsky, ndop, ndop00, &ramoon, &decmoon,
|
&azmoondx, &elmoondx, &ntsky, ndop, ndop00, &ramoon, &decmoon,
|
||||||
&dgrd, &poloffset, &xnr, &techo, 6, 6);
|
&dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx,
|
||||||
|
fname.toLatin1(), 6, 6, fname.length());
|
||||||
|
|
||||||
QString message;
|
QString message;
|
||||||
{
|
{
|
||||||
@ -117,13 +120,15 @@ void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid, qint64 fre
|
|||||||
<< qSetRealNumberPrecision (1)
|
<< qSetRealNumberPrecision (1)
|
||||||
<< "Az: " << azmoon << "\n"
|
<< "Az: " << azmoon << "\n"
|
||||||
"El: " << elmoon << "\n"
|
"El: " << elmoon << "\n"
|
||||||
"MyDop: " << *ndop00 << "\n"
|
"Dop: " << *ndop00 << "\n"
|
||||||
|
"Width: " << int(width1) << "\n"
|
||||||
<< qSetRealNumberPrecision (2)
|
<< qSetRealNumberPrecision (2)
|
||||||
<< "Delay: " << techo << "\n"
|
<< "Delay: " << techo << "\n"
|
||||||
<< qSetRealNumberPrecision (1)
|
<< qSetRealNumberPrecision (1)
|
||||||
<< "DxAz: " << azmoondx << "\n"
|
<< "DxAz: " << azmoondx << "\n"
|
||||||
"DxEl: " << elmoondx << "\n"
|
"DxEl: " << elmoondx << "\n"
|
||||||
"DxDop: " << *ndop << "\n"
|
"DxDop: " << *ndop << "\n"
|
||||||
|
"DxWid: " << int(width2) << "\n"
|
||||||
"Dec: " << decmoon << "\n"
|
"Dec: " << decmoon << "\n"
|
||||||
"SunAz: " << azsun << "\n"
|
"SunAz: " << azsun << "\n"
|
||||||
"SunEl: " << elsun << "\n"
|
"SunEl: " << elsun << "\n"
|
||||||
@ -134,6 +139,7 @@ void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid, qint64 fre
|
|||||||
}
|
}
|
||||||
ui_->text_label->setText(message);
|
ui_->text_label->setText(message);
|
||||||
|
|
||||||
|
/*
|
||||||
static QFile f {QDir {QStandardPaths::writableLocation (
|
static QFile f {QDir {QStandardPaths::writableLocation (
|
||||||
QStandardPaths::DataLocation)}.absoluteFilePath ("azel.dat")};
|
QStandardPaths::DataLocation)}.absoluteFilePath ("azel.dat")};
|
||||||
if (!f.open (QIODevice::WriteOnly | QIODevice::Text)) {
|
if (!f.open (QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
@ -185,13 +191,14 @@ void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid, qint64 fre
|
|||||||
<< qSetFieldWidth (0) << ",Doppler";
|
<< qSetFieldWidth (0) << ",Doppler";
|
||||||
}
|
}
|
||||||
f.close();
|
f.close();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Astro::on_cbDopplerTracking_toggled(bool b)
|
void Astro::on_cbDopplerTracking_toggled(bool b)
|
||||||
{
|
{
|
||||||
QRect g=this->geometry();
|
QRect g=this->geometry();
|
||||||
if(b) {
|
if(b) {
|
||||||
g.setWidth(460);
|
g.setWidth(430);
|
||||||
} else {
|
} else {
|
||||||
g.setWidth(200);
|
g.setWidth(200);
|
||||||
}
|
}
|
||||||
@ -228,15 +235,9 @@ void Astro::on_rb10Hz_clicked()
|
|||||||
void Astro::on_rb100Hz_clicked()
|
void Astro::on_rb100Hz_clicked()
|
||||||
{
|
{
|
||||||
m_stepHz=100;
|
m_stepHz=100;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Astro::on_cbRxTrack_toggled(bool b)
|
void Astro::on_cbTxAudioTrack_toggled(bool b)
|
||||||
{
|
|
||||||
m_bRxAudioTrack=b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Astro::on_cbTxTrack_toggled(bool b)
|
|
||||||
{
|
{
|
||||||
m_bTxAudioTrack=b;
|
m_bTxAudioTrack=b;
|
||||||
}
|
}
|
||||||
@ -245,3 +246,8 @@ void Astro::on_kHzSpinBox_valueChanged(int n)
|
|||||||
{
|
{
|
||||||
m_kHz=n;
|
m_kHz=n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Astro::on_HzSpinBox_valueChanged(int n)
|
||||||
|
{
|
||||||
|
m_Hz=n;
|
||||||
|
}
|
||||||
|
10
astro.h
10
astro.h
@ -23,7 +23,7 @@ public:
|
|||||||
explicit Astro(QSettings * settings, QWidget * parent = nullptr);
|
explicit Astro(QSettings * settings, QWidget * parent = nullptr);
|
||||||
~Astro ();
|
~Astro ();
|
||||||
void astroUpdate(QDateTime t, QString mygrid, QString hisgrid, qint64 freqMoon,
|
void astroUpdate(QDateTime t, QString mygrid, QString hisgrid, qint64 freqMoon,
|
||||||
qint32* ndop, qint32 *ndop00);
|
qint32* ndop, qint32 *ndop00, bool bTx);
|
||||||
|
|
||||||
bool m_bDopplerTracking;
|
bool m_bDopplerTracking;
|
||||||
bool m_bRxAudioTrack;
|
bool m_bRxAudioTrack;
|
||||||
@ -31,6 +31,7 @@ public:
|
|||||||
|
|
||||||
qint32 m_DopplerMethod;
|
qint32 m_DopplerMethod;
|
||||||
qint32 m_kHz;
|
qint32 m_kHz;
|
||||||
|
qint32 m_Hz;
|
||||||
qint32 m_stepHz;
|
qint32 m_stepHz;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -44,9 +45,9 @@ private slots:
|
|||||||
void on_rb1Hz_clicked();
|
void on_rb1Hz_clicked();
|
||||||
void on_rb10Hz_clicked();
|
void on_rb10Hz_clicked();
|
||||||
void on_rb100Hz_clicked();
|
void on_rb100Hz_clicked();
|
||||||
void on_cbRxTrack_toggled(bool b);
|
void on_cbTxAudioTrack_toggled(bool b);
|
||||||
void on_cbTxTrack_toggled(bool b);
|
|
||||||
void on_kHzSpinBox_valueChanged(int n);
|
void on_kHzSpinBox_valueChanged(int n);
|
||||||
|
void on_HzSpinBox_valueChanged(int n);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void read_settings ();
|
void read_settings ();
|
||||||
@ -63,7 +64,8 @@ extern "C" {
|
|||||||
double* elsun, double* azmoon, double* elmoon, double* azmoondx,
|
double* elsun, double* azmoon, double* elmoon, double* azmoondx,
|
||||||
double* elmoondx, int* ntsky, int* ndop, int* ndop00,
|
double* elmoondx, int* ntsky, int* ndop, int* ndop00,
|
||||||
double* ramoon, double* decmoon, double* dgrd, double* poloffset,
|
double* ramoon, double* decmoon, double* dgrd, double* poloffset,
|
||||||
double* xnr, double* techo, int len1, int len2);
|
double* xnr, double* techo, double* width1, double* width2,
|
||||||
|
bool* bTx, const char* fname, int len1, int len2, int len3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASTRO_H
|
#endif // ASTRO_H
|
||||||
|
476
astro.ui
476
astro.ui
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>460</width>
|
<width>400</width>
|
||||||
<height>420</height>
|
<height>440</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -19,7 +19,7 @@
|
|||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>200</width>
|
<width>200</width>
|
||||||
<height>420</height>
|
<height>440</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
@ -31,7 +31,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>201</width>
|
<width>201</width>
|
||||||
<height>361</height>
|
<height>400</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -48,7 +48,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>Courier New</family>
|
<family>Courier</family>
|
||||||
<pointsize>14</pointsize>
|
<pointsize>14</pointsize>
|
||||||
<weight>75</weight>
|
<weight>75</weight>
|
||||||
<italic>false</italic>
|
<italic>false</italic>
|
||||||
@ -71,222 +71,11 @@
|
|||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QFrame" name="frame">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>219</x>
|
|
||||||
<y>19</y>
|
|
||||||
<width>221</width>
|
|
||||||
<height>361</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::StyledPanel</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Raised</enum>
|
|
||||||
</property>
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>20</x>
|
|
||||||
<y>20</y>
|
|
||||||
<width>185</width>
|
|
||||||
<height>96</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>185</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Doppler tracking</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbFullTrack">
|
|
||||||
<property name="text">
|
|
||||||
<string>Full Doppler to DX Grid</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbConstFreqOnMoon">
|
|
||||||
<property name="text">
|
|
||||||
<string>Constant frequency on Moon</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbNoDoppler">
|
|
||||||
<property name="text">
|
|
||||||
<string>None</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>20</x>
|
|
||||||
<y>130</y>
|
|
||||||
<width>185</width>
|
|
||||||
<height>96</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>185</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Transceiver step size</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QRadioButton" name="rb1Hz">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>10</x>
|
|
||||||
<y>23</y>
|
|
||||||
<width>61</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>1 Hz</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QRadioButton" name="rb10Hz">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>10</x>
|
|
||||||
<y>46</y>
|
|
||||||
<width>71</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>10 Hz</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QRadioButton" name="rb100Hz">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>10</x>
|
|
||||||
<y>69</y>
|
|
||||||
<width>71</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>100 Hz</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>20</x>
|
|
||||||
<y>230</y>
|
|
||||||
<width>185</width>
|
|
||||||
<height>73</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>185</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Audio frequency tracking</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QCheckBox" name="cbRxTrack">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>10</x>
|
|
||||||
<y>23</y>
|
|
||||||
<width>36</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Rx</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QCheckBox" name="cbTxTrack">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>10</x>
|
|
||||||
<y>46</y>
|
|
||||||
<width>35</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Tx</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
<widget class="QGroupBox" name="groupBox_4">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>20</x>
|
|
||||||
<y>310</y>
|
|
||||||
<width>185</width>
|
|
||||||
<height>51</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>185</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>kHz above nominal band edge</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QSpinBox" name="kHzSpinBox">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>50</x>
|
|
||||||
<y>20</y>
|
|
||||||
<width>51</width>
|
|
||||||
<height>22</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>999</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="layoutWidget">
|
<widget class="QWidget" name="layoutWidget">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>1</x>
|
<x>1</x>
|
||||||
<y>386</y>
|
<y>410</y>
|
||||||
<width>195</width>
|
<width>195</width>
|
||||||
<height>22</height>
|
<height>22</height>
|
||||||
</rect>
|
</rect>
|
||||||
@ -327,6 +116,259 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>200</x>
|
||||||
|
<y>12</y>
|
||||||
|
<width>198</width>
|
||||||
|
<height>411</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>196</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>60</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Frequency above nominal band edge</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QSpinBox" name="kHzSpinBox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>75</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>75</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> kHz</string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>999</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>200</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QSpinBox" name="HzSpinBox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>100</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>75</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>75</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> Hz</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-2000</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>2000</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>196</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>100</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Doppler tracking</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbFullTrack">
|
||||||
|
<property name="text">
|
||||||
|
<string>Full Doppler to DX Grid</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbConstFreqOnMoon">
|
||||||
|
<property name="text">
|
||||||
|
<string>Constant frequency on Moon</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbNoDoppler">
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>196</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>90</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Transceiver step size</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QRadioButton" name="rb1Hz">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>23</y>
|
||||||
|
<width>61</width>
|
||||||
|
<height>17</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>1 Hz</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QRadioButton" name="rb10Hz">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>46</y>
|
||||||
|
<width>71</width>
|
||||||
|
<height>17</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>10 Hz</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QRadioButton" name="rb100Hz">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>69</y>
|
||||||
|
<width>71</width>
|
||||||
|
<height>17</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>100 Hz</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>196</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>60</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Tx audio tracking</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QCheckBox" name="cbTxAudioTrack">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>105</width>
|
||||||
|
<height>17</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>44</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define COMMONS_H
|
#define COMMONS_H
|
||||||
|
|
||||||
#define NSMAX 6827
|
#define NSMAX 6827
|
||||||
#define NTMAX 60
|
#define NTMAX 120
|
||||||
#define RX_SAMPLE_RATE 12000
|
#define RX_SAMPLE_RATE 12000
|
||||||
|
|
||||||
extern struct FortranCommon {
|
extern struct FortranCommon {
|
||||||
@ -28,6 +28,7 @@ extern struct FortranCommon {
|
|||||||
int nmode;
|
int nmode;
|
||||||
int minw;
|
int minw;
|
||||||
int nclearave;
|
int nclearave;
|
||||||
|
int minSync;
|
||||||
float emedelay;
|
float emedelay;
|
||||||
float dttol;
|
float dttol;
|
||||||
int nlist;
|
int nlist;
|
||||||
|
@ -13,4 +13,4 @@ GNU General Public License for more details.
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this documentation. If not, see {gnu_gpl}.
|
along with this documentation. If not, see {gnu_gpl}.
|
||||||
|
|
||||||
Copyright (C) 2001-2014 Joseph H Taylor, Jr, {joe_taylor}.
|
Copyright (C) 2001-2015 Joseph H Taylor, Jr, {joe_taylor}.
|
||||||
|
@ -8,10 +8,10 @@ suggestions and advice that have greatly aided the development of
|
|||||||
_WSJT_ and its sister programs.
|
_WSJT_ and its sister programs.
|
||||||
|
|
||||||
For _WSJT-X_ in particular, we acknowledge contributions from *AC6SL,
|
For _WSJT-X_ in particular, we acknowledge contributions from *AC6SL,
|
||||||
AE4JY, DJ0OT, G4KLA, G4WJS, K3WYC, KA6MAL, KA9Q, KB1ZMX, KI7MT, KK1D,
|
AE4JY, DJ0OT, G4KLA, G4WJS, K3WYC, K9AN, KA6MAL, KA9Q, KB1ZMX, KD6EKQ,
|
||||||
PY2SDR, VK3ACF, VK4BDJ, W4TI, W4TV, and W9MDB*. Each of these
|
KI7MT, KK1D, ND0B, PY2SDR, VK3ACF, VK4BDJ, W4TI, W4TV, and W9MDB*.
|
||||||
amateurs has helped to bring the program’s design, code, and
|
Each of these amateurs has helped to bring the program’s design, code,
|
||||||
documentation to its present state.
|
and documentation to its present state.
|
||||||
|
|
||||||
Most of the color palettes for the _WSJT-X_ waterfall were copied from
|
Most of the color palettes for the _WSJT-X_ waterfall were copied from
|
||||||
the excellent, well documented, open-source program _fldigi_, by *W1HKJ*
|
the excellent, well documented, open-source program _fldigi_, by *W1HKJ*
|
||||||
|
@ -31,7 +31,7 @@ subroutine astro0(nyear,month,nday,uth8,freq8,mygrid,hisgrid, &
|
|||||||
call tm2(day8,xlat2,xlon2,xl2,b2)
|
call tm2(day8,xlat2,xlon2,xl2,b2)
|
||||||
call tm2(day8+1.d0/1440.0,xlat1,xlon1,xl1a,b1a)
|
call tm2(day8+1.d0/1440.0,xlat1,xlon1,xl1a,b1a)
|
||||||
call tm2(day8+1.d0/1440.0,xlat2,xlon2,xl2a,b2a)
|
call tm2(day8+1.d0/1440.0,xlat2,xlon2,xl2a,b2a)
|
||||||
fghz=0.001*nfreq
|
fghz=1.d-9*freq8
|
||||||
dldt1=DEGS*(xl1a-xl1)
|
dldt1=DEGS*(xl1a-xl1)
|
||||||
dbdt1=DEGS*(b1a-b1)
|
dbdt1=DEGS*(b1a-b1)
|
||||||
dldt2=DEGS*(xl2a-xl2)
|
dldt2=DEGS*(xl2a-xl2)
|
||||||
|
@ -1,14 +1,48 @@
|
|||||||
subroutine astrosub(nyear,month,nday,uth8,freq8,mygrid,hisgrid, &
|
subroutine astrosub(nyear,month,nday,uth8,freq8,mygrid,hisgrid, &
|
||||||
AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, &
|
AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, &
|
||||||
RAMoon8,DecMoon8,Dgrd8,poloffset8,xnr8,techo8)
|
RAMoon8,DecMoon8,Dgrd8,poloffset8,xnr8,techo8,width1,width2,bTx,fname)
|
||||||
|
|
||||||
implicit real*8 (a-h,o-z)
|
implicit real*8 (a-h,o-z)
|
||||||
character*6 mygrid,hisgrid
|
character*6 mygrid,hisgrid,fname*(*),c1*1
|
||||||
|
logical*1 bTx
|
||||||
|
|
||||||
call astro0(nyear,month,nday,uth8,freq8,mygrid,hisgrid, &
|
call astro0(nyear,month,nday,uth8,freq8,mygrid,hisgrid, &
|
||||||
AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, &
|
AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, &
|
||||||
dbMoon8,RAMoon8,DecMoon8,HA8,Dgrd8,sd8,poloffset8,xnr8,dfdt,dfdt0, &
|
dbMoon8,RAMoon8,DecMoon8,HA8,Dgrd8,sd8,poloffset8,xnr8,dfdt,dfdt0, &
|
||||||
width1,width2,w501,w502,xlst8,techo8)
|
width1,width2,w501,w502,xlst8,techo8)
|
||||||
|
|
||||||
return
|
imin=60*uth8
|
||||||
|
isec=3600*uth8
|
||||||
|
ih=uth8
|
||||||
|
im=mod(imin,60)
|
||||||
|
is=mod(isec,60)
|
||||||
|
open(15,file=fname,status='unknown',err=900)
|
||||||
|
c1='R'
|
||||||
|
nRx=1
|
||||||
|
if(bTx) then
|
||||||
|
c1='T'
|
||||||
|
nRx=0
|
||||||
|
endif
|
||||||
|
AzAux=0.
|
||||||
|
ElAux=0.
|
||||||
|
nfreq=freq8/1000000
|
||||||
|
doppler=ndop
|
||||||
|
doppler00=ndop00
|
||||||
|
write(15,1010,err=10) ih,im,is,AzMoon8,ElMoon8, &
|
||||||
|
ih,im,is,AzSun8,ElSun8, &
|
||||||
|
ih,im,is,AzAux,ElAux, &
|
||||||
|
nfreq,doppler,dfdt,doppler00,dfdt0,c1
|
||||||
|
! TXFirst,TRPeriod,poloffset,Dgrd,xnr,ave,rms,nRx
|
||||||
|
1010 format( &
|
||||||
|
i2.2,':',i2.2,':',i2.2,',',f5.1,',',f5.1,',Moon'/ &
|
||||||
|
i2.2,':',i2.2,':',i2.2,',',f5.1,',',f5.1,',Sun'/ &
|
||||||
|
i2.2,':',i2.2,':',i2.2,',',f5.1,',',f5.1,',Source'/ &
|
||||||
|
i5,',',f8.1,',',f8.2,',',f8.1,',',f8.2,',Doppler, ',a1)
|
||||||
|
! i1,',',i3,',',f8.1,','f8.1,',',f8.1,',',f12.3,',',f12.3,',',i1,',RPol')
|
||||||
|
10 close(15)
|
||||||
|
go to 999
|
||||||
|
|
||||||
|
900 print*,'Error opening azel.dat'
|
||||||
|
|
||||||
|
999 return
|
||||||
end subroutine astrosub
|
end subroutine astrosub
|
||||||
|
@ -69,7 +69,7 @@ subroutine avg4(nutc,snrsync,dtxx,flip,nfreq,mode4,ntol,ndepth,neme, &
|
|||||||
do i=1,nsave
|
do i=1,nsave
|
||||||
csync='*'
|
csync='*'
|
||||||
if(flipsave(i).lt.0.0) csync='#'
|
if(flipsave(i).lt.0.0) csync='#'
|
||||||
write(14,1000) cused(i),iutc(i),syncsave(i),dtsave(i),nfsave(i),csync
|
write(14,1000) cused(i),iutc(i),syncsave(i)-5.0,dtsave(i),nfsave(i),csync
|
||||||
1000 format(a1,i5.4,f6.1,f6.2,i6,1x,a1)
|
1000 format(a1,i5.4,f6.1,f6.2,i6,1x,a1)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
@ -39,15 +39,18 @@ program code426
|
|||||||
do j=5,nmsgs !Find codewords up to j=nmsgs with maximum
|
do j=5,nmsgs !Find codewords up to j=nmsgs with maximum
|
||||||
npk=0 !distance from all the rest
|
npk=0 !distance from all the rest
|
||||||
do i=1,iters
|
do i=1,iters
|
||||||
call random_number(c)
|
call random_number(c) !Generate a random codeword candidate
|
||||||
ic(1:MZ,j)=int(4*c)
|
ic(1:MZ,j)=int(4*c) !Convert real to integer
|
||||||
nd=MZ
|
! nd=MZ
|
||||||
do k=1,j-1 !Test candidate against all others in list
|
! do k=1,j-1 !Test candidate against all others in list
|
||||||
nd=min(nd,count(ic(1:MZ,j).ne.ic(1:MZ,k)))
|
! n=count(ic(1:MZ,j).ne.ic(1:MZ,k))
|
||||||
enddo
|
! nd=min(n,nd)
|
||||||
if(nd.gt.npk) then
|
! enddo
|
||||||
npk=nd
|
call dist426(ic,j,mind)
|
||||||
|
if(mind.gt.npk) then
|
||||||
|
npk=mind
|
||||||
icsave=ic(1:MZ,j) !Best candidate so far, save it
|
icsave=ic(1:MZ,j) !Best candidate so far, save it
|
||||||
|
! if(npk.ge.19) exit !It won't get any better...
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
write(*,1000) j,npk,ic(1:MZ,j)
|
write(*,1000) j,npk,ic(1:MZ,j)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
parameter (NTMAX=60)
|
parameter (NTMAX=120)
|
||||||
parameter (NMAX=NTMAX*12000) !Total sample intervals (one minute)
|
parameter (NMAX=NTMAX*12000) !Total sample intervals (one minute)
|
||||||
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate
|
parameter (NDMAX=NTMAX*1500) !Sample intervals at 1500 Hz rate
|
||||||
parameter (NSMAX=6827) !Max length of saved spectra
|
parameter (NSMAX=6827) !Max length of saved spectra
|
||||||
|
@ -23,7 +23,8 @@ subroutine decode4(dat,npts,dtx,nfreq,flip,mode4,ndepth,neme,minw, &
|
|||||||
istart=nint((dtx+0.8)/dt) !Start index for synced FFTs
|
istart=nint((dtx+0.8)/dt) !Start index for synced FFTs
|
||||||
if(istart.lt.0) istart=0
|
if(istart.lt.0) istart=0
|
||||||
nchips=0
|
nchips=0
|
||||||
qbest=0.0
|
qbest=0.
|
||||||
|
qtop=0.
|
||||||
deepmsg=' '
|
deepmsg=' '
|
||||||
ichbest=-1
|
ichbest=-1
|
||||||
c0=0.
|
c0=0.
|
||||||
|
@ -11,7 +11,8 @@ subroutine decoder(ss,id2,nfsample)
|
|||||||
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
||||||
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfsplit,nfb, &
|
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfsplit,nfb, &
|
||||||
ntol,kin,nzhsym,nsubmode,nagain,ndepth,ntxmode,nmode,minw,nclearave, &
|
ntol,kin,nzhsym,nsubmode,nagain,ndepth,ntxmode,nmode,minw,nclearave, &
|
||||||
emedelay,dttol,nlist,listutc(10),datetime,mycall,mygrid,hiscall,hisgrid
|
minsync,emedelay,dttol,nlist,listutc(10),datetime,mycall,mygrid, &
|
||||||
|
hiscall,hisgrid
|
||||||
|
|
||||||
common/tracer/limtrace,lu
|
common/tracer/limtrace,lu
|
||||||
integer onlevel(0:10)
|
integer onlevel(0:10)
|
||||||
@ -41,9 +42,9 @@ subroutine decoder(ss,id2,nfsample)
|
|||||||
if(nfsample.eq.12000) call wav11(id2,jz,dd)
|
if(nfsample.eq.12000) call wav11(id2,jz,dd)
|
||||||
if(nfsample.eq.11025) dd(1:jz)=id2(1:jz)
|
if(nfsample.eq.11025) dd(1:jz)=id2(1:jz)
|
||||||
endif
|
endif
|
||||||
call jt4a(dd,jz,nutc,nfqso,newdat,nfa,nfb,ntol,emedelay,dttol, &
|
call jt4a(dd,jz,nutc,nfqso,ntol,emedelay,dttol,nagain,ndepth, &
|
||||||
nagain,ndepth,nclearave,minw,nsubmode,mycall,mygrid,hiscall, &
|
nclearave,minsync,minw,nsubmode,mycall,hiscall,hisgrid, &
|
||||||
hisgrid,nlist,listutc)
|
nlist,listutc)
|
||||||
go to 800
|
go to 800
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ subroutine encode232(dat,nsym,symbol)
|
|||||||
! Convolutional encoder for a K=32, r=1/2 code.
|
! Convolutional encoder for a K=32, r=1/2 code.
|
||||||
|
|
||||||
integer*1 dat(13) !User data, packed 8 bits per byte
|
integer*1 dat(13) !User data, packed 8 bits per byte
|
||||||
integer*1 symbol(500) !Channel symbols, one bit per byte
|
integer*1 symbol(206) !Channel symbols, one bit per byte
|
||||||
integer*1 i1
|
integer*1 i1
|
||||||
include 'conv232.f90'
|
include 'conv232.f90'
|
||||||
|
|
||||||
|
72
lib/fil3c.f90
Normal file
72
lib/fil3c.f90
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
subroutine fil3c(c1,n1,c2,n2)
|
||||||
|
|
||||||
|
! FIR complex-to-complex low-pass filter designed with ScopeFIR
|
||||||
|
!
|
||||||
|
!-----------------------------------------------
|
||||||
|
! fsample (Hz) 12000 Input sample rate
|
||||||
|
! Ntaps 113 Number of filter taps
|
||||||
|
! fc (Hz) 500 Cutoff frequency
|
||||||
|
! fstop (Hz) 750 Lower limit of stopband
|
||||||
|
! Ripple (dB) 0.2 Ripple in passband
|
||||||
|
! Stop Atten (dB) 50 Stopband attenuation
|
||||||
|
! fout (Hz) 1500 Output sample rate
|
||||||
|
|
||||||
|
! Suggest calling with n1 = 8*n2 + 105, where n2 is the desired number
|
||||||
|
! of 1500 Hz output samples.
|
||||||
|
|
||||||
|
parameter (NTAPS=113)
|
||||||
|
parameter (NH=NTAPS/2)
|
||||||
|
parameter (NDOWN=8) !Downsample ratio = 1/8
|
||||||
|
complex c1(n1)
|
||||||
|
complex c2(n1/NDOWN)
|
||||||
|
complex z
|
||||||
|
|
||||||
|
! Filter coefficients:
|
||||||
|
real a(-NH:NH)
|
||||||
|
data a/ &
|
||||||
|
-0.001818142144,-0.000939132050,-0.001044063556,-0.001042685542, &
|
||||||
|
-0.000908957610,-0.000628132309,-0.000202701465, 0.000346307629, &
|
||||||
|
0.000978154552, 0.001634336295, 0.002243121592, 0.002726064379, &
|
||||||
|
0.003006201675, 0.003018055983, 0.002717699575, 0.002091546534, &
|
||||||
|
0.001162489032,-0.000007904811,-0.001321554806,-0.002649908053, &
|
||||||
|
-0.003843608784,-0.004747338068,-0.005218967042,-0.005148229529, &
|
||||||
|
-0.004470167307,-0.003177923811,-0.001335998901, 0.000915924193, &
|
||||||
|
0.003386100636, 0.005818719744, 0.007939147967, 0.009465071347, &
|
||||||
|
0.010145641899, 0.009787447819, 0.008285915754, 0.005645995244, &
|
||||||
|
0.001995842303,-0.002410369720,-0.007202515555,-0.011916811719, &
|
||||||
|
-0.016028350845,-0.018993391440,-0.020297455955,-0.019503792208, &
|
||||||
|
-0.016298136197,-0.010526834635,-0.002223837363, 0.008378305829, &
|
||||||
|
0.020854478160, 0.034608532659, 0.048909701463, 0.062944127288, &
|
||||||
|
0.075874892030, 0.086903764340, 0.095332017649, 0.100619428175, &
|
||||||
|
0.102420526192, 0.100619428175, 0.095332017649, 0.086903764340, &
|
||||||
|
0.075874892030, 0.062944127288, 0.048909701463, 0.034608532659, &
|
||||||
|
0.020854478160, 0.008378305829,-0.002223837363,-0.010526834635, &
|
||||||
|
-0.016298136197,-0.019503792208,-0.020297455955,-0.018993391440, &
|
||||||
|
-0.016028350845,-0.011916811719,-0.007202515555,-0.002410369720, &
|
||||||
|
0.001995842303, 0.005645995244, 0.008285915754, 0.009787447819, &
|
||||||
|
0.010145641899, 0.009465071347, 0.007939147967, 0.005818719744, &
|
||||||
|
0.003386100636, 0.000915924193,-0.001335998901,-0.003177923811, &
|
||||||
|
-0.004470167307,-0.005148229529,-0.005218967042,-0.004747338068, &
|
||||||
|
-0.003843608784,-0.002649908053,-0.001321554806,-0.000007904811, &
|
||||||
|
0.001162489032, 0.002091546534, 0.002717699575, 0.003018055983, &
|
||||||
|
0.003006201675, 0.002726064379, 0.002243121592, 0.001634336295, &
|
||||||
|
0.000978154552, 0.000346307629,-0.000202701465,-0.000628132309, &
|
||||||
|
-0.000908957610,-0.001042685542,-0.001044063556,-0.000939132050, &
|
||||||
|
-0.001818142144/
|
||||||
|
save a
|
||||||
|
|
||||||
|
n2=(n1-NTAPS+NDOWN)/NDOWN
|
||||||
|
k0=NH-NDOWN+1
|
||||||
|
|
||||||
|
! Loop over all output samples
|
||||||
|
do i=1,n2
|
||||||
|
z=0.
|
||||||
|
k=k0 + NDOWN*i
|
||||||
|
do j=-NH,NH
|
||||||
|
z=z + c1(j+k)*a(j)
|
||||||
|
enddo
|
||||||
|
c2(i)=z
|
||||||
|
enddo
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine fil3c
|
@ -5,7 +5,8 @@ subroutine fillcom(nutc0,ndepth0,nrxfreq,mode,tx9,flow,fsplit,fhigh)
|
|||||||
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
||||||
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfsplit,nfb, &
|
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfsplit,nfb, &
|
||||||
ntol,kin,nzhsym,nsubmode,nagain,ndepth,ntxmode,nmode,minw,nclearave, &
|
ntol,kin,nzhsym,nsubmode,nagain,ndepth,ntxmode,nmode,minw,nclearave, &
|
||||||
emedelay,dttol,nlist,listutc(10),datetime,mycall,mygrid,hiscall,hisgrid
|
minsync,emedelay,dttol,nlist,listutc(10),datetime,mycall,mygrid, &
|
||||||
|
hiscall,hisgrid
|
||||||
save
|
save
|
||||||
|
|
||||||
nutc=nutc0
|
nutc=nutc0
|
||||||
|
@ -12,14 +12,10 @@ subroutine flat1(savg,iz,nsmo,syellow)
|
|||||||
call pctile(savg(i-nsmo/2),nsmo,50,x(i))
|
call pctile(savg(i-nsmo/2),nsmo,50,x(i))
|
||||||
x(i-nh:i+nh-1)=x(i)
|
x(i-nh:i+nh-1)=x(i)
|
||||||
enddo
|
enddo
|
||||||
do i=1,ia-1
|
x(1:ia-1)=x(ia)
|
||||||
x(i)=x(ia)
|
x(ib+1:iz)=x(ib)
|
||||||
enddo
|
|
||||||
do i=ib+1,iz
|
|
||||||
x(i)=x(ib)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
x0=0.001*maxval(x(1:iz))
|
x0=0.001*maxval(x(iz/10:(9*iz)/10))
|
||||||
syellow(1:iz)=savg(1:iz)/(x(1:iz)+x0)
|
syellow(1:iz)=savg(1:iz)/(x(1:iz)+x0)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
31
lib/genwspr.f90
Normal file
31
lib/genwspr.f90
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
subroutine genwspr(message,msgsent,itone)
|
||||||
|
! Encode a WSPR message and generate the array of channel symbols.
|
||||||
|
|
||||||
|
character*22 message,msgsent
|
||||||
|
parameter (MAXSYM=176)
|
||||||
|
integer*1 symbol(MAXSYM)
|
||||||
|
integer*1 data0(11)
|
||||||
|
integer*4 itone(162)
|
||||||
|
integer npr3(162)
|
||||||
|
data npr3/ &
|
||||||
|
1,1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0, &
|
||||||
|
0,1,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1, &
|
||||||
|
0,0,0,0,0,0,1,0,1,1,0,0,1,1,0,1,0,0,0,1, &
|
||||||
|
1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1, &
|
||||||
|
0,0,1,0,1,1,0,0,0,1,1,0,1,0,1,0,0,0,1,0, &
|
||||||
|
0,0,0,0,1,0,0,1,0,0,1,1,1,0,1,1,0,0,1,1, &
|
||||||
|
0,1,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,0,1,1, &
|
||||||
|
0,0,0,0,0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,0, &
|
||||||
|
0,0/
|
||||||
|
|
||||||
|
call wqencode(message,ntype,data0) !Source encoding
|
||||||
|
nbytes=(50+31+7)/8
|
||||||
|
call encode232(data0,162,symbol) !Convolutional encoding
|
||||||
|
call inter_wspr(symbol,1) !Interleaving
|
||||||
|
do i=1,162
|
||||||
|
itone(i)=npr3(i) + 2*symbol(i)
|
||||||
|
enddo
|
||||||
|
msgsent=message !### To be fixed... ?? ###
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine genwspr
|
32
lib/grayline.f90
Normal file
32
lib/grayline.f90
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
subroutine grayline(nyear,month,nday,uth,mygrid,nduration,isun)
|
||||||
|
|
||||||
|
character*6 mygrid
|
||||||
|
real LST
|
||||||
|
real lat,lon
|
||||||
|
|
||||||
|
call grid2deg(MyGrid,elon,lat)
|
||||||
|
lon=-elon
|
||||||
|
|
||||||
|
uth0=uth-0.5*nduration/60.0
|
||||||
|
uth1=uth+0.5*nduration/60.0
|
||||||
|
|
||||||
|
call sun(nyear,month,nday,uth0,lon,lat,RASun,DecSun,LST, &
|
||||||
|
AzSun,ElSun0,mjd,day)
|
||||||
|
call sun(nyear,month,nday,uth1,lon,lat,RASun,DecSun,LST, &
|
||||||
|
AzSun,ElSun1,mjd,day)
|
||||||
|
|
||||||
|
elchk=-0.8333
|
||||||
|
isun=-1
|
||||||
|
if(elsun0.lt.elchk .and. elsun1.ge.elchk) then
|
||||||
|
isun=0
|
||||||
|
else if(elsun0.gt.elchk .and. elsun1.le.elchk) then
|
||||||
|
isun=2
|
||||||
|
else if(elsun1.gt.elchk) then
|
||||||
|
isun=1
|
||||||
|
else
|
||||||
|
isun=3
|
||||||
|
endif
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine grayline
|
||||||
|
|
15
lib/hash.f90
Normal file
15
lib/hash.f90
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
subroutine hash(string,len,ihash)
|
||||||
|
|
||||||
|
parameter (MASK15=32767)
|
||||||
|
character*(*) string
|
||||||
|
integer*1 ic(12)
|
||||||
|
|
||||||
|
do i=1,len
|
||||||
|
ic(i)=ichar(string(i:i))
|
||||||
|
enddo
|
||||||
|
i=nhash(ic,len,146)
|
||||||
|
ihash=iand(i,MASK15)
|
||||||
|
|
||||||
|
! print*,'C',ihash,len,string
|
||||||
|
return
|
||||||
|
end subroutine hash
|
81
lib/hopping.f90
Normal file
81
lib/hopping.f90
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
subroutine hopping(nyear,month,nday,uth,mygrid,nduration,npctx,isun, &
|
||||||
|
iband,ntxnext)
|
||||||
|
|
||||||
|
! Determine Rx or Tx in coordinated hopping mode.
|
||||||
|
|
||||||
|
character*6 mygrid
|
||||||
|
integer tx(10,6) !T/R array for 2 hours: 10 bands, 6 time slots
|
||||||
|
real r(6) !Random numbers
|
||||||
|
integer ii(1)
|
||||||
|
data n2hr0/-999/
|
||||||
|
save n2hr0,tx
|
||||||
|
|
||||||
|
call grayline(nyear,month,nday,uth,mygrid,nduration,isun)
|
||||||
|
|
||||||
|
ns0=uth*3600.0
|
||||||
|
pctx=npctx
|
||||||
|
nrx=0
|
||||||
|
ntxnext=0
|
||||||
|
nsec=(ns0+10)/120 !Round up to start of next 2-min slot
|
||||||
|
nsec=nsec*120
|
||||||
|
n2hr=nsec/7200 !2-hour slot number
|
||||||
|
|
||||||
|
if(n2hr.ne.n2hr0) then
|
||||||
|
! Compute a new Rx/Tx pattern for this 2-hour interval
|
||||||
|
n2hr0=n2hr !Mark this one as done
|
||||||
|
tx=0 !Clear the tx array
|
||||||
|
do j=1,10 !Loop over all 10 bands
|
||||||
|
call random_number(r)
|
||||||
|
do i=1,6,2 !Select one each of 3 pairs of the
|
||||||
|
if(r(i).gt.r(i+1)) then ! 6 slots for Tx
|
||||||
|
tx(j,i)=1
|
||||||
|
r(i+1)=0.
|
||||||
|
else
|
||||||
|
tx(j,i+1)=1
|
||||||
|
r(i)=0.
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
if(pctx.lt.50.0) then !If pctx < 50, we may kill one Tx slot
|
||||||
|
ii=maxloc(r)
|
||||||
|
i=ii(1)
|
||||||
|
call random_number(rr)
|
||||||
|
rrtest=(50.0-pctx)/16.667
|
||||||
|
if(rr.lt.rrtest) then
|
||||||
|
tx(j,i)=0
|
||||||
|
r(i)=0.
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if(pctx.lt.33.333) then !If pctx < 33, may kill another
|
||||||
|
ii=maxloc(r)
|
||||||
|
i=ii(1)
|
||||||
|
call random_number(rr)
|
||||||
|
rrtest=(33.333-pctx)/16.667
|
||||||
|
if(rr.lt.rrtest) then
|
||||||
|
tx(j,i)=0
|
||||||
|
r(i)=0.
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
! We now have 1 to 3 Tx periods per band in the 2-hour interval.
|
||||||
|
endif
|
||||||
|
|
||||||
|
iband=mod(nsec/120,10) + 1
|
||||||
|
iseq=mod(nsec/1200,6) + 1
|
||||||
|
if(iseq.lt.1) iseq=1
|
||||||
|
if(tx(iband,iseq).eq.1) then
|
||||||
|
ntxnext=1
|
||||||
|
else
|
||||||
|
nrx=1
|
||||||
|
endif
|
||||||
|
iband=iband-1
|
||||||
|
|
||||||
|
! write(*,3000) iband,iseq,nrx,ntxnext
|
||||||
|
!3000 format('Fortran iband, iseq,nrx,ntxnext:',4i5)
|
||||||
|
! write(*,3001) int(tx)
|
||||||
|
!3001 format(10i2)
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine hopping
|
100
lib/indexx.f90
100
lib/indexx.f90
@ -1,19 +1,91 @@
|
|||||||
subroutine indexx(n,arr,indx)
|
subroutine indexx(arr,n,indx)
|
||||||
|
|
||||||
parameter (NMAX=3000)
|
parameter (M=7,NSTACK=50)
|
||||||
integer indx(n)
|
integer n,indx(n)
|
||||||
real arr(n)
|
integer arr(n)
|
||||||
real brr(NMAX)
|
integer i,indxt,ir,itemp,j,jstack,k,l,istack(NSTACK)
|
||||||
if(n.gt.NMAX) then
|
real a
|
||||||
print*,'n=',n,' too big in indexx.'
|
|
||||||
stop
|
do j=1,n
|
||||||
endif
|
indx(j)=j
|
||||||
do i=1,n
|
|
||||||
brr(i)=arr(i)
|
|
||||||
indx(i)=i
|
|
||||||
enddo
|
enddo
|
||||||
call ssort(brr,indx,n,2)
|
|
||||||
|
|
||||||
return
|
jstack=0
|
||||||
|
l=1
|
||||||
|
ir=n
|
||||||
|
1 if(ir-l.lt.M) then
|
||||||
|
do j=l+1,ir
|
||||||
|
indxt=indx(j)
|
||||||
|
a=arr(indxt)
|
||||||
|
do i=j-1,1,-1
|
||||||
|
if(arr(indx(i)).le.a) goto 2
|
||||||
|
indx(i+1)=indx(i)
|
||||||
|
enddo
|
||||||
|
i=0
|
||||||
|
2 indx(i+1)=indxt
|
||||||
|
enddo
|
||||||
|
if(jstack.eq.0) return
|
||||||
|
|
||||||
|
ir=istack(jstack)
|
||||||
|
l=istack(jstack-1)
|
||||||
|
jstack=jstack-2
|
||||||
|
|
||||||
|
else
|
||||||
|
k=(l+ir)/2
|
||||||
|
itemp=indx(k)
|
||||||
|
indx(k)=indx(l+1)
|
||||||
|
indx(l+1)=itemp
|
||||||
|
|
||||||
|
if(arr(indx(l+1)).gt.arr(indx(ir))) then
|
||||||
|
itemp=indx(l+1)
|
||||||
|
indx(l+1)=indx(ir)
|
||||||
|
indx(ir)=itemp
|
||||||
|
endif
|
||||||
|
|
||||||
|
if(arr(indx(l)).gt.arr(indx(ir))) then
|
||||||
|
itemp=indx(l)
|
||||||
|
indx(l)=indx(ir)
|
||||||
|
indx(ir)=itemp
|
||||||
|
endif
|
||||||
|
|
||||||
|
if(arr(indx(l+1)).gt.arr(indx(l))) then
|
||||||
|
itemp=indx(l+1)
|
||||||
|
indx(l+1)=indx(l)
|
||||||
|
indx(l)=itemp
|
||||||
|
endif
|
||||||
|
|
||||||
|
i=l+1
|
||||||
|
j=ir
|
||||||
|
indxt=indx(l)
|
||||||
|
a=arr(indxt)
|
||||||
|
3 continue
|
||||||
|
i=i+1
|
||||||
|
if(arr(indx(i)).lt.a) goto 3
|
||||||
|
|
||||||
|
4 continue
|
||||||
|
j=j-1
|
||||||
|
if(arr(indx(j)).gt.a) goto 4
|
||||||
|
if(j.lt.i) goto 5
|
||||||
|
itemp=indx(i)
|
||||||
|
indx(i)=indx(j)
|
||||||
|
indx(j)=itemp
|
||||||
|
goto 3
|
||||||
|
|
||||||
|
5 indx(l)=indx(j)
|
||||||
|
indx(j)=indxt
|
||||||
|
jstack=jstack+2
|
||||||
|
if(jstack.gt.NSTACK) stop 'NSTACK too small in indexx'
|
||||||
|
if(ir-i+1.ge.j-l)then
|
||||||
|
istack(jstack)=ir
|
||||||
|
istack(jstack-1)=i
|
||||||
|
ir=j-1
|
||||||
|
else
|
||||||
|
istack(jstack)=j-1
|
||||||
|
istack(jstack-1)=l
|
||||||
|
l=i
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
goto 1
|
||||||
|
|
||||||
end subroutine indexx
|
end subroutine indexx
|
||||||
|
|
||||||
|
45
lib/inter_wspr.f90
Normal file
45
lib/inter_wspr.f90
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
subroutine inter_wspr(id,ndir)
|
||||||
|
|
||||||
|
! Interleave (ndir=1) or de-interleave (ndir=-1) the array id.
|
||||||
|
|
||||||
|
integer*1 id(0:161),itmp(0:161)
|
||||||
|
integer j0(0:161)
|
||||||
|
logical first
|
||||||
|
data first/.true./
|
||||||
|
save
|
||||||
|
|
||||||
|
if(first) then
|
||||||
|
! Compute the interleave table using bit reversal.
|
||||||
|
k=-1
|
||||||
|
do i=0,255
|
||||||
|
n=0
|
||||||
|
ii=i
|
||||||
|
do j=0,7
|
||||||
|
n=n+n
|
||||||
|
if(iand(ii,1).ne.0) n=n+1
|
||||||
|
ii=ii/2
|
||||||
|
enddo
|
||||||
|
if(n.le.161) then
|
||||||
|
k=k+1
|
||||||
|
j0(k)=n
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
first=.false.
|
||||||
|
endif
|
||||||
|
|
||||||
|
if(ndir.eq.1) then
|
||||||
|
do i=0,161
|
||||||
|
itmp(j0(i))=id(i)
|
||||||
|
enddo
|
||||||
|
else
|
||||||
|
do i=0,161
|
||||||
|
itmp(i)=id(j0(i))
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
|
||||||
|
do i=0,161
|
||||||
|
id(i)=itmp(i)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine inter_wspr
|
@ -1,6 +1,5 @@
|
|||||||
subroutine jt4a(dd,jz,nutc,nfqso,newdat,nfa,nfb,ntol0,emedelay,dttol, &
|
subroutine jt4a(dd,jz,nutc,nfqso,ntol0,emedelay,dttol,nagain,ndepth, &
|
||||||
nagain,ndepth,nclearave,minw,nsubmode,mycall,mygrid,hiscall,hisgrid, &
|
nclearave,minsync,minw,nsubmode,mycall,hiscall,hisgrid,nlist0,listutc0)
|
||||||
nlist0,listutc0)
|
|
||||||
|
|
||||||
use jt4
|
use jt4
|
||||||
integer listutc0(10)
|
integer listutc0(10)
|
||||||
@ -8,7 +7,7 @@ subroutine jt4a(dd,jz,nutc,nfqso,newdat,nfa,nfb,ntol0,emedelay,dttol, &
|
|||||||
real*4 dat(30*12000)
|
real*4 dat(30*12000)
|
||||||
character*6 cfile6
|
character*6 cfile6
|
||||||
character*12 mycall,hiscall
|
character*12 mycall,hiscall
|
||||||
character*6 mygrid,hisgrid
|
character*6 hisgrid
|
||||||
|
|
||||||
mode4=nch(nsubmode+1)
|
mode4=nch(nsubmode+1)
|
||||||
ntol=ntol0
|
ntol=ntol0
|
||||||
@ -35,7 +34,7 @@ subroutine jt4a(dd,jz,nutc,nfqso,newdat,nfa,nfb,ntol0,emedelay,dttol, &
|
|||||||
cfile6(5:6)=' '
|
cfile6(5:6)=' '
|
||||||
|
|
||||||
call timer('wsjt4 ',0)
|
call timer('wsjt4 ',0)
|
||||||
call wsjt4(dat,jz2,nutc,NClearAve,ntol,emedelay,dttol,mode4,minw, &
|
call wsjt4(dat,jz2,nutc,NClearAve,minsync,ntol,emedelay,dttol,mode4,minw, &
|
||||||
mycall,hiscall,hisgrid,nfqso,NAgain,ndepth,neme)
|
mycall,hiscall,hisgrid,nfqso,NAgain,ndepth,neme)
|
||||||
call timer('wsjt4 ',1)
|
call timer('wsjt4 ',1)
|
||||||
|
|
||||||
|
11
lib/jt9.f90
11
lib/jt9.f90
@ -52,8 +52,9 @@ program jt9
|
|||||||
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
||||||
common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
|
common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
|
||||||
ntr,mousefqso,newdat,npts8a,nfa,nfsplit,nfb,ntol,kin,nzhsym, &
|
ntr,mousefqso,newdat,npts8a,nfa,nfsplit,nfb,ntol,kin,nzhsym, &
|
||||||
nsubmode,nagain,ndepth,ntxmode,nmode,minw,nclearave,emedelay, &
|
nsubmode,nagain,ndepth,ntxmode,nmode,minw,nclearave,minsync, &
|
||||||
dttol,nlist,listutc(10),datetime,mycall,mygrid,hiscall,hisgrid
|
emedelay,dttol,nlist,listutc(10),datetime,mycall,mygrid, &
|
||||||
|
hiscall,hisgrid
|
||||||
|
|
||||||
common/tracer/limtrace,lu
|
common/tracer/limtrace,lu
|
||||||
common/patience/npatience,nthreads
|
common/patience/npatience,nthreads
|
||||||
@ -219,7 +220,8 @@ program jt9
|
|||||||
! Compute rough symbol spectra for the JT9 decoder
|
! Compute rough symbol spectra for the JT9 decoder
|
||||||
ingain=0
|
ingain=0
|
||||||
call timer('symspec ',0)
|
call timer('symspec ',0)
|
||||||
call symspec(k,ntrperiod,nsps,ingain,pxdb,s,df3, &
|
nminw=1
|
||||||
|
call symspec(k,ntrperiod,nsps,ingain,nminw,pxdb,s,df3, &
|
||||||
ihsym,npts8)
|
ihsym,npts8)
|
||||||
call timer('symspec ',1)
|
call timer('symspec ',1)
|
||||||
endif
|
endif
|
||||||
@ -227,8 +229,7 @@ program jt9
|
|||||||
if(nhsym.ge.181) exit
|
if(nhsym.ge.181) exit
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
|
close(10)
|
||||||
10 close(10)
|
|
||||||
call fillcom(nutc0,ndepth,nrxfreq,mode,tx9,flow,fsplit,fhigh)
|
call fillcom(nutc0,ndepth,nrxfreq,mode,tx9,flow,fsplit,fhigh)
|
||||||
call decoder(ss,id2,nfsample)
|
call decoder(ss,id2,nfsample)
|
||||||
enddo
|
enddo
|
||||||
|
@ -4,11 +4,12 @@ subroutine jt9c(ss,savg,id2,nparams0)
|
|||||||
real*4 ss(184*NSMAX),savg(NSMAX)
|
real*4 ss(184*NSMAX),savg(NSMAX)
|
||||||
integer*2 id2(NTMAX*12000)
|
integer*2 id2(NTMAX*12000)
|
||||||
|
|
||||||
integer nparams0(46),nparams(46)
|
integer nparams0(47),nparams(47)
|
||||||
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
||||||
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfsplit,nfb, &
|
common/npar/nutc,ndiskdat,ntrperiod,nfqso,newdat,npts8,nfa,nfsplit,nfb, &
|
||||||
ntol,kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,minw,nclearave, &
|
ntol,kin,nzhsym,nsave,nagain,ndepth,ntxmode,nmode,minw,nclearave, &
|
||||||
emedelay,dttol,nlist,listutc(10),datetime,mycall,mygrid,hiscall,hisgrid
|
minsync,emedelay,dttol,nlist,listutc(10),datetime,mycall,mygrid, &
|
||||||
|
hiscall,hisgrid
|
||||||
|
|
||||||
common/patience/npatience,nthreads
|
common/patience/npatience,nthreads
|
||||||
equivalence (nparams,nutc)
|
equivalence (nparams,nutc)
|
||||||
|
25
lib/mixlpf.f90
Normal file
25
lib/mixlpf.f90
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
subroutine mixlpf(x1,nbfo,c0)
|
||||||
|
|
||||||
|
real*4 x1(512)
|
||||||
|
real*8 twopi,phi,dphi
|
||||||
|
complex c1(512),c2(105+512)
|
||||||
|
complex c0(64)
|
||||||
|
data phi/0.d0/
|
||||||
|
save phi,c2
|
||||||
|
|
||||||
|
twopi=8.d0*atan(1.d0)
|
||||||
|
dphi=twopi*nbfo/12000.d0
|
||||||
|
|
||||||
|
do i=1,512
|
||||||
|
phi=phi+dphi
|
||||||
|
if(phi.gt.twopi) phi=phi-twopi
|
||||||
|
xphi=phi
|
||||||
|
c1(i)=x1(i)*cmplx(cos(xphi),sin(xphi))
|
||||||
|
enddo
|
||||||
|
c2(106:105+512)=c1
|
||||||
|
|
||||||
|
call fil3c(c2,105+512,c0,n2)
|
||||||
|
c2(1:105)=c1(512-104:512) !Save 105 trailing samples
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine mixlpf
|
1826
lib/packjt.f90
1826
lib/packjt.f90
File diff suppressed because it is too large
Load Diff
54
lib/savec2.f90
Normal file
54
lib/savec2.f90
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
subroutine savec2(c2name,ntrseconds,f0m1500)
|
||||||
|
|
||||||
|
! Array c0() has complex samples at 1500 Hz sample rate.
|
||||||
|
! WSPR-2: downsample by 1/4 to produce c2, centered at 1500 Hz
|
||||||
|
! WSPR-15: downsample by 1/32 to produce c2, centered at 1612.5 Hz
|
||||||
|
|
||||||
|
parameter (NDMAX=120*1500) !Sample intervals at 1500 Hz rate
|
||||||
|
parameter (MAXFFT=256*1024)
|
||||||
|
|
||||||
|
character*(*) c2name
|
||||||
|
character*14 outfile
|
||||||
|
real*8 f0m1500
|
||||||
|
complex c0
|
||||||
|
complex c1(0:MAXFFT-1)
|
||||||
|
complex c2(0:65535)
|
||||||
|
common/c0com/c0(0:NDMAX-1)
|
||||||
|
|
||||||
|
ntrminutes=ntrseconds/60
|
||||||
|
npts=114*1500
|
||||||
|
nfft1=262144
|
||||||
|
if(ntrminutes.eq.15) then
|
||||||
|
npts=890*1500
|
||||||
|
nfft1=MAXFFT
|
||||||
|
endif
|
||||||
|
df1=1500.0/nfft1
|
||||||
|
fac=1.0/nfft1
|
||||||
|
c1(0:npts-1)=fac*c0(0:npts-1)
|
||||||
|
c1(npts:nfft1-1)=0.
|
||||||
|
|
||||||
|
call four2a(c1,nfft1,1,1,1) !Complex FFT to frequency domain
|
||||||
|
|
||||||
|
! Select the desired frequency range
|
||||||
|
nfft2=65536
|
||||||
|
nh2=nfft2/2
|
||||||
|
if(ntrminutes.eq.2) then
|
||||||
|
c2(0:nh2)=c1(0:nh2)
|
||||||
|
c2(nh2+1:nfft2-1)=c1(nfft1-nh2+1:nfft1-1)
|
||||||
|
else
|
||||||
|
i0=nint(112.5/df1)
|
||||||
|
c2(0:nh2)=c1(i0:i0+nh2)
|
||||||
|
c2(nh2+1:nfft2-1)=c1(i0-nh2+1:i0-1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call four2a(c2,nfft2,1,-1,1) !Shorter complex FFT, back to time domain
|
||||||
|
|
||||||
|
! Write complex time-domain data to disk.
|
||||||
|
i1=index(c2name,'.c2')
|
||||||
|
outfile=c2name(i1-11:i1+2)
|
||||||
|
open(18,file=c2name,status='unknown',access='stream')
|
||||||
|
write(18) outfile,ntrminutes,f0m1500,c2(0:45000-1)
|
||||||
|
close(18)
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine savec2
|
10
lib/smo.f90
10
lib/smo.f90
@ -11,13 +11,9 @@ subroutine smo(x,npts,y,nadd)
|
|||||||
enddo
|
enddo
|
||||||
y(i)=sum
|
y(i)=sum
|
||||||
enddo
|
enddo
|
||||||
y(:nh)=0.
|
x=y
|
||||||
y(npts-nh+1:)=0.
|
x(:nh)=0.
|
||||||
|
x(npts-nh+1:)=0.
|
||||||
fac=1.0/nadd
|
|
||||||
do i=1,npts
|
|
||||||
x(i)=fac*y(i)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
return
|
return
|
||||||
end subroutine smo
|
end subroutine smo
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
subroutine symspec(k,ntrperiod,nsps,ingain,pxdb,s,df3,ihsym,npts8)
|
subroutine symspec(k,ntrperiod,nsps,ingain,nminw,pxdb,s,df3,ihsym,npts8)
|
||||||
|
|
||||||
! Input:
|
! Input:
|
||||||
! k pointer to the most recent new data
|
! k pointer to the most recent new data
|
||||||
@ -11,7 +11,7 @@ subroutine symspec(k,ntrperiod,nsps,ingain,pxdb,s,df3,ihsym,npts8)
|
|||||||
! Output:
|
! Output:
|
||||||
! pxdb power (0-60 dB)
|
! pxdb power (0-60 dB)
|
||||||
! s() current spectrum for waterfall display
|
! s() current spectrum for waterfall display
|
||||||
! ihsym index number of this half-symbol (1-184)
|
! ihsym index number of this half-symbol (1-184) for 60 s modes
|
||||||
|
|
||||||
! jt9com
|
! jt9com
|
||||||
! ss() JT9 symbol spectra at half-symbol steps
|
! ss() JT9 symbol spectra at half-symbol steps
|
||||||
@ -25,15 +25,18 @@ subroutine symspec(k,ntrperiod,nsps,ingain,pxdb,s,df3,ihsym,npts8)
|
|||||||
real*4 tmp(NSMAX)
|
real*4 tmp(NSMAX)
|
||||||
complex cx(0:MAXFFT3/2)
|
complex cx(0:MAXFFT3/2)
|
||||||
integer*2 id2
|
integer*2 id2
|
||||||
|
integer nch(7)
|
||||||
|
|
||||||
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
character datetime*20,mycall*12,mygrid*6,hiscall*12,hisgrid*6
|
||||||
common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
|
common/jt9com/ss(184,NSMAX),savg(NSMAX),id2(NMAX),nutc,ndiskdat, &
|
||||||
ntr,mousefqso,newdat,npts8a,nfa,nfsplit,nfb,ntol,kin,nzhsym, &
|
ntr,mousefqso,newdat,npts8a,nfa,nfsplit,nfb,ntol,kin,nzhsym, &
|
||||||
nsubmode,nagain,ndepth,ntxmode,nmode,minw,nclearave,emedelay, &
|
nsubmode,nagain,ndepth,ntxmode,nmode,minw,nclearave,minsync, &
|
||||||
dttol,nlist,listutc(10),datetime,mycall,mygrid,hiscall,hisgrid
|
emedelay,dttol,nlist,listutc(10),datetime,mycall,mygrid, &
|
||||||
|
hiscall,hisgrid
|
||||||
|
|
||||||
common/jt9w/syellow(NSMAX)
|
common/jt9w/syellow(NSMAX)
|
||||||
data rms/999.0/,k0/99999999/,nfft3z/0/
|
data rms/999.0/,k0/99999999/,nfft3z/0/
|
||||||
|
data nch/1,2,4,9,18,36,72/
|
||||||
equivalence (xc,cx)
|
equivalence (xc,cx)
|
||||||
save
|
save
|
||||||
|
|
||||||
@ -84,34 +87,33 @@ subroutine symspec(k,ntrperiod,nsps,ingain,pxdb,s,df3,ihsym,npts8)
|
|||||||
xc(i)=0.
|
xc(i)=0.
|
||||||
if(j.ge.1 .and.j.le.NMAX) xc(i)=fac0*id2(j)
|
if(j.ge.1 .and.j.le.NMAX) xc(i)=fac0*id2(j)
|
||||||
enddo
|
enddo
|
||||||
if(ihsym.lt.184) ihsym=ihsym+1
|
ihsym=ihsym+1
|
||||||
|
|
||||||
xc(0:nfft3-1)=w3(1:nfft3)*xc(0:nfft3-1) !Apply window w3
|
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
|
call four2a(xc,nfft3,1,-1,0) !Real-to-complex FFT
|
||||||
|
|
||||||
n=min(184,ihsym)
|
|
||||||
df3=12000.0/nfft3 !JT9-1: 0.732 Hz = 0.42 * tone spacing
|
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))
|
iz=min(NSMAX,nint(5000.0/df3))
|
||||||
fac=(1.0/nfft3)**2
|
fac=(1.0/nfft3)**2
|
||||||
do i=1,iz
|
do i=1,iz
|
||||||
j=i0+i-1
|
j=i-1
|
||||||
if(j.lt.0) j=j+nfft3
|
if(j.lt.0) j=j+nfft3
|
||||||
sx=fac*(real(cx(j))**2 + aimag(cx(j))**2)
|
sx=fac*(real(cx(j))**2 + aimag(cx(j))**2)
|
||||||
ss(n,i)=sx
|
if(ihsym.le.184) ss(ihsym,i)=sx
|
||||||
ssum(i)=ssum(i) + sx
|
ssum(i)=ssum(i) + sx
|
||||||
s(i)=1000.0*gain*sx
|
s(i)=1000.0*gain*sx
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
savg=ssum/ihsym
|
savg=ssum/ihsym
|
||||||
|
|
||||||
if(mod(n,10).eq.0) then
|
if(mod(ihsym,10).eq.0) then
|
||||||
mode4=36
|
mode4=nch(nminw+1)
|
||||||
nsmo=min(10*mode4,150)
|
nsmo=min(10*mode4,150)
|
||||||
nsmo=4*nsmo
|
nsmo=4*nsmo
|
||||||
call flat1(savg,iz,nsmo,syellow)
|
call flat1(savg,iz,nsmo,syellow)
|
||||||
if(mode4.ge.9) call smo(syellow,iz,tmp,mode4)
|
if(mode4.ge.2) call smo(syellow,iz,tmp,mode4)
|
||||||
|
if(mode4.ge.2) call smo(syellow,iz,tmp,mode4)
|
||||||
|
syellow(1:250)=0.
|
||||||
ia=500./df3
|
ia=500./df3
|
||||||
ib=2700.0/df3
|
ib=2700.0/df3
|
||||||
smin=minval(syellow(ia:ib))
|
smin=minval(syellow(ia:ib))
|
||||||
|
@ -9,7 +9,6 @@ subroutine sync4(dat,jz,mode4,minw)
|
|||||||
real dat(jz)
|
real dat(jz)
|
||||||
real psavg(NHMAX) !Average spectrum of whole record
|
real psavg(NHMAX) !Average spectrum of whole record
|
||||||
real s2(NHMAX,NSMAX) !2d spectrum, stepped by half-symbols
|
real s2(NHMAX,NSMAX) !2d spectrum, stepped by half-symbols
|
||||||
real ccfblue(65) !CCF with pseudorandom sequence
|
|
||||||
real tmp(1260)
|
real tmp(1260)
|
||||||
save
|
save
|
||||||
|
|
||||||
|
142
lib/timf2.f90
Normal file
142
lib/timf2.f90
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
subroutine timf2(x0,k,nfft,nwindow,nb,peaklimit,x1, &
|
||||||
|
slimit,lstrong,px,nzap)
|
||||||
|
|
||||||
|
! Sequential processing of time-domain I/Q data, using Linrad-like
|
||||||
|
! "first FFT" and "first backward FFT", treating frequencies with
|
||||||
|
! strong signals differently. Noise blanking is applied to weak
|
||||||
|
! signals only.
|
||||||
|
|
||||||
|
! x0 - real input data
|
||||||
|
! nfft - length of FFTs
|
||||||
|
! nwindow - 0 for no window, 2 for sin^2 window
|
||||||
|
! x1 - real output data
|
||||||
|
|
||||||
|
! Non-windowed processing means no overlap, so kstep=nfft.
|
||||||
|
! Sin^2 window has 50% overlap, kstep=nfft/2.
|
||||||
|
|
||||||
|
! Frequencies with strong signals are identified and separated. Back
|
||||||
|
! transforms are done separately for weak and strong signals, so that
|
||||||
|
! noise blanking can be applied to the weak-signal portion. Strong and
|
||||||
|
! weak are finally re-combined, in the time domain.
|
||||||
|
|
||||||
|
parameter (MAXFFT=1024,MAXNH=MAXFFT/2)
|
||||||
|
parameter (MAXSIGS=100)
|
||||||
|
real x0(0:nfft-1),x1(0:nfft-1)
|
||||||
|
real x(0:MAXFFT-1),xw(0:MAXFFT-1),xs(0:MAXFFT-1)
|
||||||
|
real xwov(0:MAXNH-1),xsov(0:MAXNH-1)
|
||||||
|
complex cx(0:MAXFFT-1),cxt(0:MAXFFT-1)
|
||||||
|
complex cxs(0:MAXFFT-1) !Strong signals
|
||||||
|
complex cxw(0:MAXFFT-1) !Weak signals
|
||||||
|
real*4 w(0:MAXFFT-1)
|
||||||
|
real*4 s(0:MAXNH)
|
||||||
|
logical*1 lstrong(0:MAXNH),lprev
|
||||||
|
integer ia(MAXSIGS),ib(MAXSIGS)
|
||||||
|
logical first
|
||||||
|
equivalence (x,cx),(xw,cxw),(xs,cxs)
|
||||||
|
data first/.true./
|
||||||
|
data k0/99999999/
|
||||||
|
save
|
||||||
|
|
||||||
|
if(first) then
|
||||||
|
pi=4.0*atan(1.0)
|
||||||
|
do i=0,nfft-1
|
||||||
|
w(i)=(sin(i*pi/nfft))**2
|
||||||
|
enddo
|
||||||
|
s=0.
|
||||||
|
nh=nfft/2
|
||||||
|
kstep=nfft
|
||||||
|
if(nwindow.eq.2) kstep=nh
|
||||||
|
fac=1.0/nfft
|
||||||
|
slimit=1.e30
|
||||||
|
first=.false.
|
||||||
|
endif
|
||||||
|
|
||||||
|
if(k.lt.k0) then
|
||||||
|
xsov=0.
|
||||||
|
xwov=0.
|
||||||
|
endif
|
||||||
|
k0=k
|
||||||
|
|
||||||
|
x(0:nfft-1)=x0
|
||||||
|
if(nwindow.eq.2) x(0:nfft-1)=w(0:nfft-1)*x(0:nfft-1)
|
||||||
|
call four2a(x,nfft,1,-1,0) !First forward FFT, r2c
|
||||||
|
cxt(0:nh)=cx(0:nh)
|
||||||
|
|
||||||
|
! Identify frequencies with strong signals.
|
||||||
|
do i=0,nh
|
||||||
|
p=real(cxt(i))**2 + aimag(cxt(i))**2
|
||||||
|
s(i)=p
|
||||||
|
enddo
|
||||||
|
ave=sum(s(0:nh))/nh
|
||||||
|
lstrong(0:nh)=s(0:nh).gt.10.0*ave
|
||||||
|
|
||||||
|
nsigs=0
|
||||||
|
lprev=.false.
|
||||||
|
iwid=1
|
||||||
|
ib=-99
|
||||||
|
do i=0,nh
|
||||||
|
if(lstrong(i) .and. (.not.lprev)) then
|
||||||
|
if(nsigs.lt.MAXSIGS) nsigs=nsigs+1
|
||||||
|
ia(nsigs)=i-iwid
|
||||||
|
if(ia(nsigs).lt.0) ia(nsigs)=0
|
||||||
|
endif
|
||||||
|
if(.not.lstrong(i) .and. lprev) then
|
||||||
|
ib(nsigs)=i-1+iwid
|
||||||
|
if(ib(nsigs).gt.nh) ib(nsigs)=nh
|
||||||
|
endif
|
||||||
|
lprev=lstrong(i)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
if(nsigs.gt.0) then
|
||||||
|
do i=1,nsigs
|
||||||
|
ja=ia(i)
|
||||||
|
jb=ib(i)
|
||||||
|
if(ja.lt.0 .or. ja.gt.nh .or. jb.lt.0 .or. jb.gt.nh) then
|
||||||
|
cycle
|
||||||
|
endif
|
||||||
|
if(jb.eq.-99) jb=ja + min(2*iwid,nh)
|
||||||
|
lstrong(ja:jb)=.true.
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
|
||||||
|
! Copy frequency-domain data into array cs (strong) or cw (weak).
|
||||||
|
do i=0,nh
|
||||||
|
if(lstrong(i)) then
|
||||||
|
cxs(i)=fac*cxt(i)
|
||||||
|
cxw(i)=0.
|
||||||
|
else
|
||||||
|
cxw(i)=fac*cxt(i)
|
||||||
|
cxs(i)=0.
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
call four2a(cxw,nfft,1,1,-1) !Transform weak and strong back
|
||||||
|
call four2a(cxs,nfft,1,1,-1) !to time domain, separately (c2r)
|
||||||
|
|
||||||
|
if(nwindow.eq.2) then
|
||||||
|
xw(0:nh-1)=xw(0:nh-1)+xwov(0:nh-1) !Add previous segment's 2nd half
|
||||||
|
xwov(0:nh-1)=xw(nh:nfft-1) !Save 2nd half
|
||||||
|
xs(0:nh-1)=xs(0:nh-1)+xsov(0:nh-1) !Ditto for strong signals
|
||||||
|
xsov(0:nh-1)=xs(nh:nfft-1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
! Apply noise blanking to weak data
|
||||||
|
if(nb.ne.0) then
|
||||||
|
do i=0,kstep-1
|
||||||
|
peak=abs(xw(i))
|
||||||
|
if(peak.gt.peaklimit) then
|
||||||
|
xw(i)=0.
|
||||||
|
nzap=nzap+1
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
|
||||||
|
! Compute power levels from weak data only
|
||||||
|
do i=0,kstep-1
|
||||||
|
px=px + xw(i)**2
|
||||||
|
enddo
|
||||||
|
|
||||||
|
x1(0:kstep-1)=xw(0:kstep-1) + xs(0:kstep-1) !Recombine weak + strong
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine timf2
|
65
lib/wqencode.f90
Normal file
65
lib/wqencode.f90
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
subroutine wqencode(msg,ntype,data0)
|
||||||
|
|
||||||
|
! Parse and encode a WSPR message.
|
||||||
|
|
||||||
|
use packjt
|
||||||
|
parameter (MASK15=32767)
|
||||||
|
character*22 msg
|
||||||
|
character*12 call1,call2
|
||||||
|
character grid4*4,grid6*6
|
||||||
|
logical lbad1,lbad2
|
||||||
|
integer*1 data0(11)
|
||||||
|
integer nu(0:9)
|
||||||
|
data nu/0,-1,1,0,-1,2,1,0,-1,1/
|
||||||
|
|
||||||
|
! Standard WSPR message (types 0 3 7 10 13 17 ... 60)
|
||||||
|
i1=index(msg,' ')
|
||||||
|
i2=index(msg,'/')
|
||||||
|
i3=index(msg,'<')
|
||||||
|
call1=msg(:i1-1)
|
||||||
|
if(i1.lt.3 .or. i1.gt.7 .or. i2.gt.0 .or. i3.gt.0) go to 10
|
||||||
|
grid4=msg(i1+1:i1+4)
|
||||||
|
call packcall(call1,n1,lbad1)
|
||||||
|
call packgrid(grid4,ng,lbad2)
|
||||||
|
if(lbad1 .or. lbad2) go to 10
|
||||||
|
ndbm=0
|
||||||
|
read(msg(i1+5:),*) ndbm
|
||||||
|
if(ndbm.lt.0) ndbm=0
|
||||||
|
if(ndbm.gt.60) ndbm=60
|
||||||
|
ndbm=ndbm+nu(mod(ndbm,10))
|
||||||
|
n2=128*ng + (ndbm+64)
|
||||||
|
call pack50(n1,n2,data0)
|
||||||
|
ntype=ndbm
|
||||||
|
go to 900
|
||||||
|
|
||||||
|
10 if(i2.ge.2 .and. i3.lt.1) then
|
||||||
|
call packpfx(call1,n1,ng,nadd)
|
||||||
|
ndbm=0
|
||||||
|
read(msg(i1+1:),*) ndbm
|
||||||
|
if(ndbm.lt.0) ndbm=0
|
||||||
|
if(ndbm.gt.60) ndbm=60
|
||||||
|
ndbm=ndbm+nu(mod(ndbm,10))
|
||||||
|
ntype=ndbm + 1 + nadd
|
||||||
|
n2=128*ng + ntype + 64
|
||||||
|
call pack50(n1,n2,data0)
|
||||||
|
else if(i3.eq.1) then
|
||||||
|
i4=index(msg,'>')
|
||||||
|
call1=msg(2:i4-1)
|
||||||
|
call hash(call1,i4-2,ih)
|
||||||
|
grid6=msg(i1+1:i1+6)
|
||||||
|
call2=grid6(2:6)//grid6(1:1)//' '
|
||||||
|
call packcall(call2,n1,lbad1)
|
||||||
|
ndbm=0
|
||||||
|
read(msg(i1+8:),*) ndbm
|
||||||
|
if(ndbm.lt.0) ndbm=0
|
||||||
|
if(ndbm.gt.60) ndbm=60
|
||||||
|
ndbm=ndbm+nu(mod(ndbm,10))
|
||||||
|
ntype=-(ndbm+1)
|
||||||
|
n2=128*ih + ntype + 64
|
||||||
|
call pack50(n1,n2,data0)
|
||||||
|
endif
|
||||||
|
go to 900
|
||||||
|
|
||||||
|
900 continue
|
||||||
|
return
|
||||||
|
end subroutine wqencode
|
@ -1,4 +1,4 @@
|
|||||||
subroutine wsjt4(dat,npts,nutc,NClearAve,ntol,emedelay,dttol, &
|
subroutine wsjt4(dat,npts,nutc,NClearAve,minsync,ntol,emedelay,dttol, &
|
||||||
mode4,minw,mycall,hiscall,hisgrid,nfqso,NAgain,ndepth,neme)
|
mode4,minw,mycall,hiscall,hisgrid,nfqso,NAgain,ndepth,neme)
|
||||||
|
|
||||||
! Orchestrates the process of decoding JT4 messages, using data that
|
! Orchestrates the process of decoding JT4 messages, using data that
|
||||||
@ -30,8 +30,7 @@ subroutine wsjt4(dat,npts,nutc,NClearAve,ntol,emedelay,dttol, &
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
zz=0.
|
zz=0.
|
||||||
! syncmin=1.0
|
syncmin=5.0 + minsync
|
||||||
syncmin=7.0
|
|
||||||
naggressive=0
|
naggressive=0
|
||||||
if(ndepth.ge.2) naggressive=1
|
if(ndepth.ge.2) naggressive=1
|
||||||
nq1=3
|
nq1=3
|
||||||
@ -102,7 +101,7 @@ subroutine wsjt4(dat,npts,nutc,NClearAve,ntol,emedelay,dttol, &
|
|||||||
! Fano succeeded: display the message and return FANO OK
|
! Fano succeeded: display the message and return FANO OK
|
||||||
write(*,1010) nutc,nsnr,dtx,nfreq,csync,decoded,' *', &
|
write(*,1010) nutc,nsnr,dtx,nfreq,csync,decoded,' *', &
|
||||||
char(ichar('A')+ich-1)
|
char(ichar('A')+ich-1)
|
||||||
1010 format(i4.4,i4,f5.2,i5,a1,1x,a22,a2,1x,a1,i3)
|
1010 format(i4.4,i4,f5.2,i5,1x,a1,1x,a22,a2,1x,a1,i3)
|
||||||
nsave=0
|
nsave=0
|
||||||
go to 990
|
go to 990
|
||||||
|
|
||||||
@ -174,6 +173,5 @@ subroutine wsjt4(dat,npts,nutc,NClearAve,ntol,emedelay,dttol, &
|
|||||||
deepave,cqual,char(ichar('A')+ich-1),ndeepave
|
deepave,cqual,char(ichar('A')+ich-1),ndeepave
|
||||||
endif
|
endif
|
||||||
|
|
||||||
990 return
|
990 return
|
||||||
end subroutine wsjt4
|
end subroutine wsjt4
|
||||||
|
|
||||||
|
76
lib/wspr_downsample.f90
Normal file
76
lib/wspr_downsample.f90
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
subroutine wspr_downsample(id2,k)
|
||||||
|
|
||||||
|
! Input:
|
||||||
|
! id2 raw 16-bit integer data, 12000 Hz sample rate
|
||||||
|
! k pointer to the most recent new data
|
||||||
|
|
||||||
|
! Output (in common/c0com)
|
||||||
|
! c0 complex data downsampled to 1500 Hz
|
||||||
|
|
||||||
|
parameter (NMAX=120*12000) !Total sample intervals per 30 minutes
|
||||||
|
parameter (NDMAX=120*1500) !Sample intervals at 1500 Hz rate
|
||||||
|
parameter (NSMAX=1366) !Max length of saved spectra
|
||||||
|
parameter (NFFT1=1024)
|
||||||
|
parameter (MAXFFT3=32768)
|
||||||
|
real*4 w3(MAXFFT3)
|
||||||
|
real*4 x0(NFFT1),x1(NFFT1)
|
||||||
|
real*4 x2(NFFT1+105)
|
||||||
|
real*4 ssum(NSMAX)
|
||||||
|
logical*1 lstrong(0:1023) !Should be (0:512)
|
||||||
|
integer*2 id2(NMAX)
|
||||||
|
complex c0
|
||||||
|
common/c0com/c0(NDMAX)
|
||||||
|
data rms/999.0/,k0/99999999/,nfft3z/0/,nsps/8192/,nbfo/1500/
|
||||||
|
save
|
||||||
|
|
||||||
|
nfft3=nsps/4
|
||||||
|
jstep=nsps/16
|
||||||
|
if(k.gt.NMAX) go to 999
|
||||||
|
if(k.lt.nfft3) go to 999 !Wait for enough samples to start
|
||||||
|
if(nfft3.ne.nfft3z) then
|
||||||
|
pi=4.0*atan(1.0)
|
||||||
|
do i=1,nfft3
|
||||||
|
w3(i)=2.0*(sin(i*pi/nfft3))**2 !Window for nfft3
|
||||||
|
enddo
|
||||||
|
nfft3z=nfft3
|
||||||
|
endif
|
||||||
|
|
||||||
|
if(k.lt.k0) then
|
||||||
|
ja=0
|
||||||
|
ssum=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
|
||||||
|
endif
|
||||||
|
k0=k
|
||||||
|
|
||||||
|
nzap=0
|
||||||
|
nbslider=0
|
||||||
|
sigmas=1.0*(10.0**(0.01*nbslider)) + 0.7
|
||||||
|
peaklimit=sigmas*max(10.0,rms)
|
||||||
|
px=0.
|
||||||
|
|
||||||
|
nwindow=2
|
||||||
|
kstep1=NFFT1
|
||||||
|
if(nwindow.ne.0) kstep1=NFFT1/2
|
||||||
|
fac=2.0/NFFT1
|
||||||
|
nblks=(k-k1)/kstep1
|
||||||
|
gain=1.0
|
||||||
|
do nblk=1,nblks
|
||||||
|
do i=1,NFFT1
|
||||||
|
x0(i)=gain*id2(k1+i)
|
||||||
|
enddo
|
||||||
|
call timf2(x0,k,NFFT1,nwindow,nb,peaklimit,x1, &
|
||||||
|
slimit,lstrong,px,nzap)
|
||||||
|
! Mix at nbfo Hz, lowpass at +/-750 Hz, and downsample to 1500 Hz complex.
|
||||||
|
call mixlpf(x1,nbfo,c0(k8+1))
|
||||||
|
k1=k1+kstep1
|
||||||
|
k8=k8+kstep1/8
|
||||||
|
enddo
|
||||||
|
|
||||||
|
999 return
|
||||||
|
end subroutine wspr_downsample
|
39
lib/wsprd/Makefile
Normal file
39
lib/wsprd/Makefile
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#CC = gcc
|
||||||
|
CC = clang
|
||||||
|
FC = gfortran
|
||||||
|
|
||||||
|
FFLAGS = -O2 -Wall -Wno-conversion
|
||||||
|
CFLAGS= -I/usr/include -Wall -Wno-missing-braces -O2
|
||||||
|
LDFLAGS = -L/usr/lib
|
||||||
|
LIBS = -lfftw3 -lm
|
||||||
|
|
||||||
|
# Default rules
|
||||||
|
%.o: %.c $(DEPS)
|
||||||
|
${CC} ${CFLAGS} -c $<
|
||||||
|
%.o: %.f
|
||||||
|
${FC} ${FFLAGS} -c $<
|
||||||
|
%.o: %.F
|
||||||
|
${FC} ${FFLAGS} -c $<
|
||||||
|
%.o: %.f90
|
||||||
|
${FC} ${FFLAGS} -c $<
|
||||||
|
%.o: %.F90
|
||||||
|
${FC} ${FFLAGS} -c $<
|
||||||
|
|
||||||
|
all: wsprd WSPRcode test_wspr
|
||||||
|
|
||||||
|
DEPS = fano.h
|
||||||
|
OBJS1 = wsprd.o wsprd_utils.o fano.o tab.o nhash.o
|
||||||
|
wsprd: $(OBJS1)
|
||||||
|
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
OBJS2 = test_wspr.o unpk.o wsprd_utils.o nhash.o
|
||||||
|
test_wspr: $(OBJS2) libwspr.a
|
||||||
|
$(FC) -o test_wspr $(FFLAGS) $(OBJS2) libwspr.a
|
||||||
|
|
||||||
|
|
||||||
|
OBJS3 = WSPRcode.o
|
||||||
|
WSPRcode: $(OBJS3) libwspr.a
|
||||||
|
$(FC) -o WSPRcode $(FFLAGS) $(OBJS3) libwspr.a
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.o wsprd
|
30
lib/wsprd/Makefile.MinGW
Normal file
30
lib/wsprd/Makefile.MinGW
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
CC = gcc
|
||||||
|
#CC = clang
|
||||||
|
FC = gfortran
|
||||||
|
|
||||||
|
FFLAGS = -O2 -Wall -Wno-conversion
|
||||||
|
CFLAGS= -Wall -Wno-missing-braces -O2
|
||||||
|
#LDFLAGS = -L/JTSDK/fftw3f
|
||||||
|
LIBS = c:/JTSDK/fftw3f/libfftw3-3.dll -lm
|
||||||
|
|
||||||
|
# Default rules
|
||||||
|
%.o: %.c $(DEPS)
|
||||||
|
${CC} ${CFLAGS} -c $<
|
||||||
|
%.o: %.f
|
||||||
|
${FC} ${FFLAGS} -c $<
|
||||||
|
%.o: %.F
|
||||||
|
${FC} ${FFLAGS} -c $<
|
||||||
|
%.o: %.f90
|
||||||
|
${FC} ${FFLAGS} -c $<
|
||||||
|
%.o: %.F90
|
||||||
|
${FC} ${FFLAGS} -c $<
|
||||||
|
|
||||||
|
all: wsprd
|
||||||
|
|
||||||
|
DEPS = fano.h
|
||||||
|
OBJS1 = wsprd.o wsprd_utils.o fano.o tab.o nhash.o
|
||||||
|
wsprd: $(OBJS1)
|
||||||
|
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.o wsprd
|
132
lib/wsprd/WSPRcode.f90
Normal file
132
lib/wsprd/WSPRcode.f90
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
program wsprcode
|
||||||
|
|
||||||
|
! This program provides examples of the source encoding, convolutional
|
||||||
|
! error-control coding, bit and symbol ordering, and synchronizing
|
||||||
|
! information contained in WSPR messages.
|
||||||
|
|
||||||
|
parameter (NSYM=162)
|
||||||
|
parameter (MAXSYM=176)
|
||||||
|
character*22 msg,msg2
|
||||||
|
integer*1 data0(7)
|
||||||
|
integer*1 data1(7)
|
||||||
|
integer*1 dat(NSYM)
|
||||||
|
integer*1 softsym(NSYM)
|
||||||
|
|
||||||
|
! Define the sync vector:
|
||||||
|
integer*1 sync(NSYM)
|
||||||
|
data sync/ &
|
||||||
|
1,1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0, &
|
||||||
|
0,1,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1, &
|
||||||
|
0,0,0,0,0,0,1,0,1,1,0,0,1,1,0,1,0,0,0,1, &
|
||||||
|
1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1, &
|
||||||
|
0,0,1,0,1,1,0,0,0,1,1,0,1,0,1,0,0,0,1,0, &
|
||||||
|
0,0,0,0,1,0,0,1,0,0,1,1,1,0,1,1,0,0,1,1, &
|
||||||
|
0,1,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,0,1,1, &
|
||||||
|
0,0,0,0,0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,0, &
|
||||||
|
0,0/
|
||||||
|
|
||||||
|
! Metric table for decoding from soft symbols
|
||||||
|
integer mettab(0:255,0:1)
|
||||||
|
data mettab/ &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 4, &
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, &
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, &
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 2, &
|
||||||
|
2, 2, 2, 2, 1, 1, 1, 1, 0, 0, &
|
||||||
|
-1, -1, -1, -2, -2, -3, -4, -4, -5, -6, &
|
||||||
|
-7, -7, -8, -9, -10, -11, -12, -12, -13, -14, &
|
||||||
|
-15, -16, -17, -17, -18, -19, -20, -21, -22, -22, &
|
||||||
|
-23, -24, -25, -26, -26, -27, -28, -29, -30, -30, &
|
||||||
|
-31, -32, -33, -33, -34, -35, -36, -36, -37, -38, &
|
||||||
|
-38, -39, -40, -41, -41, -42, -43, -43, -44, -45, &
|
||||||
|
-45, -46, -47, -47, -48, -49, -49, -50, -51, -51, &
|
||||||
|
-52, -53, -53, -54, -54, -55, -56, -56, -57, -57, &
|
||||||
|
-58, -59, -59, -60, -60, -61, -62, -62, -62, -63, &
|
||||||
|
-64, -64, -65, -65, -66, -67, -67, -67, -68, -69, &
|
||||||
|
-69, -70, -70, -71, -72, -72, -72, -72, -73, -74, &
|
||||||
|
-75, -75, -75, -77, -76, -76, -78, -78, -80, -81, &
|
||||||
|
-80, -79, -83, -82, -81, -82, -82, -83, -84, -84, &
|
||||||
|
-84, -87, -86, -87, -88, -89, -89, -89, -88, -87, &
|
||||||
|
-86, -87, -84, -84, -84, -83, -82, -82, -81, -82, &
|
||||||
|
-83, -79, -80, -81, -80, -78, -78, -76, -76, -77, &
|
||||||
|
-75, -75, -75, -74, -73, -72, -72, -72, -72, -71, &
|
||||||
|
-70, -70, -69, -69, -68, -67, -67, -67, -66, -65, &
|
||||||
|
-65, -64, -64, -63, -62, -62, -62, -61, -60, -60, &
|
||||||
|
-59, -59, -58, -57, -57, -56, -56, -55, -54, -54, &
|
||||||
|
-53, -53, -52, -51, -51, -50, -49, -49, -48, -47, &
|
||||||
|
-47, -46, -45, -45, -44, -43, -43, -42, -41, -41, &
|
||||||
|
-40, -39, -38, -38, -37, -36, -36, -35, -34, -33, &
|
||||||
|
-33, -32, -31, -30, -30, -29, -28, -27, -26, -26, &
|
||||||
|
-25, -24, -23, -22, -22, -21, -20, -19, -18, -17, &
|
||||||
|
-17, -16, -15, -14, -13, -12, -12, -11, -10, -9, &
|
||||||
|
-8, -7, -7, -6, -5, -4, -4, -3, -2, -2, &
|
||||||
|
-1, -1, -1, 0, 0, 1, 1, 1, 1, 2, &
|
||||||
|
2, 2, 2, 2, 3, 3, 3, 3, 3, 3, &
|
||||||
|
3, 3, 3, 4, 4, 4, 4, 4, 4, 4, &
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, &
|
||||||
|
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5/
|
||||||
|
|
||||||
|
! Get command-line argument(s)
|
||||||
|
nargs=iargc()
|
||||||
|
if(nargs.ne.1) then
|
||||||
|
print*,'Usage: WSPRcode "message"'
|
||||||
|
go to 999
|
||||||
|
endif
|
||||||
|
call getarg(1,msg) !Get message from command line
|
||||||
|
write(*,1000) msg
|
||||||
|
1000 format('Message: ',a22)
|
||||||
|
|
||||||
|
nbits=50+31 !User bits=50, constraint length=32
|
||||||
|
nbytes=(nbits+7)/8
|
||||||
|
ndelta=50
|
||||||
|
limit=20000
|
||||||
|
|
||||||
|
data0=0
|
||||||
|
call wqencode(msg,ntype0,data0) !Source encoding
|
||||||
|
write(*,1002) data0
|
||||||
|
1002 format(/'Source-encoded message (50 bits, hex):',7z3.2)
|
||||||
|
|
||||||
|
call encode232(data0,nbytes,dat,MAXSYM) !Convolutional encoding
|
||||||
|
call inter_mept(dat,1) !Interleaving
|
||||||
|
|
||||||
|
write(*,1004)
|
||||||
|
1004 format(/'Data symbols:')
|
||||||
|
write(*,1006) (dat(i),i=1,NSYM)
|
||||||
|
1006 format(5x,30i2)
|
||||||
|
|
||||||
|
write(*,1008)
|
||||||
|
1008 format(/'Sync symbols:')
|
||||||
|
write(*,1006) (sync(i),i=1,NSYM)
|
||||||
|
|
||||||
|
write(*,1010)
|
||||||
|
1010 format(/'Channel symbols:')
|
||||||
|
write(*,1006) (2*dat(i)+sync(i),i=1,NSYM)
|
||||||
|
|
||||||
|
call inter_mept(dat,-1) !Remove interleaving
|
||||||
|
softsym=-dat !Simulate soft symbols
|
||||||
|
|
||||||
|
! Call the sequential (Fano algorithm) decoder
|
||||||
|
call fano232(softsym,nbits,mettab,ndelta,limit,data1,ncycles,metric,nerr)
|
||||||
|
call wqdecode(data1,msg2,ntype1)
|
||||||
|
|
||||||
|
write(*,1020) ntype1
|
||||||
|
1020 format(/'Message type: ',i7)
|
||||||
|
write(*,1030) msg2
|
||||||
|
1030 format('Decoded message: ',a22)
|
||||||
|
|
||||||
|
999 end program wsprcode
|
255
lib/wsprd/fano.c
Normal file
255
lib/wsprd/fano.c
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
This file is part of wsprd.
|
||||||
|
|
||||||
|
File name: fano.c
|
||||||
|
|
||||||
|
Description: Soft decision Fano sequential decoder for K=32 r=1/2
|
||||||
|
convolutional code.
|
||||||
|
|
||||||
|
Copyright 1994, Phil Karn, KA9Q
|
||||||
|
Minor modifications by Joe Taylor, K1JT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LL 1 // Select Layland-Lushbaugh code
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "fano.h"
|
||||||
|
|
||||||
|
struct node {
|
||||||
|
unsigned long encstate; // Encoder state of next node
|
||||||
|
long gamma; // Cumulative metric to this node
|
||||||
|
int metrics[4]; // Metrics indexed by all possible tx syms
|
||||||
|
int tm[2]; // Sorted metrics for current hypotheses
|
||||||
|
int i; // Current branch being tested
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convolutional coding polynomials. All are rate 1/2, K=32
|
||||||
|
#ifdef NASA_STANDARD
|
||||||
|
/* "NASA standard" code by Massey & Costello
|
||||||
|
* Nonsystematic, quick look-in, dmin=11, dfree=23
|
||||||
|
* used on Pioneer 10-12, Helios A,B
|
||||||
|
*/
|
||||||
|
#define POLY1 0xbbef6bb7
|
||||||
|
#define POLY2 0xbbef6bb5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MJ
|
||||||
|
/* Massey-Johannesson code
|
||||||
|
* Nonsystematic, quick look-in, dmin=13, dfree>=23
|
||||||
|
* Purported to be more computationally efficient than Massey-Costello
|
||||||
|
*/
|
||||||
|
#define POLY1 0xb840a20f
|
||||||
|
#define POLY2 0xb840a20d
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LL
|
||||||
|
/* Layland-Lushbaugh code
|
||||||
|
* Nonsystematic, non-quick look-in, dmin=?, dfree=?
|
||||||
|
*/
|
||||||
|
#define POLY1 0xf2d05351
|
||||||
|
#define POLY2 0xe4613c47
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Convolutional encoder macro. Takes the encoder state, generates
|
||||||
|
* a rate 1/2 symbol pair and stores it in 'sym'. The symbol generated from
|
||||||
|
* POLY1 goes into the 2-bit of sym, and the symbol generated from POLY2
|
||||||
|
* goes into the 1-bit.
|
||||||
|
*/
|
||||||
|
#define ENCODE(sym,encstate) {\
|
||||||
|
unsigned long _tmp;\
|
||||||
|
\
|
||||||
|
_tmp = (encstate) & POLY1;\
|
||||||
|
_tmp ^= _tmp >> 16;\
|
||||||
|
(sym) = Partab[(_tmp ^ (_tmp >> 8)) & 0xff] << 1;\
|
||||||
|
_tmp = (encstate) & POLY2;\
|
||||||
|
_tmp ^= _tmp >> 16;\
|
||||||
|
(sym) |= Partab[(_tmp ^ (_tmp >> 8)) & 0xff];\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convolutionally encode a packet. The input data bytes are read
|
||||||
|
* high bit first and the encoded packet is written into 'symbols',
|
||||||
|
* one symbol per byte. The first symbol is generated from POLY1,
|
||||||
|
* the second from POLY2.
|
||||||
|
*
|
||||||
|
* Storing only one symbol per byte uses more space, but it is faster
|
||||||
|
* and easier than trying to pack them more compactly.
|
||||||
|
*/
|
||||||
|
int encode(
|
||||||
|
unsigned char *symbols, // Output buffer, 2*nbytes
|
||||||
|
unsigned char *data, // Input buffer, nbytes
|
||||||
|
unsigned int nbytes) // Number of bytes in data
|
||||||
|
{
|
||||||
|
unsigned long encstate;
|
||||||
|
int sym;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
encstate = 0;
|
||||||
|
while(nbytes-- != 0) {
|
||||||
|
for(i=7;i>=0;i--) {
|
||||||
|
encstate = (encstate << 1) | ((*data >> i) & 1);
|
||||||
|
ENCODE(sym,encstate);
|
||||||
|
*symbols++ = sym >> 1;
|
||||||
|
*symbols++ = sym & 1;
|
||||||
|
}
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode packet with the Fano algorithm.
|
||||||
|
* Return 0 on success, -1 on timeout
|
||||||
|
*/
|
||||||
|
int fano(
|
||||||
|
unsigned int *metric, // Final path metric (returned value)
|
||||||
|
unsigned int *cycles, // Cycle count (returned value)
|
||||||
|
unsigned int *maxnp, // Progress before timeout (returned value)
|
||||||
|
unsigned char *data, // Decoded output data
|
||||||
|
unsigned char *symbols, // Raw deinterleaved input symbols
|
||||||
|
unsigned int nbits, // Number of output bits
|
||||||
|
int mettab[2][256], // Metric table, [sent sym][rx symbol]
|
||||||
|
int delta, // Threshold adjust parameter
|
||||||
|
unsigned int maxcycles) // Decoding timeout in cycles per bit
|
||||||
|
{
|
||||||
|
struct node *nodes; // First node
|
||||||
|
struct node *np; // Current node
|
||||||
|
struct node *lastnode; // Last node
|
||||||
|
struct node *tail; // First node of tail
|
||||||
|
int t; // Threshold
|
||||||
|
int m0,m1;
|
||||||
|
int ngamma;
|
||||||
|
unsigned int lsym;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if((nodes = (struct node *)malloc(nbits*sizeof(struct node))) == NULL) {
|
||||||
|
printf("malloc failed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lastnode = &nodes[nbits-1];
|
||||||
|
tail = &nodes[nbits-31];
|
||||||
|
*maxnp = 0;
|
||||||
|
|
||||||
|
/* Compute all possible branch metrics for each symbol pair
|
||||||
|
* This is the only place we actually look at the raw input symbols
|
||||||
|
*/
|
||||||
|
for(np=nodes;np <= lastnode;np++) {
|
||||||
|
np->metrics[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]];
|
||||||
|
np->metrics[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]];
|
||||||
|
np->metrics[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]];
|
||||||
|
np->metrics[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]];
|
||||||
|
symbols += 2;
|
||||||
|
}
|
||||||
|
np = nodes;
|
||||||
|
np->encstate = 0;
|
||||||
|
|
||||||
|
// Compute and sort branch metrics from root node */
|
||||||
|
ENCODE(lsym,np->encstate); // 0-branch (LSB is 0)
|
||||||
|
m0 = np->metrics[lsym];
|
||||||
|
|
||||||
|
/* Now do the 1-branch. To save another ENCODE call here and
|
||||||
|
* inside the loop, we assume that both polynomials are odd,
|
||||||
|
* providing complementary pairs of branch symbols.
|
||||||
|
|
||||||
|
* This code should be modified if a systematic code were used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
m1 = np->metrics[3^lsym];
|
||||||
|
if(m0 > m1) {
|
||||||
|
np->tm[0] = m0; // 0-branch has better metric
|
||||||
|
np->tm[1] = m1;
|
||||||
|
} else {
|
||||||
|
np->tm[0] = m1; // 1-branch is better
|
||||||
|
np->tm[1] = m0;
|
||||||
|
np->encstate++; // Set low bit
|
||||||
|
}
|
||||||
|
np->i = 0; // Start with best branch
|
||||||
|
maxcycles *= nbits;
|
||||||
|
np->gamma = t = 0;
|
||||||
|
|
||||||
|
// Start the Fano decoder
|
||||||
|
for(i=1;i <= maxcycles;i++) {
|
||||||
|
if((int)(np-nodes) > (int)*maxnp) *maxnp=(int)(np-nodes);
|
||||||
|
#ifdef debug
|
||||||
|
printf("k=%ld, g=%ld, t=%d, m[%d]=%d, maxnp=%d\n",
|
||||||
|
np-nodes,np->gamma,t,np->i,np->tm[np->i],*maxnp);
|
||||||
|
#endif
|
||||||
|
// Look forward */
|
||||||
|
ngamma = np->gamma + np->tm[np->i];
|
||||||
|
if(ngamma >= t) {
|
||||||
|
if(np->gamma < t + delta) { // Node is acceptable
|
||||||
|
/* First time we've visited this node;
|
||||||
|
* Tighten threshold.
|
||||||
|
*
|
||||||
|
* This loop could be replaced with
|
||||||
|
* t += delta * ((ngamma - t)/delta);
|
||||||
|
* but the multiply and divide are slower.
|
||||||
|
*/
|
||||||
|
while(ngamma >= t + delta) t += delta;
|
||||||
|
}
|
||||||
|
np[1].gamma = ngamma; // Move forward
|
||||||
|
np[1].encstate = np->encstate << 1;
|
||||||
|
if(++np == lastnode) {
|
||||||
|
break; // Done!
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute and sort metrics, starting with the
|
||||||
|
* zero branch
|
||||||
|
*/
|
||||||
|
ENCODE(lsym,np->encstate);
|
||||||
|
if(np >= tail) {
|
||||||
|
/* The tail must be all zeroes, so don't
|
||||||
|
* bother computing the 1-branches here.
|
||||||
|
*/
|
||||||
|
np->tm[0] = np->metrics[lsym];
|
||||||
|
} else {
|
||||||
|
m0 = np->metrics[lsym];
|
||||||
|
m1 = np->metrics[3^lsym];
|
||||||
|
if(m0 > m1) {
|
||||||
|
np->tm[0] = m0; // 0-branch is better
|
||||||
|
np->tm[1] = m1;
|
||||||
|
} else {
|
||||||
|
np->tm[0] = m1; // 1-branch is better
|
||||||
|
np->tm[1] = m0;
|
||||||
|
np->encstate++; // Set low bit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
np->i = 0; // Start with best branch
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Threshold violated, can't go forward
|
||||||
|
for(;;) { // Look backward
|
||||||
|
if(np == nodes || np[-1].gamma < t) {
|
||||||
|
/* Can't back up either.
|
||||||
|
* Relax threshold and and look
|
||||||
|
* forward again to better branch.
|
||||||
|
*/
|
||||||
|
t -= delta;
|
||||||
|
if(np->i != 0) {
|
||||||
|
np->i = 0;
|
||||||
|
np->encstate ^= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Back up
|
||||||
|
if(--np < tail && np->i != 1) {
|
||||||
|
np->i++; // Search next best branch
|
||||||
|
np->encstate ^= 1;
|
||||||
|
break;
|
||||||
|
} // else keep looking back
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*metric = np->gamma; // Return the final path metric
|
||||||
|
|
||||||
|
// Copy decoded data to user's buffer
|
||||||
|
nbits >>= 3;
|
||||||
|
np = &nodes[7];
|
||||||
|
while(nbits-- != 0) {
|
||||||
|
*data++ = np->encstate;
|
||||||
|
np += 8;
|
||||||
|
}
|
||||||
|
*cycles = i+1;
|
||||||
|
free(nodes);
|
||||||
|
if(i >= maxcycles) return -1; // Decoder timed out
|
||||||
|
return 0; // Successful completion
|
||||||
|
}
|
21
lib/wsprd/fano.h
Normal file
21
lib/wsprd/fano.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
This file is part of wsprd.
|
||||||
|
|
||||||
|
File name: fano.h
|
||||||
|
|
||||||
|
Description: Header file for sequential Fano decoder.
|
||||||
|
|
||||||
|
Copyright 1994, Phil Karn, KA9Q
|
||||||
|
Minor modifications by Joe Taylor, K1JT
|
||||||
|
*/
|
||||||
|
|
||||||
|
int fano(unsigned int *metric, unsigned int *cycles, unsigned int *maxnp,
|
||||||
|
unsigned char *data,unsigned char *symbols, unsigned int nbits,
|
||||||
|
int mettab[2][256],int delta,unsigned int maxcycles);
|
||||||
|
|
||||||
|
int encode(unsigned char *symbols,unsigned char *data,unsigned int nbytes);
|
||||||
|
|
||||||
|
extern unsigned char Partab[];
|
||||||
|
|
||||||
|
|
||||||
|
|
410
lib/wsprd/fftw3.h
Normal file
410
lib/wsprd/fftw3.h
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, 2007-11 Matteo Frigo
|
||||||
|
* Copyright (c) 2003, 2007-11 Massachusetts Institute of Technology
|
||||||
|
*
|
||||||
|
* The following statement of license applies *only* to this header file,
|
||||||
|
* and *not* to the other files distributed with FFTW or derived therefrom:
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************** NOTE TO USERS *********************************
|
||||||
|
*
|
||||||
|
* THIS IS A HEADER FILE, NOT A MANUAL
|
||||||
|
*
|
||||||
|
* If you want to know how to use FFTW, please read the manual,
|
||||||
|
* online at http://www.fftw.org/doc/ and also included with FFTW.
|
||||||
|
* For a quick start, see the manual's tutorial section.
|
||||||
|
*
|
||||||
|
* (Reading header files to learn how to use a library is a habit
|
||||||
|
* stemming from code lacking a proper manual. Arguably, it's a
|
||||||
|
* *bad* habit in most cases, because header files can contain
|
||||||
|
* interfaces that are not part of the public, stable API.)
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef FFTW3_H
|
||||||
|
#define FFTW3_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/* If <complex.h> is included, use the C99 complex type. Otherwise
|
||||||
|
define a type bit-compatible with C99 complex */
|
||||||
|
#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
|
||||||
|
# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
|
||||||
|
#else
|
||||||
|
# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FFTW_CONCAT(prefix, name) prefix ## name
|
||||||
|
#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
|
||||||
|
#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
|
||||||
|
#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
|
||||||
|
#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name)
|
||||||
|
|
||||||
|
/* IMPORTANT: for Windows compilers, you should add a line
|
||||||
|
#define FFTW_DLL
|
||||||
|
here and in kernel/ifftw.h if you are compiling/using FFTW as a
|
||||||
|
DLL, in order to do the proper importing/exporting, or
|
||||||
|
alternatively compile with -DFFTW_DLL or the equivalent
|
||||||
|
command-line flag. This is not necessary under MinGW/Cygwin, where
|
||||||
|
libtool does the imports/exports automatically. */
|
||||||
|
#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
|
||||||
|
/* annoying Windows syntax for shared-library declarations */
|
||||||
|
# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
|
||||||
|
# define FFTW_EXTERN extern __declspec(dllexport)
|
||||||
|
# else /* user is calling FFTW; import symbol */
|
||||||
|
# define FFTW_EXTERN extern __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define FFTW_EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum fftw_r2r_kind_do_not_use_me {
|
||||||
|
FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
|
||||||
|
FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
|
||||||
|
FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fftw_iodim_do_not_use_me {
|
||||||
|
int n; /* dimension size */
|
||||||
|
int is; /* input stride */
|
||||||
|
int os; /* output stride */
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <stddef.h> /* for ptrdiff_t */
|
||||||
|
struct fftw_iodim64_do_not_use_me {
|
||||||
|
ptrdiff_t n; /* dimension size */
|
||||||
|
ptrdiff_t is; /* input stride */
|
||||||
|
ptrdiff_t os; /* output stride */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *);
|
||||||
|
typedef int (*fftw_read_char_func_do_not_use_me)(void *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
huge second-order macro that defines prototypes for all API
|
||||||
|
functions. We expand this macro for each supported precision
|
||||||
|
|
||||||
|
X: name-mangling macro
|
||||||
|
R: real data type
|
||||||
|
C: complex data type
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FFTW_DEFINE_API(X, R, C) \
|
||||||
|
\
|
||||||
|
FFTW_DEFINE_COMPLEX(R, C); \
|
||||||
|
\
|
||||||
|
typedef struct X(plan_s) *X(plan); \
|
||||||
|
\
|
||||||
|
typedef struct fftw_iodim_do_not_use_me X(iodim); \
|
||||||
|
typedef struct fftw_iodim64_do_not_use_me X(iodim64); \
|
||||||
|
\
|
||||||
|
typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \
|
||||||
|
\
|
||||||
|
typedef fftw_write_char_func_do_not_use_me X(write_char_func); \
|
||||||
|
typedef fftw_read_char_func_do_not_use_me X(read_char_func); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute)(const X(plan) p); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \
|
||||||
|
C *in, C *out, int sign, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \
|
||||||
|
C *in, C *out, int sign, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \
|
||||||
|
C *in, C *out, int sign, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \
|
||||||
|
int howmany, \
|
||||||
|
C *in, const int *inembed, \
|
||||||
|
int istride, int idist, \
|
||||||
|
C *out, const int *onembed, \
|
||||||
|
int ostride, int odist, \
|
||||||
|
int sign, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
C *in, C *out, \
|
||||||
|
int sign, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *ri, R *ii, R *ro, R *io, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \
|
||||||
|
const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
C *in, C *out, \
|
||||||
|
int sign, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \
|
||||||
|
const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *ri, R *ii, R *ro, R *io, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \
|
||||||
|
FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \
|
||||||
|
R *ro, R *io); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \
|
||||||
|
int howmany, \
|
||||||
|
R *in, const int *inembed, \
|
||||||
|
int istride, int idist, \
|
||||||
|
C *out, const int *onembed, \
|
||||||
|
int ostride, int odist, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \
|
||||||
|
R *in, C *out, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \
|
||||||
|
R *in, C *out, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \
|
||||||
|
int n2, \
|
||||||
|
R *in, C *out, unsigned flags); \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \
|
||||||
|
int howmany, \
|
||||||
|
C *in, const int *inembed, \
|
||||||
|
int istride, int idist, \
|
||||||
|
R *out, const int *onembed, \
|
||||||
|
int ostride, int odist, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \
|
||||||
|
C *in, R *out, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \
|
||||||
|
C *in, R *out, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \
|
||||||
|
int n2, \
|
||||||
|
C *in, R *out, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *in, C *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
C *in, R *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \
|
||||||
|
int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *in, R *ro, R *io, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \
|
||||||
|
int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *ri, R *ii, R *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \
|
||||||
|
const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *in, C *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \
|
||||||
|
const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
C *in, R *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \
|
||||||
|
int rank, const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *in, R *ro, R *io, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \
|
||||||
|
int rank, const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *ri, R *ii, R *out, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \
|
||||||
|
FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \
|
||||||
|
R *in, R *ro, R *io); \
|
||||||
|
FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \
|
||||||
|
R *ri, R *ii, R *out); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \
|
||||||
|
int howmany, \
|
||||||
|
R *in, const int *inembed, \
|
||||||
|
int istride, int idist, \
|
||||||
|
R *out, const int *onembed, \
|
||||||
|
int ostride, int odist, \
|
||||||
|
const X(r2r_kind) *kind, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \
|
||||||
|
const X(r2r_kind) *kind, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \
|
||||||
|
X(r2r_kind) kind, unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \
|
||||||
|
X(r2r_kind) kind0, X(r2r_kind) kind1, \
|
||||||
|
unsigned flags); \
|
||||||
|
FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \
|
||||||
|
R *in, R *out, X(r2r_kind) kind0, \
|
||||||
|
X(r2r_kind) kind1, X(r2r_kind) kind2, \
|
||||||
|
unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim) *howmany_dims, \
|
||||||
|
R *in, R *out, \
|
||||||
|
const X(r2r_kind) *kind, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \
|
||||||
|
int howmany_rank, \
|
||||||
|
const X(iodim64) *howmany_dims, \
|
||||||
|
R *in, R *out, \
|
||||||
|
const X(r2r_kind) *kind, unsigned flags); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(destroy_plan)(X(plan) p); \
|
||||||
|
FFTW_EXTERN void X(forget_wisdom)(void); \
|
||||||
|
FFTW_EXTERN void X(cleanup)(void); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(set_timelimit)(double t); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \
|
||||||
|
FFTW_EXTERN int X(init_threads)(void); \
|
||||||
|
FFTW_EXTERN void X(cleanup_threads)(void); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \
|
||||||
|
FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \
|
||||||
|
FFTW_EXTERN char *X(export_wisdom_to_string)(void); \
|
||||||
|
FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \
|
||||||
|
void *data); \
|
||||||
|
FFTW_EXTERN int X(import_system_wisdom)(void); \
|
||||||
|
FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \
|
||||||
|
FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \
|
||||||
|
FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \
|
||||||
|
FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \
|
||||||
|
FFTW_EXTERN void X(print_plan)(const X(plan) p); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void *X(malloc)(size_t n); \
|
||||||
|
FFTW_EXTERN R *X(alloc_real)(size_t n); \
|
||||||
|
FFTW_EXTERN C *X(alloc_complex)(size_t n); \
|
||||||
|
FFTW_EXTERN void X(free)(void *p); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN void X(flops)(const X(plan) p, \
|
||||||
|
double *add, double *mul, double *fmas); \
|
||||||
|
FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \
|
||||||
|
FFTW_EXTERN double X(cost)(const X(plan) p); \
|
||||||
|
\
|
||||||
|
FFTW_EXTERN const char X(version)[]; \
|
||||||
|
FFTW_EXTERN const char X(cc)[]; \
|
||||||
|
FFTW_EXTERN const char X(codelet_optim)[];
|
||||||
|
|
||||||
|
|
||||||
|
/* end of FFTW_DEFINE_API macro */
|
||||||
|
|
||||||
|
FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
|
||||||
|
FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
|
||||||
|
FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
|
||||||
|
|
||||||
|
/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64
|
||||||
|
for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */
|
||||||
|
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \
|
||||||
|
&& !(defined(__ICC) || defined(__INTEL_COMPILER)) \
|
||||||
|
&& (defined(__i386__) || defined(__x86_64__) || defined(__ia64__))
|
||||||
|
# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
|
||||||
|
/* note: __float128 is a typedef, which is not supported with the _Complex
|
||||||
|
keyword in gcc, so instead we use this ugly __attribute__ version.
|
||||||
|
However, we can't simply pass the __attribute__ version to
|
||||||
|
FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer
|
||||||
|
types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */
|
||||||
|
# undef FFTW_DEFINE_COMPLEX
|
||||||
|
# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C
|
||||||
|
# endif
|
||||||
|
FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FFTW_FORWARD (-1)
|
||||||
|
#define FFTW_BACKWARD (+1)
|
||||||
|
|
||||||
|
#define FFTW_NO_TIMELIMIT (-1.0)
|
||||||
|
|
||||||
|
/* documented flags */
|
||||||
|
#define FFTW_MEASURE (0U)
|
||||||
|
#define FFTW_DESTROY_INPUT (1U << 0)
|
||||||
|
#define FFTW_UNALIGNED (1U << 1)
|
||||||
|
#define FFTW_CONSERVE_MEMORY (1U << 2)
|
||||||
|
#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
|
||||||
|
#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
|
||||||
|
#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
|
||||||
|
#define FFTW_ESTIMATE (1U << 6)
|
||||||
|
#define FFTW_WISDOM_ONLY (1U << 21)
|
||||||
|
|
||||||
|
/* undocumented beyond-guru flags */
|
||||||
|
#define FFTW_ESTIMATE_PATIENT (1U << 7)
|
||||||
|
#define FFTW_BELIEVE_PCOST (1U << 8)
|
||||||
|
#define FFTW_NO_DFT_R2HC (1U << 9)
|
||||||
|
#define FFTW_NO_NONTHREADED (1U << 10)
|
||||||
|
#define FFTW_NO_BUFFERING (1U << 11)
|
||||||
|
#define FFTW_NO_INDIRECT_OP (1U << 12)
|
||||||
|
#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
|
||||||
|
#define FFTW_NO_RANK_SPLITS (1U << 14)
|
||||||
|
#define FFTW_NO_VRANK_SPLITS (1U << 15)
|
||||||
|
#define FFTW_NO_VRECURSE (1U << 16)
|
||||||
|
#define FFTW_NO_SIMD (1U << 17)
|
||||||
|
#define FFTW_NO_SLOW (1U << 18)
|
||||||
|
#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
|
||||||
|
#define FFTW_ALLOW_PRUNING (1U << 20)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* FFTW3_H */
|
50
lib/wsprd/genmet.f90
Normal file
50
lib/wsprd/genmet.f90
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
program genmet
|
||||||
|
|
||||||
|
character*12 arg
|
||||||
|
integer hist(-128:128)
|
||||||
|
lim(x)=min(127,max(-128,nint(scale*x)))
|
||||||
|
|
||||||
|
nargs=iargc()
|
||||||
|
if(nargs.ne.4) then
|
||||||
|
print*,'Usage: genmet bw scale snr iters'
|
||||||
|
print*,'Example: genmet 1.46 20 -24 1000000'
|
||||||
|
go to 999
|
||||||
|
endif
|
||||||
|
call getarg(1,arg)
|
||||||
|
read(arg,*) bw
|
||||||
|
call getarg(2,arg)
|
||||||
|
read(arg,*) scale
|
||||||
|
call getarg(3,arg)
|
||||||
|
read(arg,*) snr
|
||||||
|
call getarg(4,arg)
|
||||||
|
read(arg,*) iters
|
||||||
|
|
||||||
|
hist=0
|
||||||
|
s=sqrt(2500.0/bw) * 10.0**(0.05*snr)
|
||||||
|
fac=1.0/sqrt(2.0)
|
||||||
|
do iter=1,iters
|
||||||
|
x1=fac*gran()
|
||||||
|
y1=fac*gran()
|
||||||
|
x0=fac*gran()
|
||||||
|
y0=fac*gran()
|
||||||
|
r=(x1+s)**2 + y1*y1 - x0*x0 - y0*y0
|
||||||
|
hist(lim(r))=hist(lim(r))+1
|
||||||
|
enddo
|
||||||
|
|
||||||
|
xln2=log(2.0)
|
||||||
|
do i=-128,127
|
||||||
|
p1=hist(i)/dfloat(iters)
|
||||||
|
j=-i
|
||||||
|
if(j.gt.127) j=127
|
||||||
|
p0=hist(j)/dfloat(iters)
|
||||||
|
xlhd0=log(max(0.001,2.0*p0/(p0+p1)))/xln2
|
||||||
|
xlhd1=log(max(0.001,2.0*p1/(p0+p1)))/xln2
|
||||||
|
write(13,1010) i/scale,hist(i)/dfloat(iters)
|
||||||
|
1010 format(f8.3,f12.9)
|
||||||
|
write(14,1012) i+128,xlhd0,xlhd1
|
||||||
|
1012 format(i4,2f8.3)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
999 end program genmet
|
||||||
|
|
||||||
|
|
28
lib/wsprd/gran.c
Normal file
28
lib/wsprd/gran.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/* Generate gaussian random float with mean=0 and std_dev=1 */
|
||||||
|
float gran_()
|
||||||
|
{
|
||||||
|
float fac,rsq,v1,v2;
|
||||||
|
static float gset;
|
||||||
|
static int iset;
|
||||||
|
|
||||||
|
if(iset){
|
||||||
|
/* Already got one */
|
||||||
|
iset = 0;
|
||||||
|
return gset;
|
||||||
|
}
|
||||||
|
/* Generate two evenly distributed numbers between -1 and +1
|
||||||
|
* that are inside the unit circle
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
v1 = 2.0 * (float)rand() / RAND_MAX - 1;
|
||||||
|
v2 = 2.0 * (float)rand() / RAND_MAX - 1;
|
||||||
|
rsq = v1*v1 + v2*v2;
|
||||||
|
} while(rsq >= 1.0 || rsq == 0.0);
|
||||||
|
fac = sqrt(-2.0*log(rsq)/rsq);
|
||||||
|
gset = v1*fac;
|
||||||
|
iset++;
|
||||||
|
return v2*fac;
|
||||||
|
}
|
111
lib/wsprd/metric_tables.c
Normal file
111
lib/wsprd/metric_tables.c
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 4 metric tables calculated via simulation for 2-FSK with Es/No=0,3,6,9 dB
|
||||||
|
* tables were calculated for constant rms noise level of 50. The symbol vector
|
||||||
|
* should be normalized to have rms amplitude equal to "symbol_scale".
|
||||||
|
********************************************************************************/
|
||||||
|
//float symbol_scale[4]={42.6, 53.3, 72.7, 100.2};
|
||||||
|
float metric_tables[4][256]={
|
||||||
|
0.9782, 0.9695, 0.9689, 0.9669, 0.9666, 0.9653, 0.9638, 0.9618, 0.9599, 0.9601,
|
||||||
|
0.9592, 0.9570, 0.9556, 0.9540, 0.9525, 0.9527, 0.9486, 0.9477, 0.9450, 0.9436,
|
||||||
|
0.9424, 0.9400, 0.9381, 0.9360, 0.9340, 0.9316, 0.9301, 0.9272, 0.9254, 0.9224,
|
||||||
|
0.9196, 0.9171, 0.9154, 0.9123, 0.9076, 0.9061, 0.9030, 0.9000, 0.8965, 0.8934,
|
||||||
|
0.8903, 0.8874, 0.8834, 0.8792, 0.8760, 0.8726, 0.8685, 0.8639, 0.8599, 0.8550,
|
||||||
|
0.8504, 0.8459, 0.8422, 0.8364, 0.8320, 0.8262, 0.8215, 0.8159, 0.8111, 0.8052,
|
||||||
|
0.7996, 0.7932, 0.7878, 0.7812, 0.7745, 0.7685, 0.7616, 0.7550, 0.7479, 0.7405,
|
||||||
|
0.7336, 0.7255, 0.7184, 0.7102, 0.7016, 0.6946, 0.6860, 0.6769, 0.6687, 0.6598,
|
||||||
|
0.6503, 0.6416, 0.6325, 0.6219, 0.6122, 0.6016, 0.5920, 0.5818, 0.5711, 0.5606,
|
||||||
|
0.5487, 0.5374, 0.5266, 0.5142, 0.5020, 0.4908, 0.4784, 0.4663, 0.4532, 0.4405,
|
||||||
|
0.4271, 0.4144, 0.4006, 0.3865, 0.3731, 0.3594, 0.3455, 0.3304, 0.3158, 0.3009,
|
||||||
|
0.2858, 0.2708, 0.2560, 0.2399, 0.2233, 0.2074, 0.1919, 0.1756, 0.1590, 0.1427,
|
||||||
|
0.1251, 0.1074, 0.0905, 0.0722, 0.0550, 0.0381, 0.0183, 0.0000, -0.0185, -0.0391,
|
||||||
|
-0.0571, -0.0760, -0.0966, -0.1160, -0.1370, -0.1584, -0.1787, -0.1999, -0.2214, -0.2423,
|
||||||
|
-0.2643, -0.2879, -0.3114, -0.3336, -0.3568, -0.3806, -0.4050, -0.4293, -0.4552, -0.4798,
|
||||||
|
-0.5046, -0.5296, -0.5564, -0.5836, -0.6093, -0.6372, -0.6645, -0.6933, -0.7208, -0.7495,
|
||||||
|
-0.7763, -0.8065, -0.8378, -0.8660, -0.8964, -0.9293, -0.9592, -0.9907, -1.0214, -1.0509,
|
||||||
|
-1.0850, -1.1168, -1.1528, -1.1847, -1.2157, -1.2511, -1.2850, -1.3174, -1.3540, -1.3900,
|
||||||
|
-1.4201, -1.4580, -1.4956, -1.5292, -1.5683, -1.6030, -1.6411, -1.6789, -1.7147, -1.7539,
|
||||||
|
-1.7887, -1.8289, -1.8699, -1.9043, -1.9469, -1.9849, -2.0267, -2.0610, -2.1028, -2.1391,
|
||||||
|
-2.1855, -2.2215, -2.2712, -2.3033, -2.3440, -2.3870, -2.4342, -2.4738, -2.5209, -2.5646,
|
||||||
|
-2.6016, -2.6385, -2.6868, -2.7356, -2.7723, -2.8111, -2.8524, -2.9009, -2.9428, -2.9879,
|
||||||
|
-3.0103, -3.0832, -3.1340, -3.1628, -3.2049, -3.2557, -3.3101, -3.3453, -3.4025, -3.4317,
|
||||||
|
-3.4828, -3.5270, -3.5745, -3.6181, -3.6765, -3.7044, -3.7410, -3.8118, -3.8368, -3.9549,
|
||||||
|
-3.9488, -3.9941, -4.0428, -4.0892, -4.1648, -4.1965, -4.1892, -4.2565, -4.3356, -4.3948,
|
||||||
|
-4.4481, -4.4607, -4.5533, -4.5809, -4.5927, -5.1047,
|
||||||
|
0.9978, 0.9962, 0.9961, 0.9959, 0.9958, 0.9954, 0.9949, 0.9950, 0.9947, 0.9942,
|
||||||
|
0.9940, 0.9939, 0.9933, 0.9931, 0.9928, 0.9924, 0.9921, 0.9916, 0.9911, 0.9909,
|
||||||
|
0.9903, 0.9900, 0.9892, 0.9887, 0.9883, 0.9877, 0.9869, 0.9863, 0.9857, 0.9848,
|
||||||
|
0.9842, 0.9835, 0.9825, 0.9817, 0.9808, 0.9799, 0.9791, 0.9777, 0.9767, 0.9757,
|
||||||
|
0.9744, 0.9729, 0.9716, 0.9704, 0.9690, 0.9674, 0.9656, 0.9641, 0.9625, 0.9609,
|
||||||
|
0.9587, 0.9567, 0.9548, 0.9524, 0.9501, 0.9478, 0.9453, 0.9426, 0.9398, 0.9371,
|
||||||
|
0.9339, 0.9311, 0.9277, 0.9242, 0.9206, 0.9168, 0.9131, 0.9087, 0.9043, 0.8999,
|
||||||
|
0.8953, 0.8907, 0.8857, 0.8803, 0.8747, 0.8690, 0.8632, 0.8572, 0.8507, 0.8439,
|
||||||
|
0.8368, 0.8295, 0.8217, 0.8138, 0.8058, 0.7972, 0.7883, 0.7784, 0.7694, 0.7597,
|
||||||
|
0.7489, 0.7378, 0.7269, 0.7152, 0.7030, 0.6911, 0.6782, 0.6643, 0.6506, 0.6371,
|
||||||
|
0.6211, 0.6054, 0.5897, 0.5740, 0.5565, 0.5393, 0.5214, 0.5027, 0.4838, 0.4643,
|
||||||
|
0.4436, 0.4225, 0.4004, 0.3787, 0.3562, 0.3324, 0.3089, 0.2839, 0.2584, 0.2321,
|
||||||
|
0.2047, 0.1784, 0.1499, 0.1213, 0.0915, 0.0628, 0.0314, 0.0000, -0.0321, -0.0657,
|
||||||
|
-0.0977, -0.1324, -0.1673, -0.2036, -0.2387, -0.2768, -0.3150, -0.3538, -0.3936, -0.4327,
|
||||||
|
-0.4739, -0.5148, -0.5561, -0.6000, -0.6438, -0.6889, -0.7331, -0.7781, -0.8247, -0.8712,
|
||||||
|
-0.9177, -0.9677, -1.0142, -1.0631, -1.1143, -1.1686, -1.2169, -1.2680, -1.3223, -1.3752,
|
||||||
|
-1.4261, -1.4806, -1.5356, -1.5890, -1.6462, -1.7041, -1.7591, -1.8124, -1.8735, -1.9311,
|
||||||
|
-1.9891, -2.0459, -2.1048, -2.1653, -2.2248, -2.2855, -2.3466, -2.4079, -2.4668, -2.5263,
|
||||||
|
-2.5876, -2.6507, -2.7142, -2.7761, -2.8366, -2.8995, -2.9620, -3.0279, -3.0973, -3.1576,
|
||||||
|
-3.2238, -3.2890, -3.3554, -3.4215, -3.4805, -3.5518, -3.6133, -3.6812, -3.7473, -3.8140,
|
||||||
|
-3.8781, -3.9450, -4.0184, -4.0794, -4.1478, -4.2241, -4.2853, -4.3473, -4.4062, -4.4839,
|
||||||
|
-4.5539, -4.6202, -4.6794, -4.7478, -4.8309, -4.9048, -4.9669, -5.0294, -5.1194, -5.1732,
|
||||||
|
-5.2378, -5.3094, -5.3742, -5.4573, -5.5190, -5.5728, -5.6637, -5.7259, -5.7843, -5.8854,
|
||||||
|
-5.9553, -6.0054, -6.0656, -6.1707, -6.2241, -6.3139, -6.3393, -6.4356, -6.5153, -6.5758,
|
||||||
|
-6.6506, -6.7193, -6.7542, -6.8942, -6.9219, -6.9605, -7.1013, -7.1895, -7.1549, -7.2799,
|
||||||
|
-7.4119, -7.4608, -7.5256, -7.5879, -7.7598, -8.4120,
|
||||||
|
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997,
|
||||||
|
0.9997, 0.9996, 0.9996, 0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9994, 0.9993,
|
||||||
|
0.9993, 0.9992, 0.9991, 0.9991, 0.9990, 0.9989, 0.9988, 0.9988, 0.9988, 0.9986,
|
||||||
|
0.9985, 0.9984, 0.9983, 0.9982, 0.9980, 0.9979, 0.9977, 0.9976, 0.9974, 0.9971,
|
||||||
|
0.9969, 0.9968, 0.9965, 0.9962, 0.9960, 0.9957, 0.9953, 0.9950, 0.9947, 0.9941,
|
||||||
|
0.9937, 0.9933, 0.9928, 0.9922, 0.9917, 0.9911, 0.9904, 0.9897, 0.9890, 0.9882,
|
||||||
|
0.9874, 0.9863, 0.9855, 0.9843, 0.9832, 0.9819, 0.9806, 0.9792, 0.9777, 0.9760,
|
||||||
|
0.9743, 0.9724, 0.9704, 0.9683, 0.9659, 0.9634, 0.9609, 0.9581, 0.9550, 0.9516,
|
||||||
|
0.9481, 0.9446, 0.9406, 0.9363, 0.9317, 0.9270, 0.9218, 0.9160, 0.9103, 0.9038,
|
||||||
|
0.8972, 0.8898, 0.8822, 0.8739, 0.8647, 0.8554, 0.8457, 0.8357, 0.8231, 0.8115,
|
||||||
|
0.7984, 0.7854, 0.7704, 0.7556, 0.7391, 0.7210, 0.7038, 0.6840, 0.6633, 0.6408,
|
||||||
|
0.6174, 0.5939, 0.5678, 0.5410, 0.5137, 0.4836, 0.4524, 0.4193, 0.3850, 0.3482,
|
||||||
|
0.3132, 0.2733, 0.2315, 0.1891, 0.1435, 0.0980, 0.0493, 0.0000, -0.0510, -0.1052,
|
||||||
|
-0.1593, -0.2177, -0.2759, -0.3374, -0.4005, -0.4599, -0.5266, -0.5935, -0.6626, -0.7328,
|
||||||
|
-0.8051, -0.8757, -0.9498, -1.0271, -1.1019, -1.1816, -1.2642, -1.3459, -1.4295, -1.5077,
|
||||||
|
-1.5958, -1.6818, -1.7647, -1.8548, -1.9387, -2.0295, -2.1152, -2.2154, -2.3011, -2.3904,
|
||||||
|
-2.4820, -2.5786, -2.6730, -2.7652, -2.8616, -2.9546, -3.0526, -3.1445, -3.2445, -3.3416,
|
||||||
|
-3.4357, -3.5325, -3.6324, -3.7313, -3.8225, -3.9209, -4.0248, -4.1278, -4.2261, -4.3193,
|
||||||
|
-4.4220, -4.5262, -4.6214, -4.7242, -4.8234, -4.9245, -5.0298, -5.1250, -5.2232, -5.3267,
|
||||||
|
-5.4332, -5.5342, -5.6431, -5.7270, -5.8401, -5.9350, -6.0407, -6.1418, -6.2363, -6.3384,
|
||||||
|
-6.4536, -6.5429, -6.6582, -6.7433, -6.8438, -6.9478, -7.0789, -7.1894, -7.2714, -7.3815,
|
||||||
|
-7.4810, -7.5575, -7.6852, -7.8071, -7.8580, -7.9724, -8.1000, -8.2207, -8.2867, -8.4017,
|
||||||
|
-8.5287, -8.6347, -8.7082, -8.8319, -8.9448, -9.0355, -9.1885, -9.2095, -9.2863, -9.4186,
|
||||||
|
-9.5064, -9.6386, -9.7207, -9.8286, -9.9453, -10.0701, -10.1735, -10.3001, -10.2858, -10.5427,
|
||||||
|
-10.5982, -10.7361, -10.7042, -10.9212, -11.0097, -11.0469, -11.1155, -11.2812, -11.3472, -11.4988,
|
||||||
|
-11.5327, -11.6692, -11.9376, -11.8606, -12.1372, -13.2539,
|
||||||
|
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||||
|
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||||
|
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||||
|
0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999,
|
||||||
|
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997, 0.9996,
|
||||||
|
0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9993, 0.9992, 0.9991, 0.9991, 0.9989,
|
||||||
|
0.9988, 0.9986, 0.9985, 0.9983, 0.9981, 0.9980, 0.9977, 0.9974, 0.9971, 0.9968,
|
||||||
|
0.9965, 0.9962, 0.9956, 0.9950, 0.9948, 0.9941, 0.9933, 0.9926, 0.9919, 0.9910,
|
||||||
|
0.9899, 0.9889, 0.9877, 0.9863, 0.9845, 0.9829, 0.9811, 0.9791, 0.9769, 0.9741,
|
||||||
|
0.9716, 0.9684, 0.9645, 0.9611, 0.9563, 0.9519, 0.9463, 0.9406, 0.9344, 0.9272,
|
||||||
|
0.9197, 0.9107, 0.9016, 0.8903, 0.8791, 0.8653, 0.8523, 0.8357, 0.8179, 0.7988,
|
||||||
|
0.7779, 0.7562, 0.7318, 0.7024, 0.6753, 0.6435, 0.6089, 0.5700, 0.5296, 0.4860,
|
||||||
|
0.4366, 0.3855, 0.3301, 0.2735, 0.2114, 0.1443, 0.0682, 0.0000, -0.0715, -0.1604,
|
||||||
|
-0.2478, -0.3377, -0.4287, -0.5277, -0.6291, -0.7384, -0.8457, -0.9559, -1.0742, -1.1913,
|
||||||
|
-1.3110, -1.4238, -1.5594, -1.6854, -1.8093, -1.9414, -2.0763, -2.2160, -2.3611, -2.4876,
|
||||||
|
-2.6374, -2.7710, -2.9225, -3.0591, -3.2077, -3.3452, -3.4916, -3.6316, -3.7735, -3.9296,
|
||||||
|
-4.0682, -4.2334, -4.3607, -4.5270, -4.6807, -4.8108, -4.9753, -5.1212, -5.2631, -5.4042,
|
||||||
|
-5.5510, -5.7227, -5.8794, -6.0244, -6.1677, -6.3271, -6.4862, -6.6130, -6.7449, -6.9250,
|
||||||
|
-7.1232, -7.1736, -7.3628, -7.5596, -7.6906, -7.8129, -7.9817, -8.1440, -8.3016, -8.4797,
|
||||||
|
-8.5734, -8.7692, -8.9198, -9.0610, -9.1746, -9.3536, -9.5939, -9.6957, -9.8475, -9.9639,
|
||||||
|
-10.1730, -10.2427, -10.4573, -10.5413, -10.7303, -10.9339, -11.0215, -11.2047, -11.2894, -11.4572,
|
||||||
|
-11.6256, -11.7794, -11.8801, -12.1717, -12.2354, -12.3686, -12.6195, -12.6527, -12.8247, -12.9560,
|
||||||
|
-13.3265, -13.1667, -13.4274, -13.6064, -13.5515, -13.9501, -13.9926, -14.4049, -14.1653, -14.4348,
|
||||||
|
-14.7983, -14.7807, -15.2349, -15.3536, -15.3026, -15.2739, -15.7170, -16.2161, -15.9185, -15.9490,
|
||||||
|
-16.6258, -16.5568, -16.4318, -16.7999, -16.4101, -17.6393, -17.7643, -17.2644, -17.5973, -17.0403,
|
||||||
|
-17.7039, -18.0073, -18.1840, -18.3848, -18.6286, -20.7063};
|
76
lib/wsprd/mettab.c
Normal file
76
lib/wsprd/mettab.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
This file is part of wsprd.
|
||||||
|
|
||||||
|
File name: mettab.c
|
||||||
|
Description: Metric table for sequential Fano decoder.
|
||||||
|
|
||||||
|
Copyright 2008-2015, Joseph Taylor, K1JT
|
||||||
|
License: GNU GPL v3
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mettab[2][256]={
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 2,
|
||||||
|
2, 2, 2, 2, 1, 1, 1, 1, 0, 0,
|
||||||
|
-1, -1, -1, -2, -2, -3, -4, -4, -5, -6,
|
||||||
|
-7, -7, -8, -9, -10, -11, -12, -12, -13, -14,
|
||||||
|
-15, -16, -17, -17, -18, -19, -20, -21, -22, -22,
|
||||||
|
-23, -24, -25, -26, -26, -27, -28, -29, -30, -30,
|
||||||
|
-31, -32, -33, -33, -34, -35, -36, -36, -37, -38,
|
||||||
|
-38, -39, -40, -41, -41, -42, -43, -43, -44, -45,
|
||||||
|
-45, -46, -47, -47, -48, -49, -49, -50, -51, -51,
|
||||||
|
-52, -53, -53, -54, -54, -55, -56, -56, -57, -57,
|
||||||
|
-58, -59, -59, -60, -60, -61, -62, -62, -62, -63,
|
||||||
|
-64, -64, -65, -65, -66, -67, -67, -67, -68, -69,
|
||||||
|
-69, -70, -70, -71, -72, -72, -72, -72, -73, -74,
|
||||||
|
-75, -75, -75, -77, -76, -76, -78, -78, -80, -81,
|
||||||
|
-80, -79, -83, -82, -81, -82, -82, -83, -84, -84,
|
||||||
|
-84, -87, -86, -87, -88,-105, -94,-105, -88, -87,
|
||||||
|
-86, -87, -84, -84, -84, -83, -82, -82, -81, -82,
|
||||||
|
-83, -79, -80, -81, -80, -78, -78, -76, -76, -77,
|
||||||
|
-75, -75, -75, -74, -73, -72, -72, -72, -72, -71,
|
||||||
|
-70, -70, -69, -69, -68, -67, -67, -67, -66, -65,
|
||||||
|
-65, -64, -64, -63, -62, -62, -62, -61, -60, -60,
|
||||||
|
-59, -59, -58, -57, -57, -56, -56, -55, -54, -54,
|
||||||
|
-53, -53, -52, -51, -51, -50, -49, -49, -48, -47,
|
||||||
|
-47, -46, -45, -45, -44, -43, -43, -42, -41, -41,
|
||||||
|
-40, -39, -38, -38, -37, -36, -36, -35, -34, -33,
|
||||||
|
-33, -32, -31, -30, -30, -29, -28, -27, -26, -26,
|
||||||
|
-25, -24, -23, -22, -22, -21, -20, -19, -18, -17,
|
||||||
|
-17, -16, -15, -14, -13, -12, -12, -11, -10, -9,
|
||||||
|
-8, -7, -7, -6, -5, -4, -4, -3, -2, -2,
|
||||||
|
-1, -1, -1, 0, 0, 1, 1, 1, 1, 2,
|
||||||
|
2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5 };
|
376
lib/wsprd/nhash.c
Normal file
376
lib/wsprd/nhash.c
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
This file is part of wsprd.
|
||||||
|
|
||||||
|
File name: nhash.c
|
||||||
|
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* This file is part of the WSPR application, Weak Signal Propogation Reporter
|
||||||
|
*
|
||||||
|
* File Name: nhash.c
|
||||||
|
* Description: Functions to produce 32-bit hashes for hash table lookup
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008-2014 Joseph Taylor, K1JT
|
||||||
|
* License: GNU GPL v3+
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 3 of the License, or (at your option) any later
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||||
|
* Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* Files: lookup3.c
|
||||||
|
* Copyright: Copyright (C) 2006 Bob Jenkins <bob_jenkins@burtleburtle.net>
|
||||||
|
* License: public-domain
|
||||||
|
* You may use this code any way you wish, private, educational, or commercial.
|
||||||
|
* It's free.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
These are functions for producing 32-bit hashes for hash table lookup.
|
||||||
|
hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
|
||||||
|
are externally useful functions. Routines to test the hash are included
|
||||||
|
if SELF_TEST is defined. You can use this free for any purpose. It's in
|
||||||
|
the public domain. It has no warranty.
|
||||||
|
|
||||||
|
You probably want to use hashlittle(). hashlittle() and hashbig()
|
||||||
|
hash byte arrays. hashlittle() is is faster than hashbig() on
|
||||||
|
little-endian machines. Intel and AMD are little-endian machines.
|
||||||
|
On second thought, you probably want hashlittle2(), which is identical to
|
||||||
|
hashlittle() except it returns two 32-bit hashes for the price of one.
|
||||||
|
You could implement hashbig2() if you wanted but I haven't bothered here.
|
||||||
|
|
||||||
|
If you want to find a hash of, say, exactly 7 integers, do
|
||||||
|
a = i1; b = i2; c = i3;
|
||||||
|
mix(a,b,c);
|
||||||
|
a += i4; b += i5; c += i6;
|
||||||
|
mix(a,b,c);
|
||||||
|
a += i7;
|
||||||
|
final(a,b,c);
|
||||||
|
then use c as the hash value. If you have a variable length array of
|
||||||
|
4-byte integers to hash, use hashword(). If you have a byte array (like
|
||||||
|
a character string), use hashlittle(). If you have several byte arrays, or
|
||||||
|
a mix of things, see the comments above hashlittle().
|
||||||
|
|
||||||
|
Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
|
||||||
|
then mix those integers. This is fast (you can do a lot more thorough
|
||||||
|
mixing with 12*3 instructions on 3 integers than you can with 3 instructions
|
||||||
|
on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SELF_TEST 1
|
||||||
|
|
||||||
|
#include <stdio.h> /* defines printf for tests */
|
||||||
|
#include <time.h> /* defines time_t for timings in the test */
|
||||||
|
#ifdef Win32
|
||||||
|
#include "win_stdint.h" /* defines uint32_t etc */
|
||||||
|
#else
|
||||||
|
#include <stdint.h> /* defines uint32_t etc */
|
||||||
|
#endif
|
||||||
|
//#include <sys/param.h> /* attempt to define endianness */
|
||||||
|
//#ifdef linux
|
||||||
|
//# include <endian.h> /* attempt to define endianness */
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#define HASH_LITTLE_ENDIAN 1
|
||||||
|
|
||||||
|
#define hashsize(n) ((uint32_t)1<<(n))
|
||||||
|
#define hashmask(n) (hashsize(n)-1)
|
||||||
|
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
|
||||||
|
|
||||||
|
/*
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
mix -- mix 3 32-bit values reversibly.
|
||||||
|
|
||||||
|
This is reversible, so any information in (a,b,c) before mix() is
|
||||||
|
still in (a,b,c) after mix().
|
||||||
|
|
||||||
|
If four pairs of (a,b,c) inputs are run through mix(), or through
|
||||||
|
mix() in reverse, there are at least 32 bits of the output that
|
||||||
|
are sometimes the same for one pair and different for another pair.
|
||||||
|
This was tested for:
|
||||||
|
* pairs that differed by one bit, by two bits, in any combination
|
||||||
|
of top bits of (a,b,c), or in any combination of bottom bits of
|
||||||
|
(a,b,c).
|
||||||
|
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
|
||||||
|
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
|
||||||
|
is commonly produced by subtraction) look like a single 1-bit
|
||||||
|
difference.
|
||||||
|
* the base values were pseudorandom, all zero but one bit set, or
|
||||||
|
all zero plus a counter that starts at zero.
|
||||||
|
|
||||||
|
Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
|
||||||
|
satisfy this are
|
||||||
|
4 6 8 16 19 4
|
||||||
|
9 15 3 18 27 15
|
||||||
|
14 9 3 7 17 3
|
||||||
|
Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
|
||||||
|
for "differ" defined as + with a one-bit base and a two-bit delta. I
|
||||||
|
used http://burtleburtle.net/bob/hash/avalanche.html to choose
|
||||||
|
the operations, constants, and arrangements of the variables.
|
||||||
|
|
||||||
|
This does not achieve avalanche. There are input bits of (a,b,c)
|
||||||
|
that fail to affect some output bits of (a,b,c), especially of a. The
|
||||||
|
most thoroughly mixed value is c, but it doesn't really even achieve
|
||||||
|
avalanche in c.
|
||||||
|
|
||||||
|
This allows some parallelism. Read-after-writes are good at doubling
|
||||||
|
the number of bits affected, so the goal of mixing pulls in the opposite
|
||||||
|
direction as the goal of parallelism. I did what I could. Rotates
|
||||||
|
seem to cost as much as shifts on every machine I could lay my hands
|
||||||
|
on, and rotates are much kinder to the top and bottom bits, so I used
|
||||||
|
rotates.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#define mix(a,b,c) \
|
||||||
|
{ \
|
||||||
|
a -= c; a ^= rot(c, 4); c += b; \
|
||||||
|
b -= a; b ^= rot(a, 6); a += c; \
|
||||||
|
c -= b; c ^= rot(b, 8); b += a; \
|
||||||
|
a -= c; a ^= rot(c,16); c += b; \
|
||||||
|
b -= a; b ^= rot(a,19); a += c; \
|
||||||
|
c -= b; c ^= rot(b, 4); b += a; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
final -- final mixing of 3 32-bit values (a,b,c) into c
|
||||||
|
|
||||||
|
Pairs of (a,b,c) values differing in only a few bits will usually
|
||||||
|
produce values of c that look totally different. This was tested for
|
||||||
|
* pairs that differed by one bit, by two bits, in any combination
|
||||||
|
of top bits of (a,b,c), or in any combination of bottom bits of
|
||||||
|
(a,b,c).
|
||||||
|
* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
|
||||||
|
the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
|
||||||
|
is commonly produced by subtraction) look like a single 1-bit
|
||||||
|
difference.
|
||||||
|
* the base values were pseudorandom, all zero but one bit set, or
|
||||||
|
all zero plus a counter that starts at zero.
|
||||||
|
|
||||||
|
These constants passed:
|
||||||
|
14 11 25 16 4 14 24
|
||||||
|
12 14 25 16 4 14 24
|
||||||
|
and these came close:
|
||||||
|
4 8 15 26 3 22 24
|
||||||
|
10 8 15 26 3 22 24
|
||||||
|
11 8 15 26 3 22 24
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#define final(a,b,c) \
|
||||||
|
{ \
|
||||||
|
c ^= b; c -= rot(b,14); \
|
||||||
|
a ^= c; a -= rot(c,11); \
|
||||||
|
b ^= a; b -= rot(a,25); \
|
||||||
|
c ^= b; c -= rot(b,16); \
|
||||||
|
a ^= c; a -= rot(c,4); \
|
||||||
|
b ^= a; b -= rot(a,14); \
|
||||||
|
c ^= b; c -= rot(b,24); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
hashlittle() -- hash a variable-length key into a 32-bit value
|
||||||
|
k : the key (the unaligned variable-length array of bytes)
|
||||||
|
length : the length of the key, counting by bytes
|
||||||
|
initval : can be any 4-byte value
|
||||||
|
Returns a 32-bit value. Every bit of the key affects every bit of
|
||||||
|
the return value. Two keys differing by one or two bits will have
|
||||||
|
totally different hash values.
|
||||||
|
|
||||||
|
The best hash table sizes are powers of 2. There is no need to do
|
||||||
|
mod a prime (mod is sooo slow!). If you need less than 32 bits,
|
||||||
|
use a bitmask. For example, if you need only 10 bits, do
|
||||||
|
h = (h & hashmask(10));
|
||||||
|
In which case, the hash table should have hashsize(10) elements.
|
||||||
|
|
||||||
|
If you are hashing n strings (uint8_t **)k, do it like this:
|
||||||
|
for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
|
||||||
|
|
||||||
|
By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
|
||||||
|
code any way you wish, private, educational, or commercial. It's free.
|
||||||
|
|
||||||
|
Use for hash table lookup, or anything where one collision in 2^^32 is
|
||||||
|
acceptable. Do NOT use for cryptographic purposes.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t nhash_( const void *key, size_t length, uint32_t initval)
|
||||||
|
{
|
||||||
|
uint32_t a,b,c; /* internal state */
|
||||||
|
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
|
||||||
|
|
||||||
|
/* Set up the internal state */
|
||||||
|
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
|
||||||
|
|
||||||
|
u.ptr = key;
|
||||||
|
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
|
||||||
|
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
|
||||||
|
|
||||||
|
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
|
||||||
|
while (length > 12)
|
||||||
|
{
|
||||||
|
a += k[0];
|
||||||
|
b += k[1];
|
||||||
|
c += k[2];
|
||||||
|
mix(a,b,c);
|
||||||
|
length -= 12;
|
||||||
|
k += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------- handle the last (probably partial) block */
|
||||||
|
/*
|
||||||
|
* "k[2]&0xffffff" actually reads beyond the end of the string, but
|
||||||
|
* then masks off the part it's not allowed to read. Because the
|
||||||
|
* string is aligned, the masked-off tail is in the same word as the
|
||||||
|
* rest of the string. Every machine with memory protection I've seen
|
||||||
|
* does it on word boundaries, so is OK with this. But VALGRIND will
|
||||||
|
* still catch it and complain. The masking trick does make the hash
|
||||||
|
* noticably faster for short strings (like English words).
|
||||||
|
*/
|
||||||
|
#ifndef VALGRIND
|
||||||
|
|
||||||
|
switch(length)
|
||||||
|
{
|
||||||
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||||
|
case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
|
||||||
|
case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
|
||||||
|
case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
|
||||||
|
case 8 : b+=k[1]; a+=k[0]; break;
|
||||||
|
case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
|
||||||
|
case 6 : b+=k[1]&0xffff; a+=k[0]; break;
|
||||||
|
case 5 : b+=k[1]&0xff; a+=k[0]; break;
|
||||||
|
case 4 : a+=k[0]; break;
|
||||||
|
case 3 : a+=k[0]&0xffffff; break;
|
||||||
|
case 2 : a+=k[0]&0xffff; break;
|
||||||
|
case 1 : a+=k[0]&0xff; break;
|
||||||
|
case 0 : return c; /* zero length strings require no mixing */
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* make valgrind happy */
|
||||||
|
|
||||||
|
k8 = (const uint8_t *)k;
|
||||||
|
switch(length)
|
||||||
|
{
|
||||||
|
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
|
||||||
|
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||||
|
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
|
||||||
|
case 9 : c+=k8[8]; /* fall through */
|
||||||
|
case 8 : b+=k[1]; a+=k[0]; break;
|
||||||
|
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||||
|
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
|
||||||
|
case 5 : b+=k8[4]; /* fall through */
|
||||||
|
case 4 : a+=k[0]; break;
|
||||||
|
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||||
|
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
|
||||||
|
case 1 : a+=k8[0]; break;
|
||||||
|
case 0 : return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !valgrind */
|
||||||
|
|
||||||
|
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
|
||||||
|
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
|
||||||
|
const uint8_t *k8;
|
||||||
|
|
||||||
|
/*--------------- all but last block: aligned reads and different mixing */
|
||||||
|
while (length > 12)
|
||||||
|
{
|
||||||
|
a += k[0] + (((uint32_t)k[1])<<16);
|
||||||
|
b += k[2] + (((uint32_t)k[3])<<16);
|
||||||
|
c += k[4] + (((uint32_t)k[5])<<16);
|
||||||
|
mix(a,b,c);
|
||||||
|
length -= 12;
|
||||||
|
k += 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------- handle the last (probably partial) block */
|
||||||
|
k8 = (const uint8_t *)k;
|
||||||
|
switch(length)
|
||||||
|
{
|
||||||
|
case 12: c+=k[4]+(((uint32_t)k[5])<<16);
|
||||||
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
|
break;
|
||||||
|
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||||
|
case 10: c+=k[4];
|
||||||
|
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
|
break;
|
||||||
|
case 9 : c+=k8[8]; /* fall through */
|
||||||
|
case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
|
||||||
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
|
break;
|
||||||
|
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||||
|
case 6 : b+=k[2];
|
||||||
|
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
|
break;
|
||||||
|
case 5 : b+=k8[4]; /* fall through */
|
||||||
|
case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
|
||||||
|
break;
|
||||||
|
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||||
|
case 2 : a+=k[0];
|
||||||
|
break;
|
||||||
|
case 1 : a+=k8[0];
|
||||||
|
break;
|
||||||
|
case 0 : return c; /* zero length requires no mixing */
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { /* need to read the key one byte at a time */
|
||||||
|
const uint8_t *k = (const uint8_t *)key;
|
||||||
|
|
||||||
|
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
|
||||||
|
while (length > 12)
|
||||||
|
{
|
||||||
|
a += k[0];
|
||||||
|
a += ((uint32_t)k[1])<<8;
|
||||||
|
a += ((uint32_t)k[2])<<16;
|
||||||
|
a += ((uint32_t)k[3])<<24;
|
||||||
|
b += k[4];
|
||||||
|
b += ((uint32_t)k[5])<<8;
|
||||||
|
b += ((uint32_t)k[6])<<16;
|
||||||
|
b += ((uint32_t)k[7])<<24;
|
||||||
|
c += k[8];
|
||||||
|
c += ((uint32_t)k[9])<<8;
|
||||||
|
c += ((uint32_t)k[10])<<16;
|
||||||
|
c += ((uint32_t)k[11])<<24;
|
||||||
|
mix(a,b,c);
|
||||||
|
length -= 12;
|
||||||
|
k += 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------- last block: affect all 32 bits of (c) */
|
||||||
|
switch(length) /* all the case statements fall through */
|
||||||
|
{
|
||||||
|
case 12: c+=((uint32_t)k[11])<<24;
|
||||||
|
case 11: c+=((uint32_t)k[10])<<16;
|
||||||
|
case 10: c+=((uint32_t)k[9])<<8;
|
||||||
|
case 9 : c+=k[8];
|
||||||
|
case 8 : b+=((uint32_t)k[7])<<24;
|
||||||
|
case 7 : b+=((uint32_t)k[6])<<16;
|
||||||
|
case 6 : b+=((uint32_t)k[5])<<8;
|
||||||
|
case 5 : b+=k[4];
|
||||||
|
case 4 : a+=((uint32_t)k[3])<<24;
|
||||||
|
case 3 : a+=((uint32_t)k[2])<<16;
|
||||||
|
case 2 : a+=((uint32_t)k[1])<<8;
|
||||||
|
case 1 : a+=k[0];
|
||||||
|
break;
|
||||||
|
case 0 : return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final(a,b,c);
|
||||||
|
c=(32767&c);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
63
lib/wsprd/t1.f90
Normal file
63
lib/wsprd/t1.f90
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
program t1
|
||||||
|
|
||||||
|
integer mettab(0:255,0:1)
|
||||||
|
data mettab/ &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 4, &
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, &
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, &
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 2, &
|
||||||
|
2, 2, 2, 2, 1, 1, 1, 1, 0, 0, &
|
||||||
|
-1, -1, -1, -2, -2, -3, -4, -4, -5, -6, &
|
||||||
|
-7, -7, -8, -9, -10, -11, -12, -12, -13, -14, &
|
||||||
|
-15, -16, -17, -17, -18, -19, -20, -21, -22, -22, &
|
||||||
|
-23, -24, -25, -26, -26, -27, -28, -29, -30, -30, &
|
||||||
|
-31, -32, -33, -33, -34, -35, -36, -36, -37, -38, &
|
||||||
|
-38, -39, -40, -41, -41, -42, -43, -43, -44, -45, &
|
||||||
|
-45, -46, -47, -47, -48, -49, -49, -50, -51, -51, &
|
||||||
|
-52, -53, -53, -54, -54, -55, -56, -56, -57, -57, &
|
||||||
|
-58, -59, -59, -60, -60, -61, -62, -62, -62, -63, &
|
||||||
|
-64, -64, -65, -65, -66, -67, -67, -67, -68, -69, &
|
||||||
|
-69, -70, -70, -71, -72, -72, -72, -72, -73, -74, &
|
||||||
|
-75, -75, -75, -77, -76, -76, -78, -78, -80, -81, &
|
||||||
|
-80, -79, -83, -82, -81, -82, -82, -83, -84, -84, &
|
||||||
|
-84, -87, -86, -87, -88, -89, -89, -89, -88, -87, &
|
||||||
|
-86, -87, -84, -84, -84, -83, -82, -82, -81, -82, &
|
||||||
|
-83, -79, -80, -81, -80, -78, -78, -76, -76, -77, &
|
||||||
|
-75, -75, -75, -74, -73, -72, -72, -72, -72, -71, &
|
||||||
|
-70, -70, -69, -69, -68, -67, -67, -67, -66, -65, &
|
||||||
|
-65, -64, -64, -63, -62, -62, -62, -61, -60, -60, &
|
||||||
|
-59, -59, -58, -57, -57, -56, -56, -55, -54, -54, &
|
||||||
|
-53, -53, -52, -51, -51, -50, -49, -49, -48, -47, &
|
||||||
|
-47, -46, -45, -45, -44, -43, -43, -42, -41, -41, &
|
||||||
|
-40, -39, -38, -38, -37, -36, -36, -35, -34, -33, &
|
||||||
|
-33, -32, -31, -30, -30, -29, -28, -27, -26, -26, &
|
||||||
|
-25, -24, -23, -22, -22, -21, -20, -19, -18, -17, &
|
||||||
|
-17, -16, -15, -14, -13, -12, -12, -11, -10, -9, &
|
||||||
|
-8, -7, -7, -6, -5, -4, -4, -3, -2, -2, &
|
||||||
|
-1, -1, -1, 0, 0, 1, 1, 1, 1, 2, &
|
||||||
|
2, 2, 2, 2, 3, 3, 3, 3, 3, 3, &
|
||||||
|
3, 3, 3, 4, 4, 4, 4, 4, 4, 4, &
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, &
|
||||||
|
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, &
|
||||||
|
5, 5/
|
||||||
|
|
||||||
|
do i=0,255
|
||||||
|
write(*,1010) i,mettab(i,0),mettab(i,1)
|
||||||
|
1010 format(3i6)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end program t1
|
11
lib/wsprd/t2.f90
Normal file
11
lib/wsprd/t2.f90
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
program t2
|
||||||
|
|
||||||
|
df=375.0/65536.0
|
||||||
|
do i=1,65536
|
||||||
|
w=1.0/(1.0 + ((i-32768)/26214.0)**20)
|
||||||
|
f=(i-32768)*df
|
||||||
|
write(13,1010) f,w
|
||||||
|
1010 format(2f15.6)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end program t2
|
41
lib/wsprd/tab.c
Normal file
41
lib/wsprd/tab.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
This file is part of wsprd.
|
||||||
|
|
||||||
|
File name: tab.c
|
||||||
|
Description: 8-bit parity lookup table.
|
||||||
|
*/
|
||||||
|
unsigned char Partab[] = {
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
0, 1, 1, 0, 1, 0, 0, 1,
|
||||||
|
1, 0, 0, 1, 0, 1, 1, 0,
|
||||||
|
};
|
||||||
|
|
61
lib/wsprd/test_wspr.f90
Normal file
61
lib/wsprd/test_wspr.f90
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
program test_wspr
|
||||||
|
|
||||||
|
! This program provides examples of the source encoding, convolutional
|
||||||
|
! error-control coding, bit and symbol ordering, and synchronizing
|
||||||
|
! information contained in WSPR messages.
|
||||||
|
|
||||||
|
character*22 msg,msg2
|
||||||
|
character*23 msg3
|
||||||
|
character*1 err2,err3
|
||||||
|
integer*1 data0(11)
|
||||||
|
logical lfile
|
||||||
|
|
||||||
|
! Get command-line argument(s)
|
||||||
|
nargs=iargc()
|
||||||
|
if(nargs.ne.1) then
|
||||||
|
print*,'Usage: test_wspr "message"'
|
||||||
|
go to 999
|
||||||
|
endif
|
||||||
|
call getarg(1,msg) !Get message from command line
|
||||||
|
call unpk(data0,1,msg3) !Read the C hashtable
|
||||||
|
lfile=msg(1:2).eq."-t"
|
||||||
|
if(lfile) open(10,file="messages.txt",status="old")
|
||||||
|
|
||||||
|
do imsg=1,999
|
||||||
|
if(lfile) read(10,1001,end=900) msg
|
||||||
|
1001 format(a22)
|
||||||
|
|
||||||
|
data0=0
|
||||||
|
call wqencode(msg,ntype0,data0) !Source encoding
|
||||||
|
! write(*,1002) data0(1:7)
|
||||||
|
!1002 format('Source-encoded message (50 bits, hex):',7z3.2)
|
||||||
|
! data0(8:11)=0
|
||||||
|
|
||||||
|
call wqdecode(data0,msg2,ntype1)
|
||||||
|
|
||||||
|
! write(*,1020) ntype1
|
||||||
|
!1020 format('Message type: ',i7)
|
||||||
|
! write(*,1030) msg2
|
||||||
|
!1030 format('Decoded message: ',a22)
|
||||||
|
|
||||||
|
call unpk(data0,0,msg3)
|
||||||
|
do i=1,23
|
||||||
|
if(ichar(msg3(i:i)).eq.0) then
|
||||||
|
msg3(i:)=" "
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
err2=' '
|
||||||
|
err3=' '
|
||||||
|
if(msg2.ne.msg) err2='*'
|
||||||
|
if(msg3.ne.msg) err3='*'
|
||||||
|
|
||||||
|
write(*,1040) msg,err2,msg2,err3,msg3
|
||||||
|
1040 format(a22,1x,a1,1x,a22,1x,a1,1x,a22)
|
||||||
|
if(.not.lfile) exit
|
||||||
|
enddo
|
||||||
|
900 call unpk(data0,2,msg3)
|
||||||
|
|
||||||
|
|
||||||
|
999 end program test_wspr
|
123
lib/wsprd/unpk.c
Normal file
123
lib/wsprd/unpk.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "wsprd_utils.h"
|
||||||
|
|
||||||
|
unsigned int nhash_( const void *key, size_t length, uint32_t initval);
|
||||||
|
|
||||||
|
void unpk_(signed char message[], int *nhashtab, char call_loc_pow[])
|
||||||
|
{
|
||||||
|
int i,n1,n2,n3,ndbm,ihash,nadd,noprint,nh;
|
||||||
|
char callsign[13],grid[5],grid6[7],cdbm[3];
|
||||||
|
static char hashtab[32768][13];
|
||||||
|
FILE *fhash;
|
||||||
|
|
||||||
|
if(*nhashtab==1) {
|
||||||
|
char line[80], hcall[12];
|
||||||
|
if( (fhash=fopen("hashtable.txt","r+")) ) {
|
||||||
|
while (fgets(line, sizeof(line), fhash) != NULL) {
|
||||||
|
sscanf(line,"%d %s",&nh,hcall);
|
||||||
|
strcpy(*hashtab+nh*13,hcall);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fhash=fopen("hashtable.txt","w+");
|
||||||
|
}
|
||||||
|
fclose(fhash);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*nhashtab==2) {
|
||||||
|
fhash=fopen("hashtable.txt","w");
|
||||||
|
for (i=0; i<32768; i++) {
|
||||||
|
if( strncmp(hashtab[i],"\0",1) != 0 ) {
|
||||||
|
fprintf(fhash,"%5d %s\n",i,*hashtab+i*13);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fhash);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack50(message,&n1,&n2);
|
||||||
|
unpackcall(n1,callsign);
|
||||||
|
unpackgrid(n2, grid);
|
||||||
|
int ntype = (n2&127) - 64;
|
||||||
|
callsign[12]=0;
|
||||||
|
grid[4]=0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Based on the value of ntype, decide whether this is a Type 1, 2, or
|
||||||
|
3 message.
|
||||||
|
|
||||||
|
* Type 1: 6 digit call, grid, power - ntype is positive and is a member
|
||||||
|
of the set {0,3,7,10,13,17,20...60}
|
||||||
|
|
||||||
|
* Type 2: extended callsign, power - ntype is positive but not
|
||||||
|
a member of the set of allowed powers
|
||||||
|
|
||||||
|
* Type 3: hash, 6 digit grid, power - ntype is negative.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( (ntype >= 0) && (ntype <= 62) ) {
|
||||||
|
int nu=ntype%10;
|
||||||
|
if( nu == 0 || nu == 3 || nu == 7 ) {
|
||||||
|
ndbm=ntype;
|
||||||
|
memset(call_loc_pow,0,sizeof(char)*23);
|
||||||
|
sprintf(cdbm,"%2d",ndbm);
|
||||||
|
strncat(call_loc_pow,callsign,strlen(callsign));
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,grid,4);
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,cdbm,2);
|
||||||
|
strncat(call_loc_pow,"\0",1);
|
||||||
|
ihash=nhash_(callsign,strlen(callsign),(uint32_t)146);
|
||||||
|
strcpy(*hashtab+ihash*13,callsign);
|
||||||
|
} else {
|
||||||
|
nadd=nu;
|
||||||
|
if( nu > 3 ) nadd=nu-3;
|
||||||
|
if( nu > 7 ) nadd=nu-7;
|
||||||
|
n3=n2/128+32768*(nadd-1);
|
||||||
|
unpackpfx(n3,callsign);
|
||||||
|
ndbm=ntype-nadd;
|
||||||
|
memset(call_loc_pow,0,sizeof(char)*23);
|
||||||
|
sprintf(cdbm,"%2d",ndbm);
|
||||||
|
strncat(call_loc_pow,callsign,strlen(callsign));
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,cdbm,2);
|
||||||
|
strncat(call_loc_pow,"\0",1);
|
||||||
|
ihash=nhash_(callsign,strlen(callsign),(uint32_t)146);
|
||||||
|
strcpy(*hashtab+ihash*13,callsign);
|
||||||
|
noprint=0;
|
||||||
|
}
|
||||||
|
} else if ( ntype < 0 ) {
|
||||||
|
ndbm=-(ntype+1);
|
||||||
|
memset(grid6,0,sizeof(char)*7);
|
||||||
|
strncat(grid6,callsign+5,1);
|
||||||
|
strncat(grid6,callsign,5);
|
||||||
|
ihash=(n2-ntype-64)/128;
|
||||||
|
if( strncmp(hashtab[ihash],"\0",1) != 0 ) {
|
||||||
|
sprintf(callsign,"<%s>",hashtab[ihash]);
|
||||||
|
} else {
|
||||||
|
sprintf(callsign,"%5s","<...>");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(call_loc_pow,0,sizeof(char)*23);
|
||||||
|
sprintf(cdbm,"%2d",ndbm);
|
||||||
|
strncat(call_loc_pow,callsign,strlen(callsign));
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,grid6,strlen(grid6));
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,cdbm,2);
|
||||||
|
strncat(call_loc_pow,"\0",1);
|
||||||
|
|
||||||
|
noprint=0;
|
||||||
|
|
||||||
|
// I don't know what to do with these... They show up as "A000AA" grids.
|
||||||
|
if( ntype == -64 ) noprint=1;
|
||||||
|
}
|
||||||
|
// printf("\nUnpacked in C: %s\n",call_loc_pow);
|
||||||
|
}
|
935
lib/wsprd/wsprd.c
Normal file
935
lib/wsprd/wsprd.c
Normal file
@ -0,0 +1,935 @@
|
|||||||
|
/*
|
||||||
|
This file is part of program wsprd, a detector/demodulator/decoder
|
||||||
|
for the Weak Signal Propagation Reporter (WSPR) mode.
|
||||||
|
|
||||||
|
File name: wsprd.c
|
||||||
|
|
||||||
|
Copyright 2001-2015, Joe Taylor, K1JT
|
||||||
|
|
||||||
|
Much of the present code is based on work by Steven Franke, K9AN,
|
||||||
|
which in turn was based on earlier work by K1JT.
|
||||||
|
|
||||||
|
Copyright 2014-2015, Steven Franke, K9AN
|
||||||
|
|
||||||
|
License: GNU GPL v3
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <fftw3.h>
|
||||||
|
|
||||||
|
#include "fano.h"
|
||||||
|
#include "wsprd_utils.h"
|
||||||
|
|
||||||
|
#define max(x,y) ((x) > (y) ? (x) : (y))
|
||||||
|
// Possible PATIENCE options: FFTW_ESTIMATE, FFTW_ESTIMATE_PATIENT,
|
||||||
|
// FFTW_MEASURE, FFTW_PATIENT, FFTW_EXHAUSTIVE
|
||||||
|
#define PATIENCE FFTW_ESTIMATE
|
||||||
|
fftw_plan PLAN1,PLAN2,PLAN3;
|
||||||
|
|
||||||
|
unsigned char pr3[162]=
|
||||||
|
{1,1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0,
|
||||||
|
0,1,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1,
|
||||||
|
0,0,0,0,0,0,1,0,1,1,0,0,1,1,0,1,0,0,0,1,
|
||||||
|
1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1,
|
||||||
|
0,0,1,0,1,1,0,0,0,1,1,0,1,0,1,0,0,0,1,0,
|
||||||
|
0,0,0,0,1,0,0,1,0,0,1,1,1,0,1,1,0,0,1,1,
|
||||||
|
0,1,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,0,1,1,
|
||||||
|
0,0,0,0,0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,0,
|
||||||
|
0,0};
|
||||||
|
|
||||||
|
unsigned long nr;
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
unsigned long readc2file(char *ptr_to_infile, double *idat, double *qdat,
|
||||||
|
double *freq, int *wspr_type)
|
||||||
|
{
|
||||||
|
float buffer[2*65536];
|
||||||
|
double dfreq;
|
||||||
|
int i,ntrmin;
|
||||||
|
char *c2file[15];
|
||||||
|
FILE* fp;
|
||||||
|
|
||||||
|
fp = fopen(ptr_to_infile,"rb");
|
||||||
|
if (fp == NULL) {
|
||||||
|
fprintf(stderr, "Cannot open data file '%s'\n", ptr_to_infile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
unsigned long nread=fread(c2file,sizeof(char),14,fp);
|
||||||
|
nread=fread(&ntrmin,sizeof(int),1,fp);
|
||||||
|
nread=fread(&dfreq,sizeof(double),1,fp);
|
||||||
|
*freq=dfreq;
|
||||||
|
nread=fread(buffer,sizeof(float),2*45000,fp);
|
||||||
|
|
||||||
|
*wspr_type=ntrmin;
|
||||||
|
|
||||||
|
for(i=0; i<45000; i++) {
|
||||||
|
idat[i]=buffer[2*i];
|
||||||
|
qdat[i]=-buffer[2*i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if( nread == 2*45000 ) {
|
||||||
|
return nread/2;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
unsigned long readwavfile(char *ptr_to_infile, int ntrmin, double *idat, double *qdat )
|
||||||
|
{
|
||||||
|
unsigned long i, j, npoints;
|
||||||
|
int nfft1, nfft2, nh2, i0;
|
||||||
|
double df;
|
||||||
|
|
||||||
|
nfft2=46080; //this is the number of downsampled points that will be returned
|
||||||
|
nh2=nfft2/2;
|
||||||
|
|
||||||
|
if( ntrmin == 2 ) {
|
||||||
|
nfft1=nfft2*32; //need to downsample by a factor of 32
|
||||||
|
df=12000.0/nfft1;
|
||||||
|
i0=1500.0/df+0.5;
|
||||||
|
npoints=114*12000;
|
||||||
|
} else if ( ntrmin == 15 ) {
|
||||||
|
nfft1=nfft2*8*32;
|
||||||
|
df=12000.0/nfft1;
|
||||||
|
i0=(1500.0+112.5)/df+0.5;
|
||||||
|
npoints=8*114*12000;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"This should not happen\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
double *realin;
|
||||||
|
fftw_complex *fftin, *fftout;
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
short int *buf2;
|
||||||
|
buf2 = malloc(npoints*sizeof(short int));
|
||||||
|
|
||||||
|
fp = fopen(ptr_to_infile,"rb");
|
||||||
|
if (fp == NULL) {
|
||||||
|
fprintf(stderr, "Cannot open data file '%s'\n", ptr_to_infile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
nr=fread(buf2,2,22,fp); //Read and ignore header
|
||||||
|
nr=fread(buf2,2,npoints,fp); //Read raw data
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
realin=(double*) fftw_malloc(sizeof(double)*nfft1);
|
||||||
|
fftout=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*nfft1);
|
||||||
|
PLAN1 = fftw_plan_dft_r2c_1d(nfft1, realin, fftout, PATIENCE);
|
||||||
|
|
||||||
|
for (i=0; i<npoints; i++) {
|
||||||
|
realin[i]=buf2[i]/32768.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=npoints; i<nfft1; i++) {
|
||||||
|
realin[i]=0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf2);
|
||||||
|
fftw_execute(PLAN1);
|
||||||
|
fftw_free(realin);
|
||||||
|
|
||||||
|
fftin=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*nfft2);
|
||||||
|
|
||||||
|
for (i=0; i<nfft2; i++) {
|
||||||
|
j=i0+i;
|
||||||
|
if( i>nh2 ) j=j-nfft2;
|
||||||
|
fftin[i][0]=fftout[j][0];
|
||||||
|
fftin[i][1]=fftout[j][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
fftw_free(fftout);
|
||||||
|
fftout=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*nfft2);
|
||||||
|
PLAN2 = fftw_plan_dft_1d(nfft2, fftin, fftout, FFTW_BACKWARD, PATIENCE);
|
||||||
|
fftw_execute(PLAN2);
|
||||||
|
|
||||||
|
for (i=0; i<nfft2; i++) {
|
||||||
|
idat[i]=fftout[i][0]/1000.0;
|
||||||
|
qdat[i]=fftout[i][1]/1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fftw_free(fftin);
|
||||||
|
fftw_free(fftout);
|
||||||
|
return nfft2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
void sync_and_demodulate(double *id, double *qd, long np,
|
||||||
|
unsigned char *symbols, float *f1, float fstep,
|
||||||
|
int *shift1, int lagmin, int lagmax, int lagstep,
|
||||||
|
float *drift1, int symfac, float *sync, int mode)
|
||||||
|
{
|
||||||
|
/***********************************************************************
|
||||||
|
* mode = 0: no frequency or drift search. find best time lag. *
|
||||||
|
* 1: no time lag or drift search. find best frequency. *
|
||||||
|
* 2: no frequency or time lag search. calculate soft-decision *
|
||||||
|
* symbols using passed frequency and shift. *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
float dt=1.0/375.0, df=375.0/256.0, fbest=0.0;
|
||||||
|
int i, j, k;
|
||||||
|
double pi=4.*atan(1.0),twopidt;
|
||||||
|
float f0=0.0,fp,fplast=-10000.0,ss;
|
||||||
|
int lag;
|
||||||
|
|
||||||
|
double i0[162],q0[162],i1[162],q1[162],i2[162],q2[162],i3[162],q3[162];
|
||||||
|
double p0,p1,p2,p3,cmet,totp,syncmax,fac;
|
||||||
|
double c0[256],s0[256],c1[256],s1[256],c2[256],s2[256],c3[256],s3[256];
|
||||||
|
double dphi0, cdphi0, sdphi0, dphi1, cdphi1, sdphi1, dphi2, cdphi2, sdphi2,
|
||||||
|
dphi3, cdphi3, sdphi3;
|
||||||
|
float fsum=0.0, f2sum=0.0, fsymb[162];
|
||||||
|
int best_shift = 0, ifreq;
|
||||||
|
int ifmin=0, ifmax=0;
|
||||||
|
|
||||||
|
syncmax=-1e30;
|
||||||
|
if( mode == 0 ) {ifmin=0; ifmax=0; fstep=0.0; f0=*f1;}
|
||||||
|
if( mode == 1 ) {lagmin=*shift1;lagmax=*shift1;ifmin=-5;ifmax=5;f0=*f1;}
|
||||||
|
if( mode == 2 ) {lagmin=*shift1;lagmax=*shift1;ifmin=0;ifmax=0;f0=*f1;}
|
||||||
|
|
||||||
|
twopidt=2*pi*dt;
|
||||||
|
for(ifreq=ifmin; ifreq<=ifmax; ifreq++) {
|
||||||
|
f0=*f1+ifreq*fstep;
|
||||||
|
for(lag=lagmin; lag<=lagmax; lag=lag+lagstep) {
|
||||||
|
ss=0.0;
|
||||||
|
totp=0.0;
|
||||||
|
for (i=0; i<162; i++) {
|
||||||
|
fp = f0 + ((float)*drift1/2.0)*((float)i-81.0)/81.0;
|
||||||
|
if( i==0 || (fp != fplast) ) { // only calculate sin/cos if necessary
|
||||||
|
dphi0=2*pi*(fp-1.5*df)*dt;
|
||||||
|
cdphi0=cos(dphi0);
|
||||||
|
sdphi0=sin(dphi0);
|
||||||
|
|
||||||
|
dphi1=twopidt*(fp-0.5*df);
|
||||||
|
cdphi1=cos(dphi1);
|
||||||
|
sdphi1=sin(dphi1);
|
||||||
|
|
||||||
|
dphi2=twopidt*(fp+0.5*df);
|
||||||
|
cdphi2=cos(dphi2);
|
||||||
|
sdphi2=sin(dphi2);
|
||||||
|
|
||||||
|
dphi3=twopidt*(fp+1.5*df);
|
||||||
|
cdphi3=cos(dphi3);
|
||||||
|
sdphi3=sin(dphi3);
|
||||||
|
|
||||||
|
c0[0]=1; s0[0]=0;
|
||||||
|
c1[0]=1; s1[0]=0;
|
||||||
|
c2[0]=1; s2[0]=0;
|
||||||
|
c3[0]=1; s3[0]=0;
|
||||||
|
|
||||||
|
for (j=1; j<256; j++) {
|
||||||
|
c0[j]=c0[j-1]*cdphi0 - s0[j-1]*sdphi0;
|
||||||
|
s0[j]=c0[j-1]*sdphi0 + s0[j-1]*cdphi0;
|
||||||
|
c1[j]=c1[j-1]*cdphi1 - s1[j-1]*sdphi1;
|
||||||
|
s1[j]=c1[j-1]*sdphi1 + s1[j-1]*cdphi1;
|
||||||
|
c2[j]=c2[j-1]*cdphi2 - s2[j-1]*sdphi2;
|
||||||
|
s2[j]=c2[j-1]*sdphi2 + s2[j-1]*cdphi2;
|
||||||
|
c3[j]=c3[j-1]*cdphi3 - s3[j-1]*sdphi3;
|
||||||
|
s3[j]=c3[j-1]*sdphi3 + s3[j-1]*cdphi3;
|
||||||
|
}
|
||||||
|
fplast = fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
i0[i]=0.0; q0[i]=0.0;
|
||||||
|
i1[i]=0.0; q1[i]=0.0;
|
||||||
|
i2[i]=0.0; q2[i]=0.0;
|
||||||
|
i3[i]=0.0; q3[i]=0.0;
|
||||||
|
|
||||||
|
for (j=0; j<256; j++) {
|
||||||
|
k=lag+i*256+j;
|
||||||
|
if( (k>0) & (k<np) ) {
|
||||||
|
i0[i]=i0[i] + id[k]*c0[j] + qd[k]*s0[j];
|
||||||
|
q0[i]=q0[i] - id[k]*s0[j] + qd[k]*c0[j];
|
||||||
|
i1[i]=i1[i] + id[k]*c1[j] + qd[k]*s1[j];
|
||||||
|
q1[i]=q1[i] - id[k]*s1[j] + qd[k]*c1[j];
|
||||||
|
i2[i]=i2[i] + id[k]*c2[j] + qd[k]*s2[j];
|
||||||
|
q2[i]=q2[i] - id[k]*s2[j] + qd[k]*c2[j];
|
||||||
|
i3[i]=i3[i] + id[k]*c3[j] + qd[k]*s3[j];
|
||||||
|
q3[i]=q3[i] - id[k]*s3[j] + qd[k]*c3[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p0=i0[i]*i0[i] + q0[i]*q0[i];
|
||||||
|
p1=i1[i]*i1[i] + q1[i]*q1[i];
|
||||||
|
p2=i2[i]*i2[i] + q2[i]*q2[i];
|
||||||
|
p3=i3[i]*i3[i] + q3[i]*q3[i];
|
||||||
|
|
||||||
|
p0=sqrt(p0);
|
||||||
|
p1=sqrt(p1);
|
||||||
|
p2=sqrt(p2);
|
||||||
|
p3=sqrt(p3);
|
||||||
|
|
||||||
|
totp=totp+p0+p1+p2+p3;
|
||||||
|
cmet=(p1+p3)-(p0+p2);
|
||||||
|
ss=ss+cmet*(2*pr3[i]-1);
|
||||||
|
if( mode == 2) { //Compute soft symbols
|
||||||
|
if(pr3[i]) {
|
||||||
|
fsymb[i]=p3-p1;
|
||||||
|
} else {
|
||||||
|
fsymb[i]=p2-p0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ss/totp > syncmax ) { //Save best parameters
|
||||||
|
syncmax=ss/totp;
|
||||||
|
best_shift=lag;
|
||||||
|
fbest=f0;
|
||||||
|
}
|
||||||
|
} // lag loop
|
||||||
|
} //freq loop
|
||||||
|
|
||||||
|
if( mode <=1 ) { //Send best params back to caller
|
||||||
|
*sync=syncmax;
|
||||||
|
*shift1=best_shift;
|
||||||
|
*f1=fbest;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mode == 2 ) {
|
||||||
|
*sync=syncmax;
|
||||||
|
for (i=0; i<162; i++) { //Normalize the soft symbols
|
||||||
|
fsum=fsum+fsymb[i]/162.0;
|
||||||
|
f2sum=f2sum+fsymb[i]*fsymb[i]/162.0;
|
||||||
|
}
|
||||||
|
fac=sqrt(f2sum-fsum*fsum);
|
||||||
|
for (i=0; i<162; i++) {
|
||||||
|
fsymb[i]=symfac*fsymb[i]/fac;
|
||||||
|
if( fsymb[i] > 127) fsymb[i]=127.0;
|
||||||
|
if( fsymb[i] < -128 ) fsymb[i]=-128.0;
|
||||||
|
symbols[i]=fsymb[i] + 128;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
void usage(void)
|
||||||
|
{
|
||||||
|
printf("Usage: wsprd [options...] infile\n");
|
||||||
|
printf(" infile must have suffix .wav or .c2\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -a <path> path to writeable data files, default=\".\"\n");
|
||||||
|
printf(" -e x (x is transceiver dial frequency error in Hz)\n");
|
||||||
|
printf(" -f x (x is transceiver dial frequency in MHz)\n");
|
||||||
|
// blanking is not yet implemented. The options are accepted for compatibility
|
||||||
|
// with development version of wsprd.
|
||||||
|
// printf(" -t n (n is blanking duration in milliseconds)\n");
|
||||||
|
// printf(" -b n (n is pct of time that is blanked)\n");
|
||||||
|
printf(" -H do not use (or update) the hash table\n");
|
||||||
|
printf(" -m decode wspr-15 .wav file\n");
|
||||||
|
printf(" -n write noise estimates to file noise.dat\n");
|
||||||
|
printf(" -q quick mode - doesn't dig deep for weak signals\n");
|
||||||
|
printf(" -s slow mode - much slower, yields a few more decodes\n");
|
||||||
|
printf(" -v verbose mode\n");
|
||||||
|
printf(" -w wideband mode - decode signals within +/- 150 Hz of center\n");
|
||||||
|
printf(" -z x (x is fano metric table bias, default is 0.42)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
extern char *optarg;
|
||||||
|
extern int optind;
|
||||||
|
int i,j,k;
|
||||||
|
unsigned char *symbols, *decdata;
|
||||||
|
signed char message[]={-9,13,-35,123,57,-39,64,0,0,0,0};
|
||||||
|
char *callsign,*grid,*grid6, *call_loc_pow, *cdbm;
|
||||||
|
char *ptr_to_infile,*ptr_to_infile_suffix;
|
||||||
|
char *data_dir=NULL;
|
||||||
|
char wisdom_fname[200],all_fname[200],spots_fname[200];
|
||||||
|
char timer_fname[200],hash_fname[200];
|
||||||
|
char uttime[5],date[7];
|
||||||
|
int c,delta,maxpts=65536,verbose=0,quickmode=0,writenoise=0,usehashtable=1,wspr_type=2;
|
||||||
|
int shift1, lagmin, lagmax, lagstep, worth_a_try, not_decoded;
|
||||||
|
unsigned int nbits;
|
||||||
|
unsigned int npoints, metric, maxcycles, cycles, maxnp;
|
||||||
|
float df=375.0/256.0/2;
|
||||||
|
float freq0[200],snr0[200],drift0[200],sync0[200];
|
||||||
|
int shift0[200];
|
||||||
|
float dt=1.0/375.0, dt_print;
|
||||||
|
double dialfreq_cmdline=0.0, dialfreq, freq_print;
|
||||||
|
float dialfreq_error=0.0;
|
||||||
|
float fmin=-110, fmax=110;
|
||||||
|
float f1, fstep, sync1, drift1, tblank=0, fblank=0;
|
||||||
|
double *idat, *qdat;
|
||||||
|
clock_t t0,t00;
|
||||||
|
double tfano=0.0,treadwav=0.0,tcandidates=0.0,tsync0=0.0;
|
||||||
|
double tsync1=0.0,tsync2=0.0,ttotal=0.0;
|
||||||
|
|
||||||
|
// Parameters used for performance-tuning:
|
||||||
|
maxcycles=10000; //Fano timeout limit
|
||||||
|
double minsync1=0.10; //First sync limit
|
||||||
|
double minsync2=0.12; //Second sync limit
|
||||||
|
int iifac=3; //Step size in final DT peakup
|
||||||
|
int symfac=50; //Soft-symbol normalizing factor
|
||||||
|
int maxdrift=4; //Maximum (+/-) drift
|
||||||
|
double minrms=52.0 * (symfac/64.0); //Final test for plausible decoding
|
||||||
|
delta=60; //Fano threshold step
|
||||||
|
|
||||||
|
t00=clock();
|
||||||
|
fftw_complex *fftin, *fftout;
|
||||||
|
#include "./metric_tables.c"
|
||||||
|
|
||||||
|
int mettab[2][256];
|
||||||
|
float bias=0.42;
|
||||||
|
|
||||||
|
idat=malloc(sizeof(double)*maxpts);
|
||||||
|
qdat=malloc(sizeof(double)*maxpts);
|
||||||
|
|
||||||
|
while ( (c = getopt(argc, argv, "a:b:e:f:Hmnqst:wvz:")) !=-1 ) {
|
||||||
|
switch (c) {
|
||||||
|
case 'a':
|
||||||
|
data_dir = optarg;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
fblank = strtof(optarg,NULL);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
dialfreq_error = strtof(optarg,NULL); // units of Hz
|
||||||
|
// dialfreq_error = dial reading - actual, correct frequency
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
dialfreq_cmdline = strtod(optarg,NULL); // units of MHz
|
||||||
|
break;
|
||||||
|
case 'H':
|
||||||
|
usehashtable = 0;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
wspr_type = 15;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
writenoise = 1;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
quickmode = 1;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
maxcycles=20000;
|
||||||
|
iifac=1;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
tblank = strtof(optarg,NULL);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
fmin=-150.0;
|
||||||
|
fmax=150.0;
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
bias=strtof(optarg,NULL); //fano metric bias (default is 0.42)
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
usage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( optind+1 > argc) {
|
||||||
|
usage();
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
ptr_to_infile=argv[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup metric table
|
||||||
|
for(i=0; i<256; i++) {
|
||||||
|
mettab[0][i]=round( 10*(metric_tables[2][i]-bias) );
|
||||||
|
mettab[1][i]=round( 10*(metric_tables[2][255-i]-bias) );
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp_fftw_wisdom_file, *fall_wspr, *fwsprd, *fhash, *ftimer;
|
||||||
|
strcpy(wisdom_fname,".");
|
||||||
|
strcpy(all_fname,".");
|
||||||
|
strcpy(spots_fname,".");
|
||||||
|
strcpy(timer_fname,".");
|
||||||
|
strcpy(hash_fname,".");
|
||||||
|
if(data_dir != NULL) {
|
||||||
|
strcpy(wisdom_fname,data_dir);
|
||||||
|
strcpy(all_fname,data_dir);
|
||||||
|
strcpy(spots_fname,data_dir);
|
||||||
|
strcpy(timer_fname,data_dir);
|
||||||
|
strcpy(hash_fname,data_dir);
|
||||||
|
}
|
||||||
|
strncat(wisdom_fname,"/wspr_wisdom.dat",20);
|
||||||
|
strncat(all_fname,"/ALL_WSPR.TXT",20);
|
||||||
|
strncat(spots_fname,"/wspr_spots.txt",20);
|
||||||
|
strncat(timer_fname,"/wspr_timer.out",20);
|
||||||
|
strncat(hash_fname,"/hashtable.txt",20);
|
||||||
|
if ((fp_fftw_wisdom_file = fopen(wisdom_fname, "r"))) { //Open FFTW wisdom
|
||||||
|
fftw_import_wisdom_from_file(fp_fftw_wisdom_file);
|
||||||
|
fclose(fp_fftw_wisdom_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fall_wspr=fopen(all_fname,"a");
|
||||||
|
fwsprd=fopen(spots_fname,"w");
|
||||||
|
// FILE *fdiag;
|
||||||
|
// fdiag=fopen("wsprd_diag","a");
|
||||||
|
|
||||||
|
if((ftimer=fopen(timer_fname,"r"))) {
|
||||||
|
//Accumulate timing data
|
||||||
|
nr=fscanf(ftimer,"%lf %lf %lf %lf %lf %lf %lf",
|
||||||
|
&treadwav,&tcandidates,&tsync0,&tsync1,&tsync2,&tfano,&ttotal);
|
||||||
|
fclose(ftimer);
|
||||||
|
}
|
||||||
|
ftimer=fopen(timer_fname,"w");
|
||||||
|
|
||||||
|
if( strstr(ptr_to_infile,".wav") ) {
|
||||||
|
ptr_to_infile_suffix=strstr(ptr_to_infile,".wav");
|
||||||
|
|
||||||
|
t0 = clock();
|
||||||
|
npoints=readwavfile(ptr_to_infile, wspr_type, idat, qdat);
|
||||||
|
treadwav += (double)(clock()-t0)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
if( npoints == 1 ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dialfreq=dialfreq_cmdline - (dialfreq_error*1.0e-06);
|
||||||
|
} else if ( strstr(ptr_to_infile,".c2") !=0 ) {
|
||||||
|
ptr_to_infile_suffix=strstr(ptr_to_infile,".c2");
|
||||||
|
npoints=readc2file(ptr_to_infile, idat, qdat, &dialfreq, &wspr_type);
|
||||||
|
if( npoints == 1 ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dialfreq -= (dialfreq_error*1.0e-06);
|
||||||
|
} else {
|
||||||
|
printf("Error: Failed to open %s\n",ptr_to_infile);
|
||||||
|
printf("WSPR file must have suffix .wav or .c2\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse date and time from given filename
|
||||||
|
strncpy(date,ptr_to_infile_suffix-11,6);
|
||||||
|
strncpy(uttime,ptr_to_infile_suffix-4,4);
|
||||||
|
date[6]='\0';
|
||||||
|
uttime[4]='\0';
|
||||||
|
|
||||||
|
// Do windowed ffts over 2 symbols, stepped by half symbols
|
||||||
|
int nffts=4*floor(npoints/512)-1;
|
||||||
|
fftin=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*512);
|
||||||
|
fftout=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*512);
|
||||||
|
PLAN3 = fftw_plan_dft_1d(512, fftin, fftout, FFTW_FORWARD, PATIENCE);
|
||||||
|
|
||||||
|
float ps[512][nffts];
|
||||||
|
float w[512];
|
||||||
|
for(i=0; i<512; i++) {
|
||||||
|
w[i]=sin(0.006147931*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(ps,0.0, sizeof(float)*512*nffts);
|
||||||
|
for (i=0; i<nffts; i++) {
|
||||||
|
for(j=0; j<512; j++ ) {
|
||||||
|
k=i*128+j;
|
||||||
|
fftin[j][0]=idat[k] * w[j];
|
||||||
|
fftin[j][1]=qdat[k] * w[j];
|
||||||
|
}
|
||||||
|
fftw_execute(PLAN3);
|
||||||
|
for (j=0; j<512; j++ ) {
|
||||||
|
k=j+256;
|
||||||
|
if( k>511 )
|
||||||
|
k=k-512;
|
||||||
|
ps[j][i]=fftout[k][0]*fftout[k][0]+fftout[k][1]*fftout[k][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fftw_free(fftin);
|
||||||
|
fftw_free(fftout);
|
||||||
|
|
||||||
|
// Compute average spectrum
|
||||||
|
float psavg[512];
|
||||||
|
memset(psavg,0.0, sizeof(float)*512);
|
||||||
|
for (i=0; i<nffts; i++) {
|
||||||
|
for (j=0; j<512; j++) {
|
||||||
|
psavg[j]=psavg[j]+ps[j][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smooth with 7-point window and limit spectrum to +/-150 Hz
|
||||||
|
int window[7]={1,1,1,1,1,1,1};
|
||||||
|
float smspec[411];
|
||||||
|
for (i=0; i<411; i++) {
|
||||||
|
smspec[i]=0.0;
|
||||||
|
for(j=-3; j<=3; j++) {
|
||||||
|
k=256-205+i+j;
|
||||||
|
smspec[i]=smspec[i]+window[j+3]*psavg[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort spectrum values, then pick off noise level as a percentile
|
||||||
|
float tmpsort[411];
|
||||||
|
for (j=0; j<411; j++) {
|
||||||
|
tmpsort[j]=smspec[j];
|
||||||
|
}
|
||||||
|
qsort(tmpsort, 411, sizeof(float), floatcomp);
|
||||||
|
|
||||||
|
// Noise level of spectrum is estimated as 123/411= 30'th percentile
|
||||||
|
float noise_level = tmpsort[122];
|
||||||
|
|
||||||
|
/* Renormalize spectrum so that (large) peaks represent an estimate of snr.
|
||||||
|
* We know from experience that threshold snr is near -7dB in wspr bandwidth,
|
||||||
|
* corresponding to -7-26.3=-33.3dB in 2500 Hz bandwidth.
|
||||||
|
* The corresponding threshold is -42.3 dB in 2500 Hz bandwidth for WSPR-15. */
|
||||||
|
|
||||||
|
float min_snr, snr_scaling_factor;
|
||||||
|
min_snr = pow(10.0,-7.0/10.0); //this is min snr in wspr bw
|
||||||
|
if( wspr_type == 2 ) {
|
||||||
|
snr_scaling_factor=26.3;
|
||||||
|
} else {
|
||||||
|
snr_scaling_factor=35.3;
|
||||||
|
}
|
||||||
|
for (j=0; j<411; j++) {
|
||||||
|
smspec[j]=smspec[j]/noise_level - 1.0;
|
||||||
|
if( smspec[j] < min_snr) smspec[j]=0.1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all local maxima in smoothed spectrum.
|
||||||
|
for (i=0; i<200; i++) {
|
||||||
|
freq0[i]=0.0;
|
||||||
|
snr0[i]=0.0;
|
||||||
|
drift0[i]=0.0;
|
||||||
|
shift0[i]=0;
|
||||||
|
sync0[i]=0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int npk=0;
|
||||||
|
for(j=1; j<410; j++) {
|
||||||
|
if((smspec[j]>smspec[j-1]) && (smspec[j]>smspec[j+1]) && (npk<200)) {
|
||||||
|
freq0[npk]=(j-205)*df;
|
||||||
|
snr0[npk]=10*log10(smspec[j])-snr_scaling_factor;
|
||||||
|
npk++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute corrected fmin, fmax, accounting for dial frequency error
|
||||||
|
fmin += dialfreq_error; // dialfreq_error is in units of Hz
|
||||||
|
fmax += dialfreq_error;
|
||||||
|
|
||||||
|
// Don't waste time on signals outside of the range [fmin,fmax].
|
||||||
|
i=0;
|
||||||
|
for( j=0; j<npk; j++) {
|
||||||
|
if( freq0[j] >= fmin && freq0[j] <= fmax ) {
|
||||||
|
freq0[i]=freq0[j];
|
||||||
|
snr0[i]=snr0[j];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
npk=i;
|
||||||
|
|
||||||
|
t0=clock();
|
||||||
|
/* Make coarse estimates of shift (DT), freq, and drift
|
||||||
|
|
||||||
|
* Look for time offsets up to +/- 8 symbols (about +/- 5.4 s) relative
|
||||||
|
to nominal start time, which is 2 seconds into the file
|
||||||
|
|
||||||
|
* Calculates shift relative to the beginning of the file
|
||||||
|
|
||||||
|
* Negative shifts mean that signal started before start of file
|
||||||
|
|
||||||
|
* The program prints DT = shift-2 s
|
||||||
|
|
||||||
|
* Shifts that cause sync vector to fall off of either end of the data
|
||||||
|
vector are accommodated by "partial decoding", such that missing
|
||||||
|
symbols produce a soft-decision symbol value of 128
|
||||||
|
|
||||||
|
* The frequency drift model is linear, deviation of +/- drift/2 over the
|
||||||
|
span of 162 symbols, with deviation equal to 0 at the center of the
|
||||||
|
signal vector.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int idrift,ifr,if0,ifd,k0;
|
||||||
|
int kindex;
|
||||||
|
float smax,ss,pow,p0,p1,p2,p3;
|
||||||
|
for(j=0; j<npk; j++) { //For each candidate...
|
||||||
|
smax=-1e30;
|
||||||
|
if0=freq0[j]/df+256;
|
||||||
|
for (ifr=if0-1; ifr<=if0+1; ifr++) { //Freq search
|
||||||
|
for( k0=-10; k0<22; k0++) { //Time search
|
||||||
|
for (idrift=-maxdrift; idrift<=maxdrift; idrift++) { //Drift search
|
||||||
|
ss=0.0;
|
||||||
|
pow=0.0;
|
||||||
|
for (k=0; k<162; k++) { //Sum over symbols
|
||||||
|
ifd=ifr+((float)k-81.0)/81.0*( (float)idrift )/(2.0*df);
|
||||||
|
kindex=k0+2*k;
|
||||||
|
if( kindex < nffts ) {
|
||||||
|
p0=ps[ifd-3][kindex];
|
||||||
|
p1=ps[ifd-1][kindex];
|
||||||
|
p2=ps[ifd+1][kindex];
|
||||||
|
p3=ps[ifd+3][kindex];
|
||||||
|
|
||||||
|
p0=sqrt(p0);
|
||||||
|
p1=sqrt(p1);
|
||||||
|
p2=sqrt(p2);
|
||||||
|
p3=sqrt(p3);
|
||||||
|
|
||||||
|
ss=ss+(2*pr3[k]-1)*((p1+p3)-(p0+p2));
|
||||||
|
pow=pow+p0+p1+p2+p3;
|
||||||
|
sync1=ss/pow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( sync1 > smax ) { //Save coarse parameters
|
||||||
|
smax=sync1;
|
||||||
|
shift0[j]=128*(k0+1);
|
||||||
|
drift0[j]=idrift;
|
||||||
|
freq0[j]=(ifr-256)*df;
|
||||||
|
sync0[j]=sync1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tcandidates += (double)(clock()-t0)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
nbits=81;
|
||||||
|
symbols=malloc(sizeof(char)*nbits*2);
|
||||||
|
memset(symbols,0,sizeof(char)*nbits*2);
|
||||||
|
decdata=malloc((nbits+7)/8);
|
||||||
|
grid=malloc(sizeof(char)*5);
|
||||||
|
grid6=malloc(sizeof(char)*7);
|
||||||
|
callsign=malloc(sizeof(char)*13);
|
||||||
|
call_loc_pow=malloc(sizeof(char)*23);
|
||||||
|
cdbm=malloc(sizeof(char)*3);
|
||||||
|
float allfreqs[npk];
|
||||||
|
memset(allfreqs,0,sizeof(float)*npk);
|
||||||
|
char allcalls[npk][13];
|
||||||
|
memset(allcalls,0,sizeof(char)*npk*13);
|
||||||
|
memset(grid,0,sizeof(char)*5);
|
||||||
|
memset(grid6,0,sizeof(char)*7);
|
||||||
|
memset(callsign,0,sizeof(char)*13);
|
||||||
|
memset(call_loc_pow,0,sizeof(char)*23);
|
||||||
|
memset(cdbm,0,sizeof(char)*3);
|
||||||
|
char hashtab[32768][13];
|
||||||
|
memset(hashtab,0,sizeof(char)*32768*13);
|
||||||
|
uint32_t nhash_( const void *, size_t, uint32_t);
|
||||||
|
int nh;
|
||||||
|
|
||||||
|
if( usehashtable ) {
|
||||||
|
char line[80], hcall[12];
|
||||||
|
if( (fhash=fopen(hash_fname,"r+")) ) {
|
||||||
|
while (fgets(line, sizeof(line), fhash) != NULL) {
|
||||||
|
sscanf(line,"%d %s",&nh,hcall);
|
||||||
|
strcpy(*hashtab+nh*13,hcall);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fhash=fopen(hash_fname,"w+");
|
||||||
|
}
|
||||||
|
fclose(fhash);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uniques=0, noprint=0;
|
||||||
|
/*
|
||||||
|
Refine the estimates of freq, shift using sync as a metric.
|
||||||
|
Sync is calculated such that it is a float taking values in the range
|
||||||
|
[0.0,1.0].
|
||||||
|
|
||||||
|
Function sync_and_demodulate has three modes of operation
|
||||||
|
mode is the last argument:
|
||||||
|
|
||||||
|
0 = no frequency or drift search. find best time lag.
|
||||||
|
1 = no time lag or drift search. find best frequency.
|
||||||
|
2 = no frequency or time lag search. Calculate soft-decision
|
||||||
|
symbols using passed frequency and shift.
|
||||||
|
|
||||||
|
NB: best possibility for OpenMP may be here: several worker threads
|
||||||
|
could each work on one candidate at a time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (j=0; j<npk; j++) {
|
||||||
|
f1=freq0[j];
|
||||||
|
drift1=drift0[j];
|
||||||
|
shift1=shift0[j];
|
||||||
|
sync1=sync0[j];
|
||||||
|
|
||||||
|
// Fine search for best sync lag (mode 0)
|
||||||
|
fstep=0.0;
|
||||||
|
lagmin=shift1-144;
|
||||||
|
lagmax=shift1+144;
|
||||||
|
lagstep=8;
|
||||||
|
if(quickmode) lagstep=16;
|
||||||
|
t0 = clock();
|
||||||
|
sync_and_demodulate(idat, qdat, npoints, symbols, &f1, fstep, &shift1,
|
||||||
|
lagmin, lagmax, lagstep, &drift1, symfac, &sync1, 0);
|
||||||
|
tsync0 += (double)(clock()-t0)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
// Fine search for frequency peak (mode 1)
|
||||||
|
fstep=0.1;
|
||||||
|
t0 = clock();
|
||||||
|
sync_and_demodulate(idat, qdat, npoints, symbols, &f1, fstep, &shift1,
|
||||||
|
lagmin, lagmax, lagstep, &drift1, symfac, &sync1, 1);
|
||||||
|
tsync1 += (double)(clock()-t0)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
if( sync1 > minsync1 ) {
|
||||||
|
worth_a_try = 1;
|
||||||
|
} else {
|
||||||
|
worth_a_try = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int idt=0, ii=0, jiggered_shift;
|
||||||
|
double y,sq,rms;
|
||||||
|
not_decoded=1;
|
||||||
|
|
||||||
|
while ( worth_a_try && not_decoded && idt<=(128/iifac)) {
|
||||||
|
ii=(idt+1)/2;
|
||||||
|
if( idt%2 == 1 ) ii=-ii;
|
||||||
|
ii=iifac*ii;
|
||||||
|
jiggered_shift=shift1+ii;
|
||||||
|
|
||||||
|
// Use mode 2 to get soft-decision symbols
|
||||||
|
t0 = clock();
|
||||||
|
sync_and_demodulate(idat, qdat, npoints, symbols, &f1, fstep,
|
||||||
|
&jiggered_shift, lagmin, lagmax, lagstep, &drift1, symfac,
|
||||||
|
&sync1, 2);
|
||||||
|
tsync2 += (double)(clock()-t0)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
sq=0.0;
|
||||||
|
for(i=0; i<162; i++) {
|
||||||
|
y=(double)symbols[i] - 128.0;
|
||||||
|
sq += y*y;
|
||||||
|
}
|
||||||
|
rms=sqrt(sq/162.0);
|
||||||
|
|
||||||
|
if((sync1 > minsync2) && (rms > minrms)) {
|
||||||
|
deinterleave(symbols);
|
||||||
|
t0 = clock();
|
||||||
|
not_decoded = fano(&metric,&cycles,&maxnp,decdata,symbols,nbits,
|
||||||
|
mettab,delta,maxcycles);
|
||||||
|
tfano += (double)(clock()-t0)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
/* ### Used for timing tests:
|
||||||
|
if(not_decoded) fprintf(fdiag,
|
||||||
|
"%6s %4s %4.1f %3.0f %4.1f %10.7f %-18s %2d %5u %4d %6.1f %2d\n",
|
||||||
|
date,uttime,sync1*10,snr0[j], shift1*dt-2.0, dialfreq+(1500+f1)/1e6,
|
||||||
|
"@ ", (int)drift1, cycles/81, ii, rms, maxnp);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
idt++;
|
||||||
|
if( quickmode ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( worth_a_try && !not_decoded ) {
|
||||||
|
for(i=0; i<11; i++) {
|
||||||
|
if( decdata[i]>127 ) {
|
||||||
|
message[i]=decdata[i]-256;
|
||||||
|
} else {
|
||||||
|
message[i]=decdata[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack the decoded message, update the hashtable, apply
|
||||||
|
// sanity checks on grid and power, and return
|
||||||
|
// call_loc_pow string and also callsign (for de-duping).
|
||||||
|
noprint=unpk_(message,hashtab,call_loc_pow,callsign);
|
||||||
|
|
||||||
|
// Remove dupes (same callsign and freq within 1 Hz)
|
||||||
|
int dupe=0;
|
||||||
|
for (i=0; i<npk; i++) {
|
||||||
|
if(!strcmp(callsign,allcalls[i]) &&
|
||||||
|
(fabs(f1-allfreqs[i]) <1.0)) dupe=1;
|
||||||
|
}
|
||||||
|
if( (verbose || !dupe) && !noprint) {
|
||||||
|
uniques++;
|
||||||
|
strcpy(allcalls[uniques],callsign);
|
||||||
|
allfreqs[uniques]=f1;
|
||||||
|
// Add an extra space at the end of each line so that wspr-x doesn't
|
||||||
|
// truncate the power (TNX to DL8FCL!)
|
||||||
|
|
||||||
|
if( wspr_type == 15 ) {
|
||||||
|
freq_print=dialfreq+(1500+112.5+f1/8.0)/1e6;
|
||||||
|
dt_print=shift1*8*dt-2.0;
|
||||||
|
} else {
|
||||||
|
freq_print=dialfreq+(1500+f1)/1e6;
|
||||||
|
dt_print=shift1*dt-2.0;
|
||||||
|
}
|
||||||
|
printf("%4s %3.0f %4.1f %10.6f %2d %-s \n",
|
||||||
|
uttime, snr0[j],dt_print,freq_print,
|
||||||
|
(int)drift1, call_loc_pow);
|
||||||
|
|
||||||
|
fprintf(fall_wspr,
|
||||||
|
"%6s %4s %3.0f %3.0f %4.1f %10.7f %-22s %2d %5u %4d\n",
|
||||||
|
date,uttime,sync1*10,snr0[j],
|
||||||
|
dt_print, freq_print,
|
||||||
|
call_loc_pow, (int)drift1, cycles/81, ii);
|
||||||
|
|
||||||
|
fprintf(fwsprd,"%6s %4s %3d %3.0f %4.1f %10.6f %-22s %2d %5u %4d\n",
|
||||||
|
date,uttime,(int)(sync1*10),snr0[j],
|
||||||
|
dt_print, freq_print,
|
||||||
|
call_loc_pow, (int)drift1, cycles/81, ii);
|
||||||
|
|
||||||
|
/* For timing tests
|
||||||
|
|
||||||
|
fprintf(fdiag,
|
||||||
|
"%6s %4s %4.1f %3.0f %4.1f %10.7f %-18s %2d %5u %4d %6.1f\n",
|
||||||
|
date,uttime,sync1*10,snr0[j],
|
||||||
|
shift1*dt-2.0, dialfreq+(1500+f1)/1e6,
|
||||||
|
call_loc_pow, (int)drift1, cycles/81, ii, rms);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("<DecodeFinished>\n");
|
||||||
|
|
||||||
|
if ((fp_fftw_wisdom_file = fopen(wisdom_fname, "w"))) {
|
||||||
|
fftw_export_wisdom_to_file(fp_fftw_wisdom_file);
|
||||||
|
fclose(fp_fftw_wisdom_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
ttotal += (double)(clock()-t00)/CLOCKS_PER_SEC;
|
||||||
|
|
||||||
|
fprintf(ftimer,"%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n\n",
|
||||||
|
treadwav,tcandidates,tsync0,tsync1,tsync2,tfano,ttotal);
|
||||||
|
|
||||||
|
fprintf(ftimer,"Code segment Seconds Frac\n");
|
||||||
|
fprintf(ftimer,"-----------------------------------\n");
|
||||||
|
fprintf(ftimer,"readwavfile %7.2f %7.2f\n",treadwav,treadwav/ttotal);
|
||||||
|
fprintf(ftimer,"Coarse DT f0 f1 %7.2f %7.2f\n",tcandidates,
|
||||||
|
tcandidates/ttotal);
|
||||||
|
fprintf(ftimer,"sync_and_demod(0) %7.2f %7.2f\n",tsync0,tsync0/ttotal);
|
||||||
|
fprintf(ftimer,"sync_and_demod(1) %7.2f %7.2f\n",tsync1,tsync1/ttotal);
|
||||||
|
fprintf(ftimer,"sync_and_demod(2) %7.2f %7.2f\n",tsync2,tsync2/ttotal);
|
||||||
|
fprintf(ftimer,"Fano decoder %7.2f %7.2f\n",tfano,tfano/ttotal);
|
||||||
|
fprintf(ftimer,"-----------------------------------\n");
|
||||||
|
fprintf(ftimer,"Total %7.2f %7.2f\n",ttotal,1.0);
|
||||||
|
|
||||||
|
fclose(fall_wspr);
|
||||||
|
fclose(fwsprd);
|
||||||
|
// fclose(fdiag);
|
||||||
|
fclose(ftimer);
|
||||||
|
fftw_destroy_plan(PLAN1);
|
||||||
|
fftw_destroy_plan(PLAN2);
|
||||||
|
fftw_destroy_plan(PLAN3);
|
||||||
|
|
||||||
|
if( usehashtable ) {
|
||||||
|
fhash=fopen(hash_fname,"w");
|
||||||
|
for (i=0; i<32768; i++) {
|
||||||
|
if( strncmp(hashtab[i],"\0",1) != 0 ) {
|
||||||
|
fprintf(fhash,"%5d %s\n",i,*hashtab+i*13);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fhash);
|
||||||
|
}
|
||||||
|
if(fblank+tblank+writenoise == 999) return -1; //Silence compiler warning
|
||||||
|
return 0;
|
||||||
|
}
|
24
lib/wsprd/wsprd_stats.txt
Normal file
24
lib/wsprd/wsprd_stats.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
Linux Windows
|
||||||
|
Program Time Decodes Time Decodes
|
||||||
|
-------------------------------------------------
|
||||||
|
wsprd (Mar 2013) 2413 1451 2718 1451
|
||||||
|
|
||||||
|
k9an-wsprd 1800 2122
|
||||||
|
k9an_wsprd -q 354 1939
|
||||||
|
|
||||||
|
wsprd 399 2190 356 2190
|
||||||
|
wsprd -q 214 2034 192 2034
|
||||||
|
|
||||||
|
wsprd* 1240 2215
|
||||||
|
wsprd# 1599 2220
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
* maxcycles=30000
|
||||||
|
# maxcycles=20000, iifac=1
|
||||||
|
-------------------------------------------------
|
||||||
|
Test data: 638 *.wav files (recorded by WSJT-X)
|
||||||
|
-------------------------------------------------
|
||||||
|
Linux machine: Core 2 Duo, E6750 CPU
|
||||||
|
Windows machine: 4-Core i5-2500 CPU
|
||||||
|
wsprd git commit: eecc274
|
||||||
|
-------------------------------------------------
|
322
lib/wsprd/wsprd_utils.c
Normal file
322
lib/wsprd/wsprd_utils.c
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/*
|
||||||
|
This file is part of program wsprd, a detector/demodulator/decoder
|
||||||
|
for the Weak Signal Propagation Reporter (WSPR) mode.
|
||||||
|
|
||||||
|
File name: wsprd_utils.c
|
||||||
|
|
||||||
|
Copyright 2001-2015, Joe Taylor, K1JT
|
||||||
|
|
||||||
|
Most of the code is based on work by Steven Franke, K9AN, which
|
||||||
|
in turn was based on earlier work by K1JT.
|
||||||
|
|
||||||
|
Copyright 2014-2015, Steven Franke, K9AN
|
||||||
|
|
||||||
|
License: GNU GPL v3
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "wsprd_utils.h"
|
||||||
|
|
||||||
|
#ifndef int32_t
|
||||||
|
#define int32_t int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void unpack50( signed char *dat, int32_t *n1, int32_t *n2 )
|
||||||
|
{
|
||||||
|
int32_t i,i4;
|
||||||
|
|
||||||
|
i=dat[0];
|
||||||
|
i4=i&255;
|
||||||
|
*n1=i4<<20;
|
||||||
|
|
||||||
|
i=dat[1];
|
||||||
|
i4=i&255;
|
||||||
|
*n1=*n1+(i4<<12);
|
||||||
|
|
||||||
|
i=dat[2];
|
||||||
|
i4=i&255;
|
||||||
|
*n1=*n1+(i4<<4);
|
||||||
|
|
||||||
|
i=dat[3];
|
||||||
|
i4=i&255;
|
||||||
|
*n1=*n1+((i4>>4)&15);
|
||||||
|
*n2=(i4&15)<<18;
|
||||||
|
|
||||||
|
i=dat[4];
|
||||||
|
i4=i&255;
|
||||||
|
*n2=*n2+(i4<<10);
|
||||||
|
|
||||||
|
i=dat[5];
|
||||||
|
i4=i&255;
|
||||||
|
*n2=*n2+(i4<<2);
|
||||||
|
|
||||||
|
i=dat[6];
|
||||||
|
i4=i&255;
|
||||||
|
*n2=*n2+((i4>>6)&3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpackcall( int32_t ncall, char *call )
|
||||||
|
{
|
||||||
|
char c[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E',
|
||||||
|
'F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
|
||||||
|
'U','V','W','X','Y','Z',' '};
|
||||||
|
int32_t n;
|
||||||
|
int i;
|
||||||
|
char tmp[7];
|
||||||
|
|
||||||
|
n=ncall;
|
||||||
|
strcpy(call,"......");
|
||||||
|
if (n < 262177560 ) {
|
||||||
|
i=n%27+10;
|
||||||
|
tmp[5]=c[i];
|
||||||
|
n=n/27;
|
||||||
|
i=n%27+10;
|
||||||
|
tmp[4]=c[i];
|
||||||
|
n=n/27;
|
||||||
|
i=n%27+10;
|
||||||
|
tmp[3]=c[i];
|
||||||
|
n=n/27;
|
||||||
|
i=n%10;
|
||||||
|
tmp[2]=c[i];
|
||||||
|
n=n/10;
|
||||||
|
i=n%36;
|
||||||
|
tmp[1]=c[i];
|
||||||
|
n=n/36;
|
||||||
|
i=n;
|
||||||
|
tmp[0]=c[i];
|
||||||
|
tmp[6]='\0';
|
||||||
|
// remove leading whitespace
|
||||||
|
for(i=0; i<5; i++) {
|
||||||
|
if( tmp[i] != c[36] )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sprintf(call,"%-6s",&tmp[i]);
|
||||||
|
// remove trailing whitespace
|
||||||
|
for(i=0; i<6; i++) {
|
||||||
|
if( call[i] == c[36] ) {
|
||||||
|
call[i]='\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpackgrid( int32_t ngrid, char *grid)
|
||||||
|
{
|
||||||
|
char c[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E',
|
||||||
|
'F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
|
||||||
|
'U','V','W','X','Y','Z',' '};
|
||||||
|
int dlat, dlong;
|
||||||
|
|
||||||
|
ngrid=ngrid>>7;
|
||||||
|
if( ngrid < 32400 ) {
|
||||||
|
dlat=(ngrid%180)-90;
|
||||||
|
dlong=(ngrid/180)*2 - 180 + 2;
|
||||||
|
if( dlong < -180 )
|
||||||
|
dlong=dlong+360;
|
||||||
|
if( dlong > 180 )
|
||||||
|
dlong=dlong+360;
|
||||||
|
int nlong = 60.0*(180.0-dlong)/5.0;
|
||||||
|
int n1 = nlong/240;
|
||||||
|
int n2 = (nlong - 240*n1)/24;
|
||||||
|
grid[0] = c[10+n1];
|
||||||
|
grid[2]= c[n2];
|
||||||
|
|
||||||
|
int nlat = 60.0*(dlat+90)/2.5;
|
||||||
|
n1 = nlat/240;
|
||||||
|
n2 = (nlat-240*n1)/24;
|
||||||
|
grid[1]=c[10+n1];
|
||||||
|
grid[3]=c[n2];
|
||||||
|
} else {
|
||||||
|
strcpy(grid,"XXXX");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpackpfx( int32_t nprefix, char *call)
|
||||||
|
{
|
||||||
|
char nc, pfx[4]="", tmpcall[7]="";
|
||||||
|
int i;
|
||||||
|
int32_t n;
|
||||||
|
|
||||||
|
strcpy(tmpcall,call);
|
||||||
|
|
||||||
|
if( nprefix < 60000 ) {
|
||||||
|
// add a prefix of 1 to 3 characters
|
||||||
|
n=nprefix;
|
||||||
|
for (i=2; i>=0; i--) {
|
||||||
|
nc=n%37;
|
||||||
|
if( (nc >= 0) & (nc <= 9) ) {
|
||||||
|
pfx[i]=nc+48;
|
||||||
|
}
|
||||||
|
else if( (nc >= 10) & (nc <= 35) ) {
|
||||||
|
pfx[i]=nc+55;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pfx[i]=' ';
|
||||||
|
}
|
||||||
|
n=n/37;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(call,pfx);
|
||||||
|
strncat(call,"/",1);
|
||||||
|
strncat(call,tmpcall,strlen(tmpcall));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// add a suffix of 1 or 2 characters
|
||||||
|
nc=nprefix-60000;
|
||||||
|
if( (nc >= 0) & (nc <= 9) ) {
|
||||||
|
pfx[0]=nc+48;
|
||||||
|
strcpy(call,tmpcall);
|
||||||
|
strncat(call,"/",1);
|
||||||
|
strncat(call,pfx,1);
|
||||||
|
}
|
||||||
|
else if( (nc >= 10) & (nc <= 35) ) {
|
||||||
|
pfx[0]=nc+55;
|
||||||
|
strcpy(call,tmpcall);
|
||||||
|
strncat(call,"/",1);
|
||||||
|
strncat(call,pfx,1);
|
||||||
|
}
|
||||||
|
else if( (nc >= 36) & (nc <= 125) ) {
|
||||||
|
pfx[0]=(nc-26)/10+48;
|
||||||
|
pfx[1]=(nc-26)%10+48;
|
||||||
|
strcpy(call,tmpcall);
|
||||||
|
strncat(call,"/",1);
|
||||||
|
strncat(call,pfx,2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deinterleave(unsigned char *sym)
|
||||||
|
{
|
||||||
|
unsigned char tmp[162];
|
||||||
|
unsigned char p, i, j;
|
||||||
|
|
||||||
|
p=0;
|
||||||
|
i=0;
|
||||||
|
while (p<162) {
|
||||||
|
j=((i * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
|
||||||
|
if (j < 162 ) {
|
||||||
|
tmp[p]=sym[j];
|
||||||
|
p=p+1;
|
||||||
|
}
|
||||||
|
i=i+1;
|
||||||
|
}
|
||||||
|
for (i=0; i<162; i++) {
|
||||||
|
sym[i]=tmp[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// used by qsort
|
||||||
|
int floatcomp(const void* elem1, const void* elem2)
|
||||||
|
{
|
||||||
|
if(*(const float*)elem1 < *(const float*)elem2)
|
||||||
|
return -1;
|
||||||
|
return *(const float*)elem1 > *(const float*)elem2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unpk_(signed char *message, char hashtab[32768][13], char *call_loc_pow, char *callsign)
|
||||||
|
{
|
||||||
|
int n1,n2,n3,ndbm,ihash,nadd,noprint=0;
|
||||||
|
char grid[5],grid6[7],cdbm[3];
|
||||||
|
|
||||||
|
unpack50(message,&n1,&n2);
|
||||||
|
unpackcall(n1,callsign);
|
||||||
|
unpackgrid(n2, grid);
|
||||||
|
int ntype = (n2&127) - 64;
|
||||||
|
callsign[12]=0;
|
||||||
|
grid[4]=0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Based on the value of ntype, decide whether this is a Type 1, 2, or
|
||||||
|
3 message.
|
||||||
|
|
||||||
|
* Type 1: 6 digit call, grid, power - ntype is positive and is a member
|
||||||
|
of the set {0,3,7,10,13,17,20...60}
|
||||||
|
|
||||||
|
* Type 2: extended callsign, power - ntype is positive but not
|
||||||
|
a member of the set of allowed powers
|
||||||
|
|
||||||
|
* Type 3: hash, 6 digit grid, power - ntype is negative.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( (ntype >= 0) && (ntype <= 62) ) {
|
||||||
|
int nu=ntype%10;
|
||||||
|
if( nu == 0 || nu == 3 || nu == 7 ) {
|
||||||
|
ndbm=ntype;
|
||||||
|
memset(call_loc_pow,0,sizeof(char)*23);
|
||||||
|
sprintf(cdbm,"%2d",ndbm);
|
||||||
|
strncat(call_loc_pow,callsign,strlen(callsign));
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,grid,4);
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,cdbm,2);
|
||||||
|
strncat(call_loc_pow,"\0",1);
|
||||||
|
ihash=nhash_(callsign,strlen(callsign),(uint32_t)146);
|
||||||
|
strcpy(*hashtab+ihash*13,callsign);
|
||||||
|
} else {
|
||||||
|
nadd=nu;
|
||||||
|
if( nu > 3 ) nadd=nu-3;
|
||||||
|
if( nu > 7 ) nadd=nu-7;
|
||||||
|
n3=n2/128+32768*(nadd-1);
|
||||||
|
unpackpfx(n3,callsign);
|
||||||
|
ndbm=ntype-nadd;
|
||||||
|
memset(call_loc_pow,0,sizeof(char)*23);
|
||||||
|
sprintf(cdbm,"%2d",ndbm);
|
||||||
|
strncat(call_loc_pow,callsign,strlen(callsign));
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,cdbm,2);
|
||||||
|
strncat(call_loc_pow,"\0",1);
|
||||||
|
int nu=ndbm%10;
|
||||||
|
if( nu == 0 || nu == 3 || nu == 7 || nu == 10 ) { //make sure power is OK
|
||||||
|
ihash=nhash_(callsign,strlen(callsign),(uint32_t)146);
|
||||||
|
strcpy(*hashtab+ihash*13,callsign);
|
||||||
|
} else noprint=1;
|
||||||
|
}
|
||||||
|
} else if ( ntype < 0 ) {
|
||||||
|
ndbm=-(ntype+1);
|
||||||
|
memset(grid6,0,sizeof(char)*7);
|
||||||
|
strncat(grid6,callsign+5,1);
|
||||||
|
strncat(grid6,callsign,5);
|
||||||
|
int nu=ndbm%10;
|
||||||
|
if( (nu == 0 || nu == 3 || nu == 7 || nu == 10) && \
|
||||||
|
(isalpha(grid6[0]) && isalpha(grid6[1]) && \
|
||||||
|
isdigit(grid6[2]) && isdigit(grid6[3]) ) ) {
|
||||||
|
// not testing 4'th and 5'th chars because of this case: <PA0SKT/2> JO33 40
|
||||||
|
// grid is only 4 chars even though this is a hashed callsign...
|
||||||
|
// isalpha(grid6[4]) && isalpha(grid6[5]) ) ) {
|
||||||
|
ihash=nhash_(callsign,strlen(callsign),(uint32_t)146);
|
||||||
|
strcpy(*hashtab+ihash*13,callsign);
|
||||||
|
} else noprint=1;
|
||||||
|
|
||||||
|
ihash=(n2-ntype-64)/128;
|
||||||
|
if( strncmp(hashtab[ihash],"\0",1) != 0 ) {
|
||||||
|
sprintf(callsign,"<%s>",hashtab[ihash]);
|
||||||
|
} else {
|
||||||
|
sprintf(callsign,"%5s","<...>");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(call_loc_pow,0,sizeof(char)*23);
|
||||||
|
sprintf(cdbm,"%2d",ndbm);
|
||||||
|
strncat(call_loc_pow,callsign,strlen(callsign));
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,grid6,strlen(grid6));
|
||||||
|
strncat(call_loc_pow," ",1);
|
||||||
|
strncat(call_loc_pow,cdbm,2);
|
||||||
|
strncat(call_loc_pow,"\0",1);
|
||||||
|
|
||||||
|
|
||||||
|
// I don't know what to do with these... They show up as "A000AA" grids.
|
||||||
|
if( ntype == -64 ) noprint=1;
|
||||||
|
}
|
||||||
|
return noprint;
|
||||||
|
}
|
24
lib/wsprd/wsprd_utils.h
Normal file
24
lib/wsprd/wsprd_utils.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
void unpack50( signed char *dat, int32_t *n1, int32_t *n2 );
|
||||||
|
|
||||||
|
void unpackcall( int32_t ncall, char *call );
|
||||||
|
|
||||||
|
void unpackgrid( int32_t ngrid, char *grid);
|
||||||
|
|
||||||
|
void unpackpfx( int32_t nprefix, char *call);
|
||||||
|
|
||||||
|
void deinterleave(unsigned char *sym);
|
||||||
|
|
||||||
|
// used by qsort
|
||||||
|
int floatcomp(const void* elem1, const void* elem2);
|
||||||
|
|
||||||
|
unsigned int nhash_( const void *key, size_t length, uint32_t initval);
|
||||||
|
|
||||||
|
int unpk_( signed char *message, char hashtab[32768][13], char *call_loc_pow, char *callsign);
|
1309
mainwindow.cpp
1309
mainwindow.cpp
File diff suppressed because it is too large
Load Diff
74
mainwindow.h
74
mainwindow.h
@ -30,10 +30,12 @@
|
|||||||
#include "Detector.hpp"
|
#include "Detector.hpp"
|
||||||
#include "Modulator.hpp"
|
#include "Modulator.hpp"
|
||||||
#include "decodedtext.h"
|
#include "decodedtext.h"
|
||||||
|
#include "wsprnet.h"
|
||||||
|
|
||||||
#define NUM_JT4_SYMBOLS 206
|
#define NUM_JT4_SYMBOLS 206
|
||||||
#define NUM_JT65_SYMBOLS 126
|
#define NUM_JT65_SYMBOLS 126
|
||||||
#define NUM_JT9_SYMBOLS 85
|
#define NUM_JT9_SYMBOLS 85
|
||||||
|
#define NUM_WSPR_SYMBOLS 162
|
||||||
#define NUM_CW_SYMBOLS 250
|
#define NUM_CW_SYMBOLS 250
|
||||||
#define TX_SAMPLE_RATE 48000
|
#define TX_SAMPLE_RATE 48000
|
||||||
|
|
||||||
@ -83,6 +85,9 @@ public slots:
|
|||||||
void readFromStdout();
|
void readFromStdout();
|
||||||
void readFromStderr();
|
void readFromStderr();
|
||||||
void jt9_error(QProcess::ProcessError);
|
void jt9_error(QProcess::ProcessError);
|
||||||
|
void p1ReadFromStdout();
|
||||||
|
void p1ReadFromStderr();
|
||||||
|
void p1Error(QProcess::ProcessError);
|
||||||
void setXIT(int n);
|
void setXIT(int n);
|
||||||
void setFreq4(int rxFreq, int txFreq);
|
void setFreq4(int rxFreq, int txFreq);
|
||||||
void clrAvg();
|
void clrAvg();
|
||||||
@ -188,6 +193,7 @@ private slots:
|
|||||||
void band_changed (Frequency);
|
void band_changed (Frequency);
|
||||||
void monitor (bool);
|
void monitor (bool);
|
||||||
void stop_tuning ();
|
void stop_tuning ();
|
||||||
|
void stopTuneATU();
|
||||||
void auto_tx_mode (bool);
|
void auto_tx_mode (bool);
|
||||||
void on_actionMessage_averaging_triggered();
|
void on_actionMessage_averaging_triggered();
|
||||||
void on_sbTol_valueChanged(int i);
|
void on_sbTol_valueChanged(int i);
|
||||||
@ -203,6 +209,28 @@ private slots:
|
|||||||
void on_cbTx6_toggled(bool b);
|
void on_cbTx6_toggled(bool b);
|
||||||
void networkError (QString const&);
|
void networkError (QString const&);
|
||||||
void on_ClrAvgButton_clicked();
|
void on_ClrAvgButton_clicked();
|
||||||
|
void on_actionWSPR_2_triggered();
|
||||||
|
void on_actionWSPR_15_triggered();
|
||||||
|
void on_syncSpinBox_valueChanged(int n);
|
||||||
|
void on_TxPowerComboBox_currentIndexChanged(const QString &arg1);
|
||||||
|
void on_sbTxPercent_valueChanged(int n);
|
||||||
|
void on_cbUploadWSPR_Spots_toggled(bool b);
|
||||||
|
void WSPR_config(bool b);
|
||||||
|
void uploadSpots();
|
||||||
|
void uploadResponse(QString response);
|
||||||
|
void p3ReadFromStdout();
|
||||||
|
void p3ReadFromStderr();
|
||||||
|
void p3Error(QProcess::ProcessError e);
|
||||||
|
void on_WSPRfreqSpinBox_valueChanged(int n);
|
||||||
|
void on_pbTxNext_clicked(bool b);
|
||||||
|
void on_cbBandHop_toggled(bool b);
|
||||||
|
void on_sunriseBands_editingFinished();
|
||||||
|
void on_pushButton_clicked();
|
||||||
|
void on_dayBands_editingFinished();
|
||||||
|
void on_sunsetBands_editingFinished();
|
||||||
|
void on_nightBands_editingFinished();
|
||||||
|
void on_tuneBands_editingFinished();
|
||||||
|
void on_graylineDuration_editingFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void enable_DXCC_entity (bool on);
|
void enable_DXCC_entity (bool on);
|
||||||
@ -249,6 +277,7 @@ private:
|
|||||||
QScopedPointer<MessageAveraging> m_msgAvgWidget;
|
QScopedPointer<MessageAveraging> m_msgAvgWidget;
|
||||||
|
|
||||||
Frequency m_dialFreq;
|
Frequency m_dialFreq;
|
||||||
|
Frequency m_dialFreqRxWSPR;
|
||||||
|
|
||||||
Detector m_detector;
|
Detector m_detector;
|
||||||
SoundInput m_soundInput;
|
SoundInput m_soundInput;
|
||||||
@ -263,6 +292,7 @@ private:
|
|||||||
qint64 m_dialFreqTx;
|
qint64 m_dialFreqTx;
|
||||||
|
|
||||||
float m_DTtol;
|
float m_DTtol;
|
||||||
|
float m_rxavg;
|
||||||
|
|
||||||
qint32 m_waterfallAvg;
|
qint32 m_waterfallAvg;
|
||||||
qint32 m_ntx;
|
qint32 m_ntx;
|
||||||
@ -274,6 +304,8 @@ private:
|
|||||||
qint32 m_RxLog;
|
qint32 m_RxLog;
|
||||||
qint32 m_nutc0;
|
qint32 m_nutc0;
|
||||||
qint32 m_nrx;
|
qint32 m_nrx;
|
||||||
|
qint32 m_ntr;
|
||||||
|
qint32 m_tx;
|
||||||
qint32 m_hsym;
|
qint32 m_hsym;
|
||||||
qint32 m_TRperiod;
|
qint32 m_TRperiod;
|
||||||
qint32 m_nsps;
|
qint32 m_nsps;
|
||||||
@ -291,6 +323,12 @@ private:
|
|||||||
qint32 m_nclearave;
|
qint32 m_nclearave;
|
||||||
qint32 m_DopplerMethod;
|
qint32 m_DopplerMethod;
|
||||||
qint32 m_DopplerMethod0;
|
qint32 m_DopplerMethod0;
|
||||||
|
qint32 m_minSync;
|
||||||
|
qint32 m_dBm;
|
||||||
|
qint32 m_pctx;
|
||||||
|
qint32 m_nseq;
|
||||||
|
qint32 m_grayDuration;
|
||||||
|
qint32 m_band00;
|
||||||
|
|
||||||
bool m_btxok; //True if OK to transmit
|
bool m_btxok; //True if OK to transmit
|
||||||
bool m_diskData;
|
bool m_diskData;
|
||||||
@ -338,6 +376,15 @@ private:
|
|||||||
bool m_bShMsgs;
|
bool m_bShMsgs;
|
||||||
bool m_bDopplerTracking;
|
bool m_bDopplerTracking;
|
||||||
bool m_bDopplerTracking0;
|
bool m_bDopplerTracking0;
|
||||||
|
bool m_uploadSpots;
|
||||||
|
bool m_uploading;
|
||||||
|
bool m_txNext;
|
||||||
|
bool m_grid6;
|
||||||
|
bool m_bandHopping;
|
||||||
|
bool m_hopTest;
|
||||||
|
bool m_tuneup;
|
||||||
|
bool m_bTxTime;
|
||||||
|
bool m_rxDone;
|
||||||
|
|
||||||
float m_pctZap;
|
float m_pctZap;
|
||||||
|
|
||||||
@ -347,6 +394,8 @@ private:
|
|||||||
QLabel * last_tx_label;
|
QLabel * last_tx_label;
|
||||||
QLabel * auto_tx_label;
|
QLabel * auto_tx_label;
|
||||||
|
|
||||||
|
QProgressBar* progressBar;
|
||||||
|
|
||||||
QMessageBox msgBox0;
|
QMessageBox msgBox0;
|
||||||
|
|
||||||
QFuture<void>* future1;
|
QFuture<void>* future1;
|
||||||
@ -357,6 +406,10 @@ private:
|
|||||||
QFutureWatcher<void>* watcher3;
|
QFutureWatcher<void>* watcher3;
|
||||||
|
|
||||||
QProcess proc_jt9;
|
QProcess proc_jt9;
|
||||||
|
QProcess p1;
|
||||||
|
QProcess p3;
|
||||||
|
|
||||||
|
WSPRNet *wsprNet;
|
||||||
|
|
||||||
QTimer m_guiTimer;
|
QTimer m_guiTimer;
|
||||||
QTimer* ptt1Timer; //StartTx delay
|
QTimer* ptt1Timer; //StartTx delay
|
||||||
@ -364,6 +417,8 @@ private:
|
|||||||
QTimer* logQSOTimer;
|
QTimer* logQSOTimer;
|
||||||
QTimer* killFileTimer;
|
QTimer* killFileTimer;
|
||||||
QTimer* tuneButtonTimer;
|
QTimer* tuneButtonTimer;
|
||||||
|
QTimer* uploadTimer;
|
||||||
|
QTimer* tuneATU_Timer;
|
||||||
|
|
||||||
QString m_path;
|
QString m_path;
|
||||||
QString m_pbdecoding_style1;
|
QString m_pbdecoding_style1;
|
||||||
@ -389,9 +444,17 @@ private:
|
|||||||
QString m_msgSent0;
|
QString m_msgSent0;
|
||||||
QString m_fileToSave;
|
QString m_fileToSave;
|
||||||
QString m_band;
|
QString m_band;
|
||||||
|
QString m_c2name;
|
||||||
|
|
||||||
QStringList m_prefix;
|
QStringList m_prefix;
|
||||||
QStringList m_suffix;
|
QStringList m_suffix;
|
||||||
|
QStringList m_sunriseBands;
|
||||||
|
QStringList m_dayBands;
|
||||||
|
QStringList m_sunsetBands;
|
||||||
|
QStringList m_nightBands;
|
||||||
|
QStringList m_tuneBands;
|
||||||
|
|
||||||
|
QMap<QString,double> m_fWSPR;
|
||||||
|
|
||||||
QHash<QString,bool> m_pfx;
|
QHash<QString,bool> m_pfx;
|
||||||
QHash<QString,bool> m_sfx;
|
QHash<QString,bool> m_sfx;
|
||||||
@ -444,6 +507,7 @@ private:
|
|||||||
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text);
|
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text);
|
||||||
void replayDecodes ();
|
void replayDecodes ();
|
||||||
void postDecode (bool is_new, QString const& message);
|
void postDecode (bool is_new, QString const& message);
|
||||||
|
void bandHopping();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void getfile(QString fname, int ntrperiod);
|
extern void getfile(QString fname, int ntrperiod);
|
||||||
@ -456,7 +520,7 @@ extern int ptt(int nport, int ntx, int* iptt, int* nopen);
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
//----------------------------------------------------- C and Fortran routines
|
//----------------------------------------------------- C and Fortran routines
|
||||||
void symspec_(int* k, int* ntrperiod, int* nsps, int* ingain,
|
void symspec_(int* k, int* ntrperiod, int* nsps, int* ingain, int* minw,
|
||||||
float* px, float s[], float* df3, int* nhsym, int* npts8);
|
float* px, float s[], float* df3, int* nhsym, int* npts8);
|
||||||
|
|
||||||
void gen4_(char* msg, int* ichk, char* msgsent, int itone[],
|
void gen4_(char* msg, int* ichk, char* msgsent, int itone[],
|
||||||
@ -468,6 +532,8 @@ extern "C" {
|
|||||||
void gen65_(char* msg, int* ichk, char* msgsent, int itone[],
|
void gen65_(char* msg, int* ichk, char* msgsent, int itone[],
|
||||||
int* itext, int len1, int len2);
|
int* itext, int len1, int len2);
|
||||||
|
|
||||||
|
void genwspr_(char* msg, char* msgsent, int itone[], int len1, int len2);
|
||||||
|
|
||||||
bool stdmsg_(const char* msg, int len);
|
bool stdmsg_(const char* msg, int len);
|
||||||
|
|
||||||
void azdist_(char* MyGrid, char* HisGrid, double* utch, int* nAz, int* nEl,
|
void azdist_(char* MyGrid, char* HisGrid, double* utch, int* nAz, int* nEl,
|
||||||
@ -481,6 +547,12 @@ extern "C" {
|
|||||||
int fftwf_import_wisdom_from_filename(const char *);
|
int fftwf_import_wisdom_from_filename(const char *);
|
||||||
int fftwf_export_wisdom_to_filename(const char *);
|
int fftwf_export_wisdom_to_filename(const char *);
|
||||||
|
|
||||||
|
void wspr_downsample_(short int d2[], int* k);
|
||||||
|
void savec2_(char* fname, int* m_TRseconds, double* m_dialFreq, int len1);
|
||||||
|
|
||||||
|
void hopping_(int* nyear, int* month, int* nday, float* uth, char* MyGrid,
|
||||||
|
int* nduration, int* npctx, int* isun, int* iband,
|
||||||
|
int* ntxnext, int len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
858
mainwindow.ui
858
mainwindow.ui
@ -11,14 +11,14 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>825</width>
|
<width>0</width>
|
||||||
<height>460</height>
|
<height>460</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@ -38,6 +38,9 @@
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<property name="horizontalSpacing">
|
<property name="horizontalSpacing">
|
||||||
@ -556,58 +559,7 @@
|
|||||||
<layout class="QGridLayout" name="gridLayout_5">
|
<layout class="QGridLayout" name="gridLayout_5">
|
||||||
<item row="0" column="5" rowspan="6">
|
<item row="0" column="5" rowspan="6">
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
<item row="7" column="2">
|
<item row="6" column="1">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labTol">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>60</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Tolerance for offset from selected Rx frequency.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string> F tol 500</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="sbTol">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>18</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>7</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
@ -656,7 +608,7 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="2">
|
<item row="3" column="2">
|
||||||
<widget class="QPushButton" name="pbT2R">
|
<widget class="QPushButton" name="pbT2R">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
@ -678,7 +630,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QCheckBox" name="cbTxLock">
|
<widget class="QCheckBox" name="cbTxLock">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Tx frequency tracks Rx frequency</p></body></html></string>
|
<string><html><head/><body><p>Tx frequency tracks Rx frequency</p></body></html></string>
|
||||||
@ -688,7 +640,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="2">
|
<item row="4" column="2">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
@ -742,23 +694,7 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="7" column="2">
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>18</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="2">
|
|
||||||
<widget class="QDoubleSpinBox" name="sbDT">
|
<widget class="QDoubleSpinBox" name="sbDT">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Tolerance for expected time offset.</string>
|
<string>Tolerance for expected time offset.</string>
|
||||||
@ -783,140 +719,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labMinW">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Set minimum width expected for Doppler-spread tones</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>MinW A</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="sbMinW">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>18</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="2">
|
|
||||||
<widget class="QCheckBox" name="cbEME">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Check to add 2.5 s to expected propagation delay.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>EME</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QPushButton" name="pbR2T">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>48</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Set Tx frequency to Rx Frequency</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Tx<Rx</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QSpinBox" name="RxFreqSpinBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Audio Rx frequency</string>
|
|
||||||
</property>
|
|
||||||
<property name="suffix">
|
|
||||||
<string> Hz</string>
|
|
||||||
</property>
|
|
||||||
<property name="prefix">
|
|
||||||
<string>Rx </string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>200</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>5000</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>1500</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QCheckBox" name="txFirstCheckBox">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>60</width>
|
|
||||||
<height>23</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>105</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Check to Tx in even minutes, uncheck for odd minutes</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Tx even</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QSpinBox" name="TxFreqSpinBox">
|
<widget class="QSpinBox" name="TxFreqSpinBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
@ -939,6 +742,9 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Audio Tx frequency</string>
|
<string>Audio Tx frequency</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> Hz</string>
|
<string> Hz</string>
|
||||||
</property>
|
</property>
|
||||||
@ -956,7 +762,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QPushButton" name="pbTxMode">
|
<widget class="QPushButton" name="pbTxMode">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
@ -969,7 +775,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
<item row="8" column="1">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="labSubmode">
|
<widget class="QLabel" name="labSubmode">
|
||||||
@ -1008,7 +814,7 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="0">
|
||||||
<spacer name="horizontalSpacer_3">
|
<spacer name="horizontalSpacer_3">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
@ -1024,6 +830,235 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="5" column="2">
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QSpinBox" name="syncSpinBox">
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="prefix">
|
||||||
|
<string>Sync </string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labMinW">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Set minimum width expected for Doppler-spread tones</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>MinW A</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="sbMinW">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>18</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="2">
|
||||||
|
<widget class="QCheckBox" name="cbEME">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Check to add 2.5 s to expected propagation delay.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>EME</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QPushButton" name="pbR2T">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>48</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Set Tx frequency to Rx Frequency</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Tx<Rx</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QSpinBox" name="RxFreqSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Audio Rx frequency</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> Hz</string>
|
||||||
|
</property>
|
||||||
|
<property name="prefix">
|
||||||
|
<string>Rx </string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>200</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>5000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1500</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QCheckBox" name="txFirstCheckBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>23</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>105</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Check to Tx in even minutes, uncheck for odd minutes</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Tx even</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="2">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labTol">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Tolerance for offset from selected Rx frequency.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string> F tol 500</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="sbTol">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>18</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="3">
|
<item row="1" column="3">
|
||||||
@ -1381,7 +1416,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
@ -1392,6 +1427,12 @@
|
|||||||
<height>200</height>
|
<height>200</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="baseSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="tabPosition">
|
<property name="tabPosition">
|
||||||
<enum>QTabWidget::West</enum>
|
<enum>QTabWidget::West</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -1399,7 +1440,7 @@
|
|||||||
<enum>QTabWidget::Triangular</enum>
|
<enum>QTabWidget::Triangular</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab">
|
<widget class="QWidget" name="tab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@ -2197,6 +2238,361 @@ list. The list can be maintained in Settings (F2).</string>
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_3">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>3</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QWidget" name="layoutWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>30</x>
|
||||||
|
<y>22</y>
|
||||||
|
<width>200</width>
|
||||||
|
<height>171</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_6">
|
||||||
|
<item row="0" column="0" colspan="3">
|
||||||
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>10</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>WSPR Mode</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QSpinBox" name="WSPRfreqSpinBox">
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> Hz</string>
|
||||||
|
</property>
|
||||||
|
<property name="prefix">
|
||||||
|
<string>Tx </string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1400</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>1600</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1500</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QCheckBox" name="cbUploadWSPR_Spots">
|
||||||
|
<property name="text">
|
||||||
|
<string>Upload spots</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QSpinBox" name="sbTxPercent">
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> %</string>
|
||||||
|
</property>
|
||||||
|
<property name="prefix">
|
||||||
|
<string>Tx Pct </string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>5</width>
|
||||||
|
<height>17</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QCheckBox" name="cbBandHop">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Band hopping</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QPushButton" name="pbTxNext">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QPushButton:checked {
|
||||||
|
background-color: red;
|
||||||
|
border-style: outset;
|
||||||
|
border-width: 1px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border-color: black;
|
||||||
|
min-width: 5em;
|
||||||
|
padding: 3px;
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Tx Next</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QComboBox" name="TxPowerComboBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_4">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>4</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>100</x>
|
||||||
|
<y>190</y>
|
||||||
|
<width>75</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="layoutWidget1">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>30</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>211</width>
|
||||||
|
<height>152</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_7">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_12">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>55</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Sunrise:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="sunriseBands">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>160</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>160 80 40 30 20</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_13">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>55</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Day:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="dayBands">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>160</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>30 20 17 15 12 10</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_14">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>55</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Sunset:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="sunsetBands">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>160</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>160 80 40 30 20</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_15">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>55</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Night:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLineEdit" name="nightBands">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>160</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>160 80 40 30 20</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_16">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>55</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Tune:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLineEdit" name="tuneBands">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>160</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>80 40 30 20 17 15 12 10</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_17">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>55</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Gray time:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLineEdit" name="graylineDuration">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>160</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>60</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -2508,6 +2904,22 @@ QLabel[oob="true"] {
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="6" column="3">
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>1</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -2588,6 +3000,8 @@ QLabel[oob="true"] {
|
|||||||
<addaction name="actionJT9_JT65"/>
|
<addaction name="actionJT9_JT65"/>
|
||||||
<addaction name="actionJT9W_1"/>
|
<addaction name="actionJT9W_1"/>
|
||||||
<addaction name="actionJT4"/>
|
<addaction name="actionJT4"/>
|
||||||
|
<addaction name="actionWSPR_2"/>
|
||||||
|
<addaction name="actionWSPR_15"/>
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
<addaction name="menuView"/>
|
<addaction name="menuView"/>
|
||||||
@ -2973,6 +3387,25 @@ QLabel[oob="true"] {
|
|||||||
<string>Include correlation</string>
|
<string>Include correlation</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionWSPR_2">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>WSPR-2</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionWSPR_15">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>WSPR-15</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
@ -2998,7 +3431,6 @@ QLabel[oob="true"] {
|
|||||||
<tabstop>txFirstCheckBox</tabstop>
|
<tabstop>txFirstCheckBox</tabstop>
|
||||||
<tabstop>TxFreqSpinBox</tabstop>
|
<tabstop>TxFreqSpinBox</tabstop>
|
||||||
<tabstop>rptSpinBox</tabstop>
|
<tabstop>rptSpinBox</tabstop>
|
||||||
<tabstop>tabWidget</tabstop>
|
|
||||||
<tabstop>genStdMsgsPushButton</tabstop>
|
<tabstop>genStdMsgsPushButton</tabstop>
|
||||||
<tabstop>tx1</tabstop>
|
<tabstop>tx1</tabstop>
|
||||||
<tabstop>tx2</tabstop>
|
<tabstop>tx2</tabstop>
|
||||||
|
76
plotter.cpp
76
plotter.cpp
@ -37,6 +37,7 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
|
|||||||
m_Percent2DScreen = 30; //percent of screen used for 2D display
|
m_Percent2DScreen = 30; //percent of screen used for 2D display
|
||||||
m_txFreq=0;
|
m_txFreq=0;
|
||||||
m_fftBinWidth=1500.0/2048.0;
|
m_fftBinWidth=1500.0/2048.0;
|
||||||
|
m_bScaleOK=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlotter::~CPlotter() { } // Destructor
|
CPlotter::~CPlotter() { } // Destructor
|
||||||
@ -92,8 +93,10 @@ void CPlotter::draw(float swide[], bool bScroll) //dr
|
|||||||
int j,j0,y2;
|
int j,j0,y2;
|
||||||
float y;
|
float y;
|
||||||
|
|
||||||
double gain = pow(10.0,0.02*m_plotGain);
|
double fac = sqrt(m_binsPerPixel*m_waterfallAvg/15.0);
|
||||||
|
double gain = fac*pow(10.0,0.02*m_plotGain);
|
||||||
double gain2d = pow(10.0,0.02*(m_plot2dGain));
|
double gain2d = pow(10.0,0.02*(m_plot2dGain));
|
||||||
|
qDebug() << m_binsPerPixel << m_waterfallAvg << m_plotGain << gain;
|
||||||
|
|
||||||
//move current data down one line (must do this before attaching a QPainter object)
|
//move current data down one line (must do this before attaching a QPainter object)
|
||||||
if(bScroll) m_WaterfallPixmap.scroll(0,1,0,0,m_w,m_h1);
|
if(bScroll) m_WaterfallPixmap.scroll(0,1,0,0,m_w,m_h1);
|
||||||
@ -159,7 +162,7 @@ void CPlotter::draw(float swide[], bool bScroll) //dr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_bLinearAvg) { //Linear Avg
|
if(m_bLinearAvg) { //Linear Avg (yellow)
|
||||||
float sum=0.0;
|
float sum=0.0;
|
||||||
int j=j0+m_binsPerPixel*i;
|
int j=j0+m_binsPerPixel*i;
|
||||||
for(int k=0; k<m_binsPerPixel; k++) {
|
for(int k=0; k<m_binsPerPixel; k++) {
|
||||||
@ -179,9 +182,9 @@ void CPlotter::draw(float swide[], bool bScroll) //dr
|
|||||||
if(swide[0]>1.0e29) m_line=0;
|
if(swide[0]>1.0e29) m_line=0;
|
||||||
m_line++;
|
m_line++;
|
||||||
if(m_line == 13) {
|
if(m_line == 13) {
|
||||||
UTCstr();
|
|
||||||
painter1.setPen(Qt::white);
|
painter1.setPen(Qt::white);
|
||||||
painter1.drawText(5,10,m_sutc);
|
QString t=QDateTime::currentDateTimeUtc().toString("hh:mm") + " " + m_rxBand;
|
||||||
|
painter1.drawText(5,10,t);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_mode=="JT4") {
|
if(m_mode=="JT4") {
|
||||||
@ -189,7 +192,6 @@ void CPlotter::draw(float swide[], bool bScroll) //dr
|
|||||||
painter2D.setPen(pen3);
|
painter2D.setPen(pen3);
|
||||||
Font.setWeight(QFont::Bold);
|
Font.setWeight(QFont::Bold);
|
||||||
painter2D.setFont(Font);
|
painter2D.setFont(Font);
|
||||||
// qDebug() << "B" << m_rxFreq;
|
|
||||||
int x1=XfromFreq(m_rxFreq);
|
int x1=XfromFreq(m_rxFreq);
|
||||||
y=0.2*m_h2;
|
y=0.2*m_h2;
|
||||||
painter2D.drawText(x1-4,y,"T");
|
painter2D.drawText(x1-4,y,"T");
|
||||||
@ -201,22 +203,7 @@ void CPlotter::draw(float swide[], bool bScroll) //dr
|
|||||||
painter2D.drawText(x1-4,y,"73");
|
painter2D.drawText(x1-4,y,"73");
|
||||||
}
|
}
|
||||||
update(); //trigger a new paintEvent
|
update(); //trigger a new paintEvent
|
||||||
}
|
m_bScaleOK=true;
|
||||||
|
|
||||||
void CPlotter::UTCstr() //UTCstr
|
|
||||||
{
|
|
||||||
int ihr,imin;
|
|
||||||
if(jt9com_.ndiskdat != 0) {
|
|
||||||
ihr=jt9com_.nutc/100;
|
|
||||||
imin=jt9com_.nutc % 100;
|
|
||||||
} else {
|
|
||||||
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
|
|
||||||
imin=ms/60000;
|
|
||||||
ihr=imin/60;
|
|
||||||
imin=imin % 60;
|
|
||||||
imin=imin - (imin % (m_TRperiod/60));
|
|
||||||
}
|
|
||||||
sprintf(m_sutc,"%2.2d:%2.2d",ihr,imin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlotter::DrawOverlay() //DrawOverlay()
|
void CPlotter::DrawOverlay() //DrawOverlay()
|
||||||
@ -225,7 +212,6 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||||||
if(m_WaterfallPixmap.isNull()) return;
|
if(m_WaterfallPixmap.isNull()) return;
|
||||||
int w = m_WaterfallPixmap.width();
|
int w = m_WaterfallPixmap.width();
|
||||||
int x,y,x1,x2;
|
int x,y,x1,x2;
|
||||||
// int nHzDiv[11]={0,50,100,200,200,200,500,500,500,500,500};
|
|
||||||
float pixperdiv;
|
float pixperdiv;
|
||||||
|
|
||||||
double df = m_binsPerPixel*m_fftBinWidth;
|
double df = m_binsPerPixel*m_fftBinWidth;
|
||||||
@ -233,7 +219,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||||||
{
|
{
|
||||||
QPainter painter(&m_OverlayPixmap);
|
QPainter painter(&m_OverlayPixmap);
|
||||||
painter.initFrom(this);
|
painter.initFrom(this);
|
||||||
QLinearGradient gradient(0, 0, 0 ,m_h2); //fill background with gradient
|
QLinearGradient gradient(0, 0, 0 ,m_h2); //fill background with gradient
|
||||||
gradient.setColorAt(1, Qt::black);
|
gradient.setColorAt(1, Qt::black);
|
||||||
gradient.setColorAt(0, Qt::darkBlue);
|
gradient.setColorAt(0, Qt::darkBlue);
|
||||||
painter.setBrush(gradient);
|
painter.setBrush(gradient);
|
||||||
@ -293,13 +279,13 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||||||
|
|
||||||
//draw tick marks on upper scale
|
//draw tick marks on upper scale
|
||||||
pixperdiv = m_freqPerDiv/df;
|
pixperdiv = m_freqPerDiv/df;
|
||||||
for( int i=0; i<m_hdivs; i++) { //major ticks
|
for( int i=0; i<m_hdivs; i++) { //major ticks
|
||||||
x = (int)((m_xOffset+i)*pixperdiv );
|
x = (int)((m_xOffset+i)*pixperdiv );
|
||||||
painter0.drawLine(x,18,x,30);
|
painter0.drawLine(x,18,x,30);
|
||||||
}
|
}
|
||||||
int minor=5;
|
int minor=5;
|
||||||
if(m_freqPerDiv==200) minor=4;
|
if(m_freqPerDiv==200) minor=4;
|
||||||
for( int i=1; i<minor*m_hdivs; i++) { //minor ticks
|
for( int i=1; i<minor*m_hdivs; i++) { //minor ticks
|
||||||
x = i*pixperdiv/minor;
|
x = i*pixperdiv/minor;
|
||||||
painter0.drawLine(x,24,x,30);
|
painter0.drawLine(x,24,x,30);
|
||||||
}
|
}
|
||||||
@ -311,10 +297,10 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||||||
painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter,m_HDivText[i]);
|
painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter,m_HDivText[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
float bw=9.0*12000.0/m_nsps; //JT9
|
float bw=9.0*12000.0/m_nsps; //JT9
|
||||||
|
|
||||||
if(m_mode=="JT4") { //JT4
|
if(m_mode=="JT4") { //JT4
|
||||||
bw=3*11025.0/2520.0; //NB: this is max tone spacing, 3/4 of actual BW
|
bw=3*11025.0/2520.0; //Max tone spacing (3/4 of actual BW)
|
||||||
if(m_nSubMode==1) bw=2*bw;
|
if(m_nSubMode==1) bw=2*bw;
|
||||||
if(m_nSubMode==2) bw=4*bw;
|
if(m_nSubMode==2) bw=4*bw;
|
||||||
if(m_nSubMode==3) bw=9*bw;
|
if(m_nSubMode==3) bw=9*bw;
|
||||||
@ -347,19 +333,33 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||||||
if(m_nSubMode==2) bw=4*bw;
|
if(m_nSubMode==2) bw=4*bw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(m_mode != "JT4") {
|
if(m_mode != "JT4") {
|
||||||
QPen pen0(Qt::green, 3); //Mark Rx Freq with green
|
QPen pen0(Qt::green, 3); //Mark Rx Freq with green
|
||||||
painter0.setPen(pen0);
|
painter0.setPen(pen0);
|
||||||
x1=XfromFreq(m_rxFreq);
|
if(m_mode=="WSPR-2") { //### WSPR-15 code needed here, too ###
|
||||||
x2=XfromFreq(m_rxFreq+bw);
|
x1=XfromFreq(1400);
|
||||||
painter0.drawLine(x1,24,x1,30);
|
x2=XfromFreq(1600);
|
||||||
painter0.drawLine(x1,28,x2,28);
|
painter0.drawLine(x1,29,x2,29);
|
||||||
painter0.drawLine(x2,24,x2,30);
|
} else {
|
||||||
|
x1=XfromFreq(m_rxFreq);
|
||||||
|
x2=XfromFreq(m_rxFreq+bw);
|
||||||
|
painter0.drawLine(x1,24,x1,30);
|
||||||
|
painter0.drawLine(x1,28,x2,28);
|
||||||
|
painter0.drawLine(x2,24,x2,30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_mode != "JT4") {
|
||||||
QPen pen1(Qt::red, 3); //Mark Tx freq with red
|
QPen pen1(Qt::red, 3); //Mark Tx freq with red
|
||||||
painter0.setPen(pen1);
|
painter0.setPen(pen1);
|
||||||
x1=XfromFreq(m_txFreq);
|
x1=XfromFreq(m_txFreq);
|
||||||
x2=XfromFreq(m_txFreq+bw);
|
x2=XfromFreq(m_txFreq+bw);
|
||||||
|
if(m_mode=="WSPR-2") { //### WSPR-15 code needed here, too
|
||||||
|
bw=4*12000.0/8192.0; //WSPR
|
||||||
|
x1=XfromFreq(m_txFreq-0.5*bw);
|
||||||
|
x2=XfromFreq(m_txFreq+0.5*bw);
|
||||||
|
}
|
||||||
painter0.drawLine(x1,17,x1,21);
|
painter0.drawLine(x1,17,x1,21);
|
||||||
painter0.drawLine(x1,17,x2,17);
|
painter0.drawLine(x1,17,x2,17);
|
||||||
painter0.drawLine(x2,17,x2,21);
|
painter0.drawLine(x2,17,x2,21);
|
||||||
@ -491,6 +491,11 @@ int CPlotter::binsPerPixel() //binsPerPixel
|
|||||||
return m_binsPerPixel;
|
return m_binsPerPixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPlotter::setWaterfallAvg(int n) //setBinsPerPixel
|
||||||
|
{
|
||||||
|
m_waterfallAvg = n;
|
||||||
|
}
|
||||||
|
|
||||||
void CPlotter::setRxFreq (int x) //setRxFreq
|
void CPlotter::setRxFreq (int x) //setRxFreq
|
||||||
{
|
{
|
||||||
m_rxFreq = x; // x is freq in Hz
|
m_rxFreq = x; // x is freq in Hz
|
||||||
@ -572,6 +577,11 @@ void CPlotter::setDialFreq(double d)
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPlotter::setRxBand(QString band)
|
||||||
|
{
|
||||||
|
m_rxBand=band;
|
||||||
|
}
|
||||||
|
|
||||||
void CPlotter::setFlatten(bool b)
|
void CPlotter::setFlatten(bool b)
|
||||||
{
|
{
|
||||||
m_Flatten=0;
|
m_Flatten=0;
|
||||||
|
@ -32,6 +32,8 @@ public:
|
|||||||
|
|
||||||
QSize minimumSizeHint() const;
|
QSize minimumSizeHint() const;
|
||||||
QSize sizeHint() const;
|
QSize sizeHint() const;
|
||||||
|
bool m_bScaleOK;
|
||||||
|
|
||||||
void draw(float swide[], bool bScroll); //Update the waterfall
|
void draw(float swide[], bool bScroll); //Update the waterfall
|
||||||
void SetRunningState(bool running);
|
void SetRunningState(bool running);
|
||||||
void setPlotZero(int plotZero);
|
void setPlotZero(int plotZero);
|
||||||
@ -50,6 +52,7 @@ public:
|
|||||||
void setRxRange(int fMin);
|
void setRxRange(int fMin);
|
||||||
void setBinsPerPixel(int n);
|
void setBinsPerPixel(int n);
|
||||||
int binsPerPixel();
|
int binsPerPixel();
|
||||||
|
void setWaterfallAvg(int n);
|
||||||
void setRxFreq(int n);
|
void setRxFreq(int n);
|
||||||
void DrawOverlay();
|
void DrawOverlay();
|
||||||
int rxFreq();
|
int rxFreq();
|
||||||
@ -75,6 +78,7 @@ public:
|
|||||||
void setColours(QVector<QColor> const& cl) {m_ColorTbl = cl;}
|
void setColours(QVector<QColor> const& cl) {m_ColorTbl = cl;}
|
||||||
void setFlatten(bool b);
|
void setFlatten(bool b);
|
||||||
void setTol(int n);
|
void setTol(int n);
|
||||||
|
void setRxBand(QString band);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void freezeDecode1(int n);
|
void freezeDecode1(int n);
|
||||||
@ -88,7 +92,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
void MakeFrequencyStrs();
|
void MakeFrequencyStrs();
|
||||||
void UTCstr();
|
|
||||||
int XfromFreq(float f);
|
int XfromFreq(float f);
|
||||||
float FreqfromX(int x);
|
float FreqfromX(int x);
|
||||||
|
|
||||||
@ -106,6 +109,7 @@ private:
|
|||||||
qint32 m_plot2dGain;
|
qint32 m_plot2dGain;
|
||||||
qint32 m_plot2dZero;
|
qint32 m_plot2dZero;
|
||||||
qint32 m_binsPerPixel;
|
qint32 m_binsPerPixel;
|
||||||
|
qint32 m_waterfallAvg;
|
||||||
qint32 m_w;
|
qint32 m_w;
|
||||||
qint32 m_Flatten;
|
qint32 m_Flatten;
|
||||||
qint32 m_nSubMode;
|
qint32 m_nSubMode;
|
||||||
@ -120,6 +124,7 @@ private:
|
|||||||
QString m_HDivText[483];
|
QString m_HDivText[483];
|
||||||
QString m_mode;
|
QString m_mode;
|
||||||
QString m_modeTx;
|
QString m_modeTx;
|
||||||
|
QString m_rxBand;
|
||||||
|
|
||||||
bool m_Running;
|
bool m_Running;
|
||||||
bool m_paintEventBusy;
|
bool m_paintEventBusy;
|
||||||
|
@ -53,8 +53,11 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
|
|||||||
ui->widePlot->setFlatten(m_bFlatten);
|
ui->widePlot->setFlatten(m_bFlatten);
|
||||||
ui->widePlot->setBreadth(m_settings->value("PlotWidth",1000).toInt());
|
ui->widePlot->setBreadth(m_settings->value("PlotWidth",1000).toInt());
|
||||||
ui->bppSpinBox->setValue(n);
|
ui->bppSpinBox->setValue(n);
|
||||||
|
m_nsmo=m_settings->value("SmoothYellow",1).toInt();
|
||||||
|
ui->smoSpinBox->setValue(m_nsmo);
|
||||||
m_waterfallAvg = m_settings->value("WaterfallAvg",5).toInt();
|
m_waterfallAvg = m_settings->value("WaterfallAvg",5).toInt();
|
||||||
ui->waterfallAvgSpinBox->setValue(m_waterfallAvg);
|
ui->waterfallAvgSpinBox->setValue(m_waterfallAvg);
|
||||||
|
ui->widePlot->setWaterfallAvg(m_waterfallAvg);
|
||||||
ui->widePlot->setCurrent(m_settings->value("Current",false).toBool());
|
ui->widePlot->setCurrent(m_settings->value("Current",false).toBool());
|
||||||
ui->widePlot->setCumulative(m_settings->value("Cumulative",true).toBool());
|
ui->widePlot->setCumulative(m_settings->value("Cumulative",true).toBool());
|
||||||
ui->widePlot->setLinearAvg(m_settings->value("LinearAvg",false).toBool());
|
ui->widePlot->setLinearAvg(m_settings->value("LinearAvg",false).toBool());
|
||||||
@ -111,6 +114,7 @@ void WideGraph::saveSettings() //saveS
|
|||||||
m_settings->setValue ("Plot2dZero", ui->widePlot->plot2dZero());
|
m_settings->setValue ("Plot2dZero", ui->widePlot->plot2dZero());
|
||||||
m_settings->setValue ("PlotWidth", ui->widePlot->plotWidth ());
|
m_settings->setValue ("PlotWidth", ui->widePlot->plotWidth ());
|
||||||
m_settings->setValue ("BinsPerPixel", ui->bppSpinBox->value ());
|
m_settings->setValue ("BinsPerPixel", ui->bppSpinBox->value ());
|
||||||
|
m_settings->setValue ("SmoothYellow", ui->smoSpinBox->value ());
|
||||||
m_settings->setValue ("WaterfallAvg", ui->waterfallAvgSpinBox->value ());
|
m_settings->setValue ("WaterfallAvg", ui->waterfallAvgSpinBox->value ());
|
||||||
m_settings->setValue ("Current", ui->widePlot->current());
|
m_settings->setValue ("Current", ui->widePlot->current());
|
||||||
m_settings->setValue ("Cumulative", ui->widePlot->cumulative());
|
m_settings->setValue ("Cumulative", ui->widePlot->cumulative());
|
||||||
@ -176,6 +180,7 @@ void WideGraph::on_bppSpinBox_valueChanged(int n) //b
|
|||||||
void WideGraph::on_waterfallAvgSpinBox_valueChanged(int n) //Navg
|
void WideGraph::on_waterfallAvgSpinBox_valueChanged(int n) //Navg
|
||||||
{
|
{
|
||||||
m_waterfallAvg = n;
|
m_waterfallAvg = n;
|
||||||
|
ui->widePlot->setWaterfallAvg(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WideGraph::keyPressEvent(QKeyEvent *e) //F11, F12
|
void WideGraph::keyPressEvent(QKeyEvent *e) //F11, F12
|
||||||
@ -282,9 +287,15 @@ void WideGraph::on_spec2dComboBox_currentIndexChanged(const QString &arg1)
|
|||||||
ui->widePlot->setCurrent(false);
|
ui->widePlot->setCurrent(false);
|
||||||
ui->widePlot->setCumulative(false);
|
ui->widePlot->setCumulative(false);
|
||||||
ui->widePlot->setLinearAvg(false);
|
ui->widePlot->setLinearAvg(false);
|
||||||
|
ui->smoSpinBox->setEnabled(false);
|
||||||
|
ui->labSmooth->setEnabled(false);
|
||||||
if(arg1=="Current") ui->widePlot->setCurrent(true);
|
if(arg1=="Current") ui->widePlot->setCurrent(true);
|
||||||
if(arg1=="Cumulative") ui->widePlot->setCumulative(true);
|
if(arg1=="Cumulative") ui->widePlot->setCumulative(true);
|
||||||
if(arg1=="Linear Avg") ui->widePlot->setLinearAvg(true);
|
if(arg1=="Linear Avg") {
|
||||||
|
ui->widePlot->setLinearAvg(true);
|
||||||
|
ui->smoSpinBox->setEnabled(true);
|
||||||
|
ui->labSmooth->setEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WideGraph::on_fSplitSpinBox_valueChanged(int n) //fSplit
|
void WideGraph::on_fSplitSpinBox_valueChanged(int n) //fSplit
|
||||||
@ -309,6 +320,12 @@ void WideGraph::setDialFreq(double d) //setDialFreq
|
|||||||
ui->widePlot->setDialFreq(d);
|
ui->widePlot->setDialFreq(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WideGraph::setRxBand(QString band)
|
||||||
|
{
|
||||||
|
ui->widePlot->setRxBand(band);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WideGraph::on_fStartSpinBox_valueChanged(int n) //fStart
|
void WideGraph::on_fStartSpinBox_valueChanged(int n) //fStart
|
||||||
{
|
{
|
||||||
ui->widePlot->setStartFreq(n);
|
ui->widePlot->setStartFreq(n);
|
||||||
@ -384,12 +401,13 @@ void WideGraph::on_zeroSlider_valueChanged(int value) //Zero
|
|||||||
void WideGraph::on_gain2dSlider_valueChanged(int value) //Gain2
|
void WideGraph::on_gain2dSlider_valueChanged(int value) //Gain2
|
||||||
{
|
{
|
||||||
ui->widePlot->setPlot2dGain(value);
|
ui->widePlot->setPlot2dGain(value);
|
||||||
// ui->widePlot->draw(swide);
|
if(ui->widePlot->m_bScaleOK) ui->widePlot->draw(swide,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WideGraph::on_zero2dSlider_valueChanged(int value) //Zero2
|
void WideGraph::on_zero2dSlider_valueChanged(int value) //Zero2
|
||||||
{
|
{
|
||||||
ui->widePlot->setPlot2dZero(value);
|
ui->widePlot->setPlot2dZero(value);
|
||||||
|
// ui->widePlot->draw(swide,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WideGraph::setTol(int n) //setTol
|
void WideGraph::setTol(int n) //setTol
|
||||||
@ -398,3 +416,13 @@ void WideGraph::setTol(int n) //setTol
|
|||||||
ui->widePlot->DrawOverlay();
|
ui->widePlot->DrawOverlay();
|
||||||
ui->widePlot->update();
|
ui->widePlot->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WideGraph::on_smoSpinBox_valueChanged(int n)
|
||||||
|
{
|
||||||
|
m_nsmo=n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WideGraph::smoothYellow()
|
||||||
|
{
|
||||||
|
return m_nsmo;
|
||||||
|
}
|
||||||
|
@ -40,6 +40,8 @@ public:
|
|||||||
void setLockTxFreq(bool b);
|
void setLockTxFreq(bool b);
|
||||||
bool flatten();
|
bool flatten();
|
||||||
void setTol(int n);
|
void setTol(int n);
|
||||||
|
int smoothYellow();
|
||||||
|
void setRxBand(QString band);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void freezeDecode2(int n);
|
void freezeDecode2(int n);
|
||||||
@ -69,6 +71,7 @@ private slots:
|
|||||||
void on_zeroSlider_valueChanged(int value);
|
void on_zeroSlider_valueChanged(int value);
|
||||||
void on_gain2dSlider_valueChanged(int value);
|
void on_gain2dSlider_valueChanged(int value);
|
||||||
void on_zero2dSlider_valueChanged(int value);
|
void on_zero2dSlider_valueChanged(int value);
|
||||||
|
void on_smoSpinBox_valueChanged(int n);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readPalette();
|
void readPalette();
|
||||||
@ -88,6 +91,7 @@ private:
|
|||||||
qint32 m_fMin;
|
qint32 m_fMin;
|
||||||
qint32 m_fMax;
|
qint32 m_fMax;
|
||||||
qint32 m_nSubMode;
|
qint32 m_nSubMode;
|
||||||
|
qint32 m_nsmo;
|
||||||
|
|
||||||
bool m_lockTxFreq;
|
bool m_lockTxFreq;
|
||||||
bool m_bFlatten;
|
bool m_bFlatten;
|
||||||
|
499
widegraph.ui
499
widegraph.ui
@ -95,59 +95,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QSpinBox" name="waterfallAvgSpinBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
|
|
||||||
</property>
|
|
||||||
<property name="prefix">
|
|
||||||
<string>N Avg </string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>20</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="4">
|
|
||||||
<widget class="QComboBox" name="paletteComboBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>80</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Select waterfall palette</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QSpinBox" name="fSplitSpinBox">
|
<widget class="QSpinBox" name="fSplitSpinBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -158,7 +105,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>120</width>
|
<width>100</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@ -191,6 +138,72 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="6">
|
||||||
|
<widget class="QCheckBox" name="cbFlatten">
|
||||||
|
<property name="text">
|
||||||
|
<string>Flatten</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="4">
|
||||||
|
<widget class="QComboBox" name="paletteComboBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>125</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Select waterfall palette</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="7">
|
||||||
|
<widget class="QSlider" name="gain2dSlider">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>150</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Spectrum gain</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-50</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksAbove</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QSpinBox" name="bppSpinBox">
|
<widget class="QSpinBox" name="bppSpinBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -201,7 +214,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>120</width>
|
<width>100</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@ -234,169 +247,30 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
<item row="0" column="9">
|
||||||
<widget class="QSpinBox" name="fStartSpinBox">
|
<widget class="QLabel" name="labSmooth">
|
||||||
<property name="sizePolicy">
|
<property name="enabled">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<bool>false</bool>
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>100</width>
|
<width>65</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Frequency (Hz) at left edge of waterfall</string>
|
|
||||||
</property>
|
|
||||||
<property name="suffix">
|
|
||||||
<string> Hz</string>
|
|
||||||
</property>
|
|
||||||
<property name="prefix">
|
|
||||||
<string>Start </string>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>5000</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="9">
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="6">
|
|
||||||
<widget class="QCheckBox" name="cbFlatten">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Flatten</string>
|
<string>Smoothing</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="4">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="labPalette">
|
|
||||||
<property name="text">
|
|
||||||
<string> Palette</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="adjust_palette_push_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Adjust...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="3" rowspan="2">
|
|
||||||
<widget class="Line" name="line">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="5" rowspan="2">
|
|
||||||
<widget class="Line" name="line_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="7">
|
|
||||||
<widget class="QSlider" name="gain2dSlider">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>150</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Spectrum gain</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>-50</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>50</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="tickPosition">
|
|
||||||
<enum>QSlider::TicksAbove</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="8">
|
|
||||||
<widget class="QSlider" name="zeroSlider">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>150</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Waterfall zero</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>-50</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>50</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="tickPosition">
|
|
||||||
<enum>QSlider::TicksAbove</enum>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="7">
|
<item row="0" column="7">
|
||||||
<widget class="QSlider" name="gainSlider">
|
<widget class="QSlider" name="gainSlider">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>150</width>
|
<width>150</width>
|
||||||
@ -423,8 +297,139 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QSpinBox" name="fStartSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>90</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Frequency (Hz) at left edge of waterfall</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> Hz</string>
|
||||||
|
</property>
|
||||||
|
<property name="prefix">
|
||||||
|
<string>Start </string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>5000</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QSpinBox" name="waterfallAvgSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>90</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
|
||||||
|
</property>
|
||||||
|
<property name="prefix">
|
||||||
|
<string>N Avg </string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="5" rowspan="2">
|
||||||
|
<widget class="Line" name="line_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3" rowspan="2">
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="4">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labPalette">
|
||||||
|
<property name="text">
|
||||||
|
<string> Palette </string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="adjust_palette_push_button">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>65</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Adjust...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item row="1" column="8">
|
<item row="1" column="8">
|
||||||
<widget class="QSlider" name="zero2dSlider">
|
<widget class="QSlider" name="zero2dSlider">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>150</width>
|
<width>150</width>
|
||||||
@ -448,6 +453,88 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="8">
|
||||||
|
<widget class="QSlider" name="zeroSlider">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>150</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Waterfall zero</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-50</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksAbove</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="9">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="smoSpinBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>65</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Smoothing of Linear Average spectrum</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="10">
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -83,14 +83,15 @@ SOURCES += \
|
|||||||
soundin.cpp \
|
soundin.cpp \
|
||||||
meterwidget.cpp \
|
meterwidget.cpp \
|
||||||
signalmeter.cpp \
|
signalmeter.cpp \
|
||||||
WFPalette.cpp \
|
WFPalette.cpp \
|
||||||
plotter.cpp \
|
plotter.cpp \
|
||||||
widegraph.cpp \
|
widegraph.cpp \
|
||||||
about.cpp \
|
about.cpp \
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
decodedtext.cpp \
|
decodedtext.cpp \
|
||||||
messageaveraging.cpp
|
wsprnet.cpp \
|
||||||
|
messageaveraging.cpp
|
||||||
|
|
||||||
HEADERS += qt_helpers.hpp \
|
HEADERS += qt_helpers.hpp \
|
||||||
pimpl_h.hpp pimpl_impl.hpp \
|
pimpl_h.hpp pimpl_impl.hpp \
|
||||||
@ -102,7 +103,7 @@ HEADERS += qt_helpers.hpp \
|
|||||||
FrequencyLineEdit.hpp AudioDevice.hpp Detector.hpp Modulator.hpp psk_reporter.h \
|
FrequencyLineEdit.hpp AudioDevice.hpp Detector.hpp Modulator.hpp psk_reporter.h \
|
||||||
Transceiver.hpp TransceiverBase.hpp TransceiverFactory.hpp PollingTransceiver.hpp \
|
Transceiver.hpp TransceiverBase.hpp TransceiverFactory.hpp PollingTransceiver.hpp \
|
||||||
EmulateSplitTransceiver.hpp DXLabSuiteCommanderTransceiver.hpp HamlibTransceiver.hpp \
|
EmulateSplitTransceiver.hpp DXLabSuiteCommanderTransceiver.hpp HamlibTransceiver.hpp \
|
||||||
Configuration.hpp \
|
Configuration.hpp wsprnet.h \
|
||||||
signalmeter.h \
|
signalmeter.h \
|
||||||
meterwidget.h \
|
meterwidget.h \
|
||||||
logbook/logbook.h \
|
logbook/logbook.h \
|
||||||
|
192
wsprnet.cpp
Normal file
192
wsprnet.cpp
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
// Interface to WSPRnet website
|
||||||
|
//
|
||||||
|
// by Edson Pereira - PY2SDR
|
||||||
|
|
||||||
|
#include "wsprnet.h"
|
||||||
|
|
||||||
|
WSPRNet::WSPRNet(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
wsprNetUrl = "http://wsprnet.org/post?";
|
||||||
|
//wsprNetUrl = "http://127.0.0.1/post.php?";
|
||||||
|
networkManager = new QNetworkAccessManager(this);
|
||||||
|
connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkReply(QNetworkReply*)));
|
||||||
|
|
||||||
|
uploadTimer = new QTimer(this);
|
||||||
|
connect( uploadTimer, SIGNAL(timeout()), this, SLOT(work()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WSPRNet::upload(QString call, QString grid, QString rfreq, QString tfreq,
|
||||||
|
QString mode, QString tpct, QString dbm, QString version,
|
||||||
|
QString fileName)
|
||||||
|
{
|
||||||
|
m_call = call;
|
||||||
|
m_grid = grid;
|
||||||
|
m_rfreq = rfreq;
|
||||||
|
m_tfreq = tfreq;
|
||||||
|
m_mode = mode;
|
||||||
|
m_tpct = tpct;
|
||||||
|
m_dbm = dbm;
|
||||||
|
m_vers = version;
|
||||||
|
m_file = fileName;
|
||||||
|
|
||||||
|
// Open the wsprd.out file
|
||||||
|
QFile wsprdOutFile(fileName);
|
||||||
|
if (!wsprdOutFile.open(QIODevice::ReadOnly | QIODevice::Text) ||
|
||||||
|
wsprdOutFile.size() == 0) {
|
||||||
|
urlQueue.enqueue( wsprNetUrl + urlEncodeNoSpot());
|
||||||
|
m_uploadType = 1;
|
||||||
|
uploadTimer->start(200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the contents
|
||||||
|
while (!wsprdOutFile.atEnd()) {
|
||||||
|
QHash<QString,QString> query;
|
||||||
|
if ( decodeLine(wsprdOutFile.readLine(), query) ) {
|
||||||
|
// Prevent reporting data ouside of the current frequency band
|
||||||
|
float f = fabs(m_rfreq.toFloat() - query["tqrg"].toFloat());
|
||||||
|
if (f < 0.0002) {
|
||||||
|
urlQueue.enqueue( wsprNetUrl + urlEncodeSpot(query));
|
||||||
|
m_uploadType = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_urlQueueSize = urlQueue.size();
|
||||||
|
uploadTimer->start(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WSPRNet::networkReply(QNetworkReply *reply)
|
||||||
|
{
|
||||||
|
QString serverResponse = reply->readAll();
|
||||||
|
if( m_uploadType == 2) {
|
||||||
|
if (!serverResponse.contains(QRegExp("spot\\(s\\) added"))) {
|
||||||
|
emit uploadStatus("Upload Failed");
|
||||||
|
urlQueue.clear();
|
||||||
|
uploadTimer->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlQueue.isEmpty()) {
|
||||||
|
emit uploadStatus("done");
|
||||||
|
QFile::remove(m_file);
|
||||||
|
uploadTimer->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WSPRNet::decodeLine(QString line, QHash<QString,QString> &query)
|
||||||
|
{
|
||||||
|
// 130223 2256 7 -21 -0.3 14.097090 DU1MGA PK04 37 0 40 0
|
||||||
|
// Date Time Sync dBm DT Freq Msg
|
||||||
|
// 1 2 3 4 5 6 -------7------ 8 9 10
|
||||||
|
QRegExp rx("^(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+([+-]?\\d+)\\s+([+-]?\\d+\\.\\d+)\\s+(\\d+\\.\\d+)\\s+(.*)\\s+([+-]?\\d+)\\s+([+-]?\\d+)\\s+([+-]?\\d+)");
|
||||||
|
if (rx.indexIn(line) != -1) {
|
||||||
|
int msgType = 0;
|
||||||
|
QString msg = rx.cap(7);
|
||||||
|
msg.remove(QRegExp("\\s+$"));
|
||||||
|
msg.remove(QRegExp("^\\s+"));
|
||||||
|
QString call, grid, dbm;
|
||||||
|
QRegExp msgRx;
|
||||||
|
|
||||||
|
// Check for Message Type 1
|
||||||
|
msgRx.setPattern("^([A-Z0-9]{3,6})\\s+([A-Z]{2}\\d{2})\\s+(\\d+)");
|
||||||
|
if (msgRx.indexIn(msg) != -1) {
|
||||||
|
msgType = 1;
|
||||||
|
call = msgRx.cap(1);
|
||||||
|
grid = msgRx.cap(2);
|
||||||
|
dbm = msgRx.cap(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for Message Type 2
|
||||||
|
msgRx.setPattern("^([A-Z0-9/]+)\\s+(\\d+)");
|
||||||
|
if (msgRx.indexIn(msg) != -1) {
|
||||||
|
msgType = 2;
|
||||||
|
call = msgRx.cap(1);
|
||||||
|
grid = "";
|
||||||
|
dbm = msgRx.cap(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for Message Type 3
|
||||||
|
msgRx.setPattern("^<([A-Z0-9/]+)>\\s+([A-Z]{2}\\d{2}[A-Z]{2})\\s+(\\d+)");
|
||||||
|
if (msgRx.indexIn(msg) != -1) {
|
||||||
|
msgType = 3;
|
||||||
|
call = msgRx.cap(1);
|
||||||
|
grid = msgRx.cap(2);
|
||||||
|
dbm = msgRx.cap(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unknown message format
|
||||||
|
if (!msgType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
query["function"] = "wspr";
|
||||||
|
query["date"] = rx.cap(1);
|
||||||
|
query["time"] = rx.cap(2);
|
||||||
|
query["sig"] = rx.cap(4);
|
||||||
|
query["dt"] = rx.cap(5);
|
||||||
|
query["drift"] = rx.cap(8);
|
||||||
|
query["tqrg"] = rx.cap(6);
|
||||||
|
query["tcall"] = call;
|
||||||
|
query["tgrid"] = grid;
|
||||||
|
query["dbm"] = dbm;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WSPRNet::urlEncodeNoSpot()
|
||||||
|
{
|
||||||
|
QString queryString;
|
||||||
|
queryString += "function=wsprstat&";
|
||||||
|
queryString += "rcall=" + m_call + "&";
|
||||||
|
queryString += "rgrid=" + m_grid + "&";
|
||||||
|
queryString += "rqrg=" + m_rfreq + "&";
|
||||||
|
queryString += "tpct=" + m_tpct + "&";
|
||||||
|
queryString += "tqrg=" + m_tfreq + "&";
|
||||||
|
queryString += "dbm=" + m_dbm + "&";
|
||||||
|
queryString += "version=" + m_vers;
|
||||||
|
if(m_mode=="WSPR-2") queryString += "&mode=2";
|
||||||
|
if(m_mode=="WSPR-15") queryString += "&mode=15";
|
||||||
|
return queryString;;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WSPRNet::urlEncodeSpot(QHash<QString,QString> query)
|
||||||
|
{
|
||||||
|
QString queryString;
|
||||||
|
queryString += "function=" + query["function"] + "&";
|
||||||
|
queryString += "rcall=" + m_call + "&";
|
||||||
|
queryString += "rgrid=" + m_grid + "&";
|
||||||
|
queryString += "rqrg=" + m_rfreq + "&";
|
||||||
|
queryString += "date=" + query["date"] + "&";
|
||||||
|
queryString += "time=" + query["time"] + "&";
|
||||||
|
queryString += "sig=" + query["sig"] + "&";
|
||||||
|
queryString += "dt=" + query["dt"] + "&";
|
||||||
|
queryString += "drift=" + query["drift"] + "&";
|
||||||
|
queryString += "tqrg=" + query["tqrg"] + "&";
|
||||||
|
queryString += "tcall=" + query["tcall"] + "&";
|
||||||
|
queryString += "tgrid=" + query["tgrid"] + "&";
|
||||||
|
queryString += "dbm=" + query["dbm"] + "&";
|
||||||
|
queryString += "version=" + m_vers;
|
||||||
|
if(m_mode=="WSPR-2") queryString += "&mode=2";
|
||||||
|
if(m_mode=="WSPR-15") queryString += "&mode=15";
|
||||||
|
return queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WSPRNet::work()
|
||||||
|
{
|
||||||
|
if (!urlQueue.isEmpty()) {
|
||||||
|
QUrl url(urlQueue.dequeue());
|
||||||
|
QNetworkRequest request(url);
|
||||||
|
networkManager->get(request);
|
||||||
|
QString status = "Uploading Spot " + QString::number(m_urlQueueSize - urlQueue.size()) +
|
||||||
|
"/"+ QString::number(m_urlQueueSize);
|
||||||
|
emit uploadStatus(status);
|
||||||
|
} else {
|
||||||
|
uploadTimer->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
37
wsprnet.h
Normal file
37
wsprnet.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef WSPRNET_H
|
||||||
|
#define WSPRNET_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtNetwork>
|
||||||
|
|
||||||
|
class WSPRNet : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit WSPRNet(QObject *parent = 0);
|
||||||
|
void upload(QString call, QString grid, QString rfreq, QString tfreq,
|
||||||
|
QString mode, QString tpct, QString dbm, QString version,
|
||||||
|
QString fileName);
|
||||||
|
static bool decodeLine(QString line, QHash<QString,QString> &query);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void uploadStatus(QString);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void networkReply(QNetworkReply *);
|
||||||
|
void work();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QNetworkAccessManager *networkManager;
|
||||||
|
QString wsprNetUrl;
|
||||||
|
QString m_call, m_grid, m_rfreq, m_tfreq, m_mode, m_tpct, m_dbm, m_vers, m_file;
|
||||||
|
QQueue<QString> urlQueue;
|
||||||
|
QTimer *uploadTimer;
|
||||||
|
int m_urlQueueSize;
|
||||||
|
int m_uploadType;
|
||||||
|
|
||||||
|
QString urlEncodeNoSpot();
|
||||||
|
QString urlEncodeSpot(QHash<QString,QString> spot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WSPRNET_H
|
Loading…
Reference in New Issue
Block a user