diff --git a/CMakeLists.txt b/CMakeLists.txt
index d9f50f6..4bafa56 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -295,6 +295,12 @@ set (wsjt_FSRCS
lib/timer_impl.f90
lib/timer_module.f90
lib/wavhdr.f90
+ lib/js8b_module.f90
+ lib/js8b_decode.f90
+ lib/js8c_module.f90
+ lib/js8c_decode.f90
+ lib/js8d_module.f90
+ lib/js8d_decode.f90
# remaining non-module sources
lib/addit.f90
@@ -311,6 +317,7 @@ set (wsjt_FSRCS
lib/azdist.f90
lib/badmsg.f90
lib/ft8/baseline.f90
+ # lib/js8/baselinejs8.f90
lib/bpdecode40.f90
lib/bpdecode144.f90
lib/ft8/bpdecode174.f90
@@ -350,7 +357,6 @@ set (wsjt_FSRCS
lib/ft8/extractmessage174.f90
lib/fano232.f90
lib/fast9.f90
- lib/fast_decode.f90
lib/fchisq.f90
lib/fchisq0.f90
lib/fchisq65.f90
@@ -361,7 +367,6 @@ set (wsjt_FSRCS
lib/filbig.f90
lib/ft8/filt8.f90
lib/fitcal.f90
- lib/fix_contest_msg.f90
lib/flat1.f90
lib/flat1a.f90
lib/flat1b.f90
@@ -378,19 +383,16 @@ set (wsjt_FSRCS
lib/freqcal.f90
lib/ft8/ft8apset.f90
lib/ft8/ft8b.f90
+ # lib/js8/js8params.f90
+ # lib/js8/js8b.f90
lib/ft8/ft8code.f90
lib/ft8/ft8_downsample.f90
+ # lib/js8/js8_downsample.f90
lib/ft8/ft8sim.f90
- lib/gen4.f90
- lib/gen65.f90
- lib/gen9.f90
- lib/geniscat.f90
lib/ft8/genft8.f90
- lib/genmsk144.f90
- lib/genmsk40.f90
- lib/genqra64.f90
+ lib/js8/genjs8.f90
lib/ft8/genft8refsig.f90
- lib/genwspr.f90
+ # lib/js8/genjs8refsig.f90
lib/geodist.f90
lib/getlags.f90
lib/getmet4.f90
@@ -401,7 +403,6 @@ set (wsjt_FSRCS
lib/ft8/h1.f90
lib/hash.f90
lib/hint65.f90
- lib/hspec.f90
lib/indexx.f90
lib/init_random_seed.f90
lib/interleave4.f90
@@ -414,6 +415,9 @@ set (wsjt_FSRCS
lib/jtmsg.f90
lib/ldpcsim144.f90
lib/ft8/ldpcsim174.f90
+ lib/js8/ldpcsim174js8b.f90
+ lib/js8/ldpcsim174js8c.f90
+ lib/js8/ldpcsim174js8d.f90
lib/ldpcsim40.f90
lib/libration.f90
lib/lorentzian.f90
@@ -423,20 +427,6 @@ set (wsjt_FSRCS
lib/moondopjpl.f90
lib/morse.f90
lib/move.f90
- lib/msk144d2.f90
- lib/msk40decodeframe.f90
- lib/msk144decodeframe.f90
- lib/msk144sd.f90
- lib/msk40spd.f90
- lib/msk144spd.f90
- lib/msk40sync.f90
- lib/msk144sync.f90
- lib/msk40_freq_search.f90
- lib/msk144_freq_search.f90
- lib/mskrtd.f90
- lib/msk144signalquality.f90
- lib/msk144sim.f90
- lib/mskrtd.f90
lib/ft8/osd174.f90
lib/pctile.f90
lib/peakdt9.f90
@@ -466,6 +456,7 @@ set (wsjt_FSRCS
lib/stdmsg.f90
lib/subtract65.f90
lib/ft8/subtractft8.f90
+ # lib/js8/subtractjs8.f90
lib/sun.f90
lib/symspec.f90
lib/symspec2.f90
@@ -474,7 +465,9 @@ set (wsjt_FSRCS
lib/sync64.f90
lib/sync65.f90
lib/ft8/sync8.f90
+ # lib/js8/syncjs8.f90
lib/ft8/sync8d.f90
+ # lib/js8/syncjs8d.f90
lib/sync9.f90
lib/sync9f.f90
lib/sync9w.f90
@@ -502,46 +495,24 @@ set (wsjt_FSRCS
# temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit
set_source_files_properties (lib/slasubs.f PROPERTIES COMPILE_FLAGS -O2)
-set (ka9q_CSRCS
- lib/ftrsd/decode_rs.c
- lib/ftrsd/encode_rs.c
- lib/ftrsd/init_rs.c
- )
-set_source_files_properties (${ka9q_CSRCS} PROPERTIES COMPILE_FLAGS -Wno-sign-compare)
-
-set (qra_CSRCS
- lib/qra/qra64/qra64.c
- lib/qra/qra64/qra64_subs.c
- lib/qra/qracodes/npfwht.c
- lib/qra/qracodes/pdmath.c
- lib/qra/qracodes/qra12_63_64_irr_b.c
- lib/qra/qracodes/qra13_64_64_irr_e.c
- lib/qra/qracodes/qracodes.c
- lib/qra/qracodes/normrnd.c
- )
-
set (sqlite3_CSRCS
vendor/sqlite3/sqlite3.c
)
set (wsjt_CSRCS
- ${ka9q_CSRCS}
- lib/ftrsd/ftrsdap.c
lib/sgran.c
lib/golay24_table.c
lib/gran.c
lib/igray.c
lib/init_random_seed.c
lib/ldpc32_table.c
- lib/wsprd/nhash.c
+ lib/nhash.c
lib/tab.c
lib/tmoonsub.c
lib/usleep.c
lib/vit213.c
lib/wisdom.c
- lib/wrapkarn.c
${ldpc_CSRCS}
- ${qra_CSRCS}
)
set (wsjt_qt_UISRCS
@@ -1026,6 +997,15 @@ target_link_libraries (wsjt_qtmm Qt5::Multimedia)
add_executable (ldpcsim174 lib/ft8/ldpcsim174.f90 wsjtx.rc)
target_link_libraries (ldpcsim174 wsjt_fort wsjt_cxx)
+add_executable (ldpcsim174js8b lib/js8/ldpcsim174js8b.f90 wsjtx.rc)
+target_link_libraries (ldpcsim174js8b wsjt_fort wsjt_cxx)
+
+add_executable (ldpcsim174js8c lib/js8/ldpcsim174js8c.f90 wsjtx.rc)
+target_link_libraries (ldpcsim174js8c wsjt_fort wsjt_cxx)
+
+add_executable (ldpcsim174js8d lib/js8/ldpcsim174js8d.f90 wsjtx.rc)
+target_link_libraries (ldpcsim174js8d wsjt_fort wsjt_cxx)
+
add_executable (js8 ${js8_FSRCS} ${js8_CXXSRCS} wsjtx.rc)
if (${OPENMP_FOUND} OR APPLE)
if (APPLE)
diff --git a/Configuration.ui b/Configuration.ui
index 58b5caf..9cc216d 100644
--- a/Configuration.ui
+++ b/Configuration.ui
@@ -890,56 +890,43 @@ text message.
-
-
-
-
- -
-
-
- Idle Timeout
-
-
-
-
-
-
-
-
-
- Disable automatic transmissions after:
-
-
- tx_watchdog_spin_box
-
-
-
- -
-
-
- <html><head/><body><p>Number of minutes before unattended heartbeat transmissions are aborted.</p></body></html>
-
-
- Disabled
-
-
- minutes of inactivity
-
-
-
-
-
- 0
-
-
- 1440
-
-
- 1
-
-
- 60
-
-
-
-
+ -
+
+
+ Idle timeout - disable autoreply after:
+
+
+ tx_watchdog_spin_box
+
+
+
+ -
+
+
+ <html><head/><body><p>Number of minutes before unattended heartbeat transmissions are aborted.</p></body></html>
+
+
+ Disabled
+
+
+ minutes of inactivity
+
+
+
+
+
+ 0
+
+
+ 1440
+
+
+ 1
+
+
+ 60
+
+
@@ -4383,12 +4370,12 @@ soundcard changes
-
-
+
+
+
-
diff --git a/Modulator.cpp b/Modulator.cpp
index b80acc8..47e795c 100644
--- a/Modulator.cpp
+++ b/Modulator.cpp
@@ -71,7 +71,19 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
m_toneSpacing = toneSpacing;
m_bFastMode=fastMode;
m_TRperiod=TRperiod;
- unsigned delay_ms = 1920 == m_nsps && 15 == m_period ? 500 : 250; // 1000;
+ unsigned delay_ms = 0;
+ if(m_TRperiod == JS8A_TX_SECONDS){
+ delay_ms = JS8A_START_DELAY_MS;
+ }
+ else if(m_TRperiod == JS8B_TX_SECONDS){
+ delay_ms = JS8B_START_DELAY_MS;
+ }
+ else if(m_TRperiod == JS8C_TX_SECONDS){
+ delay_ms = JS8C_START_DELAY_MS;
+ }
+ else if(m_TRperiod == JS8D_TX_SECONDS){
+ delay_ms = JS8D_START_DELAY_MS;
+ }
// noise generator parameters
if (m_addNoise) {
diff --git a/Versions.cmake b/Versions.cmake
index d828414..ed59e29 100644
--- a/Versions.cmake
+++ b/Versions.cmake
@@ -1,6 +1,6 @@
# Version number components
-set (WSJTX_VERSION_MAJOR 1)
-set (WSJTX_VERSION_MINOR 2)
+set (WSJTX_VERSION_MAJOR 2)
+set (WSJTX_VERSION_MINOR 0)
set (WSJTX_VERSION_PATCH 0)
set (WSJTX_RC 0) # release candidate number, comment out or zero for development versions
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
diff --git a/bsj.mod b/bsj.mod
new file mode 100644
index 0000000..aecd818
Binary files /dev/null and b/bsj.mod differ
diff --git a/commons.h b/commons.h
index 1dd17e8..759816a 100644
--- a/commons.h
+++ b/commons.h
@@ -7,19 +7,31 @@
#define RX_SAMPLE_RATE 12000
#define JS8_NUM_SYMBOLS 79
+#define JS8_ENABLE_JS8B 1
+#define JS8_ENABLE_JS8C 1
+#define JS8_ENABLE_JS8D 0
-#ifndef JS8_80HZ
-#define JS8_80HZ 0
-#endif
+#define JS8A_SYMBOL_SAMPLES 1920
+#define JS8A_TX_SECONDS 15
+#define JS8A_START_DELAY_MS 500
-#if JS8_80HZ
-#define JS8_SYMBOL_SAMPLES 1200 // 480 // 600 // 1200 // 1920
-#define JS8_TX_SECONDS 10 // 5 // 6 // 10 // 15
-#define JS8_SYMBOL_STOP 32 // 12 // 16 // 32 // 50 // ??? no idea why this works...
+#define JS8B_SYMBOL_SAMPLES 1200
+#define JS8B_TX_SECONDS 10
+#define JS8B_START_DELAY_MS 200
+
+#define JS8C_SYMBOL_SAMPLES 600
+#define JS8C_TX_SECONDS 6
+#define JS8C_START_DELAY_MS 100
+
+#define JS8D_IS_ULTRA 1
+#if JS8D_IS_ULTRA
+#define JS8D_SYMBOL_SAMPLES 384
+#define JS8D_TX_SECONDS 4
+#define JS8D_START_DELAY_MS 100
#else
-#define JS8_SYMBOL_SAMPLES 1920
-#define JS8_TX_SECONDS 15
-#define JS8_SYMBOL_STOP 50
+#define JS8D_SYMBOL_SAMPLES 4000
+#define JS8D_TX_SECONDS 30
+#define JS8D_START_DELAY_MS 100
#endif
#ifndef TEST_FOX_WAVE_GEN
diff --git a/decodedtext.cpp b/decodedtext.cpp
index 6e183bf..9723ce1 100644
--- a/decodedtext.cpp
+++ b/decodedtext.cpp
@@ -15,7 +15,7 @@ namespace
QRegularExpression words_re {R"(^(?:(?(?:CQ|DE|QRZ)(?:\s?DX|\s(?:[A-Z]{2}|\d{3}))|[A-Z0-9/]+)\s)(?:(?[A-Z0-9/]+)(?:\s(?[-+A-Z0-9]+)(?:\s(?(?:OOO|(?!RR73)[A-R]{2}[0-9]{2})))?)?)?)"};
}
-DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString const& my_grid)
+DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString const& my_grid, int submode)
: string_ {the_string.left (the_string.indexOf (QChar::Nbsp))} // discard appended info
, padding_ {string_.indexOf (" ") > 4 ? 2 : 0} // allow for seconds
, contest_mode_ {contest_mode}
@@ -25,6 +25,7 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
, isHeartbeat_(false)
, isAlt_(false)
, bits_{0}
+ , submode_{submode}
{
if(message_.length() >= 1) {
message_ = message_.left (21).remove (QRegularExpression {"[<>]"});
@@ -69,12 +70,13 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
tryUnpack();
}
-DecodedText::DecodedText (QString const& js8callmessage, int bits):
+DecodedText::DecodedText (QString const& js8callmessage, int bits, int submode):
frameType_(Varicode::FrameUnknown),
message_(js8callmessage),
isHeartbeat_(false),
isAlt_(false),
- bits_(bits)
+ bits_(bits),
+ submode_(submode)
{
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
@@ -89,9 +91,13 @@ bool DecodedText::tryUnpack(){
bool unpacked = false;
if(!unpacked){
- unpacked = tryUnpackData();
+ unpacked = tryUnpackFastData();
}
+ if(!unpacked){
+ unpacked = tryUnpackData();
+ }
+
if(!unpacked){
unpacked = tryUnpackHeartbeat();
}
@@ -115,6 +121,10 @@ bool DecodedText::tryUnpackHeartbeat(){
return false;
}
+ if((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData){
+ return false;
+ }
+
bool isAlt = false;
quint8 type = Varicode::FrameUnknown;
quint8 bits3 = 0;
@@ -159,6 +169,10 @@ bool DecodedText::tryUnpackCompound(){
return false;
}
+ if((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData){
+ return false;
+ }
+
QStringList cmp;
if(!parts.at(0).isEmpty()){
cmp.append(parts.at(0));
@@ -188,6 +202,10 @@ bool DecodedText::tryUnpackDirected(){
return false;
}
+ if((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData){
+ return false;
+ }
+
quint8 type = Varicode::FrameUnknown;
QStringList parts = Varicode::unpackDirectedMessage(m, &type);
@@ -218,7 +236,11 @@ bool DecodedText::tryUnpackData(){
// data frames calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
- return false;
+ return false;
+ }
+
+ if((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData){
+ return false;
}
QString data = Varicode::unpackDataMessage(m);
@@ -232,6 +254,33 @@ bool DecodedText::tryUnpackData(){
return true;
}
+bool DecodedText::tryUnpackFastData(){
+ QString m = message().trimmed();
+
+ // data frames calls will always be 12+ chars and contain no spaces.
+ if(m.length() < 12 || m.contains(' ')){
+ return false;
+ }
+
+ if((bits_ & Varicode::JS8CallData) != Varicode::JS8CallData){
+ return false;
+ }
+
+ if(submode_ != Varicode::JS8CallFast && submode_ != Varicode::JS8CallTurbo && submode_ != Varicode::JS8CallUltra){
+ return false;
+ }
+
+ QString data = Varicode::unpackFastDataMessage(m);
+
+ if(data.isEmpty()){
+ return false;
+ }
+
+ message_ = data;
+ frameType_ = Varicode::FrameData;
+ return true;
+}
+
QStringList DecodedText::messageWords () const
{
if (is_standard_)
diff --git a/decodedtext.h b/decodedtext.h
index 896eb2c..7872ccb 100644
--- a/decodedtext.h
+++ b/decodedtext.h
@@ -30,14 +30,15 @@
class DecodedText
{
public:
- explicit DecodedText (QString const& message, bool, QString const& my_grid);
- explicit DecodedText (QString const& js8callmessage, int bits);
+ explicit DecodedText (QString const& message, bool, QString const& my_grid, int submode);
+ explicit DecodedText (QString const& js8callmessage, int bits, int submode);
bool tryUnpack();
bool tryUnpackHeartbeat();
bool tryUnpackCompound();
bool tryUnpackDirected();
bool tryUnpackData();
+ bool tryUnpackFastData();
quint8 frameType() const { return frameType_; }
@@ -110,6 +111,7 @@ private:
QString message_;
bool is_standard_;
int bits_;
+ int submode_;
};
#endif // DECODEDTEXT_H
diff --git a/js8.mod b/js8.mod
new file mode 100644
index 0000000..71d9ef2
Binary files /dev/null and b/js8.mod differ
diff --git a/js8a.mod b/js8a.mod
new file mode 100644
index 0000000..76b704c
Binary files /dev/null and b/js8a.mod differ
diff --git a/js8params.mod b/js8params.mod
new file mode 100644
index 0000000..ded98cc
Binary files /dev/null and b/js8params.mod differ
diff --git a/keyeater.cpp b/keyeater.cpp
index 55bc57e..8f45f61 100644
--- a/keyeater.cpp
+++ b/keyeater.cpp
@@ -1,5 +1,20 @@
#include "keyeater.h"
+
+bool KeyPressEater::eventFilter(QObject *obj, QEvent *event){
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = static_cast(event);
+ bool processed = false;
+ emit this->keyPressed(obj, keyEvent, &processed);
+ if(processed){
+ return true;
+ }
+ }
+
+ // standard event processing
+ return QObject::eventFilter(obj, event);
+}
+
bool EscapeKeyPressEater::eventFilter(QObject *obj, QEvent *event){
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast(event);
diff --git a/keyeater.h b/keyeater.h
index e51c53d..abb011e 100644
--- a/keyeater.h
+++ b/keyeater.h
@@ -5,6 +5,20 @@
#include
#include
+class KeyPressEater : public QObject
+{
+ Q_OBJECT
+public:
+ KeyPressEater(){}
+ virtual ~KeyPressEater(){}
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *event);
+
+public:
+ Q_SIGNAL void keyPressed(QObject *obj, QKeyEvent *evt, bool *pProcessed);
+};
+
class EscapeKeyPressEater : public QObject
{
Q_OBJECT
diff --git a/lib/CQnnnCAT.txt b/lib/CQnnnCAT.txt
deleted file mode 100644
index d7e92d0..0000000
--- a/lib/CQnnnCAT.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-Before using the new "CQ nnn ..." feature in JTMSK mode, I suggest
-performing the following tests of the necessary CAT control for your
-radio. (I'm assuming that you already have some experience with
-JTMSK.)
-
-TEST 1:
---------------------------------------------------------------------------
-1. Start WSJT-X
-2. Settings: "Enable VHF/UHF/Microwave features, "Rx frequency offset
- with 'CQ nnn ...'", Split=Rig, or Split="Fake it"
-3. Main screen settings: Band=50.280, mode=JTMSK, T/R=15 s
-4. Activate CQRx, set CQ Rx=265
- ==> Rx dial should now read 50.265 and Tx6 should be queued
-5. Click "Enable Tx"
- ==> Tx sequences should occur at 50.280, Rx at 50.265
-
-With most rigs, this test should work with Split configured as either
-"Rig" or "Fake it".
-
-TEST 2:
---------------------------------------------------------------------------
-1. Start WSJT-X
-2. Settings: MyCall=K1JT, "Enable VHF/UHF/Microwave features,
- "Rx frequency offset with 'CQ nnn ...'", Split=Rig or "Fake it"
-4. Main screen settings: Band=50.280, mode=JTMSK, T/R=15 s
-5. Open file 150826_120515.wav
- ==> see decoded message "K1JT VE1SKY FN74"
-6. Click "Monitor" to restart monitoring
-7. Activate CQRx, set CQ Rx=265
- ==> Rx dial should now read 50.265; Tx6 should be queued
-8. Click "Enable Tx"
- ==> Tx sequences should occur at 50.280, Rx at 50.265
-9. After the start of a transmission, double-click on the decoded message
- "K1JT VE1SKY FN74"
- ==> Tx2 should be generated and queued; transmission will pause
- briefly, Tx freq changed to 50.265, then Tx resumed.
-
-The test file is posted at
-http://physics.princeton.edu/pulsar/K1JT/150826_120515.wav
diff --git a/lib/DXped_Operations.txt b/lib/DXped_Operations.txt
deleted file mode 100644
index 9dc268b..0000000
--- a/lib/DXped_Operations.txt
+++ /dev/null
@@ -1,186 +0,0 @@
- White Paper: FT8 for DXpeditions
- -----------------------------------
- Joe Taylor, K1JT - October 27, 2017
-
-Assumptions:
-
-1. WSJT-X will have two distinct options that enable the maximum-rate
-QSO exchanges described below. Fox must select "Fox"; all Hounds must
-select "Hound".
-
-2. There will be an announced basic dial frequency for each band, say
-f0=14082 kHz for 20m. This is the basic Channel.
-
-3. Fox always transmits in the 1st sequence, 200-800 Hz above f0.
-
-4. Hounds call in 2nd sequence, 1000-5000 Hz above f0. Hounds
-transmitting below f0+1000 Hz will not be answered.
-
-5. If found necessary, additional Channels may be defined in which
-Hounds can transmit. (However, I suggest that CQ-by-call-area may
-be easier to implement and use; and the software could be made to
-prevent Hounds in the wrong area from transmitting.)
-
-6. Ideally, Fox and Hounds should all use CAT control configured with
-*Split Operation* set to *Rig* or *Fake It*, and transceiver dial
-frequencies should best be calibrated to within a few Hz. (WSJT-X
-provides tools that make this fairly easy to do.)
-
-
-When Fox is running a pileup, QSOs will look something like the
-following exchanges. Here I've assumed the Fox callsign is KH1DX,
-his locator AJ10:
-
-------------------------------------------------------------------------
- Fox Hounds
-------------------------------------------------------------------------
-1. CQ KH1DX AJ10
-2. KH1DX K1ABC FN42, KH1DX W9XYZ EN37, ...
-3. K1ABC KH1DX -13
-4. KH1DX K1ABC R-11
-5. K1ABC RR73; W9XYZ -17
-6. ... no copy from W9XYZ ...
-7. W9XYZ KH1DX -17
-8. ... no copy from W9XYZ ...
-9. G4AAA KH1DX -11
-10. KH1DX G4AAA R-03
-11. G4AAA RR73; DL3BBB -12
-12. KH1DX DL3BBB R-09
-13. DL3BBB RR73; DE
-14. ...
-------------------------------------------------------------------------
-
-All messages except those containing "<...>" are standard FT8 messages
-(i3bit=0, iFreeText=0). Hounds transmit only standard messages.
-
-Fox transmits standard messages and also special messages with
-i3bit=1. The special messages contain a callsign whose completed QSO
-is being acknowledged; a callsign for the next station to be worked; a
-hash code corresponding to the Fox callsign; and a signal report.
-Users will see the Fox callsign enclosed in angle brackets, .
-The 72-bit message payload contains two 28-bit callsigns, a 10-bit
-hash code, and a 6-bit signal report. If no call has been queued up
-by Fox for the next QSO, the acknowledgment message takes the
-abbreviated form shown in line 13 above.
-
-When a Hound receives a message with i3bit=1, the decoder interprets
-the remaining 72 bits as described above. If the 10-bit hash code
-matches that for Fox's callsign, the message is displayed as in the
-QSO exchanges shown above. Otherwise the message is considered a
-false decode and is not displayed.
-
-
-Station Setup and Operation for FOX
------------------------------------
-
-A wide Rx bandwidth (up to 5 kHz) is selected. The basic dial
-frequency is set 1 kHz above f0 (thus 14083 kHz in my example) and the
-audio TxFreq somewhere between -200 and -800 Hz. (Yes, negative
-numbers are OK. *Split Operation* will reset the Tx dial frequency as
-needed and will keep the generated Tx audio frequency between 1500 and
-2000 Hz.) Hounds with audio TxFreq set to N Hz will be received by Fox
-at N-1000 Hz.
-
-WSJT-X at Fox will maintain and display a list of all decoded Hounds
-calling Fox in the past 2 to 4 Rx cycles. The list might look
-something like this (but typically will be much longer):
-
-----------------------------
-Call Grid Rpt Freq
-----------------------------
-AA2UK FM29 -11 240
-AD9H EN61 +02 1260
-K0TPP EM48 -15 1980
-N2BJ EN61 +11 540
-N4NDR EL98 -17 4620
-NX4E EM70 +00 3780
-ON3LA JN29 -10 3300
-PD9BG JO21 -21 2100
-PJ4/KA1XYZ FK60 -07 1020
-VE1SKY FN74 +03 1620
-WB2REM EL97 -13 3060
-...
-----------------------------
-
-Fox can choose to have the list sorted on any column.
-
-Fox selects a Hound to call next by clicking on a line. Or he can hit
-"F1" to have the program select a caller according to one of these
-criteria (maybe others as well?):
-
- - Weakest caller
- - Strongest caller
- - Strongest one below -N dB (with N selectable)
- - Choose a call at random
- - Random choice with S/N between snrMin and snrMax dB.
-
-After a particular Hound has been called, Fox's Auto-Sequencer looks
-for a response containing "R+rpt" originating from that same callsign.
-If such a message is received, Fox's next transmission will be the
-special "acknowledge-and-call-next" type, with i3bit=1. If the
-expected message is not received, as in example line 6 above, the
-report is sent to the same station again. If the second attempt fails
-and another Hound callsign has been queued up, the QSO is aborted and
-the next Hound is called.
-
-
-Station Setup and Operation for Hounds
---------------------------------------
-
-Dial frequency is set to f0, 14082 kHz in my example. Rx bandwidth and
-displayed range on the Wide Graph can be anything convenient, say 200
-to 2600 Hz. (Signal from Fox will be expected between 200 and 800
-Hz.) Enter callsign and locator of Fox on WSJT-X main window as *DX
-Call* and *DX Grid*. Choose a TxFreq offset of 1000 + 60*N for some N
-in the range 1 to 80 (maybe even higher?). Move TxFreq as desired,
-hoping to find a clear slot, by using Shift+F11 and Shift+F12.
-
- - Hit F1 to call Fox in your next Tx sequence. Yes, you must hit F1
- repeatedly, in order to keep calling.
-
- - The Auto-sequencer will watch for a decoded message that contains
- "MyCall DXcall rpt" or "MyCall rpt". When one of these is
- received, your next transmission will be "DXcall MyCall R+rpt",
- sent automatically.
-
- - After you send the "R+rpt" message, AutoSeq will watch for a
- message that starts with "MyCall RR73; ...". When that is
- received, you're in his log, and you'll be prompted to log the QSO.
-
-Random thoughts
----------------
-
-Fox's decoder has access to signals in a 4 kHz (maybe even 5 kHz?)
-window. At 60 Hz intervals, that's enough for around 65 (or 80?)
-non-overlapping Hound signals. If the pileup becomes too deep, more
-spectrum might be used; but note that WSJT-X can't access more than 5
-kHz at one time. A better solution might be for Fox to call "CQ n
-KH1DX AJ10", where n is a single digit indicating call area. The
-decoder could then limit the list of eligible calls to those in the
-specified call area. After decoding such a CQ, the software at Hound
-could refuse to transmit unless MyCall falls in the specified call
-area. (Other special CQ formats can be imagined that would limit the
-eligible Hound callsigns even further.)
-
-We haven't thought much, yet, about logging issues for Fox. I imagine
-we could do what's necessary to join a N1MM+ logging network, if that's
-deemed desirable.
-
-A few questions:
-
-Q1: Should the Auto-Sequencer allow for other cases in which a QSO has
-been initiated by Fox, but one of next two messages is not copied by
-either Fox or Hound? For example, what if K1ABC does not copy message
-#5? Should he keep sending his message "KH1DX K1ABC R-11" ? If Fox
-receives this message again, should he acknowledge again? And poor
-W9XYZ, who never received an acknowledgment, will probably keep
-sending "KH1DX W9XYZ R-19", or whatever. If Fox eventually copies the
-message, should the program remember that W9XYZ had been called, and
-thus send him an acknowledgment?
-
-Q2: Should we provide a stack for several to-be-called callsigns,
-rather than just one? Should re-ordering of calls in the stack be
-permitted?
-
-Q3: Can we handle WSJT-X "Type 1" and "Type 2" compound callsigns, for
-Hounds?
diff --git a/lib/DXped_pseudo_code.txt b/lib/DXped_pseudo_code.txt
deleted file mode 100644
index 081bfda..0000000
--- a/lib/DXped_pseudo_code.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-Auto-Sequencing algorithm for DXpedition station:
-
-Start:
- CQMsg = "CQ KH1DX" (or "CQ UP KH1DX", "CQ 116 KH1DX", etc.)
- TxMsg = CQMsg
- Ntry = 0
- QCALL = "" # Callsign of current QSO partner
- go to Transmit
-
-Transmit:
- TX # (... takes 13.6 s)
- go to Receive
-
-Receive:
- RX # (... takes ~14 s)
- N = number of decodes # RxMsg[i], i=1,N
- if(N == 0)
- go to Transmit
- J = index of a reply from current QCALL # RxMsg[J] = "KH1DX QCALL R"
-
- if(QCALL == "") # No QSO in progress
- Select new QCALL # Op chooses a caller
- if(QCALL == "")
- TxMsg = CQMsg # No callers, we'll CQ again
- else # QSO in progress
- if(J >= 1) # Expected message was received
- log the QSO with QCALL
- QCALL = ""
- Select new QCALL # Op chooses a new caller
- if(QCALL != "")
- TxMsg = "73 NOW QCALL " # Start a new QSO
- else
- TxMsg = "73 " + CQMsg # No callers, we'll CQ again
- else
- Ntry = Ntry + 1 # Expected msg not received
- if(Ntry <= NtryMax)
- go to Transmit # Ask for a repeat
- else
- QCALL = "" # Max tries exceeded, abort this QSO
- Select new QCALL # Choose a new caller
- if(QCALL != "")
- TxMsg = "NIL NOW QCALL " # Start a new QSO
- else
- TxMsg = "NIL " + CQMSG # No callers, we'll CQ again
- go to Transmit
-
-
-Auto-Sequencing algorithm for those calling the DXpedition:
-
-Start:
- TxMsg = "KH1DX MyCall"
- InQSO = false
-
-Transmit:
- TX # (... takes 13.6 s)
- go to Receive
-
-Receive:
- RX # (... takes ~14 s)
- if(RxMsg[i] contains "MyCall ")
- InQSO = true
- TxMsg = "KH1DX MyCall R"
- go to Transmit
-
- if(RxMsg[i] contains "")
- TxEnable = false
- go to Receive
-
- if(RxMsg[i] contains "CQ KH1DX")
- TxEnable = true
- go to Transmit
diff --git a/lib/Fast_Modes.txt b/lib/Fast_Modes.txt
deleted file mode 100644
index da6e27b..0000000
--- a/lib/Fast_Modes.txt
+++ /dev/null
@@ -1,395 +0,0 @@
- Fast Modes in WSJT-X
- --------------------
-
-#######################################################################
-
-IMPORTANT - IMPORTANT - IMPORTANT - IMPORTANT - IMPORTANT - IMPORTANT
-
-Third-party individuals (i.e., others not part of the WSJT development
-team) have been compiling WSJT-X from the open source code and making
-unauthorized "releases" of their builds. I do NOT reccommend use of
-unauthorized builds on the air. If a program revision has been released
-in an official way, you will see it listed here.
-
-If you operate with an unauthorized "rXXXX" code revisions in our
-experimental code branch you have no idea what you've got. Quite
-possibly, the program was built from an intermediate temporary "save"
-of various files, and was not even supposed to produce a usable
-program. Your observetions about what works or does not work are then
-worse than useless -- they waste your time and ours.
-
-So please, PLEASE, *PLEASE*: use *authorized*, "released* revisions
-of this still-in-development software, like the revisions described here.
-
-*ALSO:* If you choose to try an experimental release of JTMSK, please
-accept the responsibility of reporting on your results. You can send
-reports to the "wsjtgroup" reflector, wsjtgroup@yahoogroups.com, or
-email them directly to me. All suggestions for improvements are
-welcome!
-
-Bug reports should include details on how to reproduce the undesirable
-program behavior. Reports on decoding performance are especially
-useful when accompanied by example *.wav files with signals that
-you think should have decoded, but did not.
-
-#######################################################################
-
-September 18, 2015
------------------
-
-New alpha release of experimental WSJT-X v1.6.1, r5910
-------------------------------------------------------
-Changes since revision 5889 include the following:
-
-1. Improved behavior for auto-QSY with "CQ nnn ..." feature. (May not
-be exactly correct, yet, for all radios. Please report if you find
-problems with your rig.)
-
-2. Allow optional use of Wide Graph in fast modes.
-
-3. Add UTC labels to Fast Graph spectrograms.
-
-4. Display correct DXCC entiry for "CQ nnn ..." messages.
-
-5. Implement "Save Decoded" for fast modes.
-
-6. Select Tx6 when "CQ Rx nnn" is enabled.
-
-7. Fix bug in setting of TRperiod after switch to ISCAT mode.
-
-8. Display proper symbol '&' in Tx messages in JTMSK mode.
-
-
-To download this alpha release for Windows, paste the following link
-into your browser:
-http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5910-win32.exe
-
- -- 73, Joe, K1JT
-
-#######################################################################
-
-September 12, 2015
------------------
-
-New alpha release of experimental WSJT-X v1.6.1, r5889
-------------------------------------------------------
-
-A principal new feature in this release is designed to promote the use
-of an agreed "calling frequency" for transmissions of the form
-
- CQ 265 K1ABC FN42
-
-signifying that K1ABC will listen for replies on 50.265 (or 144.265,
-or whatever) and will complete the QSO there. The feature uses the
-rig-control features of WSJT-X to handle the necessary frequency
-switching.
-
-##########################################################################
-Changes since revision 5865 include the following:
-
-1. New features that allow automatic rig control when you transmit or
-respond to messages of the form "CQ 265 K1ABC FN42" on an agreed
-calling frequency. This feature should be especially useful for
-meteor scatter.
-
-2. Yellow-highlighted "Tx" messages in the right text window are now
-properly labeled with 6-digit UTC (hhmmss) in all fast modes.
-
-3. Fixed a bug (introduced in r5865) that inhibited transmitting in
-JT4 mode.
-
-4. Fixed a bug that caused Wide Graph to continue issuing green
-separator lines at short (e.g. 15 s) intervals after you have switched
-to a slow mode.
-
-5. Fixed several more GUI appearance bugs associated with changing
-modes or submodes.
-
-6. Fixed a bug in which double-clicking on the Fast Graph could cause
-program crashes.
-
-7. Fixed a bug that sometimes caused "high tones" to be emitted in
-JTMSK mode.
-
-#######################################################################
-Here's a brief description of how to use the "CQ nnn ..." features.
-
-1. On program startup, go to the Settings | General tab and tick the
-box labeled 'Rx frequency offset with "CQ nnn ..."'
-
-2. Select JTMSK mode and 50.280 (or your some other agreed calling
-frequency) from the drop-down band menu. Remember that this menu is
-not pre-populated with preferred frequencies for all modes on all
-bands. Use Settings | Frequencies to add your desired modes and
-frequencies to the list.
-
-3. Tick the unlabeled checkbox just under the "Report: spinner to
-activate the "CQ Rx nnn" spinner. Set this control to your desired
-QSO frequency in kHz above the nominal band edge. On 6 meters, for
-example, "265" means "50.265".
-
-4. Your transceiver dial frequency should now show 50.265. Changes to
-the "CQ Rx nnn" spinner value should be reflected immediately in the
-transceiver dial frequency, the displayed value on the WSJT-X main
-screen, and in Tx message #6, the "CQ nnn... " message.
-
-5. When you transmit the Tx6 message, the Tx frequency will be set at
-the calling frequency. Otherwise (when receiving, or when
-transmitting any of the messages Tx1 through Tx5) the offset frequency
-(50.265 in my example) will be used.
-
-6. If you double-click on a received "CQ nnn ..." message on the
-calling frequency, your rig will QSY to specified response frequency,
-e.g. 50.265, for both Rx and Tx.
-
-7. To go back to listening on the calling frequency, uncheck the box
-that activated the "CQ Rx nnn" spinner.
-
-#######################################################################
-
-Fair warning: I have not yet tested all possible combinations of
-"Split Operation" configuration (i.e., "None", "Rig", and "Fake it").
-If you normally use Split operation, that should be OK for the "CQ
-nnn ..." feature.
-
-
-As always, please report any bugs that you find in r5889, including
-pertinent details on your settings and the exact series of steps
-required to reproduce the bug.
-
-
-To download this alpha release for Windows, paste the following link
-into your browser:
-http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5889-win32.exe
-
-
- -- 73, Joe, K1JT
-
-#######################################################################
-
-New alpha release of experimental WSJT-X v1.6.1, r5865
-------------------------------------------------------
-
-This alpha release of WSJT-X includes major improvements to the JTMSK
-decoder. Changes since revision 5823 include the following:
-
-1. On-screen controls labeled "Rx nnnn Hz" and "F Tol" (Rx frequency
-and tolerance) now function as expected in JTMSK mode. The frequency
-search range can be up to 500 Hz, but note that sensitivity is
-necessarily reduced for signals off frequency by more than about 250
-Hz. Normally you should leave Rx Freq set at 1500 Hz; suitable values
-for F Tol are 100 to 500 Hz.
-
-2. The JTMSK decoder now makes good use of strong, short pings (as
-short as 0.1 s) as well as weak pings several times longer.
-
-3. Improved calculation of S/N and frequency of decoded signals.
-
-4. Unified appearance of window titles on all non-modal windows.
-
-5. CW ID is disabled (for now, at least) when operating in any of the
-WSJT fast modes.
-
-6. In WSPR mode, display of "Receiving ... " messages is
-disabled when band-hopping is not in use.
-
-7. Fixed several bugs affecting status and visibility of certain
-on-screen controls after changes in operating mode.
-
-8. Fixed a bug allowing display of duplicate decodes for the same
-signal.
-
-9. Fixed a bug preventing compilation on 64-bit systems, and cleaned
-up some harmless compiler warnings.
-
-#######################################################################
- Summary Description of JTMSK Protocol
-
-JTMSK uses the same standard message structure as slow modes JT4, JT9,
-and JT65. User information is "source encoded" to 72 bits. A 15-bit
-CRC is appended and a convolutional code with constraint length K=13
-and rate r=1/2 is applied, making a total of (72+15+12)*2 = 198
-information bits. Three copies of the "Barker-11" code and three
-even-parity bits are added for synchronization, making a total of
-198+33+3 = 234 channel symbols. Modulation uses a constant-envelope,
-continuous-phase "minimum-shift keying" (MSK) waveform, with tone
-frequencies of 1000 and 2000 Hz.
-
-#######################################################################
-
-To download this alpha release for Windows, paste the following link
-into your browser:
-http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5865-win32.exe
-
- -- 73, Joe, K1JT
-
-August 28, 2015
----------------
-
-New release of experimental WSJT-X v1.6.1, r5823
-------------------------------------------------
-
-To download for Windows, paste the following link into your browser:
-http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5823-win32.exe
-
-This experimental version of WSJT-X introduces a new fast mode called
-JTMSK. The letters MS, of course, imply meteor scatter; the three
-letters MSK mean "Minimum Shift Keying", the modulation scheme used in
-this mode.
-
-Revision 5823 also includes a number of (mostly minor) bug fixes
-relative to r5789.
-
-IMPORTANT: If you choose to try JTMSK, please accept the
-responsibility of reporting on your results. You can send reports to
-the "wsjtgroup" reflector, wsjtgroup@yahoogroups.com or email them
-directly to me. All suggestions for improvements are welcome! Bug
-reports should include details on how to reproduce the undesirable
-program behavior.
-
-The present JTMSK decoder has been optimized for short pings. It does
-not yet do a wide search for proper frequency alignment; you and your
-QSO partner need to be "on frequency" to within +/- 100 Hz or better.
-The decoder does not (yet) attempt to make optimal use of weak, slowly
-varying signals. These and other characteristics may be improved in
-coming revisions.
-
-KNOWN BUG: At present you should use T/R sequence lengths 15 s in
-JTMSK mode. If you have a program crash, open Windows Task Manager,
-select the "Processes" tab, right-click on wsjtx.exe, and select "End
-Process Tree". Then restart the program.
-
-I view JTMSK as a candidate for replacing both FSK441 and JTMS for all
-meteor scatter work. JTMSK has the major advantage of including
-strong forward error correction (FEC), similar in usage to the schemes
-used for many years in JT4, JT9, and JT65. The structure of user
-messages and the format of minimal QSOs is also identical to those
-other modes. But JTMSK is very fast, transmitting its full encoded
-message content in 0.117 s, in a 2 kHz bandwidth. JTMSK therefore
-makes much better use of short pings than (for example) JT9H can do.
-
-The Tx waveform of JTMSK has been carefully designed to have a number
-of desirable features. All messages are exactly the same length: 72
-bits of user information are followed by a 15-bit CRC and encoded into
-198 channel bits with a convolutional code (constraint length K=13,
-rate r=1/2). Three sequences of the "Barker-11" code are added, along
-with three parity bits, making a total of 234 channel bits in each
-message. The MSK symbols for these bits are transmitted at 2000 baud,
-and the full encoded message is repeated every 117 ms.
-
-A summary description of modulation parameters for all WSJT(-X) modes
-is shown in a table posted here:
-http://physics.princeton.edu/pulsar/K1JT/wsjt_modes.txt and
-illustrated graphically here:
-http://physics.princeton.edu/pulsar/K1JT/wsjt_modes.pdf
-
- -- 73, Joe, K1jT
-
-August 15, 2015
----------------
-
-New release of experimental WSJT-X v1.6.1, r5789
-
-Changes since WSJT-X v1.6.1, revision 5779:
-
-1. Major speedup (5x) of fast-JT9 decoder.
-2. Corrected logic for Auto-Sequencing operation.
-3. Stop after sending 73 five times in auto-sequence mode.
-4. Add an "Auto-Level" control to Fast Graph window.
-5. Send fast-mode decodes to PSKreporter web site.
-6. Support automatic logging via JTAlert-X.
-7. Send fast-mode output to file ALL.TXT.
-8. Better definition of dB levels for fast-JT9 signals.
-9. Rationalize the GUI behavior when changing mode, submode, fast/slow
- status, and T/R period.
-10. Correct a flaw in the display of multiple decodes in a single
- fast-JT9 sequence.
-11. Fix minor bugs reported by G3WDG, ND0B, OZ1PIF, and others.
-
-To download for Windows, paste the following link into your browser:
-http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5789-win32.exe
-
-Please keep in mind that this is an experimental version of WSJT-X.
-Bug reports and other feedback will be much appreciated, and will help
-to make the program better!
-
- -- 73, Joe, K1JT
-
-
-August 11, 2015
----------------
-
-Since its origin in the dark ages (ca. 2001) WSJT has supported "fast"
-modes (designed for meteor scatter, etc.) and "slow" modes (optimized
-for EME and other weak-signal propagation types). The most recent new
-mode, JT9, now has *both* fast and slow submodes.
-
-JT9A (the "original" JT9) is like JT65 and JT4: its T/R sequences are
-one minute long, and its primary goal is best possible sensitivity for
-very weak, approximately steady signals. The new experimental JT9
-submodes use the same message structure, encoding, and modulation type
-(9-tone FSK) as JT9A, but wider tone spacing and (optionally) faster
-keying rates.
-
-You can download an experimental version of WSJT-X (v1.6.1, r5779) here:
-http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5779-win32.exe
-
-The fast submodes currently being tested, JT9E - JT9H, have been found
-highly effective for meteors and ionoscatter propagation on 6 and 10
-meters. Sensitivity is similar to ISCAT, or slightly better.
-Decoding is much more reliable, because the JT9 protocol includes
-strong forward error correction. Decoding results are like those for
-all the WSJT "slow" modes: you should see messages exactly as they
-were transmitted, or nothing at all. A potential side benefit is
-automatic reporting of decodes to PSKreporter.
-
-For details on the modulation parameters of the JT9 submodes, see the
-table posted at
-http://physics.princeton.edu/pulsar/K1JT/wsjt_modes.txt.
-
-WSJT-X v1.6.1 r5779 has the following changes from r5769:
-
-1. Numerous bug fixes
-2. Double-click on decoded message now behaves properly
-3. Faster decoding (further optimization still to come)
-4. Decoded text is highlighted as in WSJT-X slow modes
-5. Optional auto-sequencing
-
-Fair warning: auto-sequencing is basically functional, but scarcely
-tested. Please watch what it is doing, and tell us how you think it
-should be improved!
-
-If you use WSJT-X also for other modes and other purposes, you may
-want to save several different sets of configuration settings. In
-that case it's convenient to use the "-r xxx" option and start the
-program from a command-prompt window. For example:
-
-C:\Users\joe> cd \wsjt\wsjtx\bin
-C:\WSJT\wsjtx\bin> wsjtx -r xxx
-
-... where "xxx" can be anything you like, for example "ISCAT",
-"FAST9", etc.
-
-Proper configuration for the JT9 fast modes includes the following
-settings:
-
-On the Settings | General tab:
-
- - check "Enable VHF/UHF/Microwave features"
-
-Main window settings:
-
- - Mode JT9
- - Tx 700 Hz
- - Rx 700 Hz
- - Sync 0
- - Submode G ... or E, F, and H (H not legal in US on 10m)
- - Tick "Fast"
- - T/R 30 s (also 5, 10, 15 s)
- - FTol 500
-
-Please keep in mind that this is an experimental version of WSJT-X.
-It still has some rough edges, and no doubt some bugs. Your feedback
-will be much appreciated, and will help to make the program better!
-
- -- 73, Joe, K1JT
diff --git a/lib/Makefile b/lib/Makefile
deleted file mode 100644
index c4d6279..0000000
--- a/lib/Makefile
+++ /dev/null
@@ -1,71 +0,0 @@
-CC = gcc
-CXX = g++
-FC = gfortran
-
-FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
-CFLAGS = -O2 -I.
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-#all: qratest.exe tplt.exe
-all: qra64d.exe
-
-OBJS1 = qratest.o qra64a.o ana64.o sync64a.o four2a.o smo.o smo121.o averms.o \
- timer_module.o packjt.o twkfreq.o spec64.o fmtmsg.o pctile.o \
- grid2deg.o deg2grid.o shell.o badmsg.o qra64_subs.o \
- qracodes.o npfwht.o pdmath.o qra12_63_64_irr_b.o \
- qra13_64_64_irr_e.o qra64.o image.o \
- zplt64a.o zplt64b.o lorentzian.o fchisq0.o peakup.o sync64.o
-
-qra64_subs.o: qra/qra64/qra64_subs.c
- gcc -c -O2 -o qra64_subs.o qra/qra64/qra64_subs.c
-
-qracodes.o: qra/qracodes/qracodes.c
- gcc -c -O2 -o qracodes.o qra/qracodes/qracodes.c
-
-qra64.o: qra/qra64/qra64.c
- gcc -c -O2 -o qra64.o qra/qra64/qra64.c
-
-npfwht.o: qra/qracodes/npfwht.c
- gcc -c -O2 -o npfwht.o qra/qracodes/npfwht.c
-
-pdmath.o: qra/qracodes/pdmath.c
- gcc -c -O2 -o pdmath.o qra/qracodes/pdmath.c
-
-qra12_63_64_irr_b.o: qra/qracodes/qra12_63_64_irr_b.c
- gcc -c -O2 -o qra12_63_64_irr_b.o qra/qracodes/qra12_63_64_irr_b.c
-
-qra13_64_64_irr_e.o: qra/qracodes/qra13_64_64_irr_e.c
- gcc -c -O2 -o qra13_64_64_irr_e.o qra/qracodes/qra13_64_64_irr_e.c
-
-qratest.exe: $(OBJS1)
- $(FC) -o qratest.exe $(OBJS1) C:\JTSDK\fftw3f\libfftw3f-3.dll
-
-OBJS2 = tplt.o zplt64.o image.o
-tplt.exe: $(OBJS2)
- $(FC) -o tplt.exe $(OBJS2)
-
-OBJS3 = qra64d.o sync64a.o four2a.o smo.o smo121.o averms.o \
- timer_module.o packjt.o twkfreq.o spec64.o fmtmsg.o pctile.o \
- grid2deg.o deg2grid.o shell.o badmsg.o qra64_subs.o \
- qracodes.o npfwht.o pdmath.o qra12_63_64_irr_b.o \
- qra13_64_64_irr_e.o qra64.o image.o \
- zplt64a.o zplt64b.o lorentzian.o fchisq0.o peakup.o sync64.o
-
-qra64d.exe: $(OBJS3)
- $(FC) -o qra64d.exe $(OBJS3) C:\JTSDK\fftw3f\libfftw3f-3.dll
-
-.PHONY : clean
-
-clean:
- $(RM) *.o qratest.exe tplt.exe
diff --git a/lib/Makefile.MinGW b/lib/Makefile.MinGW
deleted file mode 100644
index 1cdc665..0000000
--- a/lib/Makefile.MinGW
+++ /dev/null
@@ -1,153 +0,0 @@
-# Makefile for MinGW on Windows
-#
-# Needed libraries are located using the following variables:
-#
-# QT_DIR - point this at the root of your Qt installation
-# FFTW3_DIR - point this at the fftw v3 installation directory
-#
-# e.g.
-# make -f Makefile.MinGW \
-# QT_DIR=c:/Qt/5.2.1/mingw48_32 \
-# FFTW3_DIR = c:/fftw-3.3.3-dll32-2
-#
-# Windows re-direct:
-# C> make > junk1 2>&1
-
-# Set paths
-EXE_DIR = ..\\..\\wsjtx_install
-QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
-FFTW3_DIR = ..
-
-INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
-
-# Compilers
-CC = gcc
-CXX = g++
-FC = gfortran
-AR = ar cr
-RANLIB = ranlib
-MKDIR = mkdir -p
-CP = cp
-RM = rm -f
-
-FFLAGS = -O2 -fbounds-check -Wall -Wno-precision-loss -fno-second-underscore
-CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: libjt9.a libastro.a jt9.exe jt9code.exe jt65code.exe
-
-OBJS1 = prog_args.o options.o pctile.o graycode.o sort.o ssort.o chkmsg.o \
- unpackmsg.o igray.o unpackcall.o unpackgrid.o \
- fmtmsg.o grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
- packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
- nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.o \
- symspec.o analytic.o db.o genjt9.o flat1.o smo.o \
- packbits.o unpackbits.o encode232.o interleave9.o \
- entail.o fano232.o gran.o sync9.o decode9.o \
- fil3.o decoder.o grid2n.o n2grid.o timer.o \
- softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
- peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
- fillcom.o chkss2.o zplot9.o flat2.o \
- jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
- filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
- extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
- move.o indexx.o graycode65.o twkfreq65.o smo121.o \
- wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
- flat3.o polfit.o determ.o baddata.o
-
-libjt9.a: $(OBJS1)
- $(AR) libjt9.a $(OBJS1)
- $(RANLIB) libjt9.a
-
-OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o usleep.o
-LIBS2 = -L${QT_DIR}/lib -lQt5Core
-jt9.exe: $(OBJS2) libjt9.a
- $(CXX) -o jt9.exe $(OBJS2) $(LIBS2) libjt9.a \
- -L$(FFTW3_DIR) -lfftw3f-3 $(shell $(FC) -print-file-name=lib$(FC).a)
- -$(MKDIR) $(EXE_DIR)
- $(CP) jt9.exe $(EXE_DIR)
-
-OBJS3 = jt9sim.o
-jt9sim.exe: $(OBJS3) libjt9.a
- $(FC) -o jt9sim.exe $(OBJS3) libjt9.a
-
-OBJS4 = jt9code.o
-jt9code.exe: $(OBJS4) libjt9.a
- $(FC) -o jt9code.exe $(OBJS4) libjt9.a
- $(CP) jt9code.exe $(EXE_DIR)
-
-OBJS5 = jt65.o
-jt65.exe: $(OBJS5) libjt9.a
- $(FC) -o jt65.exe $(OBJS5) libjt9.a -L$(FFTW3_DIR) -lfftw3f-3
-
-OBJS7 = astrosub.o astro0.o astro.o tm2.o grid2deg.o sun.o moondop.o \
- coord.o dot.o moon2.o tmoonsub.o toxyz.o geocentric.o \
- dcoord.o
-
-libastro.a: $(OBJS7)
- $(AR) libastro.a $(OBJS7)
- $(RANLIB) libastro.a
-
-OBJS6 = jt65code.o
-jt65code.exe: $(OBJS6) libjt9.a
- $(FC) -o jt65code.exe $(OBJS6) libjt9.a
- $(CP) jt65code.exe $(EXE_DIR)
-
-sync9.o: sync9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c sync9.f90
-
-spec9.o: spec9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c spec9.f90
-
-peakdt9.o: peakdt9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c peakdt9.f90
-
-jt9sim.o: jt9sim.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c jt9sim.f90
-
-genjt9.o: genjt9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c genjt9.f90
-
-redsync.o: redsync.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c redsync.f90
-
-unpackmsg.o: unpackmsg.f90
- $(FC) -c -O0 -fbounds-check -Wall -Wno-precision-loss unpackmsg.f90
-
-ipcomm.o: ipcomm.cpp
- $(CXX) -c $(INCPATH) ipcomm.cpp
-
-sec_midn.o: sec_midn.f90
- $(FC) -c -fno-second-underscore sec_midn.f90
-
-#rig_control.o: rig_control.c
-# $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include rig_control.c
-
-tstrig.o: tstrig.c
- $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
-
-init_rs.o: init_rs.c
- $(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
-
-encode_rs.o: encode_rs.c
- $(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
-
-decode_rs.o: decode_rs.c
- $(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
-
-
-.PHONY : clean
-
-clean:
- $(RM) *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe
diff --git a/lib/Makefile.MinGW.qt4 b/lib/Makefile.MinGW.qt4
deleted file mode 100644
index df90745..0000000
--- a/lib/Makefile.MinGW.qt4
+++ /dev/null
@@ -1,122 +0,0 @@
-# Makefile for MinGW on Windows
-# Windows re-direct:
-# C> make > junk1 2>&1
-
-# Set paths
-EXE_DIR = ../../wsjtx_install
-INCPATH = -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore' \
- -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include' \
- -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/ActiveQt' \
- -I'release' -I'.' -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/mkspecs/win32-g++'
-
-# Compilers
-CC = gcc
-CXX = g++
-FC = g95
-
-FFLAGS = -O2 -fbounds-check -Wall -Wno-precision-loss -fno-second-underscore
-CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: libjt9.a jt9sim.exe jt9.exe jt9code.exe jt65.exe
-
-OBJS1 = pctile.o graycode.o sort.o ssort.o \
- unpackmsg.o igray.o unpackcall.o unpackgrid.o \
- grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
- packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
- nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.o \
- symspec.o analytic.o db.o genjt9.o \
- packbits.o unpackbits.o encode232.o interleave9.o \
- entail.o fano232.o gran.o sync9.o decode9.o \
- fil3.o decoder.o grid2n.o n2grid.o timer.o \
- softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
- peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
- fillcom.o chkss2.o zplot9.o flat2.o \
- jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
- filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
- extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
- move.o indexx.o graycode65.o twkfreq65.o smo121.o \
- wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o
-
-libjt9.a: $(OBJS1)
- ar cr libjt9.a $(OBJS1)
- ranlib libjt9.a
-
-OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o usleep.o
-LIBS2 = -L'c:/QtSDK/Desktop/Qt/4.7.4/mingw/lib' -lQtCore4
-jt9.exe: $(OBJS2) libjt9.a
- $(CXX) -o jt9.exe $(OBJS2) $(LIBS2) libjt9.a ../libfftw3f_win.a \
- c:/MinGW/lib/libf95.a
- mkdir -p $(EXE_DIR)
- cp jt9.exe $(EXE_DIR)
-
-OBJS3 = jt9sim.o
-jt9sim.exe: $(OBJS3) libjt9.a
- $(FC) -o jt9sim.exe $(OBJS3) libjt9.a
-
-OBJS4 = jt9code.o
-jt9code.exe: $(OBJS4) libjt9.a
- $(FC) -o jt9code.exe $(OBJS4) libjt9.a
-
-OBJS5 = jt65.o
-jt65.exe: $(OBJS5) libjt9.a
- $(FC) -o jt65.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
-
-sync9.o: sync9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c sync9.f90
-
-spec9.o: spec9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c spec9.f90
-
-peakdt9.o: peakdt9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c peakdt9.f90
-
-jt9sim.o: jt9sim.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c jt9sim.f90
-
-genjt9.o: genjt9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c genjt9.f90
-
-redsync.o: redsync.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c redsync.f90
-
-unpackmsg.o: unpackmsg.f90
- $(FC) -c -O0 -fbounds-check -Wall -Wno-precision-loss unpackmsg.f90
-
-ipcomm.o: ipcomm.cpp
- $(CXX) -c $(INCPATH) ipcomm.cpp
-
-sec_midn.o: sec_midn.f90
- $(FC) -c -fno-second-underscore sec_midn.f90
-
-#rig_control.o: rig_control.c
-# $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include rig_control.c
-
-tstrig.o: tstrig.c
- $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
-
-init_rs.o: init_rs.c
- $(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
-
-encode_rs.o: encode_rs.c
- $(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
-
-decode_rs.o: decode_rs.c
- $(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
-
-
-.PHONY : clean
-
-clean:
- rm -f *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe
diff --git a/lib/Makefile.jt65 b/lib/Makefile.jt65
deleted file mode 100644
index 7409b5c..0000000
--- a/lib/Makefile.jt65
+++ /dev/null
@@ -1,84 +0,0 @@
-# Set paths
-EXE_DIR = ../../wsjtx_exp_install_latest
-QT_DIR = /usr/include/qt5
-INCPATH = -I${QT_DIR} -I${QT_DIR}/QtCore
-
-CC = gcc
-CXX = g++
-FC = gfortran
-AR = ar cr
-MKDIR = mkdir -p
-CP = cp
-RANLIB = ranlib
-RM = rm -f
-
-FFLAGS = -I/opt/local/include -O3 -funroll-loops -Wall -Wno-conversion -fno-second-underscore -DUNIX
-CFLAGS = -I. -fbounds-check -fPIE
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: libjt9.a jt65 jt65sim t3
-
-OBJS1 = astrosub.o astro0.o astro.o sun.o coord.o tmoonsub.o \
- fmtmsg.o deg2grid.o\
- prog_args.o options.o pctile.o graycode.o sort.o chkmsg.o \
- igray.o fftw3mod.o packjt.o\
- four2a.o grid2deg.o wisdom.o \
- symspec.o analytic.o db.o \
- encode232.o interleave9.o\
- entail.o fano232.o gran.o sync9.o \
- fil3.o decoder.o fqso_first.o \
- twkfreq.o symspec2.o shell.o sync65.o peakup.o slope.o xcor.o\
- chkss2.o zplot9.o flat1.o flat2.o \
- symspec65.o flat65.o ccf65.o decode65a.o \
- filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
- extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
- move.o indexx.o graycode65.o twkfreq65.o smo.o smo121.o \
- wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
- flat4.o determ.o baddata.o subtract65.o
-
-libjt9.a: $(OBJS1)
- $(AR) libjt9.a $(OBJS1)
- $(RANLIB) libjt9.a
-
-OBJS7 = jt65.o
-jt65: $(OBJS7) libjt9.a libsfrsd.a
- $(FC) -o jt65 $(OBJS7) -L. -L/opt/local/lib -L./sfrsd2 -ljt9 -lsfrsd -lfftw3f_threads -lfftw3f
- $(CP) jt65 $(EXE_DIR)
-
-OBJS2 = jt65sim.o wavhdr.o
-jt65sim: $(OBJS2) libjt9.a
- $(FC) -o jt65sim $(OBJS2) -L. -L/opt/local/lib -ljt9 -lfftw3f
- $(CP) jt65sim $(EXE_DIR)
-
-OBJS3 = t3.o
-t3: $(OBJS3) libjt9.a
- $(FC) -o t3 $(OBJS3) -L. -L/opt/local/lib -ljt9
-
-OBJS6 = jt65code.o
-jt65code: $(OBJS6) libjt9.a
- $(FC) -o jt65code $(OBJS6) libjt9.a
-
-init_rs.o: init_rs.c
- $(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
-
-encode_rs.o: encode_rs.c
- $(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
-
-decode_rs.o: decode_rs.c
- $(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
-
-.PHONY : clean
-
-clean:
- $(RM) *.o libjt9.a jt65
diff --git a/lib/Makefile.jt65_Win b/lib/Makefile.jt65_Win
deleted file mode 100644
index 08a4d22..0000000
--- a/lib/Makefile.jt65_Win
+++ /dev/null
@@ -1,76 +0,0 @@
-# Set paths
-EXE_DIR = C:/JTSDK/wsjtx_exp/install/Debug/bin
-QT_DIR = /usr/include/qt5
-INCPATH = -I${QT_DIR} -I${QT_DIR}/QtCore
-
-CC = gcc
-CXX = g++
-FC = gfortran
-AR = ar cr
-MKDIR = mkdir -p
-CP = cp
-RANLIB = ranlib
-RM = rm -f
-
-FFLAGS = -O2 -Wall -Wno-conversion -fno-second-underscore
-CFLAGS = -I. -fbounds-check -fPIE -DBIGSYM
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: libjt9.a jt65 jt65sim
-
-OBJS1 = astrosub.o astro0.o astro.o sun.o coord.o tmoonsub.o \
- fmtmsg.o deg2grid.o\
- prog_args.o options.o pctile.o graycode.o sort.o chkmsg.o \
- igray.o fftw3mod.o packjt.o\
- four2a.o grid2deg.o wisdom.o \
- symspec.o analytic.o db.o \
- encode232.o interleave9.o \
- entail.o fano232.o gran.o sync9.o decjt9.o \
- fil3.o decoder.o timer.o exp_decode65.o fqso_first.o \
- twkfreq.o symspec2.o shell.o sync65.o peakup.o slope.o xcor.o\
- fillcom.o chkss2.o zplot9.o flat1.o flat2.o \
- jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
- filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
- extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
- move.o indexx.o graycode65.o twkfreq65.o smo.o smo121.o \
- wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
- flat4.o determ.o baddata.o subtract65.o
-
-libjt9.a: $(OBJS1)
- $(AR) libjt9.a $(OBJS1)
- $(RANLIB) libjt9.a
-
-OBJS7 = jt65.o
-jt65: $(OBJS7) libjt9.a libsfrsd.a
- $(FC) -o jt65 $(OBJS7) -L. -L./sfrsd2 -ljt9 -lsfrsd \
- C:\JTSDK\fftw3f\libfftw3f-3.dll
-
-OBJS2 = jt65sim.o wavhdr.o
-jt65sim: $(OBJS2) libjt9.a
- $(FC) -o jt65sim $(OBJS2) -L. -ljt9 C:\JTSDK\fftw3f\libfftw3f-3.dll
- $(CP) jt65sim.exe $(EXE_DIR)
-
-init_rs.o: init_rs.c
- $(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
-
-encode_rs.o: encode_rs.c
- $(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
-
-decode_rs.o: decode_rs.c
- $(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
-
-.PHONY : clean
-
-clean:
- $(RM) *.o libjt9.a jt65
diff --git a/lib/Makefile.jt65_osx b/lib/Makefile.jt65_osx
deleted file mode 100644
index c831e70..0000000
--- a/lib/Makefile.jt65_osx
+++ /dev/null
@@ -1,74 +0,0 @@
-# Set paths
-EXE_DIR = ../../wsjtx_install
-
-CC = clang
-CXX = g++
-FC = gfortran
-AR = ar cr
-MKDIR = mkdir -p
-CP = cp
-RANLIB = ranlib
-RM = rm -f
-
-FFLAGS = -I/opt/local/include -Wall -Wno-conversion -fno-second-underscore -DUNIX
-CFLAGS = -I. -fbounds-check -fPIE
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: libjt9.a jt65 jt65sim
-
-OBJS1 = astrosub.o astro0.o astro.o sun.o coord.o tmoonsub.o \
- fmtmsg.o deg2grid.o\
- prog_args.o options.o pctile.o graycode.o sort.o chkmsg.o \
- igray.o fftw3mod.o packjt.o\
- four2a.o grid2deg.o wisdom.o \
- symspec.o analytic.o db.o \
- encode232.o interleave9.o\
- entail.o fano232.o sgran.o gran.o sync9.o decjt9.o \
- fil3.o decoder.o timer.o exp_decode65.o fqso_first.o\
- twkfreq.o symspec2.o shell.o sync65.o peakup.o slope.o xcor.o\
- fillcom.o chkss2.o zplot9.o flat1.o flat2.o \
- jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
- filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
- extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
- move.o indexx.o graycode65.o twkfreq65.o smo.o smo121.o \
- wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
- flat4.o determ.o baddata.o subtract65.o
-
-libjt9.a: $(OBJS1)
- $(AR) libjt9.a $(OBJS1)
- $(RANLIB) libjt9.a
-
-OBJS7 = jt65.o
-jt65: $(OBJS7) libjt9.a libftrsd.a
- $(FC) -o jt65 $(OBJS7) -L. -L/opt/local/lib -L./ftrsd -ljt9 -lftrsd -lfftw3f_threads -lfftw3f
- $(CP) jt65 $(EXE_DIR)
-
-OBJS2 = jt65sim.o wavhdr.o
-jt65sim: $(OBJS2) libjt9.a
- $(FC) -o jt65sim $(OBJS2) -L. -L/opt/local/lib -ljt9 -lfftw3f
- $(CP) jt65sim $(EXE_DIR)
-
-init_rs.o: init_rs.c
- $(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
-
-encode_rs.o: encode_rs.c
- $(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
-
-decode_rs.o: decode_rs.c
- $(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
-
-.PHONY : clean
-
-clean:
- $(RM) *.o libjt9.a jt65
diff --git a/lib/Makefile.jt9w b/lib/Makefile.jt9w
deleted file mode 100644
index db7bd54..0000000
--- a/lib/Makefile.jt9w
+++ /dev/null
@@ -1,58 +0,0 @@
-
-# Set paths
-EXE_DIR = ..\\..\\wsjtx_install
-QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
-FFTW3_DIR = ..
-
-INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
-
-# Compilers
-CC = gcc
-CXX = g++
-FC = gfortran
-AR = ar cr
-RANLIB = ranlib
-MKDIR = mkdir -p
-CP = cp
-RM = rm -f
-
-FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
-CFLAGS = -O2 -I.
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: jt9w
-
-OBJS1 = jt9w.o smo.o sync9w.o pctile.o shell.o lorentzian.o fchisq0.o \
- softsym9w.o four2a.o interleave9.o jt9fano.o fano232.o packjt.o \
- deg2grid.o grid2deg.o fmtmsg.o db.o decode9w.o
-
-jt9w: $(OBJS1)
- $(FC) -o jt9w $(OBJS1) -lfftw3f
-
-OBJS2 = t1.o four2a.o db.o
-t1: $(OBJS2)
- $(FC) -o t1 $(OBJS2) -lfftw3f
-
-OBJS3 = t2.o four2a.o db.o
-t2: $(OBJS3)
- $(FC) -o t2 $(OBJS3) -lfftw3f
-
-OBJS4 = t3.o four2a.o db.o
-t3: $(OBJS4)
- $(FC) -o t3 $(OBJS4) -lfftw3f
-
-.PHONY : clean
-
-clean:
- $(RM) *.o JTMSKcode JTMSKcode.exe
diff --git a/lib/Makefile.jt9w_Win b/lib/Makefile.jt9w_Win
deleted file mode 100644
index 28dbe30..0000000
--- a/lib/Makefile.jt9w_Win
+++ /dev/null
@@ -1,58 +0,0 @@
-
-# Set paths
-EXE_DIR = ..\\..\\wsjtx_install
-QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
-FFTW3_DIR = ..
-
-INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
-
-# Compilers
-CC = gcc
-CXX = g++
-FC = gfortran
-AR = ar cr
-RANLIB = ranlib
-MKDIR = mkdir -p
-CP = cp
-RM = rm -f
-
-FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
-CFLAGS = -O2 -I.
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: jt9w
-
-OBJS1 = jt9w.o smo.o sync9w.o pctile.o shell.o lorentzian.o fchisq0.o \
- softsym9w.o four2a.o interleave9.o jt9fano.o fano232.o packjt.o \
- deg2grid.o grid2deg.o fmtmsg.o db.o decode9w.o
-
-jt9w: $(OBJS1)
- $(FC) -o jt9w $(OBJS1) -lfftw3f
-
-OBJS2 = t1.o four2a.o db.o
-t1: $(OBJS2)
- $(FC) -o t1 $(OBJS2) -lfftw3f
-
-OBJS3 = t2.o four2a.o db.o
-t2: $(OBJS3)
- $(FC) -o t2 $(OBJS3) -lfftw3f
-
-OBJS4 = t3.o
-t3: $(OBJS4)
- $(FC) -o t3 $(OBJS4) -L. -ljt9 C:\JTSDK\fftw3f\libfftw3f-3.dll
-
-.PHONY : clean
-
-clean:
- $(RM) *.o JTMSKcode JTMSKcode.exe
diff --git a/lib/Makefile.jtsdk b/lib/Makefile.jtsdk
deleted file mode 100644
index ce113a5..0000000
--- a/lib/Makefile.jtsdk
+++ /dev/null
@@ -1,137 +0,0 @@
-# Makefile for MinGW on Windows
-# Windows re-direct:
-# C> make > junk1 2>&1
-
-# Set paths
-EXE_DIR = ../../wsjtx_install
-
-INCPATH = -I'C:/JTSDK/Qt5/5.2.1/mingw48_32/include/QtCore' \
- -I'C:/JTSDK/Qt5/5.2.1/mingw48_32/include/'
-
-# Compilers
-CC = c:/JTSDK/Qt5/Tools/mingw48_32/bin/gcc
-FC = c:/JTSDK/Qt5/Tools/mingw48_32/bin/gfortran
-CXX = c:/JTSDK/Qt5/Tools/mingw48_32/bin/g++
-
-FFLAGS = -O3 -Wall -Wno-conversion -fno-second-underscore -DWIN32
-CFLAGS = -I. -DWIN32
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: libjt9.a libastro.a jt9.exe jt9code.exe jt65code.exe jt9sim.exe
-
-OBJS1 = pctile.o graycode.o sort.o chkmsg.o \
- unpackmsg.o igray.o unpackcall.o unpackgrid.o \
- grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
- packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
- nchar.o four2a.o grid2deg.o pfxdump.o wisdom.o \
- symspec.o analytic.o db.o genjt9.o flat1.o smo.o \
- packbits.o unpackbits.o encode232.o interleave9.o \
- entail.o fano232.o gran.o sync9.o jt9fano.o \
- fil3.o decoder.o grid2n.o n2grid.o timer.o \
- softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
- peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
- fillcom.o chkss2.o zplot9.o flat2.o \
- jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
- filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
- extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
- move.o indexx.o graycode65.o twkfreq65.o smo121.o \
- wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
- flat4.o polfit.o determ.o baddata.o prog_args.o \
- options.o fmtmsg.o decjt9.o
-
-libjt9.a: $(OBJS1)
- ar cr libjt9.a $(OBJS1)
- ranlib libjt9.a
-
-OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o usleep.o
-LIBS2 = -L'C:/JTSDK/Qt5/5.2.1/mingw48_32/lib' -lQt5Core
-jt9.exe: $(OBJS2) libjt9.a
- $(CXX) -o jt9.exe -static $(OBJS2) $(LIBS2) libjt9.a \
- C:\JTSDK\fftw3f\libfftw3f-3.dll -lgfortran
-# mkdir -p $(EXE_DIR)
- cp jt9.exe $(EXE_DIR)
-
-OBJS3 = jt9sim.o
-jt9sim.exe: $(OBJS3) libjt9.a
- $(FC) -o jt9sim.exe $(OBJS3) libjt9.a
-
-OBJS4 = jt9code.o
-jt9code.exe: $(OBJS4) libjt9.a
- $(FC) -o jt9code.exe $(OBJS4) libjt9.a
- cp jt9code.exe $(EXE_DIR)
-
-OBJS5 = jt65.o
-jt65.exe: $(OBJS5) libjt9.a
- $(FC) -o jt65.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
-
-OBJS7 = astrosub.o astro0.o astro.o tm2.o grid2deg.o sun.o moondop.o \
- coord.o dot.o moon2.o tmoonsub.o toxyz.o geocentric.o \
- dcoord.o
-
-libastro.a: $(OBJS7)
- ar cr libastro.a $(OBJS7)
- ranlib libastro.a
-
-OBJS6 = jt65code.o
-jt65code.exe: $(OBJS6) libjt9.a
- $(FC) -o jt65code.exe $(OBJS6) libjt9.a
- cp jt65code.exe $(EXE_DIR)
-
-sync9.o: sync9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c sync9.f90
-
-spec9.o: spec9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c spec9.f90
-
-peakdt9.o: peakdt9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c peakdt9.f90
-
-jt9sim.o: jt9sim.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c jt9sim.f90
-
-genjt9.o: genjt9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c genjt9.f90
-
-redsync.o: redsync.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c redsync.f90
-
-unpackmsg.o: unpackmsg.f90
- $(FC) -c -O0 -fbounds-check -Wall -Wno-precision-loss unpackmsg.f90
-
-ipcomm.o: ipcomm.cpp
- $(CXX) -c $(INCPATH) ipcomm.cpp
-
-sec_midn.o: sec_midn.f90
- $(FC) -c -fno-second-underscore sec_midn.f90
-
-#rig_control.o: rig_control.c
-# $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include rig_control.c
-
-tstrig.o: tstrig.c
- $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
-
-init_rs.o: init_rs.c
- $(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
-
-encode_rs.o: encode_rs.c
- $(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
-
-decode_rs.o: decode_rs.c
- $(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
-
-
-.PHONY : clean
-
-clean:
- rm -f *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe
diff --git a/lib/Makefile.linux b/lib/Makefile.linux
deleted file mode 100644
index 14bc077..0000000
--- a/lib/Makefile.linux
+++ /dev/null
@@ -1,115 +0,0 @@
-# Set paths
-EXE_DIR = ../../wsjtx_install
-QT_DIR = /usr/include/qt5
-INCPATH = -I${QT_DIR} -I${QT_DIR}/QtCore
-
-CC = gcc
-CXX = g++
-FC = gfortran
-AR = ar cr
-MKDIR = mkdir -p
-CP = cp
-RANLIB = ranlib
-RM = rm -f
-
-FFLAGS = -O3 -funroll-loops -Wall -Wno-conversion -fno-second-underscore -DUNIX
-CFLAGS = -I. -fbounds-check -fPIE
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: libjt9.a jt9sim jt9 jt9code jt65code
-
-OBJS1 = astrosub.o astro0.o astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \
- fmtmsg.o geocentric.o moon2.o toxyz.o dot.o dcoord.o \
- prog_args.o options.o pctile.o graycode.o sort.o chkmsg.o \
- unpackmsg.o igray.o unpackcall.o unpackgrid.o \
- grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
- packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
- nchar.o four2a.o grid2deg.o pfxdump.o wisdom.o \
- symspec.o analytic.o db.o genjt9.o jt9fano.o \
- packbits.o unpackbits.o encode232.o interleave9.o \
- entail.o fano232.o gran.o sync9.o decjt9.o \
- fil3.o decoder.o grid2n.o n2grid.o timer.o \
- softsym.o peakdt9.o getlags.o afc9.o fchisq.o \
- twkfreq.o downsam9.o symspec2.o ipcomm.o sleep_msec.o \
- stdmsg.o sec_midn.o usleep.o azdist.o geodist.o morse.o \
- fillcom.o chkss2.o zplot9.o flat1.o flat2.o \
- jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
- filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
- extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
- move.o indexx.o graycode65.o twkfreq65.o smo.o smo121.o \
- wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
- flat4.o polfit.o determ.o baddata.o
-
-libjt9.a: $(OBJS1)
- $(AR) libjt9.a $(OBJS1)
- $(RANLIB) libjt9.a
-
-OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o
-
-jt9: $(OBJS2) libjt9.a
- $(CXX) -o jt9 $(OBJS2) -L. -ljt9 -lQt5Core -lfftw3f_threads -lfftw3f `$(FC) -print-file-name=libgfortran.so`
- $(MKDIR) -p $(EXE_DIR)
- $(CP) jt9 $(EXE_DIR)
-
-OBJS3 = jt9sim.o
-jt9sim: $(OBJS3) libjt9.a
- $(FC) -o jt9sim $(OBJS3) -L. -ljt9
-
-OBJS4 = jt9code.o
-jt9code: $(OBJS4) libjt9.a
- $(FC) -o jt9code $(OBJS4) -L. -ljt9
- $(CP) jt9code $(EXE_DIR)
-
-OBJS6 = jt65code.o
-jt65code: $(OBJS6) libjt9.a
- $(FC) -o jt65code $(OBJS6) libjt9.a
- $(CP) jt65code $(EXE_DIR)
-
-sync9.o: sync9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c sync9.f90
-
-peakdf9.o: peakdf9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c peakdf9.f90
-
-peakdt9.o: peakdt9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c peakdt9.f90
-
-jt9sim.o: jt9sim.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c jt9sim.f90
-
-genjt9.o: genjt9.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c genjt9.f90
-
-redsync.o: redsync.f90 jt9sync.f90
- $(FC) $(FFLAGS) -c redsync.f90
-
-ipcomm.o: ipcomm.cpp
- $(CXX) -c $(INCPATH) -fPIE ipcomm.cpp
-
-sec_midn.o: sec_midn.f90
- $(FC) -c -fno-second-underscore sec_midn.f90
-
-init_rs.o: init_rs.c
- $(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
-
-encode_rs.o: encode_rs.c
- $(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
-
-decode_rs.o: decode_rs.c
- $(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
-
-.PHONY : clean
-
-clean:
- $(RM) *.o libjt9.a wsjtx jt9sim jt9 jt9code
diff --git a/lib/Makefile.msk b/lib/Makefile.msk
deleted file mode 100644
index 333b36c..0000000
--- a/lib/Makefile.msk
+++ /dev/null
@@ -1,71 +0,0 @@
-
-# Set paths
-EXE_DIR = ..\\..\\wsjtx_install
-QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
-FFTW3_DIR = ..
-
-INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
-
-# Compilers
-CC = gcc
-CXX = g++
-FC = gfortran
-AR = ar cr
-RANLIB = ranlib
-MKDIR = mkdir -p
-CP = cp
-RM = rm -f
-
-FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
-CFLAGS = -O2 -I.
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-#all: jt9code JTMSKcode
-all: jtmsk JTMSKcode
-
-OBJS4 = jt9code.o packjt.o fmtmsg.o gen9.o deg2grid.o grid2deg.o \
- entail.o encode232.o interleave9.o graycode.o igray.o
-jt9code: $(OBJS4)
- $(FC) -o jt9code $(OBJS4)
-
-OBJS5 = JTMSKcode.o packjt.o fmtmsg.o genmsk.o deg2grid.o grid2deg.o \
- entail.o nhash.o tab.o vit213.o
-JTMSKcode: $(OBJS5)
- $(FC) -o JTMSKcode $(OBJS5)
-
-OBJS6 = jtmsk.o jtmsk.o analytic.o four2a.o db.o mskdf.o pctile.o \
- sort.o tweak1.o syncmsk.o genmsk.o packjt.o fmtmsg.o indexx.o \
- deg2grid.o grid2deg.o entail.o nhash.o tab.o vit213.o
-jtmsk: $(OBJS6)
- $(FC) -o jtmsk $(OBJS6) -lfftw3f
-
-OBJS1 = t1.o four2a.o db.o
-t1: $(OBJS1)
- $(FC) -o t1 $(OBJS1) -lfftw3f
-
-OBJS2 = t2.o four2a.o db.o
-t2: $(OBJS2)
- $(FC) -o t2 $(OBJS2) -lfftw3f
-
-OBJS6 = t6.o four2a.o db.o
-t6: $(OBJS6)
- $(FC) -o t6 $(OBJS6) -lfftw3f
-
-nhash.o: wsprd/nhash.h wsprd/nhash.c
- $(CC) -c -O2 wsprd/nhash.c
-
-.PHONY : clean
-
-clean:
- $(RM) *.o JTMSKcode JTMSKcode.exe
diff --git a/lib/Makefile.mskWin b/lib/Makefile.mskWin
deleted file mode 100644
index 9d5e6e6..0000000
--- a/lib/Makefile.mskWin
+++ /dev/null
@@ -1,75 +0,0 @@
-
-# Set paths
-EXE_DIR = ..\\..\\wsjtx_install
-QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
-FFTW3_DIR = ..
-
-INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
-
-# Compilers
-CC = gcc
-CXX = g++
-FC = gfortran
-AR = ar cr
-RANLIB = ranlib
-MKDIR = mkdir -p
-CP = cp
-RM = rm -f
-
-FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
-CFLAGS = -O2 -I.
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-#all: jt9code JTMSKcode.exe
-all: jtmsk.exe JTMSKsim.exe JTMSKcode.exe fixwav.exe
-
-OBJS3 = JTMSKsim.o wavhdr.o gran.o four2a.o db.o
-JTMSKsim.exe: $(OBJS3)
- $(FC) -o JTMSKsim.exe $(OBJS3) C:\JTSDK\fftw3f\libfftw3f-3.dll
-
-OBJS4 = jt9code.o packjt.o fmtmsg.o gen9.o deg2grid.o grid2deg.o \
- entail.o encode232.o interleave9.o graycode.o igray.o
-jt9code: $(OBJS4)
- $(FC) -o jt9code $(OBJS4)
-
-OBJS5 = JTMSKcode.o packjt.o fmtmsg.o genmsk.o deg2grid.o grid2deg.o \
- entail.o tab.o vit213.o hashing.o nhash.o
-JTMSKcode.exe: $(OBJS5)
- $(FC) -o JTMSKcode.exe $(OBJS5)
-
-OBJS6 = jtmsk.o analytic.o four2a.o db.o pctile.o \
- shell.o tweak1.o syncmsk.o genmsk.o packjt.o fmtmsg.o indexx.o \
- deg2grid.o grid2deg.o entail.o hashing.o nhash.o tab.o vit213.o \
- mskdt.o rectify_msk.o timer.o jtmsk_decode.o genmsk_short.o \
- jtmsk_short.o golay24_table.o hash.o
-
-jtmsk.exe: $(OBJS6)
- $(FC) -o jtmsk.exe $(OBJS6) C:\JTSDK\fftw3f\libfftw3f-3.dll
-
-OBJS1 = fixwav.o wavhdr.o
-fixwav.exe: $(OBJS1)
- $(FC) -o fixwav.exe $(OBJS1)
-
-OBJS2 = t2.o four2a.o db.o
-t2: $(OBJS2)
- $(FC) -o t2 $(OBJS2) C:\JTSDK\fftw3f\libfftw3f-3.dll
-
-OBJS6 = t6.o four2a.o db.o
-t6: $(OBJS6)
- $(FC) -o t6 $(OBJS6) C:\JTSDK\fftw3f\libfftw3f-3.dll
-
-.PHONY : clean
-
-clean:
- $(RM) *.o JTMSKcode JTMSKcode.exe
diff --git a/lib/allsim.f90 b/lib/allsim.f90
deleted file mode 100644
index 2d948b6..0000000
--- a/lib/allsim.f90
+++ /dev/null
@@ -1,78 +0,0 @@
-program allsim
-
-! Generate simulated data for WSJT-X slow modes: JT4, JT9, JT65, QRA64,
-! and WSPR. Also unmodulated carrier and 20 WPM CW.
-
-
- use wavhdr
- use packjt
- parameter (NMAX=60*12000)
- type(hdr) h
- integer*2 iwave(NMAX) !Generated waveform (no noise)
- integer itone(206) !Channel symbols (values 0-8)
- integer icw(250)
- integer*1 msgbits(87)
- logical*1 bcontest
- real*4 dat(NMAX)
- character message*22,msgsent*22,arg*8,mygrid*6
-
- nargs=iargc()
- if(nargs.ne.1) then
- print*,'Usage: allsim '
- go to 999
- endif
-
- call getarg(1,arg)
- read(arg,*) snrdb !S/N in dB (2500 hz reference BW)
-
- message='CQ KA2ABC FN20'
- mygrid='FN20 '
- bcontest=.false.
- rmsdb=25.
- rms=10.0**(0.05*rmsdb)
- sig=10.0**(0.05*snrdb)
- npts=NMAX
-
- call init_random_seed() !Seed Fortran RANDOM_NUMBER generator
- call sgran() !Seed C rand generator (used in gran)
-
- h=default_header(12000,npts)
- open(10,file='000000_0000.wav',access='stream',status='unknown')
- do i=1,npts !Generate gaussian noise
- dat(i)=gran()
- enddo
-
- itone=0
- call addit(itone,12000,85,6912,400,sig,dat) !Unmodulated carrier
-
- call morse('CQ CQ DE KA2ABC KA2ABC',icw,ncw)
-! print*,ncw
-! write(*,3001) icw(1:ncw)
-!3001 format(50i1)
- call addcw(icw,ncw,600,sig,dat) !CW
-
- call genwspr(message,msgsent,itone)
- call addit(itone,12000,86,8192,800,sig,dat) !WSPR (only 59 s of data)
-
- call gen9(message,0,msgsent,itone,itype)
- call addit(itone,12000,85,6912,1000,sig,dat) !JT9
-
- call gen4(message,0,msgsent,itone,itype)
- call addit(itone,11025,206,2520,1200,sig,dat) !JT4
-
- i3bit=0 ! ### TEMPORARY ??? ###
- call genft8(message,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
- call addit(itone,12000,79,1920,1400,sig,dat) !FT8
-
- call genqra64(message,0,msgsent,itone,itype)
- call addit(itone,12000,84,6912,1600,sig,dat) !QRA64
-
- call gen65(message,0,msgsent,itone,itype)
- call addit(itone,11025,126,4096,1800,sig,dat) !JT65
-
- iwave(1:npts)=nint(rms*dat(1:npts))
-
- write(10) h,iwave(1:npts)
- close(10)
-
-999 end program allsim
diff --git a/lib/chkfft.txt b/lib/chkfft.txt
deleted file mode 100644
index 970d7a7..0000000
--- a/lib/chkfft.txt
+++ /dev/null
@@ -1,124 +0,0 @@
- Brief Description of chkfft, by K1JT
- ------------------------------------
-
-Discrete Fourier transforms (DFTs) are found at the root of most
-digital signal processing tasks. In WSJT and its sister programs the
-transforms are done using the FFTW library, and subroutine four2
-provides a convenient interface to the library. Program chkfft is a
-command-line utility offering a convenient way to test FFT execution
-times under a variety of circumstances.
-
-To compile chkfft in Linux:
-
-$ gfortran -o chkfft chkfft.f90 four2a.f90 f77_wisdom.f90 gran.c -lfftw3f
-
-To compile chkfft in Windows (you may need to customize the hard-coded
-path shown here for libfftw3f-3.dll):
-
-> gfortran -o chkfft chkfft.f90 four2a.f90 f77_wisdom.f90 gran.c \
- /JTSDK-QT/appsupport/runtime/libfftw3f-3.dll
-
-To see a brief usage message, type chkfft at the command prompt:
-
-$ chkfft
- Usage: chkfft nr nw nc np
- nfft: length of FFT
- nfft=0: do lengths 2^n, n=2^4 to 2^23
- infile: name of file with nfft values, one per line
- nr: 0/1 to not read (or read) wisdom
- nw: 0/1 to not write (or write) wisdom
- nc: 0/1 for real or complex data
- np: 0-4 patience for finding best algorithm
-
-As an example, to measure the speed of a complex DFT of length 131072:
-
-#######################################################################
-$ chkfft 131072 0 1 1 2
-
-nfft: 131072 nr: 0 nw 1 nc: 1 np: 2
-
- NFFT Time rms MHz MFlops iters tplan
--------------------------------------------------------------
- 131072 0.0021948 0.00000032 59.72 5076.1 231 2.9
-#######################################################################
-
-Program output shows that on the test machine the average time for one
-forward (or inverse) transform of length N=131072 is about 2.2 ms,
-corresponding to slightly over 5 GFlops computing speed. The planning
-time in FFTW was 2.9 s.
-
-Running the command again with parameter nr=1 will use the
-"wisdom" already accumulated for complex N=131072 FFTs. The execution
-speed will be essentially the same, but no planning time is required:
-
-#######################################################################
-$ chkfft 131072 1 1 1 2
-
-nfft: 131072 nr: 1 nw 1 nc: 1 np: 2
-
- NFFT Time rms MHz MFlops iters tplan
--------------------------------------------------------------
- 131072 0.0021575 0.00000032 60.75 5164.0 235 0.0
-#######################################################################
-
-Optimized algorithms can compute DFTs much faster for lengths that are
-the product of small integers. Length N=131072 = 2^17 is a good
-example, and FFTs should be very efficient. For comparison, look at
-the speed for N=131071, a prime number. The average time is now about
-7 times larger:
-
-#######################################################################
-C:\JTSDK-QT\src\wsjtx\lib>chkfft 131071 1 1 1 2
-
-nfft: 131071 nr: 1 nw 1 nc: 1 np: 2
-
- NFFT Time rms MHz MFlops iters tplan
--------------------------------------------------------------
- 131071 0.0153637 0.00000065 8.53 725.2 33 5.6
-#######################################################################
-
-Here's an example that measures execution times for all integral
-power-of-2 lengths from 2^4 to 2^23:
-
-#######################################################################
-$ chkfft 0 1 1 1 2
-
-nfft: 0 nr: 1 nw 1 nc: 1 np: 2
-
- n N=2^n Time rms MHz MFlops iters tplan
----------------------------------------------------------------
- 4 16 0.0000003 0.00000014 58.61 1172.2 1000000 0.0
- 5 32 0.0000004 0.00000016 89.19 2229.6 1000000 0.0
- 6 64 0.0000006 0.00000016 109.44 3283.2 866975 0.0
- 7 128 0.0000009 0.00000021 135.92 4757.1 538369 0.0
- 8 256 0.0000016 0.00000020 158.40 6335.8 313701 0.0
- 9 512 0.0000032 0.00000021 162.53 7313.8 160943 0.1
-10 1024 0.0000067 0.00000023 152.53 7626.5 75521 0.1
-11 2048 0.0000136 0.00000025 150.42 8273.3 37239 0.2
-12 4096 0.0000316 0.00000027 129.75 7784.8 16060 0.3
-13 8192 0.0000720 0.00000026 113.75 7393.8 7040 0.5
-14 16384 0.0001620 0.00000028 101.11 7078.0 3129 0.9
-15 32768 0.0003227 0.00000030 101.53 7615.1 1571 1.7
-16 65536 0.0010020 0.00000030 65.41 5232.5 506 4.1
-17 131072 0.0021575 0.00000032 60.75 5164.0 235 0.0
-18 262144 0.0053937 0.00000032 48.60 4374.2 94 3.6
-19 524288 0.0190668 0.00000034 27.50 2612.2 27 6.8
-20 1048576 0.0468001 0.00000035 22.41 2240.5 11 2.4
-21 2097152 0.0936012 0.00000036 22.41 2352.5 6 31.6
-22 4194304 0.1949997 0.00000037 21.51 2366.0 3 9.8
-23 8388608 0.4212036 0.00000038 19.92 2290.3 2 112.9
-#######################################################################
-
-Test data for all transforms is gaussian random noise of zero mean and
-standard deviation 1. Tabulated values of "rms" are the
-root-mean-square differences between the original data and the
-back-transfmred data.
-
-File nfft.dat contains all numbers between 2^3 and 2^23 with no factor
-greater than 7, followed by their factors. These numbers are good
-choices for FFT lengths. File all_fft.out gives the result on one
-machine of running the command
-
-$ chkfft nfft.dat 0 1 1 2
-
-Take note: this task may take as much as 24 hours, or even more!
diff --git a/lib/decoder.f90 b/lib/decoder.f90
index 79d8c9d..204fa1d 100644
--- a/lib/decoder.f90
+++ b/lib/decoder.f90
@@ -3,43 +3,42 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
!$ use omp_lib
use prog_args
use timer_module, only: timer
- use jt4_decode
- use jt65_decode
- use jt9_decode
use ft8_decode
+ use js8b_decode
+ use js8c_decode
+ use js8d_decode
include 'jt9com.f90'
include 'timer_common.inc'
- type, extends(jt4_decoder) :: counting_jt4_decoder
- integer :: decoded
- end type counting_jt4_decoder
-
- type, extends(jt65_decoder) :: counting_jt65_decoder
- integer :: decoded
- end type counting_jt65_decoder
-
- type, extends(jt9_decoder) :: counting_jt9_decoder
- integer :: decoded
- end type counting_jt9_decoder
-
type, extends(ft8_decoder) :: counting_ft8_decoder
integer :: decoded
end type counting_ft8_decoder
+ type, extends(js8b_decoder) :: counting_js8b_decoder
+ integer :: decoded
+ end type counting_js8b_decoder
+
+ type, extends(js8c_decoder) :: counting_js8c_decoder
+ integer :: decoded
+ end type counting_js8c_decoder
+
+ type, extends(js8d_decoder) :: counting_js8d_decoder
+ integer :: decoded
+ end type counting_js8d_decoder
+
real ss(184,NSMAX)
- logical baddata,newdat65,newdat9,single_decode,bVHF,bad0,newdat,ex
+ logical baddata,newdat65,newdat9,single_decode,bVHF,bad0,newdat
integer*2 id2(NTMAX*12000)
type(params_block) :: params
- real*4 dd(NTMAX*12000)
character(len=20) :: datetime
character(len=12) :: mycall, hiscall
character(len=6) :: mygrid, hisgrid
save
- type(counting_jt4_decoder) :: my_jt4
- type(counting_jt65_decoder) :: my_jt65
- type(counting_jt9_decoder) :: my_jt9
- type(counting_ft8_decoder) :: my_ft8
+ type(counting_ft8_decoder) :: my_js8a
+ type(counting_js8b_decoder) :: my_js8b
+ type(counting_js8c_decoder) :: my_js8c
+ type(counting_js8d_decoder) :: my_js8d
!cast C character arrays to Fortran character strings
datetime=transfer(params%datetime, datetime)
@@ -49,10 +48,10 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
hisgrid=transfer(params%hisgrid,hisgrid)
! initialize decode counts
- my_jt4%decoded = 0
- my_jt65%decoded = 0
- my_jt9%decoded = 0
- my_ft8%decoded = 0
+ my_js8a%decoded = 0
+ my_js8b%decoded = 0
+ my_js8c%decoded = 0
+ my_js8d%decoded = 0
single_decode=iand(params%nexp_decode,32).ne.0
bVHF=iand(params%nexp_decode,64).ne.0
@@ -79,20 +78,55 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
endif
endif
- if(params%nmode.eq.8) then
-! We're in FT8 mode
- call timer('decft8 ',0)
+ if(params%nmode.eq.8 .and. params%nsubmode.eq.3) then
+! We're in JS8 mode C
+ call timer('decjs8d ',0)
newdat=params%newdat
- call my_ft8%decode(ft8_decoded,id2,params%nQSOProgress,params%nfqso, &
+ call my_js8d%decode(js8d_decoded,id2,params%nQSOProgress,params%nfqso, &
params%nftx,newdat,params%nutc,params%nfa,params%nfb, &
params%nexp_decode,params%ndepth,logical(params%nagain), &
logical(params%lft8apon),logical(params%lapcqonly),params%napwid, &
mycall,mygrid,hiscall,hisgrid)
- call timer('decft8 ',1)
- if(nfox.gt.0) then
- n30min=minval(n30fox(1:nfox))
- n30max=maxval(n30fox(1:nfox))
- endif
+ call timer('decjs8d ',1)
+ go to 800
+ endif
+
+ if(params%nmode.eq.8 .and. params%nsubmode.eq.2) then
+! We're in JS8 mode C
+ call timer('decjs8c ',0)
+ newdat=params%newdat
+ call my_js8c%decode(js8c_decoded,id2,params%nQSOProgress,params%nfqso, &
+ params%nftx,newdat,params%nutc,params%nfa,params%nfb, &
+ params%nexp_decode,params%ndepth,logical(params%nagain), &
+ logical(params%lft8apon),logical(params%lapcqonly),params%napwid, &
+ mycall,mygrid,hiscall,hisgrid)
+ call timer('decjs8c ',1)
+ go to 800
+ endif
+
+ if(params%nmode.eq.8 .and. params%nsubmode.eq.1) then
+! We're in JS8 mode B
+ call timer('decjs8b ',0)
+ newdat=params%newdat
+ call my_js8b%decode(js8b_decoded,id2,params%nQSOProgress,params%nfqso, &
+ params%nftx,newdat,params%nutc,params%nfa,params%nfb, &
+ params%nexp_decode,params%ndepth,logical(params%nagain), &
+ logical(params%lft8apon),logical(params%lapcqonly),params%napwid, &
+ mycall,mygrid,hiscall,hisgrid)
+ call timer('decjs8b ',1)
+ go to 800
+ endif
+
+ if(params%nmode.eq.8) then
+! We're in JS8 mode A
+ call timer('decjs8a ',0)
+ newdat=params%newdat
+ call my_js8a%decode(js8a_decoded,id2,params%nQSOProgress,params%nfqso, &
+ params%nftx,newdat,params%nutc,params%nfa,params%nfb, &
+ params%nexp_decode,params%ndepth,logical(params%nagain), &
+ logical(params%lft8apon),logical(params%lapcqonly),params%napwid, &
+ mycall,mygrid,hiscall,hisgrid)
+ call timer('decjs8a ',1)
go to 800
endif
@@ -122,27 +156,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
! id2(1:nz)=0 ! temporarily disabled as it can breaak the JT9 decoder, maybe others
endif
- if(params%nmode.eq.4 .or. params%nmode.eq.65) open(14,file=trim(temp_dir)// &
- '/avemsg.txt',status='unknown')
- if(params%nmode.eq.164) open(17,file=trim(temp_dir)//'/red.dat', &
- status='unknown')
-
- if(params%nmode.eq.4) then
- jz=52*nfsample
- if(params%newdat) then
- if(nfsample.eq.12000) call wav11(id2,jz,dd)
- if(nfsample.eq.11025) dd(1:jz)=id2(1:jz)
- endif
- call my_jt4%decode(jt4_decoded,dd,jz,params%nutc,params%nfqso, &
- params%ntol,params%emedelay,params%dttol,logical(params%nagain), &
- params%ndepth,logical(params%nclearave),params%minsync, &
- params%minw,params%nsubmode,mycall,hiscall, &
- hisgrid,params%nlist,params%listutc,jt4_average)
- go to 800
- endif
-
npts65=52*12000
- if(params%nmode.eq.164) npts65=54*12000
if(baddata(id2,npts65)) then
nsynced=0
ndecoded=0
@@ -154,268 +168,25 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
newdat9=params%newdat
!$call omp_set_dynamic(.true.)
-!$omp parallel sections num_threads(2) copyin(/timer_private/) shared(ndecoded) if(.true.) !iif() needed on Mac
-!$omp section
- if(params%nmode.eq.65 .or. params%nmode.eq.164 .or. &
- (params%nmode.eq.(65+9) .and. params%ntxmode.eq.65)) then
-! We're in JT65 or QRA64 mode, or should do JT65 first
-
- if(newdat65) dd(1:npts65)=id2(1:npts65)
- nf1=params%nfa
- nf2=params%nfb
- call timer('jt65a ',0)
- call my_jt65%decode(jt65_decoded,dd,npts65,newdat65,params%nutc, &
- nf1,nf2,params%nfqso,ntol65,params%nsubmode,params%minsync, &
- logical(params%nagain),params%n2pass,logical(params%nrobust), &
- ntrials,params%naggressive,params%ndepth,params%emedelay, &
- logical(params%nclearave),mycall,hiscall, &
- hisgrid,params%nexp_decode,params%nQSOProgress, &
- logical(params%ljt65apon))
- call timer('jt65a ',1)
-
- else if(params%nmode.eq.9 .or. (params%nmode.eq.(65+9) .and. params%ntxmode.eq.9)) then
-! We're in JT9 mode, or should do JT9 first
- call timer('decjt9 ',0)
- call my_jt9%decode(jt9_decoded,ss,id2,params%nfqso, &
- newdat9,params%npts8,params%nfa,params%nfsplit,params%nfb, &
- params%ntol,params%nzhsym,logical(params%nagain),params%ndepth, &
- params%nmode,params%nsubmode,params%nexp_decode)
- call timer('decjt9 ',1)
- endif
-
-!$omp section
- if(params%nmode.eq.(65+9)) then !Do the other mode (we're in dual mode)
- if (params%ntxmode.eq.9) then
- if(newdat65) dd(1:npts65)=id2(1:npts65)
- nf1=params%nfa
- nf2=params%nfb
- call timer('jt65a ',0)
- call my_jt65%decode(jt65_decoded,dd,npts65,newdat65,params%nutc, &
- nf1,nf2,params%nfqso,ntol65,params%nsubmode,params%minsync, &
- logical(params%nagain),params%n2pass,logical(params%nrobust), &
- ntrials,params%naggressive,params%ndepth,params%emedelay, &
- logical(params%nclearave),mycall,hiscall, &
- hisgrid,params%nexp_decode,params%nQSOProgress, &
- logical(params%ljt65apon))
- call timer('jt65a ',1)
- else
- call timer('decjt9 ',0)
- call my_jt9%decode(jt9_decoded,ss,id2,params%nfqso, &
- newdat9,params%npts8,params%nfa,params%nfsplit,params%nfb, &
- params%ntol,params%nzhsym,logical(params%nagain), &
- params%ndepth,params%nmode,params%nsubmode,params%nexp_decode)
- call timer('decjt9 ',1)
- end if
- endif
-
-!$omp end parallel sections
-
-! JT65 is not yet producing info for nsynced, ndecoded.
-800 ndecoded = my_jt4%decoded + my_jt65%decoded + my_jt9%decoded + my_ft8%decoded
+800 ndecoded = my_js8a%decoded + my_js8b%decoded + my_js8c%decoded
write(*,1010) nsynced,ndecoded
1010 format('',2i4)
call flush(6)
- if(params%nmode.eq.4 .or. params%nmode.eq.65) close(14)
-
return
contains
- subroutine jt4_decoded(this,snr,dt,freq,have_sync,sync,is_deep, &
- decoded0,qual,ich,is_average,ave)
- implicit none
- class(jt4_decoder), intent(inout) :: this
- integer, intent(in) :: snr
- real, intent(in) :: dt
- integer, intent(in) :: freq
- logical, intent(in) :: have_sync
- logical, intent(in) :: is_deep
- character(len=1), intent(in) :: sync
- character(len=22), intent(in) :: decoded0
- real, intent(in) :: qual
- integer, intent(in) :: ich
- logical, intent(in) :: is_average
- integer, intent(in) :: ave
-
- character*22 decoded
- character*3 cflags
-
- if(ich.eq.-99) stop !Silence compiler warning
- if (have_sync) then
- decoded=decoded0
- cflags=' '
- if(decoded.ne.' ') cflags='f '
- if(is_deep) then
- cflags(1:2)='d1'
- write(cflags(3:3),'(i1)') min(int(qual),9)
- if(qual.ge.10.0) cflags(3:3)='*'
- if(qual.lt.3.0) decoded(22:22)='?'
- endif
- if(is_average) then
- write(cflags(2:2),'(i1)') min(ave,9)
- if(ave.ge.10) cflags(2:2)='*'
- endif
- write(*,1000) params%nutc,snr,dt,freq,sync,decoded,cflags
-1000 format(i4.4,i4,f5.1,i5,1x,'$',a1,1x,a22,1x,a3)
- else
- write(*,1000) params%nutc,snr,dt,freq
- end if
-
- select type(this)
- type is (counting_jt4_decoder)
- this%decoded = this%decoded + 1
- end select
- end subroutine jt4_decoded
-
- subroutine jt4_average (this, used, utc, sync, dt, freq, flip)
- implicit none
- class(jt4_decoder), intent(inout) :: this
- logical, intent(in) :: used
- integer, intent(in) :: utc
- real, intent(in) :: sync
- real, intent(in) :: dt
- integer, intent(in) :: freq
- logical, intent(in) :: flip
- character(len=1) :: cused, csync
-
- cused = '.'
- csync = '*'
- if (used) cused = '$'
- if (flip) csync = '$'
- write(14,1000) cused,utc,sync,dt,freq,csync
-1000 format(a1,i5.4,f6.1,f6.2,i6,1x,a1)
- end subroutine jt4_average
-
- subroutine jt65_decoded(this,sync,snr,dt,freq,drift,nflip,width, &
- decoded0,ft,qual,nsmo,nsum,minsync)
-
- use jt65_decode
+ subroutine js8_decoded (sync,snr,dt,freq,decoded,nap,qual)
implicit none
- class(jt65_decoder), intent(inout) :: this
- real, intent(in) :: sync
- integer, intent(in) :: snr
- real, intent(in) :: dt
- integer, intent(in) :: freq
- integer, intent(in) :: drift
- integer, intent(in) :: nflip
- real, intent(in) :: width
- character(len=22), intent(in) :: decoded0
- integer, intent(in) :: ft
- integer, intent(in) :: qual
- integer, intent(in) :: nsmo
- integer, intent(in) :: nsum
- integer, intent(in) :: minsync
-
- integer i,nap,nft
- logical is_deep,is_average
- character decoded*22,csync*2,cflags*3
-
- if(width.eq.-9999.0) stop !Silence compiler warning
-!$omp critical(decode_results)
- decoded=decoded0
- cflags=' '
- is_deep=ft.eq.2
-
- if(ft.ge.80) then !QRA64 mode
- nft=ft-100
- csync=': '
- if(sync-3.4.ge.float(minsync) .or. nft.ge.0) csync=':*'
- if(nft.lt.0) then
- write(*,1009) params%nutc,snr,dt,freq,csync,decoded
- else
- write(*,1009) params%nutc,snr,dt,freq,csync,decoded,nft
-1009 format(i4.4,i4,f5.1,i5,1x,a2,1x,a22,i2)
- endif
- go to 100
- endif
-
- if(ft.eq.0 .and. minsync.ge.0 .and. int(sync).lt.minsync) then
- write(*,1010) params%nutc,snr,dt,freq
- else
- is_average=nsum.ge.2
- if(bVHF .and. ft.gt.0) then
- cflags='f '
- if(is_deep) then
- cflags(1:2)='d1'
- write(cflags(3:3),'(i1)') min(qual,9)
- if(qual.ge.10) cflags(3:3)='*'
- if(qual.lt.3) decoded(22:22)='?'
- endif
- if(is_average) then
- write(cflags(2:2),'(i1)') min(nsum,9)
- if(nsum.ge.10) cflags(2:2)='*'
- endif
- nap=ishft(ft,-2)
- if(nap.ne.0) then
- write(cflags(1:3),'(a1,i1)') 'a',nap
- endif
- endif
- csync='# '
- i=0
- if(bVHF .and. nflip.ne.0 .and. &
- sync.ge.max(0.0,float(minsync))) then
- csync='#*'
- if(nflip.eq.-1) then
- csync='##'
- if(decoded.ne.' ') then
- do i=22,1,-1
- if(decoded(i:i).ne.' ') exit
- enddo
- if(i.gt.18) i=18
- decoded(i+2:i+4)='OOO'
- endif
- endif
- endif
- write(*,1010) params%nutc,snr,dt,freq,csync,decoded,cflags
-1010 format(i4.4,i4,f5.1,i5,1x,a2,1x,a22,1x,a3)
- endif
-
-100 call flush(6)
-
-!$omp end critical(decode_results)
- select type(this)
- type is (counting_jt65_decoder)
- this%decoded = this%decoded + 1
- end select
- end subroutine jt65_decoded
-
- subroutine jt9_decoded (this, sync, snr, dt, freq, drift, decoded)
- use jt9_decode
- implicit none
-
- class(jt9_decoder), intent(inout) :: this
- real, intent(in) :: sync
- integer, intent(in) :: snr
- real, intent(in) :: dt
- real, intent(in) :: freq
- integer, intent(in) :: drift
- character(len=22), intent(in) :: decoded
-
- !$omp critical(decode_results)
- write(*,1000) params%nutc,snr,dt,nint(freq),decoded
-1000 format(i4.4,i4,f5.1,i5,1x,'@ ',1x,a22)
- call flush(6)
- !$omp end critical(decode_results)
- select type(this)
- type is (counting_jt9_decoder)
- this%decoded = this%decoded + 1
- end select
- end subroutine jt9_decoded
-
- subroutine ft8_decoded (this,sync,snr,dt,freq,decoded,nap,qual)
- use ft8_decode
- implicit none
-
- class(ft8_decoder), intent(inout) :: this
real, intent(in) :: sync
integer, intent(in) :: snr
real, intent(in) :: dt
real, intent(in) :: freq
character(len=37), intent(in) :: decoded
- character c1*12,c2*12,g2*4,w*4,ctmp*12
- integer i0,i1,i2,i3,i4,i5,i6,n30,nwrap
+ character c1*12,c2*12,g2*4,w*4
+ integer i0,i1,i2,i3,i4,i5,n30,nwrap
integer, intent(in) :: nap
real, intent(in) :: qual
character*2 annot
@@ -488,12 +259,103 @@ contains
call flush(6)
+ return
+ end subroutine js8_decoded
+
+ subroutine js8a_decoded (this,sync,snr,dt,freq,decoded,nap,qual)
+ use ft8_decode
+ implicit none
+
+ class(ft8_decoder), intent(inout) :: this
+ real, intent(in) :: sync
+ integer, intent(in) :: snr
+ real, intent(in) :: dt
+ real, intent(in) :: freq
+ character(len=37), intent(in) :: decoded
+ integer, intent(in) :: nap
+ real, intent(in) :: qual
+ save
+
+ call js8_decoded(sync, snr, dt, freq, decoded, nap, qual)
+
select type(this)
type is (counting_ft8_decoder)
this%decoded = this%decoded + 1
end select
return
- end subroutine ft8_decoded
+ end subroutine js8a_decoded
+
+ subroutine js8b_decoded (this,sync,snr,dt,freq,decoded,nap,qual)
+ use js8b_decode
+ implicit none
+
+ class(js8b_decoder), intent(inout) :: this
+ real, intent(in) :: sync
+ integer, intent(in) :: snr
+ real, intent(in) :: dt
+ real, intent(in) :: freq
+ character(len=37), intent(in) :: decoded
+ integer, intent(in) :: nap
+ real, intent(in) :: qual
+ save
+
+ call js8_decoded(sync, snr, dt, freq, decoded, nap, qual)
+
+ select type(this)
+ type is (counting_js8b_decoder)
+ this%decoded = this%decoded + 1
+ end select
+
+ return
+ end subroutine js8b_decoded
+
+ subroutine js8c_decoded (this,sync,snr,dt,freq,decoded,nap,qual)
+ use js8c_decode
+ implicit none
+
+ class(js8c_decoder), intent(inout) :: this
+ real, intent(in) :: sync
+ integer, intent(in) :: snr
+ real, intent(in) :: dt
+ real, intent(in) :: freq
+ character(len=37), intent(in) :: decoded
+ integer, intent(in) :: nap
+ real, intent(in) :: qual
+ save
+
+ call js8_decoded(sync, snr, dt, freq, decoded, nap, qual)
+
+ select type(this)
+ type is (counting_js8c_decoder)
+ this%decoded = this%decoded + 1
+ end select
+
+ return
+ end subroutine js8c_decoded
+
+ subroutine js8d_decoded (this,sync,snr,dt,freq,decoded,nap,qual)
+ use js8d_decode
+ implicit none
+
+ class(js8d_decoder), intent(inout) :: this
+ real, intent(in) :: sync
+ integer, intent(in) :: snr
+ real, intent(in) :: dt
+ real, intent(in) :: freq
+ character(len=37), intent(in) :: decoded
+ integer, intent(in) :: nap
+ real, intent(in) :: qual
+ save
+
+ call js8_decoded(sync, snr, dt, freq, decoded, nap, qual)
+
+ select type(this)
+ type is (counting_js8d_decoder)
+ this%decoded = this%decoded + 1
+ end select
+
+ return
+ end subroutine js8d_decoded
end subroutine multimode_decoder
diff --git a/lib/dxped_fifo.f90 b/lib/dxped_fifo.f90
deleted file mode 100644
index 96f3492..0000000
--- a/lib/dxped_fifo.f90
+++ /dev/null
@@ -1,23 +0,0 @@
-subroutine dxped_fifo(cx,gx,isnrx)
-
- parameter (NCALLS=268)
- character*6 xcall(NCALLS)
- character*4 xgrid(NCALLS)
- integer isnr(NCALLS)
-
- character cx*6,gx*4
- common/dxpfifo/nc,isnr,xcall,xgrid
-
- if(nc.lt.NCALLS) then
- nc=nc+1
- cx=xcall(nc)
- gx=xgrid(nc)
- isnrx=isnr(nc)
- else
- cx=' '
- gx=' '
- isnrx=0
- endif
-
- return
-end subroutine dxped_fifo
diff --git a/lib/fast_decode.f90 b/lib/fast_decode.f90
deleted file mode 100644
index eebb731..0000000
--- a/lib/fast_decode.f90
+++ /dev/null
@@ -1,97 +0,0 @@
-subroutine fast_decode(id2,narg,ntrperiod,line,mycall_12, &
- hiscall_12)
-
- parameter (NMAX=30*12000)
- integer*2 id2(NMAX)
- integer*2 id2a(NMAX)
- integer*2 id2b(NMAX)
- integer narg(0:14)
- real dat(30*12000)
- complex cdat(262145),cdat2(262145)
- real psavg(450)
- logical pick,first
- character*6 cfile6
- character*80 line(100)
- character*12 mycall_12,hiscall_12
- character*6 mycall,hiscall
- data first/.true./,nutca/0/,nutcb/0/
- save npts,cdat,cdat2,id2a,id2b,nutca,nutcb
-
- if(first) then
- id2a=0
- id2b=0
- first=.false.
- endif
-
- mycall=mycall_12(1:6)
- hiscall=hiscall_12(1:6)
- nutc=narg(0)
- ndat0=narg(1)
- nsubmode=narg(2)
- newdat=narg(3)
- minsync=narg(4)
- npick=narg(5)
- t0=0.001*narg(6)
- t1=0.001*narg(7)
- tmid=0.5*(t0+t1)
- maxlines=narg(8)
- nmode=narg(9)
- nrxfreq=narg(10)
- ntol=narg(11)
- nhashcalls=narg(12)
-
- line(1:100)(1:1)=char(0)
- if(t0.gt.float(ntrperiod)) go to 900
- if(t0.gt.t1) go to 900
-
- if(nmode.eq.102) then
- call fast9(id2,narg,line)
- go to 900
- endif
-
- if(newdat.eq.1) then
- cdat2=cdat
- ndat=ndat0
- call wav11(id2,ndat,dat)
- nzz=11025*ntrperiod
- if(ndat.lt.nzz) dat(ndat+1:nzz)=0.0
- ndat=min(ndat,30*11025)
- call ana932(dat,ndat,cdat,npts) !Make downsampled analytic signal
- endif
-
-! Now cdat() is the downsampled analytic signal.
-! New sample rate = fsample = BW = 11025 * (9/32) = 3100.78125 Hz
-! NB: npts, nsps, etc., are all reduced by 9/32
-
- write(cfile6,'(i6.6)') nutc
- nfreeze=1
- mousedf=0
- mousebutton=0
- mode4=1
- if(nsubmode.eq.1) mode4=2
- nafc=0
- ndebug=0
- t2=0.
- ia=1
- ib=npts
- pick=.false.
-
- if(npick.gt.0) then
- pick=.true.
- dt=1.0/11025.0 * (32.0/9.0)
- ia=t0/dt + 1.
- ib=t1/dt + 1.
- t2=t0
- endif
- jz=ib-ia+1
- line(1:100)(1:1)=char(0)
- if(npick.eq.2) then
- call iscat(cdat2(ia),jz,3,40,t2,pick,cfile6,minsync,ntol,NFreeze, &
- MouseDF,mousebutton,mode4,nafc,ndebug,psavg,nmax,nlines,line)
- else
- call iscat(cdat(ia),jz,3,40,t2,pick,cfile6,minsync,ntol,NFreeze, &
- MouseDF,mousebutton,mode4,nafc,ndebug,psavg,maxlines,nlines,line)
- endif
-
-900 return
-end subroutine fast_decode
diff --git a/lib/fer b/lib/fer
deleted file mode 100755
index 7a74bf2..0000000
--- a/lib/fer
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-# jt65 end-to-end simulator. Run enough cases to get a given
-# number of successful decodes or a given number of errors
-# For better performance, copy this script and jt65, jt65sim
-# executables to a ramdisk and run from there.
-
-mode=C
-spread=4.0
-
-for i in `seq 0 21`;
-do
-nruns=0
-ndecodes=0
-ngood=0
-nbad=0
-snr=$((-25+$i))
-#while [ $[ $nruns - $ngood ] -lt 200 ]
-#while [ $ngood -lt 200 ]
-while [ $nruns -lt 1000 ]
-do
- rm 000000_0001.wav
- ./jt65sim -m $mode -n 1 -d $spread -s \\$snr > /dev/null
- rm decoded.txt
- ./jt65 -m $mode -a 10 -f 1500 -n 1000 -s 000000_0001.wav > decoded.txt
- if [ -e decoded.txt ]; then
- nd=$( wc -l < decoded.txt )
- ng=$( grep "K1ABC" decoded.txt | wc -l )
- nb=$[$nd-$ng]
- ndecodes=$[$ndecodes + $nd]
- ngood=$[$ngood + $ng]
- nbad=$[$nbad + $nb]
- fi
- nruns=$[$nruns + 1]
- nmissed=$[$nruns-$ngood]
- pe=$( echo "scale=5; $nmissed/$nruns" | bc -l )
- ps=$( echo "scale=5; $ngood/$nruns" | bc -l )
- echo -en snr: $snr nruns: $nruns ndecodes: $ndecodes ngood: $ngood nbad: $nbad nmissed: $nmissed wer: $pe success: $ps"\r"
-done
-echo snr: $snr nruns: $nruns ndecodes: $ndecodes ngood: $ngood nbad: $nbad nmissed: $nmissed wer: $pe success: $ps
-done
diff --git a/lib/fer65.f90 b/lib/fer65.f90
deleted file mode 100644
index 1284fb5..0000000
--- a/lib/fer65.f90
+++ /dev/null
@@ -1,195 +0,0 @@
-program fer65
-
-! End-to-end simulator for testing JT65.
-
-! Options
-! jt65sim jt65
-!----------------------------------------------------------------
-! -a aggressive
-! -d Doppler spread -d depth
-! -f Number of files -f freq
-! -m (sub)mode -m (sub)mode
-! -n number of generated sigs -n ntrials
-! -t Time offset (s) -r robust sync
-! -p Do not seed random #s -c mycall
-! -x hiscall
-! -g hisgrid
-! -X hinted-decode flags
-! -s S/N in 2500 Hz -s single-decode mode
-
- implicit real*8 (a-h,o-z)
- real*8 s(7),sq(7)
- character arg*12,cmnd*100,decoded*22,submode*1,csync*1,f1*15,f2*15
- character*12 outfile
- logical syncok
-
- nargs=iargc()
- if(nargs.ne.7) then
- print*,'Usage: fer65 submode fspread snr1 snr2 Navg DS iters'
- print*,'Example: fer65 C 3.0 -28 -12 8 1 1000'
- go to 999
- endif
-
- call getarg(1,submode)
- call getarg(2,arg)
- read(arg,*) d
- call getarg(3,arg)
- read(arg,*) snr1
- call getarg(4,arg)
- read(arg,*) snr2
- call getarg(5,arg)
- read(arg,*) navg
- call getarg(6,arg)
- read(arg,*) nds
- call getarg(7,arg)
- read(arg,*) iters
-
- write(outfile,1001) submode,d,navg,nds
-1001 format(a1,f6.2,'_',i2.2,'_',i1)
- if(outfile(2:2).eq.' ') outfile(2:2)='0'
- if(outfile(3:3).eq.' ') outfile(3:3)='0'
-
- ndepth=3
- if(navg.gt.1) ndepth=ndepth+16
- if(nds.ne.0) ndepth=ndepth+32
-
- dfmax=3
- if(submode.eq.'b' .or. submode.eq.'B') dfmax=6
- if(submode.eq.'c' .or. submode.eq.'C') dfmax=11
-
- ntrials=1000
- naggressive=10
-
- open(20,file=outfile,status='unknown')
- open(21,file='fer65.21',status='unknown')
-
- write(20,1000) submode,iters,ntrials,naggressive,d,ndepth,navg,nds
-1000 format(/'JT65',a1,' Iters:',i5,' T:',i6,' Aggr:',i3, &
- ' Dop:',f6.2,' Depth:',i2,' Navg:',i3,' DS:',i2)
- write(20,1002)
-1002 format(/' dB nsync ngood nbad sync dsnr ', &
- 'DT Freq Nsum Width'/85('-'))
- flush(20)
-
- do isnr=0,20
- snr=snr1+isnr
- if(snr.gt.snr2) exit
- nsync=0
- ngood=0
- nbad=0
- s=0.
- sq=0.
- do iter=1,iters
- write(cmnd,1010) submode,d,snr,navg
-1010 format('./jt65sim -n 1 -m ',a1,' -d',f7.2,' -s \\',f5.1,' -f',i3,' >devnull')
- call unlink('000000_????.wav')
- call system(cmnd)
- if(navg.gt.1) then
- do i=navg,2,-1
- j=2*i-1
- write(f1,1011) i
- write(f2,1011) j
-1011 format('000000_',i4.4,'.wav')
- call rename(f1,f2)
- enddo
- endif
- call unlink('decoded.txt')
- call unlink('fort.13')
- isync=0
- nsnr=0
- dt=0.
- nfreq=0
- ndrift=0
- nwidth=0
- cmnd='./jt65 -m A -a 10 -c K1ABC -f 1500 -n 1000 -d 5 -s 000000_????.wav > decoded.txt'
- cmnd(11:11)=submode
- write(cmnd(47:48),'(i2)') ndepth
- call system(cmnd)
- open(13,file='fort.13',status='old',err=20)
- do i=1,navg
- read(13,1012) nutc,isync,nsnr,dt,nfreq,ndrift,nwidth,decoded, &
- nft,nsum,nsmo
-1012 format(i4,i4,i5,f6.2,i5,i4,i3,1x,a22,5x,3i3)
- if(nft.gt.0) exit
- enddo
- close(13)
- syncok=abs(dt).lt.0.2 .and. float(abs(nfreq-1500)).lt.dfmax
- csync=' '
- if(syncok) csync='*'
- write(21,1014) nutc,isync,nsnr,dt,nfreq,ndrift,nwidth, &
- nft,nsum,nsmo,csync,decoded(1:16),nft,nsum,nsmo
-1014 format(i4,i4,i5,f6.2,i5,i4,3x,4i3,1x,a1,1x,a16,i2,2i3)
- flush(21)
-
- if(syncok) then
- nsync=nsync+1
- s(1)=s(1) + isync
- sq(1)=sq(1) + isync*isync
- s(6)=s(6) + nwidth
- sq(6)=sq(6) + nwidth*nwidth
- if(decoded.eq.'K1ABC W9XYZ EN37 ') then
- ngood=ngood+1
- s(2)=s(2) + nsnr
- s(3)=s(3) + dt
- s(4)=s(4) + nfreq
- s(5)=s(5) + ndrift
- s(7)=s(7) + nsum
-
- sq(2)=sq(2) + nsnr*nsnr
- sq(3)=sq(3) + dt*dt
- sq(4)=sq(4) + nfreq*nfreq
- sq(5)=sq(5) + ndrift*ndrift
- sq(7)=sq(7) + nsum*nsum
- else if(decoded.ne.' ') then
- nbad=nbad+1
- print*,'Nbad:',nbad,decoded
- endif
- endif
-20 continue
- fsync=float(nsync)/iter
- fgood=float(ngood)/iter
- fbad=float(nbad)/iter
- write(*,1020) nint(snr),iter,isync,nsnr,dt,nfreq,ndrift,nwidth,fsync, &
- fgood,fbad,decoded(1:16),nft,nsum,nsmo
-1020 format(i3,i5,i3,i4,f6.2,i5,i3,i3,2f6.3,f7.4,1x,a16,i2,2i3)
- enddo
-
- if(nsync.ge.1) then
- xsync=s(1)/nsync
- xwidth=s(6)/nsync
- endif
- esync=0.
- if(nsync.ge.2) then
- esync=sqrt(sq(1)/nsync - xsync**2)
- ewidth=sqrt(sq(6)/nsync - xwidth**2)
- endif
-
- if(ngood.ge.1) then
- xsnr=s(2)/ngood
- xdt=s(3)/ngood
- xfreq=s(4)/ngood
- xdrift=s(5)/ngood
- xsum=s(7)/ngood
- endif
- if(ngood.ge.2) then
- esnr=sqrt(sq(2)/ngood - xsnr**2)
- edt=sqrt(sq(3)/ngood - xdt**2)
- efreq=sqrt(sq(4)/ngood - xfreq**2)
- edrift=sqrt(sq(5)/ngood - xdrift**2)
- esum=sqrt(sq(7)/ngood - xsum**2)
- endif
-
- dsnr=xsnr-snr
- dfreq=xfreq-1500.0
- if(ngood.eq.0) then
- dsnr=0.
- dfreq=0.
- endif
- write(20,1100) snr,nsync,ngood,nbad,xsync,esync,dsnr,esnr, &
- xdt,edt,dfreq,efreq,xsum,esum,xwidth,ewidth
-1100 format(f5.1,2i6,i4,2f6.1,f6.1,f5.1,f6.2,f5.2,6f5.1)
- flush(20)
- if(ngood.ge.int(0.99*iters)) exit
- enddo
-
-999 end program fer65
diff --git a/lib/fersum.f90 b/lib/fersum.f90
deleted file mode 100644
index 4a99561..0000000
--- a/lib/fersum.f90
+++ /dev/null
@@ -1,72 +0,0 @@
-program fersum
-
- character mode*5
- character infile*40
- real dop(0:9)
- real thresh(0:9,12),threshsync(0:9,12)
- data dop/0.25,0.5,1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0/
-
- nargs=iargc()
- if(nargs.ne.1) then
- print*,'Usage: fersum '
- go to 999
- endif
- call getarg(1,infile)
- open(10,file=infile,status='old')
- thresh=0.
- threshsync=0.
-
- do iblk=1,999
-1 read(10,1002,end=100) mode,iters,ntot,naggr,d,navg,nds
-1002 format(a5,8x,i5,4x,i6,7x,i3,6x,f6.2,17x,i3,5x,i2)
- write(33,*) iblk,mode
- if(mode.eq.' ') go to 1
- read(10,1002)
- read(10,1002)
- read(10,1002)
-
- nsync0=0
- ngood0=0
- xsum0=0.
- do n=1,99
- read(10,1010,end=100) snr,nsync,ngood,nbad,xsync,esync,dsnr,esnr, &
- xdt,edt,dfreq,efreq,xsum,esum,xwidth,ewidth
-1010 format(f5.1,2i6i4,2f6.1,f6.1,f5.1,f6.2,f5.2,6f5.1)
- if(snr.eq.0.0) exit
- if(mode(5:5).eq.'A') nmode=1
- if(mode(5:5).eq.'B') nmode=2
- if(mode(5:5).eq.'C') nmode=3
- j=nint(log(d)/log(2.0) + 2.0)
- if(navg.eq.1 .and. nds.eq.0) k=nmode
- if(navg.eq.1 .and. nds.eq.1) k=nmode+3
- if(navg.gt.1 .and. nds.eq.0) k=nmode+6
- if(navg.gt.1 .and. nds.eq.1) k=nmode+9
- if(nsync0.le.iters/2 .and. nsync.ge.iters/2) then
- threshsync(j,k)=snr-float(nsync-iters/2)/(nsync-nsync0)
- endif
- if(ngood0.le.iters/2 .and. ngood.ge.iters/2) then
- threshold=snr-float(ngood-iters/2)/(ngood-ngood0)
- xsumavg=max(1.0,0.5*(xsum0+xsum))
-! write(*,1020) mode,iters,ntot,naggr,d,navg,nds,threshold,xsumavg
-!1020 format(a5,i7,i7,i3,f7.2,i3,i3,f7.1,f6.1)
- thresh(j,k)=threshold
- endif
- nsync0=nsync
- ngood0=ngood
- xsum0=xsum
- enddo
- enddo
-
-100 write(12,1100)
-1100 format(' ')
- do i=0,9
- write(12,1110) dop(i),thresh(i,1:12)
-1110 format(f6.2,13f6.1)
- enddo
-
- write(12,1110)
- do i=0,9
- write(12,1110) dop(i),threshsync(i,1:12)
- enddo
-
-999 end program fersum
diff --git a/lib/fix_contest_msg.f90 b/lib/fix_contest_msg.f90
deleted file mode 100644
index 8c0345e..0000000
--- a/lib/fix_contest_msg.f90
+++ /dev/null
@@ -1,32 +0,0 @@
-subroutine fix_contest_msg(mygrid,msg)
-
-! If distance from mygrid to grid1 is more thsn 10000 km, change "grid1"
-! to "R grid2" where grid2 is the antipodes of grid1.
-
- character*6 mygrid
- character*22 msg
- character*6 g1,g2
- logical isgrid
-
- isgrid(g1)=g1(1:1).ge.'A' .and. g1(1:1).le.'R' .and. g1(2:2).ge.'A' .and. &
- g1(2:2).le.'R' .and. g1(3:3).ge.'0' .and. g1(3:3).le.'9' .and. &
- g1(4:4).ge.'0' .and. g1(4:4).le.'9' .and. g1(1:4).ne.'RR73'
-
- n=len(trim(msg))
- if(n.lt.4) return
-
- g1=msg(n-3:n)//' '
- if(isgrid(g1)) then
- call azdist(mygrid,g1,0.d0,nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter)
- if(ndkm.gt.10000) then
- call grid2deg(g1,dlong,dlat)
- dlong=dlong+180.0
- if(dlong.gt.180.0) dlong=dlong-360.0
- dlat=-dlat
- call deg2grid(dlong,dlat,g2)
- msg=msg(1:n-4)//'R '//g2(1:4)
- endif
- endif
-
- return
-end subroutine fix_contest_msg
diff --git a/lib/ft8/ft8code.f90 b/lib/ft8/ft8code.f90
index 7a78f40..3100148 100644
--- a/lib/ft8/ft8code.f90
+++ b/lib/ft8/ft8code.f90
@@ -81,7 +81,6 @@ program ft8code
call extractmessage174(decoded,message,ncrcflag)
decoded=decoded0
- if(bcontest) call fix_contest_msg(mygrid6,message)
bad=" "
comment=' '
if(itype.ne.6 .and. message.ne.msgchk) bad="*"
diff --git a/lib/ft8_decode.f90 b/lib/ft8_decode.f90
index a38565c..b3c9166 100644
--- a/lib/ft8_decode.f90
+++ b/lib/ft8_decode.f90
@@ -121,12 +121,6 @@ contains
hd=nharderrors+dmin
call timer('ft8b ',1)
if(nbadcrc.eq.0) then
-! call jtmsg(message,iflag)
- if(bcontest) then
- call fix_contest_msg(mygrid6,message)
- msg37(1:22)=message
- endif
-! if(iand(iflag,31).ne.0) message(22:22)='?'
ldupe=.false.
do id=1,ndecodes
if(message.eq.allmessages(id).and.nsnr.le.allsnrs(id)) ldupe=.true.
@@ -136,11 +130,6 @@ contains
allmessages(ndecodes)=message
allsnrs(ndecodes)=nsnr
endif
-! write(81,1004) nutc,ncand,icand,ipass,iaptype,iappass, &
-! nharderrors,dmin,hd,min(sync,999.0),nint(xsnr), &
-! xdt,nint(f1),message
-!1004 format(i6.6,2i4,3i2,i3,3f6.1,i4,f6.2,i5,2x,a22)
-! flush(81)
if(.not.ldupe .and. associated(this%callback)) then
qual=1.0-(nharderrors+dmin)/60.0 ! scale qual to [0.0,1.0]
call this%callback(sync,nsnr,xdt,f1,msg37,iaptype,qual)
diff --git a/lib/ftrsd/Makefile b/lib/ftrsd/Makefile
deleted file mode 100644
index 61b1357..0000000
--- a/lib/ftrsd/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-# Makefile for Windows in JTSDK-PY environment
-
-# Re-direct stdout and stderr: cmd.exe bash
-# make > junk 2>&1 make &> junk
-
-CC = gcc
-FC = gfortran
-
-FFLAGS = -O2 -DWIN32 -fbounds-check -fno-second-underscore -Wall \
- -Wno-conversion -Wno-character-truncation
-CFLAGS = -I. -DWIN32 -DWin32 -DBIGSYM -DHAVE_STRUCT_TIMESPEC
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: libftrsd.a
-
-OBJS1 = extract2.o ftrsd2.o init_rs_int.o encode_rs_int.o decode_rs_int.o
-libftrsd.a: $(OBJS1)
- ar cr libftrsd.a $(OBJS1)
- ranlib libftrsd.a
- cp libftrsd.a ..
-
-# Build rsdtest
-OBJS2 = rsdtest.o
-rsdtest: $(OBJS2) ../libjt.a
- $(FC) -o rsdtest $(OBJS2) libftrsd.a ../libjt.a ../libpthreadGC2.a
-
-ftrsd: ftrsd.o encode_rs_int.o decode_rs_int.o init_rs_int.o
- gcc -g -o $@ $^
-
-encode_rs_int.o: encode_rs.c
- gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
-
-decode_rs_int.o: decode_rs.c
- gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
-
-init_rs_int.o: init_rs.c
- gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
-
-.PHONY : clean
-
-clean:
- rm -rf *.o libjt.a rsdtest ftrsd
diff --git a/lib/ftrsd/Makefile.sfrsd b/lib/ftrsd/Makefile.sfrsd
deleted file mode 100644
index 3f68f7e..0000000
--- a/lib/ftrsd/Makefile.sfrsd
+++ /dev/null
@@ -1,30 +0,0 @@
-srcdir = .
-prefix = /usr/local
-exec_prefix=${prefix}
-CC=gcc
-
-CFLAGS=-I/usr/local/include -Wall -O2
-
-all: encode_rs_int.o decode_rs_int.o init_rs_int.o sfrsd2.o sfrsd.o sfrsd
-
-encode_rs_int.o: encode_rs.c
- gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
-
-decode_rs_int.o: decode_rs.c
- gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
-
-init_rs_int.o: init_rs.c
- gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
-
-sfrsd2.o: sfrsd2.c
- gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
-
-sfrsd.o: sfrsd.c
- gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^
-
-sfrsd: sfrsd.o encode_rs_int.o decode_rs_int.o init_rs_int.o sfrsd2.o
- gcc -g -o $@ $^
-
-clean:
- rm -f *.o *.a sfrsd
-
diff --git a/lib/ftrsd/Makefile.sfrsd3 b/lib/ftrsd/Makefile.sfrsd3
deleted file mode 100644
index 93023f3..0000000
--- a/lib/ftrsd/Makefile.sfrsd3
+++ /dev/null
@@ -1,38 +0,0 @@
-# Makefile for Windows in JTSDK-PY environment
-
-# Re-direct stdout and stderr: cmd.exe bash
-# make > junk 2>&1 make &> junk
-
-CC = gcc
-FC = gfortran
-
-FFLAGS = -O2 -DWIN32 -fbounds-check -fno-second-underscore -Wall \
- -Wno-conversion -Wno-character-truncation
-CFLAGS = -I. -DWIN32 -DWin32 -DBIGSYM -DHAVE_STRUCT_TIMESPEC
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: rsdtest
-
-# Build rsdtest
-OBJS2 = rsdtest.o extract2.o demod64b.o sfrsd3.o
-rsdtest: $(OBJS2) ../libjt.a
- $(FC) -o rsdtest $(OBJS2) ../libjt.a ../libpthreadGC2.a
-
-sfrsd: sfrsd.o encode_rs_int.o decode_rs_int.o init_rs_int.o
- gcc -g -o $@ $^
-
-.PHONY : clean
-
-clean:
- rm -rf *.o libjt.a rsdtest sfrsd
diff --git a/lib/ftrsd/decode_rs.c b/lib/ftrsd/decode_rs.c
deleted file mode 100644
index 990b687..0000000
--- a/lib/ftrsd/decode_rs.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/* Reed-Solomon decoder
- * Copyright 2002 Phil Karn, KA9Q
- * May be used under the terms of the GNU General Public License (GPL)
- * Modified by Steve Franke, K9AN, for use in a soft-symbol RS decoder
- */
-
-#ifdef DEBUG
-#include
-#endif
-
-#include
-#include
-
-#define min(a,b) ((a) < (b) ? (a) : (b))
-
-#ifdef FIXED
-#include "fixed.h"
-#elif defined(BIGSYM)
-#include "int.h"
-#else
-#include "char.h"
-#endif
-
-int DECODE_RS(
-#ifndef FIXED
- void *p,
-#endif
- DTYPE *data, int *eras_pos, int no_eras, int calc_syn){
-
-#ifndef FIXED
- struct rs *rs = (struct rs *)p;
-#endif
- int deg_lambda, el, deg_omega;
- int i, j, r,k;
- DTYPE u,q,tmp,num1,num2,den,discr_r;
- DTYPE lambda[NROOTS+1]; // Err+Eras Locator poly
- static DTYPE s[51]; // and syndrome poly
- DTYPE b[NROOTS+1], t[NROOTS+1], omega[NROOTS+1];
- DTYPE root[NROOTS], reg[NROOTS+1], loc[NROOTS];
- int syn_error, count;
-
- if( calc_syn ) {
- /* form the syndromes; i.e., evaluate data(x) at roots of g(x) */
- for(i=0;i 0) {
- /* Init lambda to be the erasure locator polynomial */
- lambda[1] = ALPHA_TO[MODNN(PRIM*(NN-1-eras_pos[0]))];
- for (i = 1; i < no_eras; i++) {
- u = MODNN(PRIM*(NN-1-eras_pos[i]));
- for (j = i+1; j > 0; j--) {
- tmp = INDEX_OF[lambda[j - 1]];
- if(tmp != A0)
- lambda[j] ^= ALPHA_TO[MODNN(u + tmp)];
- }
- }
-
-#if DEBUG >= 1
- /* Test code that verifies the erasure locator polynomial just constructed
- Needed only for decoder debugging. */
-
- /* find roots of the erasure location polynomial */
- for(i=1;i<=no_eras;i++)
- reg[i] = INDEX_OF[lambda[i]];
-
- count = 0;
- for (i = 1,k=IPRIM-1; i <= NN; i++,k = MODNN(k+IPRIM)) {
- q = 1;
- for (j = 1; j <= no_eras; j++)
- if (reg[j] != A0) {
- reg[j] = MODNN(reg[j] + j);
- q ^= ALPHA_TO[reg[j]];
- }
- if (q != 0)
- continue;
- /* store root and error location number indices */
- root[count] = i;
- loc[count] = k;
- count++;
- }
- if (count != no_eras) {
- printf("count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras);
- count = -1;
- goto finish;
- }
-#if DEBUG >= 2
- printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
- for (i = 0; i < count; i++)
- printf("%d ", loc[i]);
- printf("\n");
-#endif
-#endif
- }
- for(i=0;i 0; j--){
- if (reg[j] != A0) {
- reg[j] = MODNN(reg[j] + j);
- q ^= ALPHA_TO[reg[j]];
- }
- }
- if (q != 0)
- continue; /* Not a root */
- /* store root (index-form) and error location number */
-#if DEBUG>=2
- printf("count %d root %d loc %d\n",count,i,k);
-#endif
- root[count] = i;
- loc[count] = k;
- /* If we've already found max possible roots,
- * abort the search to save time
- */
- if(++count == deg_lambda)
- break;
- }
- if (deg_lambda != count) {
- /*
- * deg(lambda) unequal to number of roots => uncorrectable
- * error detected
- */
- count = -1;
- goto finish;
- }
- /*
- * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
- * x**NROOTS). in index form. Also find deg(omega).
- */
- deg_omega = 0;
- for (i = 0; i < NROOTS;i++){
- tmp = 0;
- j = (deg_lambda < i) ? deg_lambda : i;
- for(;j >= 0; j--){
- if ((s[i - j] != A0) && (lambda[j] != A0))
- tmp ^= ALPHA_TO[MODNN(s[i - j] + lambda[j])];
- }
- if(tmp != 0)
- deg_omega = i;
- omega[i] = INDEX_OF[tmp];
- }
- omega[NROOTS] = A0;
-
- /*
- * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
- * inv(X(l))**(FCR-1) and den = lambda_pr(inv(X(l))) all in poly-form
- */
- for (j = count-1; j >=0; j--) {
- num1 = 0;
- for (i = deg_omega; i >= 0; i--) {
- if (omega[i] != A0)
- num1 ^= ALPHA_TO[MODNN(omega[i] + i * root[j])];
- }
- num2 = ALPHA_TO[MODNN(root[j] * (FCR - 1) + NN)];
- den = 0;
-
- /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
- for (i = min(deg_lambda,NROOTS-1) & ~1; i >= 0; i -=2) {
- if(lambda[i+1] != A0)
- den ^= ALPHA_TO[MODNN(lambda[i+1] + i * root[j])];
- }
- if (den == 0) {
-#if DEBUG >= 1
- printf("\n ERROR: denominator = 0\n");
-#endif
- count = -1;
- goto finish;
- }
- /* Apply error to data */
- if (num1 != 0) {
- data[loc[j]] ^= ALPHA_TO[MODNN(INDEX_OF[num1] + INDEX_OF[num2] + NN - INDEX_OF[den])];
- }
- }
-finish:
- if(eras_pos != NULL){
- for(i=0;i
-
-#ifdef FIXED
-#include "fixed.h"
-#elif defined(BIGSYM)
-#include "int.h"
-#else
-#include "char.h"
-#endif
-
-void ENCODE_RS(
-#ifndef FIXED
-void *p,
-#endif
-DTYPE *data, DTYPE *bb){
-#ifndef FIXED
- struct rs *rs = (struct rs *)p;
-#endif
- int i, j;
- DTYPE feedback;
-
- memset(bb,0,NROOTS*sizeof(DTYPE));
-
- for(i=0;i
-#include
-#include
-#include
-#include
-#include "rs2.h"
-
-static void *rs;
-void getpp_(int workdat[], float *pp);
-
-void ftrsd2_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
- int* ntrials0, int correct[], int param[], int ntry[])
-{
- int rxdat[63], rxprob[63], rxdat2[63], rxprob2[63];
- int workdat[63];
- int indexes[63];
- int era_pos[51];
- int i, j, numera, nerr, nn=63;
- int ntrials = *ntrials0;
- int nhard=0,nhard_min=32768,nsoft=0,nsoft_min=32768;
- int ntotal=0,ntotal_min=32768,ncandidates;
- int nera_best=0;
- float pp,pp1,pp2;
- static unsigned int nseed;
-
-// Power-percentage symbol metrics - composite gnnf/hf
- int perr[8][8] = {
- { 4, 9, 11, 13, 14, 14, 15, 15},
- { 2, 20, 20, 30, 40, 50, 50, 50},
- { 7, 24, 27, 40, 50, 50, 50, 50},
- {13, 25, 35, 46, 52, 70, 50, 50},
- {17, 30, 42, 54, 55, 64, 71, 70},
- {25, 39, 48, 57, 64, 66, 77, 77},
- {32, 45, 54, 63, 66, 75, 78, 83},
- {51, 58, 57, 66, 72, 77, 82, 86}};
-
-
-// Initialize the KA9Q Reed-Solomon encoder/decoder
- unsigned int symsize=6, gfpoly=0x43, fcr=3, prim=1, nroots=51;
- rs=init_rs_int(symsize, gfpoly, fcr, prim, nroots, 0);
-
-// Reverse the received symbol vectors for BM decoder
- for (i=0; i<63; i++) {
- rxdat[i]=mrsym[62-i];
- rxprob[i]=mrprob[62-i];
- rxdat2[i]=mr2sym[62-i];
- rxprob2[i]=mr2prob[62-i];
- }
-
-// Sort rxprob to find indexes of the least reliable symbols
- int k, pass, tmp, nsym=63;
- int probs[63];
- for (i=0; i<63; i++) {
- indexes[i]=i;
- probs[i]=rxprob[i];
- }
- for (pass = 1; pass <= nsym-1; pass++) {
- for (k = 0; k < nsym - pass; k++) {
- if( probs[k] < probs[k+1] ) {
- tmp = probs[k];
- probs[k] = probs[k+1];
- probs[k+1] = tmp;
- tmp = indexes[k];
- indexes[k] = indexes[k+1];
- indexes[k+1] = tmp;
- }
- }
- }
-
-// See if we can decode using BM HDD, and calculate the syndrome vector.
- memset(era_pos,0,51*sizeof(int));
- numera=0;
- memcpy(workdat,rxdat,sizeof(rxdat));
- nerr=decode_rs_int(rs,workdat,era_pos,numera,1);
- if( nerr >= 0 ) {
- // Hard-decision decoding succeeded. Save codeword and some parameters.
- nhard=0;
- for (i=0; i<63; i++) {
- if( workdat[i] != rxdat[i] ) nhard=nhard+1;
- }
- memcpy(correct,workdat,63*sizeof(int));
- param[0]=0;
- param[1]=nhard;
- param[2]=0;
- param[3]=0;
- param[4]=0;
- param[5]=0;
- param[7]=1000*1000;
- ntry[0]=0;
- return;
- }
-
-/*
-Hard-decision decoding failed. Try the FT soft-decision method.
-Generate random erasure-locator vectors and see if any of them
-decode. This will generate a list of "candidate" codewords. The
-soft distance between each candidate codeword and the received
-word is estimated by finding the largest (pp1) and second-largest
-(pp2) outputs from a synchronized filter-bank operating on the
-symbol spectra, and using these to decide which candidate
-codeword is "best".
-*/
-
- nseed=1; //Seed for random numbers
- float ratio;
- int thresh, nsum;
- int thresh0[63];
- ncandidates=0;
- nsum=0;
- int ii,jj;
- for (i=0; i= 0 ) {
- // We have a candidate codeword. Find its hard and soft distance from
- // the received word. Also find pp1 and pp2 from the full array
- // s3(64,63) of synchronized symbol spectra.
- ncandidates=ncandidates+1;
- nhard=0;
- nsoft=0;
- for (i=0; i<63; i++) {
- if(workdat[i] != rxdat[i]) {
- nhard=nhard+1;
- if(workdat[i] != rxdat2[i]) {
- nsoft=nsoft+rxprob[i];
- }
- }
- }
- nsoft=63*nsoft/nsum;
- ntotal=nsoft+nhard;
-
- getpp_(workdat,&pp);
- if(pp>pp1) {
- pp2=pp1;
- pp1=pp;
- nsoft_min=nsoft;
- nhard_min=nhard;
- ntotal_min=ntotal;
- memcpy(correct,workdat,63*sizeof(int));
- nera_best=numera;
- ntry[0]=k;
- } else {
- if(pp>pp2 && pp!=pp1) pp2=pp;
- }
- if(nhard_min <= 41 && ntotal_min <= 71) break;
- }
- if(k == ntrials) ntry[0]=k;
- }
-
- param[0]=ncandidates;
- param[1]=nhard_min;
- param[2]=nsoft_min;
- param[3]=nera_best;
- param[4]=1000.0*pp2/pp1;
- param[5]=ntotal_min;
- param[6]=ntry[0];
- param[7]=1000.0*pp2;
- param[8]=1000.0*pp1;
- if(param[0]==0) param[2]=-1;
- return;
-}
diff --git a/lib/ftrsd/ftrsd_paper/JT65B_EME.png b/lib/ftrsd/ftrsd_paper/JT65B_EME.png
deleted file mode 100644
index d5c86fb..0000000
Binary files a/lib/ftrsd/ftrsd_paper/JT65B_EME.png and /dev/null differ
diff --git a/lib/ftrsd/ftrsd_paper/Makefile b/lib/ftrsd/ftrsd_paper/Makefile
deleted file mode 100644
index a594397..0000000
--- a/lib/ftrsd/ftrsd_paper/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-CC = gcc
-FC = gfortran
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: mfsk probs.out
-
-OBJS1 = prob.o binomial_subs.o
-prob: $(OBJS1)
- $(FC) -o prob $(OBJS1)
-
-OBJS2 = mfsk.o binomial_subs.o
-mfsk: $(OBJS2)
- $(FC) -o mfsk $(OBJS2)
-
-OBJS3 = bodide.o binomial_subs.o
-bodide: $(OBJS3)
- $(FC) -o bodide $(OBJS3)
-
-
-probs.out: prob
-# x N X s
- prob 35 63 40 40 > probs.out
- prob 37 63 40 45 >> probs.out
- prob 37 53 40 45 >> probs.out
- prob 38 53 40 47 >> probs.out
-
-clean:
- rm -rf *.o prob probs.out
-
diff --git a/lib/ftrsd/ftrsd_paper/binomial.c b/lib/ftrsd/ftrsd_paper/binomial.c
deleted file mode 100644
index fcbdafd..0000000
--- a/lib/ftrsd/ftrsd_paper/binomial.c
+++ /dev/null
@@ -1,69 +0,0 @@
-#include
-#include
-
-/* Original code copied from
- http://rosettacode.org/wiki/Evaluate_binomial_coefficients
-*/
-
-/* We go to some effort to handle overflow situations */
-
-static unsigned long gcd_ui(unsigned long x, unsigned long y) {
- unsigned long t;
- if (y < x) { t = x; x = y; y = t; }
- while (y > 0) {
- t = y; y = x % y; x = t; /* y1 <- x0 % y0 ; x1 <- y0 */
- }
- return x;
-}
-
-unsigned long binomial(unsigned long n, unsigned long k) {
- unsigned long d, g, r = 1;
- if (k == 0) return 1;
- if (k == 1) return n;
- if (k >= n) return (k == n);
- if (k > n/2) k = n-k;
- for (d = 1; d <= k; d++) {
- if (r >= ULONG_MAX/n) { /* Possible overflow */
- unsigned long nr, dr; /* reduced numerator / denominator */
- g = gcd_ui(n, d); nr = n/g; dr = d/g;
- g = gcd_ui(r, dr); r = r/g; dr = dr/g;
- if (r >= ULONG_MAX/nr) return 0; /* Unavoidable overflow */
- r *= nr;
- r /= dr;
- n--;
- } else {
- r *= n--;
- r /= d;
- }
- }
- return r;
-}
-
-int main() {
-
- //Get test results
- printf("%lu\n", binomial(5, 3)); // 10
- printf("%lu\n", binomial(40, 19)); // 131282408400
- printf("%lu\n", binomial(67, 31)); // 11923179284862717872
-
- // Compute special cases for paper on TF soft-decision RS decoder:
- double a,b,c,p;
- a=(double)binomial(40, 35);
- b=(double)binomial(23, 5);
- c=(double)binomial(63, 40);
- p=a*b/c;
- printf("%e %e %e %e\n",a,b,c,p);
-
- a=(double)binomial(40, 36);
- b=(double)binomial(23, 4);
- c=(double)binomial(63, 40);
- p=a*b/c;
- printf("%e %e %e %e\n",a,b,c,p);
-
- a=(double)binomial(40, 37);
- b=(double)binomial(23, 8);
- c=(double)binomial(63, 45);
- p=a*b/c;
- printf("%e %e %e %e\n",a,b,c,p);
- return 0;
-}
diff --git a/lib/ftrsd/ftrsd_paper/binomial_subs.c b/lib/ftrsd/ftrsd_paper/binomial_subs.c
deleted file mode 100644
index be4a0ae..0000000
--- a/lib/ftrsd/ftrsd_paper/binomial_subs.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include
-#include
-
-/* Original code copied from
- http://rosettacode.org/wiki/Evaluate_binomial_coefficients
-*/
-
-/* We go to some effort to handle overflow situations */
-
-static unsigned long long gcd_ui(unsigned long long x, unsigned long long y) {
- unsigned long long t;
- if (y < x) { t = x; x = y; y = t; }
- while (y > 0) {
- t = y; y = x % y; x = t; /* y1 <- x0 % y0 ; x1 <- y0 */
- }
- return x;
-}
-
-unsigned long long binomial(unsigned long long n, unsigned long long k) {
- unsigned long long d, g, r = 1;
- if (k == 0) return 1;
- if (k == 1) return n;
- if (k >= n) return (k == n);
- if (k > n/2) k = n-k;
- for (d = 1; d <= k; d++) {
- if (r >= ULLONG_MAX/n) { /* Possible overflow */
- unsigned long long nr, dr; /* reduced numerator / denominator */
- g = gcd_ui(n, d); nr = n/g; dr = d/g;
- g = gcd_ui(r, dr); r = r/g; dr = dr/g;
- if (r >= ULLONG_MAX/nr) return 0; /* Unavoidable overflow */
- r *= nr;
- r /= dr;
- n--;
- } else {
- r *= n--;
- r /= d;
- }
- }
- return r;
-}
-
-unsigned long long binomial_(int *n, int *k)
-{
- // printf("n=%d k=%d %lu\n",*n,*k,binomial(*n,*k));
- return binomial(*n,*k);
-}
-
-double hypergeo_(int *x, int *NN, int *XX, int *s)
-{
- double a,b,c;
- a=(double)binomial(*XX, *x);
- b=(double)binomial(*NN-*XX, *s-*x);
- c=(double)binomial(*NN, *s);
- return a*b/c;
-}
diff --git a/lib/ftrsd/ftrsd_paper/bmdata-rf.dat b/lib/ftrsd/ftrsd_paper/bmdata-rf.dat
deleted file mode 100644
index 17d5331..0000000
--- a/lib/ftrsd/ftrsd_paper/bmdata-rf.dat
+++ /dev/null
@@ -1,11 +0,0 @@
-fspread0 0.2, BM (ntrials=0)
--22.0 0.09
--21.5 0.20
--21.0 0.36
--20.5 0.55
--20.0 0.69
--19.5 0.83
--19.0 0.91
--18.5 0.960
--18.0 0.978
--17.5 0.987
diff --git a/lib/ftrsd/ftrsd_paper/bmdata.dat b/lib/ftrsd/ftrsd_paper/bmdata.dat
deleted file mode 100644
index 987bbbb..0000000
--- a/lib/ftrsd/ftrsd_paper/bmdata.dat
+++ /dev/null
@@ -1,8 +0,0 @@
--24.5 0.000
--24.0 0.006
--23.5 0.046 0.066
--23.0 0.250 0.305
--22.5 0.630 0.701
--22.0 0.900 0.945
--21.5 0.992 0.9974
--21.0 0.99987
diff --git a/lib/ftrsd/ftrsd_paper/bmtheory25.dat b/lib/ftrsd/ftrsd_paper/bmtheory25.dat
deleted file mode 100644
index de85456..0000000
--- a/lib/ftrsd/ftrsd_paper/bmtheory25.dat
+++ /dev/null
@@ -1,43 +0,0 @@
-Es/No P(word error)
-----------------------
- 0.0 0.9008E+00 0.1000E+01
- 0.5 0.8877E+00 0.1000E+01
- 1.0 0.8724E+00 0.1000E+01
- 1.5 0.8545E+00 0.1000E+01
- 2.0 0.8338E+00 0.1000E+01
- 2.5 0.8096E+00 0.1000E+01
- 3.0 0.7817E+00 0.1000E+01
- 3.5 0.7496E+00 0.1000E+01
- 4.0 0.7128E+00 0.1000E+01
- 4.5 0.6712E+00 0.1000E+01
- 5.0 0.6246E+00 0.9998E+00
- 5.5 0.5731E+00 0.9964E+00
- 6.0 0.5170E+00 0.9629E+00
- 6.5 0.4572E+00 0.7979E+00
- 7.0 0.3949E+00 0.4327E+00
- 7.5 0.3316E+00 0.1100E+00
- 8.0 0.2696E+00 0.9707E-02
- 8.5 0.2109E+00 0.2303E-03
- 9.0 0.1578E+00 0.1170E-05
- 9.5 0.1121E+00 0.1027E-08
-10.0 0.7499E-01 0.1263E-12
-10.5 0.4684E-01 0.1768E-17
-11.0 0.2703E-01 0.2282E-23
-11.5 0.1426E-01 0.2200E-30
-12.0 0.6789E-02 -.1348E-32
-12.5 0.2879E-02 -.1733E-32
-13.0 0.1072E-02 -.2119E-32
-13.5 0.3448E-03 0.3081E-32
-14.0 0.9421E-04 0.3852E-33
-14.5 0.2148E-04 -.1156E-32
-15.0 0.4006E-05 -.1733E-32
-15.5 0.5984E-06 0.2215E-32
-16.0 0.6994E-07 -.4430E-32
-16.5 0.6230E-08 -.3081E-32
-17.0 0.4105E-09 -.2889E-32
-17.5 0.1934E-10 -.1926E-33
-18.0 0.6266E-12 0.3852E-32
-18.5 0.1335E-13 -.1926E-33
-19.0 0.1777E-15 0.2119E-32
-19.5 0.1396E-17 0.1733E-32
-20.0 0.6076E-20 -.3852E-33
diff --git a/lib/ftrsd/ftrsd_paper/bmtheory40.dat b/lib/ftrsd/ftrsd_paper/bmtheory40.dat
deleted file mode 100644
index 4903ef5..0000000
--- a/lib/ftrsd/ftrsd_paper/bmtheory40.dat
+++ /dev/null
@@ -1,43 +0,0 @@
-Es/No P(word error)
-----------------------
- 0.0 0.9008E+00 0.1000E+01
- 0.5 0.8877E+00 0.1000E+01
- 1.0 0.8724E+00 0.1000E+01
- 1.5 0.8545E+00 0.1000E+01
- 2.0 0.8338E+00 0.9999E+00
- 2.5 0.8096E+00 0.9991E+00
- 3.0 0.7817E+00 0.9944E+00
- 3.5 0.7496E+00 0.9713E+00
- 4.0 0.7128E+00 0.8887E+00
- 4.5 0.6712E+00 0.6883E+00
- 5.0 0.6246E+00 0.3865E+00
- 5.5 0.5731E+00 0.1310E+00
- 6.0 0.5170E+00 0.2215E-01
- 6.5 0.4572E+00 0.1536E-02
- 7.0 0.3949E+00 0.3562E-04
- 7.5 0.3316E+00 0.2223E-06
- 8.0 0.2696E+00 0.2951E-09
- 8.5 0.2109E+00 0.6449E-13
- 9.0 0.1578E+00 0.1758E-17
- 9.5 0.1121E+00 0.4426E-23
-10.0 0.7499E-01 0.7428E-30
-10.5 0.4684E-01 -.1733E-32
-11.0 0.2703E-01 0.1348E-32
-11.5 0.1426E-01 0.2985E-32
-12.0 0.6789E-02 -.1348E-32
-12.5 0.2879E-02 -.1733E-32
-13.0 0.1072E-02 -.2119E-32
-13.5 0.3448E-03 0.3081E-32
-14.0 0.9421E-04 0.3852E-33
-14.5 0.2148E-04 -.1156E-32
-15.0 0.4006E-05 -.1733E-32
-15.5 0.5984E-06 0.2215E-32
-16.0 0.6994E-07 -.4430E-32
-16.5 0.6230E-08 -.3081E-32
-17.0 0.4105E-09 -.2889E-32
-17.5 0.1934E-10 -.1926E-33
-18.0 0.6266E-12 0.3852E-32
-18.5 0.1335E-13 -.1926E-33
-19.0 0.1777E-15 0.2119E-32
-19.5 0.1396E-17 0.1733E-32
-20.0 0.6076E-20 -.3852E-33
diff --git a/lib/ftrsd/ftrsd_paper/bmtheory43.dat b/lib/ftrsd/ftrsd_paper/bmtheory43.dat
deleted file mode 100644
index b22ab8d..0000000
--- a/lib/ftrsd/ftrsd_paper/bmtheory43.dat
+++ /dev/null
@@ -1,43 +0,0 @@
-Es/No P(word error)
-----------------------
- 0.0 0.9008E+00 0.1000E+01
- 0.5 0.8877E+00 0.1000E+01
- 1.0 0.8724E+00 0.9999E+00
- 1.5 0.8545E+00 0.9996E+00
- 2.0 0.8338E+00 0.9977E+00
- 2.5 0.8096E+00 0.9889E+00
- 3.0 0.7817E+00 0.9559E+00
- 3.5 0.7496E+00 0.8599E+00
- 4.0 0.7128E+00 0.6586E+00
- 4.5 0.6712E+00 0.3780E+00
- 5.0 0.6246E+00 0.1397E+00
- 5.5 0.5731E+00 0.2826E-01
- 6.0 0.5170E+00 0.2632E-02
- 6.5 0.4572E+00 0.9396E-04
- 7.0 0.3949E+00 0.1052E-05
- 7.5 0.3316E+00 0.2965E-08
- 8.0 0.2696E+00 0.1650E-11
- 8.5 0.2109E+00 0.1388E-15
- 9.0 0.1578E+00 0.1316E-20
- 9.5 0.1121E+00 0.1021E-26
-10.0 0.7499E-01 -.9630E-33
-10.5 0.4684E-01 -.1733E-32
-11.0 0.2703E-01 0.1348E-32
-11.5 0.1426E-01 0.2985E-32
-12.0 0.6789E-02 -.1348E-32
-12.5 0.2879E-02 -.1733E-32
-13.0 0.1072E-02 -.2119E-32
-13.5 0.3448E-03 0.3081E-32
-14.0 0.9421E-04 0.3852E-33
-14.5 0.2148E-04 -.1156E-32
-15.0 0.4006E-05 -.1733E-32
-15.5 0.5984E-06 0.2215E-32
-16.0 0.6994E-07 -.4430E-32
-16.5 0.6230E-08 -.3081E-32
-17.0 0.4105E-09 -.2889E-32
-17.5 0.1934E-10 -.1926E-33
-18.0 0.6266E-12 0.3852E-32
-18.5 0.1335E-13 -.1926E-33
-19.0 0.1777E-15 0.2119E-32
-19.5 0.1396E-17 0.1733E-32
-20.0 0.6076E-20 -.3852E-33
diff --git a/lib/ftrsd/ftrsd_paper/bodide.f90 b/lib/ftrsd/ftrsd_paper/bodide.f90
deleted file mode 100644
index 72e0f13..0000000
--- a/lib/ftrsd/ftrsd_paper/bodide.f90
+++ /dev/null
@@ -1,54 +0,0 @@
-program bodide
-! Compute probability of word error for a bounded distance decoder.
-! Hardwired for non-coherent 64-FSK and the JT65 RS (63,12) code on GF(64).
-!
-! Let ps be symbol error probability.
-! The probability of getting an error pattern with e symbol errors is:
-! ps^e * (1-ps)*(n-e)
-! The number of error patterns with e errors is binomial(63,e)
-! Overall probability of getting a word with e errors is:
-! P(e)= binomial(63,e)* ps^e * (1-ps)*(n-e)
-! Probability that word is correct is P(0 to 25 errors) = sum{e=0}^{25} P(e)
-! Probability that word is wrong is 1-P(0 to 25 errors)
-! P_word_error=1-( sum_{e=0}^{t} P(e) )
-!
- implicit real*16 (a-h,o-z)
-
- integer*8 binomial
- integer x,s,XX,NN,M
- character arg*8
-
- nargs=iargc()
- if(nargs.ne.1) then
- print*,'Probability of word error for noncoherent 64-FSK with bounded distance decoding'
- print*,'Usage: bounded_distance D'
- print*,'Example: bounded_distance 25'
- go to 999
- endif
- call getarg(1,arg)
- read(arg,*) nt
- M=64
- write(*,1012)
-1012 format('Es/No P(word error)'/ &
- '----------------------')
- do isnr=0,40
- esno=10**(isnr/2.0/10.0)
- hsum=0.d0
- do k=1,M-1
- h=binomial(M-1,k)
- h=h*((-1)**(k+1))/(k+1)
- h=h*exp(-esno*k/(k+1))
- hsum=hsum + h
- enddo
- ps=hsum
- hsum=0.d0
- do i=0,nt
- h=binomial(63,i)
- h=h*ps**i
- h=h*(1-ps)**(63-i)
- hsum=hsum+h
- enddo
- pw=1-hsum
- write(*,'(f4.1,4x,e10.4,4x,e10.4)') isnr/2.0, ps, pw
- enddo
-999 end program bodide
diff --git a/lib/ftrsd/ftrsd_paper/bodide.lab b/lib/ftrsd/ftrsd_paper/bodide.lab
deleted file mode 100644
index 6fa108e..0000000
--- a/lib/ftrsd/ftrsd_paper/bodide.lab
+++ /dev/null
@@ -1,4 +0,0 @@
-7.5 0.05 BM
-6.9 0.015 Theory
-5.55 0.05 KV
-5.3 0.005 FT
diff --git a/lib/ftrsd/ftrsd_paper/fig_bodide.gnuplot b/lib/ftrsd/ftrsd_paper/fig_bodide.gnuplot
deleted file mode 100644
index b8bb0ad..0000000
--- a/lib/ftrsd/ftrsd_paper/fig_bodide.gnuplot
+++ /dev/null
@@ -1,24 +0,0 @@
-# gnuplot script for comparison to theoretical word error rate for
-# bounded distance decoding
-
-# run: gnuplot fig_bodide.gnuplot
-# then: pdflatex fig_bodide.tex
-
-set term epslatex standalone size 6in,2*6/3in
-set output "fig_bodide.tex"
-set xlabel "$E_b/N_0$ (dB)"
-set ylabel "Word Error Rate"
-set style func linespoints
-set key off
-set tics in
-set mxtics 2
-set mytics 10
-set grid
-set logscale y
-plot [3:9] [1e-4:1] \
- "bmdata.dat" using ($1+29.1):(1-$2) with linespoints lt 2 lw 2 pt 2, \
- "ftdata-100000.dat" using ($1+29.1):(1-$3) with linespoints lt 1 lw 2 pt 7, \
- "bmtheory25.dat" using ($1-0.6):3 with linespoints lt 1 pt 5, \
- "kvasd-15.dat" using ($1+29.1):(1-$3) with linespoints lt 4 pt 6, \
- "bodide.lab" with labels
-
diff --git a/lib/ftrsd/ftrsd_paper/fig_ntrials_vs_nhard.gnuplot b/lib/ftrsd/ftrsd_paper/fig_ntrials_vs_nhard.gnuplot
deleted file mode 100644
index 9a6c9b0..0000000
--- a/lib/ftrsd/ftrsd_paper/fig_ntrials_vs_nhard.gnuplot
+++ /dev/null
@@ -1,14 +0,0 @@
-# gnuplot script for "ntrials_vs_nhard" figure
-# run: gnuplot fig_ntrials_vs_nhard.gnuplot
-# then: pdflatex fig_ntrials_vs_nhard.tex
-#
-set term epslatex standalone size 6in,2*6/3in
-set output "fig_ntrials_vs_nhard.tex"
-set xlabel "Errors in received word, $X$"
-set ylabel "Number of trials"
-set tics in
-set mxtics 5
-set mytics 10
-#set grid
-set logscale y
-plot "stats-100000-24db-3.dat" using 1:4 pt 12 notitle
diff --git a/lib/ftrsd/ftrsd_paper/fig_psuccess.gnuplot b/lib/ftrsd/ftrsd_paper/fig_psuccess.gnuplot
deleted file mode 100644
index 3718e29..0000000
--- a/lib/ftrsd/ftrsd_paper/fig_psuccess.gnuplot
+++ /dev/null
@@ -1,25 +0,0 @@
-# gnuplot script for "Percent copy" figure
-# run: gnuplot fig_psuccess.gnuplot
-# then: pdflatex fig_psuccess.tex
-#
-set term epslatex standalone size 6in,4in
-set output "fig_psuccess.tex"
-set xlabel "SNR in 2500 Hz Bandwidth (dB)"
-set ylabel "Percent copy"
-set style func linespoints
-set key off
-set tics in
-set mxtics 2
-set mytics 2
-set grid
-plot [-30:-18] [0:105] \
- "stats_0.0" using 1:($4)/10.0 with linespoints lt 2 lw 2 pt 2, \
- "stats_0.0" using 1:($5)/10.0 with linespoints lt 1 lw 2 pt 3, \
- "stats_0.0" using 1:($6)/10.0 with linespoints lt 3 lw 2 pt 4, \
- "stats_0.2" using 1:($4)/10.0 with linespoints lt 2 pt 2, \
- "stats_0.2" using 1:($5)/10.0 with linespoints lt 1 pt 3, \
- "stats_0.2" using 1:($6)/10.0 with linespoints lt 3 pt 4, \
- "stats_1.0" using 1:($4)/10.0 with linespoints lt 2 pt 2, \
- "stats_1.0" using 1:($5)/10.0 with linespoints lt 1 pt 3, \
- "stats_1.0" using 1:($6)/10.0 with linespoints lt 3 pt 4, \
- "psuccess.lab" with labels
diff --git a/lib/ftrsd/ftrsd_paper/fig_psuccess.pdf b/lib/ftrsd/ftrsd_paper/fig_psuccess.pdf
deleted file mode 100644
index 7464629..0000000
Binary files a/lib/ftrsd/ftrsd_paper/fig_psuccess.pdf and /dev/null differ
diff --git a/lib/ftrsd/ftrsd_paper/fig_subtracted.tiff b/lib/ftrsd/ftrsd_paper/fig_subtracted.tiff
deleted file mode 100644
index b6f0f2f..0000000
Binary files a/lib/ftrsd/ftrsd_paper/fig_subtracted.tiff and /dev/null differ
diff --git a/lib/ftrsd/ftrsd_paper/fig_waterfall.png b/lib/ftrsd/ftrsd_paper/fig_waterfall.png
deleted file mode 100644
index b2a8dd9..0000000
Binary files a/lib/ftrsd/ftrsd_paper/fig_waterfall.png and /dev/null differ
diff --git a/lib/ftrsd/ftrsd_paper/fig_waterfall.tiff b/lib/ftrsd/ftrsd_paper/fig_waterfall.tiff
deleted file mode 100644
index ae2cbdd..0000000
Binary files a/lib/ftrsd/ftrsd_paper/fig_waterfall.tiff and /dev/null differ
diff --git a/lib/ftrsd/ftrsd_paper/fig_wer.gnuplot b/lib/ftrsd/ftrsd_paper/fig_wer.gnuplot
deleted file mode 100644
index bff0533..0000000
--- a/lib/ftrsd/ftrsd_paper/fig_wer.gnuplot
+++ /dev/null
@@ -1,23 +0,0 @@
-# gnuplot script for "Percent copy" figure
-# run: gnuplot fig_wer.gnuplot
-# then: pdflatex fig_wer.tex
-#
-set term epslatex standalone size 6in,4in
-set output "fig_wer.tex"
-set xlabel "$E_b/N_0$ (dB)"
-set ylabel "Word Error Rate"
-set style func linespoints
-set key off
-set tics in
-set mxtics 2
-set mytics 10
-set grid
-set logscale y
-plot [3:7] "ftdata-100000.dat" using ($1+29.1):(1-$2) with linespoints lt 1 pt 7 title 'FT-100K', \
- "ftdata-10000.dat" using ($1+29.1):(1-$2) with linespoints lt 1 pt 7 title 'FT-10K', \
- "ftdata-1000.dat" using ($1+29.1):(1-$2) with linespoints lt 1 pt 7 title 'FT-1K', \
- "kvasd-8.dat" using ($1+29.1):(1-$2) with linespoints lt 2 pt 8 title 'KV-8', \
- "kvasd-12.dat" using ($1+29.1):(1-$2) with linespoints lt 2 pt 8 title 'KV-12', \
- "kvasd-15.dat" using ($1+29.1):(1-$2) with linespoints lt 2 pt 8 title 'KV-15', \
- "bmdata.dat" using ($1+29.1):(1-$2) with linespoints pt 7 title 'BM', \
- "wer.lab" with labels
diff --git a/lib/ftrsd/ftrsd_paper/fig_wer.pdf b/lib/ftrsd/ftrsd_paper/fig_wer.pdf
deleted file mode 100644
index 6533f00..0000000
Binary files a/lib/ftrsd/ftrsd_paper/fig_wer.pdf and /dev/null differ
diff --git a/lib/ftrsd/ftrsd_paper/fig_wer2.gnuplot b/lib/ftrsd/ftrsd_paper/fig_wer2.gnuplot
deleted file mode 100644
index dc8edc9..0000000
--- a/lib/ftrsd/ftrsd_paper/fig_wer2.gnuplot
+++ /dev/null
@@ -1,23 +0,0 @@
-# gnuplot script for "Percent copy" figure
-# run: gnuplot fig_wer2.gnuplot
-# then: pdflatex fig_wer2.tex
-#
-set term epslatex standalone size 6in,6*2/3in
-set output "fig_wer2.tex"
-set xlabel "SNR in 2500 Hz Bandwidth (dB)"
-set ylabel "Percent Copy"
-set style func linespoints
-set key off
-set tics in
-set mxtics 2
-set mytics 5
-set grid
-plot [-27:-22] [0:110] \
- "ftdata-100000.dat" using 1:(100*$3) with linespoints lt 1 lw 2 pt 7, \
- "ftdata-10000.dat" using 1:(100*$3) with linespoints lt 1 lw 2 pt 7, \
- "ftdata-1000.dat" using 1:(100*$3) with linespoints lt 1 lw 2 pt 7, \
- "ftdata-100.dat" using 1:(100*$3) with linespoints lt 1 lw 2 pt 7, \
- "ftdata-10.dat" using 1:(100*$2) with linespoints lt 1 lw 2 pt 7, \
- "kvasd-15.dat" using 1:(100*$2) with linespoints lt 4 pt 6, \
- "bmdata.dat" using 1:(100*$2) with linespoints lt 2 lw 2 pt 2, \
- "wer2.lab" with labels
diff --git a/lib/ftrsd/ftrsd_paper/fig_wer3.gnuplot b/lib/ftrsd/ftrsd_paper/fig_wer3.gnuplot
deleted file mode 100644
index f3c9d27..0000000
--- a/lib/ftrsd/ftrsd_paper/fig_wer3.gnuplot
+++ /dev/null
@@ -1,21 +0,0 @@
-# gnuplot script for "Percent copy" figure
-# run: gnuplot fig_wer3.gnuplot
-# then: pdflatex fig_wer3.tex
-#
-set term epslatex standalone size 6in,6*2/3in
-set output "fig_wer3.tex"
-set xlabel "SNR in 2500 Hz Bandwidth (dB)"
-set ylabel "Percent Copy"
-set style func linespoints
-set key off
-set tics in
-set mxtics 2
-set mytics 10
-set grid
-set label "r6315" at -25.25,30
-set label "r6330" at -26.0,30
-set label "$T=10^5$" at -22.8,15
-set label "$d=0.0$" at -22.8,10
-plot [-27:-22] [0:110] \
- "ftdata-100000.dat" using 1:(100*$3) with linespoints lt 1 pt 7 title 'FT-100K', \
- "ftdata-100000.dat" using 1:(100*$2) with linespoints lt 1 pt 7 title 'FT-100K'
diff --git a/lib/ftrsd/ftrsd_paper/ftdata-10.dat b/lib/ftrsd/ftrsd_paper/ftdata-10.dat
deleted file mode 100644
index 467be38..0000000
--- a/lib/ftrsd/ftrsd_paper/ftdata-10.dat
+++ /dev/null
@@ -1,10 +0,0 @@
- snr psuccess ntrials 10, r6321, r6333
--26.0 0.0
--25.5 0.007
--25.0 0.039
--24.5 0.157 0.14
--24.0 0.362
--23.5 0.701 0.681
--23.0 0.914
--22.5 0.985 0.988
--22.0 1.0 1.0
diff --git a/lib/ftrsd/ftrsd_paper/ftdata-100.dat b/lib/ftrsd/ftrsd_paper/ftdata-100.dat
deleted file mode 100644
index a5d547c..0000000
--- a/lib/ftrsd/ftrsd_paper/ftdata-100.dat
+++ /dev/null
@@ -1,10 +0,0 @@
- snr psuccess ntrials 100, r6321, r6333
--26.0 0.003 0.003
--25.5 0.033 0.037
--25.0 0.113 0.113
--24.5 0.315 0.330
--24.0 0.635 0.670
--23.5 0.908 0.903
--23.0 0.977 0.984
--22.5 0.9986 0.999
--22.0 1.0 1.0
diff --git a/lib/ftrsd/ftrsd_paper/ftdata-1000.dat b/lib/ftrsd/ftrsd_paper/ftdata-1000.dat
deleted file mode 100644
index 156a0b3..0000000
--- a/lib/ftrsd/ftrsd_paper/ftdata-1000.dat
+++ /dev/null
@@ -1,9 +0,0 @@
- snr psuccess ntrials 1000, r6315, r6333
--26.0 0.010 0.022
--25.5 0.052 0.097
--25.0 0.22 0.262
--24.5 0.51 0.535
--24.0 0.80 0.844
--23.5 0.956 0.968
--23.0 0.9958 0.9963
--22.5 1.0 1.0
diff --git a/lib/ftrsd/ftrsd_paper/ftdata-10000.dat b/lib/ftrsd/ftrsd_paper/ftdata-10000.dat
deleted file mode 100644
index 99d4859..0000000
--- a/lib/ftrsd/ftrsd_paper/ftdata-10000.dat
+++ /dev/null
@@ -1,11 +0,0 @@
- snr psuccess ntrials 10000 r6315, r6330
--27.0 0.000 0.001
--26.5 0.004 0.014
--26.0 0.03 0.066
--25.5 0.107 0.208 0.19
--25.0 0.353 0.424 0.40 (2)
--24.5 0.653 0.725
--24.0 0.913 0.913
--23.5 0.983 0.988
--23.0 0.998 0.999
--22.0 1.0 1.0
diff --git a/lib/ftrsd/ftrsd_paper/ftdata-100000.dat b/lib/ftrsd/ftrsd_paper/ftdata-100000.dat
deleted file mode 100644
index e2db520..0000000
--- a/lib/ftrsd/ftrsd_paper/ftdata-100000.dat
+++ /dev/null
@@ -1,11 +0,0 @@
-snr psuccess 100000 trials r6315, r6330,
--27.0 0.0 0.011
--26.5 0.007 0.035
--26.0 0.057 0.135
--25.5 0.207 0.326
--25.0 0.531 0.568
--24.5 0.822 0.836
--24.0 0.953 0.966
--23.5 0.99423 0.996
--23.0 0.99967 0.99974 302956/303056, 218991/219046
-
diff --git a/lib/ftrsd/ftrsd_paper/ftrsd.lyx b/lib/ftrsd/ftrsd_paper/ftrsd.lyx
deleted file mode 100644
index 4549c76..0000000
--- a/lib/ftrsd/ftrsd_paper/ftrsd.lyx
+++ /dev/null
@@ -1,3289 +0,0 @@
-#LyX 2.1 created this file. For more info see http://www.lyx.org/
-\lyxformat 474
-\begin_document
-\begin_header
-\textclass paper
-\begin_preamble
-\usepackage{ragged2e}
-\exhyphenpenalty=10000\hyphenpenalty=10000
-
-\fancyhf{}
-\fancyhead[L]{Franke \& Taylor: {\it Open Source Soft-Decision Decoder \ldots}}
-\fancyhead[R]{\thepage}
-\makeatletter
-\let\ps@plain\ps@fancy % Plain page style = fancy page style
-\makeatother
-
-\usepackage{nomencl}
-\usepackage{overcite}
-
-\renewcommand{\nomname}{Sidebar: Glossary of Specialized Terms}
-\end_preamble
-\use_default_options true
-\begin_modules
-boxedfloat
-\end_modules
-\maintain_unincluded_children false
-\language english
-\language_package default
-\inputencoding auto
-\fontencoding global
-\font_roman lmodern
-\font_sans lmss
-\font_typewriter lmtt
-\font_math auto
-\font_default_family default
-\use_non_tex_fonts false
-\font_sc false
-\font_osf false
-\font_sf_scale 100
-\font_tt_scale 100
-\graphics default
-\default_output_format default
-\output_sync 0
-\bibtex_command default
-\index_command default
-\float_placement H
-\paperfontsize 12
-\spacing onehalf
-\use_hyperref false
-\papersize default
-\use_geometry true
-\use_package amsmath 1
-\use_package amssymb 1
-\use_package cancel 1
-\use_package esint 1
-\use_package mathdots 1
-\use_package mathtools 1
-\use_package mhchem 1
-\use_package stackrel 1
-\use_package stmaryrd 1
-\use_package undertilde 1
-\cite_engine basic
-\cite_engine_type default
-\biblio_style plain
-\use_bibtopic false
-\use_indices false
-\paperorientation portrait
-\suppress_date false
-\justification false
-\use_refstyle 1
-\index Index
-\shortcut idx
-\color #008000
-\end_index
-\leftmargin 1in
-\topmargin 1in
-\rightmargin 1in
-\bottommargin 1in
-\secnumdepth 3
-\tocdepth 3
-\paragraph_separation skip
-\defskip bigskip
-\quotes_language english
-\papercolumns 1
-\papersides 1
-\paperpagestyle fancy
-\tracking_changes false
-\output_changes false
-\html_math_output 0
-\html_css_as_file 0
-\html_be_strict false
-\end_header
-
-\begin_body
-
-\begin_layout Title
-Open Source Soft-Decision Decoder for the JT65 (63,12) Reed-Solomon Code
-\end_layout
-
-\begin_layout SubTitle
-
-\emph on
-Under-the-hood description of the JT65 decoding procedure, including a wholly
- new algorithm for its powerful error-correcting code.
-\end_layout
-
-\begin_layout Author
-Steven J.
- Franke, K9AN and Joseph H.
- Taylor, K1JT
-\end_layout
-
-\begin_layout Section
-\begin_inset CommandInset label
-LatexCommand label
-name "sec:Introduction-and-Motivation"
-
-\end_inset
-
-Background and Motivation
-\end_layout
-
-\begin_layout Standard
-\begin_inset ERT
-status open
-
-\begin_layout Plain Layout
-
-
-\backslash
-RaggedRight
-\end_layout
-
-\end_inset
-
- The JT65 protocol has revolutionized amateur-radio weak-signal communication
- by enabling operators with small or compromise antennas and relatively
- low-power transmitters to communicate over propagation paths not usable
- with traditional technologies.
- The protocol was developed in 2003 for Earth-Moon-Earth (EME, or
-\begin_inset Quotes eld
-\end_inset
-
-moonbounce
-\begin_inset Quotes erd
-\end_inset
-
-) communication
-\begin_inset CommandInset citation
-LatexCommand cite
-key "jt65_protocol"
-
-\end_inset
-
-, where the scattered return signals are always weak.
- It was soon found that JT65 also enables worldwide communication on the
- HF bands with low power, modest antennas, and efficient spectral usage.
- Thousands of amateurs now use JT65 on a regular basis, making contacts
- on all bands from 160 meters through microwaves.
-\end_layout
-
-\begin_layout Standard
-JT65 uses timed transmitting and receiving sequences one minute long.
- Messages are short and structured so as to streamline minimal exchanges
- between two amateur operators over potentially difficult radio paths.
- Most messages contain two callsigns and a grid locator, signal report,
- acknowledgment, or sign-off; one of the tokens CQ, QRZ, or DE may be substitute
-d for the first callsign.
- Alternatively, a message may contain up to 13 Latin characters of arbitrary
- text.
- All messages are efficiently compressed into exactly 72 bits of digital
- information.
- It should be obvious that the JT65 protocol is intended for the basic purpose
- of completing legitimate, documented two-way contacts, but not for extended
- conversations.
- Full details of the message structure and encoding procedure were presented
- in an earlier publication
-\begin_inset CommandInset citation
-LatexCommand cite
-key "jt65_protocol"
-
-\end_inset
-
-.
- For a concise description of the overall process of transmitting and receiving
- a JT65 message, see the accompanying sidebar
-\series bold
-JT65 Message Processing
-\series default
-.
-\end_layout
-
-\begin_layout Standard
-A major reason for the success and popularity of JT65 is its use of a strong
- error-correction code.
- Before transmission, each 72-bit message is divided into 12 six-bit
-\emph on
-symbols
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Symbol: }"
-description "The information carried in one signalling interval, usually an integral number of bits. JT65 uses 6-bit symbols."
-
-\end_inset
-
-
-\emph default
- and augmented with 51 additional symbols of error-correcting information.
- These 51
-\emph on
-parity symbols
-\emph default
- are computed according to information-theory rules that maximize the probabilit
-y of correctly decoding the message, even if many symbols are received incorrect
-ly.
- The JT65 code is properly described as a short block-length, low-rate Reed-Solo
-mon code based on a 64-symbol
-\emph on
-alphabet.
-
-\emph default
-
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Alphabet: }"
-description "A sequence of possible symbol values used for signaling. JT65 uses a 64-character alphabet, values in the range 0 to 63."
-
-\end_inset
-
- Characters in this alphabet are mapped onto 64 different frequencies for
- transmission.
-
-\end_layout
-
-\begin_layout Standard
-Reed Solomon codes are widely used to ensure reliability in data transmission
- and storage.
- In hardware implementations, decoding is generally accomplished with a
- procedure such as the Berlekamp-Massey (BM) algorithm, based on
-\emph on
-hard decisions
-\emph default
-
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Hard decision: }"
-description "Received symbols are assigned definite values by the demodulator."
-
-\end_inset
-
- for each of the symbol values received.
-
-\emph on
-Soft decisions
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Soft decision: }"
-description "Received symbols are assigned tentative values (most probable, second most probable, etc.) and quality indicators."
-
-\end_inset
-
-
-\emph default
- are potentially more powerful, however.
- For each received JT65 symbol we can estimate not only the value most likely
- to be correct, but also the second, third, etc., most likely.
- Most importantly, we can also estimate the probability that each of those
- possible values is the correct one.
- Decoders that make use of such information are called
-\emph on
-soft-decision decoders.
-\end_layout
-
-\begin_layout Standard
-Until now, nearly all programs implementing JT65 have used the patented
- Kötter-Vardy (KV) algebraic soft-decision decoder
-\begin_inset CommandInset citation
-LatexCommand cite
-key "kv2001"
-
-\end_inset
-
-, licensed to and implemented by K1JT as a closed-source executable for
- use only in amateur radio applications.
- Since 2001 the KV decoder has been considered the best available soft-decision
- decoder for Reed Solomon codes.
-\end_layout
-
-\begin_layout Standard
-We describe here a new open-source alternative called the Franke-Taylor
- (FT, or K9AN-K1JT) soft-decision decoding algorithm.
- It is conceptually simple, built on top of the BM hard-decision decoder,
- and in this application it performs even better than the KV decoder.
- The FT algorithm is implemented in the popular programs
-\emph on
-WSJT
-\emph default
-,
-\emph on
-MAP65
-\emph default
-, and
-\emph on
-WSJT-X
-\emph default
-, widely used for amateur weak-signal communication using JT65 and other
- specialized digital protocols.
- These programs are open-source, freely available
-\begin_inset CommandInset citation
-LatexCommand cite
-key "wsjt"
-
-\end_inset
-
-, and licensed under the GNU General Public License.
-\end_layout
-
-\begin_layout Standard
-The JT65 protocol specifies transmissions that start one second into a UTC
- minute and last for 46.8 seconds.
- Receiving software therefore has as much as ten seconds to decode a message
- before the start of the next minute, when the operator will send a reply.
- With today's personal computers, this relatively long time encourages experimen
-tation with decoders of high computational complexity.
- With time to spare, the FT algorithm lowers the decoding threshold on a
- typical fading channel by many dB over the hard-decision BM decoder, and
- by a meaningful amount over the KV decoder.
- In addition to its excellent performance, the new algorithm has other desirable
- properties, not least of which is its conceptual simplicity.
- Decoding performance and computational complexity scale in a convenient
- way, providing steadily increasing soft-decision decoding gain as a tunable
- parameter is increased over more than five orders of magnitude.
- Appreciable gain is available from our decoder even on very simple (and
- relatively slow) computers.
- On the other hand, because the algorithm benefits from a large number of
- independent decoding trials, further performance gains should be achievable
- through parallelization on high-performance computers.
-\end_layout
-
-\begin_layout Standard
-The remainder of this paper is organized as follows.
- Section 2 presents a brief overview of the nature of Reed Solomon codes
- and their error-correcting capabilities.
- Section 3 provides statistical motivation for the FT algorithm, and Section
- 4 describes the algorithm in full detail.
- Material in these two sections is important because it documents our approach
- and underlines its fundamental technical contributions.
- These sections are heavier in formal mathematics than common in
-\emph on
-QEX
-\emph default
-; for this reason, some readers may choose to skip or skim them and proceed
- more quickly to the results.
- Most readers will benefit by reviewing the original paper on the JT65 protocol
-
-\begin_inset CommandInset citation
-LatexCommand cite
-key "jt65_protocol"
-
-\end_inset
-
-.
- A procedure for
-\emph on
-hinted decoding
-\emph default
---- determining which one, if any, of a list of likely messages matches
- the one that was received --- is outlined in Section 5.
- Finally, in Section 6 we present performance measurements of the FT and
- hinted decoding algorithms and make explicit comparisons to the BM and
- KV decoders familiar to users of older versions of
-\emph on
-WSJT
-\emph default
-,
-\emph on
-MAP65
-\emph default
- and
-\emph on
-WSJT-X
-\emph default
-.
- Section 7 summarizes some on-the-air experiences with the new decoder.
- Refer to the sidebar
-\series bold
-Glossary of Specialized Terms
-\series default
- for brief definitions of some potentially unfamiliar language.
-\end_layout
-
-\begin_layout Section
-\begin_inset CommandInset label
-LatexCommand label
-name "sec:JT65-messages-and"
-
-\end_inset
-
-JT65 Messages and Reed Solomon Codes
-\end_layout
-
-\begin_layout Standard
-The JT65 message frame consists of a short, compressed 72-bit message encoded
- for transmission with a Reed-Solomon code.
- Reed-Solomon codes are
-\emph on
-block codes
-\emph default
-
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Block code: }"
-description "An error-correcting code that treats data in blocks of fixed size."
-
-\end_inset
-
- characterized by
-\begin_inset Formula $n$
-\end_inset
-
-, the length of their
-\emph on
-codewords
-\emph default
-;
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Codeword:}"
-description "For the JT65 code, a vector of 63 symbol values each in the range 0 to 63."
-
-\end_inset
-
-
-\begin_inset Formula $k$
-\end_inset
-
-, the number of message symbols conveyed by the codeword; and the transmission
- alphabet, or number of possible values for each symbol in a codeword.
- The codeword length and the number of message symbols are specified with
- the notation
-\begin_inset Formula $(n,k)$
-\end_inset
-
-.
- JT65 uses a (63,12) Reed-Solomon code with an alphabet of 64 possible values
- for each symbol.
- Each of the 12 message symbols represents
-\begin_inset Formula $\log_{2}64=6$
-\end_inset
-
- message bits.
- The source-encoded
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Source encoding: }"
-description "Compression of a message to use a minimum number or bits. JT65 source-encodes all messages to 72 bits."
-
-\end_inset
-
- message conveyed by a 63-symbol JT65 frame thus consists of 72 information
- bits.
- The JT65 code is
-\emph on
-systematic
-\emph default
-, which means that the 12 message symbols are embedded in the codeword without
- modification and another 51 parity symbols derived from the message symbols
- are added to form a codeword of 63 symbols.
-
-\end_layout
-
-\begin_layout Standard
-In coding theory the concept of
-\emph on
-Hamming distance
-\emph default
-
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Hamming distance: }"
-description "The Hamming distance between two codewords, or between a received word and a codeword, is equal to the number of symbol positions in which they differ."
-
-\end_inset
-
- is used as a measure of disagreement between different codewords, or between
- a received word
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Received word: }"
-description "A vector of symbol values, possibly accompanied by soft information on individual reliabilities."
-
-\end_inset
-
- and a codeword.
- Hamming distance is the number of code symbols that differ in two words
- being compared.
- Reed-Solomon codes have guaranteed minimum Hamming distance
-\begin_inset Formula $d$
-\end_inset
-
-, where
-\begin_inset Formula
-\begin{equation}
-d=n-k+1.\label{eq:minimum_distance}
-\end{equation}
-
-\end_inset
-
-With
-\begin_inset Formula $n=63$
-\end_inset
-
- and
-\begin_inset Formula $k=12$
-\end_inset
-
- the minimum Hamming distance of the JT65 code is
-\begin_inset Formula $d=52$
-\end_inset
-
-.
- With 72 information bits in each message, JT65 can transmit any one of
-
-\begin_inset Formula $2^{72}\approx4.7\times10^{21}$
-\end_inset
-
- possible messages.
- The codeword for any message differs from every other codeword in at least
- 52 of the 63 symbol positions.
-\end_layout
-
-\begin_layout Standard
-A received word containing some
-\emph on
-errors
-\emph default
- (incorrect symbols) can be decoded into the correct codeword using a determinis
-tic,
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Deterministic algorithm: }"
-description "A series of computational steps that for the same input always produces the same output."
-
-\end_inset
-
- algebraic algorithm provided that no more than
-\begin_inset Formula $t$
-\end_inset
-
- symbols were received incorrectly, where
-\begin_inset Formula
-\begin{equation}
-t=\left\lfloor \frac{n-k}{2}\right\rfloor .\label{eq:t}
-\end{equation}
-
-\end_inset
-
-For the JT65 code
-\begin_inset Formula $t=25$
-\end_inset
-
-, so it is always possible to decode a received word having 25 or fewer
- symbol errors.
- Any one of several well-known algebraic algorithms, such as the BM algorithm,
- can carry out this hard-decision decoding.
- Two steps are necessarily involved in this process.
- We must (1) determine which symbols were received incorrectly, and (2)
- find the correct value of the incorrect symbols.
- If we somehow know that certain symbols are incorrect, that information
- can be used to reduce the work involved in step 1 and allow step 2 to correct
- more than
-\begin_inset Formula $t$
-\end_inset
-
- errors.
- In the unlikely event that the location of every error is known, and if
- no correct symbols are accidentally labeled as errors, the BM algorithm
- can correct up to
-\begin_inset Formula $d-1=n-k$
-\end_inset
-
- errors.
-
-\end_layout
-
-\begin_layout Standard
-The FT algorithm creates lists of symbols suspected of being incorrect and
- sends them to the BM decoder.
- Symbols flagged in this way are called
-\emph on
-erasures
-\emph default
-
-\begin_inset CommandInset nomenclature
-LatexCommand nomenclature
-symbol "{\\bf Erasure: }"
-description "A received symbol may be ``erased'' when confidence in its value is so low that it is unlikely to provide useful information. "
-
-\end_inset
-
-.
- With perfect erasure information up to
-\begin_inset Formula $n-k=51$
-\end_inset
-
- incorrect symbols can be corrected for the JT65 code.
- Imperfect erasure information means that some erased symbols may be correct,
- and some other symbols in error.
- If
-\begin_inset Formula $s$
-\end_inset
-
- symbols are erased and the remaining
-\begin_inset Formula $n-s$
-\end_inset
-
- symbols contain
-\begin_inset Formula $e$
-\end_inset
-
- errors, the BM algorithm can find the correct codeword as long as
-\begin_inset Formula
-\begin{equation}
-s+2e\le d-1.\label{eq:erasures_and_errors}
-\end{equation}
-
-\end_inset
-
-If
-\begin_inset Formula $s=0$
-\end_inset
-
-, the decoder is said to be an
-\emph on
-errors-only
-\emph default
- decoder.
- If
-\begin_inset Formula $0=x|N,X,s) '/ &
- '-------------------------------')
-
- hsum=0.d0
- do ix=x,XX
- h=hypergeo(ix,NN,XX,s)
- hsum=hsum + h
- write(*,1020) ix,h,hsum
-1020 format(i3,2d13.4)
- enddo
-
-999 end program prob
diff --git a/lib/ftrsd/ftrsd_paper/psuccess.lab b/lib/ftrsd/ftrsd_paper/psuccess.lab
deleted file mode 100644
index 21ed973..0000000
--- a/lib/ftrsd/ftrsd_paper/psuccess.lab
+++ /dev/null
@@ -1,14 +0,0 @@
--21.5 55 BM
--24.5 50 FT
--27.0 68 DS
--25.2 25 0
--25.7 37 0.2
--24.6 16 1.0
--22.6 35 0
--20.9 29 0.2
--19.5 35 1.0
--28.5 25 1.0
--28.2 56 0.2
--28.5 72 0
-
-
diff --git a/lib/ftrsd/ftrsd_paper/stats-100000-24db-3.dat b/lib/ftrsd/ftrsd_paper/stats-100000-24db-3.dat
deleted file mode 100644
index bd2a10f..0000000
--- a/lib/ftrsd/ftrsd_paper/stats-100000-24db-3.dat
+++ /dev/null
@@ -1,930 +0,0 @@
- 35 19 45 12
- 34 20 46 6
- 35 27 43 4519
- 33 21 44 11
- 32 22 39 8
- 34 21 48 333
- 30 20 42 2
- 38 25 43 12
- 38 25 49 2958
- 28 20 43 10
- 41 29 44 4070
- 32 19 44 1
- 28 19 43 2
- 38 28 43 10421
- 25 0 0 0
- 36 24 42 8
- 38 25 42 243
- 39 25 45 81
- 33 17 39 2
- 38 25 39 157
- 37 27 45 1
- 31 18 39 8
- 35 22 41 2
- 31 20 45 32
- 40 30 45 11123
- 34 25 48 516
- 37 22 49 73
- 32 19 45 2
- 39 25 43 49
- 35 25 42 12
- 43 32 45 3645
- 35 21 45 124
- 39 26 48 31
- 40 26 48 23
- 36 25 43 169
- 33 21 41 8
- 31 21 49 3
- 37 23 46 2
- 32 27 41 8
- 36 23 43 2112
- 29 19 49 4
- 34 24 41 170
- 27 15 44 1
- 34 21 43 2
- 39 25 47 28
- 30 18 43 10
- 37 22 40 8
- 42 33 48 64709
- 36 25 43 10
- 35 20 51 17
- 37 28 45 301
- 34 18 40 9
- 34 25 47 23
- 39 28 43 4856
- 36 24 45 7057
- 35 25 47 769
- 38 28 47 208
- 39 27 47 52290
- 35 22 44 85
- 34 23 48 7
- 37 21 47 82
- 42 25 39 1677
- 29 17 41 8
- 41 24 46 656
- 35 24 43 2
- 38 22 45 10400
- 36 20 42 14
- 33 22 46 2
- 25 0 0 0
- 33 20 45 12
- 30 17 45 1
- 34 20 43 40
- 32 21 42 14
- 28 15 44 1
- 37 23 42 8
- 32 21 40 8
- 39 28 44 65
- 30 17 41 2
- 32 25 44 134
- 38 24 43 12
- 38 23 47 153
- 39 26 42 8
- 37 20 47 35
- 39 27 47 1003
- 36 23 45 215
- 38 28 49 46
- 34 24 47 200
- 35 23 40 8
- 30 19 44 1
- 38 25 43 32
- 32 22 39 103
- 33 23 42 2
- 34 24 47 6
- 33 22 43 13
- 42 28 43 2127
- 34 22 41 113
- 39 30 41 517
- 30 17 42 8
- 32 20 45 1
- 34 20 51 17
- 32 15 39 9
- 37 23 47 223
- 28 15 43 1
- 38 24 42 251
- 41 26 45 2
- 39 25 49 7
- 35 26 47 237
- 32 18 43 25
- 33 23 43 8
- 41 29 43 2667
- 28 17 45 1
- 34 23 47 53
- 32 19 39 9
- 34 24 42 59
- 36 22 44 8
- 34 20 45 59
- 37 24 45 12
- 28 17 44 1
- 41 29 43 24865
- 32 19 46 6
- 33 22 47 6
- 36 20 47 143
- 36 22 47 34
- 33 19 39 9
- 38 22 44 523
- 34 24 42 737
- 36 24 39 170
- 35 22 43 2
- 32 19 48 22
- 33 20 49 76
- 42 24 49 6910
- 37 22 47 94
- 40 24 43 6
- 35 25 45 33
- 29 22 41 2
- 40 24 46 2096
- 37 20 45 135
- 36 26 43 113
- 36 21 43 13
- 37 24 47 49
- 35 24 43 54
- 37 22 43 8
- 35 23 44 2
- 30 20 43 11
- 39 30 47 2870
- 42 33 44 585
- 26 17 45 2
- 41 29 47 79
- 40 24 46 836
- 33 19 45 201
- 34 21 39 13
- 33 21 49 60
- 35 24 44 248
- 33 24 43 24
- 39 29 44 151
- 31 23 46 1
- 36 23 46 1
- 41 27 47 5565
- 42 26 47 378
- 35 27 45 4571
- 40 30 47 6422
- 32 20 42 8
- 38 28 45 449
- 38 26 47 595
- 39 24 47 1555
- 41 25 49 645
- 32 19 40 8
- 35 25 45 97
- 25 0 0 0
- 30 19 44 25
- 31 18 45 1
- 41 24 51 6915
- 34 23 46 1917
- 30 19 43 2
- 35 22 47 20
- 38 23 43 882
- 30 20 48 5
- 37 25 44 919
- 34 20 45 74
- 38 25 46 394
- 39 21 49 738
- 35 20 47 22
- 40 30 47 190
- 41 27 45 1515
- 39 27 49 55
- 35 25 41 994
- 39 27 47 7117
- 37 22 46 19
- 33 21 41 2
- 34 18 47 19
- 30 20 46 6
- 31 21 46 1
- 36 24 47 98
- 40 24 43 39
- 38 25 45 138
- 41 27 47 33
- 40 29 49 2510
- 36 26 43 2
- 34 21 45 1
- 40 26 49 1924
- 36 17 43 2
- 38 27 45 68
- 34 22 45 61
- 32 22 40 8
- 37 19 43 4784
- 32 16 43 8
- 38 27 50 46
- 35 21 43 38
- 35 22 49 4
- 38 27 49 31
- 39 28 47 4677
- 30 18 45 2
- 43 28 47 8235
- 38 28 43 830
- 32 21 47 15
- 37 24 42 10
- 37 23 45 259
- 37 25 45 35
- 40 24 45 524
- 35 19 44 1
- 36 23 45 84
- 36 24 50 17
- 31 20 46 1
- 35 24 42 74
- 42 27 47 1445
- 40 28 48 31
- 36 23 45 151
- 34 22 46 6
- 33 24 49 16
- 30 20 45 2
- 38 22 43 125
- 40 25 49 64
- 35 23 49 86
- 38 24 46 613
- 42 25 47 4232
- 34 24 43 31
- 32 18 41 2
- 37 26 43 70
- 37 27 41 14
- 37 22 39 129
- 38 27 49 3
- 32 22 47 15
- 41 27 41 472
- 38 24 43 25
- 35 28 43 309
- 41 25 47 82
- 40 23 43 8
- 40 21 43 1716
- 38 22 48 5
- 37 20 47 22
- 42 28 43 315
- 32 23 43 79
- 25 0 0 0
- 42 23 47 2245
- 35 24 45 2
- 41 25 44 12
- 36 23 43 1
- 36 19 45 151
- 41 28 45 2207
- 40 27 45 76
- 34 20 47 6
- 41 28 46 370
- 38 20 45 12
- 32 20 43 8
- 39 24 45 8
- 41 27 47 26941
- 35 23 46 3
- 34 25 41 14
- 43 27 47 26905
- 35 25 45 2
- 32 20 50 3
- 31 17 41 2
- 38 26 47 4157
- 33 24 41 2
- 41 29 43 26513
- 35 22 45 297
- 37 26 44 99
- 33 19 43 10
- 39 23 45 138
- 39 26 47 1320
- 33 22 42 2
- 42 32 45 791
- 33 23 51 3
- 38 25 43 8
- 40 27 49 1210
- 43 27 45 32969
- 37 26 49 108
- 38 18 45 1268
- 40 28 49 7810
- 36 25 44 47
- 38 27 48 20
- 34 20 44 10
- 41 27 45 429
- 33 18 43 8
- 29 17 45 1
- 40 25 42 9
- 30 21 49 4
- 37 22 45 10
- 23 0 0 0
- 36 15 45 2509
- 29 21 45 18
- 33 23 45 53
- 43 27 49 7533
- 37 28 45 2652
- 36 24 49 31
- 32 20 43 25
- 42 27 49 1500
- 41 26 45 8
- 40 25 47 152
- 37 26 45 151
- 37 27 43 139
- 34 20 47 4
- 31 21 43 44
- 37 28 45 241
- 35 25 45 422
- 33 22 45 6
- 39 26 48 23
- 38 27 49 359
- 42 26 45 1430
- 36 28 47 116
- 33 23 41 232
- 38 25 47 73
- 35 24 43 16
- 42 29 47 398
- 38 27 49 2203
- 32 20 47 3
- 32 18 48 3
- 36 23 47 44
- 37 24 48 147
- 39 22 45 31
- 31 20 44 1
- 34 21 43 8
- 39 27 47 201
- 34 23 44 12
- 34 24 43 8
- 36 17 46 2
- 41 27 47 8709
- 41 26 45 112
- 37 23 47 216
- 38 24 45 93
- 32 19 45 44
- 34 22 45 8
- 33 24 41 14
- 34 22 41 9
- 35 23 42 136
- 36 26 43 3272
- 34 18 44 40
- 38 25 43 316
- 29 23 39 9
- 35 23 45 2
- 41 29 42 136
- 37 26 43 12
- 34 21 46 43
- 39 21 47 23
- 40 29 49 14666
- 36 19 45 400
- 37 24 43 8
- 35 19 44 2
- 36 26 45 14
- 36 22 43 103
- 33 19 45 6
- 35 24 43 1
- 31 22 43 80
- 35 23 46 22
- 28 18 41 2
- 35 24 45 31
- 34 24 47 46
- 37 24 42 2
- 37 27 43 525
- 31 16 41 9
- 30 18 45 2
- 39 25 47 1416
- 37 24 46 23
- 40 28 49 5
- 39 26 46 2071
- 28 13 42 8
- 31 17 47 3
- 34 22 49 3
- 42 23 47 61
- 30 21 41 2
- 40 23 47 208
- 38 22 48 6
- 35 17 40 8
- 36 20 45 32
- 37 22 47 1116
- 41 28 47 14145
- 43 28 49 96342
- 35 19 45 102
- 31 23 43 8
- 33 20 43 1
- 30 19 46 90
- 41 27 45 19090
- 35 26 45 2942
- 40 25 47 127
- 35 23 45 12
- 37 26 46 76
- 31 19 44 32
- 42 31 49 4951
- 43 30 44 38924
- 35 19 51 17
- 41 31 44 6637
- 33 22 42 2
- 33 25 46 12
- 31 24 44 10
- 27 16 49 4
- 39 24 45 16
- 33 20 40 8
- 39 31 48 5073
- 39 21 47 72
- 35 21 47 3
- 38 27 41 1168
- 35 22 43 8
- 28 18 45 1
- 38 28 40 776
- 33 22 51 3
- 34 22 41 370
- 37 25 43 3210
- 32 24 43 8
- 35 24 46 3
- 39 20 45 41
- 35 17 43 49
- 39 29 46 20
- 31 21 44 1
- 43 24 48 4400
- 36 23 48 350
- 38 29 47 520
- 36 24 45 49
- 39 27 43 493
- 34 15 45 6
- 41 31 43 59993
- 34 24 42 27
- 31 14 41 1
- 40 30 47 13295
- 35 23 47 202
- 36 22 47 35
- 38 26 45 18576
- 34 26 43 54
- 40 30 51 173
- 43 29 47 105
- 34 24 39 9
- 33 20 43 8
- 35 27 45 65
- 31 18 42 2
- 31 21 45 6
- 40 27 45 979
- 36 21 47 3
- 29 14 43 1
- 37 24 47 432
- 39 24 50 4778
- 33 20 44 2
- 40 27 44 7398
- 36 22 47 148
- 35 21 44 11
- 35 22 45 206
- 30 18 42 8
- 40 30 43 8
- 30 22 42 9
- 29 21 39 9
- 41 26 43 1248
- 39 24 43 14
- 38 24 49 605
- 35 20 42 155
- 33 22 47 53
- 34 20 43 10
- 35 26 49 21
- 31 18 45 1
- 32 19 39 9
- 31 20 43 19
- 41 23 41 157
- 36 23 42 9
- 28 19 45 1
- 33 19 43 10
- 38 22 44 25
- 29 19 41 2
- 34 19 42 8
- 35 21 39 9
- 34 23 45 2
- 41 30 47 71025
- 40 26 48 3059
- 36 24 45 1346
- 35 19 47 34
- 36 25 45 112
- 39 27 41 7065
- 38 24 47 4
- 29 18 42 1
- 30 20 41 2
- 32 22 49 3
- 40 29 45 4589
- 38 25 42 234
- 42 28 49 3171
- 35 22 45 34
- 39 24 41 5693
- 29 20 43 2
- 29 16 44 14
- 37 25 45 19
- 36 18 44 8
- 36 27 45 1224
- 38 28 47 8906
- 29 15 51 3
- 33 20 47 46
- 33 17 41 9
- 40 22 45 1775
- 32 22 45 8
- 35 21 43 8
- 38 24 41 9
- 41 22 47 10005
- 36 27 43 12
- 33 21 47 35
- 35 21 39 9
- 34 22 44 2
- 34 17 45 67
- 31 18 45 1
- 34 21 46 32
- 35 26 44 1
- 34 23 44 8
- 31 24 47 3
- 43 23 49 9210
- 40 20 48 114
- 36 25 42 8
- 37 24 46 336
- 37 23 43 138
- 38 26 47 89
- 38 24 47 6494
- 30 18 45 1
- 43 28 47 677
- 31 23 48 3
- 32 19 43 1
- 36 23 44 19
- 43 30 47 81276
- 37 22 48 106
- 37 24 45 12
- 37 22 45 68
- 28 17 43 24
- 43 28 45 1446
- 40 30 46 2753
- 35 23 44 1
- 28 16 43 2
- 29 19 42 2
- 31 21 42 2
- 39 26 48 98
- 41 30 47 21848
- 35 22 47 5
- 40 31 45 448
- 34 23 45 94
- 29 17 42 8
- 39 30 46 1231
- 41 22 47 49
- 30 15 51 7
- 35 26 41 9
- 29 17 49 7
- 33 22 43 12
- 33 19 46 5
- 35 24 45 12
- 33 22 42 9
- 34 18 43 13
- 36 21 43 63
- 37 27 45 32
- 37 23 49 474
- 31 17 46 19
- 38 24 41 2
- 40 28 47 1621
- 39 25 47 214
- 32 21 42 19
- 34 22 47 105
- 35 26 42 2
- 35 21 44 13
- 40 25 47 556
- 39 27 49 3
- 36 25 45 32
- 39 27 41 10
- 35 20 45 1
- 28 17 45 1
- 35 23 47 6
- 33 20 50 137
- 34 22 43 177
- 30 19 41 9
- 33 23 47 579
- 33 22 39 9
- 39 20 42 74
- 42 28 47 112
- 40 29 44 197
- 36 23 43 2
- 30 17 49 3
- 37 27 45 3815
- 35 24 43 74
- 35 22 47 24
- 40 27 46 82
- 36 25 41 366
- 33 23 44 1
- 37 21 40 131
- 34 22 45 16
- 36 24 45 306
- 39 26 47 82
- 29 17 45 1
- 36 23 48 3
- 35 20 44 63
- 35 23 46 5
- 39 25 43 792
- 32 22 49 5
- 35 23 41 9
- 37 24 41 12711
- 41 32 43 36575
- 34 23 42 8
- 31 21 43 2
- 35 24 41 2
- 35 24 39 8
- 37 23 48 75
- 35 19 43 12
- 40 25 49 914
- 38 22 49 60
- 34 19 42 10
- 42 33 44 9038
- 37 27 45 1849
- 29 20 42 138
- 37 27 43 332
- 36 26 45 36
- 32 18 45 6
- 37 25 46 4676
- 29 18 45 6
- 34 22 43 8
- 41 32 45 1966
- 30 18 42 12
- 33 20 45 1
- 31 23 45 6
- 30 21 46 1
- 36 21 43 14
- 34 18 45 37
- 42 32 47 3508
- 41 32 41 13
- 37 25 45 719
- 33 20 45 111
- 38 28 42 8
- 35 23 43 14
- 39 23 47 123
- 28 13 44 1
- 34 19 41 38
- 35 21 43 8
- 33 26 47 124
- 30 18 41 9
- 43 30 46 11935
- 40 28 48 2329
- 35 19 45 286
- 30 21 43 80
- 37 21 49 474
- 41 27 49 1560
- 42 24 46 1802
- 38 28 42 6807
- 38 24 43 63
- 33 24 49 35
- 41 27 41 9795
- 29 16 41 2
- 29 17 43 2
- 34 21 45 125
- 39 28 45 1008
- 34 21 42 8
- 36 23 45 2
- 34 22 41 8
- 34 21 41 74
- 37 21 43 262
- 30 18 41 8
- 33 22 49 3
- 33 21 42 1
- 35 28 49 21
- 31 19 43 1
- 36 24 44 10
- 40 23 49 583
- 33 19 37 9
- 32 21 45 6
- 38 24 47 15
- 42 27 47 2847
- 36 28 45 106
- 39 28 43 53
- 30 16 42 2
- 28 18 49 3
- 33 21 44 1
- 36 24 45 3050
- 37 27 40 8
- 35 19 43 12
- 41 29 43 19008
- 21 0 0 0
- 38 26 41 762
- 33 21 46 12
- 41 26 47 14517
- 33 24 49 3
- 41 31 47 287
- 35 24 51 17
- 37 27 42 38
- 34 22 43 24
- 39 26 46 135
- 38 26 41 493
- 35 22 42 8
- 38 24 41 1082
- 32 23 42 1
- 33 24 40 8
- 37 25 48 640
- 28 14 39 9
- 39 20 45 212
- 37 29 45 610
- 34 26 47 57
- 29 21 41 8
- 35 16 45 53
- 35 21 44 2
- 38 26 48 188
- 34 25 41 10
- 36 23 44 8
- 35 21 45 8
- 35 26 41 8
- 37 26 40 9
- 28 12 43 1
- 34 22 51 3
- 35 25 44 13
- 32 16 44 32
- 32 19 45 143
- 29 17 43 1
- 35 22 43 93
- 38 21 43 99
- 36 26 49 242
- 34 22 45 8
- 40 24 45 136
- 40 24 48 88
- 38 21 46 49
- 40 27 49 116
- 41 26 44 3696
- 35 23 42 8
- 28 15 45 104
- 33 21 43 106
- 35 25 45 31
- 33 24 40 113
- 36 24 46 23
- 37 25 45 334
- 32 21 46 12
- 35 21 41 2
- 36 22 45 8
- 37 18 43 13
- 37 26 47 48
- 39 25 46 400
- 37 27 43 174
- 37 23 47 41
- 40 21 47 1811
- 38 26 45 79
- 26 15 43 1
- 39 27 49 19
- 31 19 44 1
- 37 22 43 8
- 32 24 38 9
- 34 23 48 3
- 37 24 51 22
- 27 18 42 2
- 31 22 47 5
- 33 17 41 2
- 40 28 45 14534
- 37 21 47 5
- 27 15 43 2
- 43 26 47 46658
- 39 22 43 8
- 36 23 41 2
- 31 19 43 12
- 36 24 43 10
- 33 20 43 149
- 30 19 47 3
- 39 27 51 1236
- 41 26 45 4744
- 39 22 47 100
- 32 18 44 6
- 32 21 43 54
- 40 30 46 777
- 35 25 43 355
- 36 24 41 138
- 40 30 47 3056
- 39 28 46 19
- 34 21 46 6
- 34 18 46 52
- 36 27 41 232
- 35 25 51 3
- 36 28 44 110
- 33 23 45 1
- 37 22 46 64301
- 39 23 49 41
- 39 30 40 25
- 36 23 48 6
- 29 17 42 2
- 36 23 44 1
- 32 17 43 40
- 32 16 49 86
- 29 19 49 5
- 38 26 41 9
- 40 28 43 56710
- 41 29 45 1711
- 36 23 49 345
- 35 25 43 8
- 35 24 46 19
- 37 23 41 648
- 30 18 45 1
- 30 21 43 1
- 34 20 45 12
- 42 25 47 431
- 40 27 41 15878
- 34 22 43 8
- 41 29 48 49
- 32 21 43 2
- 37 22 43 2
- 39 28 49 86
- 43 28 45 8032
- 41 30 49 15674
- 34 22 48 17
- 36 24 48 107
- 28 20 44 1
- 43 28 48 1986
- 40 25 47 2585
- 38 21 43 59
- 38 28 41 167
- 34 22 39 9
- 43 27 48 4196
- 32 20 44 120
- 33 25 45 99
- 26 12 42 2
- 26 15 47 4
- 37 21 42 10
- 35 25 49 3
- 42 30 49 11151
- 33 20 44 2
- 39 26 45 65238
- 31 16 40 2
- 38 26 39 8
- 36 22 45 82
- 32 22 49 7
- 33 20 45 2
- 40 24 43 12
- 32 18 50 3
- 31 21 40 2
- 34 18 44 2
- 38 28 46 194
- 36 21 43 12
- 32 20 43 8
- 30 18 42 2
- 37 21 47 31
- 36 23 47 15
- 36 21 45 113
- 34 23 44 1
- 43 29 49 3889
- 37 24 47 32
- 41 22 43 243
- 38 25 47 707
- 35 22 43 18399
- 33 22 45 123
- 37 24 42 8
- 39 25 47 1087
- 34 23 47 107
- 32 21 42 2
- 42 25 47 106
- 39 24 42 13560
- 42 29 49 52387
- 38 27 43 59
- 31 18 39 9
- 40 28 48 41
- 37 25 45 11
- 30 23 45 242
- 38 23 47 1673
- 36 23 45 751
- 29 22 41 2
- 36 19 48 3
- 36 22 45 12
- 35 18 47 20
- 40 28 49 17369
- 29 19 46 2
- 36 26 42 25
- 42 30 49 4767
- 30 20 45 6
- 35 24 44 12
- 41 24 42 1537
- 38 25 47 629
- 31 21 44 2
- 34 22 43 1
- 33 20 47 3
- 34 20 43 8
- 40 26 49 4320
- 31 16 43 9
- 34 22 45 8
- 32 22 46 124
- 32 20 43 13
- 40 28 47 1185
- 41 24 45 30643
- 39 23 43 1658
- 33 23 44 8
- 36 22 46 23
- 41 25 47 114
- 36 21 42 12
- 33 19 48 31
- 42 28 48 76
- 29 22 39 9
- 36 21 47 3
- 37 27 45 282
- 42 29 46 24995
- 36 26 39 9
- 40 25 46 123
- 39 26 41 8
- 41 30 45 3143
- 34 20 41 27
- 38 31 42 17297
- 40 24 51 3052
- 36 28 45 190
- 31 23 42 8
- 42 26 42 68
- 39 31 45 37327
- 37 27 41 8
- 36 20 45 76
- 38 26 42 10
- 36 21 45 63
- 40 31 43 140
- 40 27 49 21
- 31 22 36 9
- 34 22 39 9
- 29 17 43 2
- 36 26 45 61
- 38 23 45 15
- 31 21 43 54
- 36 22 41 93
- 31 18 43 2
- 35 25 49 108
- 41 29 45 18292
- 37 25 45 104
- 28 20 41 2
- 35 26 46 35
- 34 20 46 19
- 38 22 51 183
- 34 14 43 8
- 32 23 43 16
- 27 17 44 1
- 29 15 42 2
- 37 26 41 129
diff --git a/lib/ftrsd/ftrsd_paper/stats_0.0 b/lib/ftrsd/ftrsd_paper/stats_0.0
deleted file mode 100644
index 75c9778..0000000
--- a/lib/ftrsd/ftrsd_paper/stats_0.0
+++ /dev/null
@@ -1,27 +0,0 @@
- SNR Files Sync BM FT Hint Total False BadSync
---------------------------------------------------------
--18.0 1000 1000 1000 1000 1000 1000 0 0
--18.5 1000 1000 1000 1000 1000 1000 0 0
--19.0 1000 1000 1000 1000 1000 1000 0 0
--19.5 1000 1000 1000 1000 1000 1000 0 0
--20.0 1000 1000 1000 1000 1000 1000 0 0
--20.5 1000 1000 1000 1000 1000 1000 0 0
--21.0 1000 1000 1000 1000 1000 1000 0 0
--21.5 1000 1000 991 1000 1000 1000 0 0
--22.0 1000 1000 918 1000 1000 1000 0 0
--22.5 1000 1000 631 1000 1000 1000 0 0
--23.0 1000 1000 261 1000 1000 1000 0 0
--23.5 1000 1000 57 990 1000 1000 0 0
--24.0 1000 1000 0 925 1000 1000 0 0
--24.5 1000 1000 0 737 1000 1000 0 0
--25.0 1000 999 0 445 999 999 1 ?
--25.5 1000 996 0 191 996 996 2 ?
--26.0 1000 980 0 68 985 985 3 ?
--26.5 1000 953 0 18 975 975 3 ?
--27.0 1000 904 0 3 926 926 4 ?
--27.5 1000 816 0 2 874 874 3 ?
--28.0 1000 722 0 0 786 786 7 ?
--28.5 1000 590 0 0 616 616 12 ?
--29.0 1000 451 0 0 479 479 15 ?
--29.5 1000 355 0 0 303 303 27 ?
--30.0 1000 277 0 0 173 173 28 ?
diff --git a/lib/ftrsd/ftrsd_paper/stats_0.2 b/lib/ftrsd/ftrsd_paper/stats_0.2
deleted file mode 100644
index 1e0cb00..0000000
--- a/lib/ftrsd/ftrsd_paper/stats_0.2
+++ /dev/null
@@ -1,27 +0,0 @@
- SNR Files Sync BM FT Hint Total False BadSync
---------------------------------------------------------
--18.0 1000 998 973 998 998 998 0 2
--18.5 1000 1000 960 1000 1000 1000 0 0
--19.0 1000 1000 917 1000 1000 1000 0 0
--19.5 1000 1000 849 1000 1000 1000 0 0
--20.0 1000 1000 725 1000 1000 1000 0 0
--20.5 1000 1000 549 1000 1000 1000 0 0
--21.0 1000 1000 373 1000 1000 1000 0 0
--21.5 1000 1000 216 1000 1000 1000 0 0
--22.0 1000 1000 100 998 1000 1000 0 0
--22.5 1000 1000 32 998 1000 1000 0 0
--23.0 1000 1000 12 991 1000 1000 0 0
--23.5 1000 998 2 958 1000 1000 0 2
--24.0 1000 992 0 878 998 998 1 8
--24.5 1000 986 0 739 995 995 0 14
--25.0 1000 977 0 533 991 991 0 23
--25.5 1000 959 0 324 975 975 3 41
--26.0 1000 930 0 153 953 953 1 70
--26.5 1000 874 0 51 924 924 8 126
--27.0 1000 808 0 14 866 866 6 192
--27.5 1000 716 0 3 799 799 10 284
--28.0 1000 610 0 1 689 689 14 390
--28.5 1000 497 0 0 596 596 19 503
--29.0 1000 399 0 0 451 451 21 601
--29.5 1000 300 0 0 270 270 27 700
--30.0 1000 243 0 0 172 172 26 757
diff --git a/lib/ftrsd/ftrsd_paper/stats_1.0 b/lib/ftrsd/ftrsd_paper/stats_1.0
deleted file mode 100644
index 34f94c6..0000000
--- a/lib/ftrsd/ftrsd_paper/stats_1.0
+++ /dev/null
@@ -1,27 +0,0 @@
- SNR Files Sync BM FT Hint Total False BadSync
---------------------------------------------------------
--18.0 1000 998 917 998 998 998 1 2
--18.5 1000 998 824 998 998 998 0 2
--19.0 1000 999 695 999 999 999 0 1
--19.5 1000 999 504 999 999 999 0 1
--20.0 1000 1000 300 1000 1000 1000 0 0
--20.5 1000 1000 148 1000 1000 1000 0 0
--21.0 1000 1000 56 1000 1000 1000 0 0
--21.5 1000 1000 10 1000 1000 1000 0 0
--22.0 1000 999 3 995 1000 1000 0 1
--22.5 1000 998 0 972 1000 1000 0 2
--23.0 1000 997 0 899 999 999 0 3
--23.5 1000 996 0 758 999 999 0 4
--24.0 1000 990 0 545 999 999 0 10
--24.5 1000 981 0 305 988 988 2 19
--25.0 1000 964 0 128 987 987 0 36
--25.5 1000 930 0 43 956 956 4 70
--26.0 1000 870 0 15 932 932 4 130
--26.5 1000 810 0 4 889 889 8 190
--27.0 1000 737 0 0 798 798 9 263
--27.5 1000 632 0 0 650 650 10 368
--28.0 1000 522 0 0 526 526 15 478
--28.5 1000 426 0 0 383 383 19 574
--29.0 1000 332 0 0 226 226 34 668
--29.5 1000 260 0 0 136 136 32 740
--30.0 1000 209 0 0 64 64 47 791
diff --git a/lib/ftrsd/ftrsd_paper/wer.lab b/lib/ftrsd/ftrsd_paper/wer.lab
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/ftrsd/ftrsd_paper/wer2.lab b/lib/ftrsd/ftrsd_paper/wer2.lab
deleted file mode 100644
index b3440f8..0000000
--- a/lib/ftrsd/ftrsd_paper/wer2.lab
+++ /dev/null
@@ -1,7 +0,0 @@
--25.7 30 $10^5$
--25.25 36 $10^4$
--24.5 44 $10^3$
--24.15 48 $10^2$
--23.7 44 10
--22.5 48 BM
--25.2 24 KV
\ No newline at end of file
diff --git a/lib/ftrsd/ftrsdap.c b/lib/ftrsd/ftrsdap.c
deleted file mode 100644
index b2b85dd..0000000
--- a/lib/ftrsd/ftrsdap.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- ftrsdap.c
-
- A soft-decision decoder for the JT65 (63,12) Reed-Solomon code.
-
- This decoding scheme is built around Phil Karn's Berlekamp-Massey
- errors and erasures decoder. The approach is inspired by a number of
- publications, including the stochastic Chase decoder described
- in "Stochastic Chase Decoding of Reed-Solomon Codes", by Leroux et al.,
- IEEE Communications Letters, Vol. 14, No. 9, September 2010 and
- "Soft-Decision Decoding of Reed-Solomon Codes Using Successive Error-
- and-Erasure Decoding," by Soo-Woong Lee and B. V. K. Vijaya Kumar.
-
- Steve Franke K9AN and Joe Taylor K1JT
- */
-
-#include
-#include
-#include
-#include
-#include
-#include "../ftrsd/rs2.h"
-
-static void *rs;
-void getpp_(int workdat[], float *pp);
-
-void ftrsdap_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
- int ap[], int* ntrials0, int correct[], int param[], int ntry[])
-{
- int rxdat[63], rxprob[63], rxdat2[63], rxprob2[63];
- int workdat[63];
- int indexes[63];
- int era_pos[51];
- int i, j, numera, nerr, nn=63;
- int ntrials = *ntrials0;
- int nhard=0,nhard_min=32768,nsoft=0,nsoft_min=32768;
- int ntotal=0,ntotal_min=32768,ncandidates;
- int nera_best=0;
- float pp,pp1,pp2;
- static unsigned int nseed;
-
-// Power-percentage symbol metrics - composite gnnf/hf
- int perr[8][8] = {
- { 4, 9, 11, 13, 14, 14, 15, 15},
- { 2, 20, 20, 30, 40, 50, 50, 50},
- { 7, 24, 27, 40, 50, 50, 50, 50},
- {13, 25, 35, 46, 52, 70, 50, 50},
- {17, 30, 42, 54, 55, 64, 71, 70},
- {25, 39, 48, 57, 64, 66, 77, 77},
- {32, 45, 54, 63, 66, 75, 78, 83},
- {51, 58, 57, 66, 72, 77, 82, 86}};
-
-
-// Initialize the KA9Q Reed-Solomon encoder/decoder
- unsigned int symsize=6, gfpoly=0x43, fcr=3, prim=1, nroots=51;
- rs=init_rs_int(symsize, gfpoly, fcr, prim, nroots, 0);
-
-// Reverse the received symbol vectors for BM decoder
- for (i=0; i<63; i++) {
- rxdat[i]=mrsym[62-i];
- rxprob[i]=mrprob[62-i];
- rxdat2[i]=mr2sym[62-i];
- rxprob2[i]=mr2prob[62-i];
- }
-
-// Set ap symbols and ap mask
- for (i=0; i<12; i++) {
- if(ap[i]>=0) {
- rxdat[11-i]=ap[i];
- rxprob2[11-i]=-1;
- }
- }
-
-// Sort rxprob to find indexes of the least reliable symbols
- int k, pass, tmp, nsym=63;
- int probs[63];
- for (i=0; i<63; i++) {
- indexes[i]=i;
- probs[i]=rxprob[i];
- }
- for (pass = 1; pass <= nsym-1; pass++) {
- for (k = 0; k < nsym - pass; k++) {
- if( probs[k] < probs[k+1] ) {
- tmp = probs[k];
- probs[k] = probs[k+1];
- probs[k+1] = tmp;
- tmp = indexes[k];
- indexes[k] = indexes[k+1];
- indexes[k+1] = tmp;
- }
- }
- }
-
-// See if we can decode using BM HDD, and calculate the syndrome vector.
- memset(era_pos,0,51*sizeof(int));
- numera=0;
- memcpy(workdat,rxdat,sizeof(rxdat));
- nerr=decode_rs_int(rs,workdat,era_pos,numera,1);
- if( nerr >= 0 ) {
- // Hard-decision decoding succeeded. Save codeword and some parameters.
- nhard=0;
- for (i=0; i<63; i++) {
- if( workdat[i] != rxdat[i] ) nhard=nhard+1;
- }
- memcpy(correct,workdat,63*sizeof(int));
- param[0]=0;
- param[1]=nhard;
- param[2]=0;
- param[3]=0;
- param[4]=0;
- param[5]=0;
- param[7]=1000*1000;
- ntry[0]=0;
- return;
- }
-
-/*
-Hard-decision decoding failed. Try the FT soft-decision method.
-Generate random erasure-locator vectors and see if any of them
-decode. This will generate a list of "candidate" codewords. The
-soft distance between each candidate codeword and the received
-word is estimated by finding the largest (pp1) and second-largest
-(pp2) outputs from a synchronized filter-bank operating on the
-symbol spectra, and using these to decide which candidate
-codeword is "best".
-*/
-
- nseed=1; //Seed for random numbers
- float ratio;
- int thresh, nsum;
- int thresh0[63];
- ncandidates=0;
- nsum=0;
- int ii,jj;
- for (i=0; i=0 ) {
- ratio = (float)rxprob2[j]/((float)rxprob[j]+0.01);
- ii = 7.999*ratio;
- jj = (62-i)/8;
- thresh0[i] = 1.3*perr[ii][jj];
- } else {
- thresh0[i] = 0.0;
- }
-//printf("%d %d %d\n",i,j,rxdat[i]);
- }
-
- if(nsum<=0) return;
-
- pp1=0.0;
- pp2=0.0;
- for (k=1; k<=ntrials; k++) {
- memset(era_pos,0,51*sizeof(int));
- memcpy(workdat,rxdat,sizeof(rxdat));
-
-/*
-Mark a subset of the symbols as erasures.
-Run through the ranked symbols, starting with the worst, i=0.
-NB: j is the symbol-vector index of the symbol with rank i.
-*/
- numera=0;
- for (i=0; i= 0 ) {
- // We have a candidate codeword. Find its hard and soft distance from
- // the received word. Also find pp1 and pp2 from the full array
- // s3(64,63) of synchronized symbol spectra.
- ncandidates=ncandidates+1;
- nhard=0;
- nsoft=0;
- for (i=0; i<63; i++) {
- if(workdat[i] != rxdat[i]) {
- nhard=nhard+1;
- if(workdat[i] != rxdat2[i]) {
- nsoft=nsoft+rxprob[i];
- }
- }
- }
- nsoft=63*nsoft/nsum;
- ntotal=nsoft+nhard;
-
- getpp_(workdat,&pp);
- if(pp>pp1) {
- pp2=pp1;
- pp1=pp;
- nsoft_min=nsoft;
- nhard_min=nhard;
- ntotal_min=ntotal;
- memcpy(correct,workdat,63*sizeof(int));
- nera_best=numera;
- ntry[0]=k;
- } else {
- if(pp>pp2 && pp!=pp1) pp2=pp;
- }
- if(nhard_min <= 41 && ntotal_min <= 71) break;
- }
- if(k == ntrials) ntry[0]=k;
- }
-
- param[0]=ncandidates;
- param[1]=nhard_min;
- param[2]=nsoft_min;
- param[3]=nera_best;
- param[4]=1000.0*pp2/pp1;
- param[5]=ntotal_min;
- param[6]=ntry[0];
- param[7]=1000.0*pp2;
- param[8]=1000.0*pp1;
- if(param[0]==0) param[2]=-1;
- return;
-}
diff --git a/lib/ftrsd/init_rs.c b/lib/ftrsd/init_rs.c
deleted file mode 100644
index 4b1d1ed..0000000
--- a/lib/ftrsd/init_rs.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Initialize a RS codec
- *
- * Copyright 2002 Phil Karn, KA9Q
- * May be used under the terms of the GNU General Public License (GPL)
- */
-#include
-
-#ifdef CCSDS
-#include "ccsds.h"
-#elif defined(BIGSYM)
-#include "int.h"
-#else
-#include "char.h"
-#endif
-
-void FREE_RS(void *p){
- struct rs *rs = (struct rs *)p;
-
- free(rs->alpha_to);
- free(rs->index_of);
- free(rs->genpoly);
- free(rs);
-}
-
-/* Initialize a Reed-Solomon codec
- * symsize = symbol size, bits (1-8)
- * gfpoly = Field generator polynomial coefficients
- * fcr = first root of RS code generator polynomial, index form
- * prim = primitive element to generate polynomial roots
- * nroots = RS code generator polynomial degree (number of roots)
- */
-void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned fcr,unsigned prim,
- unsigned int nroots){
- struct rs *rs;
- int i, j, sr,root,iprim;
-
- if(symsize > 8*sizeof(DTYPE))
- return NULL; /* Need version with ints rather than chars */
-
- if(fcr >= (1<= (1<= (1<mm = symsize;
- rs->nn = (1<alpha_to = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
- if(rs->alpha_to == NULL){
- free(rs);
- return NULL;
- }
- rs->index_of = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
- if(rs->index_of == NULL){
- free(rs->alpha_to);
- free(rs);
- return NULL;
- }
-
- /* Generate Galois field lookup tables */
- rs->index_of[0] = A0; /* log(zero) = -inf */
- rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */
- sr = 1;
- for(i=0;inn;i++){
- rs->index_of[sr] = i;
- rs->alpha_to[i] = sr;
- sr <<= 1;
- if(sr & (1<nn;
- }
- if(sr != 1){
- /* field generator polynomial is not primitive! */
- free(rs->alpha_to);
- free(rs->index_of);
- free(rs);
- return NULL;
- }
-
- /* Form RS code generator polynomial from its roots */
- rs->genpoly = (DTYPE *)malloc(sizeof(DTYPE)*(nroots+1));
- if(rs->genpoly == NULL){
- free(rs->alpha_to);
- free(rs->index_of);
- free(rs);
- return NULL;
- }
- rs->fcr = fcr;
- rs->prim = prim;
- rs->nroots = nroots;
-
- /* Find prim-th root of 1, used in decoding */
- for(iprim=1;(iprim % prim) != 0;iprim += rs->nn)
- ;
- rs->iprim = iprim / prim;
-
- rs->genpoly[0] = 1;
- for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) {
- rs->genpoly[i+1] = 1;
-
- /* Multiply rs->genpoly[] by @**(root + x) */
- for (j = i; j > 0; j--){
- if (rs->genpoly[j] != 0)
- rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
- else
- rs->genpoly[j] = rs->genpoly[j-1];
- }
- /* rs->genpoly[0] can never be zero */
- rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
- }
- /* convert rs->genpoly[] to index form for quicker encoding */
- for (i = 0; i <= nroots; i++)
- rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
-
- return rs;
-}
diff --git a/lib/ftrsd/int.h b/lib/ftrsd/int.h
deleted file mode 100644
index ada5bfd..0000000
--- a/lib/ftrsd/int.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Include file to configure the RS codec for integer symbols
- *
- * Copyright 2002, Phil Karn, KA9Q
- * May be used under the terms of the GNU General Public License (GPL)
- */
-#define DTYPE int
-
-/* Reed-Solomon codec control block */
-struct rs {
- unsigned int mm; /* Bits per symbol */
- unsigned int nn; /* Symbols per block (= (1<= rs->nn) {
- x -= rs->nn;
- x = (x >> rs->mm) + (x & rs->nn);
- }
- return x;
-}
-#define MODNN(x) modnn(rs,x)
-
-#define MM (rs->mm)
-#define NN (rs->nn)
-#define ALPHA_TO (rs->alpha_to)
-#define INDEX_OF (rs->index_of)
-#define GENPOLY (rs->genpoly)
-#define NROOTS (rs->nroots)
-#define FCR (rs->fcr)
-#define PRIM (rs->prim)
-#define IPRIM (rs->iprim)
-#define A0 (NN)
-
-#define ENCODE_RS encode_rs_int
-#define DECODE_RS decode_rs_int
-#define INIT_RS init_rs_int
-#define FREE_RS free_rs_int
-
-void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
-int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras, int calc_syn);
-void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
- unsigned int prim,unsigned int nroots);
-void FREE_RS(void *p);
-
-
-
-
diff --git a/lib/ftrsd/rs2.h b/lib/ftrsd/rs2.h
deleted file mode 100644
index c2b807d..0000000
--- a/lib/ftrsd/rs2.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* User include file for the Reed-Solomon codec
- * Copyright 2002, Phil Karn KA9Q
- * May be used under the terms of the GNU General Public License (GPL)
- */
-
-/* General purpose RS codec, integer symbols */
-void encode_rs_int(void *rs,int *data,int *parity);
-int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras, int calc_syn);
-void *init_rs_int(int symsize,int gfpoly,int fcr,
- int prim,int nroots,int pad);
-void free_rs_int(void *rs);
-
-/* Tables to map from conventional->dual (Taltab) and
- * dual->conventional (Tal1tab) bases
- */
-extern unsigned char Taltab[],Tal1tab[];
diff --git a/lib/ftrsd/rsdtest.f90 b/lib/ftrsd/rsdtest.f90
deleted file mode 100644
index 2c862e5..0000000
--- a/lib/ftrsd/rsdtest.f90
+++ /dev/null
@@ -1,34 +0,0 @@
-program rsdtest
-
- real s3(64,63)
- character msg*22,arg*12
- integer param(0:7)
-
- nargs=iargc()
- if(nargs.ne.2) then
- print*,'Usage: rsdtest ntrials nfiles'
- go to 999
- endif
- call getarg(1,arg)
- read(arg,*) ntrials
- call getarg(2,arg)
- read(arg,*) nfiles
-
- open(10,file='s3_1000.bin',access='stream', status='old')
- open(22,file='kvasd.dat',access='direct',recl=1024,status='unknown')
-
- nadd=1
- ifile0=0
- if(nfiles.lt.0) then
- ifile0=-nfiles
- nfiles=99999
- endif
-
- do ifile=1,nfiles
- read(10,end=999) s3
- if(ifile.lt.ifile0) cycle
- call extract2(s3,nadd,ntrials,param,msg)
- if(ifile.eq.ifile0) exit
- enddo
-
-999 end program rsdtest
diff --git a/lib/ftrsd/sfrsd.c b/lib/ftrsd/sfrsd.c
deleted file mode 100644
index e64dfc9..0000000
--- a/lib/ftrsd/sfrsd.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- sfrsd.c
-
- A soft-decision decoder for the JT65 (63,12) Reed-Solomon code.
-
- This decoding scheme is built around Phil Karn's Berlekamp-Massey
- errors and erasures decoder. The approach is inspired by a number of
- publications, including the stochastic Chase decoder described
- in "Stochastic Chase Decoding of Reed-Solomon Codes", by Leroux et al.,
- IEEE Communications Letters, Vol. 14, No. 9, September 2010 and
- "Soft-Decision Decoding of Reed-Solomon Codes Using Successive Error-
- and-Erasure Decoding," by Soo-Woong Lee and B. V. K. Vijaya Kumar.
-
- Steve Franke K9AN, Urbana IL, September 2015
- */
-
-#include
-#include
-#include
-#include
-#include
-#include "sfrsd2.h"
-
-//***************************************************************************
-void usage(void)
-{
- printf("Usage: sfrsd [options...] \n");
- printf(" input file should be in kvasd format\n");
- printf("\n");
- printf("Options:\n");
- printf(" -n number of random erasure vectors to try\n");
- printf(" -v verbose\n");
-}
-
-int main(int argc, char *argv[]){
-
- extern char *optarg;
- extern int optind;
-
- int correct[63], indx[63], param[8];
- int c,i;
- char *infile;
-
- FILE *datfile, *logfile;
- int nsec, maxe, nads;
- float xlambda;
- int mrsym[63],mrprob[63],mr2sym[63],mr2prob[63];
- int nsec2,ncount,dat4[12];
- int ntrials, nverbose, ntry;
- int nhard;
- double tt;
-
- ntrials=10000;
- nverbose=1;
-
- while ( (c = getopt(argc, argv, "n:qv")) !=-1 ) {
- switch (c) {
- case 'n':
- ntrials=(int)strtof(optarg,NULL);
- printf("ntrials set to %d\n",ntrials);
- break;
- case 'v':
- nverbose=1;
- break;
- case 'q': //accept (and ignore) -q option for WSJT10 compatibility
- break;
- case '?':
- usage();
- exit(1);
- }
- }
-
- if( optind+1 > argc) {
- // usage();
- // exit(1);
- infile="kvasd.dat";
- } else {
- infile=argv[optind];
- }
-
- logfile=fopen("/tmp/sfrsd.log","a");
- if( !logfile ) {
- printf("Unable to open sfrsd.log\n");
- exit(1);
- }
-
- datfile=fopen(infile,"rb");
- if( !datfile ) {
- printf("Unable to open kvasd.dat\n");
- exit(1);
- } else {
- fread(&nsec,sizeof(int),1,datfile);
- fread(&xlambda,sizeof(float),1,datfile);
- fread(&maxe,sizeof(int),1,datfile);
- fread(&nads,sizeof(int),1,datfile);
- fread(&mrsym,sizeof(int),63,datfile);
- fread(&mrprob,sizeof(int),63,datfile);
- fread(&mr2sym,sizeof(int),63,datfile);
- fread(&mr2prob,sizeof(int),63,datfile);
- fread(&nsec2,sizeof(int),1,datfile);
- fread(&ncount,sizeof(int),1,datfile);
- fread(&dat4,sizeof(int),12,datfile);
- fclose(datfile);
- }
-
- sfrsd2_(mrsym,mrprob,mr2sym,mr2prob,&ntrials,&nverbose,correct,param,indx,&tt,&ntry);
- nhard=param[1];
- if( nhard>=0 ) {
- for (i=0; i<12; i++) {
- dat4[i]=correct[11-i];
- }
- } else {
- nhard=-1;
- memset(dat4,0,12*sizeof(int));
- }
- datfile=fopen(infile,"wb");
- if( !datfile ) {
- printf("Unable to open kvasd.dat\n");
- return 1;
- } else {
- fwrite(&nsec,sizeof(int),1,datfile);
- fwrite(&xlambda,sizeof(float),1,datfile);
- fwrite(&maxe,sizeof(int),1,datfile);
- fwrite(&nads,sizeof(int),1,datfile);
- fwrite(&mrsym,sizeof(int),63,datfile);
- fwrite(&mrprob,sizeof(int),63,datfile);
- fwrite(&mr2sym,sizeof(int),63,datfile);
- fwrite(&mr2prob,sizeof(int),63,datfile);
- fwrite(&nsec2,sizeof(int),1,datfile);
- fwrite(&nhard,sizeof(int),1,datfile);
- fwrite(&dat4,sizeof(int),12,datfile);
- fclose(datfile);
- }
- exit(0);
-}
-
-
diff --git a/lib/ftrsd/sfrsd2.h b/lib/ftrsd/sfrsd2.h
deleted file mode 100644
index 4ef7ab4..0000000
--- a/lib/ftrsd/sfrsd2.h
+++ /dev/null
@@ -1,3 +0,0 @@
-void ftrsd2_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
- int* ntrials0, int* verbose0, int correct[], int param[],
- int indexes[], double tt[], int ntry[]);
diff --git a/lib/ftrsd/sfrsd3.c b/lib/ftrsd/sfrsd3.c
deleted file mode 100644
index f117dcc..0000000
--- a/lib/ftrsd/sfrsd3.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- sfrsd2.c
-
- A soft-decision decoder for the JT65 (63,12) Reed-Solomon code.
-
- This decoding scheme is built around Phil Karn's Berlekamp-Massey
- errors and erasures decoder. The approach is inspired by a number of
- publications, including the stochastic Chase decoder described
- in "Stochastic Chase Decoding of Reed-Solomon Codes", by Leroux et al.,
- IEEE Communications Letters, Vol. 14, No. 9, September 2010 and
- "Soft-Decision Decoding of Reed-Solomon Codes Using Successive Error-
- and-Erasure Decoding," by Soo-Woong Lee and B. V. K. Vijaya Kumar.
-
- Steve Franke K9AN and Joe Taylor K1JT
- */
-
-#include
-#include
-#include
-#include
-#include
-#include "rs2.h"
-
-static void *rs;
-
-void sfrsd2_(int mrsym[], int mrprob[], int mr2sym[], int mr2prob[],
- int* ntrials0, int* verbose0, int correct[], int param[],
- int indexes[], double tt[], int ntry[])
-{
- int rxdat[63], rxprob[63], rxdat2[63], rxprob2[63];
- int workdat[63],workdat2[63];
- int era_pos[51];
- int c, i, j, numera, nmr2, nerr, nn=63, kk=12;
- FILE *datfile, *logfile;
- int ntrials = *ntrials0;
- int verbose = *verbose0;
- int nhard=0,nhard_min=32768,nsoft=0,nsoft_min=32768, ncandidates;
- int ngmd,nera_best;
- clock_t t0=0,t1=0;
- int perr[8][8] = {
- 12, 31, 44, 52, 60, 57, 50, 50,
- 28, 38, 49, 58, 65, 69, 64, 80,
- 40, 41, 53, 62, 66, 73, 76, 81,
- 50, 53, 53, 64, 70, 76, 77, 81,
- 50, 50, 52, 60, 71, 72, 77, 84,
- 50, 50, 56, 62, 67, 73, 81, 85,
- 50, 50, 71, 62, 70, 77, 80, 85,
- 50, 50, 62, 64, 71, 75, 82, 87};
-
- int pmr2[8][8] = {
- 4, 8, 9, 7, 6, 0, 0, 0,
- 13, 18, 15, 11, 9, 7, 5, 0,
- 0, 23, 21, 15, 12, 10, 7, 4,
- 0, 34, 28, 20, 16, 14, 11, 7,
- 0, 20, 26, 25, 19, 14, 12, 9,
- 0, 0, 28, 27, 22, 19, 14, 11,
- 0, 0, 40, 29, 29, 23, 18, 12,
- 0, 0, 40, 35, 31, 21, 20, 13};
-
- if(verbose) {
- logfile=fopen("sfrsd.log","a");
- if( !logfile ) {
- printf("Unable to open sfrsd.log\n");
- exit(1);
- }
- }
-
-// Initialize the KA9Q Reed-Solomon encoder/decoder
- unsigned int symsize=6, gfpoly=0x43, fcr=3, prim=1, nroots=51;
- rs=init_rs_int(symsize, gfpoly, fcr, prim, nroots, 0);
-
-// Reverse the received symbol vector for BM decoder
- for (i=0; i<63; i++) {
- rxdat[i]=mrsym[62-i];
- rxprob[i]=mrprob[62-i];
- rxdat2[i]=mr2sym[62-i];
- rxprob2[i]=mr2prob[62-i];
- }
-
-// Sort the mrsym probabilities to find the least reliable symbols
- int k, pass, tmp, nsym=63;
- int probs[63];
- for (i=0; i<63; i++) {
- indexes[i]=i;
- probs[i]=rxprob[i];
- }
- for (pass = 1; pass <= nsym-1; pass++) {
- for (k = 0; k < nsym - pass; k++) {
- if( probs[k] < probs[k+1] ) {
- tmp = probs[k];
- probs[k] = probs[k+1];
- probs[k+1] = tmp;
- tmp = indexes[k];
- indexes[k] = indexes[k+1];
- indexes[k+1] = tmp;
- }
- }
- }
-
-// See if we can decode using BM HDD, and calculate the syndrome vector.
- memset(era_pos,0,51*sizeof(int));
- numera=0;
- memcpy(workdat,rxdat,sizeof(rxdat));
- nerr=decode_rs_int(rs,workdat,era_pos,numera,1);
- if( nerr >= 0 ) {
- if(verbose) fprintf(logfile," BM decode nerrors= %3d : ",nerr);
- memcpy(correct,workdat,63*sizeof(int));
- ngmd=-1;
- param[0]=0;
- param[1]=0;
- param[2]=0;
- param[3]=0;
- param[4]=0;
- return;
- }
-
-/*
-Generate random erasure-locator vectors and see if any of them
-decode. This will generate a list of potential codewords. The
-"soft" distance between each codeword and the received word is
-used to decide which codeword is "best".
-*/
-
-#ifdef WIN32
- srand(0xdeadbeef);
-#else
- srandom(0xdeadbeef);
-#endif
-
- float ratio, ratio0[63];
- int threshe, thresh2, nsum;
- int thresh0[63],thresh1[63], mr2flag;
- ncandidates=0;
- nsum=0;
- int ii,jj;
- for (i=0; i= 0 ) {
- ncandidates=ncandidates+1;
- nhard=0;
- nsoft=0;
- for (i=0; i<63; i++) {
- if(workdat[i] != rxdat[i]) {
- nhard=nhard+1;
- if(workdat[i] != rxdat2[i]) {
- nsoft=nsoft+rxprob[i];
- }
- }
- }
- nsoft=63*nsoft/nsum;
- if((nsoft < 33) && (nhard < 43) && (nhard+nsoft) < 74) { //???
- if( (nsoft < nsoft_min) ) {
- nsoft_min=nsoft;
- nhard_min=nhard;
- memcpy(correct,workdat,63*sizeof(int));
- ngmd=0;
- nera_best=numera;
- ntry[0]=k;
- }
- }
- if(nsoft_min < 27) break;
- if((nsoft_min < 32) && (nhard_min < 43) &&
- (nhard_min+nsoft_min) < 74) break;
- }
- if(k == ntrials-1) ntry[0]=k+1;
- }
-
- if(verbose) fprintf(logfile,
- "%d trials and %d candidates after stochastic loop\n",k,ncandidates);
-
- if( (ncandidates >= 0) && (nsoft_min < 36) && (nhard_min < 44) ) {
- if(verbose) {
- for (i=0; i<63; i++) {
- fprintf(logfile,"%3d %3d %3d %3d %3d %3d\n",i,correct[i],
- rxdat[i],rxprob[i],rxdat2[i],rxprob2[i]);
- }
- fprintf(logfile,"**** ncandidates %d nhard %d nsoft %d nsum %d\n",
- ncandidates,nhard_min,nsoft_min,nsum);
- }
- } else {
- nhard_min=-1;
- }
-
- if(verbose) {
- fprintf(logfile,"exiting sfrsd\n");
- fclose(logfile);
- }
- param[0]=ncandidates;
- param[1]=nhard_min;
- param[2]=nsoft_min;
- param[3]=nera_best;
- param[4]=ngmd;
- if(param[0]==0) param[2]=-1;
- return;
-}
diff --git a/lib/g1 b/lib/g1
deleted file mode 100644
index 52f7616..0000000
--- a/lib/g1
+++ /dev/null
@@ -1,4 +0,0 @@
-gcc -c gran.c
-gfortran -c four2a.f90
-gfortran -c f77_wisdom.f90
-gfortran -o chkfft chkfft.f90 four2a.o f77_wisdom.o gran.o -lfftw3f
diff --git a/lib/g1.bat b/lib/g1.bat
deleted file mode 100644
index 6242f25..0000000
--- a/lib/g1.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-gcc -c gran.c
-gfortran -c four2a.f90
-gfortran -c f77_wisdom.f90
-gfortran -o chkfft chkfft.f90 four2a.o f77_wisdom.o gran.o /JTSDK-QT/appsupport/runtime/libfftw3f-3.dll
diff --git a/lib/g2.bat b/lib/g2.bat
deleted file mode 100644
index 4067107..0000000
--- a/lib/g2.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-gcc -c gran.c
-gfortran -c fftw3mod.f90
-gfortran -c f77_wisdom.f90
-gfortran -o chkfft2 chkfft2.f90 f77_wisdom.o gran.o /JTSDK-QT/appsupport/runtime/libfftw3f-3.dll
diff --git a/lib/g3.bat b/lib/g3.bat
deleted file mode 100644
index 904fce9..0000000
--- a/lib/g3.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-gcc -c gran.c
-gfortran -c fftw3mod.f90
-gfortran -c f77_wisdom.f90
-gfortran -o chkfft3 chkfft3.f90 f77_wisdom.o gran.o /JTSDK-QT/appsupport/runtime/libfftw3f-3.dll
diff --git a/lib/g4.bat b/lib/g4.bat
deleted file mode 100644
index 6475dad..0000000
--- a/lib/g4.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-gcc -c gran.c
-gfortran -c -Wall fftw3mod.f90
-gfortran -o timefft -Wall timefft.f90 timefft_opts.f90 gran.o libfftw3f-3.dll
diff --git a/lib/gen4.f90 b/lib/gen4.f90
deleted file mode 100644
index 7b06be8..0000000
--- a/lib/gen4.f90
+++ /dev/null
@@ -1,43 +0,0 @@
-subroutine gen4(msg0,ichk,msgsent,itone,itype)
-
-! Encode a JT4 message. Returns msgsent, the message as it will be
-! decoded, an integer array itone(206) of 4-FSK tons values in the
-! range 0-3; and itype, the JT message type.
-
- use jt4
- use packjt
- character*22 msg0
- character*22 message !Message to be generated
- character*22 msgsent !Message as it will be received
- character*1 c
- integer itone(206)
- integer*4 i4Msg6BitWords(13) !72-bit message as 6-bit words
- integer mettab(-128:127,0:1)
- save
-
- if(msg0(1:1).eq.'@') then
- read(msg0(2:5),*,end=1,err=1) nfreq
- go to 2
-1 nfreq=1000
-2 itone(1)=nfreq
- msgsent=msg0
- else
- call getmet4(mettab,ndelta)
-
- message=msg0
- call fmtmsg(message,iz)
- call packmsg(message,i4Msg6BitWords,itype,.false.) !Pack into 12 6-bit bytes
- call unpackmsg(i4Msg6BitWords,msgsent,.false.,' ') !Unpack to get msgsent
- if(ichk.ne.0) go to 999
- call encode4(message,itone) !Encode the information bits
- i1=index(message,'-')
- c=message(i1+1:i1+1)
- if(i1.ge.9 .and. c.ge.'0' .and. c.le.'3') then
- itone=2*itone + (1-npr(2:)) !Inverted '#' sync
- else
- itone=2*itone + npr(2:) !Data = MSB, sync = LSB
- endif
- endif
-
-999 return
-end subroutine gen4
diff --git a/lib/gen65.f90 b/lib/gen65.f90
deleted file mode 100644
index ab61fd3..0000000
--- a/lib/gen65.f90
+++ /dev/null
@@ -1,83 +0,0 @@
-subroutine gen65(msg0,ichk,msgsent,itone,itype)
-
-! Encodes a JT65 message to yieild itone(1:126)
-! Temporarily, does not implement EME shorthands
-
- use packjt
- character*22 msg0
- character*22 message !Message to be generated
- character*22 msgsent !Message as it will be received
- integer itone(126)
- character*3 cok !' ' or 'OOO'
- integer dgen(13)
- integer sent(63)
- integer nprc(126)
- data nprc/1,0,0,1,1,0,0,0,1,1,1,1,1,1,0,1,0,1,0,0, &
- 0,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1, &
- 0,1,1,0,1,1,1,1,0,0,0,1,1,0,1,0,1,0,1,1, &
- 0,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,1, &
- 1,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,1,1,0,1, &
- 0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1, &
- 1,1,1,1,1,1/
- save
-
- if(msg0(1:1).eq.'@') then
- read(msg0(2:5),*,end=1,err=1) nfreq
- go to 2
-1 nfreq=1000
-2 itone(1)=nfreq
- else
- message=msg0
- do i=1,22
- if(ichar(message(i:i)).eq.0) then
- message(i:)=' '
- exit
- endif
- enddo
-
- do i=1,22 !Strip leading blanks
- if(message(1:1).ne.' ') exit
- message=message(i+1:)
- enddo
-
- call chkmsg(message,cok,nspecial,flip)
- ntest=0
- if(flip.lt.0.0) ntest=1
- if(nspecial.eq.0) then
- call packmsg(message,dgen,itype,.false.) !Pack message into 72 bits
- call unpackmsg(dgen,msgsent,.false.,' ') !Unpack to get message sent
- msgsent(20:22)=cok
- call fmtmsg(msgsent,iz)
- if(ichk.ne.0) go to 999 !Return if checking only
-
- call rs_encode(dgen,sent) !Apply Reed-Solomon code
- call interleave63(sent,1) !Apply interleaving
- call graycode65(sent,63,1) !Apply Gray code
- nsym=126 !Symbols per transmission
- k=0
- do j=1,nsym
- if(nprc(j).eq.ntest) then
- k=k+1
- itone(j)=sent(k)+2
- else
- itone(j)=0
- endif
- enddo
- else
- nsym=32
- k=0
- do j=1,nsym
- do n=1,4
- k=k+1
- if(iand(j,1).eq.1) itone(k)=0
- if(iand(j,1).eq.0) itone(k)=10*nspecial
- if(k.eq.126) go to 10
- enddo
- enddo
-10 msgsent=message
- itype=7
- endif
- endif
-
-999 return
-end subroutine gen65
diff --git a/lib/gen9.f90 b/lib/gen9.f90
deleted file mode 100644
index 503ef6d..0000000
--- a/lib/gen9.f90
+++ /dev/null
@@ -1,65 +0,0 @@
-subroutine gen9(msg0,ichk,msgsent,i4tone,itype)
-
-! Encodes a JT9 message and returns msgsent, the message as it will
-! be decoded, and an integer array i4tone(85) of 9-FSK tone values
-! in the range 0-8.
-
- use packjt
- character*22 msg0
- character*22 message !Message to be generated
- character*22 msgsent !Message as it will be received
- integer*4 i4Msg6BitWords(13) !72-bit message as 6-bit words
- integer*1 i1Msg8BitBytes(13) !72 bits and zero tail as 8-bit bytes
- integer*1 i1EncodedBits(207) !Encoded information-carrying bits
- integer*1 i1ScrambledBits(207) !Encoded bits after interleaving
- integer*4 i4DataSymbols(69) !Data symbols (values 0-7)
- integer*4 i4GrayCodedSymbols(69) !Gray-coded symbols (values 0-7)
- integer*4 i4tone(85) !Tone #s, data and sync (values 0-8)
- include 'jt9sync.f90'
- save
-
- if(msg0(1:1).eq.'@') then
- read(msg0(2:5),*,end=1,err=1) nfreq
- go to 2
-1 nfreq=1000
-2 i4tone(1)=nfreq
- else
- message=msg0
- do i=1,22
- if(ichar(message(i:i)).eq.0) then
- message(i:)=' '
- exit
- endif
- enddo
-
- do i=1,22 !Strip leading blanks
- if(message(1:1).ne.' ') exit
- message=message(i+1:)
- enddo
-
- call packmsg(message,i4Msg6BitWords,itype,.false.) !Pack into 12 6-bit bytes
- call unpackmsg(i4Msg6BitWords,msgsent,.false.,' ') !Unpack to get msgsent
- if(ichk.ne.0) go to 999
- call entail(i4Msg6BitWords,i1Msg8BitBytes) !Add tail, make 8-bit bytes
- nsym2=206
- call encode232(i1Msg8BitBytes,nsym2,i1EncodedBits) !Encode K=32, r=1/2
- i1EncodedBits(207)=0
- call interleave9(i1EncodedBits,1,i1ScrambledBits) !Interleave bits
- i1ScrambledBits(207)=0
- call packbits(i1ScrambledBits,69,3,i4DataSymbols) !Pk 3-bits into words
- call graycode(i4DataSymbols,69,1,i4GrayCodedSymbols) !Apply Gray code
-
-! Insert sync symbols at ntone=0 and add 1 to the data-tone numbers.
- j=0
- do i=1,85
- if(isync(i).eq.1) then
- i4tone(i)=0
- else
- j=j+1
- i4tone(i)=i4GrayCodedSymbols(j)+1
- endif
- enddo
- endif
-
-999 return
-end subroutine gen9
diff --git a/lib/geniscat.f90 b/lib/geniscat.f90
deleted file mode 100644
index 6df6ed9..0000000
--- a/lib/geniscat.f90
+++ /dev/null
@@ -1,55 +0,0 @@
-subroutine geniscat(msg,msgsent,itone)
-
-! Generate an ISCAT waveform.
-
- parameter (NSZ=1291)
- character msg*28,msgsent*28 !Message to be transmitted
- integer imsg(30)
- integer itone(NSZ)
- real*8 sps
- character c*42
- integer icos(4) !Costas array
- data icos/0,1,3,2/
- data nsync/4/,nlen/2/,ndat/18/
- data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ /.?@-'/
-
- sps=256.d0*12000.d0/11025.d0
- nsym=int(30*12000.d0/sps)
- nblk=nsync+nlen+ndat
-
- do i=22,1,-1
- if(msg(i:i).ne.' ' .and. msg(i:i).ne.char(0)) exit
- enddo
- nmsg=i
- msglen=nmsg+1
- k=0
- kk=1
- imsg(1)=40 !Always start with BOM char: '@'
- do i=1,nmsg !Define the tone sequence
- imsg(i+1)=36 !Illegal char set to blank
- do j=1,42
- if(msg(i:i).eq.c(j:j)) imsg(i+1)=j-1
- enddo
- enddo
-
- do i=1,nsym !Total symbols in 30 s
- j=mod(i-1,nblk)+1
- if(j.le.nsync) then
- itone(i)=icos(j) !Insert 4x4 Costas array
- else if(j.gt.nsync .and. j.le.nsync+nlen) then
- itone(i)=msglen !Insert message-length indicator
- if(j.ge.nsync+2) then
- n=msglen + 5*(j-nsync-1)
- if(n.gt.41) n=n-42
- itone(i)=n
- endif
- else
- k=k+1
- kk=mod(k-1,msglen)+1
- itone(i)=imsg(kk)
- endif
- enddo
- msgsent=msg
-
- return
-end subroutine geniscat
diff --git a/lib/genmet.f90 b/lib/genmet.f90
deleted file mode 100644
index 81f2e56..0000000
--- a/lib/genmet.f90
+++ /dev/null
@@ -1,90 +0,0 @@
-program genmet
-
-! Generate metric table for M-FSK modulation.
-
- character*12 arg
- real*4 r(0:255)
- integer hist(2,-128:128)
- data hist/514*0/,idum/-1/
-
- lim(x)=min(127,max(-128,nint(scale*x)))
-
- nargs=iargc()
- if(nargs.ne.5) then
- print*,'Usage: genmet ncoh nadd m0 snr iters'
- go to 999
- endif
- call getarg(1,arg)
- read(arg,*) ncoh
- call getarg(2,arg)
- read(arg,*) nadd
- call getarg(3,arg)
- read(arg,*) m0
- call getarg(4,arg)
- read(arg,*) snr
- call getarg(5,arg)
- read(arg,*) iters
-
- ntones=2**m0
- xm0=m0
- scale=5.0
- fac=sqrt(1.0/nadd)
- s=sqrt(10.0**(0.1*snr))
- hist=0
- nerr=0
-
- call sgran()
-
- do iter=1,iters
- do i=0,ntones-1
- r(i)=0.
- do n=1,nadd
- x1=0.707*gran()
- y1=0.707*gran()
- if(i.eq.0) x1=x1+s
- if(ncoh.eq.0) r(i)=r(i) + x1*x1 + y1*y1
- if(ncoh.ne.0) r(i)=r(i) + x1
- enddo
- r(i)=fac*r(i)
- enddo
- do m=0,m0-1
- n=2**m
- r1=0.
- r2=0.
- do i=0,ntones-1
- if(iand(i,n).ne.0) r1=max(r1,r(i))
- if(iand(i,n).eq.0) r2=max(r2,r(i))
- enddo
- don=r2-r1
- doff=r1-r2
- if(don.lt.0.0) nerr=nerr+1
- j1=lim(doff)
- hist(1,j1)=hist(1,j1)+1
- j2=lim(don)
- hist(2,j2)=hist(2,j2)+1
- enddo
- enddo
-
- do i=-128,127
- write(13,1010) i/scale,hist(1,i)/(xm0*iters),hist(2,i)/(xm0*iters)
-1010 format(f8.3,2f12.9)
- enddo
-
- ber=nerr/(xm0*iters)
- write(*,1020) nadd,m0,snr,ber
-1020 format('nadd:',i3,' m0:',i2,' snr: 'f5.1,' BER:',f8.3)
-
- xln2=log(2.0)
- do i=-128,127
- p1=hist(2,i)/(xm0*iters)
- p0=hist(1,i)/(xm0*iters)
- if(p0+p1.eq.0.0 .and. i.lt.0) p0=1.e-6
- if(p0+p1.eq.0.0 .and. i.gt.0) p1=1.e-6
- xlhd0=log(max(0.001,2.0*p0/(p0+p1)))/xln2
- xlhd1=log(max(0.001,2.0*p1/(p0+p1)))/xln2
- write(14,1012) i/scale,xlhd0,xlhd1,p0/(p0+p1),p1/(p0+p1)
-1012 format(f7.1,2f8.3,2f9.6)
- enddo
-
-999 end program genmet
-
diff --git a/lib/genmsk144.f90 b/lib/genmsk144.f90
deleted file mode 100644
index 5f9ce93..0000000
--- a/lib/genmsk144.f90
+++ /dev/null
@@ -1,147 +0,0 @@
-subroutine genmsk144(msg0,mygrid,ichk,bcontest,msgsent,i4tone,itype)
-! s8 + 48bits + s8 + 80 bits = 144 bits (72ms message duration)
-!
-! Encode an MSK144 message
-! Input:
-! - msg0 requested message to be transmitted
-! - ichk if ichk=1, return only msgsent
-! if ichk.ge.10000, set imsg=ichk-10000 for short msg
-! - msgsent message as it will be decoded
-! - i4tone array of audio tone values, 0 or 1
-! - itype message type
-! 1 = standard message "Call_1 Call_2 Grid/Rpt"
-! 2 = type 1 prefix
-! 3 = type 1 suffix
-! 4 = type 2 prefix
-! 5 = type 2 suffix
-! 6 = free text (up to 13 characters)
-! 7 = short message " Rpt"
-
- use iso_c_binding, only: c_loc,c_size_t
- use packjt
- use hashing
- character*22 msg0
- character*22 message !Message to be generated
- character*22 msgsent !Message as it will be received
- character*6 mygrid
- integer*4 i4Msg6BitWords(13) !72-bit message as 6-bit words
- integer*4 i4tone(144) !
- integer*1, target:: i1Msg8BitBytes(10) !80 bits represented in 10 bytes
- integer*1 codeword(128) !Encoded bits before re-ordering
- integer*1 msgbits(80) !72-bit message + 8-bit hash
- integer*1 bitseq(144) !Tone #s, data and sync (values 0-1)
- integer*1 i1hash(4)
- integer*1 s8(8)
- logical bcontest
- real*8 pp(12)
- real*8 xi(864),xq(864),pi,twopi
- data s8/0,1,1,1,0,0,1,0/
- equivalence (ihash,i1hash)
- logical first
- data first/.true./
- save
-
- if(first) then
- first=.false.
- nsym=128
- pi=4.0*atan(1.0)
- twopi=8.*atan(1.0)
- do i=1,12
- pp(i)=sin((i-1)*pi/12)
- enddo
- endif
-
- if(msg0(1:1).eq.'@') then !Generate a fixed tone
- read(msg0(2:5),*,end=1,err=1) nfreq !at specified frequency
- go to 2
-1 nfreq=1000
-2 i4tone(1)=nfreq
- else
- message=msg0
- do i=1,22
- if(ichar(message(i:i)).eq.0) then
- message(i:)=' '
- exit
- endif
- enddo
-
- do i=1,22 !Strip leading blanks
- if(message(1:1).ne.' ') exit
- message=message(i+1:)
- enddo
-
- if(message(1:1).eq.'<') then
- call genmsk40(message,msgsent,ichk,i4tone,itype)
- if(itype.lt.0) go to 999
- i4tone(41)=-40
- go to 999
- endif
-
- call packmsg(message,i4Msg6BitWords,itype,bcontest) !Pack into 12 6-bit bytes
- call unpackmsg(i4Msg6BitWords,msgsent,bcontest,mygrid) !Unpack to get msgsent
-
- if(ichk.eq.1) go to 999
- i4=0
- ik=0
- im=0
- do i=1,12
- nn=i4Msg6BitWords(i)
- do j=1, 6
- ik=ik+1
- i4=i4+i4+iand(1,ishft(nn,j-6))
- i4=iand(i4,255)
- if(ik.eq.8) then
- im=im+1
- i1Msg8BitBytes(im)=i4
- ik=0
- endif
- enddo
- enddo
-
- ihash=nhash(c_loc(i1Msg8BitBytes),int(9,c_size_t),146)
- ihash=2*iand(ihash,32767) !Generate the 8-bit hash
- i1Msg8BitBytes(10)=i1hash(1) !Hash code to byte 10
-
- mbit=0
- do i=1, 10
- i1=i1Msg8BitBytes(i)
- do ibit=1,8
- mbit=mbit+1
- msgbits(mbit)=iand(1,ishft(i1,ibit-8))
- enddo
- enddo
-
- call encode_msk144(msgbits,codeword)
-
-!Create 144-bit channel vector:
-!8-bit sync word + 48 bits + 8-bit sync word + 80 bits
- bitseq=0
- bitseq(1:8)=s8
- bitseq(9:56)=codeword(1:48)
- bitseq(57:64)=s8
- bitseq(65:144)=codeword(49:128)
- bitseq=2*bitseq-1
-
- xq(1:6)=bitseq(1)*pp(7:12) !first bit is mapped to 1st half-symbol on q
- do i=1,71
- is=(i-1)*12+7
- xq(is:is+11)=bitseq(2*i+1)*pp
- enddo
- xq(864-5:864)=bitseq(1)*pp(1:6) !last half symbol
- do i=1,72
- is=(i-1)*12+1
- xi(is:is+11)=bitseq(2*i)*pp
- enddo
-! Map I and Q to tones.
- i4tone=0
- do i=1,72
- i4tone(2*i-1)=(bitseq(2*i)*bitseq(2*i-1)+1)/2;
- i4tone(2*i)=-(bitseq(2*i)*bitseq(mod(2*i,144)+1)-1)/2;
- enddo
- endif
-
-! Flip polarity
- i4tone=-i4tone+1
-
-999 return
-end subroutine genmsk144
diff --git a/lib/genmsk40.f90 b/lib/genmsk40.f90
deleted file mode 100644
index 3310b10..0000000
--- a/lib/genmsk40.f90
+++ /dev/null
@@ -1,66 +0,0 @@
-subroutine genmsk40(msg,msgsent,ichk,itone,itype)
-
- use hashing
- character*22 msg,msgsent,hashmsg
- character*4 crpt,rpt(0:15)
- logical first
- integer*4 itone(144)
- integer*1 message(16),codeword(32),bitseq(40)
- integer*1 s8r(8)
- data s8r/1,0,1,1,0,0,0,1/ ! Sync word is reversed wrt msk144 sync word.
- data first/.true./
- data rpt/"-03 ","+00 ","+03 ","+06 ","+10 ","+13 ","+16 ", &
- "R-03","R+00","R+03","R+06","R+10","R+13","R+16", &
- "RRR ","73 "/
- save first,rpt
-
- itype=-1
- msgsent='*** bad message ***'
- itone=0
- i1=index(msg,'>')
- if(i1.lt.9) go to 900
- call fmtmsg(msg,iz)
- crpt=msg(i1+2:i1+5)
- do i=0,15
- if(crpt.eq.rpt(i)) go to 10
- enddo
- go to 900
-
-10 irpt=i !Report index, 0-15
- if(ichk.lt.10000) then
- hashmsg=msg(2:i1-1)
- call hash(hashmsg,22,ihash)
- ihash=iand(ihash,4095) !12-bit hash
- ig=16*ihash + irpt !4-bit report
- else
- ig=ichk-10000
- endif
-
- do i=1,16
- message(i)=iand(1,ishft(ig,1-i))
- enddo
-
- call encode_msk40(message,codeword)
-! write(*,'(a6,i6,2x,a6,i6,2x,a6,i6)') ' msg: ',ig,'rprt: ',irpt,'hash: ',ihash
-! write(*,'(a6,32i1)') ' cw: ',codeword
-
- bitseq(1:8)=s8r
- bitseq(9:40)=codeword
- bitseq=2*bitseq-1
-
-! Map I and Q to tones.
- itone=0
- do i=1, 20
- itone(2*i-1)=(bitseq(2*i)*bitseq(2*i-1)+1)/2;
- itone(2*i)=-(bitseq(2*i)*bitseq(mod(2*i,40)+1)-1)/2;
- enddo
-
-! Flip polarity
- itone=-itone+1
-
- msgsent=msg
- itype=7
-
-900 return
-end subroutine genmsk40
-
diff --git a/lib/genmsk_short.f90 b/lib/genmsk_short.f90
deleted file mode 100644
index f1b555f..0000000
--- a/lib/genmsk_short.f90
+++ /dev/null
@@ -1,66 +0,0 @@
-subroutine genmsk_short(msg,msgsent,ichk,itone,itype)
-
- use hashing
- character*22 msg,msgsent
- character*3 crpt,rpt(0:7)
- logical first
- integer itone(35)
- integer ig24(0:4096-1) !Codewords for Golay (24,12) code
- integer b11(11)
- data b11/1,1,1,0,0,0,1,0,0,1,0/ !Barker 11 code
- data rpt /'26 ','27 ','28 ','R26','R27','R28','RRR','73 '/
- data first/.true./
- save first,ig24
-
- if(first) then
- call golay24_table(ig24) !Define the Golay(24,12) codewords
- first=.false.
- endif
-
- itype=-1
- msgsent='*** bad message ***'
- itone=0
- i1=index(msg,'>')
- if(i1.lt.9) go to 900
- call fmtmsg(msg,iz)
- crpt=msg(i1+2:i1+5)
- do i=0,7
- if(crpt.eq.rpt(i)) go to 10
- enddo
- go to 900
-
-10 irpt=i !Report index, 0-7
- if(ichk.lt.10000) then
- call hash(msg(2:i1-1),i1-2,ihash)
- ihash=iand(ihash,511) !9-bit hash for the two callsigns
- ig=8*ihash + irpt !12-bit message information
- else
- ig=ichk-10000
- endif
- ncodeword=ig24(ig)
- itone(1:11)=b11 !Insert the Barker-11 code
- n=2**24
- do i=12,35 !Insert codeword into itone array
- n=n/2
- itone(i)=0
- if(iand(ncodeword,n).ne.0) itone(i)=1
- enddo
- msgsent=msg
- itype=7
-
- n=count(itone(1:35).eq.0)
- if(mod(n,2).ne.0) stop 'Parity error in genmsk_short.'
-
-900 return
-end subroutine genmsk_short
-
-subroutine hash_calls(calls,ih9)
-
- use hashing
- character*(*) calls
- i1=index(calls,'>')
- call hash(calls(2:i1-1),i1-2,ih9)
- ih9=iand(ih9,511) !9-bit hash for the two callsigns
-
- return
-end subroutine hash_calls
diff --git a/lib/genqra64.f90 b/lib/genqra64.f90
deleted file mode 100644
index f1bc9bf..0000000
--- a/lib/genqra64.f90
+++ /dev/null
@@ -1,57 +0,0 @@
-subroutine genqra64(msg0,ichk,msgsent,itone,itype)
-
-! Encodes a QRA64 message to yield itone(1:84)
-
- use packjt
- character*22 msg0
- character*22 message !Message to be generated
- character*22 msgsent !Message as it will be received
- integer itone(84)
- character*3 cok !' ' or 'OOO'
- logical old_qra_sync
- integer dgen(13)
- integer sent(63)
- integer icos7(0:6)
- data icos7/4,2,5,6,1,3,0/ !Costas 7x7 tone pattern
- save
-
- if(msg0(1:1).eq.'@') then
- read(msg0(2:5),*,end=1,err=1) nfreq
- go to 2
-1 nfreq=1000
-2 itone(1)=nfreq
- write(msgsent,1000) nfreq
-1000 format(i5,' Hz')
- else
- message=msg0
- do i=1,22
- if(ichar(message(i:i)).eq.0) then
- message(i:)=' '
- exit
- endif
- enddo
-
- do i=1,22 !Strip leading blanks
- if(message(1:1).ne.' ') exit
- message=message(i+1:)
- enddo
-
- call chkmsg(message,cok,nspecial,flip)
- call packmsg(message,dgen,itype,.false.) !Pack message into 72 bits
- call unpackmsg(dgen,msgsent,.false.,' ') !Unpack to get message sent
- if(ichk.ne.0) go to 999 !Return if checking only
- call qra64_enc(dgen,sent) !Encode using QRA64
-
- nsync=10
- inquire(file='old_qra_sync',exist=old_qra_sync)
- if(old_qra_sync) nsync=1
-
- itone(1:7)=nsync*icos7 !Insert 7x7 Costas array in 3 places
- itone(8:39)=sent(1:32)
- itone(40:46)=nsync*icos7
- itone(47:77)=sent(33:63)
- itone(78:84)=nsync*icos7
- endif
-
-999 return
-end subroutine genqra64
diff --git a/lib/genwspr.f90 b/lib/genwspr.f90
deleted file mode 100644
index d1d5183..0000000
--- a/lib/genwspr.f90
+++ /dev/null
@@ -1,30 +0,0 @@
-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
- 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
diff --git a/lib/hspec.f90 b/lib/hspec.f90
deleted file mode 100644
index 4ede506..0000000
--- a/lib/hspec.f90
+++ /dev/null
@@ -1,106 +0,0 @@
-subroutine hspec(id2,k,nutc0,ntrpdepth,nrxfreq,ntol,bmsk144,bcontest, &
- btrain,pcoeffs,ingain,mycall,hiscall,bshmsg,bswl,datadir,green,s, &
- jh,pxmax,dbNoGain,line1,mygrid)
-
-! Input:
-! k pointer to the most recent new data
-! nutc0 UTC for display of decode(s)
-! ntrpdepth TR period and 1000*ndepth
-! nrxfreq Rx audio center frequency
-! ntol Decoding range is +/- ntol
-! bmsk144 Boolean, true if in MSK144 mode
-! btrain Boolean, turns on training in MSK144 mode
-! ingain Relative gain for spectra
-
-! Output:
-! green() power
-! s() spectrum for horizontal spectrogram
-! jh index of most recent data in green(), s()
-
- parameter (JZ=703)
- character*80 line1
- character*512 datadir
- character*12 mycall,hiscall
- character*6 mygrid
- integer*2 id2(0:120*12000-1)
- logical*1 bmsk144,bcontest,bshmsg,btrain,bswl
- real green(0:JZ-1)
- real s(0:63,0:JZ-1)
- real x(512)
- real*8 pcoeffs(5)
- complex cx(0:256)
- data rms/999.0/,k0/99999999/
- equivalence (x,cx)
- save ja,rms0
-
- ndepth=ntrpdepth/1000
- ntrperiod=ntrpdepth - 1000*ndepth
- gain=10.0**(0.1*ingain)
- nfft=512
- nstep=nfft
- nblks=7
- if(ntrperiod.lt.30) then
- nstep=256
- nblks=14
- endif
-
- if(k.gt.30*12000) go to 900
- if(k.lt.nfft) then
- jh=0
- go to 900 !Wait for enough samples to start
- endif
-
- if(k.lt.k0) then !Start a new data block
- ja=-nstep
- jh=-1
- rms0=0.0
- endif
-
- pxmax = 0;
- do iblk=1,nblks
- if(jh.lt.JZ-1) jh=jh+1
- ja=ja+nstep
- jb=ja+nfft-1
- x=id2(ja:jb)
- sq=dot_product(x,x)
- xmax = maxval(x);
- xmin = abs(minval(x));
- if (xmin > xmax) xmax = xmin;
- if (xmax.gt.0.0) pxmax=20.0*log10(xmax);
- rms=sqrt(gain*sq/nfft)
- rms2=sqrt(sq/nfft);
- green(jh)=0.
- if(rms.gt.0.0) then
- green(jh)=20.0*log10(rms)
- dbNoGain=20.0*log10(rms2);
- endif
- call four2a(x,nfft,1,-1,0) !Real-to-complex FFT
- df=12000.0/nfft
- fac=(1.0/nfft)**2
- do i=1,64
- j=2*i
- sx=real(cx(j))**2 + aimag(cx(j))**2 + real(cx(j-1))**2 + &
- aimag(cx(j-1))**2
- s(i-1,jh)=fac*gain*sx
- enddo
- if(ja+2*nfft.gt.k) exit
- enddo
- k0=k
-
- if(bmsk144) then
- if(k.ge.7168) then
- tsec=(k-7168)/12000.0
- k0=k-7168
- tt1=sum(float(abs(id2(k0:k0+3583))))
- k0=k-3584
- tt2=sum(float(abs(id2(k0:k0+3583))))
- if(tt1.ne.0.0 .and. tt2.ne.0) then
- call mskrtd(id2(k-7168+1:k),nutc0,tsec,ntol,nrxfreq,ndepth, &
- mycall,mygrid,hiscall,bshmsg,bcontest,btrain,pcoeffs,bswl,&
- datadir,line1)
- endif
- endif
- endif
-
-900 return
-end subroutine hspec
diff --git a/lib/js8/baselinejs8.f90 b/lib/js8/baselinejs8.f90
new file mode 100644
index 0000000..79f4003
--- /dev/null
+++ b/lib/js8/baselinejs8.f90
@@ -0,0 +1,51 @@
+subroutine baselinejs8(s,nfa,nfb,sbase)
+
+! Fit baseline to spectrum (for FT8)
+! Input: s(npts) Linear scale in power
+! Output: sbase(npts) Baseline
+
+ implicit real*8 (a-h,o-z)
+
+ !include 'js8_params.f90'
+
+ real*4 s(NSPS)
+ real*4 sbase(NSPS)
+ real*4 base
+ real*8 x(1000),y(1000),a(5)
+ data nseg/10/,npct/10/
+
+ df=12000.0/(NSPS*2.0d0) !3.125 Hz
+ ia=max(1,nint(nfa/df))
+ ib=nint(nfb/df)
+ do i=ia,ib
+ s(i)=10.0*log10(s(i)) !Convert to dB scale
+ enddo
+
+ nterms=5
+ nlen=(ib-ia+1)/nseg !Length of test segment
+ i0=(ib-ia+1)/2 !Midpoint
+ k=0
+ do n=1,nseg !Loop over all segments
+ ja=ia + (n-1)*nlen
+ jb=ja+nlen-1
+ call pctile(s(ja),nlen,npct,base) !Find lowest npct of points
+ do i=ja,jb
+ if(s(i).le.base) then
+ if (k.lt.1000) k=k+1 !Save all "lower envelope" points
+ x(k)=i-i0
+ y(k)=s(i)
+ endif
+ enddo
+ enddo
+ kz=k
+ a=0.
+ call polyfit(x,y,y,kz,nterms,0,a,chisqr) !Fit a low-order polynomial
+ do i=ia,ib
+ t=i-i0
+ sbase(i)=a(1)+t*(a(2)+t*(a(3)+t*(a(4)+t*(a(5))))) + 0.65
+! write(51,3051) i*df,s(i),sbase(i)
+!3051 format(3f12.3)
+ enddo
+
+ return
+end subroutine baselinejs8
diff --git a/lib/js8/costas/Costas_essense_N=7.txt b/lib/js8/costas/Costas_essense_N=7.txt
new file mode 100644
index 0000000..b99cc8b
--- /dev/null
+++ b/lib/js8/costas/Costas_essense_N=7.txt
@@ -0,0 +1,30 @@
+ 0 1 5 3 6 2 4
+ 0 1 6 3 5 4 2
+ 0 1 6 4 3 5 2
+ 0 2 5 1 6 3 4
+ 0 2 5 1 6 4 3
+ 0 2 6 5 3 4 1
+ 0 3 4 2 6 5 1
+ 0 3 4 6 1 5 2
+ 0 3 5 4 2 6 1
+ 0 4 2 5 6 1 3
+ 0 4 6 5 2 3 1
+ 0 5 4 6 2 3 1
+ 0 6 2 3 5 4 1
+ 1 0 4 6 2 5 3
+ 1 0 5 3 6 2 4
+ 1 2 4 0 6 5 3
+ 1 3 2 5 6 0 4
+ 1 3 4 0 6 5 2
+ 1 3 6 2 0 5 4
+ 1 4 0 5 6 3 2
+ 1 4 0 6 5 2 3
+ 1 4 5 0 2 6 3
+ 1 4 5 3 0 6 2
+ 1 4 6 0 5 2 3
+ 1 4 6 0 5 3 2
+ 1 5 0 2 3 6 4
+ 1 5 6 0 3 2 4
+ 2 1 4 6 0 5 3
+ 2 3 0 6 5 1 4
+ 2 5 0 6 4 1 3
diff --git a/lib/js8/costas/Costas_symmetrical_N=7.txt b/lib/js8/costas/Costas_symmetrical_N=7.txt
new file mode 100644
index 0000000..7e38271
--- /dev/null
+++ b/lib/js8/costas/Costas_symmetrical_N=7.txt
@@ -0,0 +1,10 @@
+ 0 1 5 3 6 2 4
+ 0 1 6 3 5 4 2
+ 0 1 6 4 3 5 2
+ 0 6 2 3 5 4 1
+ 1 0 4 6 2 5 3
+ 1 0 5 3 6 2 4
+ 1 4 5 0 2 6 3
+ 1 4 5 3 0 6 2
+ 1 5 0 2 3 6 4
+ 2 5 0 6 4 1 3
diff --git a/lib/js8/costas/Sorted_Costas_arrays_N=7.txt b/lib/js8/costas/Sorted_Costas_arrays_N=7.txt
new file mode 100644
index 0000000..b547377
--- /dev/null
+++ b/lib/js8/costas/Sorted_Costas_arrays_N=7.txt
@@ -0,0 +1,201 @@
+ 7 200
+ 0 1 5 3 6 2 4
+ 0 1 6 3 5 4 2
+ 0 1 6 4 3 5 2
+ 0 2 5 1 6 3 4
+ 0 2 5 1 6 4 3
+ 0 2 6 5 3 4 1
+ 0 3 1 5 6 2 4
+ 0 3 1 6 5 2 4
+ 0 3 4 2 6 5 1
+ 0 3 4 6 1 5 2
+ 0 3 5 4 2 6 1
+ 0 4 2 5 6 1 3
+ 0 4 6 1 2 5 3
+ 0 4 6 5 2 3 1
+ 0 5 2 6 1 3 4
+ 0 5 4 6 2 3 1
+ 0 6 1 4 5 3 2
+ 0 6 2 3 5 4 1
+ 0 6 3 1 2 5 4
+ 0 6 4 1 3 2 5
+ 0 6 4 5 1 3 2
+ 0 6 4 5 2 1 3
+ 1 0 4 6 2 5 3
+ 1 0 5 3 6 2 4
+ 1 2 4 0 6 5 3
+ 1 3 2 5 6 0 4
+ 1 3 2 5 6 4 0
+ 1 3 2 6 4 5 0
+ 1 3 4 0 6 5 2
+ 1 3 6 2 0 5 4
+ 1 4 0 5 6 3 2
+ 1 4 0 6 5 2 3
+ 1 4 3 5 2 0 6
+ 1 4 3 5 6 2 0
+ 1 4 5 0 2 6 3
+ 1 4 5 3 0 6 2
+ 1 4 5 3 2 6 0
+ 1 4 6 0 5 2 3
+ 1 4 6 0 5 3 2
+ 1 5 0 2 3 6 4
+ 1 5 6 0 3 2 4
+ 1 5 6 2 4 3 0
+ 1 6 2 4 5 3 0
+ 1 6 4 5 0 3 2
+ 2 0 3 4 6 1 5
+ 2 0 5 6 1 4 3
+ 2 0 6 5 1 3 4
+ 2 1 4 0 5 6 3
+ 2 1 4 5 0 6 3
+ 2 1 4 5 3 0 6
+ 2 1 4 6 0 5 3
+ 2 1 6 4 0 3 5
+ 2 1 6 4 5 0 3
+ 2 3 0 5 1 4 6
+ 2 3 0 5 4 6 1
+ 2 3 0 6 5 1 4
+ 2 3 1 5 4 6 0
+ 2 3 5 0 4 1 6
+ 2 3 5 0 6 4 1
+ 2 3 5 1 0 6 4
+ 2 3 5 4 1 6 0
+ 2 3 6 5 0 4 1
+ 2 4 0 1 5 3 6
+ 2 4 0 3 1 5 6
+ 2 4 0 3 1 6 5
+ 2 4 1 0 5 3 6
+ 2 4 1 5 6 0 3
+ 2 4 1 6 5 0 3
+ 2 4 3 6 0 1 5
+ 2 4 5 3 6 1 0
+ 2 5 0 1 6 4 3
+ 2 5 0 6 4 1 3
+ 2 5 1 0 6 3 4
+ 2 5 1 6 4 3 0
+ 2 5 3 4 6 1 0
+ 2 5 6 0 4 1 3
+ 2 5 6 0 4 3 1
+ 2 5 6 1 3 0 4
+ 2 6 0 1 4 3 5
+ 2 6 0 3 5 4 1
+ 2 6 3 5 0 1 4
+ 3 0 1 6 2 5 4
+ 3 0 4 6 1 2 5
+ 3 0 5 4 6 1 2
+ 3 0 5 6 1 4 2
+ 3 0 6 1 2 5 4
+ 3 0 6 5 1 4 2
+ 3 1 0 6 2 4 5
+ 3 1 2 5 4 6 0
+ 3 1 4 0 2 6 5
+ 3 1 4 0 6 5 2
+ 3 1 4 5 0 2 6
+ 3 1 4 6 0 5 2
+ 3 1 6 0 2 5 4
+ 3 1 6 5 2 4 0
+ 3 2 0 5 1 4 6
+ 3 2 0 5 6 1 4
+ 3 2 5 0 1 6 4
+ 3 2 5 0 6 4 1
+ 3 2 5 6 0 4 1
+ 3 4 1 0 6 2 5
+ 3 4 1 6 0 2 5
+ 3 4 1 6 5 0 2
+ 3 4 6 1 0 5 2
+ 3 4 6 1 5 2 0
+ 3 5 0 1 4 2 6
+ 3 5 0 6 4 1 2
+ 3 5 2 0 6 1 4
+ 3 5 2 1 6 4 0
+ 3 5 2 6 0 1 4
+ 3 5 2 6 4 0 1
+ 3 5 4 1 2 0 6
+ 3 5 6 0 4 2 1
+ 3 6 0 1 5 2 4
+ 3 6 0 5 4 1 2
+ 3 6 1 0 5 2 4
+ 3 6 1 2 0 5 4
+ 3 6 2 0 5 4 1
+ 3 6 5 0 4 1 2
+ 4 0 3 1 6 5 2
+ 4 0 6 3 1 2 5
+ 4 0 6 5 2 3 1
+ 4 1 0 5 3 6 2
+ 4 1 0 6 2 3 5
+ 4 1 0 6 2 5 3
+ 4 1 3 2 0 5 6
+ 4 1 5 0 2 3 6
+ 4 1 5 6 0 3 2
+ 4 1 6 0 2 5 3
+ 4 1 6 5 0 2 3
+ 4 2 1 3 0 5 6
+ 4 2 3 0 6 5 1
+ 4 2 5 0 1 6 3
+ 4 2 5 1 0 6 3
+ 4 2 5 6 1 3 0
+ 4 2 6 3 5 0 1
+ 4 2 6 3 5 1 0
+ 4 2 6 5 1 3 0
+ 4 3 0 1 6 2 5
+ 4 3 1 2 5 0 6
+ 4 3 1 5 6 0 2
+ 4 3 1 6 0 2 5
+ 4 3 1 6 2 5 0
+ 4 3 5 1 2 0 6
+ 4 3 6 0 1 5 2
+ 4 3 6 1 2 0 5
+ 4 3 6 1 5 2 0
+ 4 5 0 2 1 6 3
+ 4 5 0 2 6 3 1
+ 4 5 2 0 6 1 3
+ 4 5 2 1 3 6 0
+ 4 5 2 1 6 0 3
+ 4 5 2 6 1 0 3
+ 4 6 0 1 5 3 2
+ 4 6 1 0 5 2 3
+ 4 6 3 2 0 5 1
+ 5 0 2 1 6 3 4
+ 5 0 4 2 1 3 6
+ 5 1 0 4 2 3 6
+ 5 1 0 6 3 4 2
+ 5 1 6 4 3 0 2
+ 5 2 0 6 1 3 4
+ 5 2 0 6 1 4 3
+ 5 2 1 3 4 0 6
+ 5 2 1 3 6 0 4
+ 5 2 1 6 4 0 3
+ 5 2 3 1 0 4 6
+ 5 2 3 1 4 6 0
+ 5 2 6 0 1 4 3
+ 5 2 6 1 0 3 4
+ 5 3 0 4 6 1 2
+ 5 3 2 6 0 1 4
+ 5 3 4 0 2 1 6
+ 5 3 4 1 0 2 6
+ 5 3 4 1 0 6 2
+ 5 4 2 6 0 1 3
+ 5 6 1 3 0 4 2
+ 5 6 2 0 4 1 3
+ 6 0 2 1 4 5 3
+ 6 0 2 1 5 3 4
+ 6 0 2 5 3 4 1
+ 6 0 3 5 4 1 2
+ 6 0 4 3 1 2 5
+ 6 0 5 2 1 3 4
+ 6 1 2 0 4 3 5
+ 6 1 4 0 5 3 2
+ 6 2 0 1 4 3 5
+ 6 2 0 5 4 1 3
+ 6 2 4 1 0 5 3
+ 6 3 1 2 4 0 5
+ 6 3 2 0 5 1 4
+ 6 3 2 4 0 1 5
+ 6 3 5 0 1 4 2
+ 6 3 5 1 0 4 2
+ 6 4 0 1 3 2 5
+ 6 4 1 5 0 2 3
+ 6 4 1 5 0 3 2
+ 6 5 0 2 3 1 4
+ 6 5 0 3 1 2 4
+ 6 5 1 3 0 4 2
diff --git a/lib/js8/genjs8.f90 b/lib/js8/genjs8.f90
new file mode 100644
index 0000000..37bba4b
--- /dev/null
+++ b/lib/js8/genjs8.f90
@@ -0,0 +1,93 @@
+subroutine genjs8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
+
+! Encode an FT8 message, producing array itone().
+
+ use crc
+ use packjt
+
+ include 'js8_params.f90'
+
+ parameter (KK=87) !Information bits (75 + CRC12)
+ parameter (ND=58) !Data symbols
+ parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
+ parameter (NN=NS+ND) !Total channel symbols (79)
+
+ character*68 alphabet
+ character*22 msg,msgsent
+ character*6 mygrid
+ character*87 cbits
+ logical bcontest,checksumok
+ integer*4 i4Msg6BitWords(12) !72-bit message as 6-bit words
+ integer*1 msgbits(KK),codeword(3*ND)
+ integer*1, target:: i1Msg8BitBytes(11)
+ integer itone(NN)
+
+ integer icos7a(0:6), icos7b(0:6), icos7c(0:6)
+ if(NCOSTAS.eq.1) then
+ icos7a = (/4,2,5,6,1,3,0/) !Beginning Costas 7x7 tone pattern
+ icos7b = (/4,2,5,6,1,3,0/) !Middle Costas 7x7 tone pattern
+ icos7c = (/4,2,5,6,1,3,0/) !End Costas 7x7 tone pattern
+ else
+ icos7a = (/0,6,2,3,5,4,1/) !Beginning Costas 7x7 tone pattern
+ icos7b = (/1,5,0,2,3,6,4/) !Middle Costas 7x7 tone pattern
+ icos7c = (/2,5,0,6,4,1,3/) !End Costas 7x7 tone pattern
+ endif
+
+ alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+/?.'
+
+ itype=6
+ do i=1,12
+ v=index(alphabet, msg(i:i))
+ if(v.eq.0) exit
+ i4Msg6BitWords(i)=v - 1
+ enddo
+ msgsent=' '
+ msgsent(1:12)=msg(1:12)
+
+ ! call packmsg(msg,i4Msg6BitWords,itype,bcontest) !Pack into 12 6-bit bytes
+ ! call unpackmsg(i4Msg6BitWords,msgsent,bcontest,mygrid) !Unpack to get msgsent
+
+ write(cbits,1000) i4Msg6BitWords,32*i3bit
+1000 format(12b6.6,b8.8)
+ read(cbits,1001) i1Msg8BitBytes(1:10)
+1001 format(10b8)
+ i1Msg8BitBytes(10)=iand(i1Msg8BitBytes(10),transfer(128+64+32,0_1))
+ i1Msg8BitBytes(11)=0
+ icrc12=crc12(c_loc(i1Msg8BitBytes),11)
+ icrc12=xor(icrc12, 42) ! TODO: jsherer - could change the crc here
+
+! For reference, here's how to check the CRC
+! i1Msg8BitBytes(10)=icrc12/256
+! i1Msg8BitBytes(11)=iand (icrc12,255)
+! checksumok = crc12_check(c_loc (i1Msg8BitBytes), 11)
+! if( checksumok ) write(*,*) 'Good checksum'
+
+ write(cbits,1003) i4Msg6BitWords,i3bit,icrc12
+1003 format(12b6.6,b3.3,b12.12)
+ read(cbits,1004) msgbits
+1004 format(87i1)
+
+ call encode174(msgbits,codeword) !Encode the test message
+
+! Message structure: S7 D29 S7 D29 S7
+ itone(1:7)=icos7a
+ itone(36+1:36+7)=icos7b
+ itone(NN-6:NN)=icos7c
+ k=7
+ do j=1,ND
+ i=3*j -2
+ k=k+1
+ if(j.eq.30) k=k+7
+ indx=codeword(i)*4 + codeword(i+1)*2 + codeword(i+2)
+ itone(k)=indx
+ enddo
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'tones', itone
+ write(99,*) '...', icos7a, '--->', NCOSTAS
+ close(99)
+ endif
+
+ return
+end subroutine genjs8
diff --git a/lib/js8/genjs8refsig.f90 b/lib/js8/genjs8refsig.f90
new file mode 100644
index 0000000..d3f4ea4
--- /dev/null
+++ b/lib/js8/genjs8refsig.f90
@@ -0,0 +1,24 @@
+subroutine genjs8refsig(itone,cref,f0)
+ !include 'js8_params.f90'
+
+ complex cref(NN*NSPS)
+ integer itone(NN)
+ real*8 twopi,phi,dphi,dt,xnsps
+ data twopi/0.d0/
+ save twopi
+ if( twopi .lt. 0.1 ) twopi=8.d0*atan(1.d0)
+
+ xnsps=NSPS*1.0d0
+ dt=1.d0/12000.d0
+ phi=0.d0
+ k=1
+ do i=1,NN
+ dphi=twopi*(f0*dt+itone(i)/xnsps)
+ do is=1,NSPS
+ cref(k)=cmplx(cos(phi),sin(phi))
+ phi=mod(phi+dphi,twopi)
+ k=k+1
+ enddo
+ enddo
+ return
+end subroutine genjs8refsig
diff --git a/lib/js8/js8_downsample.f90 b/lib/js8/js8_downsample.f90
new file mode 100644
index 0000000..f933be1
--- /dev/null
+++ b/lib/js8/js8_downsample.f90
@@ -0,0 +1,54 @@
+subroutine js8_downsample(dd,newdat,f0,c1)
+
+ ! Downconvert to complex data sampled at 200 Hz ==> 32 samples/symbol
+
+ !include 'js8_params.f90'
+
+ parameter (NDFFT1=NSPS*NDD, NDFFT2=NDFFT1/NDOWN) ! Downconverted FFT Size - 192000/60 = 3200
+
+ logical newdat,first
+
+ complex c1(0:NDFFT2-1)
+ complex cx(0:NDFFT1/2)
+ real dd(NMAX),x(NDFFT1),taper(0:NDD)
+ equivalence (x,cx)
+ data first/.true./
+ save cx,first,taper
+
+ if(first) then
+ pi=4.0*atan(1.0)
+ do i=0,NDD
+ taper(i)=0.5*(1.0+cos(i*pi/NDD))
+ enddo
+ first=.false.
+ endif
+ if(newdat) then
+ ! Data in dd have changed, recompute the long FFT
+ x(1:NMAX)=dd
+ x(NMAX+1:NDFFT1)=0. !Zero-pad the x array
+ call four2a(cx,NDFFT1,1,-1,0) !r2c FFT to freq domain
+ newdat=.false.
+ endif
+
+ df=12000.0/NDFFT1
+ baud=12000.0/NSPS
+ i0=nint(f0/df)
+ ft=f0+8.5*baud
+ it=min(nint(ft/df),NDFFT1/2)
+ fb=f0-1.5*baud
+ ib=max(1,nint(fb/df))
+ k=0
+ c1=0.
+ do i=ib,it
+ c1(k)=cx(i)
+ k=k+1
+ enddo
+ c1(0:NDD)=c1(0:NDD)*taper(NDD:0:-1)
+ c1(k-1-NDD:k-1)=c1(k-1-NDD:k-1)*taper
+ c1=cshift(c1,i0-ib)
+ call four2a(c1,NDFFT2,1,1,1) !c2c FFT back to time domain
+ fac=1.0/sqrt(float(NDFFT1)*NDFFT2)
+ c1=fac*c1
+
+ return
+end subroutine js8_downsample
diff --git a/lib/js8/js8_params.f90 b/lib/js8/js8_params.f90
new file mode 100644
index 0000000..fc5512c
--- /dev/null
+++ b/lib/js8/js8_params.f90
@@ -0,0 +1,2 @@
+parameter (NCOSTAS=2) !Which JS8 Costas Arrays to use (1=original, 2=three symmetrical costas)
+parameter (NWRITELOG=0) !Write log file?
diff --git a/lib/js8/js8b_params.f90 b/lib/js8/js8b_params.f90
new file mode 100644
index 0000000..aece5a5
--- /dev/null
+++ b/lib/js8/js8b_params.f90
@@ -0,0 +1,36 @@
+!parameter (NSPS=480) !Samples per symbol at 12000 S/s
+!parameter (NTXDUR=5) !TX Duration in Seconds
+!parameter (NDOWNSPS=16) !Downsampled samples per symbol
+!parameter (AZ=6.0) !Near dupe sync spacing
+!parameter (NDD=136) !Downconverted FFT Bins - 100 Bins
+!parameter (JZ=62) !Sync Search Space over +/- 2.5s relative to 0.5s TX start time. 2.48 = 62/4/(12000/1920) ?
+
+
+! parameter (NSPS=384, NTXDUR=4, NDOWNSPS=16, NDD=150, JZ=116) ! 250 Hz 31.25 baud 60 wpm -18.0dB (1.0Eb/N0) 2.52s
+! parameter (NSPS=384, NTXDUR=5, NDOWNSPS=16, NDD=160, JZ=116) ! 250 Hz 31.25 baud 48 wpm -18.0dB (1.0Eb/N0) 2.52s
+! parameter (NSPS=480, NTXDUR=5, NDOWNSPS=16, NDD=136, JZ=116) ! 200 Hz 25 baud 48 wpm -19.0dB (1.0Eb/N0) 3.16s
+! parameter (NSPS=480, NTXDUR=6, NDOWNSPS=20, NDD=150, JZ=116) ! 200 Hz 25 baud 40 wpm -19.0dB (1.0Eb/N0) 3.16s
+! parameter (NSPS=500, NTXDUR=6, NDOWNSPS=20, NDD=144, JZ=116) ! 192 Hz 24 baud 40 wpm -19.4dB (1.0Eb/N0) 3.29s
+! parameter (NSPS=600, NTXDUR=6, NDOWNSPS=24, NDD=120, JZ=116) ! 160 Hz 20 baud 40 wpm -20.0dB (1.0Eb/N0) 3.95s
+! parameter (NSPS=768, NTXDUR=8, NDOWNSPS=24, NDD=125, JZ=116) ! 125 Hz 15.625 baud 32 wpm -21.0dB (1.0Eb/N0) 5.05s
+! parameter (NSPS=800, NTXDUR=8, NDOWNSPS=24, NDD=100, JZ=116) ! 120 Hz 15 baud 32 wpm -21.2dB (1.0Eb/N0) 5.26s
+! parameter (NSPS=960, NTXDUR=8, NDOWNSPS=24, NDD=100, JZ=116) ! 100 Hz 12.50 baud 32 wpm -22.0dB (1.0Eb/N0) 5.92s
+ parameter (NSPS=1200, NTXDUR=10, NDOWNSPS=20, NDD=100, JZ=172) ! 80 Hz 10 baud 24 wpm -23.0dB (1.0Eb/N0) 7.90s
+! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
+! parameter (NSPS=4000, NTXDUR=30, NDOWNSPS=20, NDD=90, JZ=62) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
+
+parameter (AZ=12000.0/(1.0*NSPS)*0.64d0) !Dedupe overlap in Hz
+parameter (ASTART=0.2) !Start delay in seconds
+parameter (ASYNCMIN=1.5) !Minimum Sync
+
+parameter (KK=87) !Information bits (75 + CRC12)
+parameter (ND=58) !Data symbols
+parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
+parameter (NN=NS+ND) !Total channel symbols (79)
+parameter (NZ=NSPS*NN) !Samples in full 15 s waveform (151,680)
+parameter (NMAX=NTXDUR*12000) !Samples in iwave (180,000)
+parameter (NFFT1=2*NSPS, NH1=NFFT1/2) !Length of FFTs for symbol spectra
+parameter (NSTEP=NSPS/4) !Rough time-sync step size
+parameter (NHSYM=NMAX/NSTEP-3) !Number of symbol spectra (1/4-sym steps)
+parameter (NDOWN=NSPS/NDOWNSPS) !Downsample factor to 32 samples per symbol
+parameter (NQSYMBOL=NDOWNSPS/4) !Downsample factor of a quarter symbol
diff --git a/lib/js8/js8c_params.f90 b/lib/js8/js8c_params.f90
new file mode 100644
index 0000000..caba06e
--- /dev/null
+++ b/lib/js8/js8c_params.f90
@@ -0,0 +1,36 @@
+!parameter (NSPS=480) !Samples per symbol at 12000 S/s
+!parameter (NTXDUR=5) !TX Duration in Seconds
+!parameter (NDOWNSPS=16) !Downsampled samples per symbol
+!parameter (AZ=6.0) !Near dupe sync spacing
+!parameter (NDD=136) !Downconverted FFT Bins - 100 Bins
+!parameter (JZ=62) !Sync Search Space over +/- 2.5s relative to 0.5s TX start time. 2.48 = 62/4/(12000/1920) ?
+
+
+! parameter (NSPS=384, NTXDUR=4, NDOWNSPS=16, NDD=150, JZ=116) ! 250 Hz 31.25 baud 60 wpm -18.0dB (1.0Eb/N0) 2.52s
+! parameter (NSPS=384, NTXDUR=5, NDOWNSPS=16, NDD=160, JZ=116) ! 250 Hz 31.25 baud 48 wpm -18.0dB (1.0Eb/N0) 2.52s
+! parameter (NSPS=480, NTXDUR=5, NDOWNSPS=16, NDD=136, JZ=116) ! 200 Hz 25 baud 48 wpm -19.0dB (1.0Eb/N0) 3.16s
+! parameter (NSPS=480, NTXDUR=6, NDOWNSPS=20, NDD=150, JZ=116) ! 200 Hz 25 baud 40 wpm -19.0dB (1.0Eb/N0) 3.16s
+! parameter (NSPS=500, NTXDUR=6, NDOWNSPS=20, NDD=144, JZ=116) ! 192 Hz 24 baud 40 wpm -19.4dB (1.0Eb/N0) 3.29s
+ parameter (NSPS=600, NTXDUR=6, NDOWNSPS=12, NDD=120, JZ=172) ! 160 Hz 20 baud 40 wpm -20.0dB (1.0Eb/N0) 3.95s
+! parameter (NSPS=768, NTXDUR=8, NDOWNSPS=24, NDD=125, JZ=116) ! 125 Hz 15.625 baud 32 wpm -21.0dB (1.0Eb/N0) 5.05s
+! parameter (NSPS=800, NTXDUR=8, NDOWNSPS=24, NDD=100, JZ=116) ! 120 Hz 15 baud 32 wpm -21.2dB (1.0Eb/N0) 5.26s
+! parameter (NSPS=960, NTXDUR=8, NDOWNSPS=24, NDD=100, JZ=116) ! 100 Hz 12.50 baud 32 wpm -22.0dB (1.0Eb/N0) 5.92s
+! parameter (NSPS=1200, NTXDUR=10, NDOWNSPS=20, NDD=100, JZ=116) ! 80 Hz 10 baud 24 wpm -23.0dB (1.0Eb/N0) 7.90s
+! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
+! parameter (NSPS=4000, NTXDUR=30, NDOWNSPS=20, NDD=90, JZ=62) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
+
+parameter (AZ=12000.0/(1.0*NSPS)*0.64d0) !Dedupe overlap in Hz
+parameter (ASTART=0.1) !Start delay in seconds
+parameter (ASYNCMIN=1.5) !Minimum Sync
+
+parameter (KK=87) !Information bits (75 + CRC12)
+parameter (ND=58) !Data symbols
+parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
+parameter (NN=NS+ND) !Total channel symbols (79)
+parameter (NZ=NSPS*NN) !Samples in full 15 s waveform (151,680)
+parameter (NMAX=NTXDUR*12000) !Samples in iwave (180,000)
+parameter (NFFT1=2*NSPS, NH1=NFFT1/2) !Length of FFTs for symbol spectra
+parameter (NSTEP=NSPS/4) !Rough time-sync step size
+parameter (NHSYM=NMAX/NSTEP-3) !Number of symbol spectra (1/4-sym steps)
+parameter (NDOWN=NSPS/NDOWNSPS) !Downsample factor to 32 samples per symbol
+parameter (NQSYMBOL=NDOWNSPS/4) !Downsample factor of a quarter symbol
diff --git a/lib/js8/js8d_params.f90 b/lib/js8/js8d_params.f90
new file mode 100644
index 0000000..664e9c1
--- /dev/null
+++ b/lib/js8/js8d_params.f90
@@ -0,0 +1,36 @@
+!parameter (NSPS=480) !Samples per symbol at 12000 S/s
+!parameter (NTXDUR=5) !TX Duration in Seconds
+!parameter (NDOWNSPS=16) !Downsampled samples per symbol
+!parameter (AZ=6.0) !Near dupe sync spacing
+!parameter (NDD=136) !Downconverted FFT Bins - 100 Bins
+!parameter (JZ=62) !Sync Search Space over +/- 2.5s relative to 0.5s TX start time. 2.48 = 62/4/(12000/1920) ?
+
+
+ parameter (NSPS=384, NTXDUR=4, NDOWNSPS=12, NDD=125, JZ=250) ! 250 Hz 31.25 baud 60 wpm -18.0dB (1.0Eb/N0) 2.52s
+! parameter (NSPS=384, NTXDUR=5, NDOWNSPS=12, NDD=125, JZ=116) ! 250 Hz 31.25 baud 48 wpm -18.0dB (1.0Eb/N0) 2.52s
+! parameter (NSPS=480, NTXDUR=5, NDOWNSPS=12, NDD=125, JZ=116) ! 200 Hz 25 baud 48 wpm -19.0dB (1.0Eb/N0) 3.16s
+! parameter (NSPS=480, NTXDUR=6, NDOWNSPS=20, NDD=150, JZ=116) ! 200 Hz 25 baud 40 wpm -19.0dB (1.0Eb/N0) 3.16s
+! parameter (NSPS=500, NTXDUR=6, NDOWNSPS=20, NDD=144, JZ=116) ! 192 Hz 24 baud 40 wpm -19.4dB (1.0Eb/N0) 3.29s
+! parameter (NSPS=600, NTXDUR=6, NDOWNSPS=24, NDD=120, JZ=172) ! 160 Hz 20 baud 40 wpm -20.0dB (1.0Eb/N0) 3.95s
+! parameter (NSPS=768, NTXDUR=8, NDOWNSPS=24, NDD=125, JZ=116) ! 125 Hz 15.625 baud 32 wpm -21.0dB (1.0Eb/N0) 5.05s
+! parameter (NSPS=800, NTXDUR=8, NDOWNSPS=24, NDD=100, JZ=116) ! 120 Hz 15 baud 32 wpm -21.2dB (1.0Eb/N0) 5.26s
+! parameter (NSPS=960, NTXDUR=8, NDOWNSPS=24, NDD=100, JZ=116) ! 100 Hz 12.50 baud 32 wpm -22.0dB (1.0Eb/N0) 5.92s
+! parameter (NSPS=1200, NTXDUR=10, NDOWNSPS=20, NDD=100, JZ=116) ! 80 Hz 10 baud 24 wpm -23.0dB (1.0Eb/N0) 7.90s
+! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
+! parameter (NSPS=4000, NTXDUR=30, NDOWNSPS=40, NDD=90, JZ=116) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
+
+parameter (AZ=12000.0/(1.0*NSPS)*0.64d0) !Dedupe overlap in Hz
+parameter (ASTART=0.1) !Start delay in seconds
+parameter (ASYNCMIN=1.5) !Minimum Sync
+
+parameter (KK=87) !Information bits (75 + CRC12)
+parameter (ND=58) !Data symbols
+parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
+parameter (NN=NS+ND) !Total channel symbols (79)
+parameter (NZ=NSPS*NN) !Samples in full 15 s waveform (151,680)
+parameter (NMAX=NTXDUR*12000) !Samples in iwave (180,000)
+parameter (NFFT1=2*NSPS, NH1=NFFT1/2) !Length of FFTs for symbol spectra
+parameter (NSTEP=NSPS/4) !Rough time-sync step size
+parameter (NHSYM=NMAX/NSTEP-3) !Number of symbol spectra (1/4-sym steps)
+parameter (NDOWN=NSPS/NDOWNSPS) !Downsample factor to 32 samples per symbol
+parameter (NQSYMBOL=NDOWNSPS/4) !Downsample factor of a quarter symbol
diff --git a/lib/js8/js8dec.f90 b/lib/js8/js8dec.f90
new file mode 100644
index 0000000..36b8f56
--- /dev/null
+++ b/lib/js8/js8dec.f90
@@ -0,0 +1,486 @@
+subroutine js8dec(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
+ napwid,lsubtract,nagain,iaptype,mycall12,mygrid6,hiscall12,bcontest, &
+ sync0,f1,xdt,xbase,apsym,nharderrors,dmin,nbadcrc,ipass,iera,msg37,xsnr)
+
+ use crc
+ use timer_module, only: timer
+
+ !include 'js8_params.f90'
+
+ parameter(NP=3200) ! why 3200? not sure...
+ parameter(NP2=2812)
+ character*37 msg37
+ character message*22,msgsent*22,origmsg*22
+ character*12 mycall12,hiscall12
+ character*6 mycall6,mygrid6,hiscall6,c1,c2
+ character*87 cbits
+ logical bcontest
+ real a(5)
+ real s1(0:7,ND),s2(0:7,NN),s1sort(8*ND)
+ real ps(0:7),psl(0:7)
+ real bmeta(3*ND),bmetb(3*ND),bmetap(3*ND)
+ real llr(3*ND),llra(3*ND),llr0(3*ND),llr1(3*ND),llrap(3*ND) !Soft symbols
+ real dd0(NMAX)
+ integer*1 decoded(KK),decoded0(KK),apmask(3*ND),cw(3*ND)
+ integer*1 msgbits(KK)
+ integer apsym(KK)
+ integer mcq(28),mde(28),mrrr(16),m73(16),mrr73(16)
+ integer itone(NN)
+ integer indxs1(8*ND)
+ integer ip(1)
+ integer nappasses(0:5) !Number of decoding passes to use for each QSO state
+ integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
+ integer*1, target:: i1hiscall(12)
+ complex cd0(0:NP-1)
+ complex ctwk(4*NSPS/NDOWN)
+ complex csymb(NDOWNSPS)
+ logical first,newdat,lsubtract,lapon,lapcqonly,nagain
+ equivalence (s1,s1sort)
+ data mcq/1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,1,1,0,0,1/
+ data mrrr/0,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1/
+ data m73/0,1,1,1,1,1,1,0,1,1,0,1,0,0,0,0/
+ data mde/1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0,1,1,1,0,1,0,0,0,1/
+ data mrr73/0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1/
+ data first/.true./
+ save nappasses,naptypes
+
+ integer icos7a(0:6), icos7b(0:6), icos7c(0:6)
+ if(NCOSTAS.eq.1) then
+ icos7a = (/4,2,5,6,1,3,0/) !Beginning Costas 7x7 tone pattern
+ icos7b = (/4,2,5,6,1,3,0/) !Middle Costas 7x7 tone pattern
+ icos7c = (/4,2,5,6,1,3,0/) !End Costas 7x7 tone pattern
+ else
+ icos7a = (/0,6,2,3,5,4,1/) !Beginning Costas 7x7 tone pattern
+ icos7b = (/1,5,0,2,3,6,4/) !Middle Costas 7x7 tone pattern
+ icos7c = (/2,5,0,6,4,1,3/) !End Costas 7x7 tone pattern
+ endif
+
+ if(first) then
+ mcq=2*mcq-1
+ mde=2*mde-1
+ mrrr=2*mrrr-1
+ m73=2*m73-1
+ mrr73=2*mrr73-1
+ nappasses(0)=2
+ nappasses(1)=2
+ nappasses(2)=2
+ nappasses(3)=4
+ nappasses(4)=4
+ nappasses(5)=3
+
+! iaptype
+!------------------------
+! 1 CQ ??? ???
+! 2 MyCall ??? ???
+! 3 MyCall DxCall ???
+! 4 MyCall DxCall RRR
+! 5 MyCall DxCall 73
+! 6 MyCall DxCall RR73
+! 7 ??? DxCall ???
+
+ naptypes(0,1:4)=(/1,2,0,0/)
+ naptypes(1,1:4)=(/2,3,0,0/)
+ naptypes(2,1:4)=(/2,3,0,0/)
+ naptypes(3,1:4)=(/3,4,5,6/)
+ naptypes(4,1:4)=(/3,4,5,6/)
+ naptypes(5,1:4)=(/3,1,2,0/)
+ first=.false.
+ endif
+
+ max_iterations=30
+ nharderrors=-1
+ fs2=12000.0/NDOWN
+ dt2=1.0/fs2
+ twopi=8.0*atan(1.0)
+ delfbest=0.
+ ibest=0
+
+ call timer('js8_down',0)
+ call js8_downsample(dd0,newdat,f1,cd0) !Mix f1 to baseband and downsample
+ call timer('js8_down',1)
+
+ xdt=xdt+ASTART
+ i0=nint(xdt*fs2) !Initial guess for start of signal
+ smax=0.0
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'initial dt guess', i0, xdt
+ close(99)
+ endif
+
+ do idt=i0-NQSYMBOL,i0+NQSYMBOL !Search over +/- one quarter symbol
+ call syncjs8d(cd0,idt,ctwk,0,sync)
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'idt', idt, 'sync', sync
+ close(99)
+ endif
+ if(sync.gt.smax) then
+ smax=sync
+ ibest=idt
+ endif
+ enddo
+ xdt2=ibest*dt2 !Improved estimate for DT
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'xdt2', xdt2, ibest
+ close(99)
+ endif
+
+! Now peak up in frequency
+ i0=nint(xdt2*fs2)
+ smax=0.0
+
+ do ifr=-5,5 !Search over +/- 2.5 Hz
+ delf=ifr*0.5
+ dphi=twopi*delf*dt2
+ phi=0.0
+ do i=1,NDOWNSPS
+ ctwk(i)=cmplx(cos(phi),sin(phi))
+ phi=mod(phi+dphi,twopi)
+ enddo
+ call syncjs8d(cd0,i0,ctwk,1,sync)
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'df', delf, 'sync', sync
+ close(99)
+ endif
+ if( sync .gt. smax ) then
+ smax=sync
+ delfbest=delf
+ endif
+ enddo
+ a=0.0
+ a(1)=-delfbest
+ call twkfreq1(cd0,NP2,fs2,a,cd0)
+ xdt=xdt2
+ f1=f1+delfbest !Improved estimate of DF
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'twk', xdt, f1, smax
+ close(99)
+ endif
+
+ call syncjs8d(cd0,i0,ctwk,2,sync)
+
+ j=0
+ do k=1,NN
+ i1=ibest+(k-1)*NDOWNSPS
+ csymb=cmplx(0.0,0.0)
+ !if( i1.ge.1 .and. i1+31 .le. NP2 ) csymb=cd0(i1:i1+31)
+ if( i1.ge.0 .and. i1+(NDOWNSPS-1) .le. NP2-1 ) csymb=cd0(i1:i1+(NDOWNSPS-1))
+ call four2a(csymb,NDOWNSPS,1,-1,1)
+ s2(0:7,k)=abs(csymb(1:8))/1e3
+ enddo
+
+! sync quality check
+ is1=0
+ is2=0
+ is3=0
+ do k=1,7
+ ip=maxloc(s2(:,k))
+ if(icos7a(k-1).eq.(ip(1)-1)) is1=is1+1
+ ip=maxloc(s2(:,k+36))
+ if(icos7b(k-1).eq.(ip(1)-1)) is2=is2+1
+ ip=maxloc(s2(:,k+72))
+ if(icos7c(k-1).eq.(ip(1)-1)) is3=is3+1
+ enddo
+! hard sync sum - max is 21
+ nsync=is1+is2+is3
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'sync', ibest, nsync
+ close(99)
+ endif
+
+ if(nsync .le. 6) then ! bail out
+ call timer('badnsync', 0)
+ nbadcrc=1
+ call timer('badnsync', 1)
+ return
+ endif
+
+ j=0
+ do k=1,NN
+ if(k.le.7) cycle
+ if(k.ge.37 .and. k.le.43) cycle
+ if(k.gt.72) cycle
+ j=j+1
+ s1(0:7,j)=s2(0:7,k)
+ enddo
+
+ call indexx(s1sort,8*ND,indxs1)
+ xmeds1=s1sort(indxs1(nint(0.5*8*ND)))
+ s1=s1/xmeds1
+
+ do j=1,ND
+ i4=3*j-2
+ i2=3*j-1
+ i1=3*j
+! Max amplitude
+ ps=s1(0:7,j)
+ r1=max(ps(1),ps(3),ps(5),ps(7))-max(ps(0),ps(2),ps(4),ps(6))
+ r2=max(ps(2),ps(3),ps(6),ps(7))-max(ps(0),ps(1),ps(4),ps(5))
+ r4=max(ps(4),ps(5),ps(6),ps(7))-max(ps(0),ps(1),ps(2),ps(3))
+ bmeta(i4)=r4
+ bmeta(i2)=r2
+ bmeta(i1)=r1
+ bmetap(i4)=r4
+ bmetap(i2)=r2
+ bmetap(i1)=r1
+! Max log metric
+ psl=log(ps+1e-32)
+ r1=max(psl(1),psl(3),psl(5),psl(7))-max(psl(0),psl(2),psl(4),psl(6))
+ r2=max(psl(2),psl(3),psl(6),psl(7))-max(psl(0),psl(1),psl(4),psl(5))
+ r4=max(psl(4),psl(5),psl(6),psl(7))-max(psl(0),psl(1),psl(2),psl(3))
+ bmetb(i4)=r4
+ bmetb(i2)=r2
+ bmetb(i1)=r1
+
+! Metric for Cauchy noise
+! r1=log(ps(1)**3+ps(3)**3+ps(5)**3+ps(7)**3)- &
+! log(ps(0)**3+ps(2)**3+ps(4)**3+ps(6)**3)
+! r2=log(ps(2)**3+ps(3)**3+ps(6)**3+ps(7)**3)- &
+! log(ps(0)**3+ps(1)**3+ps(4)**3+ps(5)**3)
+! r4=log(ps(4)**3+ps(5)**3+ps(6)**3+ps(7)**3)- &
+! log(ps(0)**3+ps(1)**3+ps(2)**3+ps(3)**3)
+! Metric for AWGN, no fading
+! bscale=2.5
+! b0=bessi0(bscale*ps(0))
+! b1=bessi0(bscale*ps(1))
+! b2=bessi0(bscale*ps(2))
+! b3=bessi0(bscale*ps(3))
+! b4=bessi0(bscale*ps(4))
+! b5=bessi0(bscale*ps(5))
+! b6=bessi0(bscale*ps(6))
+! b7=bessi0(bscale*ps(7))
+! r1=log(b1+b3+b5+b7)-log(b0+b2+b4+b6)
+! r2=log(b2+b3+b6+b7)-log(b0+b1+b4+b5)
+! r4=log(b4+b5+b6+b7)-log(b0+b1+b2+b3)
+
+ if(nQSOProgress .eq. 0 .or. nQSOProgress .eq. 5) then
+! When bits 88:115 are set as ap bits, bit 115 lives in symbol 39 along
+! with no-ap bits 116 and 117. Take care of metrics for bits 116 and 117.
+ if(j.eq.39) then ! take care of bits that live in symbol 39
+ if(apsym(28).lt.0) then
+ bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
+ bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
+ else
+ bmetap(i2)=max(ps(6),ps(7))-max(ps(4),ps(5))
+ bmetap(i1)=max(ps(5),ps(7))-max(ps(4),ps(6))
+ endif
+ endif
+ endif
+
+! When bits 116:143 are set as ap bits, bit 115 lives in symbol 39 along
+! with ap bits 116 and 117. Take care of metric for bit 115.
+ if(j.eq.39) then ! take care of bit 115
+ iii=2*(apsym(29)+1)/2 + (apsym(30)+1)/2 ! known values of bits 116 & 117
+ if(iii.eq.0) bmetap(i4)=ps(4)-ps(0)
+ if(iii.eq.1) bmetap(i4)=ps(5)-ps(1)
+ if(iii.eq.2) bmetap(i4)=ps(6)-ps(2)
+ if(iii.eq.3) bmetap(i4)=ps(7)-ps(3)
+ endif
+
+! bit 144 lives in symbol 48 and will be 1 if it is set as an ap bit.
+! take care of metrics for bits 142 and 143
+ if(j.eq.48) then ! bit 144 is always 1
+ bmetap(i4)=max(ps(5),ps(7))-max(ps(1),ps(3))
+ bmetap(i2)=max(ps(3),ps(7))-max(ps(1),ps(5))
+ endif
+
+! bit 154 lives in symbol 52 and will be 0 if it is set as an ap bit
+! take care of metrics for bits 155 and 156
+ if(j.eq.52) then ! bit 154 will be 0 if it is set as an ap bit.
+ bmetap(i2)=max(ps(2),ps(3))-max(ps(0),ps(1))
+ bmetap(i1)=max(ps(1),ps(3))-max(ps(0),ps(2))
+ endif
+
+ enddo
+
+ call normalizebmet(bmeta,3*ND)
+ call normalizebmet(bmetb,3*ND)
+ call normalizebmet(bmetap,3*ND)
+
+ scalefac=2.83
+ llr0=scalefac*bmeta
+ llr1=scalefac*bmetb
+ llra=scalefac*bmetap ! llr's for use with ap
+ apmag=scalefac*(maxval(abs(bmetap))*1.01)
+
+! pass #
+!------------------------------
+! 1 regular decoding
+! 2 erase 24
+! 3 erase 48
+! 4 ap pass 1
+! 5 ap pass 2
+! 6 ap pass 3
+! 7 ap pass 4, etc.
+
+ !if(lapon) then
+ ! if(.not.lapcqonly) then
+ ! npasses=4+nappasses(nQSOProgress)
+ ! else
+ ! npasses=5
+ ! endif
+ !else
+ npasses=4
+ !endif
+
+ do ipass=1,npasses
+
+ llr=llr0
+ if(ipass.eq.2) llr=llr1
+ if(ipass.eq.3) llr(1:24)=0.
+ if(ipass.eq.4) llr(1:48)=0.
+ if(ipass.le.4) then
+ apmask=0
+ llrap=llr
+ iaptype=0
+ endif
+
+ !if(ipass .gt. 4) then
+ ! if(.not.lapcqonly) then
+ ! iaptype=naptypes(nQSOProgress,ipass-4)
+ ! else
+ ! iaptype=1
+ ! endif
+ ! if(iaptype.ge.3 .and. (abs(f1-nfqso).gt.napwid .and. abs(f1-nftx).gt.napwid) ) cycle
+ ! if(iaptype.eq.1 .or. iaptype.eq.2 ) then ! AP,???,???
+ ! apmask=0
+ ! apmask(88:115)=1 ! first 28 bits are AP
+ ! apmask(144)=1 ! not free text
+ ! llrap=llr
+ ! if(iaptype.eq.1) llrap(88:115)=apmag*mcq
+ ! if(iaptype.eq.2) llrap(88:115)=apmag*apsym(1:28)
+ ! llrap(116:117)=llra(116:117)
+ ! llrap(142:143)=llra(142:143)
+ ! llrap(144)=-apmag
+ ! endif
+ ! if(iaptype.eq.3) then ! mycall, dxcall, ???
+ ! apmask=0
+ ! apmask(88:115)=1 ! mycall
+ ! apmask(116:143)=1 ! hiscall
+ ! apmask(144)=1 ! not free text
+ ! llrap=llr
+ ! llrap(88:143)=apmag*apsym(1:56)
+ ! llrap(144)=-apmag
+ ! endif
+ ! if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then
+ ! apmask=0
+ ! apmask(88:115)=1 ! mycall
+ ! apmask(116:143)=1 ! hiscall
+ ! apmask(144:159)=1 ! RRR or 73 or RR73
+ ! llrap=llr
+ ! llrap(88:143)=apmag*apsym(1:56)
+ ! if(iaptype.eq.4) llrap(144:159)=apmag*mrrr
+ ! if(iaptype.eq.5) llrap(144:159)=apmag*m73
+ ! if(iaptype.eq.6) llrap(144:159)=apmag*mrr73
+ ! endif
+ ! if(iaptype.eq.7) then ! ???, dxcall, ???
+ ! apmask=0
+ ! apmask(116:143)=1 ! hiscall
+ ! apmask(144)=1 ! not free text
+ ! llrap=llr
+ ! llrap(115)=llra(115)
+ ! llrap(116:143)=apmag*apsym(29:56)
+ ! llrap(144)=-apmag
+ ! endif
+ !endif
+
+ cw=0
+ call timer('bpd174 ',0)
+ call bpdecode174(llrap,apmask,max_iterations,decoded,cw,nharderrors, &
+ niterations)
+ call timer('bpd174 ',1)
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) '> bpd174 ', ipass, nharderrors, dmin
+ close(99)
+ endif
+
+ dmin=0.0
+ if(ndepth.eq.3 .and. nharderrors.lt.0) then
+ ndeep=3
+ if(abs(nfqso-f1).le.napwid .or. abs(nftx-f1).le.napwid) then
+ if((ipass.eq.3 .or. ipass.eq.4) .and. .not.nagain) then
+ ndeep=3
+ else
+ ndeep=4
+ endif
+ endif
+ if(nagain) ndeep=5
+ call timer('osd174 ',0)
+ call osd174(llrap,apmask,ndeep,decoded,cw,nharderrors,dmin)
+ call timer('osd174 ',1)
+ endif
+ nbadcrc=1
+ message=' '
+ xsnr=-99.0
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) '> osd174', ipass, nharderrors, dmin, nharderrors + dmin, sync
+ close(99)
+ endif
+
+ if(count(cw.eq.0).eq.174) cycle !Reject the all-zero codeword
+ if(nharderrors.ge.0 .and. nharderrors+dmin.lt.60.0 .and. &
+ .not.(sync.lt.2.0 .and. nharderrors.gt.35) .and. &
+ .not.(ipass.gt.2 .and. nharderrors.gt.39) .and. &
+ .not.(ipass.eq.4 .and. nharderrors.gt.30) &
+ ) then
+ call chkcrc12a(decoded,nbadcrc)
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) '> crc', decoded
+ if(nbadcrc.eq.1) then
+ write(99,*) '> crc failed'
+ endif
+ close(99)
+ endif
+ else
+ nharderrors=-1
+ cycle
+ endif
+ i3bit=4*decoded(73) + 2*decoded(74) + decoded(75)
+
+ if(nbadcrc.eq.0) then
+ decoded0=decoded
+ call extractmessage174(decoded,origmsg,ncrcflag)
+ decoded=decoded0
+
+ message(1:12)=origmsg(1:12)
+ call genjs8(message,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
+ if(lsubtract) call subtractjs8(dd0,itone,f1,xdt2)
+ xsig=0.0
+ xnoi=0.0
+ do i=1,NN
+ xsig=xsig+s2(itone(i),i)**2
+ ios=mod(itone(i)+4,7)
+ xnoi=xnoi+s2(ios,i)**2
+ enddo
+ xsnr=0.001
+ if(xnoi.gt.0 .and. xnoi.lt.xsig) xsnr=xsig/xnoi-1.0
+ xsnr=10.0*log10(xsnr)-27.0
+ xsnr2=db(xsig/xbase - 1.0) - 32.0
+ if(.not.nagain) xsnr=xsnr2
+ if(xsnr .lt. -24.0) xsnr=-24.0
+
+ msg37=origmsg//' '
+
+ msg37(22:22) = char(48 + i3bit)
+
+ return
+ endif
+ enddo
+
+ return
+end subroutine js8dec
diff --git a/lib/js8/ldpcsim174js8b.f90 b/lib/js8/ldpcsim174js8b.f90
new file mode 100644
index 0000000..de047d3
--- /dev/null
+++ b/lib/js8/ldpcsim174js8b.f90
@@ -0,0 +1,238 @@
+program ldpcsim174js8
+! End to end test of the (174,75)/crc12 encoder and decoder.
+use crc
+use packjt
+
+include 'js8_params.f90'
+include 'js8b_params.f90'
+
+character*22 msg,msgsent,msgreceived
+character*8 arg
+character*6 grid
+integer*1, allocatable :: codeword(:), decoded(:), message(:)
+integer*1, target:: i1Msg8BitBytes(11)
+integer*1 msgbits(87)
+integer*1 apmask(174), cw(174)
+integer*2 checksum
+integer*4 i4Msg6BitWords(13)
+integer colorder(174)
+integer nerrtot(174),nerrdec(174),nmpcbad(87)
+logical checksumok,fsk,bpsk
+real*8, allocatable :: rxdata(:)
+real, allocatable :: llr(:)
+
+data colorder/ &
+ 0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16,&
+ 17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43,&
+ 36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62,&
+ 56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79,&
+ 73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,&
+ 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,&
+ 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,&
+ 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,&
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173/
+
+nerrtot=0
+nerrdec=0
+nmpcbad=0 ! Used to collect the number of errors in the message+crc part of the codeword
+
+nargs=iargc()
+if(nargs.ne.4) then
+ print*,'Usage: ldpcsim niter ndepth #trials s '
+ print*,'eg: ldpcsim 10 2 1000 0.84'
+ print*,'belief propagation iterations: niter, ordered-statistics depth: ndepth'
+ print*,'If s is negative, then value is ignored and sigma is calculated from SNR.'
+ return
+endif
+call getarg(1,arg)
+read(arg,*) max_iterations
+call getarg(2,arg)
+read(arg,*) ndepth
+call getarg(3,arg)
+read(arg,*) ntrials
+call getarg(4,arg)
+read(arg,*) s
+
+fsk=.false.
+bpsk=.true.
+
+! don't count crc bits as data bits
+N=174
+K=87
+! scale Eb/No for a (174,87) code
+rate=real(K)/real(N)
+
+write(*,*) "rate: ",rate
+write(*,*) "niter= ",max_iterations," s= ",s
+
+allocate ( codeword(N), decoded(K), message(K) )
+allocate ( rxdata(N), llr(N) )
+
+ msg="0123456789012"
+! msg="G4WJS K9AN EN50"
+ call packmsg(msg,i4Msg6BitWords,itype,.false.) !Pack into 12 6-bit bytes
+ call unpackmsg(i4Msg6BitWords,msgsent,.false.,grid) !Unpack to get msgsent
+ write(*,*) "message sent ",msgsent
+
+ i4=0
+ ik=0
+ im=0
+ do i=1,12
+ nna=i4Msg6BitWords(i)
+ do j=1, 6
+ ik=ik+1
+ i4=i4+i4+iand(1,ishft(nna,j-6))
+ i4=iand(i4,255)
+ if(ik.eq.8) then
+ im=im+1
+! if(i4.gt.127) i4=i4-256
+ i1Msg8BitBytes(im)=i4
+ ik=0
+ endif
+ enddo
+ enddo
+
+ i1Msg8BitBytes(10:11)=0
+ checksum = crc12 (c_loc (i1Msg8BitBytes), 11)
+ checksum = xor(checksum, 42) ! TODO: jsherer - could change the crc here
+! For reference, the next 3 lines show how to check the CRC
+ i1Msg8BitBytes(10)=checksum/256
+ i1Msg8BitBytes(11)=iand(checksum,transfer(255,0_2))
+ checksumok = crc12_check(c_loc (i1Msg8BitBytes), 11)
+ if( checksumok ) write(*,*) 'Good checksum'
+
+! K=87, For now:
+! msgbits(1:72) JT message bits
+! msgbits(73:75) 3 free message bits (set to 0)
+! msgbits(76:87) CRC12
+ mbit=0
+ do i=1, 9
+ i1=i1Msg8BitBytes(i)
+ do ibit=1,8
+ mbit=mbit+1
+ msgbits(mbit)=iand(1,ishft(i1,ibit-8))
+ enddo
+ enddo
+ msgbits(73:75)=0 ! the three extra message bits go here
+ i1=i1Msg8BitBytes(10) ! First 4 bits of crc12 are LSB of this byte
+ do ibit=1,4
+ msgbits(75+ibit)=iand(1,ishft(i1,ibit-4))
+ enddo
+ i1=i1Msg8BitBytes(11) ! Now shift in last 8 bits of the CRC
+ do ibit=1,8
+ msgbits(79+ibit)=iand(1,ishft(i1,ibit-8))
+ enddo
+
+ write(*,*) 'message'
+ write(*,'(11(8i1,1x))') msgbits
+
+ call encode174(msgbits,codeword)
+ call init_random_seed()
+! call sgran()
+
+ write(*,*) 'codeword'
+ write(*,'(22(8i1,1x))') codeword
+
+write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma"
+do idb = 20,-10,-1
+!do idb = -3,-3,-1
+ db=idb/2.0-1.0
+ sigma=1/sqrt( 2*(10**(db/10.0)) )
+ ngood=0
+ nue=0
+ nbadcrc=0
+ nberr=0
+ do itrial=1, ntrials
+! Create a realization of a noisy received word
+ do i=1,N
+ if( bpsk ) then
+ rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
+ elseif( fsk ) then
+ if( codeword(i) .eq. 1 ) then
+ r1=(1.0 + sigma*gran())**2 + (sigma*gran())**2
+ r2=(sigma*gran())**2 + (sigma*gran())**2
+ elseif( codeword(i) .eq. 0 ) then
+ r2=(1.0 + sigma*gran())**2 + (sigma*gran())**2
+ r1=(sigma*gran())**2 + (sigma*gran())**2
+ endif
+! rxdata(i)=0.35*(sqrt(r1)-sqrt(r2))
+! rxdata(i)=0.35*(exp(r1)-exp(r2))
+ rxdata(i)=0.12*(log(r1)-log(r2))
+ endif
+ enddo
+ nerr=0
+ do i=1,N
+ if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
+ enddo
+ if(nerr.ge.1) nerrtot(nerr)=nerrtot(nerr)+1
+ nberr=nberr+nerr
+
+! Correct signal normalization is important for this decoder.
+ rxav=sum(rxdata)/N
+ rx2av=sum(rxdata*rxdata)/N
+ rxsig=sqrt(rx2av-rxav*rxav)
+ rxdata=rxdata/rxsig
+! To match the metric to the channel, s should be set to the noise standard deviation.
+! For now, set s to the value that optimizes decode probability near threshold.
+! The s parameter can be tuned to trade a few tenth's dB of threshold for an order of
+! magnitude in UER
+ if( s .lt. 0 ) then
+ ss=sigma
+ else
+ ss=s
+ endif
+
+ llr=2.0*rxdata/(ss*ss)
+ nap=0 ! number of AP bits
+ llr(colorder(174-87+1:174-87+nap)+1)=5*(2.0*msgbits(1:nap)-1.0)
+ apmask=0
+ apmask(colorder(174-87+1:174-87+nap)+1)=1
+
+! max_iterations is max number of belief propagation iterations
+ call bpdecode174(llr, apmask, max_iterations, decoded, cw, nharderrors,niterations)
+ if( ndepth .ge. 0 .and. nharderrors .lt. 0 ) call osd174(llr, apmask, ndepth, decoded, cw, nharderrors, dmin)
+! If the decoder finds a valid codeword, nharderrors will be .ge. 0.
+ if( nharderrors .ge. 0 ) then
+ call extractmessage174(decoded,msgreceived,ncrcflag)
+ if( ncrcflag .ne. 1 ) then
+ nbadcrc=nbadcrc+1
+ endif
+
+ nueflag=0
+ nerrmpc=0
+ do i=1,K ! find number of errors in message+crc part of codeword
+ if( msgbits(i) .ne. decoded(i) ) then
+ nueflag=1
+ nerrmpc=nerrmpc+1
+ endif
+ enddo
+ if(nerrmpc.ge.1) nmpcbad(nerrmpc)=nmpcbad(nerrmpc)+1
+ if( ncrcflag .eq. 1 ) then
+ if( nueflag .eq. 0 ) then
+ ngood=ngood+1
+ if(nerr.ge.1) nerrdec(nerr)=nerrdec(nerr)+1
+ else if( nueflag .eq. 1 ) then
+ nue=nue+1;
+ endif
+ endif
+ endif
+ enddo
+ baud=12000.0/NSPS
+ snr2500=db+10.0*log10((baud/2500.0))
+ pberr=real(nberr)/(real(ntrials*N))
+ write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,snr2500,ngood,nue,nbadcrc,ss,pberr
+
+enddo
+
+open(unit=23,file='nerrhisto.dat',status='unknown')
+do i=1,174
+ write(23,'(i4,2x,i10,i10,f10.2)') i,nerrdec(i),nerrtot(i),real(nerrdec(i))/real(nerrtot(i)+1e-10)
+enddo
+close(23)
+open(unit=25,file='nmpcbad.dat',status='unknown')
+do i=1,87
+ write(25,'(i4,2x,i10)') i,nmpcbad(i)
+enddo
+close(25)
+
+end program ldpcsim174js8
diff --git a/lib/js8/ldpcsim174js8c.f90 b/lib/js8/ldpcsim174js8c.f90
new file mode 100644
index 0000000..d42070d
--- /dev/null
+++ b/lib/js8/ldpcsim174js8c.f90
@@ -0,0 +1,238 @@
+program ldpcsim174js8
+! End to end test of the (174,75)/crc12 encoder and decoder.
+use crc
+use packjt
+
+include 'js8_params.f90'
+include 'js8c_params.f90'
+
+character*22 msg,msgsent,msgreceived
+character*8 arg
+character*6 grid
+integer*1, allocatable :: codeword(:), decoded(:), message(:)
+integer*1, target:: i1Msg8BitBytes(11)
+integer*1 msgbits(87)
+integer*1 apmask(174), cw(174)
+integer*2 checksum
+integer*4 i4Msg6BitWords(13)
+integer colorder(174)
+integer nerrtot(174),nerrdec(174),nmpcbad(87)
+logical checksumok,fsk,bpsk
+real*8, allocatable :: rxdata(:)
+real, allocatable :: llr(:)
+
+data colorder/ &
+ 0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16,&
+ 17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43,&
+ 36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62,&
+ 56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79,&
+ 73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,&
+ 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,&
+ 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,&
+ 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,&
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173/
+
+nerrtot=0
+nerrdec=0
+nmpcbad=0 ! Used to collect the number of errors in the message+crc part of the codeword
+
+nargs=iargc()
+if(nargs.ne.4) then
+ print*,'Usage: ldpcsim niter ndepth #trials s '
+ print*,'eg: ldpcsim 10 2 1000 0.84'
+ print*,'belief propagation iterations: niter, ordered-statistics depth: ndepth'
+ print*,'If s is negative, then value is ignored and sigma is calculated from SNR.'
+ return
+endif
+call getarg(1,arg)
+read(arg,*) max_iterations
+call getarg(2,arg)
+read(arg,*) ndepth
+call getarg(3,arg)
+read(arg,*) ntrials
+call getarg(4,arg)
+read(arg,*) s
+
+fsk=.false.
+bpsk=.true.
+
+! don't count crc bits as data bits
+N=174
+K=87
+! scale Eb/No for a (174,87) code
+rate=real(K)/real(N)
+
+write(*,*) "rate: ",rate
+write(*,*) "niter= ",max_iterations," s= ",s
+
+allocate ( codeword(N), decoded(K), message(K) )
+allocate ( rxdata(N), llr(N) )
+
+ msg="0123456789012"
+! msg="G4WJS K9AN EN50"
+ call packmsg(msg,i4Msg6BitWords,itype,.false.) !Pack into 12 6-bit bytes
+ call unpackmsg(i4Msg6BitWords,msgsent,.false.,grid) !Unpack to get msgsent
+ write(*,*) "message sent ",msgsent
+
+ i4=0
+ ik=0
+ im=0
+ do i=1,12
+ nna=i4Msg6BitWords(i)
+ do j=1, 6
+ ik=ik+1
+ i4=i4+i4+iand(1,ishft(nna,j-6))
+ i4=iand(i4,255)
+ if(ik.eq.8) then
+ im=im+1
+! if(i4.gt.127) i4=i4-256
+ i1Msg8BitBytes(im)=i4
+ ik=0
+ endif
+ enddo
+ enddo
+
+ i1Msg8BitBytes(10:11)=0
+ checksum = crc12 (c_loc (i1Msg8BitBytes), 11)
+ checksum = xor(checksum, 42) ! TODO: jsherer - could change the crc here
+! For reference, the next 3 lines show how to check the CRC
+ i1Msg8BitBytes(10)=checksum/256
+ i1Msg8BitBytes(11)=iand(checksum,transfer(255,0_2))
+ checksumok = crc12_check(c_loc (i1Msg8BitBytes), 11)
+ if( checksumok ) write(*,*) 'Good checksum'
+
+! K=87, For now:
+! msgbits(1:72) JT message bits
+! msgbits(73:75) 3 free message bits (set to 0)
+! msgbits(76:87) CRC12
+ mbit=0
+ do i=1, 9
+ i1=i1Msg8BitBytes(i)
+ do ibit=1,8
+ mbit=mbit+1
+ msgbits(mbit)=iand(1,ishft(i1,ibit-8))
+ enddo
+ enddo
+ msgbits(73:75)=0 ! the three extra message bits go here
+ i1=i1Msg8BitBytes(10) ! First 4 bits of crc12 are LSB of this byte
+ do ibit=1,4
+ msgbits(75+ibit)=iand(1,ishft(i1,ibit-4))
+ enddo
+ i1=i1Msg8BitBytes(11) ! Now shift in last 8 bits of the CRC
+ do ibit=1,8
+ msgbits(79+ibit)=iand(1,ishft(i1,ibit-8))
+ enddo
+
+ write(*,*) 'message'
+ write(*,'(11(8i1,1x))') msgbits
+
+ call encode174(msgbits,codeword)
+ call init_random_seed()
+! call sgran()
+
+ write(*,*) 'codeword'
+ write(*,'(22(8i1,1x))') codeword
+
+write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma"
+do idb = 20,-10,-1
+!do idb = -3,-3,-1
+ db=idb/2.0-1.0
+ sigma=1/sqrt( 2*(10**(db/10.0)) )
+ ngood=0
+ nue=0
+ nbadcrc=0
+ nberr=0
+ do itrial=1, ntrials
+! Create a realization of a noisy received word
+ do i=1,N
+ if( bpsk ) then
+ rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
+ elseif( fsk ) then
+ if( codeword(i) .eq. 1 ) then
+ r1=(1.0 + sigma*gran())**2 + (sigma*gran())**2
+ r2=(sigma*gran())**2 + (sigma*gran())**2
+ elseif( codeword(i) .eq. 0 ) then
+ r2=(1.0 + sigma*gran())**2 + (sigma*gran())**2
+ r1=(sigma*gran())**2 + (sigma*gran())**2
+ endif
+! rxdata(i)=0.35*(sqrt(r1)-sqrt(r2))
+! rxdata(i)=0.35*(exp(r1)-exp(r2))
+ rxdata(i)=0.12*(log(r1)-log(r2))
+ endif
+ enddo
+ nerr=0
+ do i=1,N
+ if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
+ enddo
+ if(nerr.ge.1) nerrtot(nerr)=nerrtot(nerr)+1
+ nberr=nberr+nerr
+
+! Correct signal normalization is important for this decoder.
+ rxav=sum(rxdata)/N
+ rx2av=sum(rxdata*rxdata)/N
+ rxsig=sqrt(rx2av-rxav*rxav)
+ rxdata=rxdata/rxsig
+! To match the metric to the channel, s should be set to the noise standard deviation.
+! For now, set s to the value that optimizes decode probability near threshold.
+! The s parameter can be tuned to trade a few tenth's dB of threshold for an order of
+! magnitude in UER
+ if( s .lt. 0 ) then
+ ss=sigma
+ else
+ ss=s
+ endif
+
+ llr=2.0*rxdata/(ss*ss)
+ nap=0 ! number of AP bits
+ llr(colorder(174-87+1:174-87+nap)+1)=5*(2.0*msgbits(1:nap)-1.0)
+ apmask=0
+ apmask(colorder(174-87+1:174-87+nap)+1)=1
+
+! max_iterations is max number of belief propagation iterations
+ call bpdecode174(llr, apmask, max_iterations, decoded, cw, nharderrors,niterations)
+ if( ndepth .ge. 0 .and. nharderrors .lt. 0 ) call osd174(llr, apmask, ndepth, decoded, cw, nharderrors, dmin)
+! If the decoder finds a valid codeword, nharderrors will be .ge. 0.
+ if( nharderrors .ge. 0 ) then
+ call extractmessage174(decoded,msgreceived,ncrcflag)
+ if( ncrcflag .ne. 1 ) then
+ nbadcrc=nbadcrc+1
+ endif
+
+ nueflag=0
+ nerrmpc=0
+ do i=1,K ! find number of errors in message+crc part of codeword
+ if( msgbits(i) .ne. decoded(i) ) then
+ nueflag=1
+ nerrmpc=nerrmpc+1
+ endif
+ enddo
+ if(nerrmpc.ge.1) nmpcbad(nerrmpc)=nmpcbad(nerrmpc)+1
+ if( ncrcflag .eq. 1 ) then
+ if( nueflag .eq. 0 ) then
+ ngood=ngood+1
+ if(nerr.ge.1) nerrdec(nerr)=nerrdec(nerr)+1
+ else if( nueflag .eq. 1 ) then
+ nue=nue+1;
+ endif
+ endif
+ endif
+ enddo
+ baud=12000.0/NSPS
+ snr2500=db+10.0*log10((baud/2500.0))
+ pberr=real(nberr)/(real(ntrials*N))
+ write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,snr2500,ngood,nue,nbadcrc,ss,pberr
+
+enddo
+
+open(unit=23,file='nerrhisto.dat',status='unknown')
+do i=1,174
+ write(23,'(i4,2x,i10,i10,f10.2)') i,nerrdec(i),nerrtot(i),real(nerrdec(i))/real(nerrtot(i)+1e-10)
+enddo
+close(23)
+open(unit=25,file='nmpcbad.dat',status='unknown')
+do i=1,87
+ write(25,'(i4,2x,i10)') i,nmpcbad(i)
+enddo
+close(25)
+
+end program ldpcsim174js8
diff --git a/lib/js8/ldpcsim174js8d.f90 b/lib/js8/ldpcsim174js8d.f90
new file mode 100644
index 0000000..44f6a05
--- /dev/null
+++ b/lib/js8/ldpcsim174js8d.f90
@@ -0,0 +1,238 @@
+program ldpcsim174js8
+! End to end test of the (174,75)/crc12 encoder and decoder.
+use crc
+use packjt
+
+include 'js8_params.f90'
+include 'js8d_params.f90'
+
+character*22 msg,msgsent,msgreceived
+character*8 arg
+character*6 grid
+integer*1, allocatable :: codeword(:), decoded(:), message(:)
+integer*1, target:: i1Msg8BitBytes(11)
+integer*1 msgbits(87)
+integer*1 apmask(174), cw(174)
+integer*2 checksum
+integer*4 i4Msg6BitWords(13)
+integer colorder(174)
+integer nerrtot(174),nerrdec(174),nmpcbad(87)
+logical checksumok,fsk,bpsk
+real*8, allocatable :: rxdata(:)
+real, allocatable :: llr(:)
+
+data colorder/ &
+ 0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16,&
+ 17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43,&
+ 36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62,&
+ 56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79,&
+ 73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,&
+ 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,&
+ 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,&
+ 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,&
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173/
+
+nerrtot=0
+nerrdec=0
+nmpcbad=0 ! Used to collect the number of errors in the message+crc part of the codeword
+
+nargs=iargc()
+if(nargs.ne.4) then
+ print*,'Usage: ldpcsim niter ndepth #trials s '
+ print*,'eg: ldpcsim 10 2 1000 0.84'
+ print*,'belief propagation iterations: niter, ordered-statistics depth: ndepth'
+ print*,'If s is negative, then value is ignored and sigma is calculated from SNR.'
+ return
+endif
+call getarg(1,arg)
+read(arg,*) max_iterations
+call getarg(2,arg)
+read(arg,*) ndepth
+call getarg(3,arg)
+read(arg,*) ntrials
+call getarg(4,arg)
+read(arg,*) s
+
+fsk=.false.
+bpsk=.true.
+
+! don't count crc bits as data bits
+N=174
+K=87
+! scale Eb/No for a (174,87) code
+rate=real(K)/real(N)
+
+write(*,*) "rate: ",rate
+write(*,*) "niter= ",max_iterations," s= ",s
+
+allocate ( codeword(N), decoded(K), message(K) )
+allocate ( rxdata(N), llr(N) )
+
+ msg="0123456789012"
+! msg="G4WJS K9AN EN50"
+ call packmsg(msg,i4Msg6BitWords,itype,.false.) !Pack into 12 6-bit bytes
+ call unpackmsg(i4Msg6BitWords,msgsent,.false.,grid) !Unpack to get msgsent
+ write(*,*) "message sent ",msgsent
+
+ i4=0
+ ik=0
+ im=0
+ do i=1,12
+ nna=i4Msg6BitWords(i)
+ do j=1, 6
+ ik=ik+1
+ i4=i4+i4+iand(1,ishft(nna,j-6))
+ i4=iand(i4,255)
+ if(ik.eq.8) then
+ im=im+1
+! if(i4.gt.127) i4=i4-256
+ i1Msg8BitBytes(im)=i4
+ ik=0
+ endif
+ enddo
+ enddo
+
+ i1Msg8BitBytes(10:11)=0
+ checksum = crc12 (c_loc (i1Msg8BitBytes), 11)
+ checksum = xor(checksum, 42) ! TODO: jsherer - could change the crc here
+! For reference, the next 3 lines show how to check the CRC
+ i1Msg8BitBytes(10)=checksum/256
+ i1Msg8BitBytes(11)=iand(checksum,transfer(255,0_2))
+ checksumok = crc12_check(c_loc (i1Msg8BitBytes), 11)
+ if( checksumok ) write(*,*) 'Good checksum'
+
+! K=87, For now:
+! msgbits(1:72) JT message bits
+! msgbits(73:75) 3 free message bits (set to 0)
+! msgbits(76:87) CRC12
+ mbit=0
+ do i=1, 9
+ i1=i1Msg8BitBytes(i)
+ do ibit=1,8
+ mbit=mbit+1
+ msgbits(mbit)=iand(1,ishft(i1,ibit-8))
+ enddo
+ enddo
+ msgbits(73:75)=0 ! the three extra message bits go here
+ i1=i1Msg8BitBytes(10) ! First 4 bits of crc12 are LSB of this byte
+ do ibit=1,4
+ msgbits(75+ibit)=iand(1,ishft(i1,ibit-4))
+ enddo
+ i1=i1Msg8BitBytes(11) ! Now shift in last 8 bits of the CRC
+ do ibit=1,8
+ msgbits(79+ibit)=iand(1,ishft(i1,ibit-8))
+ enddo
+
+ write(*,*) 'message'
+ write(*,'(11(8i1,1x))') msgbits
+
+ call encode174(msgbits,codeword)
+ call init_random_seed()
+! call sgran()
+
+ write(*,*) 'codeword'
+ write(*,'(22(8i1,1x))') codeword
+
+write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma"
+do idb = 20,-10,-1
+!do idb = -3,-3,-1
+ db=idb/2.0-1.0
+ sigma=1/sqrt( 2*(10**(db/10.0)) )
+ ngood=0
+ nue=0
+ nbadcrc=0
+ nberr=0
+ do itrial=1, ntrials
+! Create a realization of a noisy received word
+ do i=1,N
+ if( bpsk ) then
+ rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
+ elseif( fsk ) then
+ if( codeword(i) .eq. 1 ) then
+ r1=(1.0 + sigma*gran())**2 + (sigma*gran())**2
+ r2=(sigma*gran())**2 + (sigma*gran())**2
+ elseif( codeword(i) .eq. 0 ) then
+ r2=(1.0 + sigma*gran())**2 + (sigma*gran())**2
+ r1=(sigma*gran())**2 + (sigma*gran())**2
+ endif
+! rxdata(i)=0.35*(sqrt(r1)-sqrt(r2))
+! rxdata(i)=0.35*(exp(r1)-exp(r2))
+ rxdata(i)=0.12*(log(r1)-log(r2))
+ endif
+ enddo
+ nerr=0
+ do i=1,N
+ if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
+ enddo
+ if(nerr.ge.1) nerrtot(nerr)=nerrtot(nerr)+1
+ nberr=nberr+nerr
+
+! Correct signal normalization is important for this decoder.
+ rxav=sum(rxdata)/N
+ rx2av=sum(rxdata*rxdata)/N
+ rxsig=sqrt(rx2av-rxav*rxav)
+ rxdata=rxdata/rxsig
+! To match the metric to the channel, s should be set to the noise standard deviation.
+! For now, set s to the value that optimizes decode probability near threshold.
+! The s parameter can be tuned to trade a few tenth's dB of threshold for an order of
+! magnitude in UER
+ if( s .lt. 0 ) then
+ ss=sigma
+ else
+ ss=s
+ endif
+
+ llr=2.0*rxdata/(ss*ss)
+ nap=0 ! number of AP bits
+ llr(colorder(174-87+1:174-87+nap)+1)=5*(2.0*msgbits(1:nap)-1.0)
+ apmask=0
+ apmask(colorder(174-87+1:174-87+nap)+1)=1
+
+! max_iterations is max number of belief propagation iterations
+ call bpdecode174(llr, apmask, max_iterations, decoded, cw, nharderrors,niterations)
+ if( ndepth .ge. 0 .and. nharderrors .lt. 0 ) call osd174(llr, apmask, ndepth, decoded, cw, nharderrors, dmin)
+! If the decoder finds a valid codeword, nharderrors will be .ge. 0.
+ if( nharderrors .ge. 0 ) then
+ call extractmessage174(decoded,msgreceived,ncrcflag)
+ if( ncrcflag .ne. 1 ) then
+ nbadcrc=nbadcrc+1
+ endif
+
+ nueflag=0
+ nerrmpc=0
+ do i=1,K ! find number of errors in message+crc part of codeword
+ if( msgbits(i) .ne. decoded(i) ) then
+ nueflag=1
+ nerrmpc=nerrmpc+1
+ endif
+ enddo
+ if(nerrmpc.ge.1) nmpcbad(nerrmpc)=nmpcbad(nerrmpc)+1
+ if( ncrcflag .eq. 1 ) then
+ if( nueflag .eq. 0 ) then
+ ngood=ngood+1
+ if(nerr.ge.1) nerrdec(nerr)=nerrdec(nerr)+1
+ else if( nueflag .eq. 1 ) then
+ nue=nue+1;
+ endif
+ endif
+ endif
+ enddo
+ baud=12000.0/NSPS
+ snr2500=db+10.0*log10((baud/2500.0))
+ pberr=real(nberr)/(real(ntrials*N))
+ write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,snr2500,ngood,nue,nbadcrc,ss,pberr
+
+enddo
+
+open(unit=23,file='nerrhisto.dat',status='unknown')
+do i=1,174
+ write(23,'(i4,2x,i10,i10,f10.2)') i,nerrdec(i),nerrtot(i),real(nerrdec(i))/real(nerrtot(i)+1e-10)
+enddo
+close(23)
+open(unit=25,file='nmpcbad.dat',status='unknown')
+do i=1,87
+ write(25,'(i4,2x,i10)') i,nmpcbad(i)
+enddo
+close(25)
+
+end program ldpcsim174js8
diff --git a/lib/js8/subtractjs8.f90 b/lib/js8/subtractjs8.f90
new file mode 100644
index 0000000..c5689c5
--- /dev/null
+++ b/lib/js8/subtractjs8.f90
@@ -0,0 +1,64 @@
+subroutine subtractjs8(dd,itone,f0,dt)
+
+! Subtract an ft8 signal
+!
+! Measured signal : dd(t) = a(t)cos(2*pi*f0*t+theta(t))
+! Reference signal : cref(t) = exp( j*(2*pi*f0*t+phi(t)) )
+! Complex amp : cfilt(t) = LPF[ dd(t)*CONJG(cref(t)) ]
+! Subtract : dd(t) = dd(t) - 2*REAL{cref*cfilt}
+
+ use timer_module, only: timer
+
+ !include 'js8_params.f90'
+
+ parameter (NFRAME=NSPS*NN)
+ parameter (NFFT=NMAX, NFILT=1400)
+
+ real*4 dd(NMAX), window(-NFILT/2:NFILT/2)
+ complex cref,camp,cfilt,cw
+ integer itone(NN)
+ logical first
+ data first/.true./
+ common/heap8/cref(NFRAME),camp(NMAX),cfilt(NMAX),cw(NMAX)
+ save first
+
+ nstart=dt*12000+1
+ call genjs8refsig(itone,cref,f0)
+ camp=0.
+ do i=1,nframe
+ id=nstart-1+i
+ if(id.ge.1.and.id.le.NMAX) camp(i)=dd(id)*conjg(cref(i))
+ enddo
+
+ if(first) then
+! Create and normalize the filter
+ pi=4.0*atan(1.0)
+ fac=1.0/float(nfft)
+ sum=0.0
+ do j=-NFILT/2,NFILT/2
+ window(j)=cos(pi*j/NFILT)**2
+ sum=sum+window(j)
+ enddo
+ cw=0.
+ cw(1:NFILT+1)=window/sum
+ cw=cshift(cw,NFILT/2+1)
+ call four2a(cw,nfft,1,-1,1)
+ cw=cw*fac
+ first=.false.
+ endif
+
+ cfilt=0.0
+ cfilt(1:nframe)=camp(1:nframe)
+ call four2a(cfilt,nfft,1,-1,1)
+ cfilt(1:nfft)=cfilt(1:nfft)*cw(1:nfft)
+ call four2a(cfilt,nfft,1,1,1)
+
+! Subtract the reconstructed signal
+ do i=1,nframe
+ j=nstart+i-1
+ if(j.ge.1 .and. j.le.NMAX) dd(j)=dd(j)-2*REAL(cfilt(i)*cref(i))
+ enddo
+
+ return
+end subroutine subtractjs8
+
diff --git a/lib/js8/syncjs8.f90 b/lib/js8/syncjs8.f90
new file mode 100644
index 0000000..f4008bd
--- /dev/null
+++ b/lib/js8/syncjs8.f90
@@ -0,0 +1,183 @@
+subroutine syncjs8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
+
+ !include 'js8_params.f90'
+
+ complex cx(0:NH1)
+ real s(NH1,NHSYM)
+ real savg(NH1)
+ real sbase(NH1)
+ real x(NFFT1)
+ real sync2d(NH1,-JZ:JZ)
+ real red(NH1)
+ real candidate0(3,200)
+ real candidate(3,200)
+ real dd(NMAX)
+ integer jpeak(NH1)
+ integer indx(NH1)
+ integer ii(1)
+ integer syoff !symbol offset
+ equivalence (x,cx)
+
+ integer icos7a(0:6), icos7b(0:6), icos7c(0:6)
+ if(NCOSTAS.eq.1) then
+ icos7a = (/4,2,5,6,1,3,0/) !Beginning Costas 7x7 tone pattern
+ icos7b = (/4,2,5,6,1,3,0/) !Middle Costas 7x7 tone pattern
+ icos7c = (/4,2,5,6,1,3,0/) !End Costas 7x7 tone pattern
+ else
+ icos7a = (/0,6,2,3,5,4,1/) !Beginning Costas 7x7 tone pattern
+ icos7b = (/1,5,0,2,3,6,4/) !Middle Costas 7x7 tone pattern
+ icos7c = (/2,5,0,6,4,1,3/) !End Costas 7x7 tone pattern
+ endif
+
+! Compute symbol spectra, stepping by NSTEP steps.
+ savg=0.
+ tstep=NSTEP/12000.0
+ df=12000.0/NFFT1
+ fac=1.0/300.0
+ do j=1,NHSYM
+ ia=(j-1)*NSTEP + 1
+ ib=ia+NSPS-1
+ x(1:NSPS)=fac*dd(ia:ib)
+ x(NSPS+1:)=0.
+ call four2a(x,NFFT1,1,-1,0) !r2c FFT
+ do i=1,NH1
+ s(i,j)=real(cx(i))**2 + aimag(cx(i))**2
+ enddo
+ savg=savg + s(1:NH1,j) !Average spectrum
+ enddo
+ call baselinejs8(savg,nfa,nfb,sbase)
+
+ ia=max(1,nint(nfa/df)) ! min freq
+ ib=nint(nfb/df) ! max freq
+ nssy=NSPS/NSTEP ! steps per symbol
+ nfos=NFFT1/NSPS ! frequency bin oversampling factor
+ jstrt=ASTART/tstep ! the symbol step that we are starting at (NHSYM)
+
+ candidate0=0.
+ k=0
+
+ do i=ia,ib
+ do j=-JZ,+JZ
+ ta=0.
+ tb=0.
+ tc=0.
+ t0a=0.
+ t0b=0.
+ t0c=0.
+ do n=0,6
+ k=j+jstrt+nssy*n
+
+ syoff=k
+ if(syoff.ge.1.and.syoff.le.NHSYM) then
+ ta=ta + s(i+nfos*icos7a(n),syoff)
+ t0a=t0a + sum(s(i:i+nfos*6:nfos,syoff))
+ endif
+
+ syoff=k+nssy*36
+ if(syoff.ge.1.and.syoff.le.NHSYM) then
+ tb=tb + s(i+nfos*icos7b(n),syoff)
+ t0b=t0b + sum(s(i:i+nfos*6:nfos,syoff))
+ endif
+
+ syoff=k+nssy*72
+ if(syoff.ge.1.and.syoff.le.NHSYM) then
+ tc=tc + s(i+nfos*icos7c(n),syoff)
+ t0c=t0c + sum(s(i:i+nfos*6:nfos,syoff))
+ endif
+ enddo
+
+ t=ta+tb+tc
+ t0=t0a+t0b+t0c
+ t0=(t0-t)/6.0
+ sync_abc=t/t0
+
+ t=ta+tb
+ t0=t0a+t0b
+ t0=(t0-t)/6.0
+ sync_ab=t/t0
+
+ t=ta+tc
+ t0=t0a+t0c
+ t0=(t0-t)/6.0
+ sync_ac=t/t0
+
+ t=tb+tc
+ t0=t0b+t0c
+ t0=(t0-t)/6.0
+ sync_bc=t/t0
+
+ !sync2d(i,j)=max(max(max(sync_abc, sync_ab), sync_ac), sync_bc)
+ sync2d(i,j)=max(sync_abc, sync_ab, sync_bc)
+ enddo
+ enddo
+
+ red=0.
+ do i=ia,ib
+ ii=maxloc(sync2d(i,-JZ:JZ)) - 1 - JZ
+ j0=ii(1)
+ jpeak(i)=j0
+ red(i)=sync2d(i,j0)
+ enddo
+
+ iz=ib-ia+1
+ call indexx(red(ia:ib),iz,indx)
+
+ ibase=indx(nint(0.40*iz)) - 1 + ia
+ if(ibase.lt.1) ibase=1
+ if(ibase.gt.nh1) ibase=nh1
+ base=red(ibase)
+ red=red/base
+
+ k=0
+ do i=1,min(200,iz)
+ if(k.ge.200) exit
+ n=ia + indx(iz+1-i) - 1
+ if(red(n).lt.syncmin.or.isnan(red(n))) exit
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'red candidate', red(n), n*df, (jpeak(n)-1)*tstep
+ close(99)
+ endif
+ k=k+1
+ candidate0(1,k)=n*df
+ candidate0(2,k)=(jpeak(n)-1)*tstep
+ candidate0(3,k)=red(n)
+ enddo
+ ncand=k
+
+! Put nfqso at top of list, and save only the best of near-dupe freqs.
+ do i=1,ncand
+ if(abs(candidate0(1,i)-nfqso).lt.10.0) candidate0(1,i)=-candidate0(1,i)
+ if(i.ge.2) then
+ do j=1,i-1
+ fdiff=abs(candidate0(1,i))-abs(candidate0(1,j))
+ if(abs(fdiff).lt.AZ) then ! note: this dedupe difference is dependent on symbol spacing
+ if(candidate0(3,i).ge.candidate0(3,j)) candidate0(3,j)=0.
+ if(candidate0(3,i).lt.candidate0(3,j)) candidate0(3,i)=0.
+ endif
+ enddo
+ endif
+ enddo
+
+ fac=20.0/maxval(s)
+ s=fac*s
+
+! Sort by sync
+! call indexx(candidate0(3,1:ncand),ncand,indx)
+! Sort by frequency
+ call indexx(candidate0(1,1:ncand),ncand,indx)
+ k=1
+! do i=ncand,1,-1
+ do i=1,ncand
+ j=indx(i)
+! if( candidate0(3,j) .ge. syncmin .and. candidate0(2,j).ge.-1.5 ) then
+ if( candidate0(3,j) .ge. syncmin ) then
+ candidate(1,k)=abs(candidate0(1,j))
+ candidate(2,k)=candidate0(2,j)
+ candidate(3,k)=candidate0(3,j)
+ k=k+1
+ endif
+ enddo
+ ncand=k-1
+ return
+end subroutine syncjs8
diff --git a/lib/js8/syncjs8d.f90 b/lib/js8/syncjs8d.f90
new file mode 100644
index 0000000..532e704
--- /dev/null
+++ b/lib/js8/syncjs8d.f90
@@ -0,0 +1,89 @@
+subroutine syncjs8d(cd0,i0,ctwk,itwk,sync)
+! Compute sync power for a complex, downsampled FT8 signal.
+
+ !include 'js8_params.f90'
+
+ parameter(NP=NMAX/NDOWN,NSS=NSPS/NDOWN)
+ complex cd0(0:NP-1)
+ complex csynca(4*NSS),csyncb(4*NSS),csyncc(4*NSS)
+ complex csync2(4*NSS)
+ complex ctwk(4*NSS)
+ complex z1,z2,z3
+ logical first
+ data first/.true./
+ save first,twopi,csynca,csyncb,csyncc
+
+ p(z1)=(real(z1)**2 + aimag(z1)**2) !Statement function for power
+
+ integer icos7a(0:6), icos7b(0:6), icos7c(0:6)
+ if(NCOSTAS.eq.1) then
+ icos7a = (/4,2,5,6,1,3,0/) !Beginning Costas 7x7 tone pattern
+ icos7b = (/4,2,5,6,1,3,0/) !Middle Costas 7x7 tone pattern
+ icos7c = (/4,2,5,6,1,3,0/) !End Costas 7x7 tone pattern
+ else
+ icos7a = (/0,6,2,3,5,4,1/) !Beginning Costas 7x7 tone pattern
+ icos7b = (/1,5,0,2,3,6,4/) !Middle Costas 7x7 tone pattern
+ icos7c = (/2,5,0,6,4,1,3/) !End Costas 7x7 tone pattern
+ endif
+
+! Set some constants and compute the csync array.
+ if( first ) then
+ twopi=8.0*atan(1.0)
+
+ k=1
+ phia=0.0
+ phib=0.0
+ phic=0.0
+
+ !fs2=12000.0/NDOWN !Sample rate after downsampling
+ !dt2=1/fs2 !Corresponding sample interval
+ !taus=NDOWNSPS*dt2 !Symbol duration
+ !baud=1.0/taus !Keying rate
+
+ do i=0,6
+
+ dphia=2*twopi*icos7a(i)/real(NSS)
+ dphib=2*twopi*icos7b(i)/real(NSS)
+ dphic=2*twopi*icos7c(i)/real(NSS)
+
+ do j=1,NSS/2
+
+ csynca(k)=cmplx(cos(phia),sin(phia)) !Waveform for Beginning 7x7 Costas array
+ csyncb(k)=cmplx(cos(phib),sin(phib)) !Waveform for Middle 7x7 Costas array
+ csyncc(k)=cmplx(cos(phic),sin(phic)) !Waveform for End 7x7 Costas array
+ phia=mod(phia+dphia,twopi)
+ phib=mod(phib+dphib,twopi)
+ phic=mod(phia+dphic,twopi)
+
+ k=k+1
+
+ enddo
+
+ enddo
+ first=.false.
+ endif
+
+ i1=i0 !four Costas arrays
+ i2=i0+36*NSS
+ i3=i0+72*NSS
+
+ z1=0.
+ z2=0.
+ z3=0.
+
+ csync2=csynca
+ if(itwk.eq.1) csync2=ctwk*csynca !Tweak the frequency
+ if(i1.ge.0 .and. i1+8*NSS-1.le.NP-1) z1=sum(cd0(i1:i1+8*NSS-1:2)*conjg(csync2))
+
+ csync2=csyncb
+ if(itwk.eq.1) csync2=ctwk*csyncb !Tweak the frequency
+ if(i2.ge.0 .and. i2+8*NSS-1.le.NP-1) z2=sum(cd0(i2:i2+8*NSS-1:2)*conjg(csync2))
+
+ csync2=csyncc
+ if(itwk.eq.1) csync2=ctwk*csyncc !Tweak the frequency
+ if(i3.ge.0 .and. i3+8*NSS-1.le.NP-1) z3=sum(cd0(i3:i3+8*NSS-1:2)*conjg(csync2))
+
+ sync = p(z1) + p(z2) + p(z3)
+
+ return
+end subroutine syncjs8d
diff --git a/lib/js8b_decode.f90 b/lib/js8b_decode.f90
new file mode 100644
index 0000000..22361b7
--- /dev/null
+++ b/lib/js8b_decode.f90
@@ -0,0 +1,157 @@
+module js8b_decode
+
+ type :: js8b_decoder
+ procedure(js8b_decode_callback), pointer :: callback
+ contains
+ procedure :: decode
+ end type js8b_decoder
+
+ abstract interface
+ subroutine js8b_decode_callback (this,sync,snr,dt,freq,decoded,nap,qual)
+ import js8b_decoder
+ implicit none
+ class(js8b_decoder), intent(inout) :: this
+ real, intent(in) :: sync
+ integer, intent(in) :: snr
+ real, intent(in) :: dt
+ real, intent(in) :: freq
+ character(len=37), intent(in) :: decoded
+ integer, intent(in) :: nap
+ real, intent(in) :: qual
+ end subroutine js8b_decode_callback
+ end interface
+
+contains
+
+ subroutine decode(this,callback,iwave,nQSOProgress,nfqso,nftx,newdat, &
+ nutc,nfa,nfb,nexp_decode,ndepth,nagain,lft8apon,lapcqonly,napwid, &
+ mycall12,mygrid6,hiscall12,hisgrid6)
+! use wavhdr
+ use timer_module, only: timer
+! type(hdr) h
+ use js8b_module
+
+ class(js8b_decoder), intent(inout) :: this
+ procedure(js8b_decode_callback) :: callback
+ real s(NH1,NHSYM)
+ real sbase(NH1)
+ real candidate(3,200)
+ real dd(NMAX)
+ logical, intent(in) :: lft8apon,lapcqonly,nagain
+ logical newdat,lsubtract,ldupe,bcontest
+ character*12 mycall12, hiscall12
+ character*6 mygrid6,hisgrid6
+ integer*2 iwave(NMAX)
+ integer apsym(KK)
+ character datetime*13,message*22,msg37*37
+ character*22 allmessages(100)
+ integer allsnrs(100)
+ save s,dd
+
+ bcontest=iand(nexp_decode,128).ne.0
+ this%callback => callback
+ write(datetime,1001) nutc !### TEMPORARY ###
+1001 format("000000_",i6.6)
+
+ call ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype)
+
+ dd=iwave
+ ndecodes=0
+ allmessages=' '
+ allsnrs=0
+ ifa=nfa
+ ifb=nfb
+ if(nagain) then
+ ifa=nfqso-10
+ ifb=nfqso+10
+ endif
+
+! For now:
+! ndepth=1: no subtraction, 1 pass, belief propagation only
+! ndepth=2: subtraction, 3 passes, belief propagation only
+! ndepth=3: subtraction, 3 passes, bp+osd
+ if(ndepth.eq.1) npass=1
+ if(ndepth.ge.2) npass=3
+ do ipass=1,npass
+ newdat=.true. ! Is this a problem? I hijacked newdat.
+ syncmin=ASYNCMIN
+ if(ipass.eq.1) then
+ lsubtract=.true.
+ if(ndepth.eq.1) lsubtract=.false.
+ elseif(ipass.eq.2) then
+ n2=ndecodes
+ if(ndecodes.eq.0) cycle
+ lsubtract=.true.
+ elseif(ipass.eq.3) then
+ if((ndecodes-n2).eq.0) cycle
+ lsubtract=.false.
+ endif
+
+ call timer('syncjs8 ',0)
+ call syncjs8(dd,ifa,ifb,syncmin,nfqso,s,candidate,ncand,sbase)
+ call timer('syncjs8 ',1)
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) ncand, "candidates"
+ write(99,*) "---"
+ close(99)
+ endif
+
+ do icand=1,ncand
+ sync=candidate(3,icand)
+ f1=candidate(1,icand)
+ xdt=candidate(2,icand)
+ xbase=10.0**(0.1*(sbase(nint(f1/(12000.0/NFFT1)))-40.0)) ! 3.125Hz
+ nsnr0=min(99,nint(10.0*log10(sync) - 25.5)) !### empirical ###
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'icand', icand, f1, sync, xdt, xbase
+ close(99)
+ endif
+
+ call timer('js8dec ',0)
+ call js8dec(dd,newdat,nQSOProgress,nfqso,nftx,ndepth,lft8apon, &
+ lapcqonly,napwid,lsubtract,nagain,iaptype,mycall12,mygrid6, &
+ hiscall12,bcontest,sync,f1,xdt,xbase,apsym,nharderrors,dmin, &
+ nbadcrc,iappass,iera,msg37,xsnr)
+ message=msg37(1:22) !###
+ nsnr=nint(xsnr)
+ xdt=xdt-ASTART
+ hd=nharderrors+dmin
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'icand', icand, hd, nbadcrc
+ close(99)
+ endif
+
+ call timer('js8dec ',1)
+ if(nbadcrc.eq.0) then
+ ldupe=.false.
+ do id=1,ndecodes
+ if(message.eq.allmessages(id).and.nsnr.le.allsnrs(id)) ldupe=.true.
+ enddo
+ if(.not.ldupe) then
+ ndecodes=ndecodes+1
+ allmessages(ndecodes)=message
+ allsnrs(ndecodes)=nsnr
+ endif
+ if(.not.ldupe .and. associated(this%callback)) then
+ qual=1.0-(nharderrors+dmin)/60.0 ! scale qual to [0.0,1.0]
+ call this%callback(sync,nsnr,xdt,f1,msg37,iaptype,qual)
+ endif
+ endif
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) '---'
+ close(99)
+ endif
+ enddo
+ enddo
+ return
+ end subroutine decode
+
+end module js8b_decode
diff --git a/lib/js8b_module.f90 b/lib/js8b_module.f90
new file mode 100644
index 0000000..8e099c2
--- /dev/null
+++ b/lib/js8b_module.f90
@@ -0,0 +1,13 @@
+module js8b_module
+ include 'js8/js8_params.f90'
+ include 'js8/js8b_params.f90'
+
+contains
+ include 'js8/baselinejs8.f90'
+ include 'js8/syncjs8.f90'
+ include 'js8/js8_downsample.f90'
+ include 'js8/syncjs8d.f90'
+ include 'js8/genjs8refsig.f90'
+ include 'js8/subtractjs8.f90'
+ include 'js8/js8dec.f90'
+end module js8b_module
diff --git a/lib/js8c_decode.f90 b/lib/js8c_decode.f90
new file mode 100644
index 0000000..cdb5da8
--- /dev/null
+++ b/lib/js8c_decode.f90
@@ -0,0 +1,156 @@
+module js8c_decode
+
+ type :: js8c_decoder
+ procedure(js8c_decode_callback), pointer :: callback
+ contains
+ procedure :: decode
+ end type js8c_decoder
+
+ abstract interface
+ subroutine js8c_decode_callback (this,sync,snr,dt,freq,decoded,nap,qual)
+ import js8c_decoder
+ implicit none
+ class(js8c_decoder), intent(inout) :: this
+ real, intent(in) :: sync
+ integer, intent(in) :: snr
+ real, intent(in) :: dt
+ real, intent(in) :: freq
+ character(len=37), intent(in) :: decoded
+ integer, intent(in) :: nap
+ real, intent(in) :: qual
+ end subroutine js8c_decode_callback
+ end interface
+
+contains
+
+ subroutine decode(this,callback,iwave,nQSOProgress,nfqso,nftx,newdat, &
+ nutc,nfa,nfb,nexp_decode,ndepth,nagain,lft8apon,lapcqonly,napwid, &
+ mycall12,mygrid6,hiscall12,hisgrid6)
+! use wavhdr
+ use timer_module, only: timer
+! type(hdr) h
+ use js8c_module
+
+ class(js8c_decoder), intent(inout) :: this
+ procedure(js8c_decode_callback) :: callback
+ real s(NH1,NHSYM)
+ real sbase(NH1)
+ real candidate(3,200)
+ real dd(NMAX)
+ logical, intent(in) :: lft8apon,lapcqonly,nagain
+ logical newdat,lsubtract,ldupe,bcontest
+ character*12 mycall12, hiscall12
+ character*6 mygrid6,hisgrid6
+ integer*2 iwave(NMAX)
+ integer apsym(KK)
+ character datetime*13,message*22,msg37*37
+ character*22 allmessages(100)
+ integer allsnrs(100)
+ save s,dd
+
+ bcontest=iand(nexp_decode,128).ne.0
+ this%callback => callback
+ write(datetime,1001) nutc !### TEMPORARY ###
+1001 format("000000_",i6.6)
+
+ call ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype)
+
+ dd=iwave
+ ndecodes=0
+ allmessages=' '
+ allsnrs=0
+ ifa=nfa
+ ifb=nfb
+ if(nagain) then
+ ifa=nfqso-10
+ ifb=nfqso+10
+ endif
+
+! For now:
+! ndepth=1: no subtraction, 1 pass, belief propagation only
+! ndepth=2: subtraction, 3 passes, belief propagation only
+! ndepth=3: subtraction, 3 passes, bp+osd
+ if(ndepth.eq.1) npass=1
+ if(ndepth.ge.2) npass=3
+ do ipass=1,npass
+ newdat=.true. ! Is this a problem? I hijacked newdat.
+ syncmin=ASYNCMIN
+ if(ipass.eq.1) then
+ lsubtract=.true.
+ if(ndepth.eq.1) lsubtract=.false.
+ elseif(ipass.eq.2) then
+ n2=ndecodes
+ if(ndecodes.eq.0) cycle
+ lsubtract=.true.
+ elseif(ipass.eq.3) then
+ if((ndecodes-n2).eq.0) cycle
+ lsubtract=.false.
+ endif
+
+ call timer('syncjs8 ',0)
+ call syncjs8(dd,ifa,ifb,syncmin,nfqso,s,candidate,ncand,sbase)
+ call timer('syncjs8 ',1)
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) ncand, "candidates"
+ close(99)
+ endif
+
+ do icand=1,ncand
+ sync=candidate(3,icand)
+ f1=candidate(1,icand)
+ xdt=candidate(2,icand)
+ xbase=10.0**(0.1*(sbase(nint(f1/(12000.0/NFFT1)))-40.0)) ! 3.125Hz
+ nsnr0=min(99,nint(10.0*log10(sync) - 25.5)) !### empirical ###
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'icand', icand, f1, sync, xdt, xbase
+ close(99)
+ endif
+
+ call timer('js8dec ',0)
+ call js8dec(dd,newdat,nQSOProgress,nfqso,nftx,ndepth,lft8apon, &
+ lapcqonly,napwid,lsubtract,nagain,iaptype,mycall12,mygrid6, &
+ hiscall12,bcontest,sync,f1,xdt,xbase,apsym,nharderrors,dmin, &
+ nbadcrc,iappass,iera,msg37,xsnr)
+ message=msg37(1:22) !###
+ nsnr=nint(xsnr)
+ xdt=xdt-ASTART
+ hd=nharderrors+dmin
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'icand', icand, hd, nbadcrc
+ close(99)
+ endif
+
+ call timer('js8dec ',1)
+ if(nbadcrc.eq.0) then
+ ldupe=.false.
+ do id=1,ndecodes
+ if(message.eq.allmessages(id).and.nsnr.le.allsnrs(id)) ldupe=.true.
+ enddo
+ if(.not.ldupe) then
+ ndecodes=ndecodes+1
+ allmessages(ndecodes)=message
+ allsnrs(ndecodes)=nsnr
+ endif
+ if(.not.ldupe .and. associated(this%callback)) then
+ qual=1.0-(nharderrors+dmin)/60.0 ! scale qual to [0.0,1.0]
+ call this%callback(sync,nsnr,xdt,f1,msg37,iaptype,qual)
+ endif
+ endif
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) '---'
+ close(99)
+ endif
+ enddo
+ enddo
+ return
+ end subroutine decode
+
+end module js8c_decode
diff --git a/lib/js8c_module.f90 b/lib/js8c_module.f90
new file mode 100644
index 0000000..b5f28b9
--- /dev/null
+++ b/lib/js8c_module.f90
@@ -0,0 +1,13 @@
+module js8c_module
+ include 'js8/js8_params.f90'
+ include 'js8/js8c_params.f90'
+
+contains
+ include 'js8/baselinejs8.f90'
+ include 'js8/syncjs8.f90'
+ include 'js8/js8_downsample.f90'
+ include 'js8/syncjs8d.f90'
+ include 'js8/genjs8refsig.f90'
+ include 'js8/subtractjs8.f90'
+ include 'js8/js8dec.f90'
+end module js8c_module
diff --git a/lib/js8d_decode.f90 b/lib/js8d_decode.f90
new file mode 100644
index 0000000..328fced
--- /dev/null
+++ b/lib/js8d_decode.f90
@@ -0,0 +1,156 @@
+module js8d_decode
+
+ type :: js8d_decoder
+ procedure(js8d_decode_callback), pointer :: callback
+ contains
+ procedure :: decode
+ end type js8d_decoder
+
+ abstract interface
+ subroutine js8d_decode_callback (this,sync,snr,dt,freq,decoded,nap,qual)
+ import js8d_decoder
+ implicit none
+ class(js8d_decoder), intent(inout) :: this
+ real, intent(in) :: sync
+ integer, intent(in) :: snr
+ real, intent(in) :: dt
+ real, intent(in) :: freq
+ character(len=37), intent(in) :: decoded
+ integer, intent(in) :: nap
+ real, intent(in) :: qual
+ end subroutine js8d_decode_callback
+ end interface
+
+contains
+
+ subroutine decode(this,callback,iwave,nQSOProgress,nfqso,nftx,newdat, &
+ nutc,nfa,nfb,nexp_decode,ndepth,nagain,lft8apon,lapcqonly,napwid, &
+ mycall12,mygrid6,hiscall12,hisgrid6)
+! use wavhdr
+ use timer_module, only: timer
+! type(hdr) h
+ use js8d_module
+
+ class(js8d_decoder), intent(inout) :: this
+ procedure(js8d_decode_callback) :: callback
+ real s(NH1,NHSYM)
+ real sbase(NH1)
+ real candidate(3,200)
+ real dd(NMAX)
+ logical, intent(in) :: lft8apon,lapcqonly,nagain
+ logical newdat,lsubtract,ldupe,bcontest
+ character*12 mycall12, hiscall12
+ character*6 mygrid6,hisgrid6
+ integer*2 iwave(NMAX)
+ integer apsym(KK)
+ character datetime*13,message*22,msg37*37
+ character*22 allmessages(100)
+ integer allsnrs(100)
+ save s,dd
+
+ bcontest=iand(nexp_decode,128).ne.0
+ this%callback => callback
+ write(datetime,1001) nutc !### TEMPORARY ###
+1001 format("000000_",i6.6)
+
+ call ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype)
+
+ dd=iwave
+ ndecodes=0
+ allmessages=' '
+ allsnrs=0
+ ifa=nfa
+ ifb=nfb
+ if(nagain) then
+ ifa=nfqso-10
+ ifb=nfqso+10
+ endif
+
+! For now:
+! ndepth=1: no subtraction, 1 pass, belief propagation only
+! ndepth=2: subtraction, 3 passes, belief propagation only
+! ndepth=3: subtraction, 3 passes, bp+osd
+ if(ndepth.eq.1) npass=1
+ if(ndepth.ge.2) npass=3
+ do ipass=1,npass
+ newdat=.true. ! Is this a problem? I hijacked newdat.
+ syncmin=ASYNCMIN
+ if(ipass.eq.1) then
+ lsubtract=.true.
+ if(ndepth.eq.1) lsubtract=.false.
+ elseif(ipass.eq.2) then
+ n2=ndecodes
+ if(ndecodes.eq.0) cycle
+ lsubtract=.true.
+ elseif(ipass.eq.3) then
+ if((ndecodes-n2).eq.0) cycle
+ lsubtract=.false.
+ endif
+
+ call timer('syncjs8 ',0)
+ call syncjs8(dd,ifa,ifb,syncmin,nfqso,s,candidate,ncand,sbase)
+ call timer('syncjs8 ',1)
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) ncand, "candidates"
+ close(99)
+ endif
+
+ do icand=1,ncand
+ sync=candidate(3,icand)
+ f1=candidate(1,icand)
+ xdt=candidate(2,icand)
+ xbase=10.0**(0.1*(sbase(nint(f1/(12000.0/NFFT1)))-40.0)) ! 3.125Hz
+ nsnr0=min(99,nint(10.0*log10(sync) - 25.5)) !### empirical ###
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'icand', icand, f1, sync, xdt, xbase
+ close(99)
+ endif
+
+ call timer('js8dec ',0)
+ call js8dec(dd,newdat,nQSOProgress,nfqso,nftx,ndepth,lft8apon, &
+ lapcqonly,napwid,lsubtract,nagain,iaptype,mycall12,mygrid6, &
+ hiscall12,bcontest,sync,f1,xdt,xbase,apsym,nharderrors,dmin, &
+ nbadcrc,iappass,iera,msg37,xsnr)
+ message=msg37(1:22) !###
+ nsnr=nint(xsnr)
+ xdt=xdt-ASTART
+ hd=nharderrors+dmin
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) 'icand', icand, hd, nbadcrc
+ close(99)
+ endif
+
+ call timer('js8dec ',1)
+ if(nbadcrc.eq.0) then
+ ldupe=.false.
+ do id=1,ndecodes
+ if(message.eq.allmessages(id).and.nsnr.le.allsnrs(id)) ldupe=.true.
+ enddo
+ if(.not.ldupe) then
+ ndecodes=ndecodes+1
+ allmessages(ndecodes)=message
+ allsnrs(ndecodes)=nsnr
+ endif
+ if(.not.ldupe .and. associated(this%callback)) then
+ qual=1.0-(nharderrors+dmin)/60.0 ! scale qual to [0.0,1.0]
+ call this%callback(sync,nsnr,xdt,f1,msg37,iaptype,qual)
+ endif
+ endif
+
+ if(NWRITELOG.eq.1) then
+ open(99, file="./js8.log", status="old", position="append", action="write")
+ write(99,*) '---'
+ close(99)
+ endif
+ enddo
+ enddo
+ return
+ end subroutine decode
+
+end module js8d_decode
diff --git a/lib/js8d_module.f90 b/lib/js8d_module.f90
new file mode 100644
index 0000000..315e2d7
--- /dev/null
+++ b/lib/js8d_module.f90
@@ -0,0 +1,13 @@
+module js8d_module
+ include 'js8/js8_params.f90'
+ include 'js8/js8d_params.f90'
+
+contains
+ include 'js8/baselinejs8.f90'
+ include 'js8/syncjs8.f90'
+ include 'js8/js8_downsample.f90'
+ include 'js8/syncjs8d.f90'
+ include 'js8/genjs8refsig.f90'
+ include 'js8/subtractjs8.f90'
+ include 'js8/js8dec.f90'
+end module js8d_module
diff --git a/lib/jt4sim.f90 b/lib/jt4sim.f90
deleted file mode 100644
index 73edabf..0000000
--- a/lib/jt4sim.f90
+++ /dev/null
@@ -1,181 +0,0 @@
-program jt4sim
-
-! Generate simulated jt4 data for testing the decoder using new fading models
-! Based on qra64sim with appropriate changes for JT4
-! Includes option to generate 1000Hz single tone with "ST" as the message
-
- use wavhdr
- use packjt
- use jt4
- parameter (NMAX=60*12000) ! = 648,000
- parameter (NFFT=10*65536,NH=NFFT/2)
- type(hdr) h !Header for .wav file
- integer*2 iwave(NMAX) !Generated waveform
- integer*4 itone(206) !Channel symbols (values 0-8)
- real*4 xnoise(NMAX) !Generated random noise
- real*4 dat(NMAX) !Generated real data
- complex cdat(NMAX) !Generated complex waveform
- complex cspread(0:NFFT-1) !Complex amplitude for Rayleigh fading
- complex z
- real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq
- character message*22,fname*11,csubmode*1,arg*12
- character msgsent*22
-
- nargs=iargc()
- if(nargs.ne. 7) then
- print *, 'Usage: jt4sim "msg" A-E Nsigs fDop DT Nfiles SNR'
- print *, 'Example jt4sim "K1ABC W9XYZ EN37" A 10 0.2 0.0 1 0'
- print *, 'Example jt4sim "ST" A 10 0.2 0.0 1 0'
- go to 999
- endif
- call getarg(1,message)
- call fmtmsg(message, iz)
- call getarg(2,csubmode)
- mode4=ichar(csubmode) - ichar('A') + 1
- call getarg(3,arg)
- read(arg,*) nsigs
- call getarg(4,arg)
- read(arg,*) fspread
- call getarg(5,arg)
- read(arg,*) xdt
- call getarg(6,arg)
- read(arg,*) nfiles
- call getarg(7,arg)
- read(arg,*) snrdb
-
- if(mode4.ge.8) nsigs=1 ! temporary - will need sorting out
- rms=100.
- fsample=12000.d0 !Sample rate (Hz)
- dt=1.d0/fsample !Sample interval (s)
- twopi=8.d0*atan(1.d0)
- npts=60*12000 !Total samples in .wav file
- nsps=12000.d0/4.375d0
- baud=12000.d0/nsps !Keying rate = 1.7361111111
- nsym=206 !Number of channel symbols
- h=default_header(12000,npts)
- dfsig=2000.0/nsigs !Freq spacing between sigs in file (Hz)
- ichk=0
-
- write(*,1000)
-1000 format('File Sig Freq A-E S/N DT Dop Message'/60('-'))
-
- do ifile=1,nfiles !Loop over requested number of files
- write(fname,1002) ifile !Output filename
-1002 format('000000_',i4.4)
- open(10,file=fname//'.wav',access='stream',status='unknown')
- xnoise=0.
- cdat=0.
- if(snrdb.lt.90) then
- do i=1,npts
- xnoise(i)=gran() !Generate gaussian noise
- enddo
- endif
-
- do isig=1,nsigs !Generate requested number of sigs
- if(mod(nsigs,2).eq.0) f0=1500.0 + dfsig*(isig-0.5-nsigs/2)
- if(mod(nsigs,2).eq.1) f0=1500.0 + dfsig*(isig-(nsigs+1)/2)
- if(nsigs.eq.1) f0=1000.0
- xsnr=snrdb
- if(snrdb.eq.0.0) xsnr=-20 - isig
-
- call gen4(message,ichk,msgsent,itone,itype)
-
- bandwidth_ratio=2500.0/6000.0
- sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*xsnr)
- if(xsnr.gt.90.0) sig=1.0
- write(*,1020) ifile,isig,f0,csubmode,xsnr,xdt,fspread,message
-1020 format(i4,i4,f10.3,2x,a1,2x,f5.1,f6.2,f6.1,1x,a22)
-
- phi=0.d0
- dphi=0.d0
- k=(xdt+1.0)*12000 !Start audio at t = xdt + 1.0 s
- isym0=-99
-
- do i=1,npts !Add this signal into cdat()
- isym=i/nsps + 1
- if(isym.gt.nsym) exit
- if(isym.ne.isym0) then
- if(message(1:2).eq.'ST') then !Finds ST in message string for single tone
- freq=1000 !1000Hz for single tone
- else
- freq=f0 + itone(isym)*baud*nch(mode4)
- endif
- dphi=twopi*freq*dt
- isym0=isym
-
- endif
- phi=phi + dphi
- if(phi.gt.twopi) phi=phi-twopi
- xphi=phi
- z=cmplx(cos(xphi),sin(xphi))
- k=k+1
- if(k.ge.1) cdat(k)=cdat(k) + sig*z
- enddo
- enddo
-
- if(fspread.ne.0) then !Apply specified Doppler spread
- df=12000.0/nfft
- twopi=8*atan(1.0)
- cspread(0)=1.0
- cspread(NH)=0.
- b=6.0 !Lorenzian 3/28 onward
- do i=1,NH
- f=i*df
- x=b*f/fspread
- z=0.
- a=0.
- if(x.lt.3.0) then !Cutoff beyond x=3
- a=sqrt(1.111/(1.0+x*x)-0.1) !Lorentzian
- call random_number(r1)
- phi1=twopi*r1
- z=a*cmplx(cos(phi1),sin(phi1))
- endif
- cspread(i)=z
- z=0.
- if(x.lt.50.0) then
- call random_number(r2)
- phi2=twopi*r2
- z=a*cmplx(cos(phi2),sin(phi2))
- endif
- cspread(NFFT-i)=z
- enddo
-
- do i=0,NFFT-1
- f=i*df
- if(i.gt.NH) f=(i-nfft)*df
- s=real(cspread(i))**2 + aimag(cspread(i))**2
-! write(13,3000) i,f,s,cspread(i)
-!3000 format(i5,f10.3,3f12.6)
- enddo
-! s=real(cspread(0))**2 + aimag(cspread(0))**2
-! write(13,3000) 1024,0.0,s,cspread(0)
-
- call four2a(cspread,NFFT,1,1,1) !Transform to time domain
-
- sum=0.
- do i=0,NFFT-1
- p=real(cspread(i))**2 + aimag(cspread(i))**2
- sum=sum+p
- enddo
- avep=sum/NFFT
- fac=sqrt(1.0/avep)
- cspread=fac*cspread !Normalize to constant avg power
- cdat(1:NFFT)=cspread*cdat(1:NFFT) !Apply Rayleigh fading
-
-! do i=0,NFFT-1
-! p=real(cspread(i))**2 + aimag(cspread(i))**2
-! write(14,3010) i,p,cspread(i)
-!3010 format(i8,3f12.6)
-! enddo
-
- endif
-
- dat=aimag(cdat) + xnoise !Add the generated noise
- fac=32767.0/nsigs
- if(snrdb.ge.90.0) iwave(1:npts)=nint(fac*dat(1:npts))
- if(snrdb.lt.90.0) iwave(1:npts)=nint(rms*dat(1:npts))
- write(10) h,iwave(1:npts) !Save the .wav file
- close(10)
- enddo
-
-999 end program jt4sim
diff --git a/lib/msgs.txt b/lib/msgs.txt
deleted file mode 100644
index c38aba9..0000000
--- a/lib/msgs.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-W1AAA K2BBB EM00
-W2CCC K3DDD EM01
-W3EEE K4FFF EM02
-W5GGG K6HHH EM03
-W7III K8JJJ EM04
-W9KKK K0LLL EM05
-G0MMM F1NNN JN06
-G2OOO F3PPP JN07
-G4QQQ F5RRR JN08
-G6SSS F7TTT JN09
-W1XAA K2XBB EM10
-W2XCC K3XDD EM11
-W3XEE K4XFF EM12
-W5XGG K6XHH EM13
-W7XII K8XJJ EM14
-W9XKK K0XLL EM15
-G0XMM F1XNN JN16
-G2XOO F3XPP JN17
-G4XQQ F5XRR JN18
-G6XSS F7XTT JN19
-W1YAA K2YBB EM20
-W2YCC K3YDD EM21
-W3YEE K4YFF EM22
-W5YGG K6YHH EM23
-W7YII K8YJJ EM24
-W9YKK K0YLL EM25
-G0YMM F1YNN JN26
-G2YOO F3YPP JN27
-G4YQQ F5YRR JN28
-G6YSS F7YTT JN29
-W1ZAA K2ZBB EM30
-W2ZCC K3ZDD EM31
-W3ZEE K4ZFF EM32
-W5ZGG K6ZHH EM33
-W7ZII K8ZJJ EM34
-W9ZKK K0ZLL EM35
-G0ZMM F1ZNN JN36
-G2ZOO F3ZPP JN37
-G4ZQQ F5ZRR JN38
-G6ZSS F7ZTT JN39
-W1AXA K2BXB EM40
-W2CXC K3DXD EM41
-W3EXE K4FXF EM42
-W5GXG K6HXH EM43
-W7IXI K8JXJ EM44
-W9KXK K0LXL EM45
-G0MXM F1NXN JN46
-G2OXO F3PXP JN47
-G4QXQ F5RXR JN48
-G6SXS F7TXT JN49
-W1AYA K2BYB EM50
-W2CYC K3DYD EM51
-W3EYE K4FYF EM52
-W5GYG K6HYH EM53
-W7IYI K8JYJ EM54
-W9KYK K0LYL EM55
-G0MYM F1NYN JN56
-G2OYO F3PYP JN57
-G4QYQ F5RYR JN58
-G6SYS F7TYT JN59
diff --git a/lib/msk144_freq_search.f90 b/lib/msk144_freq_search.f90
deleted file mode 100644
index 5029816..0000000
--- a/lib/msk144_freq_search.f90
+++ /dev/null
@@ -1,50 +0,0 @@
-subroutine msk144_freq_search(cdat,fc,if1,if2,delf,nframes,navmask,cb, &
- cdat2,xmax,bestf,cs,xccs)
-
- parameter (NSPM=864,NZ=7*NSPM)
- complex cdat(NZ)
- complex cdat2(NZ)
- complex c(NSPM) !Coherently averaged complex data
- complex ct2(2*NSPM)
- complex cs(NSPM)
- complex cb(42) !Complex waveform for sync word
- complex cc(0:NSPM-1)
- real xcc(0:NSPM-1)
- real xccs(0:NSPM-1)
- integer navmask(nframes) !Tells which frames to average
-
- navg=sum(navmask)
- n=nframes*NSPM
- fac=1.0/(48.0*sqrt(float(navg)))
-
- do ifr=if1,if2 !Find freq that maximizes sync
- ferr=ifr*delf
- call tweak1(cdat,n,-(fc+ferr),cdat2)
- c=0
- sumw=0.
- do i=1,nframes
- ib=(i-1)*NSPM+1
- ie=ib+NSPM-1
- if(navmask(i).eq.1) c=c + cdat2(ib:ie)
- enddo
-
- cc=0
- ct2(1:NSPM)=c
- ct2(NSPM+1:2*NSPM)=c
-
- do ish=0,NSPM-1
- cc(ish)=dot_product(ct2(1+ish:42+ish)+ct2(337+ish:378+ish),cb(1:42))
- enddo
-
- xcc=abs(cc)
- xb=maxval(xcc)*fac
- if(xb.gt.xmax) then
- xmax=xb
- bestf=ferr
- cs=c
- xccs=xcc
- endif
- enddo
-
- return
-end subroutine msk144_freq_search
diff --git a/lib/msk144code.f90 b/lib/msk144code.f90
deleted file mode 100644
index f49bebc..0000000
--- a/lib/msk144code.f90
+++ /dev/null
@@ -1,70 +0,0 @@
-program msk144code
-
-! Provides examples of message packing, bit and symbol ordering,
-! LDPC encoding, and other necessary details of the MSK144 protocol.
-
- use packjt
- character msg*22,msgsent*22,decoded,bad*1,msgtype*13,mygrid*6
- integer*4 i4tone(144)
- logical*1 bcontest
- include 'testmsg.f90'
- data mygrid/'FN20qi'/
-
- nargs=iargc()
- if(nargs.ne.1) then
- print*,'Usage: msk144code "message"'
- print*,' msk144code -t'
- print*,' '
- print*,'Examples:'
- print*,' msk144code "KA1ABC WB9XYZ EN37"'
- print*,' msk144code " R-03"'
- print*,' msk144code "KA1ABC WB9XYZ R EN37"'
- go to 999
- endif
-
- call getarg(1,msg)
- nmsg=1
- if(msg(1:2).eq."-t") then
- testmsg(NTEST+1)=" -03"
- testmsg(NTEST+2)=" R+03"
- testmsg(NTEST+3)=" RRR"
- testmsg(NTEST+4)=" 73"
- testmsg(NTEST+5)="KA1ABC WB9XYZ R EN37"
- nmsg=NTEST+5
- endif
-
- write(*,1010)
-1010 format(" Message Decoded Err? Type"/ &
- 74("-"))
- do imsg=1,nmsg
- if(nmsg.gt.1) msg=testmsg(imsg)
- call fmtmsg(msg,iz) !To upper case, collapse multiple blanks
- i1=len(trim(msg))-5
- bcontest=.false.
- if(msg(i1:i1+1).eq.'R ') bcontest=.true.
- ichk=0
- call genmsk144(msg,mygrid,ichk,bcontest,msgsent,i4tone,itype)
-
- msgtype=""
- if(itype.eq.1) msgtype="Std Msg"
- if(itype.eq.2) msgtype="Type 1 prefix"
- if(itype.eq.3) msgtype="Type 1 suffix"
- if(itype.eq.4) msgtype="Type 2 prefix"
- if(itype.eq.5) msgtype="Type 2 suffix"
- if(itype.eq.6) msgtype="Free text"
- if(itype.eq.7) msgtype="Hashed calls"
-
- bad=" "
- if(msgsent.ne.msg) bad="*"
- write(*,1020) imsg,msg,msgsent,bad,itype,msgtype
-1020 format(i2,'.',2x,a22,2x,a22,3x,a1,i3,": ",a13)
- enddo
-
- if(nmsg.eq.1) then
- n=144
- if(msg(1:1).eq."<") n=40
- write(*,1030) i4tone(1:n)
-1030 format(/'Channel symbols'/(72i1))
- endif
-
-999 end program msk144code
diff --git a/lib/msk144d2.f90 b/lib/msk144d2.f90
deleted file mode 100644
index 47eb43b..0000000
--- a/lib/msk144d2.f90
+++ /dev/null
@@ -1,138 +0,0 @@
-program msk144d2
-
- ! Test the msk144 decoder for WSJT-X
-
- use options
- use timer_module, only: timer
- use timer_impl, only: init_timer
- use readwav
-
- character c
- character*80 line
- character*512 datadir
- character*500 infile
- character*12 mycall,hiscall
- character*6 mygrid
- character(len=500) optarg
-
- logical :: display_help=.false.
- logical*1 bShMsgs
- logical*1 bcontest
- logical*1 btrain
- logical*1 bswl
-
- type(wav_header) :: wav
-
- integer*2 id2(30*12000)
- integer*2 ichunk(7*1024)
-
- real*8 pcoeffs(5)
-
- type (option) :: long_options(9) = [ &
- option ('ndepth',.true.,'c','ndepth',''), &
- option ('dxcall',.true.,'d','hiscall',''), &
- option ('evemode',.true.,'e','Must be used with -s.',''), &
- option ('frequency',.true.,'f','rxfreq',''), &
- option ('help',.false.,'h','Display this help message',''), &
- option ('mycall',.true.,'m','mycall',''), &
- option ('nftol',.true.,'n','nftol',''), &
- option ('rxequalize',.false.,'r','Rx Equalize',''), &
- option ('short',.false.,'s','enable Sh','') &
- ]
- t0=0.0
- ndepth=3
- ntol=100
- nrxfreq=1500
- mycall=''
- mygrid='EN50WC'
- hiscall=''
- bShMsgs=.false.
- bcontest=.false.
- btrain=.false.
- bswl=.false.
- datadir='.'
- pcoeffs=0.d0
-
- do
- call getopt('c:d:ef:hm:n:rs',long_options,c,optarg,narglen,nstat,noffset,nremain,.true.)
- if( nstat .ne. 0 ) then
- exit
- end if
- select case (c)
- case ('c')
- read (optarg(:narglen), *) ndepth
- case ('d')
- read (optarg(:narglen), *) hiscall
- case ('e')
- bswl=.true.
- case ('f')
- read (optarg(:narglen), *) nrxfreq
- case ('h')
- display_help = .true.
- case ('m')
- read (optarg(:narglen), *) mycall
- case ('n')
- read (optarg(:narglen), *) ntol
- case ('r')
- btrain=.true.
- case ('s')
- bShMsgs=.true.
- end select
- end do
-
- if(display_help .or. nstat.lt.0 .or. nremain.lt.1) then
- print *, ''
- print *, 'Usage: msk144d [OPTIONS] file1 [file2 ...]'
- print *, ''
- print *, ' msk144 decode pre-recorded .WAV file(s)'
- print *, ''
- print *, 'OPTIONS:'
- do i = 1, size (long_options)
- call long_options(i) % print (6)
- end do
- go to 999
- endif
-
- call init_timer ('timer.out')
- call timer('msk144 ',0)
- ndecoded=0
- do ifile=noffset+1,noffset+nremain
- call get_command_argument(ifile,optarg,narglen)
- infile=optarg(:narglen)
- call timer('read ',0)
- call wav%read (infile)
- i1=index(infile,'.wav')
- if( i1 .eq. 0 ) i1=index(infile,'.WAV')
- read(infile(i1-6:i1-1),*,err=998) nutc
- inquire(FILE=infile,SIZE=isize)
- npts=min((isize-216)/2,360000)
- read(unit=wav%lun) id2(1:npts)
- close(unit=wav%lun)
- call timer('read ',1)
-
- do i=1,npts-7*1024+1,7*512
- ichunk=id2(i:i+7*1024-1)
- tsec=(i-1)/12000.0
- tt=sum(float(abs(id2(i:i+7*512-1))))
- if( tt .ne. 0.0 ) then
- call mskrtd(ichunk,nutc,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall,bShMsgs, &
- bcontest,btrain,pcoeffs,bswl,datadir,line)
- if( index(line,"&") .ne. 0 .or. &
- index(line,"^") .ne. 0 .or. &
- index(line,"!") .ne. 0 .or. &
- index(line,"@") .ne. 0 ) then
- write(*,*) line
- endif
- endif
- enddo
- enddo
-
- call timer('msk144 ',1)
- call timer('msk144 ',101)
- go to 999
-
-998 print*,'Cannot read from file:'
- print*,infile
-
-999 continue
-end program msk144d2
diff --git a/lib/msk144decodeframe.f90 b/lib/msk144decodeframe.f90
deleted file mode 100644
index 5d5e155..0000000
--- a/lib/msk144decodeframe.f90
+++ /dev/null
@@ -1,107 +0,0 @@
-subroutine msk144decodeframe(c,softbits,msgreceived,nsuccess,recent_calls,nrecent)
-! use timer_module, only: timer
-
- parameter (NSPM=864)
- character*22 msgreceived
- character*12 recent_calls(nrecent)
- complex cb(42)
- complex cfac,cca,ccb
- complex c(NSPM)
- integer*1 decoded(80)
- integer s8(8),hardbits(144)
- real*8 dt, fs, pi, twopi
- real cbi(42),cbq(42)
- real pp(12)
- real softbits(144)
- real llr(128)
- logical first
- data first/.true./
- data s8/0,1,1,1,0,0,1,0/
- save first,cb,fs,pi,twopi,dt,s8,pp
-
- if(first) then
-! define half-sine pulse and raised-cosine edge window
- pi=4d0*datan(1d0)
- twopi=8d0*datan(1d0)
- fs=12000.0
- dt=1.0/fs
-
- do i=1,12
- angle=(i-1)*pi/12.0
- pp(i)=sin(angle)
- enddo
-
-! define the sync word waveforms
- s8=2*s8-1
- cbq(1:6)=pp(7:12)*s8(1)
- cbq(7:18)=pp*s8(3)
- cbq(19:30)=pp*s8(5)
- cbq(31:42)=pp*s8(7)
- cbi(1:12)=pp*s8(2)
- cbi(13:24)=pp*s8(4)
- cbi(25:36)=pp*s8(6)
- cbi(37:42)=pp(1:6)*s8(8)
- cb=cmplx(cbi,cbq)
- first=.false.
- endif
-
- nsuccess=0
- msgreceived=' '
-
-! Estimate carrier phase.
- cca=sum(c(1:1+41)*conjg(cb))
- ccb=sum(c(1+56*6:1+56*6+41)*conjg(cb))
- cfac=ccb*conjg(cca)
- phase0=atan2(imag(cca+ccb),real(cca+ccb))
-
-! Remove phase error - want constellation rotated so that sample points lie on I/Q axes
- cfac=cmplx(cos(phase0),sin(phase0))
- c=c*conjg(cfac)
-
-! matched filter -
- softbits(1)=sum(imag(c(1:6))*pp(7:12))+sum(imag(c(864-5:864))*pp(1:6))
- softbits(2)=sum(real(c(1:12))*pp)
- do i=2,72
- softbits(2*i-1)=sum(imag(c(1+(i-1)*12-6:1+(i-1)*12+5))*pp)
- softbits(2*i)=sum(real(c(7+(i-1)*12-6:7+(i-1)*12+5))*pp)
- enddo
-
-! sync word hard error weight is used as a discriminator for
-! frames that have reasonable probability of decoding
- hardbits=0
- do i=1,144
- if( softbits(i) .ge. 0.0 ) then
- hardbits(i)=1
- endif
- enddo
- nbadsync1=(8-sum( (2*hardbits(1:8)-1)*s8 ) )/2
- nbadsync2=(8-sum( (2*hardbits(1+56:8+56)-1)*s8 ) )/2
- nbadsync=nbadsync1+nbadsync2
- if( nbadsync .gt. 4 ) then
- return
- endif
-
-! normalize the softsymbols before submitting to decoder
- sav=sum(softbits)/144
- s2av=sum(softbits*softbits)/144
- ssig=sqrt(s2av-sav*sav)
- softbits=softbits/ssig
-
- sigma=0.75
- llr(1:48)=softbits(9:9+47)
- llr(49:128)=softbits(65:65+80-1)
- llr=2.0*llr/(sigma*sigma)
-
- max_iterations=10
-! call timer('bpdec144 ',0)
- call bpdecode144(llr,max_iterations,decoded,niterations)
-! call timer('bpdec144 ',1)
- if( niterations .ge. 0.0 ) then
- call extractmessage144(decoded,msgreceived,nhashflag,recent_calls,nrecent)
- if( nhashflag .gt. 0 ) then !Hash codes match, so print it
- nsuccess=1
- endif
- endif
-
- return
-end subroutine msk144decodeframe
diff --git a/lib/msk144sd.f90 b/lib/msk144sd.f90
deleted file mode 100644
index 267fff5..0000000
--- a/lib/msk144sd.f90
+++ /dev/null
@@ -1,197 +0,0 @@
-program msk144sd
-!
-! A simple decoder for slow msk144.
-! Can be used as a (slow) brute-force multi-decoder by looping
-! over a set of carrier frequencies.
-!
- use options
- use timer_module, only: timer
- use timer_impl, only: init_timer
- use readwav
-
- parameter (NRECENT=10)
- parameter (NSPM=864)
- parameter (NPATTERNS=4)
-
- character ch
- character*80 line
- character*500 infile
- character*12 mycall,hiscall
- character*6 mygrid
- character(len=500) optarg
- character*22 msgreceived
- character*12 recent_calls(NRECENT)
-
- complex cdat(30*375)
- complex c(NSPM)
- complex ct(NSPM)
-
- real softbits(144)
- real xmc(NPATTERNS)
-
- logical :: display_help=.false.
-
- type(wav_header) :: wav
-
- integer iavmask(8)
- integer iavpatterns(8,NPATTERNS)
- integer npkloc(10)
-
- integer*2 id2(30*12000)
- integer*2 ichunk(7*1024)
-
- data iavpatterns/ &
- 1,1,1,1,0,0,0,0, &
- 0,1,1,1,1,0,0,0, &
- 0,0,1,1,1,1,0,0, &
- 1,1,1,1,1,1,0,0/
- data xmc/2.0,4.5,2.5,3.0/
-
- type (option) :: long_options(2) = [ &
- option ('frequency',.true.,'f','rxfreq',''), &
- option ('help',.false.,'h','Display this help message','') &
- ]
- t0=0.0
- ntol=100
- nrxfreq=1500
-
- do
- call getopt('f:h',long_options,ch,optarg,narglen,nstat,noffset,nremain,.true.)
- if( nstat .ne. 0 ) then
- exit
- end if
- select case (ch)
- case ('f')
- read (optarg(:narglen), *) nrxfreq
- case ('h')
- display_help = .true.
- end select
- end do
-
- if(display_help .or. nstat.lt.0 .or. nremain.lt.1) then
- print *, ''
- print *, 'Usage: msk144sd [OPTIONS] file1 [file2 ...]'
- print *, ''
- print *, ' decode pre-recorded .WAV file(s)'
- print *, ''
- print *, 'OPTIONS:'
- do i = 1, size (long_options)
- call long_options(i) % print (6)
- end do
- go to 999
- endif
-
- call init_timer ('timer.out')
- call timer('msk144 ',0)
- ndecoded=0
- do ifile=noffset+1,noffset+nremain
- call get_command_argument(ifile,optarg,narglen)
- infile=optarg(:narglen)
- call timer('read ',0)
- call wav%read (infile)
- i1=index(infile,'.wav')
- if( i1 .eq. 0 ) i1=index(infile,'.WAV')
- read(infile(i1-6:i1-1),*,err=998) nutc
- inquire(FILE=infile,SIZE=isize)
- npts=min((isize-216)/2,360000)
- read(unit=wav%lun) id2(1:npts)
- close(unit=wav%lun)
- call timer('read ',1)
-
-! do if=1,89 ! brute force multi-decoder
- fo=nrxfreq
-! fo=(if-1)*25.0+300.0
- call msksddc(id2,npts,fo,cdat)
- np=npts/32
- ntol=200 ! actual ntol is ntol/32=6.25 Hz. Detection window is 12.5 Hz wide
- fc=1500.0
- call msk144spd(cdat,np,ntol,ndecodesuccess,msgreceived,fc,fest,tdec,navg,ct, &
- softbits,recent_calls,nrecent)
- nsnr=0 ! need an snr estimate
- if( ndecodesuccess .eq. 1 ) then
- fest=fo+fest-fc ! fudging because spd thinks input signal is at 1500 Hz
- goto 900
- endif
-! If short ping decoder doesn't find a decode
- npat=NPATTERNS
- do iavg=1,npat
- iavmask=iavpatterns(1:8,iavg)
- navg=sum(iavmask)
- deltaf=4.0/real(navg) ! search increment for frequency sync
- npeaks=4
- ntol=200
- fc=1500.0
- call msk144sync(cdat(1:6*NSPM),6,ntol,deltaf,iavmask,npeaks,fc, &
- fest,npkloc,nsyncsuccess,xmax,c)
- if( nsyncsuccess .eq. 0 ) cycle
-
- do ipk=1,npeaks
- do is=1,3
- ic0=npkloc(ipk)
- if(is.eq.2) ic0=max(1,ic0-1)
- if(is.eq.3) ic0=min(NSPM,ic0+1)
- ct=cshift(c,ic0-1)
- call msk144decodeframe(ct,softbits,msgreceived,ndecodesuccess, &
- recent_calls,nrecent)
- if(ndecodesuccess .gt. 0) then
- tdec=tsec+xmc(iavg)*tframe
- fest=fo+(fest-fc)/32.0
- goto 900
- endif
- enddo !Slicer dither
- enddo !Peak loop
- enddo
-
-! enddo
-900 continue
- if( ndecodesuccess .gt. 0 ) then
- write(*,1020) nutc,nsnr,tdec,nint(fest),' % ',msgreceived,navg
-1020 format(i6.6,i4,f5.1,i5,a3,a22,i4)
- endif
- enddo
-
- call timer('msk144 ',1)
- call timer('msk144 ',101)
- go to 999
-
-998 print*,'Cannot read from file:'
- print*,infile
-
-999 continue
-end program msk144sd
-
-subroutine msksddc(id2,npts,fc,cdat)
-
-! The msk144 detector/demodulator/decoder will decode signals
-! with carrier frequency, fc, in the range fN/4 +/- 0.03333*fN.
-!
-! For slow MSK144 with nslow=32:
-! fs=12000/32=375 Hz, fN=187.5 Hz
-!
-! This routine accepts input samples with fs=12000 Hz. It
-! downconverts and decimates by 32 to center a signal with input carrier
-! frequency fc at new carrier frequency 1500/32=46.875 Hz.
-! The analytic signal is returned.
-
- parameter (NFFT1=30*12000,NFFT2=30*375)
- integer*2 id2(npts)
- complex cx(0:NFFT1)
- complex cdat(30*375)
-
- dt=1.0/12000.0
- df=1.0/(NFFT1*dt)
- icenter=int(fc/df+0.5)
- i46p875=int(46.875/df+0.5)
- ishift=icenter-i46p875
- cx=cmplx(0.0,0.0)
- cx(1:npts)=id2
- call four2a(cx,NFFT1,1,-1,1)
- cx=cshift(cx,ishift)
- cx(1)=0.5*cx(1)
- cx(2*i46p875+1:)=cmplx(0.0,0.0)
- call four2a(cx,NFFT2,1,1,1)
- cdat(1:npts/32)=cx(0:npts/32-1)/NFFT1
- return
-
-end subroutine msksddc
-
diff --git a/lib/msk144signalquality.f90 b/lib/msk144signalquality.f90
deleted file mode 100644
index 24a146c..0000000
--- a/lib/msk144signalquality.f90
+++ /dev/null
@@ -1,219 +0,0 @@
-subroutine msk144signalquality(cframe,snr,freq,t0,softbits,msg,dxcall, &
- btrain,datadir,nbiterrors,eyeopening,pcoeffs)
-
- character*22 msg,msgsent
- character*12 dxcall
- character*12 training_dxcall
- character*12 trained_dxcall
- character*6 mygrid
- character*512 pcoeff_filename
- character*8 date
- character*10 time
- character*5 zone
- character*512 datadir
-
- complex cframe(864)
- complex cross(864)
- complex cross_avg(864)
- complex canalytic(1024)
- complex cmodel(1024)
-
- integer i4tone(144)
- integer hardbits(144)
- integer msgbits(144)
- integer values(8)
-
- logical*1 bcontest
- logical*1 btrain
- logical*1 first
- logical*1 currently_training
- logical*1 msg_has_dxcall
- logical*1 is_training_frame
-
- real softbits(144)
- real waveform(0:863)
- real d(1024)
- real phase(864)
- real twopi,freq,phi,dphi0,dphi1,dphi
- real*8 x(145),y(145),pp(145),sigmay(145),a(5),chisqr
- real*8 pcoeffs(5)
-
- parameter (NFREQLOW=500,NFREQHIGH=2500)
- data first/.true./
- save cross_avg,wt_avg,first,currently_training, &
- navg,tlast,training_dxcall,trained_dxcall
-
- if (first) then
- navg=0
- cross=cmplx(0.0,0.0)
- cross_avg=cmplx(0.0,0.0)
- wt_avg=0.0
- tlast=0.0
- trained_dxcall(1:12)=' '
- training_dxcall(1:12)=' '
- currently_training=.false.
- first=.false.
- endif
-
- if( (currently_training .and. (dxcall .ne. training_dxcall)) .or. &
- (navg .gt. 10 )) then !reset and retrain
- navg=0
- cross=cmplx(0.0,0.0)
- cross_avg=cmplx(0.0,0.0)
- wt_avg=0.0
- tlast=0.0
- trained_dxcall(1:12)=' '
- currently_training=.false.
- training_dxcall(1:12)=' '
- trained_dxcall(1:12)=' '
-!write(*,*) 'reset to untrained state '
- endif
-
- indx_dxcall=index(msg,trim(dxcall))
- msg_has_dxcall = indx_dxcall .ge. 4
-
- if( btrain .and. msg_has_dxcall .and. (.not. currently_training) ) then
- currently_training=.true.
- training_dxcall=trim(dxcall)
- trained_dxcall(1:12)=' '
-!write(*,*) 'start training on call ',training_dxcall
- endif
-
- if( msg_has_dxcall .and. currently_training ) then
- trained_dxcall(1:12)=' '
- training_dxcall=dxcall
- endif
-
-! use decoded message to figure out how many bit errors in the frame
- do i=1, 144
- hardbits(i)=0
- if(softbits(i) .gt. 0 ) hardbits(i)=1
- enddo
-
-! generate tones from decoded message
- mygrid="EN50"
- ichk=0
- bcontest=.false.
- call genmsk144(msg,mygrid,ichk,bcontest,msgsent,i4tone,itype)
-
-! reconstruct message bits from tones
- msgbits(1)=0
- do i=1,143
- if( i4tone(i) .eq. 0 ) then
- if( mod(i,2) .eq. 1 ) then
- msgbits(i+1)=msgbits(i)
- else
- msgbits(i+1)=mod(msgbits(i)+1,2)
- endif
- else
- if( mod(i,2) .eq. 1 ) then
- msgbits(i+1)=mod(msgbits(i)+1,2)
- else
- msgbits(i+1)=msgbits(i)
- endif
- endif
- enddo
-
- nbiterrors=0
- do i=1,144
- if( hardbits(i) .ne. msgbits(i) ) nbiterrors=nbiterrors+1
- enddo
-
- nplus=0
- nminus=0
- eyetop=1
- eyebot=-1
- do i=1,144
- if( msgbits(i) .eq. 1 ) then
- if( softbits(i) .lt. eyetop ) eyetop=softbits(i)
- else
- if( softbits(i) .gt. eyebot ) eyebot=softbits(i)
- endif
- enddo
- eyeopening=eyetop-eyebot
-
- is_training_frame = &
- (snr.gt.5.0 .and.(nbiterrors.lt.7)) .and. &
- (abs(t0-tlast) .gt. 0.072) .and. &
- msg_has_dxcall
- if( currently_training .and. is_training_frame ) then
- twopi=8.0*atan(1.0)
- nsym=144
- if( i4tone(41) .lt. 0 ) nsym=40
- dphi0=twopi*(freq-500)/12000.0
- dphi1=twopi*(freq+500)/12000.0
- phi=-twopi/8
- indx=0
- do i=1,nsym
- if( i4tone(i) .eq. 0 ) then
- dphi=dphi0
- else
- dphi=dphi1
- endif
- do j=1,6
- waveform(indx)=cos(phi);
- indx=indx+1
- phi=mod(phi+dphi,twopi)
- enddo
- enddo
-! convert the passband waveform to complex baseband
- npts=864
- nfft=1024
- d=0
- d(1:864)=waveform(0:863)
- call analytic(d,npts,nfft,canalytic,pcoeffs,.false.) ! don't equalize the model
- call tweak1(canalytic,nfft,-freq,cmodel)
- call four2a(cframe(1:864),864,1,-1,1)
- call four2a(cmodel(1:864),864,1,-1,1)
-
-! Cross spectra from different messages can be averaged
-! as long as all messages originate from dxcall.
- cross=cmodel(1:864)*conjg(cframe)/1000.0
- cross=cshift(cross,864/2)
- cross_avg=cross_avg+10**(snr/20.0)*cross
- wt_avg=wt_avg+10**(snr/20.0)
- navg=navg+1
- tlast=t0
- phase=atan2(imag(cross_avg),real(cross_avg))
- df=12000.0/864.0
- nm=145
- do i=1,145
- x(i)=(i-73)*df/1000.0
- enddo
- y=phase((864/2-nm/2):(864/2+nm/2))
- sigmay=wt_avg/abs(cross_avg((864/2-nm/2):(864/2+nm/2)))
- mode=1
- npts=145
- nterms=5
- call polyfit(x,y,sigmay,npts,nterms,mode,a,chisqr)
- pp=a(1)+x*(a(2)+x*(a(3)+x*(a(4)+x*a(5))))
- rmsdiff=sum( (pp-phase((864/2-nm/2):(864/2+nm/2)))**2 )/145.0
-!write(*,*) 'training ',navg,sqrt(chisqr),rmsdiff
- if( (sqrt(chisqr).lt.1.8) .and. (rmsdiff.lt.0.5) .and. (navg.ge.5) ) then
- trained_dxcall=dxcall
- call date_and_time(date,time,zone,values)
- write(pcoeff_filename,'(i2.2,i2.2,i2.2,"_",i2.2,i2.2,i2.2)') &
- values(1)-2000,values(2),values(3),values(5),values(6),values(7)
- pcoeff_filename=trim(trained_dxcall)//"_"//trim(pcoeff_filename)//".pcoeff"
- l1=index(datadir,char(0))-1
- datadir(l1+1:l1+1)="/"
- pcoeff_filename=datadir(1:l1+1)//trim(pcoeff_filename)
-!write(*,*) 'trained - writing coefficients to: ',pcoeff_filename
- open(17,file=pcoeff_filename,status='new')
- write(17,'(i4,2f10.2,3i5,5e25.16)') navg,sqrt(chisqr),rmsdiff,NFREQLOW,NFREQHIGH,nterms,a
- do i=1, 145
- write(17,*) x(i),pp(i),y(i),sigmay(i)
- enddo
- do i=1,864
- write(17,*) i,real(cframe(i)),imag(cframe(i)),real(cross_avg(i)),imag(cross_avg(i))
- enddo
- close(17)
- training_dxcall(1:12)=' '
- currently_training=.false.
- btrain=.false.
- navg=0
- endif
- endif
-
- return
- end subroutine msk144signalquality
diff --git a/lib/msk144sim.f90 b/lib/msk144sim.f90
deleted file mode 100644
index 28f17e6..0000000
--- a/lib/msk144sim.f90
+++ /dev/null
@@ -1,99 +0,0 @@
-program msk144sim
-
- use wavhdr
- parameter (NMAX=15*12000)
- real pings(0:NMAX-1)
- real waveform(0:NMAX-1)
- character*6 mygrid
- character arg*8,msg*22,msgsent*22,fname*40
- real wave(0:NMAX-1) !Simulated received waveform
- real*8 twopi,freq,phi,dphi0,dphi1,dphi
- type(hdr) h !Header for .wav file
- integer*2 iwave(0:NMAX-1)
- integer itone(144) !Message bits
- logical*1 bcontest
- data mygrid/"EN50wc"/
-
- nargs=iargc()
- if(nargs.ne.6) then
- print*,'Usage: msk144sim message freq width nslow snr nfiles'
- print*,'Example: msk144sim "K1ABC W9XYZ EN37" 1500 0.12 1 2 1'
- print*,' msk144sim "K1ABC W9XYZ EN37" 1500 2.5 32 15 1'
- go to 999
- endif
- call getarg(1,msg)
- call getarg(2,arg)
- read(arg,*) freq
- call getarg(3,arg)
- read(arg,*) width
- call getarg(4,arg)
- read(arg,*) nslow
- call getarg(5,arg)
- read(arg,*) snrdb
- call getarg(6,arg)
- read(arg,*) nfiles
-
-!sig is the peak amplitude of the ping.
- sig=sqrt(2.0)*10.0**(0.05*snrdb)
- h=default_header(12000,NMAX)
- i1=len(trim(msg))-5
- bcontest=.false.
- if(msg(i1:i1+1).eq.'R ') bcontest=.true.
- ichk=0
- call genmsk144(msg,mygrid,ichk,bcontest,msgsent,itone,itype)
- twopi=8.d0*atan(1.d0)
-
- nsym=144
- nsps=6*nslow
- if( itone(41) .lt. 0 ) nsym=40
- baud=2000.d0/nslow
- dphi0=twopi*(freq-0.25d0*baud)/12000.d0
- dphi1=twopi*(freq+0.25d0*baud)/12000.d0
- phi=0.0
- k=0
- nreps=NMAX/(nsym*nsps)
- print*,nsym,nslow,nsps,baud,freq
- do jrep=1,nreps
- do i=1,nsym
- if( itone(i) .eq. 0 ) then
- dphi=dphi0
- else
- dphi=dphi1
- endif
- do j=1,nsps
- waveform(k)=cos(phi)
- k=k+1
- phi=mod(phi+dphi,twopi)
- enddo
- enddo
- enddo
-
- if(itype.lt.1 .or. itype.gt.7) then
- print*,'Illegal message'
- go to 999
- endif
-
- if(nslow.eq.1) call makepings(pings,NMAX,width,sig)
-
-! call sgran()
- do ifile=1,nfiles !Loop over requested number of files
- write(fname,1002) ifile !Output filename
-1002 format('000000_',i6.6)
- open(10,file=fname(1:13)//'.wav',access='stream',status='unknown')
-
- wave=0.0
- iwave=0
- fac=sqrt(6000.0/2500.0)
- do i=0,NMAX-1
- xx=gran()
- if(nslow.eq.1) wave(i)=pings(i)*waveform(i) + fac*xx
- if(nslow.gt.1) wave(i)=sig*waveform(i) + fac*xx
- iwave(i)=30.0*wave(i)
- enddo
-
- write(10) h,iwave !Save the .wav file
- close(10)
-
- enddo
-
-999 end program msk144sim
diff --git a/lib/msk144spd.f90 b/lib/msk144spd.f90
deleted file mode 100644
index dcba359..0000000
--- a/lib/msk144spd.f90
+++ /dev/null
@@ -1,197 +0,0 @@
-subroutine msk144spd(cbig,n,ntol,nsuccess,msgreceived,fc,fret,tret,navg,ct, &
- softbits,recent_calls,nrecent)
-
-! MSK144 short-ping-decoder
-
- use timer_module, only: timer
-
- parameter (NSPM=864, MAXSTEPS=100, NFFT=NSPM, MAXCAND=5, NPATTERNS=6)
- character*22 msgreceived
- character*12 recent_calls(nrecent)
- complex cbig(n)
- complex cdat(3*NSPM) !Analytic signal
- complex c(NSPM)
- complex ct(NSPM)
- complex ctmp(NFFT)
- integer, dimension(1) :: iloc
- integer indices(MAXSTEPS)
- integer npkloc(10)
- integer navpatterns(3,NPATTERNS)
- integer navmask(3)
- integer nstart(MAXCAND)
- logical ismask(NFFT)
- real detmet(-2:MAXSTEPS+3)
- real detmet2(-2:MAXSTEPS+3)
- real detfer(MAXSTEPS)
- real rcw(12)
- real ferrs(MAXCAND)
- real snrs(MAXCAND)
- real softbits(144)
- real tonespec(NFFT)
- real tpat(NPATTERNS)
- real*8 dt, df, fs, pi, twopi
- logical first
- data first/.true./
- data navpatterns/ &
- 0,1,0, &
- 1,0,0, &
- 0,0,1, &
- 1,1,0, &
- 0,1,1, &
- 1,1,1/
- data tpat/1.5,0.5,2.5,1.0,2.0,1.5/
-
- save df,first,fs,pi,twopi,dt,tframe,rcw
-
- if(first) then
- nmatchedfilter=1
-! define half-sine pulse and raised-cosine edge window
- pi=4d0*datan(1d0)
- twopi=8d0*datan(1d0)
- fs=12000.0
- dt=1.0/fs
- df=fs/NFFT
- tframe=NSPM/fs
-
- do i=1,12
- angle=(i-1)*pi/12.0
- rcw(i)=(1-cos(angle))/2
- enddo
-
- first=.false.
- endif
-
- ! fill the detmet, detferr arrays
- nstep=(n-NSPM)/216 ! 72ms/4=18ms steps
- detmet=0
- detmet2=0
- detfer=-999.99
- nfhi=2*(fc+500)
- nflo=2*(fc-500)
- ihlo=nint((nfhi-2*ntol)/df) + 1
- ihhi=nint((nfhi+2*ntol)/df) + 1
- illo=nint((nflo-2*ntol)/df) + 1
- ilhi=nint((nflo+2*ntol)/df) + 1
- i2000=nint(nflo/df) + 1
- i4000=nint(nfhi/df) + 1
- do istp=1,nstep
- ns=1+216*(istp-1)
- ne=ns+NSPM-1
- if( ne .gt. n ) exit
- ctmp=cmplx(0.0,0.0)
- ctmp(1:NSPM)=cbig(ns:ne)
-
-! Coarse carrier frequency sync - seek tones at 2000 Hz and 4000 Hz in
-! squared signal spectrum.
-
- ctmp=ctmp**2
- ctmp(1:12)=ctmp(1:12)*rcw
- ctmp(NSPM-11:NSPM)=ctmp(NSPM-11:NSPM)*rcw(12:1:-1)
- call four2a(ctmp,NFFT,1,-1,1)
- tonespec=abs(ctmp)**2
-
- ismask=.false.
- ismask(ihlo:ihhi)=.true. ! high tone search window
- iloc=maxloc(tonespec,ismask)
- ihpk=iloc(1)
- deltah=-real( (ctmp(ihpk-1)-ctmp(ihpk+1)) / (2*ctmp(ihpk)-ctmp(ihpk-1)-ctmp(ihpk+1)) )
- ah=tonespec(ihpk)
- ahavp=(sum(tonespec,ismask)-ah)/count(ismask)
- trath=ah/(ahavp+0.01)
- ismask=.false.
- ismask(illo:ilhi)=.true. ! window for low tone
- iloc=maxloc(tonespec,ismask)
- ilpk=iloc(1)
- deltal=-real( (ctmp(ilpk-1)-ctmp(ilpk+1)) / (2*ctmp(ilpk)-ctmp(ilpk-1)-ctmp(ilpk+1)) )
- al=tonespec(ilpk)
- alavp=(sum(tonespec,ismask)-al)/count(ismask)
- tratl=al/(alavp+0.01)
- fdiff=(ihpk+deltah-ilpk-deltal)*df
- ferrh=(ihpk+deltah-i4000)*df/2.0
- ferrl=(ilpk+deltal-i2000)*df/2.0
- if( ah .ge. al ) then
- ferr=ferrh
- else
- ferr=ferrl
- endif
- detmet(istp)=max(ah,al)
- detmet2(istp)=max(trath,tratl)
- detfer(istp)=ferr
- enddo ! end of detection-metric and frequency error estimation loop
-
- call indexx(detmet(1:nstep),nstep,indices) !find median of detection metric vector
- xmed=detmet(indices(nstep/4))
- detmet=detmet/xmed ! noise floor of detection metric is 1.0
- ndet=0
-
- do ip=1,MAXCAND ! Find candidates
- iloc=maxloc(detmet(1:nstep))
- il=iloc(1)
- if( (detmet(il) .lt. 3.0) ) exit
- if( abs(detfer(il)) .le. ntol ) then
- ndet=ndet+1
- nstart(ndet)=1+(il-1)*216+1
- ferrs(ndet)=detfer(il)
- snrs(ndet)=12.0*log10(detmet(il))/2-9.0
- endif
- detmet(il)=0.0
- enddo
-
- if( ndet .lt. 3 ) then
- do ip=1,MAXCAND-ndet ! Find candidates
- iloc=maxloc(detmet2(1:nstep))
- il=iloc(1)
- if( (detmet2(il) .lt. 12.0) ) exit
- if( abs(detfer(il)) .le. ntol ) then
- ndet=ndet+1
- nstart(ndet)=1+(il-1)*216+1
- ferrs(ndet)=detfer(il)
- snrs(ndet)=12.0*log10(detmet2(il))/2-9.0
- endif
- detmet2(il)=0.0
- enddo
- endif
-
- nsuccess=0
- msgreceived=' '
- npeaks=2
- ntol0=8
- deltaf=2.0
- do icand=1,ndet ! Try to sync/demod/decode each candidate.
- ib=max(1,nstart(icand)-NSPM)
- ie=ib-1+3*NSPM
- if( ie .gt. n ) then
- ie=n
- ib=ie-3*NSPM+1
- endif
- cdat=cbig(ib:ie)
- fo=fc+ferrs(icand)
- do iav=1,NPATTERNS
- navmask=navpatterns(1:3,iav)
- call msk144sync(cdat,3,ntol0,deltaf,navmask,npeaks,fo,fest,npkloc, &
- nsyncsuccess,xmax,c)
-
- if( nsyncsuccess .eq. 0 ) cycle
-
- do ipk=1,npeaks
- do is=1,3
- ic0=npkloc(ipk)
- if( is.eq.2) ic0=max(1,ic0-1)
- if( is.eq.3) ic0=min(NSPM,ic0+1)
- ct=cshift(c,ic0-1)
- call msk144decodeframe(ct,softbits,msgreceived,ndecodesuccess, &
- recent_calls,nrecent)
- if( ndecodesuccess .gt. 0 ) then
- tret=(nstart(icand)+NSPM/2)/fs
- fret=fest
- navg=sum(navmask)
- nsuccess=1
- return
- endif
- enddo
- enddo
- enddo
- enddo ! candidate loop
-
- return
-end subroutine msk144spd
diff --git a/lib/msk144sync.f90 b/lib/msk144sync.f90
deleted file mode 100644
index dfae9a2..0000000
--- a/lib/msk144sync.f90
+++ /dev/null
@@ -1,101 +0,0 @@
-subroutine msk144sync(cdat,nframes,ntol,delf,navmask,npeaks,fc,fest, &
- npklocs,nsuccess,xmax,c)
-
-!$ use omp_lib
-
- parameter (NSPM=864)
- complex cdat(NSPM*nframes)
- complex cdat2(NSPM*nframes,8)
- complex c(NSPM) !Coherently averaged complex data
- complex cs(NSPM,8)
- complex cb(42) !Complex waveform for sync word
-
- integer s8(8)
- integer iloc(1)
- integer npklocs(npeaks)
- integer navmask(nframes) ! defines which frames to average
-
- real cbi(42),cbq(42)
- real pkamps(npeaks)
- real xcc(0:NSPM-1)
- real xccs(0:NSPM-1,8)
- real xm(8)
- real bf(8)
- real pp(12) !Half-sine pulse shape
- logical first
- data first/.true./
- data s8/0,1,1,1,0,0,1,0/
- save first,cb,fs,pi,twopi,dt,s8,pp
-
- if(first) then
- pi=4.0*atan(1.0)
- twopi=8.0*atan(1.0)
- fs=12000.0
- dt=1.0/fs
-
- do i=1,12 !Define half-sine pulse
- angle=(i-1)*pi/12.0
- pp(i)=sin(angle)
- enddo
-
-! Define the sync word waveforms
- s8=2*s8-1
- cbq(1:6)=pp(7:12)*s8(1)
- cbq(7:18)=pp*s8(3)
- cbq(19:30)=pp*s8(5)
- cbq(31:42)=pp*s8(7)
- cbi(1:12)=pp*s8(2)
- cbi(13:24)=pp*s8(4)
- cbi(25:36)=pp*s8(6)
- cbi(37:42)=pp(1:6)*s8(8)
- cb=cmplx(cbi,cbq)
-
- first=.false.
- endif
-
- nfreqs=2*nint(ntol/delf) + 1
- xm=0.0
- bf=0.0
- nthreads=1
-!$ nthreads=min(8,int(OMP_GET_MAX_THREADS(),4))
- nstep=nfreqs/nthreads
-
-!$OMP PARALLEL NUM_THREADS(nthreads) PRIVATE(id,if1,if2)
- id=1
-!$ id=OMP_GET_THREAD_NUM() + 1 !Thread id = 1,2,...
- if1=-nint(ntol/delf) + (id-1)*nstep
- if2=if1+nstep-1
- if(id.eq.nthreads) if2=nint(ntol/delf)
- call msk144_freq_search(cdat,fc,if1,if2,delf,nframes,navmask,cb, &
- cdat2(1,id),xm(id),bf(id),cs(1,id),xccs(1,id))
-!$OMP END PARALLEL
-
- xmax=xm(1)
- fest=fc+bf(1)
- c=cs(1:NSPM,1)
- xcc=xccs(0:NSPM-1,1)
- if(nthreads.gt.1) then
- do i=2,nthreads
- if(xm(i).gt.xmax) then
- xmax=xm(i)
- fest=fc+bf(i)
- c=cs(1:NSPM,i)
- xcc=xccs(0:NSPM-1,i)
- endif
- enddo
- endif
-
-! Find npeaks largest peaks
- do ipk=1,npeaks
- iloc=maxloc(xcc)
- ic2=iloc(1)
- npklocs(ipk)=ic2
- pkamps(ipk)=xcc(ic2-1)
- xcc(max(0,ic2-7):min(NSPM-1,ic2+7))=0.0
- enddo
-
- nsuccess=0
- if(xmax.ge.1.3) nsuccess=1
-
- return
-end subroutine msk144sync
diff --git a/lib/msk40_freq_search.f90 b/lib/msk40_freq_search.f90
deleted file mode 100644
index 97f74f5..0000000
--- a/lib/msk40_freq_search.f90
+++ /dev/null
@@ -1,53 +0,0 @@
-subroutine msk40_freq_search(cdat,fc,if1,if2,delf,nframes,navmask,cb, &
- cdat2,xmax,bestf,cs,xccs)
-
- parameter (NSPM=240,NZ=7*NSPM)
- complex cdat(NZ)
- complex cdat2(NZ)
- complex c(NSPM) !Coherently averaged complex data
- complex ct2(2*NSPM)
- complex cs(NSPM)
- complex cb(42) !Complex waveform for sync word
- complex cc(0:NSPM-1)
- real xcc(0:NSPM-1)
- real xccs(0:NSPM-1)
- integer navmask(nframes) !Tells which frames to average
-
- navg=sum(navmask)
- n=nframes*NSPM
-! fac=1.0/(48.0*sqrt(float(navg)))
- fac=1.0/(24.0*sqrt(float(navg)))
-
- do ifr=if1,if2 !Find freq that maximizes sync
- ferr=ifr*delf
- call tweak1(cdat,n,-(fc+ferr),cdat2)
- c=0
- do i=1,nframes
- ib=(i-1)*NSPM+1
- ie=ib+NSPM-1
- if( navmask(i) .eq. 1 ) c=c+cdat2(ib:ie)
- enddo
-
- cc=0
- ct2(1:NSPM)=c
- ct2(NSPM+1:2*NSPM)=c
-
- do ish=0,NSPM-1
- cc(ish)=dot_product(ct2(1+ish:42+ish),cb(1:42))
- enddo
-
- xcc=abs(cc)
- xb=maxval(xcc)*fac
- if(xb.gt.xmax) then
- xmax=xb
- bestf=ferr
- cs=c
- xccs=xcc
- endif
- enddo
-
-! write(71,3001) fc,delf,if1,if2,nframes,bestf,xmax
-!3001 format(2f8.3,3i5,2f8.3)
-
- return
-end subroutine msk40_freq_search
diff --git a/lib/msk40decodeframe.f90 b/lib/msk40decodeframe.f90
deleted file mode 100644
index 363d8dc..0000000
--- a/lib/msk40decodeframe.f90
+++ /dev/null
@@ -1,169 +0,0 @@
-subroutine msk40decodeframe(c,mycall,hiscall,xsnr,bswl,nhasharray, &
- recent_calls,nrecent,msgreceived,nsuccess)
-! use timer_module, only: timer
-
- parameter (NSPM=240)
- character*4 rpt(0:15)
- character*6 mycall,hiscall,mycall0,hiscall0
- character*22 hashmsg,msgreceived
- character*12 recent_calls(nrecent)
- complex cb(42)
- complex cfac,cca
- complex c(NSPM)
- integer*1 cw(32)
- integer*1 decoded(16)
- integer s8r(8),hardbits(40)
- integer nhasharray(nrecent,nrecent)
- real*8 dt, fs, pi, twopi
- real cbi(42),cbq(42)
- real pp(12)
- real softbits(40)
- real llr(32)
- logical first
- logical*1 bswl
- data first/.true./
- data s8r/1,0,1,1,0,0,0,1/
- data mycall0/'dummy'/,hiscall0/'dummy'/
- data rpt/"-03 ","+00 ","+03 ","+06 ","+10 ","+13 ","+16 ", &
- "R-03","R+00","R+03","R+06","R+10","R+13","R+16", &
- "RRR ","73 "/
- save first,cb,fs,pi,twopi,dt,s8r,pp,rpt,mycall0,hiscall0,ihash
-
- if(first) then
-! define half-sine pulse and raised-cosine edge window
- pi=4d0*datan(1d0)
- twopi=8d0*datan(1d0)
- fs=12000.0
- dt=1.0/fs
-
- do i=1,12
- angle=(i-1)*pi/12.0
- pp(i)=sin(angle)
- enddo
-
-! define the sync word waveforms
- s8r=2*s8r-1
- cbq(1:6)=pp(7:12)*s8r(1)
- cbq(7:18)=pp*s8r(3)
- cbq(19:30)=pp*s8r(5)
- cbq(31:42)=pp*s8r(7)
- cbi(1:12)=pp*s8r(2)
- cbi(13:24)=pp*s8r(4)
- cbi(25:36)=pp*s8r(6)
- cbi(37:42)=pp(1:6)*s8r(8)
- cb=cmplx(cbi,cbq)
- first=.false.
- endif
-
- if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then
- hashmsg=trim(mycall)//' '//trim(hiscall)
- if( hashmsg .ne. ' ' .and. hiscall .ne. '' ) then ! protect against blank mycall/hiscall
- call fmtmsg(hashmsg,iz)
- call hash(hashmsg,22,ihash)
- ihash=iand(ihash,4095)
- else
- ihash=9999 ! so that it can never match a received hash
- endif
- mycall0=mycall
- hiscall0=hiscall
- endif
-
- nsuccess=0
- msgreceived=' '
-
-! Estimate carrier phase.
- cca=sum(c(1:1+41)*conjg(cb))
- phase0=atan2(imag(cca),real(cca))
-
-! Remove phase error - want constellation rotated so that sample points lie on I/Q axes
- cfac=cmplx(cos(phase0),sin(phase0))
- c=c*conjg(cfac)
-
-! Matched filter.
- softbits(1)=sum(imag(c(1:6))*pp(7:12))+sum(imag(c(NSPM-5:NSPM))*pp(1:6))
- softbits(2)=sum(real(c(1:12))*pp)
- do i=2,20
- softbits(2*i-1)=sum(imag(c(1+(i-1)*12-6:1+(i-1)*12+5))*pp)
- softbits(2*i)=sum(real(c(7+(i-1)*12-6:7+(i-1)*12+5))*pp)
- enddo
-
-! Sync word hard error weight is used to reject frames that
-! are unlikely to decode.
- hardbits=0
- do i=1,40
- if( softbits(i) .ge. 0.0 ) then
- hardbits(i)=1
- endif
- enddo
- nbadsync1=(8-sum( (2*hardbits(1:8)-1)*s8r ) )/2
- nbadsync=nbadsync1
- if( nbadsync .gt. 3 ) then
- return
- endif
-
-! Normalize the softsymbols before submitting to decoder.
- sav=sum(softbits)/40
- s2av=sum(softbits*softbits)/40
- ssig=sqrt(s2av-sav*sav)
- softbits=softbits/ssig
-
- sigma=0.75
-! if(xsnr.lt.0.0) sigma=0.75-0.0875*xsnr
- if(xsnr.lt.0.0) sigma=0.75-0.11*xsnr
- llr(1:32)=softbits(9:40)
- llr=2.0*llr/(sigma*sigma)
-
- max_iterations=5
- call bpdecode40(llr,max_iterations,decoded,niterations)
-
- if( niterations .ge. 0.0 ) then
- call encode_msk40(decoded,cw)
- nhammd=0
- cord=0.0
- do i=1,32
- if( cw(i) .ne. hardbits(i+8) ) then
- nhammd=nhammd+1
- cord=cord+abs(softbits(i+8))
- endif
- enddo
-
- imsg=0
- do i=1,16
- imsg=ishft(imsg,1)+iand(1_1,decoded(17-i))
- enddo
- nrxrpt=iand(imsg,15)
- nrxhash=(imsg-nrxrpt)/16
-
- if(nhammd.le.4 .and. cord .lt. 0.65 .and. &
- nrxhash.eq.ihash .and. nrxrpt.ge.7) then
-!write(*,*) 'decodeframe 1',nbadsync,nhammd,cord,nrxhash,nrxrpt,ihash,xsnr,sigma
- nsuccess=1
- write(msgreceived,'(a1,a,1x,a,a1,1x,a4)') "<",trim(mycall), &
- trim(hiscall),">",rpt(nrxrpt)
- return
- elseif(bswl .and. nhammd.le.4 .and. cord.lt.0.65 .and. nrxrpt.ge.7 ) then
- do i=1,nrecent
- do j=i+1,nrecent
- if( nrxhash .eq. nhasharray(i,j) ) then
- nsuccess=2
- write(msgreceived,'(a1,a,1x,a,a1,1x,a4)') "<",trim(recent_calls(i)), &
- trim(recent_calls(j)),">",rpt(nrxrpt)
-!write(*,*) 'decodeframe 2',nbadsync,nhammd,cord,nrxhash,nrxrpt,ihash,xsnr,sigma
- elseif( nrxhash .eq. nhasharray(j,i) ) then
- nsuccess=2
- write(msgreceived,'(a1,a,1x,a,a1,1x,a4)') "<",trim(recent_calls(j)), &
- trim(recent_calls(i)),">",rpt(nrxrpt)
-!write(*,*) 'decodeframe 3',nbadsync,nhammd,cord,nrxhash,nrxrpt,ihash,xsnr,sigma
- endif
- enddo
- enddo
- if(nsuccess.eq.0) then
- nsuccess=3
-!write(*,*) 'decodeframe 4',bswl,nbadsync,nhammd,cord,nrxhash,nrxrpt,ihash,xsnr,sigma,nsuccess
- write(msgreceived,'(a1,i4.4,a1,1x,a4)') "<",nrxhash,">",rpt(nrxrpt)
- endif
- endif
- endif
-
- return
-end subroutine msk40decodeframe
diff --git a/lib/msk40spd.f90 b/lib/msk40spd.f90
deleted file mode 100644
index c8af1a4..0000000
--- a/lib/msk40spd.f90
+++ /dev/null
@@ -1,199 +0,0 @@
-subroutine msk40spd(cbig,n,ntol,mycall,hiscall,bswl,nhasharray,recent_calls, &
- nrecent,nsuccess,msgreceived,fc,fret,tret,navg)
-! msk40 short-ping-decoder
-
- use timer_module, only: timer
-
- parameter (NSPM=240, MAXSTEPS=150, NFFT=NSPM, MAXCAND=5, NPATTERNS=6)
- character*6 mycall,hiscall
- character*22 msgreceived
- character*12 recent_calls(nrecent)
- complex cbig(n)
- complex cdat(3*NSPM) !Analytic signal
- complex c(NSPM)
- complex ct(NSPM)
- complex ctmp(NFFT)
- integer, dimension(1) :: iloc
- integer indices(MAXSTEPS)
- integer npkloc(10)
- integer navpatterns(3,NPATTERNS)
- integer navmask(3)
- integer nstart(MAXCAND)
- integer nhasharray(nrecent,nrecent)
- logical ismask(NFFT)
- logical*1 bswl
- real detmet(-2:MAXSTEPS+3)
- real detmet2(-2:MAXSTEPS+3)
- real detfer(MAXSTEPS)
- real rcw(12)
- real ferrs(MAXCAND)
- real snrs(MAXCAND)
- real tonespec(NFFT)
- real tpat(NPATTERNS)
- real*8 dt, df, fs, pi, twopi
- logical first
- data first/.true./
- data navpatterns/ &
- 0,1,0, &
- 1,0,0, &
- 0,0,1, &
- 1,1,0, &
- 0,1,1, &
- 1,1,1/
- data tpat/1.5,0.5,2.5,1.0,2.0,1.5/
- save df,first,fs,pi,twopi,dt,tframe,rcw
-
- if(first) then
- nmatchedfilter=1
-! define half-sine pulse and raised-cosine edge window
- pi=4d0*datan(1d0)
- twopi=8d0*datan(1d0)
- fs=12000.0
- dt=1.0/fs
- df=fs/NFFT
- tframe=NSPM/fs
-
- do i=1,12
- angle=(i-1)*pi/12.0
- rcw(i)=(1-cos(angle))/2
- enddo
-
- first=.false.
- endif
-
-
- ! fill the detmet, detferr arrays
- nstep=(n-NSPM)/60 ! 20ms/4=5ms steps
- detmet=0
- detmet2=0
- detfer=-999.99
- nfhi=2*(fc+500)
- nflo=2*(fc-500)
- ihlo=nint((nfhi-2*ntol)/df)+1
- ihhi=nint((nfhi+2*ntol)/df)+1
- illo=nint((nflo-2*ntol)/df)+1
- ilhi=nint((nflo+2*ntol)/df)+1
- i2000=nint(nflo/df)+1
- i4000=nint(nfhi/df)+1
- do istp=1,nstep
- ns=1+60*(istp-1)
- ne=ns+NSPM-1
- if( ne .gt. n ) exit
- ctmp=cmplx(0.0,0.0)
- ctmp(1:NSPM)=cbig(ns:ne)
-
-! Coarse carrier frequency sync - seek tones at 2000 Hz and 4000 Hz in
-! squared signal spectrum.
-
- ctmp=ctmp**2
- ctmp(1:12)=ctmp(1:12)*rcw
- ctmp(NSPM-11:NSPM)=ctmp(NSPM-11:NSPM)*rcw(12:1:-1)
- call four2a(ctmp,NFFT,1,-1,1)
- tonespec=abs(ctmp)**2
-
- ismask=.false.
- ismask(ihlo:ihhi)=.true. ! high tone search window
- iloc=maxloc(tonespec,ismask)
- ihpk=iloc(1)
- deltah=-real( (ctmp(ihpk-1)-ctmp(ihpk+1)) / (2*ctmp(ihpk)-ctmp(ihpk-1)-ctmp(ihpk+1)) )
- ah=tonespec(ihpk)
- ahavp=(sum(tonespec,ismask)-ah)/count(ismask)
- trath=ah/(ahavp+0.01)
- ismask=.false.
- ismask(illo:ilhi)=.true. ! window for low tone
- iloc=maxloc(tonespec,ismask)
- ilpk=iloc(1)
- deltal=-real( (ctmp(ilpk-1)-ctmp(ilpk+1)) / (2*ctmp(ilpk)-ctmp(ilpk-1)-ctmp(ilpk+1)) )
- al=tonespec(ilpk)
- alavp=(sum(tonespec,ismask)-al)/count(ismask)
- tratl=al/(alavp+0.01)
- fdiff=(ihpk+deltah-ilpk-deltal)*df
- ferrh=(ihpk+deltah-i4000)*df/2.0
- ferrl=(ilpk+deltal-i2000)*df/2.0
- if( ah .ge. al ) then
- ferr=ferrh
- else
- ferr=ferrl
- endif
- detmet(istp)=max(ah,al)
- detmet2(istp)=max(trath,tratl)
- detfer(istp)=ferr
- enddo ! end of detection-metric and frequency error estimation loop
-
- call indexx(detmet(1:nstep),nstep,indices) !find median of detection metric vector
- xmed=detmet(indices(nstep/4))
- detmet=detmet/xmed ! noise floor of detection metric is 1.0
- ndet=0
-
- do ip=1,MAXCAND ! Find candidates
- iloc=maxloc(detmet(1:nstep))
- il=iloc(1)
- if( (detmet(il) .lt. 3.5) ) exit
- if( abs(detfer(il)) .le. ntol ) then
- ndet=ndet+1
- nstart(ndet)=1+(il-1)*60+1
- ferrs(ndet)=detfer(il)
- snrs(ndet)=12.0*log10(detmet(il))/2-9.0
- endif
- detmet(il)=0.0
- enddo
-
- if( ndet .lt. 3 ) then
- do ip=1,MAXCAND-ndet ! Find candidates
- iloc=maxloc(detmet2(1:nstep))
- il=iloc(1)
- if( (detmet2(il) .lt. 12.0) ) exit
- if( abs(detfer(il)) .le. ntol ) then
- ndet=ndet+1
- nstart(ndet)=1+(il-1)*60+1
- ferrs(ndet)=detfer(il)
- snrs(ndet)=12.0*log10(detmet2(il))/2-9.0
- endif
- detmet2(il)=0.0
- enddo
- endif
-
- nsuccess=0
- msgreceived=' '
- npeaks=2
- ntol0=29
- deltaf=7.2
- do icand=1,ndet ! Try to sync/demod/decode each candidate.
- ib=max(1,nstart(icand)-NSPM)
- ie=ib-1+3*NSPM
- if( ie .gt. n ) then
- ie=n
- ib=ie-3*NSPM+1
- endif
- cdat=cbig(ib:ie)
- fo=fc+ferrs(icand)
- xsnr=snrs(icand)
- do iav=1,NPATTERNS
- navmask=navpatterns(1:3,iav)
- call msk40sync(cdat,3,ntol0,deltaf,navmask,npeaks,fo,fest,npkloc, &
- nsyncsuccess,c)
- if( nsyncsuccess .eq. 0 ) cycle
-
- do ipk=1,npeaks
- do is=1,3
- ic0=npkloc(ipk)
- if( is.eq.2) ic0=max(1,ic0-1)
- if( is.eq.3) ic0=min(NSPM,ic0+1)
- ct=cshift(c,ic0-1)
- call msk40decodeframe(ct,mycall,hiscall,xsnr,bswl,nhasharray, &
- recent_calls,nrecent,msgreceived,ndecodesuccess)
- if( ndecodesuccess .gt. 0 ) then
-!write(*,*) icand, iav, ipk, is, tret, fret, msgreceived
- tret=(nstart(icand)+NSPM/2)/fs
- fret=fest
- navg=sum(navmask)
- nsuccess=ndecodesuccess
- return
- endif
- enddo
- enddo
- enddo
- enddo ! candidate loop
-
- return
-end subroutine msk40spd
diff --git a/lib/msk40sync.f90 b/lib/msk40sync.f90
deleted file mode 100644
index 5a2ca1e..0000000
--- a/lib/msk40sync.f90
+++ /dev/null
@@ -1,103 +0,0 @@
-subroutine msk40sync(cdat,nframes,ntol,delf,navmask,npeaks,fc,fest, &
- npklocs,nsuccess,c)
-
- !$ use omp_lib
-
- parameter (NSPM=240)
- complex cdat(NSPM*nframes)
- complex cdat2(NSPM*nframes,8)
- complex c(NSPM) !Coherently averaged complex data
- complex cs(NSPM,8)
- complex cb(42) !Complex waveform for sync word
-
- integer s8r(8)
- integer iloc(1)
- integer npklocs(npeaks)
- integer navmask(nframes) ! defines which frames to average
-
- real cbi(42),cbq(42)
- real pkamps(npeaks)
- real xcc(0:NSPM-1)
- real xccs(0:NSPM-1,8)
- real xm(8)
- real bf(8)
- real pp(12) !Half-sine pulse shape
- logical first
- data first/.true./
- data s8r/1,0,1,1,0,0,0,1/
- save first,cb,fs,pi,twopi,dt,s8r,pp
-
- if(first) then
- pi=4.0*atan(1.0)
- twopi=8.0*atan(1.0)
- fs=12000.0
- dt=1.0/fs
-
- do i=1,12 !Define half-sine pulse
- angle=(i-1)*pi/12.0
- pp(i)=sin(angle)
- enddo
-
-! Define the sync word waveforms
- s8r=2*s8r-1
- cbq(1:6)=pp(7:12)*s8r(1)
- cbq(7:18)=pp*s8r(3)
- cbq(19:30)=pp*s8r(5)
- cbq(31:42)=pp*s8r(7)
- cbi(1:12)=pp*s8r(2)
- cbi(13:24)=pp*s8r(4)
- cbi(25:36)=pp*s8r(6)
- cbi(37:42)=pp(1:6)*s8r(8)
- cb=cmplx(cbi,cbq)
-
- first=.false.
- endif
-
- nfreqs=2*nint(ntol/delf) + 1
- xm=0.0
- bf=0.0
- nthreads=1
- !$ nthreads=min(8,int(OMP_GET_MAX_THREADS(),4))
- nstep=nfreqs/nthreads
-
- !$OMP PARALLEL NUM_THREADS(nthreads) PRIVATE(id,if1,if2)
- id=1
- !$ id=OMP_GET_THREAD_NUM() + 1 !Thread id = 1,2,...
- if1=-nint(ntol/delf) + (id-1)*nstep
- if2=if1+nstep-1
- if(id.eq.nthreads) if2=nint(ntol/delf)
- call msk40_freq_search(cdat,fc,if1,if2,delf,nframes,navmask,cb, &
- cdat2(1,id),xm(id),bf(id),cs(1,id),xccs(1,id))
-! write(73,3002) id,if1,if2,nfreqs,nthreads,bf(id),xm(id)
-!3002 format(5i5,2f10.3)
- !$OMP END PARALLEL
-
- xmax=xm(1)
- fest=fc+bf(1)
- c=cs(1:NSPM,1)
- xcc=xccs(0:NSPM-1,1)
- if(nthreads.gt.1) then
- do i=2,nthreads
- if(xm(i).gt.xmax) then
- xmax=xm(i)
- fest=fc+bf(i)
- c=cs(1:NSPM,i)
- xcc=xccs(0:NSPM-1,i)
- endif
- enddo
- endif
-
-! Find npeaks largest peaks
- do ipk=1,npeaks
- iloc=maxloc(xcc)
- ic2=iloc(1)
- npklocs(ipk)=ic2
- pkamps(ipk)=xcc(ic2-1)
- xcc(max(0,ic2-7):min(NSPM-1,ic2+7))=0.0
- enddo
-
- nsuccess=0
- if( xmax .ge. 1.3 ) nsuccess=1
-
- return
-end subroutine msk40sync
diff --git a/lib/mskber.f90 b/lib/mskber.f90
deleted file mode 100644
index 4b31127..0000000
--- a/lib/mskber.f90
+++ /dev/null
@@ -1,146 +0,0 @@
-program mskber
-
-! Generate an MSK waveform, pass it through an AWGN channel, apply coherent
-! MSK receiver, and count number of errors at each Eb/No.
-
- parameter (MAXSYM=1000*1000)
- parameter (NSPS=5) !Samples per symbol
- real ct(-NSPS:NSPS*MAXSYM-1) !cos(pi*t/2T)
- real st(-NSPS:NSPS*MAXSYM-1) !sin(pi*t/2T)
- real r(0:MAXSYM-1) !Random numbers to set test bits
- real xsym(0:MAXSYM-1) !Soft Rx symbols
-
- complex xt(-NSPS:NSPS*MAXSYM-1) !Complex baseband Tx waveform
- complex nt(-NSPS:NSPS*MAXSYM-1) !Generated AWGN channel noise
- complex yt(-NSPS:NSPS*MAXSYM-1) !Received signal, yt = xt + fac*nt
- complex cwave(-NSPS:NSPS*MAXSYM-1) !Audio waveform, Tx real part
- complex z
-
- integer sym0(0:MAXSYM-1) !Generated test bits
- integer sym(0:MAXSYM-1) !Hard-copy received bits
- integer sym1(0:7)
-
- character*12 arg
- data sym1/1,1,0,0,0,1,1,1/
-
- nargs=iargc()
- if(nargs.ne.2) then
- print*,'Usage: mskber nsym EbNo'
- go to 999
- endif
- call getarg(1,arg)
- read(arg,*) nsym
- call getarg(2,arg)
- read(arg,*) EbNo
-
- pi=4.0*atan(1.0)
-
- do i=-NSPS,NSPS*nsym-1 !Define ct, st arrays
- t=i*pi/(2.0*NSPS)
- ct(i)=cos(t)
- st(i)=sin(t)
- enddo
- fac=1.0/sqrt(float(NSPS))
-
- do iEbNo=0,10 !Loop over a range of Eb/No
- sym0=0
- call random_number(r)
- where(r(0:nsym-1).gt.0.5) sym0(0:nsym-1)=1 !Generate random data bits
- if(nsym.eq.8) sym0(0:nsym-1)=sym1
- call mskmod(sym0,nsym,NSPS,ct,st,xt,cwave) !Generate Tx waveform
-
- do i=-NSPS,NSPS*nsym-1 !Generate Gaussian noise
- xx=0.707*gran()
- yy=0.707*gran()
- nt(i)=cmplx(xx,yy)
- enddo
- fac_noise=10.0**(-iEbNo/20.0)
- if(EbNo.ne.0.0) fac_noise=10.0**(-EbNo/20.0)
- yt=xt + fac_noise*nt !Rx signal, with noise
-
- call mskdemod(yt,nsym,NSPS,ct,st,xsym) !MSK demodulator
-
- sym=0
- where(xsym.gt.0.0) sym=1
-
- if(nsym.le.160 .and. EbNo.ne.0.0) then
- write(*,1012) sym0(0:nsym-1)
- if(nsym.gt.50) write(*,1012)
- write(*,1012) sym(0:nsym-1)
-1012 format(50i1)
- do i=-nsps,nsps*nsym-1
- phi=i*2.0*pi*1500/12000.0
- z=cwave(i)*cmplx(cos(phi),sin(phi)) !Mix back to baseband
- write(51,1014) float(i)/nsps,xt(i),abs(xt(i)),cwave(i),z
-1014 format(8f8.4)
- enddo
- endif
-
-! Count the hard errors
- nerr=count(sym(0:nsym-1).ne.sym0(0:nsym-1))
- thber=0.5*erfc(10.0**(iEbNo/20.0))
- xEbNo=iEbNo
- if(EbNo.ne.0.0) xEbNo=EbNo
- write(*,1000) xEbNo,thber,float(nerr)/nsym
-1000 format(f6.1,2f10.6)
- if(EbNo.ne.0.0) exit
- enddo
-
-999 end program mskber
-
-subroutine mskmod(sym,nsym,nsps,ct,st,xt,cwave)
-
-! Generate MSK Tx waveform at baseband.
-
- integer sym(0:nsym-1) !Hard-copy received bits
- complex xt(-nsps:nsps*nsym-1) !Complex baseband Tx waveform
- complex cwave(-nsps:nsps*nsym-1) !Audio waveform, fc=1500 Hz.
- real ct(-nsps:nsps*nsym-1) !cos(pi*t/2T)
- real st(-nsps:nsps*nsym-1) !sin(pi*t/2T)
- real ai(-nsps:nsps*nsym-1) !Rectangular pulses for even symbols
- real aq(-nsps:nsps*nsym-1) !Rectangular pulses for odd symbols
-
- ai=0.
- aq=0.
- fac=1.0/sqrt(float(nsps))
- do j=0,nsym-1,2
- ia=(j-1)*nsps
- ib=ia+2*nsps-1
- ai(ia:ib)=2*sym(j)-1 !Even bits as rectangular pulses
- aq(ia+nsps:ib+nsps)=2*sym(j+1)-1 !Odd bits as rectangular pulses
- enddo
- xt=fac*cmplx(ai*ct,aq*st) !Baseband Tx waveform
-
- twopi=8.0*atan(1.0)
- do i=-nsps,nsps*nsym-1
- phi=i*twopi*1500/12000.0
- cwave(i)=xt(i)*cmplx(cos(phi),-sin(phi))
- enddo
-
- return
-end subroutine mskmod
-
-subroutine mskdemod(yt,nsym,nsps,ct,st,xsym)
-
-! MSK demodulator
-! Rx phase must be known and stable; symbol sync must be established.
-
- complex yt(-nsps:nsps*nsym-1) !Received signal
- real ct(-nsps:nsps*nsym-1) !cos(pi*t/2T)
- real st(-nsps:nsps*nsym-1) !sin(pi*t/2T)
- real xe(-nsps:nsps*nsym-1) !Temp array for received even symbols
- real xo(-nsps:nsps*nsym-1) !Temp array for received odd symbols
- real xsym(0:nsym-1) !Soft Rx symbols
-
- iz=nsps*(nsym+1)
- xe(-nsps:nsps*nsym-1)=real(yt)*ct !Apply matched filters
- xo(-nsps:nsps*nsym-1)=aimag(yt)*st
- do j=0,nsym-1,2
- ia=(j-1)*nsps
- ib=ia+2*nsps-1
- xsym(j)=sum(xe(ia:ib)) !Integrate over 2 symbol lengths
- xsym(j+1)=sum(xo(ia+nsps:ib+nsps))
- enddo
-
- return
-end subroutine mskdemod
diff --git a/lib/mskdt.f90 b/lib/mskdt.f90
deleted file mode 100644
index bca8359..0000000
--- a/lib/mskdt.f90
+++ /dev/null
@@ -1,78 +0,0 @@
-subroutine mskdt(d,npts,ty,yellow,nyel)
-
- parameter (NFFT=1024,NH=NFFT/2)
- real d(npts)
- real x(0:NFFT-1)
- real green(703)
- real yellow(703) !703 = 30*12000/512
- real ty(703)
- real y2(175)
- real ty2(175)
- integer indx(703)
- logical ok
- complex c(0:NH)
- equivalence (x,c)
-
- df=12000.0/NFFT
- i1=nint(300.0/df)
- i2=nint(800.0/df)
- i3=nint(2200.0/df)
- i4=nint(2700.0/df)
- nblks=npts/NH - 1
-
- do j=1,nblks
- ib=(j+1)*NH
- ia=ib-NFFT+1
- x=d(ia:ib)
- call four2a(x,NFFT,1,-1,0) !r2c FFT
- sqlow=0.
- do i=i1,i2
- sqlow=sqlow + real(c(i))**2 + aimag(c(i))**2
- enddo
- sqmid=0.
- do i=i2,i3
- sqmid=sqmid + real(c(i))**2 + aimag(c(i))**2
- enddo
- sqhigh=0.
- do i=i3,i4
- sqhigh=sqhigh + real(c(i))**2 + aimag(c(i))**2
- enddo
- green(j)=db(sqlow+sqmid+sqhigh)
- yellow(j)=db(sqmid/(sqlow+sqhigh))
- ty(j)=j*512.0/12000.0
- enddo
-
- npct=20
- call pctile(green,nblks,npct,base)
- green(1:nblks)=green(1:nblks) - base - 0.3
- call pctile(yellow,nblks,npct,base)
- yellow(1:nblks)=yellow(1:nblks) - base - 0.6
- call indexx(yellow,nblks,indx)
-
- do j=1,nblks/4
- k=indx(nblks+1-j)
- ty(j)=ty(k)
- yellow(j)=yellow(k)
- if(yellow(j).lt.1.5) exit
- enddo
- nyel=j-1
- k=1
- y2(1)=yellow(1)
- ty2(1)=ty(1)
- do j=2,nyel
- ok=.true.
- do i=1,j-1
- if(abs(ty(i)-ty(j)).lt.0.117) ok=.false.
- enddo
- if(ok) then
- k=k+1
- y2(k)=yellow(j)
- ty2(k)=ty(j)
- endif
- enddo
- nyel=k
- yellow(1:nyel)=y2(1:nyel)
- ty(1:nyel)=ty2(1:nyel)
-
- return
-end subroutine mskdt
diff --git a/lib/mskrtd.f90 b/lib/mskrtd.f90
deleted file mode 100644
index 5712c71..0000000
--- a/lib/mskrtd.f90
+++ /dev/null
@@ -1,257 +0,0 @@
-subroutine mskrtd(id2,nutc0,tsec,ntol,nrxfreq,ndepth,mycall,mygrid,hiscall, &
- bshmsg,bcontest,btrain,pcoeffs,bswl,datadir,line)
-
-! Real-time decoder for MSK144.
-! Analysis block size = NZ = 7168 samples, t_block = 0.597333 s
-! Called from hspec() at half-block increments, about 0.3 s
-
- parameter (NZ=7168) !Block size
- parameter (NSPM=864) !Number of samples per message frame
- parameter (NFFT1=8192) !FFT size for making analytic signal
- parameter (NPATTERNS=4) !Number of frame averaging patterns to try
- parameter (NRECENT=10) !Number of recent calls to remember
- parameter (NSHMEM=50) !Number of recent SWL messages to remember
-
- character*4 decsym !"&" for mskspd or "^" for long averages
- character*22 msgreceived !Decoded message
- character*22 msglast,msglastswl !Used for dupechecking
- character*80 line !Formatted line with UTC dB T Freq Msg
- character*12 mycall,hiscall
- character*6 mygrid
- character*12 recent_calls(NRECENT)
- character*22 recent_shmsgs(NSHMEM)
- character*512 datadir
-
- complex cdat(NFFT1) !Analytic signal
- complex c(NSPM) !Coherently averaged complex data
- complex ct(NSPM)
-
- integer*2 id2(NZ) !Raw 16-bit data
- integer iavmask(8)
- integer iavpatterns(8,NPATTERNS)
- integer npkloc(10)
- integer nhasharray(NRECENT,NRECENT)
- integer nsnrlast,nsnrlastswl
-
- real d(NFFT1)
- real pow(8)
- real softbits(144)
- real xmc(NPATTERNS)
- real*8 pcoeffs(5)
-
- logical*1 bshmsg,bcontest,btrain,bswl
- logical*1 first
- logical*1 bshdecode
- logical*1 seenb4
- logical*1 bflag
- logical*1 bvar
-
- data first/.true./
- data iavpatterns/ &
- 1,1,1,1,0,0,0,0, &
- 0,0,1,1,1,1,0,0, &
- 1,1,1,1,1,0,0,0, &
- 1,1,1,1,1,1,1,0/
- data xmc/2.0,4.5,2.5,3.5/ !Used to set time at center of averaging mask
- save first,tsec0,nutc00,pnoise,cdat,msglast,msglastswl, &
- nsnrlast,nsnrlastswl,recent_calls,nhasharray,recent_shmsgs
-
- if(first) then
- tsec0=tsec
- nutc00=nutc0
- pnoise=-1.0
- do i=1,nrecent
- recent_calls(i)(1:12)=' '
- enddo
- do i=1,nshmem
- recent_shmsgs(i)(1:22)=' '
- enddo
- msglast=' '
- msglastswl=' '
- nsnrlast=-99
- nsnrlastswl=-99
- first=.false.
- endif
-
- fc=nrxfreq
-
-! Dupe checking setup
- if(nutc00.ne.nutc0 .or. tsec.lt.tsec0) then ! reset dupe checker
- msglast=' '
- msglastswl=' '
- nsnrlast=-99
- nsnrlastswl=-99
- nutc00=nutc0
- endif
-
- tframe=float(NSPM)/12000.0
- line=char(0)
- msgreceived=' '
- max_iterations=10
- niterations=0
- d(1:NZ)=id2
- rms=sqrt(sum(d(1:NZ)*d(1:NZ))/NZ)
- if(rms.lt.1.0) go to 999
- fac=1.0/rms
- d(1:NZ)=fac*d(1:NZ)
- d(NZ+1:NFFT1)=0.
- bvar=.true.
- if( btrain ) bvar=.false. ! if training, turn off rx eq
- call analytic(d,NZ,NFFT1,cdat,pcoeffs,bvar)
-
-! Calculate average power for each frame and for the entire block.
-! If decode is successful, largest power will be taken as signal+noise.
-! If no decode, entire-block average will be used to update noise estimate.
- pmax=-99
- do i=1,8
- ib=(i-1)*NSPM+1
- ie=ib+NSPM-1
- pow(i)=real(dot_product(cdat(ib:ie),cdat(ib:ie)))*rms**2
- pmax=max(pmax,pow(i))
- enddo
- pavg=sum(pow)/8.0
-
-! Short ping decoder uses squared-signal spectrum to determine where to
-! center a 3-frame analysis window and attempts to decode each of the
-! 3 frames along with 2- and 3-frame averages.
- np=8*NSPM
- call msk144spd(cdat,np,ntol,ndecodesuccess,msgreceived,fc,fest,tdec,navg,ct, &
- softbits,recent_calls,nrecent)
- if(ndecodesuccess.eq.0 .and. (bshmsg.or.bswl)) then
- call msk40spd(cdat,np,ntol,mycall(1:6),hiscall(1:6),bswl,nhasharray, &
- recent_calls,nrecent,ndecodesuccess,msgreceived,fc,fest,tdec,navg)
- endif
- if( ndecodesuccess .ge. 1 ) then
- tdec=tsec+tdec
- ipk=0
- is=0
- goto 900
- endif
-
-! If short ping decoder doesn't find a decode,
-! Fast - short ping decoder only.
-! Normal - try 4-frame averages
-! Deep - try 4-, 5- and 7-frame averages.
- npat=NPATTERNS
- if( ndepth .eq. 1 ) npat=0
- if( ndepth .eq. 2 ) npat=2
- do iavg=1,npat
- iavmask=iavpatterns(1:8,iavg)
- navg=sum(iavmask)
- deltaf=10.0/real(navg) ! search increment for frequency sync
- npeaks=2
- call msk144sync(cdat(1:8*NSPM),8,ntol,deltaf,iavmask,npeaks,fc, &
- fest,npkloc,nsyncsuccess,xmax,c)
- if( nsyncsuccess .eq. 0 ) cycle
-
- do ipk=1,npeaks
- do is=1,3
- ic0=npkloc(ipk)
- if(is.eq.2) ic0=max(1,ic0-1)
- if(is.eq.3) ic0=min(NSPM,ic0+1)
- ct=cshift(c,ic0-1)
- call msk144decodeframe(ct,softbits,msgreceived,ndecodesuccess, &
- recent_calls,nrecent)
- if(ndecodesuccess .gt. 0) then
- tdec=tsec+xmc(iavg)*tframe
- goto 900
- endif
- enddo !Slicer dither
- enddo !Peak loop
- enddo
-
-
- msgreceived=' '
-
-! no decode - update noise level used for calculating displayed snr.
- if( pnoise .lt. 0 ) then ! initialize noise level
- pnoise=pavg
- elseif( pavg .gt. pnoise ) then ! noise level is slow to rise
- pnoise=0.9*pnoise+0.1*pavg
- elseif( pavg .lt. pnoise ) then ! and quick to fall
- pnoise=pavg
- endif
- go to 999
-
-900 continue
-! Successful decode - estimate snr
- if( pnoise .gt. 0.0 ) then
- snr0=10.0*log10(pmax/pnoise-1.0)
- else
- snr0=0.0
- endif
- nsnr=nint(snr0)
-
- bshdecode=.false.
- if( msgreceived(1:1) .eq. '<' ) bshdecode=.true.
-
- if(.not. bshdecode) then
- call msk144signalquality(ct,snr0,fest,tdec,softbits,msgreceived,hiscall, &
- btrain,datadir,ncorrected,eyeopening,pcoeffs)
- endif
-
- decsym=' & '
- if( btrain ) decsym=' ^ '
- if( msgreceived(1:1).eq.'<') then
- ncorrected=0
- eyeopening=0.0
- endif
-
- if( nsnr .lt. -8 ) nsnr=-8
- if( nsnr .gt. 24 ) nsnr=24
-
-! Dupe check.
- bflag=ndecodesuccess.eq.1 .and. &
- (msgreceived.ne.msglast .or. nsnr.gt.nsnrlast .or. tsec.lt.tsec0)
- if(bflag) then
- msglast=msgreceived
- nsnrlast=nsnr
- if(.not. bshdecode) then
- call update_hasharray(recent_calls,nrecent,nhasharray)
- if(bcontest) call fix_contest_msg(mygrid,msgreceived)
- endif
- write(line,1020) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived, &
- navg,ncorrected,eyeopening,char(0)
-1020 format(i6.6,i4,f5.1,i5,a4,a22,i2,i3,f5.1,a1)
- elseif(bswl .and. ndecodesuccess.ge.2) then
- seenb4=.false.
- do i=1,nshmem
- if( msgreceived .eq. recent_shmsgs(i) ) then
- seenb4=.true.
- endif
- enddo
- call update_recent_shmsgs(msgreceived,recent_shmsgs,nshmem)
- bflag=seenb4 .and. &
- (msgreceived.ne.msglastswl .or. nsnr.gt.nsnrlastswl .or. tsec.lt.tsec0) &
- .and. nsnr.gt.-6
- if(bflag) then
- msglastswl=msgreceived
- nsnrlastswl=nsnr
- write(line,1020) nutc0,nsnr,tdec,nint(fest),decsym,msgreceived, &
- navg,ncorrected,eyeopening,char(0)
- endif
- endif
-999 tsec0=tsec
-
- return
-end subroutine mskrtd
-
-subroutine update_recent_shmsgs(message,msgs,nsize)
- character*22 msgs(nsize)
- character*22 message
- logical*1 seen
-
- seen=.false.
- do i=1,nsize
- if( msgs(i) .eq. message ) seen=.true.
- enddo
-
- if( .not. seen ) then
- do i=nsize,2,-1
- msgs(i)=msgs(i-1)
- enddo
- msgs(1)=message
- endif
-
- return
-end subroutine update_recent_shmsgs
diff --git a/lib/wsprd/nhash.c b/lib/nhash.c
similarity index 100%
rename from lib/wsprd/nhash.c
rename to lib/nhash.c
diff --git a/lib/wsprd/nhash.h b/lib/nhash.h
similarity index 100%
rename from lib/wsprd/nhash.h
rename to lib/nhash.h
diff --git a/lib/packjt.f90 b/lib/packjt.f90
index faefe7b..de76813 100644
--- a/lib/packjt.f90
+++ b/lib/packjt.f90
@@ -660,8 +660,6 @@ subroutine packbits(dbits,nsymd,m0,sym)
msg(4:4).ge.'A' .and. msg(4:4).le.'Z' .and. &
msg(5:5).eq.' ') msg='CQ '//msg(3:)
- if(bcontest) call fix_contest_msg(mygrid,msg)
-
if(msg(1:5).eq.'CQ 00' .and. msg(6:6).ge.'0' .and. &
msg(6:6).le.'9') msg='CQ '//msg(6:)
diff --git a/lib/qra/qra64/Makefile.Win b/lib/qra/qra64/Makefile.Win
deleted file mode 100644
index 7bd10c2..0000000
--- a/lib/qra/qra64/Makefile.Win
+++ /dev/null
@@ -1,30 +0,0 @@
-FC = gfortran
-CC = gcc
-CFLAGS = -O2 -Wall -I. -D_WIN32
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: qra64.exe
-
-OBJS1 = main.o qra64.o
-qra64.exe: $(OBJS1)
- ${CC} -o qra64.exe $(OBJS1) ../qracodes/libqra64.a -lm
-
-OBJS2 = qra64sim.o options.o wavhdr.o
-qra64sim.exe: $(OBJS2)
- ${FC} -o qra64sim.exe $(OBJS2) ../qracodes/libqra64.a -lm
-
-.PHONY : clean
-
-clean:
- $(RM) *.o qra64.exe qra64sim.exe
diff --git a/lib/qra/qra64/fadengauss.c b/lib/qra/qra64/fadengauss.c
deleted file mode 100644
index c229626..0000000
--- a/lib/qra/qra64/fadengauss.c
+++ /dev/null
@@ -1,302 +0,0 @@
-// Gaussian energy fading tables for QRA64
-static const int glen_tab_gauss[64] = {
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 5, 5, 5, 6,
- 6, 6, 7, 7, 8, 8, 9, 10,
- 10, 11, 12, 13, 14, 15, 17, 18,
- 19, 21, 23, 25, 27, 29, 32, 34,
- 37, 41, 44, 48, 52, 57, 62, 65
-};
-static const float ggauss1[2] = {
-0.0296f, 0.9101f
-};
-static const float ggauss2[2] = {
-0.0350f, 0.8954f
-};
-static const float ggauss3[2] = {
-0.0411f, 0.8787f
-};
-static const float ggauss4[2] = {
-0.0483f, 0.8598f
-};
-static const float ggauss5[2] = {
-0.0566f, 0.8387f
-};
-static const float ggauss6[2] = {
-0.0660f, 0.8154f
-};
-static const float ggauss7[2] = {
-0.0767f, 0.7898f
-};
-static const float ggauss8[2] = {
-0.0886f, 0.7621f
-};
-static const float ggauss9[2] = {
-0.1017f, 0.7325f
-};
-static const float ggauss10[2] = {
-0.1159f, 0.7012f
-};
-static const float ggauss11[2] = {
-0.1310f, 0.6687f
-};
-static const float ggauss12[2] = {
-0.1465f, 0.6352f
-};
-static const float ggauss13[2] = {
-0.1621f, 0.6013f
-};
-static const float ggauss14[2] = {
-0.1771f, 0.5674f
-};
-static const float ggauss15[2] = {
-0.1911f, 0.5339f
-};
-static const float ggauss16[2] = {
-0.2034f, 0.5010f
-};
-static const float ggauss17[3] = {
-0.0299f, 0.2135f, 0.4690f
-};
-static const float ggauss18[3] = {
-0.0369f, 0.2212f, 0.4383f
-};
-static const float ggauss19[3] = {
-0.0454f, 0.2263f, 0.4088f
-};
-static const float ggauss20[3] = {
-0.0552f, 0.2286f, 0.3806f
-};
-static const float ggauss21[3] = {
-0.0658f, 0.2284f, 0.3539f
-};
-static const float ggauss22[3] = {
-0.0766f, 0.2258f, 0.3287f
-};
-static const float ggauss23[3] = {
-0.0869f, 0.2212f, 0.3049f
-};
-static const float ggauss24[3] = {
-0.0962f, 0.2148f, 0.2826f
-};
-static const float ggauss25[4] = {
-0.0351f, 0.1041f, 0.2071f, 0.2616f
-};
-static const float ggauss26[4] = {
-0.0429f, 0.1102f, 0.1984f, 0.2420f
-};
-static const float ggauss27[4] = {
-0.0508f, 0.1145f, 0.1890f, 0.2237f
-};
-static const float ggauss28[4] = {
-0.0582f, 0.1169f, 0.1791f, 0.2067f
-};
-static const float ggauss29[5] = {
-0.0289f, 0.0648f, 0.1176f, 0.1689f, 0.1908f
-};
-static const float ggauss30[5] = {
-0.0351f, 0.0703f, 0.1168f, 0.1588f, 0.1760f
-};
-static const float ggauss31[5] = {
-0.0411f, 0.0745f, 0.1146f, 0.1488f, 0.1623f
-};
-static const float ggauss32[6] = {
-0.0246f, 0.0466f, 0.0773f, 0.1115f, 0.1390f, 0.1497f
-};
-static const float ggauss33[6] = {
-0.0297f, 0.0512f, 0.0788f, 0.1075f, 0.1295f, 0.1379f
-};
-static const float ggauss34[6] = {
-0.0345f, 0.0549f, 0.0791f, 0.1029f, 0.1205f, 0.1270f
-};
-static const float ggauss35[7] = {
-0.0240f, 0.0387f, 0.0575f, 0.0784f, 0.0979f, 0.1118f, 0.1169f
-};
-static const float ggauss36[7] = {
-0.0281f, 0.0422f, 0.0590f, 0.0767f, 0.0926f, 0.1037f, 0.1076f
-};
-static const float ggauss37[8] = {
-0.0212f, 0.0318f, 0.0449f, 0.0596f, 0.0744f, 0.0872f, 0.0960f, 0.0991f
-};
-static const float ggauss38[8] = {
-0.0247f, 0.0348f, 0.0467f, 0.0593f, 0.0716f, 0.0819f, 0.0887f, 0.0911f
-};
-static const float ggauss39[9] = {
-0.0199f, 0.0278f, 0.0372f, 0.0476f, 0.0584f, 0.0684f, 0.0766f, 0.0819f,
-0.0838f
-};
-static const float ggauss40[10] = {
-0.0166f, 0.0228f, 0.0303f, 0.0388f, 0.0478f, 0.0568f, 0.0649f, 0.0714f,
-0.0756f, 0.0771f
-};
-static const float ggauss41[10] = {
-0.0193f, 0.0254f, 0.0322f, 0.0397f, 0.0474f, 0.0548f, 0.0613f, 0.0664f,
-0.0697f, 0.0709f
-};
-static const float ggauss42[11] = {
-0.0168f, 0.0217f, 0.0273f, 0.0335f, 0.0399f, 0.0464f, 0.0524f, 0.0576f,
-0.0617f, 0.0643f, 0.0651f
-};
-static const float ggauss43[12] = {
-0.0151f, 0.0191f, 0.0237f, 0.0288f, 0.0342f, 0.0396f, 0.0449f, 0.0498f,
-0.0540f, 0.0572f, 0.0592f, 0.0599f
-};
-static const float ggauss44[13] = {
-0.0138f, 0.0171f, 0.0210f, 0.0252f, 0.0297f, 0.0343f, 0.0388f, 0.0432f,
-0.0471f, 0.0504f, 0.0529f, 0.0545f, 0.0550f
-};
-static const float ggauss45[14] = {
-0.0128f, 0.0157f, 0.0189f, 0.0224f, 0.0261f, 0.0300f, 0.0339f, 0.0377f,
-0.0412f, 0.0444f, 0.0470f, 0.0489f, 0.0501f, 0.0505f
-};
-static const float ggauss46[15] = {
-0.0121f, 0.0146f, 0.0173f, 0.0202f, 0.0234f, 0.0266f, 0.0299f, 0.0332f,
-0.0363f, 0.0391f, 0.0416f, 0.0437f, 0.0452f, 0.0461f, 0.0464f
-};
-static const float ggauss47[17] = {
-0.0097f, 0.0116f, 0.0138f, 0.0161f, 0.0186f, 0.0212f, 0.0239f, 0.0267f,
-0.0294f, 0.0321f, 0.0346f, 0.0369f, 0.0389f, 0.0405f, 0.0417f, 0.0424f,
-0.0427f
-};
-static const float ggauss48[18] = {
-0.0096f, 0.0113f, 0.0131f, 0.0151f, 0.0172f, 0.0194f, 0.0217f, 0.0241f,
-0.0264f, 0.0287f, 0.0308f, 0.0329f, 0.0347f, 0.0362f, 0.0375f, 0.0384f,
-0.0390f, 0.0392f
-};
-static const float ggauss49[19] = {
-0.0095f, 0.0110f, 0.0126f, 0.0143f, 0.0161f, 0.0180f, 0.0199f, 0.0219f,
-0.0239f, 0.0258f, 0.0277f, 0.0294f, 0.0310f, 0.0325f, 0.0337f, 0.0347f,
-0.0354f, 0.0358f, 0.0360f
-};
-static const float ggauss50[21] = {
-0.0083f, 0.0095f, 0.0108f, 0.0122f, 0.0136f, 0.0152f, 0.0168f, 0.0184f,
-0.0201f, 0.0217f, 0.0234f, 0.0250f, 0.0265f, 0.0279f, 0.0292f, 0.0303f,
-0.0313f, 0.0320f, 0.0326f, 0.0329f, 0.0330f
-};
-static const float ggauss51[23] = {
-0.0074f, 0.0084f, 0.0095f, 0.0106f, 0.0118f, 0.0131f, 0.0144f, 0.0157f,
-0.0171f, 0.0185f, 0.0199f, 0.0213f, 0.0227f, 0.0240f, 0.0252f, 0.0263f,
-0.0273f, 0.0282f, 0.0290f, 0.0296f, 0.0300f, 0.0303f, 0.0303f
-};
-static const float ggauss52[25] = {
-0.0068f, 0.0076f, 0.0085f, 0.0094f, 0.0104f, 0.0115f, 0.0126f, 0.0137f,
-0.0149f, 0.0160f, 0.0172f, 0.0184f, 0.0196f, 0.0207f, 0.0218f, 0.0228f,
-0.0238f, 0.0247f, 0.0255f, 0.0262f, 0.0268f, 0.0273f, 0.0276f, 0.0278f,
-0.0279f
-};
-static const float ggauss53[27] = {
-0.0063f, 0.0070f, 0.0078f, 0.0086f, 0.0094f, 0.0103f, 0.0112f, 0.0121f,
-0.0131f, 0.0141f, 0.0151f, 0.0161f, 0.0170f, 0.0180f, 0.0190f, 0.0199f,
-0.0208f, 0.0216f, 0.0224f, 0.0231f, 0.0237f, 0.0243f, 0.0247f, 0.0251f,
-0.0254f, 0.0255f, 0.0256f
-};
-static const float ggauss54[29] = {
-0.0060f, 0.0066f, 0.0072f, 0.0079f, 0.0086f, 0.0093f, 0.0101f, 0.0109f,
-0.0117f, 0.0125f, 0.0133f, 0.0142f, 0.0150f, 0.0159f, 0.0167f, 0.0175f,
-0.0183f, 0.0190f, 0.0197f, 0.0204f, 0.0210f, 0.0216f, 0.0221f, 0.0225f,
-0.0228f, 0.0231f, 0.0233f, 0.0234f, 0.0235f
-};
-static const float ggauss55[32] = {
-0.0053f, 0.0058f, 0.0063f, 0.0068f, 0.0074f, 0.0080f, 0.0086f, 0.0093f,
-0.0099f, 0.0106f, 0.0113f, 0.0120f, 0.0127f, 0.0134f, 0.0141f, 0.0148f,
-0.0155f, 0.0162f, 0.0168f, 0.0174f, 0.0180f, 0.0186f, 0.0191f, 0.0196f,
-0.0201f, 0.0204f, 0.0208f, 0.0211f, 0.0213f, 0.0214f, 0.0215f, 0.0216f
-};
-static const float ggauss56[34] = {
-0.0052f, 0.0056f, 0.0060f, 0.0065f, 0.0070f, 0.0075f, 0.0080f, 0.0086f,
-0.0091f, 0.0097f, 0.0103f, 0.0109f, 0.0115f, 0.0121f, 0.0127f, 0.0133f,
-0.0138f, 0.0144f, 0.0150f, 0.0155f, 0.0161f, 0.0166f, 0.0170f, 0.0175f,
-0.0179f, 0.0183f, 0.0186f, 0.0189f, 0.0192f, 0.0194f, 0.0196f, 0.0197f,
-0.0198f, 0.0198f
-};
-static const float ggauss57[37] = {
-0.0047f, 0.0051f, 0.0055f, 0.0058f, 0.0063f, 0.0067f, 0.0071f, 0.0076f,
-0.0080f, 0.0085f, 0.0090f, 0.0095f, 0.0100f, 0.0105f, 0.0110f, 0.0115f,
-0.0120f, 0.0125f, 0.0130f, 0.0134f, 0.0139f, 0.0144f, 0.0148f, 0.0152f,
-0.0156f, 0.0160f, 0.0164f, 0.0167f, 0.0170f, 0.0173f, 0.0175f, 0.0177f,
-0.0179f, 0.0180f, 0.0181f, 0.0181f, 0.0182f
-};
-static const float ggauss58[41] = {
-0.0041f, 0.0044f, 0.0047f, 0.0050f, 0.0054f, 0.0057f, 0.0060f, 0.0064f,
-0.0068f, 0.0072f, 0.0076f, 0.0080f, 0.0084f, 0.0088f, 0.0092f, 0.0096f,
-0.0101f, 0.0105f, 0.0109f, 0.0113f, 0.0117f, 0.0121f, 0.0125f, 0.0129f,
-0.0133f, 0.0137f, 0.0140f, 0.0144f, 0.0147f, 0.0150f, 0.0153f, 0.0155f,
-0.0158f, 0.0160f, 0.0162f, 0.0163f, 0.0164f, 0.0165f, 0.0166f, 0.0167f,
-0.0167f
-};
-static const float ggauss59[44] = {
-0.0039f, 0.0042f, 0.0044f, 0.0047f, 0.0050f, 0.0053f, 0.0056f, 0.0059f,
-0.0062f, 0.0065f, 0.0068f, 0.0072f, 0.0075f, 0.0079f, 0.0082f, 0.0086f,
-0.0089f, 0.0093f, 0.0096f, 0.0100f, 0.0104f, 0.0107f, 0.0110f, 0.0114f,
-0.0117f, 0.0120f, 0.0124f, 0.0127f, 0.0130f, 0.0132f, 0.0135f, 0.0138f,
-0.0140f, 0.0142f, 0.0144f, 0.0146f, 0.0148f, 0.0149f, 0.0150f, 0.0151f,
-0.0152f, 0.0153f, 0.0153f, 0.0153f
-};
-static const float ggauss60[48] = {
-0.0036f, 0.0038f, 0.0040f, 0.0042f, 0.0044f, 0.0047f, 0.0049f, 0.0052f,
-0.0055f, 0.0057f, 0.0060f, 0.0063f, 0.0066f, 0.0068f, 0.0071f, 0.0074f,
-0.0077f, 0.0080f, 0.0083f, 0.0086f, 0.0089f, 0.0092f, 0.0095f, 0.0098f,
-0.0101f, 0.0104f, 0.0107f, 0.0109f, 0.0112f, 0.0115f, 0.0117f, 0.0120f,
-0.0122f, 0.0124f, 0.0126f, 0.0128f, 0.0130f, 0.0132f, 0.0134f, 0.0135f,
-0.0136f, 0.0137f, 0.0138f, 0.0139f, 0.0140f, 0.0140f, 0.0140f, 0.0140f
-};
-static const float ggauss61[52] = {
-0.0033f, 0.0035f, 0.0037f, 0.0039f, 0.0041f, 0.0043f, 0.0045f, 0.0047f,
-0.0049f, 0.0051f, 0.0053f, 0.0056f, 0.0058f, 0.0060f, 0.0063f, 0.0065f,
-0.0068f, 0.0070f, 0.0073f, 0.0075f, 0.0078f, 0.0080f, 0.0083f, 0.0085f,
-0.0088f, 0.0090f, 0.0093f, 0.0095f, 0.0098f, 0.0100f, 0.0102f, 0.0105f,
-0.0107f, 0.0109f, 0.0111f, 0.0113f, 0.0115f, 0.0116f, 0.0118f, 0.0120f,
-0.0121f, 0.0122f, 0.0124f, 0.0125f, 0.0126f, 0.0126f, 0.0127f, 0.0128f,
-0.0128f, 0.0129f, 0.0129f, 0.0129f
-};
-static const float ggauss62[57] = {
-0.0030f, 0.0031f, 0.0033f, 0.0034f, 0.0036f, 0.0038f, 0.0039f, 0.0041f,
-0.0043f, 0.0045f, 0.0047f, 0.0048f, 0.0050f, 0.0052f, 0.0054f, 0.0056f,
-0.0058f, 0.0060f, 0.0063f, 0.0065f, 0.0067f, 0.0069f, 0.0071f, 0.0073f,
-0.0075f, 0.0077f, 0.0080f, 0.0082f, 0.0084f, 0.0086f, 0.0088f, 0.0090f,
-0.0092f, 0.0094f, 0.0096f, 0.0097f, 0.0099f, 0.0101f, 0.0103f, 0.0104f,
-0.0106f, 0.0107f, 0.0108f, 0.0110f, 0.0111f, 0.0112f, 0.0113f, 0.0114f,
-0.0115f, 0.0116f, 0.0116f, 0.0117f, 0.0117f, 0.0118f, 0.0118f, 0.0118f,
-0.0118f
-};
-static const float ggauss63[62] = {
-0.0027f, 0.0029f, 0.0030f, 0.0031f, 0.0032f, 0.0034f, 0.0035f, 0.0037f,
-0.0038f, 0.0040f, 0.0041f, 0.0043f, 0.0045f, 0.0046f, 0.0048f, 0.0049f,
-0.0051f, 0.0053f, 0.0055f, 0.0056f, 0.0058f, 0.0060f, 0.0062f, 0.0063f,
-0.0065f, 0.0067f, 0.0069f, 0.0071f, 0.0072f, 0.0074f, 0.0076f, 0.0078f,
-0.0079f, 0.0081f, 0.0083f, 0.0084f, 0.0086f, 0.0088f, 0.0089f, 0.0091f,
-0.0092f, 0.0094f, 0.0095f, 0.0096f, 0.0098f, 0.0099f, 0.0100f, 0.0101f,
-0.0102f, 0.0103f, 0.0104f, 0.0105f, 0.0105f, 0.0106f, 0.0107f, 0.0107f,
-0.0108f, 0.0108f, 0.0108f, 0.0108f, 0.0109f, 0.0109f
-};
-static const float ggauss64[65] = {
-0.0028f, 0.0029f, 0.0030f, 0.0031f, 0.0032f, 0.0034f, 0.0035f, 0.0036f,
-0.0037f, 0.0039f, 0.0040f, 0.0041f, 0.0043f, 0.0044f, 0.0046f, 0.0047f,
-0.0048f, 0.0050f, 0.0051f, 0.0053f, 0.0054f, 0.0056f, 0.0057f, 0.0059f,
-0.0060f, 0.0062f, 0.0063f, 0.0065f, 0.0066f, 0.0068f, 0.0069f, 0.0071f,
-0.0072f, 0.0074f, 0.0075f, 0.0077f, 0.0078f, 0.0079f, 0.0081f, 0.0082f,
-0.0083f, 0.0084f, 0.0086f, 0.0087f, 0.0088f, 0.0089f, 0.0090f, 0.0091f,
-0.0092f, 0.0093f, 0.0094f, 0.0094f, 0.0095f, 0.0096f, 0.0097f, 0.0097f,
-0.0098f, 0.0098f, 0.0099f, 0.0099f, 0.0099f, 0.0099f, 0.0100f, 0.0100f,
-0.0100f
-};
-static const float *gptr_tab_gauss[64] = {
-ggauss1, ggauss2, ggauss3, ggauss4,
-ggauss5, ggauss6, ggauss7, ggauss8,
-ggauss9, ggauss10, ggauss11, ggauss12,
-ggauss13, ggauss14, ggauss15, ggauss16,
-ggauss17, ggauss18, ggauss19, ggauss20,
-ggauss21, ggauss22, ggauss23, ggauss24,
-ggauss25, ggauss26, ggauss27, ggauss28,
-ggauss29, ggauss30, ggauss31, ggauss32,
-ggauss33, ggauss34, ggauss35, ggauss36,
-ggauss37, ggauss38, ggauss39, ggauss40,
-ggauss41, ggauss42, ggauss43, ggauss44,
-ggauss45, ggauss46, ggauss47, ggauss48,
-ggauss49, ggauss50, ggauss51, ggauss52,
-ggauss53, ggauss54, ggauss55, ggauss56,
-ggauss57, ggauss58, ggauss59, ggauss60,
-ggauss61, ggauss62, ggauss63, ggauss64
-};
diff --git a/lib/qra/qra64/fadenlorentz.c b/lib/qra/qra64/fadenlorentz.c
deleted file mode 100644
index 673a890..0000000
--- a/lib/qra/qra64/fadenlorentz.c
+++ /dev/null
@@ -1,304 +0,0 @@
-// Lorentz energy fading tables for QRA64
-static const int glen_tab_lorentz[64] = {
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 3, 3,
- 3, 3, 3, 3, 3, 4, 4, 4,
- 4, 4, 5, 5, 5, 5, 6, 6,
- 7, 7, 7, 8, 8, 9, 10, 10,
- 11, 12, 13, 14, 15, 16, 17, 19,
- 20, 22, 23, 25, 27, 30, 32, 35,
- 38, 41, 45, 49, 53, 57, 62, 65
-};
-static const float glorentz1[2] = {
-0.0214f, 0.9107f
-};
-static const float glorentz2[2] = {
-0.0244f, 0.9030f
-};
-static const float glorentz3[2] = {
-0.0280f, 0.8950f
-};
-static const float glorentz4[2] = {
-0.0314f, 0.8865f
-};
-static const float glorentz5[2] = {
-0.0349f, 0.8773f
-};
-static const float glorentz6[2] = {
-0.0388f, 0.8675f
-};
-static const float glorentz7[2] = {
-0.0426f, 0.8571f
-};
-static const float glorentz8[2] = {
-0.0463f, 0.8459f
-};
-static const float glorentz9[2] = {
-0.0500f, 0.8339f
-};
-static const float glorentz10[2] = {
-0.0538f, 0.8210f
-};
-static const float glorentz11[2] = {
-0.0579f, 0.8074f
-};
-static const float glorentz12[2] = {
-0.0622f, 0.7930f
-};
-static const float glorentz13[2] = {
-0.0668f, 0.7777f
-};
-static const float glorentz14[2] = {
-0.0715f, 0.7616f
-};
-static const float glorentz15[3] = {
-0.0196f, 0.0765f, 0.7445f
-};
-static const float glorentz16[3] = {
-0.0210f, 0.0816f, 0.7267f
-};
-static const float glorentz17[3] = {
-0.0226f, 0.0870f, 0.7080f
-};
-static const float glorentz18[3] = {
-0.0242f, 0.0925f, 0.6885f
-};
-static const float glorentz19[3] = {
-0.0259f, 0.0981f, 0.6682f
-};
-static const float glorentz20[3] = {
-0.0277f, 0.1039f, 0.6472f
-};
-static const float glorentz21[3] = {
-0.0296f, 0.1097f, 0.6255f
-};
-static const float glorentz22[4] = {
-0.0143f, 0.0316f, 0.1155f, 0.6031f
-};
-static const float glorentz23[4] = {
-0.0153f, 0.0337f, 0.1213f, 0.5803f
-};
-static const float glorentz24[4] = {
-0.0163f, 0.0358f, 0.1270f, 0.5570f
-};
-static const float glorentz25[4] = {
-0.0174f, 0.0381f, 0.1325f, 0.5333f
-};
-static const float glorentz26[4] = {
-0.0186f, 0.0405f, 0.1378f, 0.5095f
-};
-static const float glorentz27[5] = {
-0.0113f, 0.0198f, 0.0429f, 0.1428f, 0.4855f
-};
-static const float glorentz28[5] = {
-0.0120f, 0.0211f, 0.0455f, 0.1473f, 0.4615f
-};
-static const float glorentz29[5] = {
-0.0129f, 0.0225f, 0.0481f, 0.1514f, 0.4376f
-};
-static const float glorentz30[5] = {
-0.0137f, 0.0239f, 0.0508f, 0.1549f, 0.4140f
-};
-static const float glorentz31[6] = {
-0.0095f, 0.0147f, 0.0254f, 0.0536f, 0.1578f, 0.3907f
-};
-static const float glorentz32[6] = {
-0.0101f, 0.0156f, 0.0270f, 0.0564f, 0.1600f, 0.3680f
-};
-static const float glorentz33[7] = {
-0.0076f, 0.0109f, 0.0167f, 0.0287f, 0.0592f, 0.1614f, 0.3458f
-};
-static const float glorentz34[7] = {
-0.0081f, 0.0116f, 0.0178f, 0.0305f, 0.0621f, 0.1620f, 0.3243f
-};
-static const float glorentz35[7] = {
-0.0087f, 0.0124f, 0.0190f, 0.0324f, 0.0649f, 0.1618f, 0.3035f
-};
-static const float glorentz36[8] = {
-0.0069f, 0.0093f, 0.0133f, 0.0203f, 0.0343f, 0.0676f, 0.1607f, 0.2836f
-};
-static const float glorentz37[8] = {
-0.0074f, 0.0100f, 0.0142f, 0.0216f, 0.0362f, 0.0702f, 0.1588f, 0.2645f
-};
-static const float glorentz38[9] = {
-0.0061f, 0.0080f, 0.0107f, 0.0152f, 0.0230f, 0.0382f, 0.0726f, 0.1561f,
-0.2464f
-};
-static const float glorentz39[10] = {
-0.0052f, 0.0066f, 0.0086f, 0.0115f, 0.0162f, 0.0244f, 0.0402f, 0.0747f,
-0.1526f, 0.2291f
-};
-static const float glorentz40[10] = {
-0.0056f, 0.0071f, 0.0092f, 0.0123f, 0.0173f, 0.0259f, 0.0422f, 0.0766f,
-0.1484f, 0.2128f
-};
-static const float glorentz41[11] = {
-0.0049f, 0.0061f, 0.0076f, 0.0098f, 0.0132f, 0.0184f, 0.0274f, 0.0441f,
-0.0780f, 0.1437f, 0.1975f
-};
-static const float glorentz42[12] = {
-0.0044f, 0.0053f, 0.0065f, 0.0082f, 0.0106f, 0.0141f, 0.0196f, 0.0290f,
-0.0460f, 0.0791f, 0.1384f, 0.1831f
-};
-static const float glorentz43[13] = {
-0.0040f, 0.0048f, 0.0057f, 0.0070f, 0.0088f, 0.0113f, 0.0150f, 0.0209f,
-0.0305f, 0.0477f, 0.0797f, 0.1327f, 0.1695f
-};
-static const float glorentz44[14] = {
-0.0037f, 0.0043f, 0.0051f, 0.0062f, 0.0075f, 0.0094f, 0.0121f, 0.0160f,
-0.0221f, 0.0321f, 0.0493f, 0.0799f, 0.1267f, 0.1568f
-};
-static const float glorentz45[15] = {
-0.0035f, 0.0040f, 0.0047f, 0.0055f, 0.0066f, 0.0081f, 0.0101f, 0.0129f,
-0.0171f, 0.0234f, 0.0335f, 0.0506f, 0.0795f, 0.1204f, 0.1450f
-};
-static const float glorentz46[16] = {
-0.0033f, 0.0037f, 0.0043f, 0.0050f, 0.0059f, 0.0071f, 0.0087f, 0.0108f,
-0.0138f, 0.0181f, 0.0246f, 0.0349f, 0.0517f, 0.0786f, 0.1141f, 0.1340f
-};
-static const float glorentz47[17] = {
-0.0031f, 0.0035f, 0.0040f, 0.0046f, 0.0054f, 0.0064f, 0.0077f, 0.0093f,
-0.0116f, 0.0147f, 0.0192f, 0.0259f, 0.0362f, 0.0525f, 0.0773f, 0.1076f,
-0.1237f
-};
-static const float glorentz48[19] = {
-0.0027f, 0.0030f, 0.0034f, 0.0038f, 0.0043f, 0.0050f, 0.0058f, 0.0069f,
-0.0082f, 0.0100f, 0.0123f, 0.0156f, 0.0203f, 0.0271f, 0.0374f, 0.0530f,
-0.0755f, 0.1013f, 0.1141f
-};
-static const float glorentz49[20] = {
-0.0026f, 0.0029f, 0.0032f, 0.0036f, 0.0041f, 0.0047f, 0.0054f, 0.0063f,
-0.0074f, 0.0088f, 0.0107f, 0.0131f, 0.0165f, 0.0213f, 0.0282f, 0.0383f,
-0.0531f, 0.0734f, 0.0950f, 0.1053f
-};
-static const float glorentz50[22] = {
-0.0023f, 0.0025f, 0.0028f, 0.0031f, 0.0035f, 0.0039f, 0.0044f, 0.0050f,
-0.0058f, 0.0067f, 0.0079f, 0.0094f, 0.0114f, 0.0139f, 0.0175f, 0.0223f,
-0.0292f, 0.0391f, 0.0529f, 0.0709f, 0.0889f, 0.0971f
-};
-static const float glorentz51[23] = {
-0.0023f, 0.0025f, 0.0027f, 0.0030f, 0.0034f, 0.0037f, 0.0042f, 0.0048f,
-0.0054f, 0.0062f, 0.0072f, 0.0085f, 0.0100f, 0.0121f, 0.0148f, 0.0184f,
-0.0233f, 0.0301f, 0.0396f, 0.0524f, 0.0681f, 0.0829f, 0.0894f
-};
-static const float glorentz52[25] = {
-0.0021f, 0.0023f, 0.0025f, 0.0027f, 0.0030f, 0.0033f, 0.0036f, 0.0040f,
-0.0045f, 0.0051f, 0.0058f, 0.0067f, 0.0077f, 0.0090f, 0.0107f, 0.0128f,
-0.0156f, 0.0192f, 0.0242f, 0.0308f, 0.0398f, 0.0515f, 0.0650f, 0.0772f,
-0.0824f
-};
-static const float glorentz53[27] = {
-0.0019f, 0.0021f, 0.0022f, 0.0024f, 0.0027f, 0.0029f, 0.0032f, 0.0035f,
-0.0039f, 0.0044f, 0.0049f, 0.0055f, 0.0062f, 0.0072f, 0.0083f, 0.0096f,
-0.0113f, 0.0135f, 0.0164f, 0.0201f, 0.0249f, 0.0314f, 0.0398f, 0.0502f,
-0.0619f, 0.0718f, 0.0759f
-};
-static const float glorentz54[30] = {
-0.0017f, 0.0018f, 0.0019f, 0.0021f, 0.0022f, 0.0024f, 0.0026f, 0.0029f,
-0.0031f, 0.0034f, 0.0038f, 0.0042f, 0.0047f, 0.0052f, 0.0059f, 0.0067f,
-0.0076f, 0.0088f, 0.0102f, 0.0120f, 0.0143f, 0.0171f, 0.0208f, 0.0256f,
-0.0317f, 0.0395f, 0.0488f, 0.0586f, 0.0666f, 0.0698f
-};
-static const float glorentz55[32] = {
-0.0016f, 0.0017f, 0.0018f, 0.0019f, 0.0021f, 0.0022f, 0.0024f, 0.0026f,
-0.0028f, 0.0031f, 0.0034f, 0.0037f, 0.0041f, 0.0045f, 0.0050f, 0.0056f,
-0.0063f, 0.0071f, 0.0081f, 0.0094f, 0.0108f, 0.0127f, 0.0149f, 0.0178f,
-0.0214f, 0.0261f, 0.0318f, 0.0389f, 0.0470f, 0.0553f, 0.0618f, 0.0643f
-};
-static const float glorentz56[35] = {
-0.0014f, 0.0015f, 0.0016f, 0.0017f, 0.0018f, 0.0020f, 0.0021f, 0.0023f,
-0.0024f, 0.0026f, 0.0028f, 0.0031f, 0.0033f, 0.0036f, 0.0040f, 0.0044f,
-0.0049f, 0.0054f, 0.0060f, 0.0067f, 0.0076f, 0.0087f, 0.0099f, 0.0114f,
-0.0133f, 0.0156f, 0.0184f, 0.0220f, 0.0264f, 0.0318f, 0.0381f, 0.0451f,
-0.0520f, 0.0572f, 0.0591f
-};
-static const float glorentz57[38] = {
-0.0013f, 0.0014f, 0.0015f, 0.0016f, 0.0017f, 0.0018f, 0.0019f, 0.0020f,
-0.0021f, 0.0023f, 0.0024f, 0.0026f, 0.0028f, 0.0031f, 0.0033f, 0.0036f,
-0.0039f, 0.0043f, 0.0047f, 0.0052f, 0.0058f, 0.0064f, 0.0072f, 0.0081f,
-0.0092f, 0.0104f, 0.0120f, 0.0139f, 0.0162f, 0.0190f, 0.0224f, 0.0265f,
-0.0315f, 0.0371f, 0.0431f, 0.0487f, 0.0529f, 0.0544f
-};
-static const float glorentz58[41] = {
-0.0012f, 0.0013f, 0.0014f, 0.0014f, 0.0015f, 0.0016f, 0.0017f, 0.0018f,
-0.0019f, 0.0020f, 0.0022f, 0.0023f, 0.0025f, 0.0026f, 0.0028f, 0.0030f,
-0.0033f, 0.0036f, 0.0039f, 0.0042f, 0.0046f, 0.0050f, 0.0056f, 0.0061f,
-0.0068f, 0.0076f, 0.0086f, 0.0097f, 0.0110f, 0.0125f, 0.0144f, 0.0167f,
-0.0194f, 0.0226f, 0.0265f, 0.0309f, 0.0359f, 0.0409f, 0.0455f, 0.0488f,
-0.0500f
-};
-static const float glorentz59[45] = {
-0.0011f, 0.0012f, 0.0012f, 0.0013f, 0.0013f, 0.0014f, 0.0015f, 0.0016f,
-0.0016f, 0.0017f, 0.0018f, 0.0019f, 0.0021f, 0.0022f, 0.0023f, 0.0025f,
-0.0026f, 0.0028f, 0.0030f, 0.0033f, 0.0035f, 0.0038f, 0.0041f, 0.0045f,
-0.0049f, 0.0054f, 0.0059f, 0.0065f, 0.0072f, 0.0081f, 0.0090f, 0.0102f,
-0.0115f, 0.0130f, 0.0149f, 0.0171f, 0.0197f, 0.0227f, 0.0263f, 0.0302f,
-0.0345f, 0.0387f, 0.0425f, 0.0451f, 0.0460f
-};
-static const float glorentz60[49] = {
-0.0010f, 0.0011f, 0.0011f, 0.0012f, 0.0012f, 0.0013f, 0.0013f, 0.0014f,
-0.0014f, 0.0015f, 0.0016f, 0.0017f, 0.0018f, 0.0019f, 0.0020f, 0.0021f,
-0.0022f, 0.0024f, 0.0025f, 0.0027f, 0.0028f, 0.0030f, 0.0033f, 0.0035f,
-0.0038f, 0.0041f, 0.0044f, 0.0048f, 0.0052f, 0.0057f, 0.0063f, 0.0069f,
-0.0077f, 0.0085f, 0.0095f, 0.0106f, 0.0119f, 0.0135f, 0.0153f, 0.0174f,
-0.0199f, 0.0227f, 0.0259f, 0.0293f, 0.0330f, 0.0365f, 0.0395f, 0.0415f,
-0.0423f
-};
-static const float glorentz61[53] = {
-0.0009f, 0.0010f, 0.0010f, 0.0011f, 0.0011f, 0.0011f, 0.0012f, 0.0012f,
-0.0013f, 0.0014f, 0.0014f, 0.0015f, 0.0016f, 0.0016f, 0.0017f, 0.0018f,
-0.0019f, 0.0020f, 0.0021f, 0.0023f, 0.0024f, 0.0025f, 0.0027f, 0.0029f,
-0.0031f, 0.0033f, 0.0035f, 0.0038f, 0.0041f, 0.0044f, 0.0047f, 0.0051f,
-0.0056f, 0.0061f, 0.0067f, 0.0073f, 0.0081f, 0.0089f, 0.0099f, 0.0110f,
-0.0124f, 0.0139f, 0.0156f, 0.0176f, 0.0199f, 0.0225f, 0.0253f, 0.0283f,
-0.0314f, 0.0343f, 0.0367f, 0.0383f, 0.0389f
-};
-static const float glorentz62[57] = {
-0.0009f, 0.0009f, 0.0009f, 0.0010f, 0.0010f, 0.0011f, 0.0011f, 0.0011f,
-0.0012f, 0.0012f, 0.0013f, 0.0013f, 0.0014f, 0.0015f, 0.0015f, 0.0016f,
-0.0017f, 0.0018f, 0.0019f, 0.0020f, 0.0021f, 0.0022f, 0.0023f, 0.0024f,
-0.0026f, 0.0027f, 0.0029f, 0.0031f, 0.0033f, 0.0035f, 0.0038f, 0.0040f,
-0.0043f, 0.0047f, 0.0050f, 0.0055f, 0.0059f, 0.0064f, 0.0070f, 0.0077f,
-0.0085f, 0.0093f, 0.0103f, 0.0114f, 0.0127f, 0.0142f, 0.0158f, 0.0177f,
-0.0198f, 0.0221f, 0.0246f, 0.0272f, 0.0297f, 0.0321f, 0.0340f, 0.0353f,
-0.0357f
-};
-static const float glorentz63[62] = {
-0.0008f, 0.0008f, 0.0009f, 0.0009f, 0.0009f, 0.0010f, 0.0010f, 0.0010f,
-0.0011f, 0.0011f, 0.0011f, 0.0012f, 0.0012f, 0.0013f, 0.0013f, 0.0014f,
-0.0015f, 0.0015f, 0.0016f, 0.0017f, 0.0017f, 0.0018f, 0.0019f, 0.0020f,
-0.0021f, 0.0022f, 0.0023f, 0.0025f, 0.0026f, 0.0028f, 0.0029f, 0.0031f,
-0.0033f, 0.0035f, 0.0038f, 0.0040f, 0.0043f, 0.0046f, 0.0050f, 0.0053f,
-0.0058f, 0.0062f, 0.0068f, 0.0074f, 0.0081f, 0.0088f, 0.0097f, 0.0106f,
-0.0117f, 0.0130f, 0.0144f, 0.0159f, 0.0176f, 0.0195f, 0.0216f, 0.0237f,
-0.0259f, 0.0280f, 0.0299f, 0.0315f, 0.0325f, 0.0328f
-};
-static const float glorentz64[65] = {
-0.0008f, 0.0008f, 0.0008f, 0.0009f, 0.0009f, 0.0009f, 0.0010f, 0.0010f,
-0.0010f, 0.0011f, 0.0011f, 0.0012f, 0.0012f, 0.0012f, 0.0013f, 0.0013f,
-0.0014f, 0.0014f, 0.0015f, 0.0016f, 0.0016f, 0.0017f, 0.0018f, 0.0019f,
-0.0020f, 0.0021f, 0.0022f, 0.0023f, 0.0024f, 0.0025f, 0.0027f, 0.0028f,
-0.0030f, 0.0031f, 0.0033f, 0.0035f, 0.0038f, 0.0040f, 0.0043f, 0.0046f,
-0.0049f, 0.0052f, 0.0056f, 0.0061f, 0.0066f, 0.0071f, 0.0077f, 0.0084f,
-0.0091f, 0.0100f, 0.0109f, 0.0120f, 0.0132f, 0.0145f, 0.0159f, 0.0175f,
-0.0192f, 0.0209f, 0.0228f, 0.0246f, 0.0264f, 0.0279f, 0.0291f, 0.0299f,
-0.0301f
-};
-static const float *gptr_tab_lorentz[64] = {
-glorentz1, glorentz2, glorentz3, glorentz4,
-glorentz5, glorentz6, glorentz7, glorentz8,
-glorentz9, glorentz10, glorentz11, glorentz12,
-glorentz13, glorentz14, glorentz15, glorentz16,
-glorentz17, glorentz18, glorentz19, glorentz20,
-glorentz21, glorentz22, glorentz23, glorentz24,
-glorentz25, glorentz26, glorentz27, glorentz28,
-glorentz29, glorentz30, glorentz31, glorentz32,
-glorentz33, glorentz34, glorentz35, glorentz36,
-glorentz37, glorentz38, glorentz39, glorentz40,
-glorentz41, glorentz42, glorentz43, glorentz44,
-glorentz45, glorentz46, glorentz47, glorentz48,
-glorentz49, glorentz50, glorentz51, glorentz52,
-glorentz53, glorentz54, glorentz55, glorentz56,
-glorentz57, glorentz58, glorentz59, glorentz60,
-glorentz61, glorentz62, glorentz63, glorentz64
-};
diff --git a/lib/qra/qra64/main.c b/lib/qra/qra64/main.c
deleted file mode 100644
index b685fd3..0000000
--- a/lib/qra/qra64/main.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
-main.c
-QRA64 mode encode/decode tests
-
-(c) 2016 - Nico Palermo, IV3NWV
-
-Thanks to Andrea Montefusco IW0HDV for his help on adapting the sources
-to OSs other than MS Windows
-
-------------------------------------------------------------------------------
-This file is part of the qracodes project, a Forward Error Control
-encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-
-Files in this package:
- main.c - this file
- qra64.c/.h - qra64 mode encode/decoding functions
-
- ../qracodes/normrnd.{c,h} - random gaussian number generator
- ../qracodes/npfwht.{c,h} - Fast Walsh-Hadamard Transforms
- ../qracodes/pdmath.{c,h} - Elementary math on probability distributions
- ../qracodes/qra12_63_64_irr_b.{c,h} - Tables for a QRA(12,63) irregular RA
- code over GF(64)
- ../qracodes/qra13_64_64_irr_e.{c,h} - Tables for a QRA(13,64) irregular RA
- code over GF(64)
- ../qracodes/qracodes.{c,h} - QRA codes encoding/decoding functions
-
--------------------------------------------------------------------------------
-
- qracodes 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.
- qracodes 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 qracodes source distribution.
- If not, see .
-
------------------------------------------------------------------------------
-
-The code used by the QRA64 mode is the code: QRA13_64_64_IRR_E: K=13
-N=64 Q=64 irregular QRA code (defined in qra13_64_64_irr_e.{h,c}).
-
-This code has been designed to include a CRC as the 13th information
-symbol and improve the code UER (Undetected Error Rate). The CRC
-symbol is not sent along the channel (the codes are punctured) and the
-resulting code is still a (12,63) code with an effective code rate of
-R = 12/63.
-*/
-
-// OS dependent defines and includes ------------------------------------------
-
-#if _WIN32 // note the underscore: without it, it's not msdn official!
-// Windows (x64 and x86)
-#include // required only for GetTickCount(...)
-#include // _beginthread
-#endif
-
-#if __linux__
-#include
-#include
-
-unsigned GetTickCount(void) {
- struct timespec ts;
- unsigned theTick = 0U;
- clock_gettime( CLOCK_REALTIME, &ts );
- theTick = ts.tv_nsec / 1000000;
- theTick += ts.tv_sec * 1000;
- return theTick;
-}
-#endif
-
-#if __APPLE__
-#endif
-
-#include
-#include
-#include
-
-#include "qra64.h"
-#include "../qracodes/normrnd.h" // gaussian numbers generator
-
-// ----------------------------------------------------------------------------
-
-// channel types
-#define CHANNEL_AWGN 0
-#define CHANNEL_RAYLEIGH 1
-#define CHANNEL_FASTFADE 2
-
-#define JT65_SNR_EBNO_OFFSET 29.1f // with the synch used in JT65
-#define QRA64_SNR_EBNO_OFFSET 31.0f // with the costas array synch
-
-void printwordd(char *msg, int *x, int size)
-{
- int k;
- printf("\n%s ",msg);
- for (k=0;k-15)
- if (channel_type == CHANNEL_AWGN)
- for (k=0;k=0) { // decoded
- printf("K1JT rx: received with apcode=%d %s\n",rc, decode_type[rc]);
-
-// Step 2a: K1JT replies to IV3NWV (with no grid)
- printf("K1JT tx: IV3NWV K1JT\n");
- encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT, GRID_BLANK);
- qra64_encode(codec_k1jt, y, x);
- rx = mfskchannel(y,channel_type,EbNodB);
-
-// Step 2b: IV3NWV attempts to decode [? ? ?], [IV3NWV ? ?] or [IV3NWV ?]
- rc = qra64_decode(codec_iv3nwv, 0, xdec,rx);
- if (rc>=0) { // decoded
- printf("IV3NWV rx: received with apcode=%d %s\n",rc, decode_type[rc]);
-
-// Step 3a: IV3NWV replies to K1JT with a 73
- printf("IV3NWV tx: K1JT IV3NWV 73\n");
- encodemsg_jt65(x,CALL_K1JT,CALL_IV3NWV, GRID_73);
- qra64_encode(codec_iv3nwv, y, x);
- rx = mfskchannel(y,channel_type,EbNodB);
-
-// Step 3b: K1JT attempts to decode [? ? ?] or [K1JT IV3NWV ?]
- rc = qra64_decode(codec_k1jt, 0, xdec,rx);
- if (rc>=0) { // decoded
- printf("K1JT rx: received with apcode=%d %s\n",rc, decode_type[rc]);
-
-// Step 4a: K1JT replies to IV3NWV with a 73
- printf("K1JT tx: IV3NWV K1JT 73\n");
- encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT, GRID_73);
- qra64_encode(codec_k1jt, y, x);
- rx = mfskchannel(y,channel_type,EbNodB);
-
-// Step 4b: IV3NWV attempts to decode [? ? ?], [IV3NWV ? ?], or [IV3NWV ?]
- rc = qra64_decode(codec_iv3nwv, 0, xdec,rx);
- if (rc>=0) { // decoded
- printf("IV3NWV rx: received with apcode=%d %s\n",rc, decode_type[rc]);
- return 0;
- }
- }
- }
- }
- printf("no decode\n");
- return -1;
-}
-
-int test_proc_2(int channel_type, float EbNodB, int mode)
-{
-/*
-Here we simulate the decoder of K1JT after K1JT has sent a msg [IV3NWV K1JT]
-and IV3NWV sends him the msg [K1JT IV3NWV JN66].
-
-If mode=QRA_NOAP, K1JT decoder attempts to decode only msgs of type [? ? ?].
-
-If mode=QRA_AUTOP, K1JT decoder will attempt to decode also the msgs
-[K1JT IV3NWV] and [K1JT IV3NWV ?].
-
-In the case a decode is successful the return code of the qra64_decode function
-indicates the amount of a-priori information required to decode the received
-message according to this table:
-
- rc=0 [? ? ?] AP0
- rc=1 [CQ ? ?] AP27
- rc=2 [CQ ? ] AP42
- rc=3 [CALL ? ?] AP29
- rc=4 [CALL ? ] AP44
- rc=5 [CALL CALL ?] AP57
- rc=6 [? CALL ?] AP29
- rc=7 [? CALL ] AP44
- rc=8 [CALL CALL GRID] AP72
- rc=9 [CQ CALL ?] AP55
- rc=10 [CQ CALL ] AP70
- rc=11 [CQ CALL GRID] AP70
-
-The return code is <0 when decoding is unsuccessful
-
-This test simulates the situation ntx times and reports how many times
-a particular type decode among the above 6 cases succeded.
-*/
-
- int x[QRA64_K], xdec[QRA64_K];
- int y[QRA64_N];
- float *rx;
- float ebnodbest, ebnodbavg=0;
- int rc,k;
-
- int ndecok[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int nundet = 0;
- int ntx = 200,ndec=0;
-
- qra64codec *codec_iv3nwv = qra64_init(mode); // codec for IV3NWV
- qra64codec *codec_k1jt = qra64_init(mode); // codec for K1JT
-
- printf("\nQRA64 Test #2 - Decoding with AP knowledge (SNR-Eb/No offset = %.1f dB)\n\n",
- QRA64_SNR_EBNO_OFFSET);
-
-// This will enable K1JT's decoder to look for calls directed to him [K1JT ? ?/b]
-// printf("K1JT decoder enabled for [K1JT ? ?/blank]\n");
-// qra64_apset(codec_k1jt, CALL_K1JT,0,0,APTYPE_MYCALL);
-
-// This will enable K1JT's decoder to look for IV3NWV calls directed to him [K1JT IV3NWV ?/b]
-// printf("K1JT decoder enabled for [K1JT IV3NWV ?]\n");
-// qra64_apset(codec_k1jt, CALL_CQ,CALL_IV3NWV,0,APTYPE_BOTHCALLS);
-
-// This will enable K1JT's decoder to look for msges sent by IV3NWV [? IV3NWV ?]
-// printf("K1JT decoder enabled for [? IV3NWV ?/blank]\n");
-// qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_BLANK,APTYPE_HISCALL);
-
-// This will enable K1JT's decoder to look for full-knowledge [K1JT IV3NWV JN66] msgs
- printf("K1JT decoder enabled for [K1JT IV3NWV JN66]\n");
- qra64_apset(codec_k1jt, CALL_K1JT,CALL_IV3NWV,GRID_JN66,APTYPE_FULL);
-
-// This will enable K1JT's decoder to look for calls from IV3NWV [CQ IV3NWV ?/b] msgs
- printf("K1JT decoder enabled for [CQ IV3NWV ?/b/JN66]\n");
- qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_JN66,APTYPE_CQHISCALL);
-
-
- // Dx station IV3NWV calls
- printf("\nIV3NWV encoder sends msg: [K1JT IV3NWV JN66]\n\n");
- encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_JN66);
-
-// printf("\nIV3NWV encoder sends msg: [CQ IV3NWV JN66]\n\n");
-// encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_JN66);
-
-// printf("\nIV3NWV encoder sends msg: [CQ IV3NWV]\n\n");
-// encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_BLANK);
- qra64_encode(codec_iv3nwv, y, x);
-
- printf("Simulating K1JT decoder up to AP72\n");
-
- for (k=0;k=0) {
- ebnodbavg +=ebnodbest;
- if (memcmp(xdec,x,12*sizeof(int))==0)
- ndecok[rc]++;
- else
- nundet++;
- }
- }
- printf("\n\n");
-
-
- printf("Transimtted msgs:%d\nDecoded msgs:\n\n",ntx);
- for (k=0;k<12;k++) {
- printf("%3d with %s\n",ndecok[k],decode_type[k]);
- ndec += ndecok[k];
- }
- printf("\nTotal: %d/%d (%d undetected errors)\n\n",ndec,ntx,nundet);
- printf("");
-
- ebnodbavg/=(ndec+nundet);
- printf("Estimated SNR (average in dB) = %.2f dB\n\n",ebnodbavg-QRA64_SNR_EBNO_OFFSET);
-
- return 0;
-}
-
-int test_fastfading(float EbNodB, float B90, int fadingModel, int submode, int apmode, int olddec, int channel_type, int ntx)
-{
- int x[QRA64_K], xdec[QRA64_K];
- int y[QRA64_N];
- float *rx;
- float ebnodbest, ebnodbavg=0;
- int rc,k;
- float rxolddec[QRA64_N*QRA64_M]; // holds the energies at nominal tone freqs
-
- int ndecok[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int nundet = 0;
- int ndec=0;
-
- qra64codec *codec_iv3nwv;
- qra64codec *codec_k1jt;
-
- codec_iv3nwv=qra64_init(QRA_NOAP);
- codec_k1jt =qra64_init(apmode);
-
- if (channel_type==2) { // fast-fading case
- printf("Simulating the fast-fading channel\n");
- printf("B90=%.2f Hz - Fading Model=%s - Submode=QRA64%c\n",B90,fadingModel?"Lorentz":"Gauss",submode+'A');
- printf("Decoder metric = %s\n",olddec?"AWGN":"Matched to fast-fading signal");
- }
- else {
- printf("Simulating the %s channel\n",channel_type?"Rayleigh block fading":"AWGN");
- printf("Decoder metric = AWGN\n");
- }
-
-
- printf("\nEncoding msg [K1JT IV3NWV JN66]\n");
- encodemsg_jt65(x,CALL_K1JT,CALL_IV3NWV,GRID_JN66);
-// printf("[");
-// for (k=0;k<11;k++) printf("%02hX ",x[k]); printf("%02hX]\n",x[11]);
-
- qra64_encode(codec_iv3nwv, y, x);
- printf("%d transmissions will be simulated\n\n",ntx);
-
- if (apmode==QRA_USERAP) {
- // This will enable K1JT's decoder to look for cq/qrz calls [CQ/QRZ ? ?/b]
- printf("K1JT decoder enabled for [CQ ? ?/blank]\n");
- qra64_apset(codec_k1jt, CALL_K1JT,0,0,APTYPE_CQQRZ);
-
- // This will enable K1JT's decoder to look for calls directed to him [K1JT ? ?/b]
- printf("K1JT decoder enabled for [K1JT ? ?/blank]\n");
- qra64_apset(codec_k1jt, CALL_K1JT,0,0,APTYPE_MYCALL);
-
- // This will enable K1JT's decoder to look for msges sent by IV3NWV [? IV3NWV ?]
- printf("K1JT decoder enabled for [? IV3NWV ?/blank]\n");
- qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_BLANK,APTYPE_HISCALL);
-
- // This will enable K1JT's decoder to look for IV3NWV calls directed to him [K1JT IV3NWV ?/b]
- printf("K1JT decoder enabled for [K1JT IV3NWV ?]\n");
- qra64_apset(codec_k1jt, CALL_K1JT,CALL_IV3NWV,0,APTYPE_BOTHCALLS);
-
- // This will enable K1JT's decoder to look for full-knowledge [K1JT IV3NWV JN66] msgs
- printf("K1JT decoder enabled for [K1JT IV3NWV JN66]\n");
- qra64_apset(codec_k1jt, CALL_K1JT,CALL_IV3NWV,GRID_JN66,APTYPE_FULL);
-
- // This will enable K1JT's decoder to look for calls from IV3NWV [CQ IV3NWV ?/b] msgs
- printf("K1JT decoder enabled for [CQ IV3NWV ?/b/JN66]\n");
- qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_JN66,APTYPE_CQHISCALL);
-
- }
-
- printf("\nNow decoding with K1JT's decoder...\n");
-/*
- if (channel_type==2) // simulate a fast-faded signal
- printf("Simulating a fast-fading channel with given B90 and spread type\n");
- else
- printf("Simulating a %s channel\n",channel_type?"Rayleigh block fading":"AWGN");
-*/
- for (k=0;k=0) {
- ebnodbavg +=ebnodbest;
- if (memcmp(xdec,x,12*sizeof(int))==0)
- ndecok[rc]++;
- else {
- fprintf(stderr,"\nUndetected error with rc=%d\n",rc);
- nundet++;
- }
- }
-
- }
- printf(" %5.1f %%\r",100.0*k/ntx);
-
- printf("\n\n");
-
- printf("Msgs transmitted:%d\nMsg decoded:\n\n",ntx);
- for (k=0;k<12;k++) {
- printf("rc=%2d %3d with %s\n",k,ndecok[k],decode_type[k]);
- ndec += ndecok[k];
- }
- printf("\nTotal: %d/%d (%d undetected errors)\n\n",ndec,ntx,nundet);
- printf("");
-
- if (ndec>0) {
- ebnodbavg/=(ndec+nundet);
- printf("Estimated SNR (average in dB) = %.2f dB\n\n",ebnodbavg-QRA64_SNR_EBNO_OFFSET);
- }
-
- return 0;
-}
-
-
-
-void syntax(void)
-{
-
- printf("\nQRA64 Mode Tests\n");
- printf("2016, Nico Palermo - IV3NWV\n\n");
- printf("---------------------------\n\n");
- printf("Syntax: qra64 [-s] [-c] [-a] [-t] [-h]\n");
- printf("Options: \n");
- printf(" -s : set simulation SNR in 2500 Hz BW (default:-27.5 dB)\n");
- printf(" -c : set channel type 0=AWGN (default) 1=Rayleigh 2=Fast-fading\n");
- printf(" -a : set decode type 0=NOAP 1=AUTOAP (default) 2=USERAP\n");
- printf(" -t: 0=simulate seq of msgs between IV3NWV and K1JT (default)\n");
- printf(" 1=simulate K1JT receiving K1JT IV3NWV JN66\n");
- printf(" 2=simulate fast-fading/awgn/rayliegh decoders performance\n");
- printf(" -n : simulate the transmission of ntx codewords (default=100)\n");
-
- printf("Options used only for fast-fading simulations (-c2):\n");
- printf(" -b : 90%% fading bandwidth in Hz [1..230 Hz] (default = 2.5 Hz)\n");
- printf(" -m : fading model. 0=Gauss, 1=Lorentz (default = Lorentz)\n");
- printf(" -q : qra64 submode. 0=QRA64A,... 4=QRA64E (default = QRA64A)\n");
- printf(" -d : use the old awgn decoder\n");
- printf(" -h: this help\n");
- printf("Example:\n");
- printf(" qra64 -t2 -c2 -a2 -b50 -m1 -q2 -n10000 -s-26\n");
- printf(" runs the error performance test (-t2)\n");
- printf(" with USER_AP (-a2)\n");
- printf(" simulating a fast fading channel (-c2)\n");
- printf(" with B90 = 50 Hz (-b50), Lorentz Doppler (-m1), mode QRA64C (-q2)\n");
- printf(" ntx = 10000 codewords (-n10000) and SNR = -26 dB (-s-26)\n");
-
-}
-
-int main(int argc, char* argv[])
-{
- int k, rc, nok=0;
- float SNRdB = -27.5f;
- unsigned int channel = CHANNEL_AWGN;
- unsigned int mode = QRA_AUTOAP;
- unsigned int testtype=0;
- int nqso = 100;
- float EbNodB;
- float B90 = 2.5;
- int fadingModel = 1;
- int submode = 0;
- int olddec = 0;
- int ntx = 100;
-
-// Parse the command line
- while(--argc) {
- argv++;
-
- if (strncmp(*argv,"-h",2)==0) {
- syntax();
- return 0;
- }
- else
- if (strncmp(*argv,"-n",2)==0) {
- ntx = ( int)atoi((*argv)+2);
- if (ntx<100 || ntx>1000000) {
- printf("Invalid -n option. ntx must be in the range [100..1000000]\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-a",2)==0) {
- mode = ( int)atoi((*argv)+2);
- if (mode>2) {
- printf("Invalid decoding mode\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-s",2)==0) {
- SNRdB = (float)atof((*argv)+2);
- if (SNRdB>20 || SNRdB<-50) {
- printf("SNR should be in the range [-50..20]\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-t",2)==0) {
- testtype = ( int)atoi((*argv)+2);
- if (testtype>2) {
- printf("Invalid test type\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-c",2)==0) {
- channel = ( int)atoi((*argv)+2);
- if (channel>CHANNEL_FASTFADE) {
- printf("Invalid channel type\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-b",2)==0) {
- B90 = (float)atof((*argv)+2);
- if (B90<1 || B90>230) {
- printf("Invalid B90\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-m",2)==0) {
- fadingModel = (int)atoi((*argv)+2);
- if (fadingModel<0 || fadingModel>1) {
- printf("Invalid fading model\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-q",2)==0) {
- submode = (int)atoi((*argv)+2);
- if (submode<0 || submode>4) {
- printf("Invalid submode\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-d",2)==0) {
- olddec = 1;
- }
- else {
- printf("Invalid option\n");
- syntax();
- return -1;
- }
- }
-
- if (testtype<2) // old tests
- if (channel==CHANNEL_FASTFADE) {
- printf("Invalid Option. Test type 0 and 1 supports only AWGN or Rayleigh Channel model\n");
- return -1;
- }
-
- EbNodB = SNRdB+QRA64_SNR_EBNO_OFFSET;
-
-#if defined(__linux__) || defined(__unix__)
- srand48(GetTickCount());
-#endif
-
- if (testtype==0) {
- for (k=0;k.
-
------------------------------------------------------------------------------
-
-QRA code used in this sowftware release:
-
-QRA13_64_64_IRR_E: K=13 N=64 Q=64 irregular QRA code (defined in
-qra13_64_64_irr_e.h /.c)
-
-Codes with K=13 are designed to include a CRC as the 13th information symbol
-and improve the code UER (Undetected Error Rate).
-The CRC symbol is not sent along the channel (the codes are punctured) and the
-resulting code is a (12,63) code
-*/
-//----------------------------------------------------------------------------
-
-#include
-#include
-
-#include "qra64.h"
-#include "../qracodes/qracodes.h"
-#include "../qracodes/qra13_64_64_irr_e.h"
-#include "../qracodes/pdmath.h"
-#include "../qracodes/normrnd.h"
-
-// Code parameters of the QRA64 mode
-#define QRA64_CODE qra_13_64_64_irr_e
-#define QRA64_NMSG 218 // Must much value indicated in QRA64_CODE.NMSG
-
-#define QRA64_KC (QRA64_K+1) // Information symbols (crc included)
-#define QRA64_NC (QRA64_N+1) // Codeword length (as defined in the code)
-#define QRA64_NITER 100 // max number of iterations per decode
-
-// static functions declarations ----------------------------------------------
-static int calc_crc6(const int *x, int sz);
-static void ix_mask(float *dst, const float *src, const int *mask,
- const int *x);
-static int qra64_decode_attempts(qra64codec *pcodec, int *xdec, const float *ix);
-static int qra64_do_decode(int *x, const float *pix, const int *ap_mask,
- const int *ap_x);
-static float qra64_fastfading_estim_noise_std(
- const float *rxen,
- const float esnometric,
- const int submode);
-
-static void qra64_fastfading_intrinsics(
- float *pix,
- const float *rxen,
- const float *hptr,
- const int hlen,
- const float sigma,
- const float EsNoMetric,
- const int submode);
-
-static float qra64_fastfading_msg_esno(
- const int *ydec,
- const float *rxen,
- const float sigma,
- const float EsNoMetric,
- const int hlen,
- const int submode);
-
-
-// a-priori information masks for fields in JT65-like msgs --------------------
-
-// when defined limits the AP masks to reduce the false decode rate
-#define LIMIT_AP_MASKS
-
-#ifdef LIMIT_AP_MASKS
-#define MASK_CQQRZ 0xFFFFFFC
-#define MASK_CALL1 0xFFFFFFC
-#define MASK_CALL2 0xFFFFFFC
-#define MASK_GRIDFULL 0x3FFC
-#define MASK_GRIDFULL12 0x3FFC
-#define MASK_GRIDBIT 0x8000
-#else
-#define MASK_CQQRZ 0xFFFFFFC
-#define MASK_CALL1 0xFFFFFFF
-#define MASK_CALL2 0xFFFFFFF
-#define MASK_GRIDFULL 0xFFFF
-#define MASK_GRIDFULL12 0x3FFC
-#define MASK_GRIDBIT 0x8000 // b[15] is 1 for free text, 0 otherwise
-#endif
-
-// ----------------------------------------------------------------------------
-
-
-
-
-qra64codec *qra64_init(int flags)
-{
-
- // Eb/No value for which we optimize the decoder metric
- const float EbNodBMetric = 2.8f;
- const float EbNoMetric = (float)pow(10,EbNodBMetric/10);
- const float R = 1.0f*(QRA64_KC)/(QRA64_NC);
-
- qra64codec *pcodec = (qra64codec*)malloc(sizeof(qra64codec));
-
- if (!pcodec)
- return 0; // can't allocate memory
-
- pcodec->decEsNoMetric = 1.0f*QRA64_m*R*EbNoMetric;
- pcodec->apflags = flags;
-
- memset(pcodec->apmsg_set,0,APTYPE_SIZE*sizeof(int));
-
- if (flags==QRA_NOAP)
- return pcodec;
-
- // for QRA_USERAP and QRA_AUTOAP modes we always enable [CQ/QRZ ? ?] mgs look-up.
- // encode CQ/QRZ AP messages
- // NOTE: Here we handle only CQ and QRZ msgs.
- // 'CQ nnn', 'CQ DX' and 'DE' msgs will be handled by the decoder
- // as messages with no a-priori knowledge
- qra64_apset(pcodec, CALL_CQ, 0, GRID_BLANK, APTYPE_CQQRZ);
-
- // initialize masks for decoding with a-priori information
- encodemsg_jt65(pcodec->apmask_cqqrz, MASK_CQQRZ, 0, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_cqqrz_ooo, MASK_CQQRZ, 0, MASK_GRIDFULL);
- encodemsg_jt65(pcodec->apmask_call1, MASK_CALL1, 0, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_call1_ooo, MASK_CALL1, 0, MASK_GRIDFULL);
- encodemsg_jt65(pcodec->apmask_call2, 0, MASK_CALL2, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_call2_ooo, 0, MASK_CALL2, MASK_GRIDFULL);
- encodemsg_jt65(pcodec->apmask_call1_call2, MASK_CALL1,MASK_CALL2, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_call1_call2_grid,MASK_CALL1,MASK_CALL2, MASK_GRIDFULL12);
- encodemsg_jt65(pcodec->apmask_cq_call2, MASK_CQQRZ, MASK_CALL2, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_cq_call2_ooo, MASK_CQQRZ, MASK_CALL2, MASK_GRIDFULL12);
-
- return pcodec;
-}
-
-void qra64_close(qra64codec *pcodec)
-{
- free(pcodec);
-}
-
-int qra64_apset(qra64codec *pcodec, const int mycall, const int hiscall, const int grid, const int aptype)
-{
-// Set decoder a-priori knowledge accordingly to the type of the message to look up for
-// arguments:
-// pcodec = pointer to a qra64codec data structure as returned by qra64_init
-// mycall = mycall to look for
-// hiscall = hiscall to look for
-// grid = grid to look for
-// aptype = define and masks the type of AP to be set accordingly to the following:
-// APTYPE_CQQRZ set [cq/qrz ? ?/blank]
-// APTYPE_MYCALL set [mycall ? ?/blank]
-// APTYPE_HISCALL set [? hiscall ?/blank]
-// APTYPE_BOTHCALLS set [mycall hiscall ?]
-// APTYPE_FULL set [mycall hiscall grid]
-// APTYPE_CQHISCALL set [cq/qrz hiscall ?/blank] and [cq/qrz hiscall grid]
-// returns:
-// 0 on success
-// -1 when qra64_init was called with the QRA_NOAP flag
-// -2 invalid apytpe
-
- if (pcodec->apflags==QRA_NOAP)
- return -1;
-
- switch (aptype) {
- case APTYPE_CQQRZ:
- encodemsg_jt65(pcodec->apmsg_cqqrz, CALL_CQ, 0, GRID_BLANK);
- break;
- case APTYPE_MYCALL:
- encodemsg_jt65(pcodec->apmsg_call1, mycall, 0, GRID_BLANK);
- break;
- case APTYPE_HISCALL:
- encodemsg_jt65(pcodec->apmsg_call2, 0, hiscall, GRID_BLANK);
- break;
- case APTYPE_BOTHCALLS:
- encodemsg_jt65(pcodec->apmsg_call1_call2, mycall, hiscall, GRID_BLANK);
- break;
- case APTYPE_FULL:
- encodemsg_jt65(pcodec->apmsg_call1_call2_grid, mycall, hiscall, grid);
- break;
- case APTYPE_CQHISCALL:
- encodemsg_jt65(pcodec->apmsg_cq_call2, CALL_CQ, hiscall, GRID_BLANK);
- encodemsg_jt65(pcodec->apmsg_cq_call2_grid, CALL_CQ, hiscall, grid);
- break;
- default:
- return -2; // invalid ap type
- }
-
- pcodec->apmsg_set[aptype]=1; // signal the decoder to look-up for the specified type
-
-
- return 0;
-}
-void qra64_apdisable(qra64codec *pcodec, const int aptype)
-{
- if (pcodec->apflags==QRA_NOAP)
- return;
-
- if (aptype=APTYPE_SIZE)
- return;
-
- pcodec->apmsg_set[aptype] = 0; // signal the decoder not to look-up to the specified type
-}
-
-void qra64_encode(qra64codec *pcodec, int *y, const int *x)
-{
- int encx[QRA64_KC]; // encoder input buffer
- int ency[QRA64_NC]; // encoder output buffer
-
- int hiscall,mycall,grid;
-
- memcpy(encx,x,QRA64_K*sizeof(int)); // Copy input to encoder buffer
- encx[QRA64_K]=calc_crc6(encx,QRA64_K); // Compute and add crc symbol
- qra_encode(&QRA64_CODE, ency, encx); // encode msg+crc using given QRA code
-
- // copy codeword to output puncturing the crc symbol
- memcpy(y,ency,QRA64_K*sizeof(int)); // copy information symbols
- memcpy(y+QRA64_K,ency+QRA64_KC,QRA64_C*sizeof(int)); // copy parity symbols
-
- if (pcodec->apflags!=QRA_AUTOAP)
- return;
-
- // Here we handle the QRA_AUTOAP mode --------------------------------------------
-
- // When a [hiscall mycall ?] msg is detected we instruct the decoder
- // to look for [mycall hiscall ?] msgs
- // otherwise when a [cq mycall ?] msg is sent we reset the APTYPE_BOTHCALLS
-
- // look if the msg sent is a std type message (bit15 of grid field = 0)
- if ((x[9]&0x80)==1)
- return; // no, it's a text message, nothing to do
-
- // It's a [hiscall mycall grid] message
-
- // We assume that mycall is our call (but we don't check it)
- // hiscall the station we are calling or a general call (CQ/QRZ/etc..)
- decodemsg_jt65(&hiscall,&mycall,&grid,x);
-
-
- if ((hiscall>=CALL_CQ && hiscall<=CALL_CQ999) || hiscall==CALL_CQDX ||
- hiscall==CALL_DE) {
- // tell the decoder to look for msgs directed to us
- qra64_apset(pcodec,mycall,0,0,APTYPE_MYCALL);
- // We are making a general call and don't know who might reply
- // Reset APTYPE_BOTHCALLS so decoder won't look for [mycall hiscall ?] msgs
- qra64_apdisable(pcodec,APTYPE_BOTHCALLS);
- } else {
- // We are replying to someone named hiscall
- // Set APTYPE_BOTHCALLS so decoder will try for [mycall hiscall ?] msgs
- qra64_apset(pcodec,mycall, hiscall, GRID_BLANK, APTYPE_BOTHCALLS);
- }
-
-}
-
-#define EBNO_MIN -10.0f // minimum Eb/No value returned by the decoder (in dB)
-// AWGN metric decoder
-int qra64_decode(qra64codec *pcodec, float *ebno, int *x, const float *rxen)
-{
- int k;
- float *srctmp, *dsttmp;
- float ix[QRA64_NC*QRA64_M]; // (depunctured) intrisic information
- int xdec[QRA64_KC]; // decoded message (with crc)
- int ydec[QRA64_NC]; // re-encoded message (for snr calculations)
- float noisestd; // estimated noise variance
- float msge; // estimated message energy
- float ebnoval; // estimated Eb/No
- int rc;
-
- if (QRA64_NMSG!=QRA64_CODE.NMSG) // sanity check
- return -16; // QRA64_NMSG define is wrong
-
- // compute symbols intrinsic probabilities from received energy observations
- noisestd = qra_mfskbesselmetric(ix, rxen, QRA64_m, QRA64_N,pcodec->decEsNoMetric);
-
- // de-puncture observations adding a uniform distribution for the crc symbol
-
- // move check symbols distributions one symbol towards the end
- dsttmp = PD_ROWADDR(ix,QRA64_M, QRA64_NC-1); //Point to last symbol prob dist
- srctmp = dsttmp-QRA64_M; // source is the previous pd
- for (k=0;k57.004f)
- ebnoval=57.004f;
- ebnoval = ebnoval*57.03f/(57.03f-ebnoval);
-
- // compute value in dB
- if (ebnoval<=0) {
- ebnoval = EBNO_MIN; // assume a minimum, positive value
- }
- else {
- ebnoval = 10.0f*(float)log10(ebnoval);
- if (ebnoval4)
- return -17; // invalid submode
-
- if (B90<1.0f || B90>238.0f)
- return -18; // B90 out of range
-
- // compute index to most appropriate amplitude weighting function coefficients
- hidx = (int)(log((float)B90)/log(1.09f) - 0.499f);
-
- if (hidx<0 || hidx > 64)
- return -19; // index of weighting function out of range
-
- if (fadingModel==0) { // gaussian fading model
- // point to gaussian energy weighting taps
- hlen = glen_tab_gauss[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = gptr_tab_gauss[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else if (fadingModel==1) {
- // point to lorentzian energy weighting taps
- hlen = glen_tab_lorentz[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = gptr_tab_lorentz[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else
- return -20; // invalid fading model index
-
-
- // compute (euristically) the optimal decoder metric accordingly the given spread amount
- // We assume that the decoder threshold is:
- // Es/No(dB) = Es/No(AWGN)(dB) + 8*log(B90)/log(240)(dB)
- // that's to say, at the maximum Doppler spread bandwidth (240 Hz) there's a ~8 dB Es/No degradation
- // over the AWGN case
- tempf = 8.0f*(float)log((float)B90)/(float)log(240.0f);
- EsNoMetric = pcodec->decEsNoMetric*(float)pow(10.0f,tempf/10.0f);
-
-
-
- // Step 1 -----------------------------------------------------------------------------------
- // Evaluate the noise stdev from the received energies at nominal tone frequencies
- noisestd = qra64_fastfading_estim_noise_std(rxen, EsNoMetric, submode);
-
- // Step 2 -----------------------------------------------------------------------------------
- // Compute message symbols probability distributions
- qra64_fastfading_intrinsics(ix, rxen, hptr, hlen, noisestd, EsNoMetric, submode);
-
- // Step 3 ---------------------------------------------------------------------------
- // De-puncture observations adding a uniform distribution for the crc symbol
- // Move check symbols distributions one symbol towards the end
- dsttmp = PD_ROWADDR(ix,QRA64_M, QRA64_NC-1); //Point to last symbol prob dist
- srctmp = dsttmp-QRA64_M; // source is the previous pd
- for (k=0;k Eb/N0 conversion
- ebnoval = 1.0f/(1.0f*QRA64_K/QRA64_N*QRA64_m)*esno;
-
- // compute value in dB
- if (ebnoval<=0) {
- ebnoval = EBNO_MIN; // assume a minimum, positive value
- }
- else {
- ebnoval = 10.0f*(float)log10(ebnoval);
- if (ebnoval238.0f)
- return -18; // B90 out of range
-
- // compute index to most appropriate energy weighting function coefficients
- hidx = (int)(log((float)B90)/log(1.09f) - 0.499f);
-
- if (hidx<0 || hidx > 64)
- return -19; // index of weighting function out of range
-
- if (fadingModel==0) { // gaussian fading model
- // point to gaussian weighting taps
- hlen = glen_tab_gauss[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = gptr_tab_gauss[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else if (fadingModel==1) {
- // point to lorentzian weighting taps
- hlen = glen_tab_lorentz[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = gptr_tab_lorentz[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else
- return -20; // invalid fading model index
-
-
- // Compute the unfaded tone amplitudes from the Eb/No value passed to the call
- N0 = 1.0f; // assume unitary noise PSD
- sigmanoise = (float)sqrt(N0/2);
- EsN0 = (float)pow(10.0f,EbN0dB/10.0f)*QRA64_m*QRA64_K/QRA64_N; // Es/No = m*R*Eb/No
- Es = EsN0*N0;
-
- // compute signal bin sigmas
- for (n=0;n=0;j--) {
- normrnd_s(iq, 2, 0 , sigmasig[j]);
- *curi++ += iq[0];
- *curq++ += iq[1];
- }
-
- }
-
- // compute total bin energies (S+N) and store in first half of buffer
- curi = channel_out;
- curq = channel_out+bpm;
- for (n=0;nmaxloglh) // keep track of the max loglikelihood
- maxloglh = loglh;
- curix[k]=loglh;
- }
-
- // scale to likelihoods
- sumix = 0.f;
- for (k=0;k1
- if (u<1)
- return 0.f;
-
- // check u(bps/tothlen))
- return 10000.f;
-
- // solve for Es/No
- esno = (u-1.0f)/(1.0f/tothlen-u/bps);
-
- return esno;
-
-
-}
-
-#ifdef LIMIT_AP_MASKS
-
-static int call1_match(const int *papmsg, const int *pdec)
-{
- // assumes MASK_CALL1 = 0xFFFFFFC
- int u = papmsg[4]^pdec[4];
- return (u&0x3C)==0;
-}
-static int call2_match(const int *papmsg, const int *pdec)
-{
- // assumes MASK_CALL2 = 0xFFFFFFC
- int u = papmsg[9]^pdec[9];
- return (u&0x30)==0;
-}
-static int grid_match(const int *papmsg, const int *pdec)
-{
- // assumes MASK_GRIDFULL = 0x3FFC
- int u = papmsg[11]^pdec[11];
- int rc = (u&0x03)==0;
-
- u = papmsg[9]^pdec[9];
-
- return (u&0x0C)==0 && rc;
-}
-
-#else
-#define call1_match(a,b) (1)
-#define call2_match(a,b) (1)
-#define grid_match(a,b) (1)
-#endif
-
-
-
-
-// Attempt to decode given intrisic information
-static int qra64_decode_attempts(qra64codec *pcodec, int *xdec, const float *ix)
-{
- int rc;
-
- // Attempt to decode without a-priori info --------------------------------
- rc = qra64_do_decode(xdec, ix, NULL, NULL);
- if (rc>=0)
- return 0; // successfull decode with AP0
- else
- if (pcodec->apflags==QRA_NOAP)
- // nothing more to do
- return rc; // rc<0 = unsuccessful decode
-
- // Here we handle decoding with AP knowledge
-
-
- // Attempt to decode CQ calls
- rc = qra64_do_decode(xdec,ix,pcodec->apmask_cqqrz, pcodec->apmsg_cqqrz);
- if (rc>=0)
- return 1; // decoded [cq/qrz ? ?]
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_cqqrz_ooo,
- pcodec->apmsg_cqqrz);
- if (rc>=0)
- // check that ooo really matches
- if (grid_match(pcodec->apmsg_cqqrz,xdec))
- return 2; // decoded [cq/qrz ? ooo]
-
- // attempt to decode calls directed to us
- if (pcodec->apmsg_set[APTYPE_MYCALL]) {
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1,
- pcodec->apmsg_call1);
- if (rc>=0)
- // check that mycall really matches
- if (call1_match(pcodec->apmsg_call1,xdec))
- return 3; // decoded [mycall ? ?]
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_ooo,
- pcodec->apmsg_call1);
- if (rc>=0)
- // check that mycall and ooo really match
- if (call1_match(pcodec->apmsg_call1,xdec) &&
- grid_match(pcodec->apmsg_call1,xdec))
- return 4; // decoded [mycall ? ooo]
- }
-
- // attempt to decode [mycall hiscall ?] msgs
- if (pcodec->apmsg_set[APTYPE_BOTHCALLS]) {
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_call2,
- pcodec->apmsg_call1_call2);
- if (rc>=0)
- // check that mycall and hiscall really match
- if (call1_match(pcodec->apmsg_call1_call2,xdec) &&
- call2_match(pcodec->apmsg_call1_call2,xdec))
- return 5; // decoded [mycall srccall ?]
- }
-
- // attempt to decode [? hiscall ?/b] msgs
- if (pcodec->apmsg_set[APTYPE_HISCALL]) {
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call2,
- pcodec->apmsg_call2);
- if (rc>=0)
- // check that hiscall really match
- if (call2_match(pcodec->apmsg_call2,xdec))
- return 6; // decoded [? hiscall ?]
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call2_ooo,
- pcodec->apmsg_call2);
- if (rc>=0)
- // check that hiscall and ooo match
- if (call2_match(pcodec->apmsg_call2,xdec) &&
- grid_match(pcodec->apmsg_call2,xdec))
- return 7; // decoded [? hiscall ooo]
- }
-
- // attempt to decode [cq/qrz hiscall ?/b/grid] msgs
- if (pcodec->apmsg_set[APTYPE_CQHISCALL]) {
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2,
- pcodec->apmsg_cq_call2);
- if (rc>=0)
- // check that hiscall matches
- if (call2_match(pcodec->apmsg_call2,xdec))
- return 9; // decoded [cq/qrz hiscall ?]
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2_ooo,
- pcodec->apmsg_cq_call2_grid);
- if (rc>=0) {
- // Full AP mask need special handling
- // To minimize false decodes we check the decoded message
- // with what passed in the ap_set call
- if (memcmp(pcodec->apmsg_cq_call2_grid,xdec, QRA64_K*sizeof(int))==0)
- return 11; // decoded [cq/qrz hiscall grid]
- }
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2_ooo,
- pcodec->apmsg_cq_call2);
- if (rc>=0) {
- // Full AP mask need special handling
- // To minimize false decodes we check the decoded message
- // with what passed in the ap_set call
- if (memcmp(pcodec->apmsg_cq_call2,xdec, QRA64_K*sizeof(int))==0)
- return 10; // decoded [cq/qrz hiscall ]
- }
- }
-
- // attempt to decode [mycall hiscall grid]
- if (pcodec->apmsg_set[APTYPE_FULL]) {
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_call2_grid,
- pcodec->apmsg_call1_call2_grid);
- if (rc>=0) {
- // Full AP mask need special handling
- // All the three msg fields were given.
- // To minimize false decodes we check the decoded message
- // with what passed in the ap_set call
- if (memcmp(pcodec->apmsg_call1_call2_grid,xdec, QRA64_K*sizeof(int))==0)
- return 8; // decoded [mycall hiscall grid]
- }
- }
-
- // all decoding attempts failed
- return -1;
-}
-
-
-
-// Decode with given a-priori information
-static int qra64_do_decode(int *xdec, const float *pix, const int *ap_mask,
- const int *ap_x)
-{
- int rc;
- const float *ixsrc;
- float ix_masked[QRA64_NC*QRA64_M]; // Masked intrinsic information
- float ex[QRA64_NC*QRA64_M]; // Extrinsic information from the decoder
-
- float v2cmsg[QRA64_NMSG*QRA64_M]; // buffers for the decoder messages
- float c2vmsg[QRA64_NMSG*QRA64_M];
-
- if (ap_mask==NULL) { // no a-priori information
- ixsrc = pix; // intrinsic source is what passed as argument
- } else {
- // a-priori information provided
- // mask channel observations with a-priori
- ix_mask(ix_masked,pix,ap_mask,ap_x);
- ixsrc = ix_masked; // intrinsic source is the masked version
- }
-
- // run the decoding algorithm
- rc = qra_extrinsic(&QRA64_CODE,ex,ixsrc,QRA64_NITER,v2cmsg,c2vmsg);
- if (rc<0)
- return -1; // no convergence in given iterations
-
- // decode
- qra_mapdecode(&QRA64_CODE,xdec,ex,ixsrc);
-
- // verify crc
- if (calc_crc6(xdec,QRA64_K)!=xdec[QRA64_K]) // crc doesn't match (detected error)
- return -2; // decoding was succesfull but crc doesn't match
-
- return 0;
-}
-
-
-// crc functions --------------------------------------------------------------
-// crc-6 generator polynomial
-// g(x) = x^6 + a5*x^5 + ... + a1*x + a0
-
-// g(x) = x^6 + x + 1
-#define CRC6_GEN_POL 0x30 // MSB=a0 LSB=a5
-
-// g(x) = x^6 + x^2 + x + 1 (See: https://users.ece.cmu.edu/~koopman/crc/)
-// #define CRC6_GEN_POL 0x38 // MSB=a0 LSB=a5. Simulation results are similar
-
-static int calc_crc6(const int *x, int sz)
-{
- // todo: compute it faster using a look up table
- int k,j,t,sr = 0;
- for (k=0;k>1) ^ CRC6_GEN_POL;
- else
- sr = (sr>>1);
- t>>=1;
- }
- }
- return sr;
-}
-
-static void ix_mask(float *dst, const float *src, const int *mask,
- const int *x)
-{
- // mask intrinsic information (channel observations) with a priori knowledge
-
- int k,kk, smask;
- float *row;
-
- memcpy(dst,src,(QRA64_NC*QRA64_M)*sizeof(float));
-
- for (k=0;k>22)&0x3F;
- y[1]= (call1>>16)&0x3F;
- y[2]= (call1>>10)&0x3F;
- y[3]= (call1>>4)&0x3F;
- y[4]= (call1<<2)&0x3F;
-
- y[4] |= (call2>>26)&0x3F;
- y[5]= (call2>>20)&0x3F;
- y[6]= (call2>>14)&0x3F;
- y[7]= (call2>>8)&0x3F;
- y[8]= (call2>>2)&0x3F;
- y[9]= (call2<<4)&0x3F;
-
- y[9] |= (grid>>12)&0x3F;
- y[10]= (grid>>6)&0x3F;
- y[11]= (grid)&0x3F;
-
-}
-void decodemsg_jt65(int *call1, int *call2, int *grid, const int *x)
-{
- int nc1, nc2, ng;
-
- nc1 = x[4]>>2;
- nc1 |= x[3]<<4;
- nc1 |= x[2]<<10;
- nc1 |= x[1]<<16;
- nc1 |= x[0]<<22;
-
- nc2 = x[9]>>4;
- nc2 |= x[8]<<2;
- nc2 |= x[7]<<8;
- nc2 |= x[6]<<14;
- nc2 |= x[5]<<20;
- nc2 |= (x[4]&0x03)<<26;
-
- ng = x[11];
- ng |= x[10]<<6;
- ng |= (x[9]&0x0F)<<12;
-
- *call1 = nc1;
- *call2 = nc2;
- *grid = ng;
-}
diff --git a/lib/qra/qra64/qra64.h b/lib/qra/qra64/qra64.h
deleted file mode 100644
index 3b2b5bd..0000000
--- a/lib/qra/qra64/qra64.h
+++ /dev/null
@@ -1,269 +0,0 @@
-// qra64.h
-// Encoding/decoding functions for the QRA64 mode
-//
-// (c) 2016 - Nico Palermo, IV3NWV
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#ifndef _qra64_h_
-#define _qra64_h_
-
-// qra64_init(...) initialization flags
-#define QRA_NOAP 0 // don't use a-priori knowledge
-#define QRA_AUTOAP 1 // use auto a-priori knowledge
-#define QRA_USERAP 2 // a-priori knowledge messages provided by the user
-
-// QRA code parameters
-#define QRA64_K 12 // information symbols
-#define QRA64_N 63 // codeword length
-#define QRA64_C 51 // (number of parity checks C=(N-K))
-#define QRA64_M 64 // code alphabet size
-#define QRA64_m 6 // bits per symbol
-
-// packed predefined callsigns and fields as defined in JT65
-#define CALL_CQ 0xFA08319
-#define CALL_QRZ 0xFA0831A
-#define CALL_CQ000 0xFA0831B
-#define CALL_CQ999 0xFA08702
-#define CALL_CQDX 0x5624C39
-#define CALL_DE 0xFF641D1
-#define GRID_BLANK 0x7E91
-
-// Types of a-priori knowledge messages
-#define APTYPE_CQQRZ 0 // [cq/qrz ? ?/blank]
-#define APTYPE_MYCALL 1 // [mycall ? ?/blank]
-#define APTYPE_HISCALL 2 // [? hiscall ?/blank]
-#define APTYPE_BOTHCALLS 3 // [mycall hiscall ?]
-#define APTYPE_FULL 4 // [mycall hiscall grid]
-#define APTYPE_CQHISCALL 5 // [cq/qrz hiscall ?/blank]
-#define APTYPE_SIZE (APTYPE_CQHISCALL+1)
-
-typedef struct {
- float decEsNoMetric;
- int apflags;
- int apmsg_set[APTYPE_SIZE]; // indicate which ap type knowledge has
- // been set by the user
-// ap messages buffers
- int apmsg_cqqrz[12]; // [cq/qrz ? ?/blank]
- int apmsg_call1[12]; // [mycall ? ?/blank]
- int apmsg_call2[12]; // [? hiscall ?/blank]
- int apmsg_call1_call2[12]; // [mycall hiscall ?]
- int apmsg_call1_call2_grid[12]; // [mycall hiscall grid]
- int apmsg_cq_call2[12]; // [cq hiscall ?/blank]
- int apmsg_cq_call2_grid[12]; // [cq hiscall grid]
-
-// ap messages masks
- int apmask_cqqrz[12];
- int apmask_cqqrz_ooo[12];
- int apmask_call1[12];
- int apmask_call1_ooo[12];
- int apmask_call2[12];
- int apmask_call2_ooo[12];
- int apmask_call1_call2[12];
- int apmask_call1_call2_grid[12];
- int apmask_cq_call2[12];
- int apmask_cq_call2_ooo[12];
-} qra64codec;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-qra64codec *qra64_init(int flags);
-// QRA64 mode initialization function
-// arguments:
-// flags: set the decoder mode
-// QRA_NOAP use no a-priori information
-// QRA_AUTOAP use any relevant previous decodes
-// QRA_USERAP use a-priori information provided via qra64_apset(...)
-// returns:
-// Pointer to initialized qra64codec data structure
-// this pointer should be passed to the encoding/decoding functions
-//
-// 0 if unsuccessful (can't allocate memory)
-// ----------------------------------------------------------------------------
-
-void qra64_encode(qra64codec *pcodec, int *y, const int *x);
-// QRA64 encoder
-// arguments:
-// pcodec = pointer to a qra64codec data structure as returned by qra64_init
-// x = pointer to the message to be encoded, int x[12]
-// x must point to an array of integers (i.e. defined as int x[12])
-// y = pointer to encoded message, int y[63]=
-// ----------------------------------------------------------------------------
-
-int qra64_decode(qra64codec *pcodec, float *ebno, int *x, const float *r);
-// QRA64 mode decoder
-// arguments:
-// pcodec = pointer to a qra64codec data structure as returned by qra64_init
-// ebno = pointer to a float where the avg Eb/No (in dB) will be stored
-// in case of successfull decoding
-// (pass a null pointer if not interested)
-// x = pointer to decoded message, int x[12]
-// r = pointer to received symbol energies (squared amplitudes)
-// r must point to an array of length QRA64_M*QRA64_N (=64*63=4032)
-// The first QRA_M entries should be the energies of the first
-// symbol in the codeword; the last QRA_M entries should be the
-// energies of the last symbol in the codeword
-//
-// return code:
-//
-// The return code is <0 when decoding is unsuccessful
-// -16 indicates that the definition of QRA64_NMSG does not match what required by the code
-// If the decoding process is successfull the return code is accordingly to the following table
-// rc=0 [? ? ?] AP0 (decoding with no a-priori)
-// rc=1 [CQ ? ?] AP27
-// rc=2 [CQ ? ] AP44
-// rc=3 [CALL ? ?] AP29
-// rc=4 [CALL ? ] AP45
-// rc=5 [CALL CALL ?] AP57
-// rc=6 [? CALL ?] AP29
-// rc=7 [? CALL ] AP45
-// rc=8 [CALL CALL GRID] AP72 (actually a AP68 mask to reduce false decodes)
-// rc=9 [CQ CALL ?] AP55
-// rc=10 [CQ CALL ] AP70 (actaully a AP68 mask to reduce false decodes)
-
-// return codes in the range 1-10 indicate the amount and the type of a-priori
-// information was required to decode the received message.
-
-
-// Decode a QRA64 msg using a fast-fading metric
-int qra64_decode_fastfading(
- qra64codec *pcodec, // ptr to the codec structure
- float *ebno, // ptr to where the estimated Eb/No value will be saved
- int *x, // ptr to decoded message
- const float *rxen, // ptr to received symbol energies array
- const int submode, // submode idx (0=QRA64A ... 4=QRA64E)
- const float B90, // spread bandwidth (90% fractional energy)
- const int fadingModel); // 0=Gaussian 1=Lorentzian fade model
-//
-// rxen: The array of the received bin energies
-// Bins must be spaced by integer multiples of the symbol rate (1/Ts Hz)
-// The array must be an array of total length U = L x N where:
-// L: is the number of frequency bins per message symbol (see after)
-// N: is the number of symbols in a QRA64 msg (63)
-//
-// The number of bins/symbol L depends on the selected submode accordingly to
-// the following rule:
-// L = (64+64*2^submode+64) = 64*(2+2^submode)
-// Tone 0 is always supposed to be at offset 64 in the array.
-// The m-th tone nominal frequency is located at offset 64 + m*2^submode (m=0..63)
-//
-// Submode A: (2^submode = 1)
-// L = 64*3 = 196 bins/symbol
-// Total length of the energies array: U = 192*63 = 12096 floats
-//
-// Submode B: (2^submode = 2)
-// L = 64*4 = 256 bins/symbol
-// Total length of the energies array: U = 256*63 = 16128 floats
-//
-// Submode C: (2^submode = 4)
-// L = 64*6 = 384 bins/symbol
-// Total length of the energies array: U = 384*63 = 24192 floats
-//
-// Submode D: (2^submode = 8)
-// L = 64*10 = 640 bins/symbol
-// Total length of the energies array: U = 640*63 = 40320 floats
-//
-// Submode E: (2^submode = 16)
-// L = 64*18 = 1152 bins/symbol
-// Total length of the energies array: U = 1152*63 = 72576 floats
-//
-// Note: The rxen array is modified and reused for internal calculations.
-//
-//
-// B90: spread fading bandwidth in Hz (90% fractional average energy)
-//
-// B90 should be in the range 1 Hz ... 238 Hz
-// The value passed to the call is rounded to the closest value among the
-// 64 available values:
-// B = 1.09^k Hz, with k=0,1,...,63
-//
-// I.e. B90=27 Hz will be approximated in this way:
-// k = rnd(log(27)/log(1.09)) = 38
-// B90 = 1.09^k = 1.09^38 = 26.4 Hz
-//
-// For any input value the maximum rounding error is not larger than +/- 5%
-//
-// return codes: same return codes of qra64_decode (+some additional error codes)
-
-
-// Simulate the fast-fading channel (to be used with qra64_decode_fastfading)
-int qra64_fastfading_channel(
- float **rxen,
- const int *xmsg,
- const int submode,
- const float EbN0dB,
- const float B90,
- const int fadingModel);
-// Simulate transmission over a fading channel with given B90, fading model and submode
-// and non coherent detection.
-// Sets rxen to point to an array of bin energies formatted as required
-// by the (fast-fading) decoding routine.
-// returns 0 on success or negative values on error conditions
-
-
-int qra64_apset(qra64codec *pcodec, const int mycall, const int hiscall, const int grid, const int aptype);
-// Set decoder a-priori knowledge accordingly to the type of the message to
-// look up for
-// arguments:
-// pcodec = pointer to a qra64codec data structure as returned by qra64_init
-// mycall = mycall to look for
-// hiscall = hiscall to look for
-// grid = grid to look for
-// aptype = define the type of AP to be set:
-// APTYPE_CQQRZ set [cq/qrz ? ?/blank]
-// APTYPE_MYCALL set [mycall ? ?/blank]
-// APTYPE_HISCALL set [? hiscall ?/blank]
-// APTYPE_BOTHCALLS set [mycall hiscall ?]
-// APTYPE_FULL set [mycall hiscall grid]
-// APTYPE_CQHISCALL set [cq/qrz hiscall ?/blank]
-
-// returns:
-// 0 on success
-// -1 when qra64_init was called with the QRA_NOAP flag
-// -2 invalid apytpe (valid range [APTYPE_CQQRZ..APTYPE_CQHISCALL]
-// (APTYPE_CQQRZ [cq/qrz ? ?] is set by default )
-
-void qra64_apdisable(qra64codec *pcodec, const int aptype);
-// disable specific AP type
-// arguments:
-// pcodec = pointer to a qra64codec data structure as returned by qra64_init
-// aptype = define the type of AP to be disabled
-// APTYPE_CQQRZ disable [cq/qrz ? ?/blank]
-// APTYPE_MYCALL disable [mycall ? ?/blank]
-// APTYPE_HISCALL disable [ ? hiscall ?/blank]
-// APTYPE_BOTHCALLS disable [mycall hiscall ? ]
-// APTYPE_FULL disable [mycall hiscall grid]
-// APTYPE_CQHISCALL set [cq/qrz hiscall ?/blank]
-
-void qra64_close(qra64codec *pcodec);
-// Free memory allocated by qra64_init
-// arguments:
-// pcodec = pointer to a qra64codec data structure as returned by qra64_init
-
-// ----------------------------------------------------------------------------
-
-// encode/decode std msgs in 12 symbols as done in jt65
-void encodemsg_jt65(int *y, const int call1, const int call2, const int grid);
-void decodemsg_jt65(int *call1, int *call2, int *grid, const int *x);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _qra64_h_
diff --git a/lib/qra/qra64/qra64_all.c b/lib/qra/qra64/qra64_all.c
deleted file mode 100644
index 28f8ab9..0000000
--- a/lib/qra/qra64/qra64_all.c
+++ /dev/null
@@ -1,1050 +0,0 @@
-/*
-qra64.c
-Encoding/decoding functions for the QRA64 mode
-
-(c) 2016 - Nico Palermo, IV3NWV
-
--------------------------------------------------------------------------------
-
- qracodes 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.
- qracodes 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 qracodes source distribution.
- If not, see .
-
------------------------------------------------------------------------------
-
-QRA code used in this sowftware release:
-
-QRA13_64_64_IRR_E: K=13 N=64 Q=64 irregular QRA code (defined in
-qra13_64_64_irr_e.h /.c)
-
-Codes with K=13 are designed to include a CRC as the 13th information symbol
-and improve the code UER (Undetected Error Rate).
-The CRC symbol is not sent along the channel (the codes are punctured) and the
-resulting code is a (12,63) code
-*/
-//----------------------------------------------------------------------------
-
-#include
-#include
-
-#include "qra64.h"
-#include "../qracodes/qracodes.h"
-#include "../qracodes/qra13_64_64_irr_e.h"
-#include "../qracodes/pdmath.h"
-#include "../qracodes/normrnd.h"
-
-// Code parameters of the QRA64 mode
-#define QRA64_CODE qra_13_64_64_irr_e
-#define QRA64_NMSG 218 // Must much value indicated in QRA64_CODE.NMSG
-
-#define QRA64_KC (QRA64_K+1) // Information symbols (crc included)
-#define QRA64_NC (QRA64_N+1) // Codeword length (as defined in the code)
-#define QRA64_NITER 100 // max number of iterations per decode
-
-// static functions declarations ----------------------------------------------
-static int calc_crc6(const int *x, int sz);
-static void ix_mask(float *dst, const float *src, const int *mask,
- const int *x);
-static int qra64_decode_attempts(qra64codec *pcodec, int *xdec, const float *ix);
-static int qra64_do_decode(int *x, const float *pix, const int *ap_mask,
- const int *ap_x);
-static float qra64_fastfading_estim_noise_std(
- float *rxen,
- const float esnometric,
- const int submode);
-static void qra64_fastfading_intrinsics(
- float *pix,
- const float *rxamp,
- const float *hptr,
- const int hlen,
- const float cmetric,
- const int submode);
-static float qra64_fastfading_msg_esno(
- const int *ydec,
- const float *rxamp,
- const float sigma,
- const float EsNoMetric,
- const int hlen,
- const int submode);
-
-
-// a-priori information masks for fields in JT65-like msgs --------------------
-#define MASK_CQQRZ 0xFFFFFFC // CQ/QRZ calls common bits
-#define MASK_CALL1 0xFFFFFFF
-#define MASK_CALL2 0xFFFFFFF
-#define MASK_GRIDFULL 0xFFFF
-#define MASK_GRIDFULL12 0x3FFC // less aggressive mask (to be used with full AP decoding)
-#define MASK_GRIDBIT 0x8000 // b[15] is 1 for free text, 0 otherwise
-// ----------------------------------------------------------------------------
-
-qra64codec *qra64_init(int flags)
-{
-
- // Eb/No value for which we optimize the decoder metric
- const float EbNodBMetric = 2.8f;
- const float EbNoMetric = (float)pow(10,EbNodBMetric/10);
- const float R = 1.0f*(QRA64_KC)/(QRA64_NC);
-
- qra64codec *pcodec = (qra64codec*)malloc(sizeof(qra64codec));
-
- if (!pcodec)
- return 0; // can't allocate memory
-
- pcodec->decEsNoMetric = 1.0f*QRA64_m*R*EbNoMetric;
- pcodec->apflags = flags;
-
- memset(pcodec->apmsg_set,0,APTYPE_SIZE*sizeof(int));
-
- if (flags==QRA_NOAP)
- return pcodec;
-
- // for QRA_USERAP and QRA_AUTOAP modes we always enable [CQ/QRZ ? ?] mgs look-up.
- // encode CQ/QRZ AP messages
- // NOTE: Here we handle only CQ and QRZ msgs.
- // 'CQ nnn', 'CQ DX' and 'DE' msgs will be handled by the decoder
- // as messages with no a-priori knowledge
- qra64_apset(pcodec, CALL_CQ, 0, GRID_BLANK, APTYPE_CQQRZ);
-
- // initialize masks for decoding with a-priori information
- encodemsg_jt65(pcodec->apmask_cqqrz, MASK_CQQRZ, 0, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_cqqrz_ooo, MASK_CQQRZ, 0, MASK_GRIDFULL);
- encodemsg_jt65(pcodec->apmask_call1, MASK_CALL1, 0, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_call1_ooo, MASK_CALL1, 0, MASK_GRIDFULL);
- encodemsg_jt65(pcodec->apmask_call2, 0, MASK_CALL2, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_call2_ooo, 0, MASK_CALL2, MASK_GRIDFULL);
- encodemsg_jt65(pcodec->apmask_call1_call2, MASK_CALL1,MASK_CALL2, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_call1_call2_grid,MASK_CALL1,MASK_CALL2, MASK_GRIDFULL12);
- encodemsg_jt65(pcodec->apmask_cq_call2, MASK_CQQRZ, MASK_CALL2, MASK_GRIDBIT);
- encodemsg_jt65(pcodec->apmask_cq_call2_ooo, MASK_CQQRZ, MASK_CALL2, MASK_GRIDFULL12);
-
- return pcodec;
-}
-
-void qra64_close(qra64codec *pcodec)
-{
- free(pcodec);
-}
-
-int qra64_apset(qra64codec *pcodec, const int mycall, const int hiscall, const int grid, const int aptype)
-{
-// Set decoder a-priori knowledge accordingly to the type of the message to look up for
-// arguments:
-// pcodec = pointer to a qra64codec data structure as returned by qra64_init
-// mycall = mycall to look for
-// hiscall = hiscall to look for
-// grid = grid to look for
-// aptype = define and masks the type of AP to be set accordingly to the following:
-// APTYPE_CQQRZ set [cq/qrz ? ?/blank]
-// APTYPE_MYCALL set [mycall ? ?/blank]
-// APTYPE_HISCALL set [? hiscall ?/blank]
-// APTYPE_BOTHCALLS set [mycall hiscall ?]
-// APTYPE_FULL set [mycall hiscall grid]
-// APTYPE_CQHISCALL set [cq/qrz hiscall ?/blank] and [cq/qrz hiscall grid]
-// returns:
-// 0 on success
-// -1 when qra64_init was called with the QRA_NOAP flag
-// -2 invalid apytpe
-
- if (pcodec->apflags==QRA_NOAP)
- return -1;
-
- switch (aptype) {
- case APTYPE_CQQRZ:
- encodemsg_jt65(pcodec->apmsg_cqqrz, CALL_CQ, 0, GRID_BLANK);
- break;
- case APTYPE_MYCALL:
- encodemsg_jt65(pcodec->apmsg_call1, mycall, 0, GRID_BLANK);
- break;
- case APTYPE_HISCALL:
- encodemsg_jt65(pcodec->apmsg_call2, 0, hiscall, GRID_BLANK);
- break;
- case APTYPE_BOTHCALLS:
- encodemsg_jt65(pcodec->apmsg_call1_call2, mycall, hiscall, GRID_BLANK);
- break;
- case APTYPE_FULL:
- encodemsg_jt65(pcodec->apmsg_call1_call2_grid, mycall, hiscall, grid);
- break;
- case APTYPE_CQHISCALL:
- encodemsg_jt65(pcodec->apmsg_cq_call2, CALL_CQ, hiscall, GRID_BLANK);
- encodemsg_jt65(pcodec->apmsg_cq_call2_grid, CALL_CQ, hiscall, grid);
- break;
- default:
- return -2; // invalid ap type
- }
-
- pcodec->apmsg_set[aptype]=1; // signal the decoder to look-up for the specified type
-
-
- return 0;
-}
-void qra64_apdisable(qra64codec *pcodec, const int aptype)
-{
- if (pcodec->apflags==QRA_NOAP)
- return;
-
- if (aptype=APTYPE_SIZE)
- return;
-
- pcodec->apmsg_set[aptype] = 0; // signal the decoder not to look-up to the specified type
-}
-
-void qra64_encode(qra64codec *pcodec, int *y, const int *x)
-{
- int encx[QRA64_KC]; // encoder input buffer
- int ency[QRA64_NC]; // encoder output buffer
-
- int hiscall,mycall,grid;
-
- memcpy(encx,x,QRA64_K*sizeof(int)); // Copy input to encoder buffer
- encx[QRA64_K]=calc_crc6(encx,QRA64_K); // Compute and add crc symbol
- qra_encode(&QRA64_CODE, ency, encx); // encode msg+crc using given QRA code
-
- // copy codeword to output puncturing the crc symbol
- memcpy(y,ency,QRA64_K*sizeof(int)); // copy information symbols
- memcpy(y+QRA64_K,ency+QRA64_KC,QRA64_C*sizeof(int)); // copy parity symbols
-
- if (pcodec->apflags!=QRA_AUTOAP)
- return;
-
- // Here we handle the QRA_AUTOAP mode --------------------------------------------
-
- // When a [hiscall mycall ?] msg is detected we instruct the decoder
- // to look for [mycall hiscall ?] msgs
- // otherwise when a [cq mycall ?] msg is sent we reset the APTYPE_BOTHCALLS
-
- // look if the msg sent is a std type message (bit15 of grid field = 0)
- if ((x[9]&0x80)==1)
- return; // no, it's a text message, nothing to do
-
- // It's a [hiscall mycall grid] message
-
- // We assume that mycall is our call (but we don't check it)
- // hiscall the station we are calling or a general call (CQ/QRZ/etc..)
- decodemsg_jt65(&hiscall,&mycall,&grid,x);
-
-
- if ((hiscall>=CALL_CQ && hiscall<=CALL_CQ999) || hiscall==CALL_CQDX ||
- hiscall==CALL_DE) {
- // tell the decoder to look for msgs directed to us
- qra64_apset(pcodec,mycall,0,0,APTYPE_MYCALL);
- // We are making a general call and don't know who might reply
- // Reset APTYPE_BOTHCALLS so decoder won't look for [mycall hiscall ?] msgs
- qra64_apdisable(pcodec,APTYPE_BOTHCALLS);
- } else {
- // We are replying to someone named hiscall
- // Set APTYPE_BOTHCALLS so decoder will try for [mycall hiscall ?] msgs
- qra64_apset(pcodec,mycall, hiscall, GRID_BLANK, APTYPE_BOTHCALLS);
- }
-
-}
-
-#define EBNO_MIN -10.0f // minimum Eb/No value returned by the decoder (in dB)
-int qra64_decode(qra64codec *pcodec, float *ebno, int *x, const float *rxen)
-{
- int k;
- float *srctmp, *dsttmp;
- float ix[QRA64_NC*QRA64_M]; // (depunctured) intrisic information
- int xdec[QRA64_KC]; // decoded message (with crc)
- int ydec[QRA64_NC]; // re-encoded message (for snr calculations)
- float noisestd; // estimated noise variance
- float msge; // estimated message energy
- float ebnoval; // estimated Eb/No
- int rc;
-
- if (QRA64_NMSG!=QRA64_CODE.NMSG) // sanity check
- return -16; // QRA64_NMSG define is wrong
-
- // compute symbols intrinsic probabilities from received energy observations
- noisestd = qra_mfskbesselmetric(ix, rxen, QRA64_m, QRA64_N,pcodec->decEsNoMetric);
-
- // de-puncture observations adding a uniform distribution for the crc symbol
-
- // move check symbols distributions one symbol towards the end
- dsttmp = PD_ROWADDR(ix,QRA64_M, QRA64_NC-1); //Point to last symbol prob dist
- srctmp = dsttmp-QRA64_M; // source is the previous pd
- for (k=0;k57.004f)
- ebnoval=57.004f;
- ebnoval = ebnoval*57.03f/(57.03f-ebnoval);
-
- // compute value in dB
- if (ebnoval<=0)
- ebnoval = EBNO_MIN; // assume a minimum, positive value
- else
- ebnoval = 10.0f*(float)log10(ebnoval);
- if (ebnoval4)
- return -17; // invalid submode
-
- if (B90<1.0f || B90>238.0f)
- return -18; // B90 out of range
-
- // compute index to most appropriate amplitude weighting function coefficients
- hidx = (int)(log((float)B90)/log(1.09f) - 0.499f);
-
- if (hidx<0 || hidx > 64)
- return -19; // index of weighting function out of range
-
- if (fadingModel==0) { // gaussian fading model
- // point to gaussian weighting taps
- hlen = hlen_tab_gauss[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = hptr_tab_gauss[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else if (fadingModel==1) {
- // point to lorentzian weighting taps
- hlen = hlen_tab_lorentz[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = hptr_tab_lorentz[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else
- return -20; // invalid fading model index
-
-
- // compute (euristically) the optimal decoder metric accordingly the given spread amount
- // We assume that the decoder threshold is:
- // Es/No(dB) = Es/No(AWGN)(dB) + 8*log(B90)/log(240)(dB)
- // that's to say, at the maximum Doppler spread bandwidth (240 Hz) there's a ~8 dB Es/No degradation
- // over the AWGN case
- tempf = 8.0f*(float)log((float)B90)/(float)log(240.0f);
- EsNoMetric = pcodec->decEsNoMetric*(float)pow(10.0f,tempf/10.0f);
-
- // Step 1 -----------------------------------------------------------------------------------
- // Evaluate the noise stdev from the received energies at nominal tone frequencies
- // and transform energies to amplitudes
- tempf = hptr[hlen-1]; // amplitude weigth at nominal freq;
- tempf = tempf*tempf; // fractional energy at nominal freq. bin
-
- noisestd = qra64_fastfading_estim_noise_std(rxen, EsNoMetric, submode);
- cmetric = (float)sqrt(M_PI_2*EsNoMetric)/noisestd;
-
- // Step 2 -----------------------------------------------------------------------------------
- // Compute message symbols probability distributions
- qra64_fastfading_intrinsics(ix, rxen, hptr, hlen, cmetric, submode);
-
- // Step 3 ---------------------------------------------------------------------------
- // De-puncture observations adding a uniform distribution for the crc symbol
- // Move check symbols distributions one symbol towards the end
- dsttmp = PD_ROWADDR(ix,QRA64_M, QRA64_NC-1); //Point to last symbol prob dist
- srctmp = dsttmp-QRA64_M; // source is the previous pd
- for (k=0;k238.0f)
- return -18; // B90 out of range
-
- // compute index to most appropriate amplitude weighting function coefficients
- hidx = (int)(log((float)B90)/log(1.09f) - 0.499f);
-
- if (hidx<0 || hidx > 64)
- return -19; // index of weighting function out of range
-
- if (fadingModel==0) { // gaussian fading model
- // point to gaussian weighting taps
- hlen = hlen_tab_gauss[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = hptr_tab_gauss[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else if (fadingModel==1) {
- // point to lorentzian weighting taps
- hlen = hlen_tab_lorentz[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
- hptr = hptr_tab_lorentz[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
- }
- else
- return -20; // invalid fading model index
-
-
- // Compute the unfaded tone amplitudes from the Eb/No value passed to the call
- N0 = 1.0f; // assume unitary noise PSD
- sigmanoise = (float)sqrt(N0/2);
- EsN0 = (float)pow(10.0f,EbN0dB/10.0f)*QRA64_m*QRA64_K/QRA64_N; // Es/No = m*R*Eb/No
- Es = EsN0*N0;
- A = (float)sqrt(Es/2.0f); // unfaded tone amplitude (i^2+q^2 = Es/2+Es/2 = Es)
-
-
- // Generate gaussian noise iq components
- normrnd_s(channel_out, bpm*2, 0 , sigmanoise);
-
- // Add message symbols energies
- for (n=0;n=0;j--) {
- sigmasig = A*hptr[j];
- normrnd_s(iq, 2, 0 , sigmasig);
-// iq[0]=sigmasig*sqrt(2); iq[1]=0; debug: used to verify Eb/No
- *curi++ += iq[0];
- *curq++ += iq[1];
-// tote +=iq[0]*iq[0]+iq[1]*iq[1]; // debug
- }
-
- }
-
-// tote = tote/QRA64_N; // debug
-
- // compute total bin energies (S+N) and store in first half of buffer
- curi = channel_out;
- curq = channel_out+bpm;
- for (n=0;n=0;j--) {
- u = *curbin++ * hptr[j]*cmetric;
- u = u*u/(u+(float)M_E); // log(I0(u)) approx.
- loglh = loglh + u;
- }
- if (loglh>maxloglh) // keep track of the max loglikelihood
- maxloglh = loglh;
- curix[k]=loglh;
- }
- // scale to likelihoods
- sumix = 0.f;
- for (k=0;k=0;j--) {
- u = *curbin++;
- msgsn += u*u;
- }
-
- }
-
- msgsn = msgsn/(QRA64_N*tothlen); // avg msg energy per bin (noise included)
-
- // as sigma is overestimated (sigmatrue = sigma*sqrt((1+EsNoMetric/bps)/(1+EsNo/bps))
- // we have: msgsn = (1+x/hlen)/(1+x/bps)*2*sigma^2*(1+EsnoMetric/bps), where x = Es/N0(true)
- //
- // we can then write:
- // u = msgsn/2.0f/(sigma*sigma)/(1.0f+EsNoMetric/bps);
- // (1+x/hlen)/(1+x/bps) = u
-
- u = msgsn/(2.0f*sigma*sigma)/(1.0f+EsNoMetric/bps);
-
- // check u>1
- if (u<1)
- return 0.f;
-
- // check u(bps/tothlen))
- return 10000.f;
-
- // solve for Es/No
- esno = (u-1.0f)/(1.0f/tothlen-u/bps);
-
- return esno;
-
-
-}
-
-
-// Attempt to decode given intrisic information
-static int qra64_decode_attempts(qra64codec *pcodec, int *xdec, const float *ix)
-{
- int rc;
-
- // Attempt to decode without a-priori info --------------------------------
- rc = qra64_do_decode(xdec, ix, NULL, NULL);
- if (rc>=0)
- return 0; // successfull decode with AP0
- else
- if (pcodec->apflags==QRA_NOAP)
- // nothing more to do
- return rc; // rc<0 = unsuccessful decode
-
- // Here we handle decoding with AP knowledge
-
- // Attempt to decode CQ calls
- rc = qra64_do_decode(xdec,ix,pcodec->apmask_cqqrz, pcodec->apmsg_cqqrz);
- if (rc>=0) return 1; // decoded [cq/qrz ? ?]
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_cqqrz_ooo,
- pcodec->apmsg_cqqrz);
- if (rc>=0) return 2; // decoded [cq ? ooo]
-
- // attempt to decode calls directed to us
- if (pcodec->apmsg_set[APTYPE_MYCALL]) {
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1,
- pcodec->apmsg_call1);
- if (rc>=0) return 3; // decoded [mycall ? ?]
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_ooo,
- pcodec->apmsg_call1);
- if (rc>=0) return 4; // decoded [mycall ? ooo]
- }
-
- // attempt to decode [mycall srccall ?] msgs
- if (pcodec->apmsg_set[APTYPE_BOTHCALLS]) {
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_call2,
- pcodec->apmsg_call1_call2);
- if (rc>=0) return 5; // decoded [mycall srccall ?]
- }
-
- // attempt to decode [? hiscall ?/b] msgs
- if (pcodec->apmsg_set[APTYPE_HISCALL]) {
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call2,
- pcodec->apmsg_call2);
- if (rc>=0) return 6; // decoded [? hiscall ?]
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call2_ooo,
- pcodec->apmsg_call2);
- if (rc>=0) return 7; // decoded [? hiscall ooo]
- }
-
- // attempt to decode [cq/qrz hiscall ?/b/grid] msgs
- if (pcodec->apmsg_set[APTYPE_CQHISCALL]) {
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2,
- pcodec->apmsg_cq_call2);
- if (rc>=0) return 9; // decoded [cq/qrz hiscall ?]
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2_ooo,
- pcodec->apmsg_cq_call2_grid);
- if (rc>=0) {
- // Full AP mask need special handling
- // To minimize false decodes we check the decoded message
- // with what passed in the ap_set call
- if (memcmp(pcodec->apmsg_cq_call2_grid,xdec, QRA64_K*sizeof(int))!=0)
- return -1;
- else
- return 11; // decoded [cq/qrz hiscall grid]
- };
-
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2_ooo,
- pcodec->apmsg_cq_call2);
- if (rc>=0) {
- // Full AP mask need special handling
- // To minimize false decodes we check the decoded message
- // with what passed in the ap_set call
- if (memcmp(pcodec->apmsg_cq_call2,xdec, QRA64_K*sizeof(int))!=0)
- return -1;
- else
- return 10; // decoded [cq/qrz hiscall ]
- }
- }
-
- // attempt to decode [mycall hiscall grid]
- if (pcodec->apmsg_set[APTYPE_FULL]) {
- rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_call2_grid,
- pcodec->apmsg_call1_call2_grid);
- if (rc>=0) {
- // Full AP mask need special handling
- // All the three msg fields were given.
- // To minimize false decodes we check the decoded message
- // with what passed in the ap_set call
- if (memcmp(pcodec->apmsg_call1_call2_grid,xdec, QRA64_K*sizeof(int))!=0)
- return -1;
- else
- return 8; // decoded [mycall hiscall grid]
- }
- }
-
- // all decoding attempts failed
- return rc;
-}
-
-
-
-// Decode with given a-priori information
-static int qra64_do_decode(int *xdec, const float *pix, const int *ap_mask,
- const int *ap_x)
-{
- int rc;
- const float *ixsrc;
- float ix_masked[QRA64_NC*QRA64_M]; // Masked intrinsic information
- float ex[QRA64_NC*QRA64_M]; // Extrinsic information from the decoder
-
- float v2cmsg[QRA64_NMSG*QRA64_M]; // buffers for the decoder messages
- float c2vmsg[QRA64_NMSG*QRA64_M];
-
- if (ap_mask==NULL) { // no a-priori information
- ixsrc = pix; // intrinsic source is what passed as argument
- } else {
- // a-priori information provided
- // mask channel observations with a-priori
- ix_mask(ix_masked,pix,ap_mask,ap_x);
- ixsrc = ix_masked; // intrinsic source is the masked version
- }
-
- // run the decoding algorithm
- rc = qra_extrinsic(&QRA64_CODE,ex,ixsrc,QRA64_NITER,v2cmsg,c2vmsg);
- if (rc<0)
- return -1; // no convergence in given iterations
-
- // decode
- qra_mapdecode(&QRA64_CODE,xdec,ex,ixsrc);
-
- // verify crc
- if (calc_crc6(xdec,QRA64_K)!=xdec[QRA64_K]) // crc doesn't match (detected error)
- return -2; // decoding was succesfull but crc doesn't match
-
- return 0;
-}
-
-
-// crc functions --------------------------------------------------------------
-// crc-6 generator polynomial
-// g(x) = x^6 + a5*x^5 + ... + a1*x + a0
-
-// g(x) = x^6 + x + 1
-#define CRC6_GEN_POL 0x30 // MSB=a0 LSB=a5
-
-// g(x) = x^6 + x^2 + x + 1 (See: https://users.ece.cmu.edu/~koopman/crc/)
-// #define CRC6_GEN_POL 0x38 // MSB=a0 LSB=a5. Simulation results are similar
-
-static int calc_crc6(const int *x, int sz)
-{
- // todo: compute it faster using a look up table
- int k,j,t,sr = 0;
- for (k=0;k>1) ^ CRC6_GEN_POL;
- else
- sr = (sr>>1);
- t>>=1;
- }
- }
- return sr;
-}
-
-static void ix_mask(float *dst, const float *src, const int *mask,
- const int *x)
-{
- // mask intrinsic information (channel observations) with a priori knowledge
-
- int k,kk, smask;
- float *row;
-
- memcpy(dst,src,(QRA64_NC*QRA64_M)*sizeof(float));
-
- for (k=0;k>22)&0x3F;
- y[1]= (call1>>16)&0x3F;
- y[2]= (call1>>10)&0x3F;
- y[3]= (call1>>4)&0x3F;
- y[4]= (call1<<2)&0x3F;
-
- y[4] |= (call2>>26)&0x3F;
- y[5]= (call2>>20)&0x3F;
- y[6]= (call2>>14)&0x3F;
- y[7]= (call2>>8)&0x3F;
- y[8]= (call2>>2)&0x3F;
- y[9]= (call2<<4)&0x3F;
-
- y[9] |= (grid>>12)&0x3F;
- y[10]= (grid>>6)&0x3F;
- y[11]= (grid)&0x3F;
-
-}
-void decodemsg_jt65(int *call1, int *call2, int *grid, const int *x)
-{
- int nc1, nc2, ng;
-
- nc1 = x[4]>>2;
- nc1 |= x[3]<<4;
- nc1 |= x[2]<<10;
- nc1 |= x[1]<<16;
- nc1 |= x[0]<<22;
-
- nc2 = x[9]>>4;
- nc2 |= x[8]<<2;
- nc2 |= x[7]<<8;
- nc2 |= x[6]<<14;
- nc2 |= x[5]<<20;
- nc2 |= (x[4]&0x03)<<26;
-
- ng = x[11];
- ng |= x[10]<<6;
- ng |= (x[9]&0x0F)<<12;
-
- *call1 = nc1;
- *call2 = nc2;
- *grid = ng;
-}
diff --git a/lib/qra/qra64/qra64_subs.c b/lib/qra/qra64/qra64_subs.c
deleted file mode 100644
index b60f9fa..0000000
--- a/lib/qra/qra64/qra64_subs.c
+++ /dev/null
@@ -1,65 +0,0 @@
-// qra64_subs.c
-// Fortran interface routines for QRA64
-
-#include "qra64.h"
-#include
-
-static qra64codec *pqra64codec = NULL;
-
-void qra64_enc_(int x[], int y[])
-{
- if (pqra64codec==NULL) pqra64codec = qra64_init(QRA_USERAP);
- qra64_encode(pqra64codec, y, x);
-}
-
-void qra64_dec_(float r[], int* nc1, int* nc2, int* ng2, int* APtype,
- int* iset, int* ns0, float* b0, int* nf0,
- int xdec[], float* snr, int* rc)
-{
-/*
- APtype: AP
------------------------------------------------------------------------
- -1 0 (no AP information)
- 0 [CQ/QRZ ? ? ] 25/37
- 1 [MyCall ? ? ] 25/37
- 2 [ ? HisCall ? ] 25/37
- 3 [MyCall HisCall ? ] 49/68
- 4 [MyCall HisCall grid] 68
- 5 [CQ/QRZ HisCall ? ] 49/68
-
- rc Message format AP APTYPE Comments
-------------------------------------------------------------------------
- -16 Failed sanity check
- -2 Decoded but CRC failed
- -1 No decode
- 0 [ ? ? ? ] 0 -1 Decode with no AP info
- 1 [CQ/QRZ ? ? ] 25 0
- 2 [CQ/QRZ ? _ ] 37 0
- 3 [MyCall ? ? ] 25 1
- 4 [MyCall ? _ ] 37 1
- 5 [MyCall HisCall ? ] 49 3
- 6 [ ? HisCall ? ] 25 2 Optional
- 7 [ ? HisCall _ ] 37 2 Optional
- 8 [MyCall HisCall Grid] 68 4
- 9 [CQ/QRZ HisCall ? ] 49 5 Optional (not needed?)
- 10 [CQ/QRZ HisCall _ ] 68 5 Optional
- 11 [CQ/QRZ HisCall Grid] 68 ? Optional
-*/
-
- float EbNodBEstimated;
- int err=0;
- int nSubmode=*ns0;
- float b90=*b0;
- int nFadingModel=*nf0;
-
- if(pqra64codec==NULL) pqra64codec = qra64_init(QRA_USERAP);
- err=qra64_apset(pqra64codec,*nc1,*nc2,*ng2,*APtype);
- if(err<0) printf("ERROR: qra64_apset returned %d\n",err);
-
- if(*iset==0) {
- *rc = qra64_decode_fastfading(pqra64codec,&EbNodBEstimated,xdec,r,
- nSubmode,b90,nFadingModel);
- *snr = EbNodBEstimated - 31.0;
- }
-}
-
diff --git a/lib/qra/qra64/qra64example.txt b/lib/qra/qra64/qra64example.txt
deleted file mode 100644
index 3add33d..0000000
--- a/lib/qra/qra64/qra64example.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-$ qra64_nico -h
-
-QRA64 Mode Tests
-2016, Nico Palermo - IV3NWV
-
----------------------------
-
-Syntax: qra64 [-s] [-c] [-a] [-t] [-h]
-Options:
- -s : set simulation SNR in 2500 Hz BW (default:-27.5 dB)
- -c : set channel type 0=AWGN (default) 1=Rayleigh
- -a : set decode type 0=NOAP 1=AUTOAP (default) 2=USERAP
- -t: 0=simulate seq of msgs between IV3NWV and K1JT (default)
- 1=simulate K1JT receiving K1JT IV3NWV JN66
- 2=simulate fast-fading routines (option -c ignored)
-Options used only for fast-fading simulations:
- -b : 90% fading bandwidth in Hz [1..230 Hz] (default = 2.5 Hz)
- -m : fading model. 0=Gauss, 1=Lorentz (default = Lorentz)
- -q : qra64 submode. 0=QRA64A,... 4=QRA64E (default = QRA64A)
- -h: this help
-
-
-#############################################################################
-Usage example:
-
-qra64 -c2 -t2 -a2 -b50 -m1 -q2 -s-26.0 -n50000
-
-Simulate a fast-fading channel (-c2)
-Evaluate decoder performance (-t2) with
-USER_AP (-a2)
-B90 = 50 Hz (-b50)
-Lorentz model (-m1)
-submode QRA64C (-q2)
-Input SNR = -26.0 dB (-s-26.0)
-Simulate 50000 transmissions (-n50000)
-
-(type qra64 -h for command syntax)
-
-Command Output:
-
-Input SNR = -26.0dB ap-mode=USER AP
-
-Simulating the fast-fading channel
-B90=50.00 Hz - Fading Model=Lorentz - Submode=QRA64C
-Decoder metric = Matched to fast-fading signal
-
-Encoding msg [K1JT IV3NWV JN66]
-50000 transmissions will be simulated
-
-K1JT decoder enabled for [CQ ? ?/blank]
-K1JT decoder enabled for [K1JT ? ?/blank]
-K1JT decoder enabled for [? IV3NWV ?/blank]
-K1JT decoder enabled for [K1JT IV3NWV ?]
-K1JT decoder enabled for [K1JT IV3NWV JN66]
-K1JT decoder enabled for [CQ IV3NWV ?/b/JN66]
-
-Now decoding with K1JT's decoder...
- 5.5 %
-Undetected error with rc=6
- 13.1 %
-Undetected error with rc=7
- 70.8 %
-Undetected error with rc=1
- 75.8 %
-Undetected error with rc=9
- 88.9 %
-Undetected error with rc=6
- 100.0 %
-
-Msgs transmitted:50000
-Msg decoded:
-
-rc= 0 0 with [? ? ?] AP0
-rc= 1 0 with [CQ ? ?] AP27
-rc= 2 0 with [CQ ? ] AP42
-rc= 3 145 with [CALL ? ?] AP29
-rc= 4 0 with [CALL ? ] AP44
-rc= 5 12085 with [CALL CALL ?] AP57
-rc= 6 0 with [? CALL ?] AP29
-rc= 7 0 with [? CALL ] AP44
-rc= 8 24307 with [CALL CALL G] AP72
-rc= 9 0 with [CQ CALL ?] AP55
-rc=10 0 with [CQ CALL ] AP70
-rc=11 0 with [CQ CALL G] AP70
-
-Total: 36537/50000 (5 undetected errors)
-
-Estimated SNR (average in dB) = -26.26 dB
diff --git a/lib/qra/qra64/qra64sim.f90 b/lib/qra/qra64/qra64sim.f90
deleted file mode 100644
index b7ca2e1..0000000
--- a/lib/qra/qra64/qra64sim.f90
+++ /dev/null
@@ -1,170 +0,0 @@
-program qra64sim
-
-! Generate simulated QRA64 data for testing the decoder.
-
- use wavhdr
- use packjt
- parameter (NMAX=54*12000) ! = 648,000
- parameter (NFFT=10*65536,NH=NFFT/2)
- type(hdr) h !Header for .wav file
- integer*2 iwave(NMAX) !Generated waveform
- integer*4 itone(84) !Channel symbols (values 0-63)
- real*4 xnoise(NMAX) !Generated random noise
- real*4 dat(NMAX) !Generated real data
- complex cdat(NMAX) !Generated complex waveform
- complex cspread(0:NFFT-1) !Complex amplitude for Rayleigh fading
- complex z
- real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq
- character msg*22,fname*11,csubmode*1,arg*12
- character msgsent*22
-
- nargs=iargc()
- if(nargs.ne. 7) then
- print *, 'Usage: qra64sim "msg" A-E Nsigs fDop DT Nfiles SNR'
- print *, 'Example qra64sim "K1ABC W9XYZ EN37" A 10 0.2 0.0 1 0'
- go to 999
- endif
- call getarg(1,msg)
- call getarg(2,csubmode)
- mode64=2**(ichar(csubmode)-ichar('A'))
- call getarg(3,arg)
- read(arg,*) nsigs
- call getarg(4,arg)
- read(arg,*) fspread
- call getarg(5,arg)
- read(arg,*) xdt
- call getarg(6,arg)
- read(arg,*) nfiles
- call getarg(7,arg)
- read(arg,*) snrdb
-
- if(mode64.ge.8) nsigs=1
- rms=100.
- fsample=12000.d0 !Sample rate (Hz)
- dt=1.d0/fsample !Sample interval (s)
- twopi=8.d0*atan(1.d0)
- npts=54*12000 !Total samples in .wav file
- nsps=6912
- baud=12000.d0/nsps !Keying rate = 1.7361111111
- nsym=84 !Number of channel symbols
- h=default_header(12000,npts)
- dfsig=2000.0/nsigs !Freq spacing between sigs in file (Hz)
- ichk=0
-
- write(*,1000)
-1000 format('File Sig Freq A-E S/N DT Dop Message'/60('-'))
-
- do ifile=1,nfiles !Loop over requested number of files
- write(fname,1002) ifile !Output filename
-1002 format('000000_',i4.4)
- open(10,file=fname//'.wav',access='stream',status='unknown')
- xnoise=0.
- cdat=0.
- if(snrdb.lt.90) then
- do i=1,npts
- xnoise(i)=gran() !Generate gaussian noise
- enddo
- endif
-
- do isig=1,nsigs !Generate requested number of sigs
- if(mod(nsigs,2).eq.0) f0=1500.0 + dfsig*(isig-0.5-nsigs/2)
- if(mod(nsigs,2).eq.1) f0=1500.0 + dfsig*(isig-(nsigs+1)/2)
- if(nsigs.eq.1) f0=1000.0
- xsnr=snrdb
- if(snrdb.eq.0.0) xsnr=-20 - isig
-
- call genqra64(msg,ichk,msgsent,itone,itype)
-
- bandwidth_ratio=2500.0/6000.0
- sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*xsnr)
- if(xsnr.gt.90.0) sig=1.0
- write(*,1020) ifile,isig,f0,csubmode,xsnr,xdt,fspread,msg
-1020 format(i4,i4,f10.3,2x,a1,2x,f5.1,f6.2,f6.1,1x,a22)
-
- phi=0.d0
- dphi=0.d0
- k=(xdt+1.0)*12000 !Start audio at t = xdt + 1.0 s
- isym0=-99
- do i=1,npts !Add this signal into cdat()
- isym=i/nsps + 1
- if(isym.gt.nsym) exit
- if(isym.ne.isym0) then
- freq=f0 + itone(isym)*baud*mode64
- dphi=twopi*freq*dt
- isym0=isym
- endif
- phi=phi + dphi
- if(phi.gt.twopi) phi=phi-twopi
- xphi=phi
- z=cmplx(cos(xphi),sin(xphi))
- k=k+1
- if(k.ge.1) cdat(k)=cdat(k) + sig*z
- enddo
- enddo
-
- if(fspread.ne.0) then !Apply specified Doppler spread
- df=12000.0/nfft
- twopi=8*atan(1.0)
- cspread(0)=1.0
- cspread(NH)=0.
- b=6.0 !Lorenzian 3/28 onward
- do i=1,NH
- f=i*df
- x=b*f/fspread
- z=0.
- a=0.
- if(x.lt.3.0) then !Cutoff beyond x=3
- a=sqrt(1.111/(1.0+x*x)-0.1) !Lorentzian
- call random_number(r1)
- phi1=twopi*r1
- z=a*cmplx(cos(phi1),sin(phi1))
- endif
- cspread(i)=z
- z=0.
- if(x.lt.50.0) then
- call random_number(r2)
- phi2=twopi*r2
- z=a*cmplx(cos(phi2),sin(phi2))
- endif
- cspread(NFFT-i)=z
- enddo
-
- do i=0,NFFT-1
- f=i*df
- if(i.gt.NH) f=(i-nfft)*df
- s=real(cspread(i))**2 + aimag(cspread(i))**2
-! write(13,3000) i,f,s,cspread(i)
-!3000 format(i5,f10.3,3f12.6)
- enddo
-! s=real(cspread(0))**2 + aimag(cspread(0))**2
-! write(13,3000) 1024,0.0,s,cspread(0)
-
- call four2a(cspread,NFFT,1,1,1) !Transform to time domain
-
- sum=0.
- do i=0,NFFT-1
- p=real(cspread(i))**2 + aimag(cspread(i))**2
- sum=sum+p
- enddo
- avep=sum/NFFT
- fac=sqrt(1.0/avep)
- cspread=fac*cspread !Normalize to constant avg power
- cdat=cspread(1:npts)*cdat !Apply Rayleigh fading
-
-! do i=0,NFFT-1
-! p=real(cspread(i))**2 + aimag(cspread(i))**2
-! write(14,3010) i,p,cspread(i)
-!3010 format(i8,3f12.6)
-! enddo
-
- endif
-
- dat=aimag(cdat) + xnoise !Add the generated noise
- fac=32767.0/nsigs
- if(snrdb.ge.90.0) iwave(1:npts)=nint(fac*dat(1:npts))
- if(snrdb.lt.90.0) iwave(1:npts)=nint(rms*dat(1:npts))
- write(10) h,iwave(1:npts) !Save the .wav file
- close(10)
- enddo
-
-999 end program qra64sim
diff --git a/lib/qra/qracodes/Makefile.Win b/lib/qra/qracodes/Makefile.Win
deleted file mode 100644
index fb30504..0000000
--- a/lib/qra/qracodes/Makefile.Win
+++ /dev/null
@@ -1,33 +0,0 @@
-CC = gcc
-CFLAGS = -O2 -Wall -I. -D_WIN32
-
-# Default rules
-%.o: %.c
- ${CC} ${CFLAGS} -c $<
-%.o: %.f
- ${FC} ${FFLAGS} -c $<
-%.o: %.F
- ${FC} ${FFLAGS} -c $<
-%.o: %.f90
- ${FC} ${FFLAGS} -c $<
-%.o: %.F90
- ${FC} ${FFLAGS} -c $<
-
-all: libqra64.a qracodes.exe
-
-OBJS1 = normrnd.o npfwht.o pdmath.o qra12_63_64_irr_b.o \
- qra13_64_64_irr_e.o qracodes.o
-
-libqra64.a: $(OBJS1)
- ar cr libqra64.a $(OBJS1)
- ranlib libqra64.a
-
-OBJS2 = main.o
-
-qracodes.exe: $(OBJS2)
- ${CC} -o qracodes.exe $(OBJS2) libqra64.a -lm
-
-.PHONY : clean
-
-clean:
- $(RM) *.o libqra64.a qracodes.exe
diff --git a/lib/qra/qracodes/ebno10000.txt b/lib/qra/qracodes/ebno10000.txt
deleted file mode 100644
index c41174b..0000000
--- a/lib/qra/qracodes/ebno10000.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Eb/No Values to be used during the code simulation
-# Each line of this file indicates the Eb/No value to be simulated (in dB)
-# and the number of errors to be detected by the decoder
-0.6 10000
-1.1 10000
-1.6 10000
-2.1 10000
diff --git a/lib/qra/qracodes/ebnovalues.txt b/lib/qra/qracodes/ebnovalues.txt
deleted file mode 100644
index 7dba138..0000000
--- a/lib/qra/qracodes/ebnovalues.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-# Eb/No Values to be used during the code simulation
-# Each line of this file indicates the Eb/No value to be simulated (in dB)
-# and the number of errors to be detected by the decoder
-1.1 1000
-1.6 1000
-2.1 1000
-2.6 1000
-3.1 1000
-3.6 1000
-4.1 1000
-4.6 1000
-5.1 500
-5.6 200
-6.1 100
-6.6 50
\ No newline at end of file
diff --git a/lib/qra/qracodes/ebnovaluesfast.txt b/lib/qra/qracodes/ebnovaluesfast.txt
deleted file mode 100644
index b057b31..0000000
--- a/lib/qra/qracodes/ebnovaluesfast.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-# Eb/No Values to be used during the code simulation
-# Each line of this file indicates the Eb/No value to be simulated (in dB)
-# and the number of errors to be detected by the decoder
-1.1 500
-1.6 500
-2.1 500
-2.6 500
-3.1 500
-3.6 500
-4.1 200
-4.6 50
diff --git a/lib/qra/qracodes/main.c b/lib/qra/qracodes/main.c
deleted file mode 100644
index 5f9f067..0000000
--- a/lib/qra/qracodes/main.c
+++ /dev/null
@@ -1,737 +0,0 @@
-// main.c
-// Word Error Rate test example for Q-ary RA codes over GF(64)
-//
-// (c) 2016 - Nico Palermo, IV3NWV
-//
-// Thanks to Andrea Montefusco IW0HDV for his help on adapting the sources
-// to OSs other than MS Windows
-//
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// Files in this package:
-// main.c - this file
-// normrnd.c/.h - random gaussian number generator
-// npfwht.c/.h - Fast Walsh-Hadamard Transforms
-// pdmath.c/.h - Elementary math on probability distributions
-// qra12_63_64_irr_b.c/.h - Tables for a QRA(12,63) irregular RA code over GF(64)
-// qra13_64_64_irr_e.c/.h - Tables for a QRA(13,64) irregular RA code " "
-// qracodes.c/.h - QRA codes encoding/decoding functions
-//
-// -------------------------------------------------------------------------------
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-// -----------------------------------------------------------------------------
-
-// Two codes are available for simulations in this sowftware release:
-
-// QRA12_63_64_IRR_B: K=12 N=63 Q=64 irregular QRA code (defined in qra12_63_64_irr_b.h /.c)
-// QRA13_64_64_IRR_E: K=13 N=64 Q=64 irregular QRA code (defined in qra13_64_64_irr_b.h /.c)
-
-// Codes with K=13 are designed to include a CRC as the 13th information symbol
-// and improve the code UER (Undetected Error Rate).
-// The CRC symbol is not sent along the channel (the codes are punctured) and the
-// resulting code is still a (12,63) code with an effective code rate of R = 12/63.
-
-// ------------------------------------------------------------------------------
-
-// OS dependent defines and includes --------------------------------------------
-
-#if _WIN32 // note the underscore: without it, it's not msdn official!
- // Windows (x64 and x86)
- #include // required only for GetTickCount(...)
- #include // _beginthread
-#endif
-
-#if defined(__linux__)
-
-// remove unwanted macros
-#define __cdecl
-
-// implements Windows API
-#include
-
- unsigned int GetTickCount(void) {
- struct timespec ts;
- unsigned int theTick = 0U;
- clock_gettime( CLOCK_REALTIME, &ts );
- theTick = ts.tv_nsec / 1000000;
- theTick += ts.tv_sec * 1000;
- return theTick;
-}
-
-// Convert Windows millisecond sleep
-//
-// VOID WINAPI Sleep(_In_ DWORD dwMilliseconds);
-//
-// to Posix usleep (in microseconds)
-//
-// int usleep(useconds_t usec);
-//
-#include
-#define Sleep(x) usleep(x*1000)
-
-#endif
-
-#if defined(__linux__) || ( defined(__MINGW32__) || defined (__MIGW64__) )
-#include
-#endif
-
-#if __APPLE__
-#endif
-
-#include
-#include
-
-#include "qracodes.h"
-#include "normrnd.h" // gaussian numbers generator
-#include "pdmath.h" // operations on probability distributions
-
-// defined codes
-#include "qra12_63_64_irr_b.h"
-#include "qra13_64_64_irr_e.h"
-
-// -----------------------------------------------------------------------------------
-
-#define NTHREADS_MAX 160
-
-// channel types
-#define CHANNEL_AWGN 0
-#define CHANNEL_RAYLEIGH 1
-
-// amount of a-priori information provided to the decoder
-#define AP_NONE 0
-#define AP_28 1
-#define AP_44 2
-#define AP_56 3
-
-const char ap_str[4][16] = {
- "None",
- "28 bit",
- "44 bit",
- "56 bit"
-};
-
-const char fnameout_pfx[2][64] = {
- "wer-awgn-",
- "wer-rayleigh-"
-};
-const char fnameout_sfx[4][64] = {
- "-ap00.txt",
- "-ap28.txt",
- "-ap44.txt",
- "-ap56.txt"
-};
-
-const int ap_masks_jt65[4][13] = {
-// Each row must be 13 entries long (to handle puntc. codes 13,64)
-// The mask of 13th symbol (crc) is alway initializated to 0
- // AP0 - no a-priori knowledge
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- // AP28 - 1st field known [cq ? ?] or [dst ? ?]
- {0x3F,0x3F,0x3F,0x3F,0x3C, 0, 0, 0, 0, 0, 0, 0},
- // AP44 - 1st and 3rd fields known [cq ? 0] or [dst ? 0]
- {0x3F,0x3F,0x3F,0x3F,0x3C, 0, 0, 0, 0,0x0F,0x3F,0x3F},
- // AP56 - 1st and 2nd fields known [dst src ?]
- {0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x30, 0, 0}
-};
-
-void ix_mask(const qracode *pcode, float *r, const int *mask, const int *x);
-
-void printword(char *msg, int *x, int size)
-{
- int k;
- printf("\n%s ",msg);
- for (k=0;kc msg buffer
- float *qra_c2vmsg; //[qra_NMSG*qra_M]; MP decoder c->v msg buffer
- float *rp; // [qra_N*qra_M]; received samples (real component) buffer
- float *rq; // [qra_N*qra_M]; received samples (imag component) buffer
- float *chp; //[qra_N]; channel gains (real component) buffer
- float *chq; //[qra_N]; channel gains (imag component) buffer
- float *r; //[qra_N*qra_M]; received samples (amplitude) buffer
- float *ix; // [qra_N*qra_M]; // intrinsic information to the MP algorithm
- float *ex; // [qra_N*qra_M]; // extrinsic information from the MP algorithm
-
-} wer_test_ds;
-
-typedef void( __cdecl *pwer_test_thread)(wer_test_ds*);
-
-// crc-6 generator polynomial
-// g(x) = x^6 + a5*x^5 + ... + a1*x + a0
-
-// g(x) = x^6 + x + 1
-#define CRC6_GEN_POL 0x30 // MSB=a0 LSB=a5
-
-// g(x) = x^6 + x^2 + x + 1 (as suggested by Joe. See: https://users.ece.cmu.edu/~koopman/crc/)
-// #define CRC6_GEN_POL 0x38 // MSB=a0 LSB=a5. Simulation results are similar
-
-int calc_crc6(int *x, int sz)
-{
- int k,j,t,sr = 0;
- for (k=0;k>1) ^ CRC6_GEN_POL;
- else
- sr = (sr>>1);
- t>>=1;
- }
- }
- return sr;
-}
-
-void wer_test_thread(wer_test_ds *pdata)
-{
- const qracode *pcode=pdata->pcode;
- const int qra_K = pcode->K;
- const int qra_N = pcode->N;
- const int qra_M = pcode->M;
- const int qra_m = pcode->m;
- const int NSAMPLES = pcode->N*pcode->M;
-
- const float No = 1.0f; // noise spectral density
- const float sigma = (float)sqrt(No/2.0f); // std dev of noise I/Q components
- const float sigmach = (float)sqrt(1/2.0f); // std dev of channel I/Q gains
-
- // Eb/No value for which we optimize the bessel metric
- const float EbNodBMetric = 2.8f;
- const float EbNoMetric = (float)pow(10,EbNodBMetric/10);
-
- int k,t,j,diff;
- float R;
- float EsNoMetric;
- float EbNo, EsNo, Es, A;
- int channel_type, code_type;
- int nt=0; // transmitted codewords
- int nerrs = 0; // total number of errors
- int nerrsu = 0; // number of undetected errors
- int rc;
-
-
- // inizialize pointer to required buffers
- int *x=pdata->x; // message buffer
- int *y=pdata->y, *ydec=pdata->ydec; // encoded/decoded codeword buffers
- float *qra_v2cmsg=pdata->qra_v2cmsg; // table of the v->c messages
- float *qra_c2vmsg=pdata->qra_c2vmsg; // table of the c->v messages
- float *rp=pdata->rp; // received samples (real component)
- float *rq=pdata->rq; // received samples (imag component)
- float *chp=pdata->chp; // channel gains (real component)
- float *chq=pdata->chq; // channel gains (imag component)
- float *r=pdata->r; // received samples amplitudes
- float *ix=pdata->ix; // intrinsic information to the MP algorithm
- float *ex=pdata->ex; // extrinsic information from the MP algorithm
-
- channel_type = pdata->channel_type;
- code_type = pcode->type;
-
- // define the (true) code rate accordingly to the code type
- switch(code_type) {
- case QRATYPE_CRC:
- R = 1.0f*(qra_K-1)/qra_N;
- break;
- case QRATYPE_CRCPUNCTURED:
- R = 1.0f*(qra_K-1)/(qra_N-1);
- break;
- case QRATYPE_NORMAL:
- default:
- R = 1.0f*(qra_K)/(qra_N);
- }
-
- EsNoMetric = 1.0f*qra_m*R*EbNoMetric;
-
- EbNo = (float)pow(10,pdata->EbNodB/10);
- EsNo = 1.0f*qra_m*R*EbNo;
- Es = EsNo*No;
- A = (float)sqrt(Es);
-
-
- // encode the input
- if (code_type==QRATYPE_CRC || code_type==QRATYPE_CRCPUNCTURED) {
- // compute the information message symbol check as the (negated) xor of all the
- // information message symbols
- for (k=0;k<(qra_K-1);k++)
- x[k]=k%qra_M;
- x[k]=calc_crc6(x,qra_K-1);
- }
- else
- for (k=0;kstop==0) {
-
- // simulate the channel
- // NOTE: in the case that the code is punctured, for simplicity
- // we compute the channel outputs and the metric also for the crc symbol
- // then we ignore its observation.
- normrnd_s(rp,NSAMPLES,0,sigma);
- normrnd_s(rq,NSAMPLES,0,sigma);
-
- if (channel_type == CHANNEL_AWGN) {
- for (k=0;kdone = 1;
- return; // unknown channel type
- }
-
- // compute the squares of the amplitudes of the received samples
- for (k=0;km,pcode->N,EsNoMetric);
-
- if (code_type==QRATYPE_CRCPUNCTURED) {
- // ignore observations of the CRC symbol as it is not actually sent
- // over the channel
- pd_init(PD_ROWADDR(ix,qra_M,qra_K),pd_uniform(qra_m),qra_M);
- }
-
-
- if (pdata->ap_index!=0)
- // mask channel observations with a priori knowledge
- ix_mask(pcode,ix,ap_masks_jt65[pdata->ap_index],x);
-
-
- // compute the extrinsic symbols probabilities with the message-passing algorithm
- // stop if extrinsic information does not converges to 1 within the given number of iterations
- rc = qra_extrinsic(pcode,ex,ix,100,qra_v2cmsg,qra_c2vmsg);
-
- if (rc>=0) { // the MP algorithm converged to Iex~1 in rc iterations
-
- // decode the codeword
- qra_mapdecode(pcode,ydec,ex,ix);
-
- // look for undetected errors
- if (code_type==QRATYPE_CRC || code_type==QRATYPE_CRCPUNCTURED) {
-
- j = 0; diff = 0;
- for (k=0;k<(qra_K-1);k++)
- diff |= (ydec[k]!=x[k]);
- t = calc_crc6(ydec,qra_K-1);
- if (t!=ydec[k]) // error detected - crc doesn't matches
- nerrs += 1;
- else
- if (diff) { // decoded message is not equal to the transmitted one but
- // the crc test passed
- // add as undetected error
- nerrsu += 1;
- nerrs += 1;
- // uncomment to see what the undetected error pattern looks like
- //printword("U", ydec);
- }
- }
- else
- for (k=0;knt=nt;
- pdata->nerrs=nerrs;
- pdata->nerrsu=nerrsu;
-
- }
-
- pdata->done=1;
-
- #if _WIN32
- _endthread();
- #endif
-}
-
-#if defined(__linux__) || ( defined(__MINGW32__) || defined (__MIGW64__) )
-
-void *wer_test_pthread(void *p)
-{
- wer_test_thread ((wer_test_ds *)p);
- return 0;
-}
-
-#endif
-
-void ix_mask(const qracode *pcode, float *r, const int *mask, const int *x)
-{
- // mask intrinsic information (channel observations) with a priori knowledge
-
- int k,kk, smask;
- const int qra_K=pcode->K;
- const int qra_M=pcode->M;
- const int qra_m=pcode->m;
-
- for (k=0;kNTHREADS_MAX) {
- printf("Error: nthreads should be <=%d\n",NTHREADS_MAX);
- return -1;
- }
-
- sprintf(fnameout,"%s%s%s",
- fnameout_pfx[chtype],
- pcode->name,
- fnameout_sfx[ap_index]);
-
- fout = fopen(fnameout,"w");
- fprintf(fout,"# Channel (0=AWGN,1=Rayleigh), Eb/No (dB), Transmitted codewords, Errors, Undetected Errors, Avg dec. time (ms), WER\n");
-
- printf("\nTesting the code %s over the %s channel\nSimulation data will be saved to %s\n",
- pcode->name,
- chtype==CHANNEL_AWGN?"AWGN":"Rayleigh",
- fnameout);
- fflush (stdout);
-
- // init fixed thread parameters and preallocate buffers
- for (j=0;jK*sizeof(int));
- wt[j].y = (int*)malloc(pcode->N*sizeof(int));
- wt[j].ydec = (int*)malloc(pcode->N*sizeof(int));
- wt[j].qra_v2cmsg = (float*)malloc(pcode->NMSG*pcode->M*sizeof(float));
- wt[j].qra_c2vmsg = (float*)malloc(pcode->NMSG*pcode->M*sizeof(float));
- wt[j].rp = (float*)malloc(pcode->N*pcode->M*sizeof(float));
- wt[j].rq = (float*)malloc(pcode->N*pcode->M*sizeof(float));
- wt[j].chp = (float*)malloc(pcode->N*sizeof(float));
- wt[j].chq = (float*)malloc(pcode->N*sizeof(float));
- wt[j].r = (float*)malloc(pcode->N*pcode->M*sizeof(float));
- wt[j].ix = (float*)malloc(pcode->N*pcode->M*sizeof(float));
- wt[j].ex = (float*)malloc(pcode->N*pcode->M*sizeof(float));
- }
-
-
- for (k=0;k=nerrstgt[k]) {
- for (j=0;j] [-t] [-c] [-a] [-f[-h]\n");
- printf("Options: \n");
- printf(" -q: code to simulate. 0=qra_12_63_64_irr_b\n");
- printf(" 1=qra_13_64_64_irr_e (default)\n");
- printf(" -t : number of threads to be used for the simulation [1..24]\n");
- printf(" (default=8)\n");
- printf(" -c : channel_type. 0=AWGN 1=Rayleigh \n");
- printf(" (default=AWGN)\n");
- printf(" -a : amount of a-priori information provided to decoder. \n");
- printf(" 0= No a-priori (default)\n");
- printf(" 1= 28 bit \n");
- printf(" 2= 44 bit \n");
- printf(" 3= 56 bit \n");
- printf(" -f : name of the file containing the Eb/No values to be simulated\n");
- printf(" (default=ebnovalues.txt)\n");
- printf(" This file should contain lines in this format:\n");
- printf(" # Eb/No(dB) Target Errors\n");
- printf(" 0.1 5000\n");
- printf(" 0.6 5000\n");
- printf(" 1.1 1000\n");
- printf(" 1.6 1000\n");
- printf(" ...\n");
- printf(" (lines beginning with a # are treated as comments\n\n");
-}
-
-#define SIM_POINTS_MAX 20
-
-int main(int argc, char* argv[])
-{
-
- float EbNodB[SIM_POINTS_MAX];
- int nerrstgt[SIM_POINTS_MAX];
- FILE *fin;
-
- char fnamein[128]= "ebnovalues.txt";
- char buf[128];
-
- int nitems = 0;
- int code_idx = 1;
- int nthreads = 8;
- int ch_type = CHANNEL_AWGN;
- int ap_index = AP_NONE;
-
- // parse command line
- while(--argc) {
- argv++;
- if (strncmp(*argv,"-h",2)==0) {
- syntax();
- return 0;
- }
- else
- if (strncmp(*argv,"-q",2)==0) {
- code_idx = (int)atoi((*argv)+2);
- if (code_idx>1) {
- printf("Invalid code index\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-t",2)==0) {
- nthreads = (int)atoi((*argv)+2);
- printf("nthreads = %d\n",nthreads);
- if (nthreads>NTHREADS_MAX) {
- printf("Invalid number of threads\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-c",2)==0) {
- ch_type = (int)atoi((*argv)+2);
- if (ch_type>CHANNEL_RAYLEIGH) {
- printf("Invalid channel type\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-a",2)==0) {
- ap_index = (int)atoi((*argv)+2);
- if (ap_index>AP_56) {
- printf("Invalid a-priori information index\n");
- syntax();
- return -1;
- }
- }
- else
- if (strncmp(*argv,"-f",2)==0) {
- strncpy(fnamein,(*argv)+2,127);
- }
- else
- if (strncmp(*argv,"-h",2)==0) {
- syntax();
- return -1;
- }
- else {
- printf("Invalid option\n");
- syntax();
- return -1;
- }
- }
-
- // parse points to be simulated from the input file
- fin = fopen(fnamein,"r");
- if (!fin) {
- printf("Can't open file: %s\n",fnamein);
- syntax();
- }
-
- while (fgets(buf,128,fin)!=0)
- if (*buf=='#' || *buf=='\n' )
- continue;
- else
- if (nitems==SIM_POINTS_MAX)
- break;
- else
- if (sscanf(buf,"%f %u",&EbNodB[nitems],&nerrstgt[nitems])!=2) {
- printf("Invalid input file format\n");
- syntax();
- return -1;
- }
- else
- nitems++;
-
- fclose(fin);
-
- if (nitems==0) {
- printf("No Eb/No point specified in file %s\n",fnamein);
- syntax();
- return -1;
- }
-
- printf("\nQ-ary Repeat-Accumulate Code Word Error Rate Simulator\n");
- printf("2016, Nico Palermo - IV3NWV\n\n");
-
- printf("Nthreads = %d\n",nthreads);
- printf("Channel = %s\n",ch_type==CHANNEL_AWGN?"AWGN":"Rayleigh");
- printf("Codename = %s\n",codetotest[code_idx]->name);
- printf("A-priori = %s\n",ap_str[ap_index]);
- printf("Eb/No input file = %s\n\n",fnamein);
-
- wer_test_proc(codetotest[code_idx], nthreads, ch_type, ap_index, EbNodB, nerrstgt, nitems);
-
- return 0;
-}
-
diff --git a/lib/qra/qracodes/normrnd.c b/lib/qra/qracodes/normrnd.c
deleted file mode 100644
index 90abfa4..0000000
--- a/lib/qra/qracodes/normrnd.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// normrnd.c
-// functions to generate gaussian distributed numbers
-//
-// (c) 2016 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
-//
-// Credits to Andrea Montefusco - IW0HDV for his help on adapting the sources
-// to OSs other than MS Windows
-//
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-
-#include "normrnd.h"
-
-#if _WIN32 // note the underscore: without it, it's not msdn official!
- // Windows (x64 and x86)
- #include // required only for GetTickCount(...)
- #define K_RAND_MAX UINT_MAX
-#elif _SVID_SOURCE || _XOPEN_SOURCE || __unix__ || (defined (__APPLE__) && defined(__MACH__)) /* POSIX or Unix or Apple */
- #include
- #define rand_s(x) (*x)=(unsigned int)lrand48() // returns unsigned integers in the range 0..0x7FFFFFFF
- #define K_RAND_MAX 0x7FFFFFFF // that's the max number
- // generated by lrand48
-#else
- #error "No good quality PRNG found"
-#endif
-
-
-// use MS rand_s(...) function
-void normrnd_s(float *dst, int nitems, float mean, float stdev)
-{
- unsigned int r;
- float phi=0, u=0;
- int set = 0;
-
- while (nitems--)
- if (set==1) {
- *dst++ = (float)sin(phi)*u*stdev+mean;
- set = 0;
- }
- else {
- rand_s((unsigned int*)&r); phi = (M_2PI/(1.0f+K_RAND_MAX))*r;
- rand_s((unsigned int*)&r); u = (float)sqrt(-2.0f* log( (1.0f/(1.0f+K_RAND_MAX))*(1.0f+r) ) );
- *dst++ = (float)cos(phi)*u*stdev+mean;
- set=1;
- }
-}
-
-/* NOT USED
-// use MS rand() function
-void normrnd(float *dst, int nitems, float mean, float stdev)
-{
- float phi=0, u=0;
- int set = 0;
-
- while (nitems--)
- if (set==1) {
- *dst++ = (float)sin(phi)*u*stdev+mean;
- set = 0;
- }
- else {
- phi = (M_2PI/(1.0f+RAND_MAX))*rand();
- u = (float)sqrt(-2.0f* log( (1.0f/(1.0f+RAND_MAX))*(1.0f+rand()) ) );
- *dst++ = (float)cos(phi)*u*stdev+mean;
- set=1;
- }
-}
-*/
diff --git a/lib/qra/qracodes/normrnd.h b/lib/qra/qracodes/normrnd.h
deleted file mode 100644
index dd4b65b..0000000
--- a/lib/qra/qracodes/normrnd.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// normrnd.h
-// Functions to generate gaussian distributed numbers
-//
-// (c) 2016 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#ifndef _normrnd_h_
-#define _normrnd_h_
-
-#define _CRT_RAND_S
-#include
-
-#define _USE_MATH_DEFINES
-#include
-#define M_2PI (2.0f*(float)M_PI)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void normrnd_s(float *dst, int nitems, float mean, float stdev);
-// generate a random array of numbers with a gaussian distribution of given mean and stdev
-// use MS rand_s(...) function
-
-/* not used
-void normrnd(float *dst, int nitems, float mean, float stdev);
-// generate a random array of numbers with a gaussian distribution of given mean and stdev
-// use MS rand() function
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _normrnd_h_
-
diff --git a/lib/qra/qracodes/npfwht.c b/lib/qra/qracodes/npfwht.c
deleted file mode 100644
index 5732ce9..0000000
--- a/lib/qra/qracodes/npfwht.c
+++ /dev/null
@@ -1,216 +0,0 @@
-// npfwht.c
-// Basic implementation of the Fast Walsh-Hadamard Transforms
-//
-// (c) 2016 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (repeat and accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#include "npfwht.h"
-
-#define WHBFY(dst,src,base,offs,dist) { dst[base+offs]=src[base+offs]+src[base+offs+dist]; dst[base+offs+dist]=src[base+offs]-src[base+offs+dist]; }
-
-typedef void (*pnp_fwht)(float*,float*);
-
-static void np_fwht2(float *dst, float *src);
-
-static void np_fwht1(float *dst, float *src);
-static void np_fwht2(float *dst, float *src);
-static void np_fwht4(float *dst, float *src);
-static void np_fwht8(float *dst, float *src);
-static void np_fwht16(float *dst, float *src);
-static void np_fwht32(float *dst, float *src);
-static void np_fwht64(float *dst, float *src);
-
-static pnp_fwht np_fwht_tab[7] = {
- np_fwht1,
- np_fwht2,
- np_fwht4,
- np_fwht8,
- np_fwht16,
- np_fwht32,
- np_fwht64
-};
-
-void np_fwht(int nlogdim, float *dst, float *src)
-{
- np_fwht_tab[nlogdim](dst,src);
-}
-
-static void np_fwht1(float *dst, float *src)
-{
- dst[0] = src[0];
-}
-
-
-static void np_fwht2(float *dst, float *src)
-{
- float t[2];
-
- WHBFY(t,src,0,0,1);
- dst[0]= t[0];
- dst[1]= t[1];
-}
-
-static void np_fwht4(float *dst, float *src)
-{
- float t[4];
-
- // group 1
- WHBFY(t,src,0,0,2); WHBFY(t,src,0,1,2);
- // group 2
- WHBFY(dst,t,0,0,1); WHBFY(dst,t,2,0,1);
-};
-
-
-static void np_fwht8(float *dst, float *src)
-{
- float t[16];
- float *t1=t, *t2=t+8;
-
- // group 1
- WHBFY(t1,src,0,0,4); WHBFY(t1,src,0,1,4); WHBFY(t1,src,0,2,4); WHBFY(t1,src,0,3,4);
- // group 2
- WHBFY(t2,t1,0,0,2); WHBFY(t2,t1,0,1,2); WHBFY(t2,t1,4,0,2); WHBFY(t2,t1,4,1,2);
- // group 3
- WHBFY(dst,t2,0,0,1); WHBFY(dst,t2,2,0,1); WHBFY(dst,t2,4,0,1); WHBFY(dst,t2,6,0,1);
-};
-
-
-static void np_fwht16(float *dst, float *src)
-{
- float t[32];
- float *t1=t, *t2=t+16;
-
- // group 1
- WHBFY(t1,src,0,0,8); WHBFY(t1,src,0,1,8); WHBFY(t1,src,0,2,8); WHBFY(t1,src,0,3,8);
- WHBFY(t1,src,0,4,8); WHBFY(t1,src,0,5,8); WHBFY(t1,src,0,6,8); WHBFY(t1,src,0,7,8);
- // group 2
- WHBFY(t2,t1,0,0,4); WHBFY(t2,t1,0,1,4); WHBFY(t2,t1,0,2,4); WHBFY(t2,t1,0,3,4);
- WHBFY(t2,t1,8,0,4); WHBFY(t2,t1,8,1,4); WHBFY(t2,t1,8,2,4); WHBFY(t2,t1,8,3,4);
- // group 3
- WHBFY(t1,t2,0,0,2); WHBFY(t1,t2,0,1,2); WHBFY(t1,t2,4,0,2); WHBFY(t1,t2,4,1,2);
- WHBFY(t1,t2,8,0,2); WHBFY(t1,t2,8,1,2); WHBFY(t1,t2,12,0,2); WHBFY(t1,t2,12,1,2);
- // group 4
- WHBFY(dst,t1,0,0,1); WHBFY(dst,t1,2,0,1); WHBFY(dst,t1,4,0,1); WHBFY(dst,t1,6,0,1);
- WHBFY(dst,t1,8,0,1); WHBFY(dst,t1,10,0,1); WHBFY(dst,t1,12,0,1); WHBFY(dst,t1,14,0,1);
-
-}
-
-static void np_fwht32(float *dst, float *src)
-{
- float t[64];
- float *t1=t, *t2=t+32;
-
- // group 1
- WHBFY(t1,src,0,0,16); WHBFY(t1,src,0,1,16); WHBFY(t1,src,0,2,16); WHBFY(t1,src,0,3,16);
- WHBFY(t1,src,0,4,16); WHBFY(t1,src,0,5,16); WHBFY(t1,src,0,6,16); WHBFY(t1,src,0,7,16);
- WHBFY(t1,src,0,8,16); WHBFY(t1,src,0,9,16); WHBFY(t1,src,0,10,16); WHBFY(t1,src,0,11,16);
- WHBFY(t1,src,0,12,16); WHBFY(t1,src,0,13,16); WHBFY(t1,src,0,14,16); WHBFY(t1,src,0,15,16);
-
- // group 2
- WHBFY(t2,t1,0,0,8); WHBFY(t2,t1,0,1,8); WHBFY(t2,t1,0,2,8); WHBFY(t2,t1,0,3,8);
- WHBFY(t2,t1,0,4,8); WHBFY(t2,t1,0,5,8); WHBFY(t2,t1,0,6,8); WHBFY(t2,t1,0,7,8);
- WHBFY(t2,t1,16,0,8); WHBFY(t2,t1,16,1,8); WHBFY(t2,t1,16,2,8); WHBFY(t2,t1,16,3,8);
- WHBFY(t2,t1,16,4,8); WHBFY(t2,t1,16,5,8); WHBFY(t2,t1,16,6,8); WHBFY(t2,t1,16,7,8);
-
- // group 3
- WHBFY(t1,t2,0,0,4); WHBFY(t1,t2,0,1,4); WHBFY(t1,t2,0,2,4); WHBFY(t1,t2,0,3,4);
- WHBFY(t1,t2,8,0,4); WHBFY(t1,t2,8,1,4); WHBFY(t1,t2,8,2,4); WHBFY(t1,t2,8,3,4);
- WHBFY(t1,t2,16,0,4); WHBFY(t1,t2,16,1,4); WHBFY(t1,t2,16,2,4); WHBFY(t1,t2,16,3,4);
- WHBFY(t1,t2,24,0,4); WHBFY(t1,t2,24,1,4); WHBFY(t1,t2,24,2,4); WHBFY(t1,t2,24,3,4);
-
- // group 4
- WHBFY(t2,t1,0,0,2); WHBFY(t2,t1,0,1,2); WHBFY(t2,t1,4,0,2); WHBFY(t2,t1,4,1,2);
- WHBFY(t2,t1,8,0,2); WHBFY(t2,t1,8,1,2); WHBFY(t2,t1,12,0,2); WHBFY(t2,t1,12,1,2);
- WHBFY(t2,t1,16,0,2); WHBFY(t2,t1,16,1,2); WHBFY(t2,t1,20,0,2); WHBFY(t2,t1,20,1,2);
- WHBFY(t2,t1,24,0,2); WHBFY(t2,t1,24,1,2); WHBFY(t2,t1,28,0,2); WHBFY(t2,t1,28,1,2);
-
- // group 5
- WHBFY(dst,t2,0,0,1); WHBFY(dst,t2,2,0,1); WHBFY(dst,t2,4,0,1); WHBFY(dst,t2,6,0,1);
- WHBFY(dst,t2,8,0,1); WHBFY(dst,t2,10,0,1); WHBFY(dst,t2,12,0,1); WHBFY(dst,t2,14,0,1);
- WHBFY(dst,t2,16,0,1); WHBFY(dst,t2,18,0,1); WHBFY(dst,t2,20,0,1); WHBFY(dst,t2,22,0,1);
- WHBFY(dst,t2,24,0,1); WHBFY(dst,t2,26,0,1); WHBFY(dst,t2,28,0,1); WHBFY(dst,t2,30,0,1);
-
-}
-
-static void np_fwht64(float *dst, float *src)
-{
- float t[128];
- float *t1=t, *t2=t+64;
-
-
- // group 1
- WHBFY(t1,src,0,0,32); WHBFY(t1,src,0,1,32); WHBFY(t1,src,0,2,32); WHBFY(t1,src,0,3,32);
- WHBFY(t1,src,0,4,32); WHBFY(t1,src,0,5,32); WHBFY(t1,src,0,6,32); WHBFY(t1,src,0,7,32);
- WHBFY(t1,src,0,8,32); WHBFY(t1,src,0,9,32); WHBFY(t1,src,0,10,32); WHBFY(t1,src,0,11,32);
- WHBFY(t1,src,0,12,32); WHBFY(t1,src,0,13,32); WHBFY(t1,src,0,14,32); WHBFY(t1,src,0,15,32);
- WHBFY(t1,src,0,16,32); WHBFY(t1,src,0,17,32); WHBFY(t1,src,0,18,32); WHBFY(t1,src,0,19,32);
- WHBFY(t1,src,0,20,32); WHBFY(t1,src,0,21,32); WHBFY(t1,src,0,22,32); WHBFY(t1,src,0,23,32);
- WHBFY(t1,src,0,24,32); WHBFY(t1,src,0,25,32); WHBFY(t1,src,0,26,32); WHBFY(t1,src,0,27,32);
- WHBFY(t1,src,0,28,32); WHBFY(t1,src,0,29,32); WHBFY(t1,src,0,30,32); WHBFY(t1,src,0,31,32);
-
- // group 2
- WHBFY(t2,t1,0,0,16); WHBFY(t2,t1,0,1,16); WHBFY(t2,t1,0,2,16); WHBFY(t2,t1,0,3,16);
- WHBFY(t2,t1,0,4,16); WHBFY(t2,t1,0,5,16); WHBFY(t2,t1,0,6,16); WHBFY(t2,t1,0,7,16);
- WHBFY(t2,t1,0,8,16); WHBFY(t2,t1,0,9,16); WHBFY(t2,t1,0,10,16); WHBFY(t2,t1,0,11,16);
- WHBFY(t2,t1,0,12,16); WHBFY(t2,t1,0,13,16); WHBFY(t2,t1,0,14,16); WHBFY(t2,t1,0,15,16);
-
- WHBFY(t2,t1,32,0,16); WHBFY(t2,t1,32,1,16); WHBFY(t2,t1,32,2,16); WHBFY(t2,t1,32,3,16);
- WHBFY(t2,t1,32,4,16); WHBFY(t2,t1,32,5,16); WHBFY(t2,t1,32,6,16); WHBFY(t2,t1,32,7,16);
- WHBFY(t2,t1,32,8,16); WHBFY(t2,t1,32,9,16); WHBFY(t2,t1,32,10,16); WHBFY(t2,t1,32,11,16);
- WHBFY(t2,t1,32,12,16); WHBFY(t2,t1,32,13,16); WHBFY(t2,t1,32,14,16); WHBFY(t2,t1,32,15,16);
-
- // group 3
- WHBFY(t1,t2,0,0,8); WHBFY(t1,t2,0,1,8); WHBFY(t1,t2,0,2,8); WHBFY(t1,t2,0,3,8);
- WHBFY(t1,t2,0,4,8); WHBFY(t1,t2,0,5,8); WHBFY(t1,t2,0,6,8); WHBFY(t1,t2,0,7,8);
- WHBFY(t1,t2,16,0,8); WHBFY(t1,t2,16,1,8); WHBFY(t1,t2,16,2,8); WHBFY(t1,t2,16,3,8);
- WHBFY(t1,t2,16,4,8); WHBFY(t1,t2,16,5,8); WHBFY(t1,t2,16,6,8); WHBFY(t1,t2,16,7,8);
- WHBFY(t1,t2,32,0,8); WHBFY(t1,t2,32,1,8); WHBFY(t1,t2,32,2,8); WHBFY(t1,t2,32,3,8);
- WHBFY(t1,t2,32,4,8); WHBFY(t1,t2,32,5,8); WHBFY(t1,t2,32,6,8); WHBFY(t1,t2,32,7,8);
- WHBFY(t1,t2,48,0,8); WHBFY(t1,t2,48,1,8); WHBFY(t1,t2,48,2,8); WHBFY(t1,t2,48,3,8);
- WHBFY(t1,t2,48,4,8); WHBFY(t1,t2,48,5,8); WHBFY(t1,t2,48,6,8); WHBFY(t1,t2,48,7,8);
-
- // group 4
- WHBFY(t2,t1,0,0,4); WHBFY(t2,t1,0,1,4); WHBFY(t2,t1,0,2,4); WHBFY(t2,t1,0,3,4);
- WHBFY(t2,t1,8,0,4); WHBFY(t2,t1,8,1,4); WHBFY(t2,t1,8,2,4); WHBFY(t2,t1,8,3,4);
- WHBFY(t2,t1,16,0,4); WHBFY(t2,t1,16,1,4); WHBFY(t2,t1,16,2,4); WHBFY(t2,t1,16,3,4);
- WHBFY(t2,t1,24,0,4); WHBFY(t2,t1,24,1,4); WHBFY(t2,t1,24,2,4); WHBFY(t2,t1,24,3,4);
- WHBFY(t2,t1,32,0,4); WHBFY(t2,t1,32,1,4); WHBFY(t2,t1,32,2,4); WHBFY(t2,t1,32,3,4);
- WHBFY(t2,t1,40,0,4); WHBFY(t2,t1,40,1,4); WHBFY(t2,t1,40,2,4); WHBFY(t2,t1,40,3,4);
- WHBFY(t2,t1,48,0,4); WHBFY(t2,t1,48,1,4); WHBFY(t2,t1,48,2,4); WHBFY(t2,t1,48,3,4);
- WHBFY(t2,t1,56,0,4); WHBFY(t2,t1,56,1,4); WHBFY(t2,t1,56,2,4); WHBFY(t2,t1,56,3,4);
-
- // group 5
- WHBFY(t1,t2,0,0,2); WHBFY(t1,t2,0,1,2); WHBFY(t1,t2,4,0,2); WHBFY(t1,t2,4,1,2);
- WHBFY(t1,t2,8,0,2); WHBFY(t1,t2,8,1,2); WHBFY(t1,t2,12,0,2); WHBFY(t1,t2,12,1,2);
- WHBFY(t1,t2,16,0,2); WHBFY(t1,t2,16,1,2); WHBFY(t1,t2,20,0,2); WHBFY(t1,t2,20,1,2);
- WHBFY(t1,t2,24,0,2); WHBFY(t1,t2,24,1,2); WHBFY(t1,t2,28,0,2); WHBFY(t1,t2,28,1,2);
- WHBFY(t1,t2,32,0,2); WHBFY(t1,t2,32,1,2); WHBFY(t1,t2,36,0,2); WHBFY(t1,t2,36,1,2);
- WHBFY(t1,t2,40,0,2); WHBFY(t1,t2,40,1,2); WHBFY(t1,t2,44,0,2); WHBFY(t1,t2,44,1,2);
- WHBFY(t1,t2,48,0,2); WHBFY(t1,t2,48,1,2); WHBFY(t1,t2,52,0,2); WHBFY(t1,t2,52,1,2);
- WHBFY(t1,t2,56,0,2); WHBFY(t1,t2,56,1,2); WHBFY(t1,t2,60,0,2); WHBFY(t1,t2,60,1,2);
-
- // group 6
- WHBFY(dst,t1,0,0,1); WHBFY(dst,t1,2,0,1); WHBFY(dst,t1,4,0,1); WHBFY(dst,t1,6,0,1);
- WHBFY(dst,t1,8,0,1); WHBFY(dst,t1,10,0,1); WHBFY(dst,t1,12,0,1); WHBFY(dst,t1,14,0,1);
- WHBFY(dst,t1,16,0,1); WHBFY(dst,t1,18,0,1); WHBFY(dst,t1,20,0,1); WHBFY(dst,t1,22,0,1);
- WHBFY(dst,t1,24,0,1); WHBFY(dst,t1,26,0,1); WHBFY(dst,t1,28,0,1); WHBFY(dst,t1,30,0,1);
- WHBFY(dst,t1,32,0,1); WHBFY(dst,t1,34,0,1); WHBFY(dst,t1,36,0,1); WHBFY(dst,t1,38,0,1);
- WHBFY(dst,t1,40,0,1); WHBFY(dst,t1,42,0,1); WHBFY(dst,t1,44,0,1); WHBFY(dst,t1,46,0,1);
- WHBFY(dst,t1,48,0,1); WHBFY(dst,t1,50,0,1); WHBFY(dst,t1,52,0,1); WHBFY(dst,t1,54,0,1);
- WHBFY(dst,t1,56,0,1); WHBFY(dst,t1,58,0,1); WHBFY(dst,t1,60,0,1); WHBFY(dst,t1,62,0,1);
-}
\ No newline at end of file
diff --git a/lib/qra/qracodes/npfwht.h b/lib/qra/qracodes/npfwht.h
deleted file mode 100644
index 9452e20..0000000
--- a/lib/qra/qracodes/npfwht.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// np_fwht.h
-// Basic implementation of the Fast Walsh-Hadamard Transforms
-//
-// (c) 2016 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (repeat and accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#ifndef _npfwht_h_
-#define _npfwht_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void np_fwht(int nlogdim, float *dst, float *src);
-// Compute the Walsh-Hadamard transform of the given data up to a
-// 64-dimensional transform
-//
-// Input parameters:
-// nlogdim: log2 of the transform size. Must be in the range [0..6]
-// src : pointer to the input data buffer.
-// dst : pointer to the output data buffer.
-//
-// src and dst must point to preallocated data buffers of size 2^nlogdim*sizeof(float)
-// src and dst buffers can overlap
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _npfwht_
diff --git a/lib/qra/qracodes/pdmath.c b/lib/qra/qracodes/pdmath.c
deleted file mode 100644
index 47ecab9..0000000
--- a/lib/qra/qracodes/pdmath.c
+++ /dev/null
@@ -1,385 +0,0 @@
-// pdmath.c
-// Elementary math on probability distributions
-//
-// (c) 2016 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#include "pdmath.h"
-
-typedef const float *ppd_uniform;
-typedef void (*ppd_imul)(float*,const float*);
-typedef float (*ppd_norm)(float*);
-
-// define vector size in function of its logarithm in base 2
-static const int pd_log2dim[7] = {
- 1,2,4,8,16,32,64
-};
-
-// define uniform distributions of given size
-static const float pd_uniform1[1] = {
- 1.
-};
-static const float pd_uniform2[2] = {
- 1./2., 1./2.
-};
-static const float pd_uniform4[4] = {
- 1./4., 1./4.,1./4., 1./4.
-};
-static const float pd_uniform8[8] = {
- 1./8., 1./8.,1./8., 1./8.,1./8., 1./8.,1./8., 1./8.
-};
-static const float pd_uniform16[16] = {
- 1./16., 1./16., 1./16., 1./16.,1./16., 1./16.,1./16., 1./16.,
- 1./16., 1./16., 1./16., 1./16.,1./16., 1./16.,1./16., 1./16.
-};
-static const float pd_uniform32[32] = {
- 1./32., 1./32., 1./32., 1./32.,1./32., 1./32.,1./32., 1./32.,
- 1./32., 1./32., 1./32., 1./32.,1./32., 1./32.,1./32., 1./32.,
- 1./32., 1./32., 1./32., 1./32.,1./32., 1./32.,1./32., 1./32.,
- 1./32., 1./32., 1./32., 1./32.,1./32., 1./32.,1./32., 1./32.
-};
-static const float pd_uniform64[64] = {
- 1./64., 1./64., 1./64., 1./64.,1./64., 1./64.,1./64., 1./64.,
- 1./64., 1./64., 1./64., 1./64.,1./64., 1./64.,1./64., 1./64.,
- 1./64., 1./64., 1./64., 1./64.,1./64., 1./64.,1./64., 1./64.,
- 1./64., 1./64., 1./64., 1./64.,1./64., 1./64.,1./64., 1./64.,
- 1./64., 1./64., 1./64., 1./64.,1./64., 1./64.,1./64., 1./64.,
- 1./64., 1./64., 1./64., 1./64.,1./64., 1./64.,1./64., 1./64.,
- 1./64., 1./64., 1./64., 1./64.,1./64., 1./64.,1./64., 1./64.,
- 1./64., 1./64., 1./64., 1./64.,1./64., 1./64.,1./64., 1./64.
-
-};
-
-static const ppd_uniform pd_uniform_tab[7] = {
- pd_uniform1,
- pd_uniform2,
- pd_uniform4,
- pd_uniform8,
- pd_uniform16,
- pd_uniform32,
- pd_uniform64
-};
-
-// returns a pointer to the uniform distribution of the given logsize
-const float *pd_uniform(int nlogdim)
-{
- return pd_uniform_tab[nlogdim];
-}
-
-// in-place multiplication functions
-// compute dst = dst*src for any element of the distrib
-
-static void pd_imul1(float *dst, const float *src)
-{
- dst[0] *= src[0];
-}
-
-static void pd_imul2(float *dst, const float *src)
-{
- dst[0] *= src[0]; dst[1] *= src[1];
-}
-static void pd_imul4(float *dst, const float *src)
-{
- dst[0] *= src[0]; dst[1] *= src[1];
- dst[2] *= src[2]; dst[3] *= src[3];
-}
-static void pd_imul8(float *dst, const float *src)
-{
- dst[0] *= src[0]; dst[1] *= src[1]; dst[2] *= src[2]; dst[3] *= src[3];
- dst[4] *= src[4]; dst[5] *= src[5]; dst[6] *= src[6]; dst[7] *= src[7];
-}
-static void pd_imul16(float *dst, const float *src)
-{
- dst[0] *= src[0]; dst[1] *= src[1]; dst[2] *= src[2]; dst[3] *= src[3];
- dst[4] *= src[4]; dst[5] *= src[5]; dst[6] *= src[6]; dst[7] *= src[7];
- dst[8] *= src[8]; dst[9] *= src[9]; dst[10]*= src[10]; dst[11]*= src[11];
- dst[12]*= src[12]; dst[13]*= src[13]; dst[14]*= src[14]; dst[15]*= src[15];
-}
-static void pd_imul32(float *dst, const float *src)
-{
- pd_imul16(dst,src);
- pd_imul16(dst+16,src+16);
-}
-static void pd_imul64(float *dst, const float *src)
-{
- pd_imul16(dst, src);
- pd_imul16(dst+16, src+16);
- pd_imul16(dst+32, src+32);
- pd_imul16(dst+48, src+48);
-}
-
-static const ppd_imul pd_imul_tab[7] = {
- pd_imul1,
- pd_imul2,
- pd_imul4,
- pd_imul8,
- pd_imul16,
- pd_imul32,
- pd_imul64
-};
-
-// in place multiplication
-// compute dst = dst*src for any element of the distrib give their log2 size
-// arguments must be pointers to array of floats of the given size
-void pd_imul(float *dst, const float *src, int nlogdim)
-{
- pd_imul_tab[nlogdim](dst,src);
-}
-
-static float pd_norm1(float *ppd)
-{
- float t = ppd[0];
- ppd[0] = 1.f;
- return t;
-}
-
-static float pd_norm2(float *ppd)
-{
- float t,to;
-
- t =ppd[0]; t +=ppd[1];
-
- if (t<=0) {
- pd_init(ppd,pd_uniform(1),pd_log2dim[1]);
- return t;
- }
-
- to = t;
- t = 1.f/t;
- ppd[0] *=t; ppd[1] *=t;
- return to;
-
-}
-
-static float pd_norm4(float *ppd)
-{
- float t,to;
-
- t =ppd[0]; t +=ppd[1]; t +=ppd[2]; t +=ppd[3];
-
- if (t<=0) {
- pd_init(ppd,pd_uniform(2),pd_log2dim[2]);
- return t;
- }
-
- to = t;
- t = 1.f/t;
- ppd[0] *=t; ppd[1] *=t; ppd[2] *=t; ppd[3] *=t;
- return to;
-}
-
-static float pd_norm8(float *ppd)
-{
- float t,to;
-
- t =ppd[0]; t +=ppd[1]; t +=ppd[2]; t +=ppd[3];
- t +=ppd[4]; t +=ppd[5]; t +=ppd[6]; t +=ppd[7];
-
- if (t<=0) {
- pd_init(ppd,pd_uniform(3),pd_log2dim[3]);
- return t;
- }
-
- to = t;
- t = 1.f/t;
- ppd[0] *=t; ppd[1] *=t; ppd[2] *=t; ppd[3] *=t;
- ppd[4] *=t; ppd[5] *=t; ppd[6] *=t; ppd[7] *=t;
- return to;
-}
-static float pd_norm16(float *ppd)
-{
- float t,to;
-
- t =ppd[0]; t +=ppd[1]; t +=ppd[2]; t +=ppd[3];
- t +=ppd[4]; t +=ppd[5]; t +=ppd[6]; t +=ppd[7];
- t +=ppd[8]; t +=ppd[9]; t +=ppd[10]; t +=ppd[11];
- t +=ppd[12]; t +=ppd[13]; t +=ppd[14]; t +=ppd[15];
-
- if (t<=0) {
- pd_init(ppd,pd_uniform(4),pd_log2dim[4]);
- return t;
- }
-
- to = t;
- t = 1.f/t;
- ppd[0] *=t; ppd[1] *=t; ppd[2] *=t; ppd[3] *=t;
- ppd[4] *=t; ppd[5] *=t; ppd[6] *=t; ppd[7] *=t;
- ppd[8] *=t; ppd[9] *=t; ppd[10] *=t; ppd[11] *=t;
- ppd[12] *=t; ppd[13] *=t; ppd[14] *=t; ppd[15] *=t;
-
- return to;
-}
-static float pd_norm32(float *ppd)
-{
- float t,to;
-
- t =ppd[0]; t +=ppd[1]; t +=ppd[2]; t +=ppd[3];
- t +=ppd[4]; t +=ppd[5]; t +=ppd[6]; t +=ppd[7];
- t +=ppd[8]; t +=ppd[9]; t +=ppd[10]; t +=ppd[11];
- t +=ppd[12]; t +=ppd[13]; t +=ppd[14]; t +=ppd[15];
- t +=ppd[16]; t +=ppd[17]; t +=ppd[18]; t +=ppd[19];
- t +=ppd[20]; t +=ppd[21]; t +=ppd[22]; t +=ppd[23];
- t +=ppd[24]; t +=ppd[25]; t +=ppd[26]; t +=ppd[27];
- t +=ppd[28]; t +=ppd[29]; t +=ppd[30]; t +=ppd[31];
-
- if (t<=0) {
- pd_init(ppd,pd_uniform(5),pd_log2dim[5]);
- return t;
- }
-
- to = t;
- t = 1.f/t;
- ppd[0] *=t; ppd[1] *=t; ppd[2] *=t; ppd[3] *=t;
- ppd[4] *=t; ppd[5] *=t; ppd[6] *=t; ppd[7] *=t;
- ppd[8] *=t; ppd[9] *=t; ppd[10] *=t; ppd[11] *=t;
- ppd[12] *=t; ppd[13] *=t; ppd[14] *=t; ppd[15] *=t;
- ppd[16] *=t; ppd[17] *=t; ppd[18] *=t; ppd[19] *=t;
- ppd[20] *=t; ppd[21] *=t; ppd[22] *=t; ppd[23] *=t;
- ppd[24] *=t; ppd[25] *=t; ppd[26] *=t; ppd[27] *=t;
- ppd[28] *=t; ppd[29] *=t; ppd[30] *=t; ppd[31] *=t;
-
- return to;
-}
-
-static float pd_norm64(float *ppd)
-{
- float t,to;
-
- t =ppd[0]; t +=ppd[1]; t +=ppd[2]; t +=ppd[3];
- t +=ppd[4]; t +=ppd[5]; t +=ppd[6]; t +=ppd[7];
- t +=ppd[8]; t +=ppd[9]; t +=ppd[10]; t +=ppd[11];
- t +=ppd[12]; t +=ppd[13]; t +=ppd[14]; t +=ppd[15];
- t +=ppd[16]; t +=ppd[17]; t +=ppd[18]; t +=ppd[19];
- t +=ppd[20]; t +=ppd[21]; t +=ppd[22]; t +=ppd[23];
- t +=ppd[24]; t +=ppd[25]; t +=ppd[26]; t +=ppd[27];
- t +=ppd[28]; t +=ppd[29]; t +=ppd[30]; t +=ppd[31];
-
- t +=ppd[32]; t +=ppd[33]; t +=ppd[34]; t +=ppd[35];
- t +=ppd[36]; t +=ppd[37]; t +=ppd[38]; t +=ppd[39];
- t +=ppd[40]; t +=ppd[41]; t +=ppd[42]; t +=ppd[43];
- t +=ppd[44]; t +=ppd[45]; t +=ppd[46]; t +=ppd[47];
- t +=ppd[48]; t +=ppd[49]; t +=ppd[50]; t +=ppd[51];
- t +=ppd[52]; t +=ppd[53]; t +=ppd[54]; t +=ppd[55];
- t +=ppd[56]; t +=ppd[57]; t +=ppd[58]; t +=ppd[59];
- t +=ppd[60]; t +=ppd[61]; t +=ppd[62]; t +=ppd[63];
-
- if (t<=0) {
- pd_init(ppd,pd_uniform(6),pd_log2dim[6]);
- return t;
- }
-
- to = t;
- t = 1.0f/t;
- ppd[0] *=t; ppd[1] *=t; ppd[2] *=t; ppd[3] *=t;
- ppd[4] *=t; ppd[5] *=t; ppd[6] *=t; ppd[7] *=t;
- ppd[8] *=t; ppd[9] *=t; ppd[10] *=t; ppd[11] *=t;
- ppd[12] *=t; ppd[13] *=t; ppd[14] *=t; ppd[15] *=t;
- ppd[16] *=t; ppd[17] *=t; ppd[18] *=t; ppd[19] *=t;
- ppd[20] *=t; ppd[21] *=t; ppd[22] *=t; ppd[23] *=t;
- ppd[24] *=t; ppd[25] *=t; ppd[26] *=t; ppd[27] *=t;
- ppd[28] *=t; ppd[29] *=t; ppd[30] *=t; ppd[31] *=t;
-
- ppd[32] *=t; ppd[33] *=t; ppd[34] *=t; ppd[35] *=t;
- ppd[36] *=t; ppd[37] *=t; ppd[38] *=t; ppd[39] *=t;
- ppd[40] *=t; ppd[41] *=t; ppd[42] *=t; ppd[43] *=t;
- ppd[44] *=t; ppd[45] *=t; ppd[46] *=t; ppd[47] *=t;
- ppd[48] *=t; ppd[49] *=t; ppd[50] *=t; ppd[51] *=t;
- ppd[52] *=t; ppd[53] *=t; ppd[54] *=t; ppd[55] *=t;
- ppd[56] *=t; ppd[57] *=t; ppd[58] *=t; ppd[59] *=t;
- ppd[60] *=t; ppd[61] *=t; ppd[62] *=t; ppd[63] *=t;
-
- return to;
-}
-
-
-static const ppd_norm pd_norm_tab[7] = {
- pd_norm1,
- pd_norm2,
- pd_norm4,
- pd_norm8,
- pd_norm16,
- pd_norm32,
- pd_norm64
-};
-
-float pd_norm(float *pd, int nlogdim)
-{
- return pd_norm_tab[nlogdim](pd);
-}
-
-void pd_memset(float *dst, const float *src, int ndim, int nitems)
-{
- int size = PD_SIZE(ndim);
- while(nitems--) {
- memcpy(dst,src,size);
- dst +=ndim;
- }
-}
-
-void pd_fwdperm(float *dst, float *src, const int *perm, int ndim)
-{
- // TODO: non-loop implementation
- while (ndim--)
- dst[ndim] = src[perm[ndim]];
-}
-
-void pd_bwdperm(float *dst, float *src, const int *perm, int ndim)
-{
- // TODO: non-loop implementation
- while (ndim--)
- dst[perm[ndim]] = src[ndim];
-}
-
-float pd_max(float *src, int ndim)
-{
- // TODO: faster implementation
-
- float cmax=0; // we assume that prob distributions are always positive
- float cval;
-
- while (ndim--) {
- cval = src[ndim];
- if (cval>=cmax) {
- cmax = cval;
- }
- }
-
- return cmax;
-}
-
-int pd_argmax(float *pmax, float *src, int ndim)
-{
- // TODO: faster implementation
-
- float cmax=0; // we assume that prob distributions are always positive
- float cval;
- int idxmax=-1; // indicates that all pd elements are <0
-
- while (ndim--) {
- cval = src[ndim];
- if (cval>=cmax) {
- cmax = cval;
- idxmax = ndim;
- }
- }
-
- if (pmax)
- *pmax = cmax;
-
- return idxmax;
-}
diff --git a/lib/qra/qracodes/pdmath.h b/lib/qra/qracodes/pdmath.h
deleted file mode 100644
index bbd1210..0000000
--- a/lib/qra/qracodes/pdmath.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// pdmath.h
-// Elementary math on probability distributions
-//
-// (c) 2016 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (repeat and accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-
-#ifndef _pdmath_h_
-#define _pdmath_h_
-
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PD_NDIM(nlogdim) ((1<<(nlogdim))
-#define PD_SIZE(ndim) ((ndim)*sizeof(float))
-#define PD_ROWADDR(fp,ndim,idx) (fp+((ndim)*(idx)))
-
-const float *pd_uniform(int nlogdim);
-// Returns a pointer to a (constant) uniform distribution of the given log2 size
-
-#define pd_init(dst,src,ndim) memcpy(dst,src,PD_SIZE(ndim))
-// Distribution copy
-
-void pd_memset(float *dst, const float *src, int ndim, int nitems);
-// Copy the distribution pointed by src to the array of distributions dst
-// src is a pointer to the input distribution (a vector of size ndim)
-// dst is a pointer to a linear array of distributions (a vector of size ndim*nitems)
-
-void pd_imul(float *dst, const float *src, int nlogdim);
-// In place multiplication
-// Compute dst = dst*src for any element of the distrib give their log2 size
-// src and dst arguments must be pointers to array of floats of the given size
-
-float pd_norm(float *pd, int nlogdim);
-// In place normalizazion
-// Normalizes the input vector so that the sum of its components are one
-// pd must be a pointer to an array of floats of the given size.
-// If the norm of the input vector is non-positive the vector components
-// are replaced with a uniform distribution
-// Returns the norm of the distribution prior to the normalization
-
-void pd_fwdperm(float *dst, float *src, const int *perm, int ndim);
-// Forward permutation of a distribution
-// Computes dst[k] = src[perm[k]] for every element in the distribution
-// perm must be a pointer to an array of integers of length ndim
-
-void pd_bwdperm(float *dst, float *src, const int *perm, int ndim);
-// Backward permutation of a distribution
-// Computes dst[perm[k]] = src[k] for every element in the distribution
-// perm must be a pointer to an array of integers of length ndim
-
-float pd_max(float *src, int ndim);
-// Return the maximum of the elements of the given distribution
-// Assumes that the input vector is a probability distribution and that each element in the
-// distribution is non negative
-
-int pd_argmax(float *pmax, float *src, int ndim);
-// Return the index of the maximum element of the given distribution
-// The maximum is stored in the variable pointed by pmax if pmax is not null
-// Same note of pd_max applies.
-// Return -1 if all the elements in the distribution are negative
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _pdmath_h_
diff --git a/lib/qra/qracodes/qra12_63_64_irr_b.c b/lib/qra/qracodes/qra12_63_64_irr_b.c
deleted file mode 100644
index d69443b..0000000
--- a/lib/qra/qracodes/qra12_63_64_irr_b.c
+++ /dev/null
@@ -1,534 +0,0 @@
-// qra12_63_64_irr_b.c
-// Encoding/Decoding tables for Q-ary RA code (12,63) over GF(64)
-// Code Name: qra12_63_64_irr_b
-// (12,63) RA Code over GF(64) - RF=333344455567
-
-// (c) 2016 - Nico Palermo - IV3NWV - Microtelecom Srl, Italy
-
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#include "qra12_63_64_irr_b.h"
-
-#define qra_K 12 // number of information symbols
-#define qra_N 63 // codeword length in symbols
-#define qra_m 6 // bits/symbol
-#define qra_M 64 // Symbol alphabet cardinality
-#define qra_a 1 // grouping factor
-#define qra_NC 51 // number of check symbols (N-K)
-
-// Defines used by the message passing decoder --------
-
-#define qra_V 63 // number of variables in the code graph (N)
-#define qra_C 115 // number of factors in the code graph (N +(N-K)+1)
-#define qra_NMSG 217 // number of msgs in the code graph
-#define qra_MAXVDEG 8 // maximum variable degree
-#define qra_MAXCDEG 3 // maximum factor degree
-#define qra_R 0.19048f // code rate (K/N)
-#define CODE_NAME "qra_12_63_64_irr_b"
-
-
-// table of the systematic symbols indexes in the accumulator chain
-static const int qra_acc_input_idx[qra_NC+1] = {
- 3, 11, 0, 1, 7, 8, 6, 5, 10, 4,
- 11, 9, 0, 2, 6, 7, 8, 4, 11, 5,
- 10, 2, 1, 9, 3, 8, 4, 11, 5, 7,
- 10, 9, 6, 3, 11, 5, 8, 10, 0, 7,
- 9, 11, 4, 2, 10, 6, 8, 1, 9, 7,
- 11, 10
-};
-
-// table of the systematic symbols weight logarithms over GF(M)
-static const int qra_acc_input_wlog[qra_NC+1] = {
- 39, 0, 34, 16, 25, 0, 34, 48, 19, 13,
- 29, 56, 0, 5, 39, 42, 31, 0, 10, 0,
- 57, 62, 33, 43, 0, 14, 22, 48, 28, 20,
- 5, 45, 16, 43, 17, 4, 32, 0, 31, 0,
- 0, 28, 57, 0, 18, 0, 60, 0, 10, 31,
- 57, 27
-};
-
-// table of the logarithms of the elements of GF(M) (log(0) never used)
-static const int qra_log[qra_M] = {
- -1, 0, 1, 6, 2, 12, 7, 26, 3, 32,
- 13, 35, 8, 48, 27, 18, 4, 24, 33, 16,
- 14, 52, 36, 54, 9, 45, 49, 38, 28, 41,
- 19, 56, 5, 62, 25, 11, 34, 31, 17, 47,
- 15, 23, 53, 51, 37, 44, 55, 40, 10, 61,
- 46, 30, 50, 22, 39, 43, 29, 60, 42, 21,
- 20, 59, 57, 58
-};
-
-// table of GF(M) elements given their logarithm
-static const int qra_exp[qra_M-1] = {
- 1, 2, 4, 8, 16, 32, 3, 6, 12, 24,
- 48, 35, 5, 10, 20, 40, 19, 38, 15, 30,
- 60, 59, 53, 41, 17, 34, 7, 14, 28, 56,
- 51, 37, 9, 18, 36, 11, 22, 44, 27, 54,
- 47, 29, 58, 55, 45, 25, 50, 39, 13, 26,
- 52, 43, 21, 42, 23, 46, 31, 62, 63, 61,
- 57, 49, 33
-};
-
-// table of the messages weight logarithms over GF(M)
-static const int qra_msgw[qra_NMSG] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 39, 0, 34, 16, 25, 0, 34,
- 48, 19, 13, 29, 56, 0, 5, 39, 42, 31,
- 0, 10, 0, 57, 62, 33, 43, 0, 14, 22,
- 48, 28, 20, 5, 45, 16, 43, 17, 4, 32,
- 0, 31, 0, 0, 28, 57, 0, 18, 0, 60,
- 0, 10, 31, 57, 27, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0
-};
-
-// table of the degrees of the variable nodes
-static const int qra_vdeg[qra_V] = {
- 4, 4, 4, 4, 5, 5, 5, 6, 6, 6,
- 7, 8, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3
-};
-
-// table of the degrees of the factor nodes
-static const int qra_cdeg[qra_C] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 2, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 2
-};
-
-// table (uncompressed) of the v->c message indexes (-1=unused entry)
-static const int qra_v2cmidx[qra_V*qra_MAXVDEG] = {
- 0, 65, 75, 101, -1, -1, -1, -1,
- 1, 66, 85, 110, -1, -1, -1, -1,
- 2, 76, 84, 106, -1, -1, -1, -1,
- 3, 63, 87, 96, -1, -1, -1, -1,
- 4, 72, 80, 89, 105, -1, -1, -1,
- 5, 70, 82, 91, 98, -1, -1, -1,
- 6, 69, 77, 95, 108, -1, -1, -1,
- 7, 67, 78, 92, 102, 112, -1, -1,
- 8, 68, 79, 88, 99, 109, -1, -1,
- 9, 74, 86, 94, 103, 111, -1, -1,
- 10, 71, 83, 93, 100, 107, 114, -1,
- 11, 64, 73, 81, 90, 97, 104, 113,
- 12, 115, 116, -1, -1, -1, -1, -1,
- 13, 117, 118, -1, -1, -1, -1, -1,
- 14, 119, 120, -1, -1, -1, -1, -1,
- 15, 121, 122, -1, -1, -1, -1, -1,
- 16, 123, 124, -1, -1, -1, -1, -1,
- 17, 125, 126, -1, -1, -1, -1, -1,
- 18, 127, 128, -1, -1, -1, -1, -1,
- 19, 129, 130, -1, -1, -1, -1, -1,
- 20, 131, 132, -1, -1, -1, -1, -1,
- 21, 133, 134, -1, -1, -1, -1, -1,
- 22, 135, 136, -1, -1, -1, -1, -1,
- 23, 137, 138, -1, -1, -1, -1, -1,
- 24, 139, 140, -1, -1, -1, -1, -1,
- 25, 141, 142, -1, -1, -1, -1, -1,
- 26, 143, 144, -1, -1, -1, -1, -1,
- 27, 145, 146, -1, -1, -1, -1, -1,
- 28, 147, 148, -1, -1, -1, -1, -1,
- 29, 149, 150, -1, -1, -1, -1, -1,
- 30, 151, 152, -1, -1, -1, -1, -1,
- 31, 153, 154, -1, -1, -1, -1, -1,
- 32, 155, 156, -1, -1, -1, -1, -1,
- 33, 157, 158, -1, -1, -1, -1, -1,
- 34, 159, 160, -1, -1, -1, -1, -1,
- 35, 161, 162, -1, -1, -1, -1, -1,
- 36, 163, 164, -1, -1, -1, -1, -1,
- 37, 165, 166, -1, -1, -1, -1, -1,
- 38, 167, 168, -1, -1, -1, -1, -1,
- 39, 169, 170, -1, -1, -1, -1, -1,
- 40, 171, 172, -1, -1, -1, -1, -1,
- 41, 173, 174, -1, -1, -1, -1, -1,
- 42, 175, 176, -1, -1, -1, -1, -1,
- 43, 177, 178, -1, -1, -1, -1, -1,
- 44, 179, 180, -1, -1, -1, -1, -1,
- 45, 181, 182, -1, -1, -1, -1, -1,
- 46, 183, 184, -1, -1, -1, -1, -1,
- 47, 185, 186, -1, -1, -1, -1, -1,
- 48, 187, 188, -1, -1, -1, -1, -1,
- 49, 189, 190, -1, -1, -1, -1, -1,
- 50, 191, 192, -1, -1, -1, -1, -1,
- 51, 193, 194, -1, -1, -1, -1, -1,
- 52, 195, 196, -1, -1, -1, -1, -1,
- 53, 197, 198, -1, -1, -1, -1, -1,
- 54, 199, 200, -1, -1, -1, -1, -1,
- 55, 201, 202, -1, -1, -1, -1, -1,
- 56, 203, 204, -1, -1, -1, -1, -1,
- 57, 205, 206, -1, -1, -1, -1, -1,
- 58, 207, 208, -1, -1, -1, -1, -1,
- 59, 209, 210, -1, -1, -1, -1, -1,
- 60, 211, 212, -1, -1, -1, -1, -1,
- 61, 213, 214, -1, -1, -1, -1, -1,
- 62, 215, 216, -1, -1, -1, -1, -1
-};
-
-// table (uncompressed) of the c->v message indexes (-1=unused entry)
-static const int qra_c2vmidx[qra_C*qra_MAXCDEG] = {
- 0, -1, -1, 1, -1, -1, 2, -1, -1, 3, -1, -1,
- 4, -1, -1, 5, -1, -1, 6, -1, -1, 7, -1, -1,
- 8, -1, -1, 9, -1, -1, 10, -1, -1, 11, -1, -1,
- 12, -1, -1, 13, -1, -1, 14, -1, -1, 15, -1, -1,
- 16, -1, -1, 17, -1, -1, 18, -1, -1, 19, -1, -1,
- 20, -1, -1, 21, -1, -1, 22, -1, -1, 23, -1, -1,
- 24, -1, -1, 25, -1, -1, 26, -1, -1, 27, -1, -1,
- 28, -1, -1, 29, -1, -1, 30, -1, -1, 31, -1, -1,
- 32, -1, -1, 33, -1, -1, 34, -1, -1, 35, -1, -1,
- 36, -1, -1, 37, -1, -1, 38, -1, -1, 39, -1, -1,
- 40, -1, -1, 41, -1, -1, 42, -1, -1, 43, -1, -1,
- 44, -1, -1, 45, -1, -1, 46, -1, -1, 47, -1, -1,
- 48, -1, -1, 49, -1, -1, 50, -1, -1, 51, -1, -1,
- 52, -1, -1, 53, -1, -1, 54, -1, -1, 55, -1, -1,
- 56, -1, -1, 57, -1, -1, 58, -1, -1, 59, -1, -1,
- 60, -1, -1, 61, -1, -1, 62, -1, -1, 63, 115, -1,
- 64, 116, 117, 65, 118, 119, 66, 120, 121, 67, 122, 123,
- 68, 124, 125, 69, 126, 127, 70, 128, 129, 71, 130, 131,
- 72, 132, 133, 73, 134, 135, 74, 136, 137, 75, 138, 139,
- 76, 140, 141, 77, 142, 143, 78, 144, 145, 79, 146, 147,
- 80, 148, 149, 81, 150, 151, 82, 152, 153, 83, 154, 155,
- 84, 156, 157, 85, 158, 159, 86, 160, 161, 87, 162, 163,
- 88, 164, 165, 89, 166, 167, 90, 168, 169, 91, 170, 171,
- 92, 172, 173, 93, 174, 175, 94, 176, 177, 95, 178, 179,
- 96, 180, 181, 97, 182, 183, 98, 184, 185, 99, 186, 187,
-100, 188, 189, 101, 190, 191, 102, 192, 193, 103, 194, 195,
-104, 196, 197, 105, 198, 199, 106, 200, 201, 107, 202, 203,
-108, 204, 205, 109, 206, 207, 110, 208, 209, 111, 210, 211,
-112, 212, 213, 113, 214, 215, 114, 216, -1
-};
-
-// permutation matrix to compute Prob(x*alfa^logw)
-static const int qra_pmat[qra_M*qra_M] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 0, 33, 1, 32, 2, 35, 3, 34, 4, 37, 5, 36, 6, 39, 7, 38,
- 8, 41, 9, 40, 10, 43, 11, 42, 12, 45, 13, 44, 14, 47, 15, 46,
- 16, 49, 17, 48, 18, 51, 19, 50, 20, 53, 21, 52, 22, 55, 23, 54,
- 24, 57, 25, 56, 26, 59, 27, 58, 28, 61, 29, 60, 30, 63, 31, 62,
- 0, 49, 33, 16, 1, 48, 32, 17, 2, 51, 35, 18, 3, 50, 34, 19,
- 4, 53, 37, 20, 5, 52, 36, 21, 6, 55, 39, 22, 7, 54, 38, 23,
- 8, 57, 41, 24, 9, 56, 40, 25, 10, 59, 43, 26, 11, 58, 42, 27,
- 12, 61, 45, 28, 13, 60, 44, 29, 14, 63, 47, 30, 15, 62, 46, 31,
- 0, 57, 49, 8, 33, 24, 16, 41, 1, 56, 48, 9, 32, 25, 17, 40,
- 2, 59, 51, 10, 35, 26, 18, 43, 3, 58, 50, 11, 34, 27, 19, 42,
- 4, 61, 53, 12, 37, 28, 20, 45, 5, 60, 52, 13, 36, 29, 21, 44,
- 6, 63, 55, 14, 39, 30, 22, 47, 7, 62, 54, 15, 38, 31, 23, 46,
- 0, 61, 57, 4, 49, 12, 8, 53, 33, 28, 24, 37, 16, 45, 41, 20,
- 1, 60, 56, 5, 48, 13, 9, 52, 32, 29, 25, 36, 17, 44, 40, 21,
- 2, 63, 59, 6, 51, 14, 10, 55, 35, 30, 26, 39, 18, 47, 43, 22,
- 3, 62, 58, 7, 50, 15, 11, 54, 34, 31, 27, 38, 19, 46, 42, 23,
- 0, 63, 61, 2, 57, 6, 4, 59, 49, 14, 12, 51, 8, 55, 53, 10,
- 33, 30, 28, 35, 24, 39, 37, 26, 16, 47, 45, 18, 41, 22, 20, 43,
- 1, 62, 60, 3, 56, 7, 5, 58, 48, 15, 13, 50, 9, 54, 52, 11,
- 32, 31, 29, 34, 25, 38, 36, 27, 17, 46, 44, 19, 40, 23, 21, 42,
- 0, 62, 63, 1, 61, 3, 2, 60, 57, 7, 6, 56, 4, 58, 59, 5,
- 49, 15, 14, 48, 12, 50, 51, 13, 8, 54, 55, 9, 53, 11, 10, 52,
- 33, 31, 30, 32, 28, 34, 35, 29, 24, 38, 39, 25, 37, 27, 26, 36,
- 16, 46, 47, 17, 45, 19, 18, 44, 41, 23, 22, 40, 20, 42, 43, 21,
- 0, 31, 62, 33, 63, 32, 1, 30, 61, 34, 3, 28, 2, 29, 60, 35,
- 57, 38, 7, 24, 6, 25, 56, 39, 4, 27, 58, 37, 59, 36, 5, 26,
- 49, 46, 15, 16, 14, 17, 48, 47, 12, 19, 50, 45, 51, 44, 13, 18,
- 8, 23, 54, 41, 55, 40, 9, 22, 53, 42, 11, 20, 10, 21, 52, 43,
- 0, 46, 31, 49, 62, 16, 33, 15, 63, 17, 32, 14, 1, 47, 30, 48,
- 61, 19, 34, 12, 3, 45, 28, 50, 2, 44, 29, 51, 60, 18, 35, 13,
- 57, 23, 38, 8, 7, 41, 24, 54, 6, 40, 25, 55, 56, 22, 39, 9,
- 4, 42, 27, 53, 58, 20, 37, 11, 59, 21, 36, 10, 5, 43, 26, 52,
- 0, 23, 46, 57, 31, 8, 49, 38, 62, 41, 16, 7, 33, 54, 15, 24,
- 63, 40, 17, 6, 32, 55, 14, 25, 1, 22, 47, 56, 30, 9, 48, 39,
- 61, 42, 19, 4, 34, 53, 12, 27, 3, 20, 45, 58, 28, 11, 50, 37,
- 2, 21, 44, 59, 29, 10, 51, 36, 60, 43, 18, 5, 35, 52, 13, 26,
- 0, 42, 23, 61, 46, 4, 57, 19, 31, 53, 8, 34, 49, 27, 38, 12,
- 62, 20, 41, 3, 16, 58, 7, 45, 33, 11, 54, 28, 15, 37, 24, 50,
- 63, 21, 40, 2, 17, 59, 6, 44, 32, 10, 55, 29, 14, 36, 25, 51,
- 1, 43, 22, 60, 47, 5, 56, 18, 30, 52, 9, 35, 48, 26, 39, 13,
- 0, 21, 42, 63, 23, 2, 61, 40, 46, 59, 4, 17, 57, 44, 19, 6,
- 31, 10, 53, 32, 8, 29, 34, 55, 49, 36, 27, 14, 38, 51, 12, 25,
- 62, 43, 20, 1, 41, 60, 3, 22, 16, 5, 58, 47, 7, 18, 45, 56,
- 33, 52, 11, 30, 54, 35, 28, 9, 15, 26, 37, 48, 24, 13, 50, 39,
- 0, 43, 21, 62, 42, 1, 63, 20, 23, 60, 2, 41, 61, 22, 40, 3,
- 46, 5, 59, 16, 4, 47, 17, 58, 57, 18, 44, 7, 19, 56, 6, 45,
- 31, 52, 10, 33, 53, 30, 32, 11, 8, 35, 29, 54, 34, 9, 55, 28,
- 49, 26, 36, 15, 27, 48, 14, 37, 38, 13, 51, 24, 12, 39, 25, 50,
- 0, 52, 43, 31, 21, 33, 62, 10, 42, 30, 1, 53, 63, 11, 20, 32,
- 23, 35, 60, 8, 2, 54, 41, 29, 61, 9, 22, 34, 40, 28, 3, 55,
- 46, 26, 5, 49, 59, 15, 16, 36, 4, 48, 47, 27, 17, 37, 58, 14,
- 57, 13, 18, 38, 44, 24, 7, 51, 19, 39, 56, 12, 6, 50, 45, 25,
- 0, 26, 52, 46, 43, 49, 31, 5, 21, 15, 33, 59, 62, 36, 10, 16,
- 42, 48, 30, 4, 1, 27, 53, 47, 63, 37, 11, 17, 20, 14, 32, 58,
- 23, 13, 35, 57, 60, 38, 8, 18, 2, 24, 54, 44, 41, 51, 29, 7,
- 61, 39, 9, 19, 22, 12, 34, 56, 40, 50, 28, 6, 3, 25, 55, 45,
- 0, 13, 26, 23, 52, 57, 46, 35, 43, 38, 49, 60, 31, 18, 5, 8,
- 21, 24, 15, 2, 33, 44, 59, 54, 62, 51, 36, 41, 10, 7, 16, 29,
- 42, 39, 48, 61, 30, 19, 4, 9, 1, 12, 27, 22, 53, 56, 47, 34,
- 63, 50, 37, 40, 11, 6, 17, 28, 20, 25, 14, 3, 32, 45, 58, 55,
- 0, 39, 13, 42, 26, 61, 23, 48, 52, 19, 57, 30, 46, 9, 35, 4,
- 43, 12, 38, 1, 49, 22, 60, 27, 31, 56, 18, 53, 5, 34, 8, 47,
- 21, 50, 24, 63, 15, 40, 2, 37, 33, 6, 44, 11, 59, 28, 54, 17,
- 62, 25, 51, 20, 36, 3, 41, 14, 10, 45, 7, 32, 16, 55, 29, 58,
- 0, 50, 39, 21, 13, 63, 42, 24, 26, 40, 61, 15, 23, 37, 48, 2,
- 52, 6, 19, 33, 57, 11, 30, 44, 46, 28, 9, 59, 35, 17, 4, 54,
- 43, 25, 12, 62, 38, 20, 1, 51, 49, 3, 22, 36, 60, 14, 27, 41,
- 31, 45, 56, 10, 18, 32, 53, 7, 5, 55, 34, 16, 8, 58, 47, 29,
- 0, 25, 50, 43, 39, 62, 21, 12, 13, 20, 63, 38, 42, 51, 24, 1,
- 26, 3, 40, 49, 61, 36, 15, 22, 23, 14, 37, 60, 48, 41, 2, 27,
- 52, 45, 6, 31, 19, 10, 33, 56, 57, 32, 11, 18, 30, 7, 44, 53,
- 46, 55, 28, 5, 9, 16, 59, 34, 35, 58, 17, 8, 4, 29, 54, 47,
- 0, 45, 25, 52, 50, 31, 43, 6, 39, 10, 62, 19, 21, 56, 12, 33,
- 13, 32, 20, 57, 63, 18, 38, 11, 42, 7, 51, 30, 24, 53, 1, 44,
- 26, 55, 3, 46, 40, 5, 49, 28, 61, 16, 36, 9, 15, 34, 22, 59,
- 23, 58, 14, 35, 37, 8, 60, 17, 48, 29, 41, 4, 2, 47, 27, 54,
- 0, 55, 45, 26, 25, 46, 52, 3, 50, 5, 31, 40, 43, 28, 6, 49,
- 39, 16, 10, 61, 62, 9, 19, 36, 21, 34, 56, 15, 12, 59, 33, 22,
- 13, 58, 32, 23, 20, 35, 57, 14, 63, 8, 18, 37, 38, 17, 11, 60,
- 42, 29, 7, 48, 51, 4, 30, 41, 24, 47, 53, 2, 1, 54, 44, 27,
- 0, 58, 55, 13, 45, 23, 26, 32, 25, 35, 46, 20, 52, 14, 3, 57,
- 50, 8, 5, 63, 31, 37, 40, 18, 43, 17, 28, 38, 6, 60, 49, 11,
- 39, 29, 16, 42, 10, 48, 61, 7, 62, 4, 9, 51, 19, 41, 36, 30,
- 21, 47, 34, 24, 56, 2, 15, 53, 12, 54, 59, 1, 33, 27, 22, 44,
- 0, 29, 58, 39, 55, 42, 13, 16, 45, 48, 23, 10, 26, 7, 32, 61,
- 25, 4, 35, 62, 46, 51, 20, 9, 52, 41, 14, 19, 3, 30, 57, 36,
- 50, 47, 8, 21, 5, 24, 63, 34, 31, 2, 37, 56, 40, 53, 18, 15,
- 43, 54, 17, 12, 28, 1, 38, 59, 6, 27, 60, 33, 49, 44, 11, 22,
- 0, 47, 29, 50, 58, 21, 39, 8, 55, 24, 42, 5, 13, 34, 16, 63,
- 45, 2, 48, 31, 23, 56, 10, 37, 26, 53, 7, 40, 32, 15, 61, 18,
- 25, 54, 4, 43, 35, 12, 62, 17, 46, 1, 51, 28, 20, 59, 9, 38,
- 52, 27, 41, 6, 14, 33, 19, 60, 3, 44, 30, 49, 57, 22, 36, 11,
- 0, 54, 47, 25, 29, 43, 50, 4, 58, 12, 21, 35, 39, 17, 8, 62,
- 55, 1, 24, 46, 42, 28, 5, 51, 13, 59, 34, 20, 16, 38, 63, 9,
- 45, 27, 2, 52, 48, 6, 31, 41, 23, 33, 56, 14, 10, 60, 37, 19,
- 26, 44, 53, 3, 7, 49, 40, 30, 32, 22, 15, 57, 61, 11, 18, 36,
- 0, 27, 54, 45, 47, 52, 25, 2, 29, 6, 43, 48, 50, 41, 4, 31,
- 58, 33, 12, 23, 21, 14, 35, 56, 39, 60, 17, 10, 8, 19, 62, 37,
- 55, 44, 1, 26, 24, 3, 46, 53, 42, 49, 28, 7, 5, 30, 51, 40,
- 13, 22, 59, 32, 34, 57, 20, 15, 16, 11, 38, 61, 63, 36, 9, 18,
- 0, 44, 27, 55, 54, 26, 45, 1, 47, 3, 52, 24, 25, 53, 2, 46,
- 29, 49, 6, 42, 43, 7, 48, 28, 50, 30, 41, 5, 4, 40, 31, 51,
- 58, 22, 33, 13, 12, 32, 23, 59, 21, 57, 14, 34, 35, 15, 56, 20,
- 39, 11, 60, 16, 17, 61, 10, 38, 8, 36, 19, 63, 62, 18, 37, 9,
- 0, 22, 44, 58, 27, 13, 55, 33, 54, 32, 26, 12, 45, 59, 1, 23,
- 47, 57, 3, 21, 52, 34, 24, 14, 25, 15, 53, 35, 2, 20, 46, 56,
- 29, 11, 49, 39, 6, 16, 42, 60, 43, 61, 7, 17, 48, 38, 28, 10,
- 50, 36, 30, 8, 41, 63, 5, 19, 4, 18, 40, 62, 31, 9, 51, 37,
- 0, 11, 22, 29, 44, 39, 58, 49, 27, 16, 13, 6, 55, 60, 33, 42,
- 54, 61, 32, 43, 26, 17, 12, 7, 45, 38, 59, 48, 1, 10, 23, 28,
- 47, 36, 57, 50, 3, 8, 21, 30, 52, 63, 34, 41, 24, 19, 14, 5,
- 25, 18, 15, 4, 53, 62, 35, 40, 2, 9, 20, 31, 46, 37, 56, 51,
- 0, 36, 11, 47, 22, 50, 29, 57, 44, 8, 39, 3, 58, 30, 49, 21,
- 27, 63, 16, 52, 13, 41, 6, 34, 55, 19, 60, 24, 33, 5, 42, 14,
- 54, 18, 61, 25, 32, 4, 43, 15, 26, 62, 17, 53, 12, 40, 7, 35,
- 45, 9, 38, 2, 59, 31, 48, 20, 1, 37, 10, 46, 23, 51, 28, 56,
- 0, 18, 36, 54, 11, 25, 47, 61, 22, 4, 50, 32, 29, 15, 57, 43,
- 44, 62, 8, 26, 39, 53, 3, 17, 58, 40, 30, 12, 49, 35, 21, 7,
- 27, 9, 63, 45, 16, 2, 52, 38, 13, 31, 41, 59, 6, 20, 34, 48,
- 55, 37, 19, 1, 60, 46, 24, 10, 33, 51, 5, 23, 42, 56, 14, 28,
- 0, 9, 18, 27, 36, 45, 54, 63, 11, 2, 25, 16, 47, 38, 61, 52,
- 22, 31, 4, 13, 50, 59, 32, 41, 29, 20, 15, 6, 57, 48, 43, 34,
- 44, 37, 62, 55, 8, 1, 26, 19, 39, 46, 53, 60, 3, 10, 17, 24,
- 58, 51, 40, 33, 30, 23, 12, 5, 49, 56, 35, 42, 21, 28, 7, 14,
- 0, 37, 9, 44, 18, 55, 27, 62, 36, 1, 45, 8, 54, 19, 63, 26,
- 11, 46, 2, 39, 25, 60, 16, 53, 47, 10, 38, 3, 61, 24, 52, 17,
- 22, 51, 31, 58, 4, 33, 13, 40, 50, 23, 59, 30, 32, 5, 41, 12,
- 29, 56, 20, 49, 15, 42, 6, 35, 57, 28, 48, 21, 43, 14, 34, 7,
- 0, 51, 37, 22, 9, 58, 44, 31, 18, 33, 55, 4, 27, 40, 62, 13,
- 36, 23, 1, 50, 45, 30, 8, 59, 54, 5, 19, 32, 63, 12, 26, 41,
- 11, 56, 46, 29, 2, 49, 39, 20, 25, 42, 60, 15, 16, 35, 53, 6,
- 47, 28, 10, 57, 38, 21, 3, 48, 61, 14, 24, 43, 52, 7, 17, 34,
- 0, 56, 51, 11, 37, 29, 22, 46, 9, 49, 58, 2, 44, 20, 31, 39,
- 18, 42, 33, 25, 55, 15, 4, 60, 27, 35, 40, 16, 62, 6, 13, 53,
- 36, 28, 23, 47, 1, 57, 50, 10, 45, 21, 30, 38, 8, 48, 59, 3,
- 54, 14, 5, 61, 19, 43, 32, 24, 63, 7, 12, 52, 26, 34, 41, 17,
- 0, 28, 56, 36, 51, 47, 11, 23, 37, 57, 29, 1, 22, 10, 46, 50,
- 9, 21, 49, 45, 58, 38, 2, 30, 44, 48, 20, 8, 31, 3, 39, 59,
- 18, 14, 42, 54, 33, 61, 25, 5, 55, 43, 15, 19, 4, 24, 60, 32,
- 27, 7, 35, 63, 40, 52, 16, 12, 62, 34, 6, 26, 13, 17, 53, 41,
- 0, 14, 28, 18, 56, 54, 36, 42, 51, 61, 47, 33, 11, 5, 23, 25,
- 37, 43, 57, 55, 29, 19, 1, 15, 22, 24, 10, 4, 46, 32, 50, 60,
- 9, 7, 21, 27, 49, 63, 45, 35, 58, 52, 38, 40, 2, 12, 30, 16,
- 44, 34, 48, 62, 20, 26, 8, 6, 31, 17, 3, 13, 39, 41, 59, 53,
- 0, 7, 14, 9, 28, 27, 18, 21, 56, 63, 54, 49, 36, 35, 42, 45,
- 51, 52, 61, 58, 47, 40, 33, 38, 11, 12, 5, 2, 23, 16, 25, 30,
- 37, 34, 43, 44, 57, 62, 55, 48, 29, 26, 19, 20, 1, 6, 15, 8,
- 22, 17, 24, 31, 10, 13, 4, 3, 46, 41, 32, 39, 50, 53, 60, 59,
- 0, 34, 7, 37, 14, 44, 9, 43, 28, 62, 27, 57, 18, 48, 21, 55,
- 56, 26, 63, 29, 54, 20, 49, 19, 36, 6, 35, 1, 42, 8, 45, 15,
- 51, 17, 52, 22, 61, 31, 58, 24, 47, 13, 40, 10, 33, 3, 38, 4,
- 11, 41, 12, 46, 5, 39, 2, 32, 23, 53, 16, 50, 25, 59, 30, 60,
- 0, 17, 34, 51, 7, 22, 37, 52, 14, 31, 44, 61, 9, 24, 43, 58,
- 28, 13, 62, 47, 27, 10, 57, 40, 18, 3, 48, 33, 21, 4, 55, 38,
- 56, 41, 26, 11, 63, 46, 29, 12, 54, 39, 20, 5, 49, 32, 19, 2,
- 36, 53, 6, 23, 35, 50, 1, 16, 42, 59, 8, 25, 45, 60, 15, 30,
- 0, 41, 17, 56, 34, 11, 51, 26, 7, 46, 22, 63, 37, 12, 52, 29,
- 14, 39, 31, 54, 44, 5, 61, 20, 9, 32, 24, 49, 43, 2, 58, 19,
- 28, 53, 13, 36, 62, 23, 47, 6, 27, 50, 10, 35, 57, 16, 40, 1,
- 18, 59, 3, 42, 48, 25, 33, 8, 21, 60, 4, 45, 55, 30, 38, 15,
- 0, 53, 41, 28, 17, 36, 56, 13, 34, 23, 11, 62, 51, 6, 26, 47,
- 7, 50, 46, 27, 22, 35, 63, 10, 37, 16, 12, 57, 52, 1, 29, 40,
- 14, 59, 39, 18, 31, 42, 54, 3, 44, 25, 5, 48, 61, 8, 20, 33,
- 9, 60, 32, 21, 24, 45, 49, 4, 43, 30, 2, 55, 58, 15, 19, 38,
- 0, 59, 53, 14, 41, 18, 28, 39, 17, 42, 36, 31, 56, 3, 13, 54,
- 34, 25, 23, 44, 11, 48, 62, 5, 51, 8, 6, 61, 26, 33, 47, 20,
- 7, 60, 50, 9, 46, 21, 27, 32, 22, 45, 35, 24, 63, 4, 10, 49,
- 37, 30, 16, 43, 12, 55, 57, 2, 52, 15, 1, 58, 29, 38, 40, 19,
- 0, 60, 59, 7, 53, 9, 14, 50, 41, 21, 18, 46, 28, 32, 39, 27,
- 17, 45, 42, 22, 36, 24, 31, 35, 56, 4, 3, 63, 13, 49, 54, 10,
- 34, 30, 25, 37, 23, 43, 44, 16, 11, 55, 48, 12, 62, 2, 5, 57,
- 51, 15, 8, 52, 6, 58, 61, 1, 26, 38, 33, 29, 47, 19, 20, 40,
- 0, 30, 60, 34, 59, 37, 7, 25, 53, 43, 9, 23, 14, 16, 50, 44,
- 41, 55, 21, 11, 18, 12, 46, 48, 28, 2, 32, 62, 39, 57, 27, 5,
- 17, 15, 45, 51, 42, 52, 22, 8, 36, 58, 24, 6, 31, 1, 35, 61,
- 56, 38, 4, 26, 3, 29, 63, 33, 13, 19, 49, 47, 54, 40, 10, 20,
- 0, 15, 30, 17, 60, 51, 34, 45, 59, 52, 37, 42, 7, 8, 25, 22,
- 53, 58, 43, 36, 9, 6, 23, 24, 14, 1, 16, 31, 50, 61, 44, 35,
- 41, 38, 55, 56, 21, 26, 11, 4, 18, 29, 12, 3, 46, 33, 48, 63,
- 28, 19, 2, 13, 32, 47, 62, 49, 39, 40, 57, 54, 27, 20, 5, 10,
- 0, 38, 15, 41, 30, 56, 17, 55, 60, 26, 51, 21, 34, 4, 45, 11,
- 59, 29, 52, 18, 37, 3, 42, 12, 7, 33, 8, 46, 25, 63, 22, 48,
- 53, 19, 58, 28, 43, 13, 36, 2, 9, 47, 6, 32, 23, 49, 24, 62,
- 14, 40, 1, 39, 16, 54, 31, 57, 50, 20, 61, 27, 44, 10, 35, 5,
- 0, 19, 38, 53, 15, 28, 41, 58, 30, 13, 56, 43, 17, 2, 55, 36,
- 60, 47, 26, 9, 51, 32, 21, 6, 34, 49, 4, 23, 45, 62, 11, 24,
- 59, 40, 29, 14, 52, 39, 18, 1, 37, 54, 3, 16, 42, 57, 12, 31,
- 7, 20, 33, 50, 8, 27, 46, 61, 25, 10, 63, 44, 22, 5, 48, 35,
- 0, 40, 19, 59, 38, 14, 53, 29, 15, 39, 28, 52, 41, 1, 58, 18,
- 30, 54, 13, 37, 56, 16, 43, 3, 17, 57, 2, 42, 55, 31, 36, 12,
- 60, 20, 47, 7, 26, 50, 9, 33, 51, 27, 32, 8, 21, 61, 6, 46,
- 34, 10, 49, 25, 4, 44, 23, 63, 45, 5, 62, 22, 11, 35, 24, 48,
- 0, 20, 40, 60, 19, 7, 59, 47, 38, 50, 14, 26, 53, 33, 29, 9,
- 15, 27, 39, 51, 28, 8, 52, 32, 41, 61, 1, 21, 58, 46, 18, 6,
- 30, 10, 54, 34, 13, 25, 37, 49, 56, 44, 16, 4, 43, 63, 3, 23,
- 17, 5, 57, 45, 2, 22, 42, 62, 55, 35, 31, 11, 36, 48, 12, 24,
- 0, 10, 20, 30, 40, 34, 60, 54, 19, 25, 7, 13, 59, 49, 47, 37,
- 38, 44, 50, 56, 14, 4, 26, 16, 53, 63, 33, 43, 29, 23, 9, 3,
- 15, 5, 27, 17, 39, 45, 51, 57, 28, 22, 8, 2, 52, 62, 32, 42,
- 41, 35, 61, 55, 1, 11, 21, 31, 58, 48, 46, 36, 18, 24, 6, 12,
- 0, 5, 10, 15, 20, 17, 30, 27, 40, 45, 34, 39, 60, 57, 54, 51,
- 19, 22, 25, 28, 7, 2, 13, 8, 59, 62, 49, 52, 47, 42, 37, 32,
- 38, 35, 44, 41, 50, 55, 56, 61, 14, 11, 4, 1, 26, 31, 16, 21,
- 53, 48, 63, 58, 33, 36, 43, 46, 29, 24, 23, 18, 9, 12, 3, 6,
- 0, 35, 5, 38, 10, 41, 15, 44, 20, 55, 17, 50, 30, 61, 27, 56,
- 40, 11, 45, 14, 34, 1, 39, 4, 60, 31, 57, 26, 54, 21, 51, 16,
- 19, 48, 22, 53, 25, 58, 28, 63, 7, 36, 2, 33, 13, 46, 8, 43,
- 59, 24, 62, 29, 49, 18, 52, 23, 47, 12, 42, 9, 37, 6, 32, 3,
- 0, 48, 35, 19, 5, 53, 38, 22, 10, 58, 41, 25, 15, 63, 44, 28,
- 20, 36, 55, 7, 17, 33, 50, 2, 30, 46, 61, 13, 27, 43, 56, 8,
- 40, 24, 11, 59, 45, 29, 14, 62, 34, 18, 1, 49, 39, 23, 4, 52,
- 60, 12, 31, 47, 57, 9, 26, 42, 54, 6, 21, 37, 51, 3, 16, 32,
- 0, 24, 48, 40, 35, 59, 19, 11, 5, 29, 53, 45, 38, 62, 22, 14,
- 10, 18, 58, 34, 41, 49, 25, 1, 15, 23, 63, 39, 44, 52, 28, 4,
- 20, 12, 36, 60, 55, 47, 7, 31, 17, 9, 33, 57, 50, 42, 2, 26,
- 30, 6, 46, 54, 61, 37, 13, 21, 27, 3, 43, 51, 56, 32, 8, 16,
- 0, 12, 24, 20, 48, 60, 40, 36, 35, 47, 59, 55, 19, 31, 11, 7,
- 5, 9, 29, 17, 53, 57, 45, 33, 38, 42, 62, 50, 22, 26, 14, 2,
- 10, 6, 18, 30, 58, 54, 34, 46, 41, 37, 49, 61, 25, 21, 1, 13,
- 15, 3, 23, 27, 63, 51, 39, 43, 44, 32, 52, 56, 28, 16, 4, 8,
- 0, 6, 12, 10, 24, 30, 20, 18, 48, 54, 60, 58, 40, 46, 36, 34,
- 35, 37, 47, 41, 59, 61, 55, 49, 19, 21, 31, 25, 11, 13, 7, 1,
- 5, 3, 9, 15, 29, 27, 17, 23, 53, 51, 57, 63, 45, 43, 33, 39,
- 38, 32, 42, 44, 62, 56, 50, 52, 22, 16, 26, 28, 14, 8, 2, 4,
- 0, 3, 6, 5, 12, 15, 10, 9, 24, 27, 30, 29, 20, 23, 18, 17,
- 48, 51, 54, 53, 60, 63, 58, 57, 40, 43, 46, 45, 36, 39, 34, 33,
- 35, 32, 37, 38, 47, 44, 41, 42, 59, 56, 61, 62, 55, 52, 49, 50,
- 19, 16, 21, 22, 31, 28, 25, 26, 11, 8, 13, 14, 7, 4, 1, 2,
- 0, 32, 3, 35, 6, 38, 5, 37, 12, 44, 15, 47, 10, 42, 9, 41,
- 24, 56, 27, 59, 30, 62, 29, 61, 20, 52, 23, 55, 18, 50, 17, 49,
- 48, 16, 51, 19, 54, 22, 53, 21, 60, 28, 63, 31, 58, 26, 57, 25,
- 40, 8, 43, 11, 46, 14, 45, 13, 36, 4, 39, 7, 34, 2, 33, 1,
- 0, 16, 32, 48, 3, 19, 35, 51, 6, 22, 38, 54, 5, 21, 37, 53,
- 12, 28, 44, 60, 15, 31, 47, 63, 10, 26, 42, 58, 9, 25, 41, 57,
- 24, 8, 56, 40, 27, 11, 59, 43, 30, 14, 62, 46, 29, 13, 61, 45,
- 20, 4, 52, 36, 23, 7, 55, 39, 18, 2, 50, 34, 17, 1, 49, 33,
- 0, 8, 16, 24, 32, 40, 48, 56, 3, 11, 19, 27, 35, 43, 51, 59,
- 6, 14, 22, 30, 38, 46, 54, 62, 5, 13, 21, 29, 37, 45, 53, 61,
- 12, 4, 28, 20, 44, 36, 60, 52, 15, 7, 31, 23, 47, 39, 63, 55,
- 10, 2, 26, 18, 42, 34, 58, 50, 9, 1, 25, 17, 41, 33, 57, 49,
- 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
- 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63,
- 6, 2, 14, 10, 22, 18, 30, 26, 38, 34, 46, 42, 54, 50, 62, 58,
- 5, 1, 13, 9, 21, 17, 29, 25, 37, 33, 45, 41, 53, 49, 61, 57,
- 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
- 3, 1, 7, 5, 11, 9, 15, 13, 19, 17, 23, 21, 27, 25, 31, 29,
- 35, 33, 39, 37, 43, 41, 47, 45, 51, 49, 55, 53, 59, 57, 63, 61
-};
-
-const qracode qra_12_63_64_irr_b = {
- qra_K,
- qra_N,
- qra_m,
- qra_M,
- qra_a,
- qra_NC,
- qra_V,
- qra_C,
- qra_NMSG,
- qra_MAXVDEG,
- qra_MAXCDEG,
- QRATYPE_NORMAL,
- qra_R,
- CODE_NAME,
- qra_acc_input_idx,
- qra_acc_input_wlog,
- qra_log,
- qra_exp,
- qra_msgw,
- qra_vdeg,
- qra_cdeg,
- qra_v2cmidx,
- qra_c2vmidx,
- qra_pmat
-};
-
-#undef qra_K
-#undef qra_N
-#undef qra_m
-#undef qra_M
-#undef qra_a
-#undef qra_NC
-#undef qra_V
-#undef qra_C
-#undef qra_NMSG
-#undef qra_MAXVDEG
-#undef qra_MAXCDEG
-#undef qra_R
-#undef CODE_NAME
\ No newline at end of file
diff --git a/lib/qra/qracodes/qra12_63_64_irr_b.h b/lib/qra/qracodes/qra12_63_64_irr_b.h
deleted file mode 100644
index bf70b36..0000000
--- a/lib/qra/qracodes/qra12_63_64_irr_b.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// qra12_63_64_irr_b.h
-// Code tables and defines for Q-ary RA code (12,63) over GF(64)
-// Code Name: qra12_63_64_irr_b
-// (12,63) RA Code over GF(64) - RF=333344455567
-
-// (c) 2016 - Nico Palermo - IV3NWV - Microtelecom Srl, Italy
-
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#ifndef _qra12_63_64_irr_b_h
-#define _qra12_63_64_irr_b_h
-
-#include "qracodes.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern const qracode qra_12_63_64_irr_b;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _qra12_63_64_irr_b_h
diff --git a/lib/qra/qracodes/qra13_64_64_irr_e.c b/lib/qra/qracodes/qra13_64_64_irr_e.c
deleted file mode 100644
index 7adf22f..0000000
--- a/lib/qra/qracodes/qra13_64_64_irr_e.c
+++ /dev/null
@@ -1,534 +0,0 @@
-// qra13_64_64_irr_e.c
-// Encoding/Decoding tables for Q-ary RA code (13,64) over GF(64)
-// Code Name: qra13_64_64_irr_e
-// (13,64) RA Code over GF(64) RF=[3x4 4x4 6x1 3x2 5x1 7x1]/18
-
-// (c) 2016 - Nico Palermo - IV3NWV - Microtelecom Srl, Italy
-
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#include "qra13_64_64_irr_e.h"
-
-#define qra_K 13 // number of information symbols
-#define qra_N 64 // codeword length in symbols
-#define qra_m 6 // bits/symbol
-#define qra_M 64 // Symbol alphabet cardinality
-#define qra_a 1 // grouping factor
-#define qra_NC 51 // number of check symbols (N-K)
-
-// Defines used by the message passing decoder --------
-
-#define qra_V 64 // number of variables in the code graph (N)
-#define qra_C 116 // number of factors in the code graph (N +(N-K)+1)
-#define qra_NMSG 218 // number of msgs in the code graph
-#define qra_MAXVDEG 8 // maximum variable degree
-#define qra_MAXCDEG 3 // maximum factor degree
-#define qra_R 0.20313f // code rate (K/N)
-#define CODE_NAME "qra_13_64_64_irr_e"
-
-// table of the systematic symbols indexes in the accumulator chain
-static const int qra_acc_input_idx[qra_NC+1] = {
- 12, 4, 3, 9, 0, 11, 6, 8, 12, 1,
- 2, 7, 4, 11, 3, 5, 9, 8, 12, 7,
- 2, 4, 10, 3, 5, 11, 12, 8, 9, 6,
- 7, 2, 5, 4, 12, 8, 11, 1, 6, 7,
- 0, 10, 12, 8, 11, 5, 6, 1, 0, 10,
- 12, 8
-};
-
-// table of the systematic symbols weight logarithms over GF(M)
-static const int qra_acc_input_wlog[qra_NC+1] = {
- 0, 27, 0, 0, 0, 31, 28, 61, 31, 0,
- 0, 52, 22, 7, 19, 47, 44, 62, 32, 50,
- 52, 42, 48, 56, 40, 50, 51, 37, 37, 0,
- 5, 14, 0, 0, 18, 2, 0, 45, 21, 0,
- 62, 8, 11, 60, 36, 32, 17, 9, 5, 0,
- 53, 0
-};
-
-// table of the logarithms of the elements of GF(M) (log(0) never used)
-static const int qra_log[qra_M] = {
- -1, 0, 1, 6, 2, 12, 7, 26, 3, 32,
- 13, 35, 8, 48, 27, 18, 4, 24, 33, 16,
- 14, 52, 36, 54, 9, 45, 49, 38, 28, 41,
- 19, 56, 5, 62, 25, 11, 34, 31, 17, 47,
- 15, 23, 53, 51, 37, 44, 55, 40, 10, 61,
- 46, 30, 50, 22, 39, 43, 29, 60, 42, 21,
- 20, 59, 57, 58
-};
-
-// table of GF(M) elements given their logarithm
-static const int qra_exp[qra_M-1] = {
- 1, 2, 4, 8, 16, 32, 3, 6, 12, 24,
- 48, 35, 5, 10, 20, 40, 19, 38, 15, 30,
- 60, 59, 53, 41, 17, 34, 7, 14, 28, 56,
- 51, 37, 9, 18, 36, 11, 22, 44, 27, 54,
- 47, 29, 58, 55, 45, 25, 50, 39, 13, 26,
- 52, 43, 21, 42, 23, 46, 31, 62, 63, 61,
- 57, 49, 33
-};
-
-// table of the messages weight logarithms over GF(M)
-static const int qra_msgw[qra_NMSG] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 27, 0, 0, 0, 31,
- 28, 61, 31, 0, 0, 52, 22, 7, 19, 47,
- 44, 62, 32, 50, 52, 42, 48, 56, 40, 50,
- 51, 37, 37, 0, 5, 14, 0, 0, 18, 2,
- 0, 45, 21, 0, 62, 8, 11, 60, 36, 32,
- 17, 9, 5, 0, 53, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-// table of the degrees of the variable nodes
-static const int qra_vdeg[qra_V] = {
- 4, 4, 4, 4, 5, 5, 5, 5, 7, 4,
- 4, 6, 8, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3
-};
-
-// table of the degrees of the factor nodes
-static const int qra_cdeg[qra_C] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 2, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 2
-};
-
-// table (uncompressed) of the v->c message indexes (-1=unused entry)
-static const int qra_v2cmidx[qra_V*qra_MAXVDEG] = {
- 0, 68, 104, 112, -1, -1, -1, -1,
- 1, 73, 101, 111, -1, -1, -1, -1,
- 2, 74, 84, 95, -1, -1, -1, -1,
- 3, 66, 78, 87, -1, -1, -1, -1,
- 4, 65, 76, 85, 97, -1, -1, -1,
- 5, 79, 88, 96, 109, -1, -1, -1,
- 6, 70, 93, 102, 110, -1, -1, -1,
- 7, 75, 83, 94, 103, -1, -1, -1,
- 8, 71, 81, 91, 99, 107, 115, -1,
- 9, 67, 80, 92, -1, -1, -1, -1,
- 10, 86, 105, 113, -1, -1, -1, -1,
- 11, 69, 77, 89, 100, 108, -1, -1,
- 12, 64, 72, 82, 90, 98, 106, 114,
- 13, 116, 117, -1, -1, -1, -1, -1,
- 14, 118, 119, -1, -1, -1, -1, -1,
- 15, 120, 121, -1, -1, -1, -1, -1,
- 16, 122, 123, -1, -1, -1, -1, -1,
- 17, 124, 125, -1, -1, -1, -1, -1,
- 18, 126, 127, -1, -1, -1, -1, -1,
- 19, 128, 129, -1, -1, -1, -1, -1,
- 20, 130, 131, -1, -1, -1, -1, -1,
- 21, 132, 133, -1, -1, -1, -1, -1,
- 22, 134, 135, -1, -1, -1, -1, -1,
- 23, 136, 137, -1, -1, -1, -1, -1,
- 24, 138, 139, -1, -1, -1, -1, -1,
- 25, 140, 141, -1, -1, -1, -1, -1,
- 26, 142, 143, -1, -1, -1, -1, -1,
- 27, 144, 145, -1, -1, -1, -1, -1,
- 28, 146, 147, -1, -1, -1, -1, -1,
- 29, 148, 149, -1, -1, -1, -1, -1,
- 30, 150, 151, -1, -1, -1, -1, -1,
- 31, 152, 153, -1, -1, -1, -1, -1,
- 32, 154, 155, -1, -1, -1, -1, -1,
- 33, 156, 157, -1, -1, -1, -1, -1,
- 34, 158, 159, -1, -1, -1, -1, -1,
- 35, 160, 161, -1, -1, -1, -1, -1,
- 36, 162, 163, -1, -1, -1, -1, -1,
- 37, 164, 165, -1, -1, -1, -1, -1,
- 38, 166, 167, -1, -1, -1, -1, -1,
- 39, 168, 169, -1, -1, -1, -1, -1,
- 40, 170, 171, -1, -1, -1, -1, -1,
- 41, 172, 173, -1, -1, -1, -1, -1,
- 42, 174, 175, -1, -1, -1, -1, -1,
- 43, 176, 177, -1, -1, -1, -1, -1,
- 44, 178, 179, -1, -1, -1, -1, -1,
- 45, 180, 181, -1, -1, -1, -1, -1,
- 46, 182, 183, -1, -1, -1, -1, -1,
- 47, 184, 185, -1, -1, -1, -1, -1,
- 48, 186, 187, -1, -1, -1, -1, -1,
- 49, 188, 189, -1, -1, -1, -1, -1,
- 50, 190, 191, -1, -1, -1, -1, -1,
- 51, 192, 193, -1, -1, -1, -1, -1,
- 52, 194, 195, -1, -1, -1, -1, -1,
- 53, 196, 197, -1, -1, -1, -1, -1,
- 54, 198, 199, -1, -1, -1, -1, -1,
- 55, 200, 201, -1, -1, -1, -1, -1,
- 56, 202, 203, -1, -1, -1, -1, -1,
- 57, 204, 205, -1, -1, -1, -1, -1,
- 58, 206, 207, -1, -1, -1, -1, -1,
- 59, 208, 209, -1, -1, -1, -1, -1,
- 60, 210, 211, -1, -1, -1, -1, -1,
- 61, 212, 213, -1, -1, -1, -1, -1,
- 62, 214, 215, -1, -1, -1, -1, -1,
- 63, 216, 217, -1, -1, -1, -1, -1
-};
-
-// table (uncompressed) of the c->v message indexes (-1=unused entry)
-static const int qra_c2vmidx[qra_C*qra_MAXCDEG] = {
- 0, -1, -1, 1, -1, -1, 2, -1, -1, 3, -1, -1,
- 4, -1, -1, 5, -1, -1, 6, -1, -1, 7, -1, -1,
- 8, -1, -1, 9, -1, -1, 10, -1, -1, 11, -1, -1,
- 12, -1, -1, 13, -1, -1, 14, -1, -1, 15, -1, -1,
- 16, -1, -1, 17, -1, -1, 18, -1, -1, 19, -1, -1,
- 20, -1, -1, 21, -1, -1, 22, -1, -1, 23, -1, -1,
- 24, -1, -1, 25, -1, -1, 26, -1, -1, 27, -1, -1,
- 28, -1, -1, 29, -1, -1, 30, -1, -1, 31, -1, -1,
- 32, -1, -1, 33, -1, -1, 34, -1, -1, 35, -1, -1,
- 36, -1, -1, 37, -1, -1, 38, -1, -1, 39, -1, -1,
- 40, -1, -1, 41, -1, -1, 42, -1, -1, 43, -1, -1,
- 44, -1, -1, 45, -1, -1, 46, -1, -1, 47, -1, -1,
- 48, -1, -1, 49, -1, -1, 50, -1, -1, 51, -1, -1,
- 52, -1, -1, 53, -1, -1, 54, -1, -1, 55, -1, -1,
- 56, -1, -1, 57, -1, -1, 58, -1, -1, 59, -1, -1,
- 60, -1, -1, 61, -1, -1, 62, -1, -1, 63, -1, -1,
- 64, 116, -1, 65, 117, 118, 66, 119, 120, 67, 121, 122,
- 68, 123, 124, 69, 125, 126, 70, 127, 128, 71, 129, 130,
- 72, 131, 132, 73, 133, 134, 74, 135, 136, 75, 137, 138,
- 76, 139, 140, 77, 141, 142, 78, 143, 144, 79, 145, 146,
- 80, 147, 148, 81, 149, 150, 82, 151, 152, 83, 153, 154,
- 84, 155, 156, 85, 157, 158, 86, 159, 160, 87, 161, 162,
- 88, 163, 164, 89, 165, 166, 90, 167, 168, 91, 169, 170,
- 92, 171, 172, 93, 173, 174, 94, 175, 176, 95, 177, 178,
- 96, 179, 180, 97, 181, 182, 98, 183, 184, 99, 185, 186,
-100, 187, 188, 101, 189, 190, 102, 191, 192, 103, 193, 194,
-104, 195, 196, 105, 197, 198, 106, 199, 200, 107, 201, 202,
-108, 203, 204, 109, 205, 206, 110, 207, 208, 111, 209, 210,
-112, 211, 212, 113, 213, 214, 114, 215, 216, 115, 217, -1
-};
-
-// permutation matrix to compute Prob(x*alfa^logw)
-static const int qra_pmat[qra_M*qra_M] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 0, 33, 1, 32, 2, 35, 3, 34, 4, 37, 5, 36, 6, 39, 7, 38,
- 8, 41, 9, 40, 10, 43, 11, 42, 12, 45, 13, 44, 14, 47, 15, 46,
- 16, 49, 17, 48, 18, 51, 19, 50, 20, 53, 21, 52, 22, 55, 23, 54,
- 24, 57, 25, 56, 26, 59, 27, 58, 28, 61, 29, 60, 30, 63, 31, 62,
- 0, 49, 33, 16, 1, 48, 32, 17, 2, 51, 35, 18, 3, 50, 34, 19,
- 4, 53, 37, 20, 5, 52, 36, 21, 6, 55, 39, 22, 7, 54, 38, 23,
- 8, 57, 41, 24, 9, 56, 40, 25, 10, 59, 43, 26, 11, 58, 42, 27,
- 12, 61, 45, 28, 13, 60, 44, 29, 14, 63, 47, 30, 15, 62, 46, 31,
- 0, 57, 49, 8, 33, 24, 16, 41, 1, 56, 48, 9, 32, 25, 17, 40,
- 2, 59, 51, 10, 35, 26, 18, 43, 3, 58, 50, 11, 34, 27, 19, 42,
- 4, 61, 53, 12, 37, 28, 20, 45, 5, 60, 52, 13, 36, 29, 21, 44,
- 6, 63, 55, 14, 39, 30, 22, 47, 7, 62, 54, 15, 38, 31, 23, 46,
- 0, 61, 57, 4, 49, 12, 8, 53, 33, 28, 24, 37, 16, 45, 41, 20,
- 1, 60, 56, 5, 48, 13, 9, 52, 32, 29, 25, 36, 17, 44, 40, 21,
- 2, 63, 59, 6, 51, 14, 10, 55, 35, 30, 26, 39, 18, 47, 43, 22,
- 3, 62, 58, 7, 50, 15, 11, 54, 34, 31, 27, 38, 19, 46, 42, 23,
- 0, 63, 61, 2, 57, 6, 4, 59, 49, 14, 12, 51, 8, 55, 53, 10,
- 33, 30, 28, 35, 24, 39, 37, 26, 16, 47, 45, 18, 41, 22, 20, 43,
- 1, 62, 60, 3, 56, 7, 5, 58, 48, 15, 13, 50, 9, 54, 52, 11,
- 32, 31, 29, 34, 25, 38, 36, 27, 17, 46, 44, 19, 40, 23, 21, 42,
- 0, 62, 63, 1, 61, 3, 2, 60, 57, 7, 6, 56, 4, 58, 59, 5,
- 49, 15, 14, 48, 12, 50, 51, 13, 8, 54, 55, 9, 53, 11, 10, 52,
- 33, 31, 30, 32, 28, 34, 35, 29, 24, 38, 39, 25, 37, 27, 26, 36,
- 16, 46, 47, 17, 45, 19, 18, 44, 41, 23, 22, 40, 20, 42, 43, 21,
- 0, 31, 62, 33, 63, 32, 1, 30, 61, 34, 3, 28, 2, 29, 60, 35,
- 57, 38, 7, 24, 6, 25, 56, 39, 4, 27, 58, 37, 59, 36, 5, 26,
- 49, 46, 15, 16, 14, 17, 48, 47, 12, 19, 50, 45, 51, 44, 13, 18,
- 8, 23, 54, 41, 55, 40, 9, 22, 53, 42, 11, 20, 10, 21, 52, 43,
- 0, 46, 31, 49, 62, 16, 33, 15, 63, 17, 32, 14, 1, 47, 30, 48,
- 61, 19, 34, 12, 3, 45, 28, 50, 2, 44, 29, 51, 60, 18, 35, 13,
- 57, 23, 38, 8, 7, 41, 24, 54, 6, 40, 25, 55, 56, 22, 39, 9,
- 4, 42, 27, 53, 58, 20, 37, 11, 59, 21, 36, 10, 5, 43, 26, 52,
- 0, 23, 46, 57, 31, 8, 49, 38, 62, 41, 16, 7, 33, 54, 15, 24,
- 63, 40, 17, 6, 32, 55, 14, 25, 1, 22, 47, 56, 30, 9, 48, 39,
- 61, 42, 19, 4, 34, 53, 12, 27, 3, 20, 45, 58, 28, 11, 50, 37,
- 2, 21, 44, 59, 29, 10, 51, 36, 60, 43, 18, 5, 35, 52, 13, 26,
- 0, 42, 23, 61, 46, 4, 57, 19, 31, 53, 8, 34, 49, 27, 38, 12,
- 62, 20, 41, 3, 16, 58, 7, 45, 33, 11, 54, 28, 15, 37, 24, 50,
- 63, 21, 40, 2, 17, 59, 6, 44, 32, 10, 55, 29, 14, 36, 25, 51,
- 1, 43, 22, 60, 47, 5, 56, 18, 30, 52, 9, 35, 48, 26, 39, 13,
- 0, 21, 42, 63, 23, 2, 61, 40, 46, 59, 4, 17, 57, 44, 19, 6,
- 31, 10, 53, 32, 8, 29, 34, 55, 49, 36, 27, 14, 38, 51, 12, 25,
- 62, 43, 20, 1, 41, 60, 3, 22, 16, 5, 58, 47, 7, 18, 45, 56,
- 33, 52, 11, 30, 54, 35, 28, 9, 15, 26, 37, 48, 24, 13, 50, 39,
- 0, 43, 21, 62, 42, 1, 63, 20, 23, 60, 2, 41, 61, 22, 40, 3,
- 46, 5, 59, 16, 4, 47, 17, 58, 57, 18, 44, 7, 19, 56, 6, 45,
- 31, 52, 10, 33, 53, 30, 32, 11, 8, 35, 29, 54, 34, 9, 55, 28,
- 49, 26, 36, 15, 27, 48, 14, 37, 38, 13, 51, 24, 12, 39, 25, 50,
- 0, 52, 43, 31, 21, 33, 62, 10, 42, 30, 1, 53, 63, 11, 20, 32,
- 23, 35, 60, 8, 2, 54, 41, 29, 61, 9, 22, 34, 40, 28, 3, 55,
- 46, 26, 5, 49, 59, 15, 16, 36, 4, 48, 47, 27, 17, 37, 58, 14,
- 57, 13, 18, 38, 44, 24, 7, 51, 19, 39, 56, 12, 6, 50, 45, 25,
- 0, 26, 52, 46, 43, 49, 31, 5, 21, 15, 33, 59, 62, 36, 10, 16,
- 42, 48, 30, 4, 1, 27, 53, 47, 63, 37, 11, 17, 20, 14, 32, 58,
- 23, 13, 35, 57, 60, 38, 8, 18, 2, 24, 54, 44, 41, 51, 29, 7,
- 61, 39, 9, 19, 22, 12, 34, 56, 40, 50, 28, 6, 3, 25, 55, 45,
- 0, 13, 26, 23, 52, 57, 46, 35, 43, 38, 49, 60, 31, 18, 5, 8,
- 21, 24, 15, 2, 33, 44, 59, 54, 62, 51, 36, 41, 10, 7, 16, 29,
- 42, 39, 48, 61, 30, 19, 4, 9, 1, 12, 27, 22, 53, 56, 47, 34,
- 63, 50, 37, 40, 11, 6, 17, 28, 20, 25, 14, 3, 32, 45, 58, 55,
- 0, 39, 13, 42, 26, 61, 23, 48, 52, 19, 57, 30, 46, 9, 35, 4,
- 43, 12, 38, 1, 49, 22, 60, 27, 31, 56, 18, 53, 5, 34, 8, 47,
- 21, 50, 24, 63, 15, 40, 2, 37, 33, 6, 44, 11, 59, 28, 54, 17,
- 62, 25, 51, 20, 36, 3, 41, 14, 10, 45, 7, 32, 16, 55, 29, 58,
- 0, 50, 39, 21, 13, 63, 42, 24, 26, 40, 61, 15, 23, 37, 48, 2,
- 52, 6, 19, 33, 57, 11, 30, 44, 46, 28, 9, 59, 35, 17, 4, 54,
- 43, 25, 12, 62, 38, 20, 1, 51, 49, 3, 22, 36, 60, 14, 27, 41,
- 31, 45, 56, 10, 18, 32, 53, 7, 5, 55, 34, 16, 8, 58, 47, 29,
- 0, 25, 50, 43, 39, 62, 21, 12, 13, 20, 63, 38, 42, 51, 24, 1,
- 26, 3, 40, 49, 61, 36, 15, 22, 23, 14, 37, 60, 48, 41, 2, 27,
- 52, 45, 6, 31, 19, 10, 33, 56, 57, 32, 11, 18, 30, 7, 44, 53,
- 46, 55, 28, 5, 9, 16, 59, 34, 35, 58, 17, 8, 4, 29, 54, 47,
- 0, 45, 25, 52, 50, 31, 43, 6, 39, 10, 62, 19, 21, 56, 12, 33,
- 13, 32, 20, 57, 63, 18, 38, 11, 42, 7, 51, 30, 24, 53, 1, 44,
- 26, 55, 3, 46, 40, 5, 49, 28, 61, 16, 36, 9, 15, 34, 22, 59,
- 23, 58, 14, 35, 37, 8, 60, 17, 48, 29, 41, 4, 2, 47, 27, 54,
- 0, 55, 45, 26, 25, 46, 52, 3, 50, 5, 31, 40, 43, 28, 6, 49,
- 39, 16, 10, 61, 62, 9, 19, 36, 21, 34, 56, 15, 12, 59, 33, 22,
- 13, 58, 32, 23, 20, 35, 57, 14, 63, 8, 18, 37, 38, 17, 11, 60,
- 42, 29, 7, 48, 51, 4, 30, 41, 24, 47, 53, 2, 1, 54, 44, 27,
- 0, 58, 55, 13, 45, 23, 26, 32, 25, 35, 46, 20, 52, 14, 3, 57,
- 50, 8, 5, 63, 31, 37, 40, 18, 43, 17, 28, 38, 6, 60, 49, 11,
- 39, 29, 16, 42, 10, 48, 61, 7, 62, 4, 9, 51, 19, 41, 36, 30,
- 21, 47, 34, 24, 56, 2, 15, 53, 12, 54, 59, 1, 33, 27, 22, 44,
- 0, 29, 58, 39, 55, 42, 13, 16, 45, 48, 23, 10, 26, 7, 32, 61,
- 25, 4, 35, 62, 46, 51, 20, 9, 52, 41, 14, 19, 3, 30, 57, 36,
- 50, 47, 8, 21, 5, 24, 63, 34, 31, 2, 37, 56, 40, 53, 18, 15,
- 43, 54, 17, 12, 28, 1, 38, 59, 6, 27, 60, 33, 49, 44, 11, 22,
- 0, 47, 29, 50, 58, 21, 39, 8, 55, 24, 42, 5, 13, 34, 16, 63,
- 45, 2, 48, 31, 23, 56, 10, 37, 26, 53, 7, 40, 32, 15, 61, 18,
- 25, 54, 4, 43, 35, 12, 62, 17, 46, 1, 51, 28, 20, 59, 9, 38,
- 52, 27, 41, 6, 14, 33, 19, 60, 3, 44, 30, 49, 57, 22, 36, 11,
- 0, 54, 47, 25, 29, 43, 50, 4, 58, 12, 21, 35, 39, 17, 8, 62,
- 55, 1, 24, 46, 42, 28, 5, 51, 13, 59, 34, 20, 16, 38, 63, 9,
- 45, 27, 2, 52, 48, 6, 31, 41, 23, 33, 56, 14, 10, 60, 37, 19,
- 26, 44, 53, 3, 7, 49, 40, 30, 32, 22, 15, 57, 61, 11, 18, 36,
- 0, 27, 54, 45, 47, 52, 25, 2, 29, 6, 43, 48, 50, 41, 4, 31,
- 58, 33, 12, 23, 21, 14, 35, 56, 39, 60, 17, 10, 8, 19, 62, 37,
- 55, 44, 1, 26, 24, 3, 46, 53, 42, 49, 28, 7, 5, 30, 51, 40,
- 13, 22, 59, 32, 34, 57, 20, 15, 16, 11, 38, 61, 63, 36, 9, 18,
- 0, 44, 27, 55, 54, 26, 45, 1, 47, 3, 52, 24, 25, 53, 2, 46,
- 29, 49, 6, 42, 43, 7, 48, 28, 50, 30, 41, 5, 4, 40, 31, 51,
- 58, 22, 33, 13, 12, 32, 23, 59, 21, 57, 14, 34, 35, 15, 56, 20,
- 39, 11, 60, 16, 17, 61, 10, 38, 8, 36, 19, 63, 62, 18, 37, 9,
- 0, 22, 44, 58, 27, 13, 55, 33, 54, 32, 26, 12, 45, 59, 1, 23,
- 47, 57, 3, 21, 52, 34, 24, 14, 25, 15, 53, 35, 2, 20, 46, 56,
- 29, 11, 49, 39, 6, 16, 42, 60, 43, 61, 7, 17, 48, 38, 28, 10,
- 50, 36, 30, 8, 41, 63, 5, 19, 4, 18, 40, 62, 31, 9, 51, 37,
- 0, 11, 22, 29, 44, 39, 58, 49, 27, 16, 13, 6, 55, 60, 33, 42,
- 54, 61, 32, 43, 26, 17, 12, 7, 45, 38, 59, 48, 1, 10, 23, 28,
- 47, 36, 57, 50, 3, 8, 21, 30, 52, 63, 34, 41, 24, 19, 14, 5,
- 25, 18, 15, 4, 53, 62, 35, 40, 2, 9, 20, 31, 46, 37, 56, 51,
- 0, 36, 11, 47, 22, 50, 29, 57, 44, 8, 39, 3, 58, 30, 49, 21,
- 27, 63, 16, 52, 13, 41, 6, 34, 55, 19, 60, 24, 33, 5, 42, 14,
- 54, 18, 61, 25, 32, 4, 43, 15, 26, 62, 17, 53, 12, 40, 7, 35,
- 45, 9, 38, 2, 59, 31, 48, 20, 1, 37, 10, 46, 23, 51, 28, 56,
- 0, 18, 36, 54, 11, 25, 47, 61, 22, 4, 50, 32, 29, 15, 57, 43,
- 44, 62, 8, 26, 39, 53, 3, 17, 58, 40, 30, 12, 49, 35, 21, 7,
- 27, 9, 63, 45, 16, 2, 52, 38, 13, 31, 41, 59, 6, 20, 34, 48,
- 55, 37, 19, 1, 60, 46, 24, 10, 33, 51, 5, 23, 42, 56, 14, 28,
- 0, 9, 18, 27, 36, 45, 54, 63, 11, 2, 25, 16, 47, 38, 61, 52,
- 22, 31, 4, 13, 50, 59, 32, 41, 29, 20, 15, 6, 57, 48, 43, 34,
- 44, 37, 62, 55, 8, 1, 26, 19, 39, 46, 53, 60, 3, 10, 17, 24,
- 58, 51, 40, 33, 30, 23, 12, 5, 49, 56, 35, 42, 21, 28, 7, 14,
- 0, 37, 9, 44, 18, 55, 27, 62, 36, 1, 45, 8, 54, 19, 63, 26,
- 11, 46, 2, 39, 25, 60, 16, 53, 47, 10, 38, 3, 61, 24, 52, 17,
- 22, 51, 31, 58, 4, 33, 13, 40, 50, 23, 59, 30, 32, 5, 41, 12,
- 29, 56, 20, 49, 15, 42, 6, 35, 57, 28, 48, 21, 43, 14, 34, 7,
- 0, 51, 37, 22, 9, 58, 44, 31, 18, 33, 55, 4, 27, 40, 62, 13,
- 36, 23, 1, 50, 45, 30, 8, 59, 54, 5, 19, 32, 63, 12, 26, 41,
- 11, 56, 46, 29, 2, 49, 39, 20, 25, 42, 60, 15, 16, 35, 53, 6,
- 47, 28, 10, 57, 38, 21, 3, 48, 61, 14, 24, 43, 52, 7, 17, 34,
- 0, 56, 51, 11, 37, 29, 22, 46, 9, 49, 58, 2, 44, 20, 31, 39,
- 18, 42, 33, 25, 55, 15, 4, 60, 27, 35, 40, 16, 62, 6, 13, 53,
- 36, 28, 23, 47, 1, 57, 50, 10, 45, 21, 30, 38, 8, 48, 59, 3,
- 54, 14, 5, 61, 19, 43, 32, 24, 63, 7, 12, 52, 26, 34, 41, 17,
- 0, 28, 56, 36, 51, 47, 11, 23, 37, 57, 29, 1, 22, 10, 46, 50,
- 9, 21, 49, 45, 58, 38, 2, 30, 44, 48, 20, 8, 31, 3, 39, 59,
- 18, 14, 42, 54, 33, 61, 25, 5, 55, 43, 15, 19, 4, 24, 60, 32,
- 27, 7, 35, 63, 40, 52, 16, 12, 62, 34, 6, 26, 13, 17, 53, 41,
- 0, 14, 28, 18, 56, 54, 36, 42, 51, 61, 47, 33, 11, 5, 23, 25,
- 37, 43, 57, 55, 29, 19, 1, 15, 22, 24, 10, 4, 46, 32, 50, 60,
- 9, 7, 21, 27, 49, 63, 45, 35, 58, 52, 38, 40, 2, 12, 30, 16,
- 44, 34, 48, 62, 20, 26, 8, 6, 31, 17, 3, 13, 39, 41, 59, 53,
- 0, 7, 14, 9, 28, 27, 18, 21, 56, 63, 54, 49, 36, 35, 42, 45,
- 51, 52, 61, 58, 47, 40, 33, 38, 11, 12, 5, 2, 23, 16, 25, 30,
- 37, 34, 43, 44, 57, 62, 55, 48, 29, 26, 19, 20, 1, 6, 15, 8,
- 22, 17, 24, 31, 10, 13, 4, 3, 46, 41, 32, 39, 50, 53, 60, 59,
- 0, 34, 7, 37, 14, 44, 9, 43, 28, 62, 27, 57, 18, 48, 21, 55,
- 56, 26, 63, 29, 54, 20, 49, 19, 36, 6, 35, 1, 42, 8, 45, 15,
- 51, 17, 52, 22, 61, 31, 58, 24, 47, 13, 40, 10, 33, 3, 38, 4,
- 11, 41, 12, 46, 5, 39, 2, 32, 23, 53, 16, 50, 25, 59, 30, 60,
- 0, 17, 34, 51, 7, 22, 37, 52, 14, 31, 44, 61, 9, 24, 43, 58,
- 28, 13, 62, 47, 27, 10, 57, 40, 18, 3, 48, 33, 21, 4, 55, 38,
- 56, 41, 26, 11, 63, 46, 29, 12, 54, 39, 20, 5, 49, 32, 19, 2,
- 36, 53, 6, 23, 35, 50, 1, 16, 42, 59, 8, 25, 45, 60, 15, 30,
- 0, 41, 17, 56, 34, 11, 51, 26, 7, 46, 22, 63, 37, 12, 52, 29,
- 14, 39, 31, 54, 44, 5, 61, 20, 9, 32, 24, 49, 43, 2, 58, 19,
- 28, 53, 13, 36, 62, 23, 47, 6, 27, 50, 10, 35, 57, 16, 40, 1,
- 18, 59, 3, 42, 48, 25, 33, 8, 21, 60, 4, 45, 55, 30, 38, 15,
- 0, 53, 41, 28, 17, 36, 56, 13, 34, 23, 11, 62, 51, 6, 26, 47,
- 7, 50, 46, 27, 22, 35, 63, 10, 37, 16, 12, 57, 52, 1, 29, 40,
- 14, 59, 39, 18, 31, 42, 54, 3, 44, 25, 5, 48, 61, 8, 20, 33,
- 9, 60, 32, 21, 24, 45, 49, 4, 43, 30, 2, 55, 58, 15, 19, 38,
- 0, 59, 53, 14, 41, 18, 28, 39, 17, 42, 36, 31, 56, 3, 13, 54,
- 34, 25, 23, 44, 11, 48, 62, 5, 51, 8, 6, 61, 26, 33, 47, 20,
- 7, 60, 50, 9, 46, 21, 27, 32, 22, 45, 35, 24, 63, 4, 10, 49,
- 37, 30, 16, 43, 12, 55, 57, 2, 52, 15, 1, 58, 29, 38, 40, 19,
- 0, 60, 59, 7, 53, 9, 14, 50, 41, 21, 18, 46, 28, 32, 39, 27,
- 17, 45, 42, 22, 36, 24, 31, 35, 56, 4, 3, 63, 13, 49, 54, 10,
- 34, 30, 25, 37, 23, 43, 44, 16, 11, 55, 48, 12, 62, 2, 5, 57,
- 51, 15, 8, 52, 6, 58, 61, 1, 26, 38, 33, 29, 47, 19, 20, 40,
- 0, 30, 60, 34, 59, 37, 7, 25, 53, 43, 9, 23, 14, 16, 50, 44,
- 41, 55, 21, 11, 18, 12, 46, 48, 28, 2, 32, 62, 39, 57, 27, 5,
- 17, 15, 45, 51, 42, 52, 22, 8, 36, 58, 24, 6, 31, 1, 35, 61,
- 56, 38, 4, 26, 3, 29, 63, 33, 13, 19, 49, 47, 54, 40, 10, 20,
- 0, 15, 30, 17, 60, 51, 34, 45, 59, 52, 37, 42, 7, 8, 25, 22,
- 53, 58, 43, 36, 9, 6, 23, 24, 14, 1, 16, 31, 50, 61, 44, 35,
- 41, 38, 55, 56, 21, 26, 11, 4, 18, 29, 12, 3, 46, 33, 48, 63,
- 28, 19, 2, 13, 32, 47, 62, 49, 39, 40, 57, 54, 27, 20, 5, 10,
- 0, 38, 15, 41, 30, 56, 17, 55, 60, 26, 51, 21, 34, 4, 45, 11,
- 59, 29, 52, 18, 37, 3, 42, 12, 7, 33, 8, 46, 25, 63, 22, 48,
- 53, 19, 58, 28, 43, 13, 36, 2, 9, 47, 6, 32, 23, 49, 24, 62,
- 14, 40, 1, 39, 16, 54, 31, 57, 50, 20, 61, 27, 44, 10, 35, 5,
- 0, 19, 38, 53, 15, 28, 41, 58, 30, 13, 56, 43, 17, 2, 55, 36,
- 60, 47, 26, 9, 51, 32, 21, 6, 34, 49, 4, 23, 45, 62, 11, 24,
- 59, 40, 29, 14, 52, 39, 18, 1, 37, 54, 3, 16, 42, 57, 12, 31,
- 7, 20, 33, 50, 8, 27, 46, 61, 25, 10, 63, 44, 22, 5, 48, 35,
- 0, 40, 19, 59, 38, 14, 53, 29, 15, 39, 28, 52, 41, 1, 58, 18,
- 30, 54, 13, 37, 56, 16, 43, 3, 17, 57, 2, 42, 55, 31, 36, 12,
- 60, 20, 47, 7, 26, 50, 9, 33, 51, 27, 32, 8, 21, 61, 6, 46,
- 34, 10, 49, 25, 4, 44, 23, 63, 45, 5, 62, 22, 11, 35, 24, 48,
- 0, 20, 40, 60, 19, 7, 59, 47, 38, 50, 14, 26, 53, 33, 29, 9,
- 15, 27, 39, 51, 28, 8, 52, 32, 41, 61, 1, 21, 58, 46, 18, 6,
- 30, 10, 54, 34, 13, 25, 37, 49, 56, 44, 16, 4, 43, 63, 3, 23,
- 17, 5, 57, 45, 2, 22, 42, 62, 55, 35, 31, 11, 36, 48, 12, 24,
- 0, 10, 20, 30, 40, 34, 60, 54, 19, 25, 7, 13, 59, 49, 47, 37,
- 38, 44, 50, 56, 14, 4, 26, 16, 53, 63, 33, 43, 29, 23, 9, 3,
- 15, 5, 27, 17, 39, 45, 51, 57, 28, 22, 8, 2, 52, 62, 32, 42,
- 41, 35, 61, 55, 1, 11, 21, 31, 58, 48, 46, 36, 18, 24, 6, 12,
- 0, 5, 10, 15, 20, 17, 30, 27, 40, 45, 34, 39, 60, 57, 54, 51,
- 19, 22, 25, 28, 7, 2, 13, 8, 59, 62, 49, 52, 47, 42, 37, 32,
- 38, 35, 44, 41, 50, 55, 56, 61, 14, 11, 4, 1, 26, 31, 16, 21,
- 53, 48, 63, 58, 33, 36, 43, 46, 29, 24, 23, 18, 9, 12, 3, 6,
- 0, 35, 5, 38, 10, 41, 15, 44, 20, 55, 17, 50, 30, 61, 27, 56,
- 40, 11, 45, 14, 34, 1, 39, 4, 60, 31, 57, 26, 54, 21, 51, 16,
- 19, 48, 22, 53, 25, 58, 28, 63, 7, 36, 2, 33, 13, 46, 8, 43,
- 59, 24, 62, 29, 49, 18, 52, 23, 47, 12, 42, 9, 37, 6, 32, 3,
- 0, 48, 35, 19, 5, 53, 38, 22, 10, 58, 41, 25, 15, 63, 44, 28,
- 20, 36, 55, 7, 17, 33, 50, 2, 30, 46, 61, 13, 27, 43, 56, 8,
- 40, 24, 11, 59, 45, 29, 14, 62, 34, 18, 1, 49, 39, 23, 4, 52,
- 60, 12, 31, 47, 57, 9, 26, 42, 54, 6, 21, 37, 51, 3, 16, 32,
- 0, 24, 48, 40, 35, 59, 19, 11, 5, 29, 53, 45, 38, 62, 22, 14,
- 10, 18, 58, 34, 41, 49, 25, 1, 15, 23, 63, 39, 44, 52, 28, 4,
- 20, 12, 36, 60, 55, 47, 7, 31, 17, 9, 33, 57, 50, 42, 2, 26,
- 30, 6, 46, 54, 61, 37, 13, 21, 27, 3, 43, 51, 56, 32, 8, 16,
- 0, 12, 24, 20, 48, 60, 40, 36, 35, 47, 59, 55, 19, 31, 11, 7,
- 5, 9, 29, 17, 53, 57, 45, 33, 38, 42, 62, 50, 22, 26, 14, 2,
- 10, 6, 18, 30, 58, 54, 34, 46, 41, 37, 49, 61, 25, 21, 1, 13,
- 15, 3, 23, 27, 63, 51, 39, 43, 44, 32, 52, 56, 28, 16, 4, 8,
- 0, 6, 12, 10, 24, 30, 20, 18, 48, 54, 60, 58, 40, 46, 36, 34,
- 35, 37, 47, 41, 59, 61, 55, 49, 19, 21, 31, 25, 11, 13, 7, 1,
- 5, 3, 9, 15, 29, 27, 17, 23, 53, 51, 57, 63, 45, 43, 33, 39,
- 38, 32, 42, 44, 62, 56, 50, 52, 22, 16, 26, 28, 14, 8, 2, 4,
- 0, 3, 6, 5, 12, 15, 10, 9, 24, 27, 30, 29, 20, 23, 18, 17,
- 48, 51, 54, 53, 60, 63, 58, 57, 40, 43, 46, 45, 36, 39, 34, 33,
- 35, 32, 37, 38, 47, 44, 41, 42, 59, 56, 61, 62, 55, 52, 49, 50,
- 19, 16, 21, 22, 31, 28, 25, 26, 11, 8, 13, 14, 7, 4, 1, 2,
- 0, 32, 3, 35, 6, 38, 5, 37, 12, 44, 15, 47, 10, 42, 9, 41,
- 24, 56, 27, 59, 30, 62, 29, 61, 20, 52, 23, 55, 18, 50, 17, 49,
- 48, 16, 51, 19, 54, 22, 53, 21, 60, 28, 63, 31, 58, 26, 57, 25,
- 40, 8, 43, 11, 46, 14, 45, 13, 36, 4, 39, 7, 34, 2, 33, 1,
- 0, 16, 32, 48, 3, 19, 35, 51, 6, 22, 38, 54, 5, 21, 37, 53,
- 12, 28, 44, 60, 15, 31, 47, 63, 10, 26, 42, 58, 9, 25, 41, 57,
- 24, 8, 56, 40, 27, 11, 59, 43, 30, 14, 62, 46, 29, 13, 61, 45,
- 20, 4, 52, 36, 23, 7, 55, 39, 18, 2, 50, 34, 17, 1, 49, 33,
- 0, 8, 16, 24, 32, 40, 48, 56, 3, 11, 19, 27, 35, 43, 51, 59,
- 6, 14, 22, 30, 38, 46, 54, 62, 5, 13, 21, 29, 37, 45, 53, 61,
- 12, 4, 28, 20, 44, 36, 60, 52, 15, 7, 31, 23, 47, 39, 63, 55,
- 10, 2, 26, 18, 42, 34, 58, 50, 9, 1, 25, 17, 41, 33, 57, 49,
- 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
- 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63,
- 6, 2, 14, 10, 22, 18, 30, 26, 38, 34, 46, 42, 54, 50, 62, 58,
- 5, 1, 13, 9, 21, 17, 29, 25, 37, 33, 45, 41, 53, 49, 61, 57,
- 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
- 3, 1, 7, 5, 11, 9, 15, 13, 19, 17, 23, 21, 27, 25, 31, 29,
- 35, 33, 39, 37, 43, 41, 47, 45, 51, 49, 55, 53, 59, 57, 63, 61
-};
-
-const qracode qra_13_64_64_irr_e = {
- qra_K,
- qra_N,
- qra_m,
- qra_M,
- qra_a,
- qra_NC,
- qra_V,
- qra_C,
- qra_NMSG,
- qra_MAXVDEG,
- qra_MAXCDEG,
- QRATYPE_CRCPUNCTURED,
- qra_R,
- CODE_NAME,
- qra_acc_input_idx,
- qra_acc_input_wlog,
- qra_log,
- qra_exp,
- qra_msgw,
- qra_vdeg,
- qra_cdeg,
- qra_v2cmidx,
- qra_c2vmidx,
- qra_pmat
-};
-
-#undef qra_K
-#undef qra_N
-#undef qra_m
-#undef qra_M
-#undef qra_a
-#undef qra_NC
-#undef qra_V
-#undef qra_C
-#undef qra_NMSG
-#undef qra_MAXVDEG
-#undef qra_MAXCDEG
-#undef qra_R
-#undef CODE_NAME
\ No newline at end of file
diff --git a/lib/qra/qracodes/qra13_64_64_irr_e.h b/lib/qra/qracodes/qra13_64_64_irr_e.h
deleted file mode 100644
index d24421d..0000000
--- a/lib/qra/qracodes/qra13_64_64_irr_e.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// qra13_64_64_irr_e.h
-// Code tables and defines for Q-ary RA code (13,64) over GF(64)
-// Code Name: qra13_64_64_irr_e
-// (13,64) RA Code over GF(64) RF=[3x4 4x4 6x1 3x2 5x1 7x1]/18
-
-// (c) 2016 - Nico Palermo - IV3NWV - Microtelecom Srl, Italy
-
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#ifndef _qra13_64_64_irr_e_h
-#define _qra13_64_64_irr_e_h
-
-#include "qracodes.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern const qracode qra_13_64_64_irr_e;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _qra13_64_64_irr_e_h
diff --git a/lib/qra/qracodes/qracodes.c b/lib/qra/qracodes/qracodes.c
deleted file mode 100644
index 748a9c9..0000000
--- a/lib/qra/qracodes/qracodes.c
+++ /dev/null
@@ -1,474 +0,0 @@
-// qracodes.c
-// Q-ary RA codes encoding/decoding functions
-//
-// (c) 2016 - Nico Palermo, IV3NWV - Microtelecom Srl, Italy
-// ------------------------------------------------------------------------------
-// This file is part of the qracodes project, a Forward Error Control
-// encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
-//
-// qracodes 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.
-// qracodes 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 qracodes source distribution.
-// If not, see .
-
-#include
-#include
-
-#include "npfwht.h"
-#include "pdmath.h"
-
-#include "qracodes.h"
-
-int qra_encode(const qracode *pcode, int *y, const int *x)
-{
- int k,j,kk,jj;
- int t, chk = 0;
-
- const int K = pcode->K;
- const int M = pcode->M;
- const int NC= pcode->NC;
- const int a = pcode->a;
- const int *acc_input_idx = pcode->acc_input_idx;
- const int *acc_input_wlog = pcode->acc_input_wlog;
- const int *gflog = pcode->gflog;
- const int *gfexp = pcode->gfexp;
-
- // copy the systematic symbols to destination
- memcpy(y,x,K*sizeof(int));
-
- y = y+K; // point to check symbols
-
- // compute the code check symbols as a weighted accumulation of a permutated
- // sequence of the (repeated) systematic input symbols:
- // chk(k+1) = x(idx(k))*alfa^(logw(k)) + chk(k)
- // (all operations performed over GF(M))
-
- if (a==1) { // grouping factor = 1
- for (k=0;k 1
- for (k=0;k80.f) // avoid floating point exp() overflows
- v=80.f;
-
- src[nitems] = (float)exp(v);
- }
-}
-
-
-float qra_mfskbesselmetric(float *pix, const float *rsq, const int m, const int N, float EsNoMetric)
-{
- // Computes the codeword symbols intrinsic probabilities
- // given the square of the received input amplitudes.
-
- // The input vector rqs must be a linear array of size M*N, where M=2^m,
- // containing the squared amplitudes (rp*rp+rq*rq) of the input samples
-
- // First symbol amplitudes should be stored in the first M positions,
- // second symbol amplitudes stored at positions [M ... 2*M-1], and so on.
-
- // Output vector is the intrinsic symbol metric (the probability distribution)
- // assuming that symbols are transmitted using a M-FSK modulation
- // and incoherent demodulation.
-
- // As the input Es/No is generally unknown (as it cannot be exstimated accurately
- // when the codeword length is few tens symbols) but an exact metric requires it
- // we simply fix it to a predefined EsNoMetric value so that the metric is what
- // expected at that specific value.
- // The metric computed in this way is optimal only at this predefined Es/No value,
- // nevertheless it is usually better than a generic parameter-free metric which
- // makes no assumptions on the input Es/No.
-
- // returns the estimated noise standard deviation
-
- int k;
- float rsum = 0.f;
- float sigmaest, cmetric;
-
- const int M = 1<M;
- const int qra_m = pcode->m;
- const int qra_V = pcode->V;
- const int qra_MAXVDEG = pcode->MAXVDEG;
- const int *qra_vdeg = pcode->vdeg;
- const int qra_C = pcode->C;
- const int qra_MAXCDEG = pcode->MAXCDEG;
- const int *qra_cdeg = pcode->cdeg;
- const int *qra_v2cmidx = pcode->v2cmidx;
- const int *qra_c2vmidx = pcode->c2vmidx;
- const int *qra_pmat = pcode->gfpmat;
- const int *qra_msgw = pcode->msgw;
-
-// float msgout[qra_M]; // buffer to store temporary results
- float msgout[QRACODE_MAX_M]; // we use a fixed size in order to avoid mallocs
-
- float totex; // total extrinsic information
- int nit; // current iteration
- int nv; // current variable
- int nc; // current check
- int k,kk; // loop indexes
-
- int ndeg; // current node degree
- int msgbase; // current offset in the table of msg indexes
- int imsg; // current message index
- int wmsg; // current message weight
-
- int rc = -1; // rc>=0 extrinsic converged to 1 at iteration rc (rc=0..maxiter-1)
- // rc=-1 no convergence in the given number of iterations
- // rc=-2 error in the code tables (code checks degrees must be >1)
- // rc=-3 M is larger than QRACODE_MAX_M
-
-
-
- if (qra_M>QRACODE_MAX_M)
- return -3;
-
- // message initialization -------------------------------------------------------
-
- // init c->v variable intrinsic msgs
- pd_init(C2VMSG(0),pix,qra_M*qra_V);
-
- // init the v->c messages directed to code factors (k=1..ndeg) with the intrinsic info
- for (nv=0;nvc
- for (k=1;kv step -----------------------------------------------------
- // Computes messages from code checks to code variables.
- // As the first qra_V checks are associated with intrinsic information
- // (the code tables have been constructed in this way)
- // we need to do this step only for code checks in the range [qra_V..qra_C)
-
- // The convolutions of probability distributions over the alphabet of a finite field GF(qra_M)
- // are performed with a fast convolution algorithm over the given field.
- //
- // I.e. given the code check x1+x2+x3 = 0 (with x1,x2,x3 in GF(2^m))
- // and given Prob(x2) and Prob(x3), we have that:
- // Prob(x1=X1) = Prob((x2+x3)=X1) = sum((Prob(x2=X2)*Prob(x3=(X1+X2))) for all the X2s in the field
- // This translates to Prob(x1) = IWHT(WHT(Prob(x2))*WHT(Prob(x3)))
- // where WHT and IWHT are the direct and inverse Walsh-Hadamard transforms of the argument.
- // Note that the WHT and the IWHF differs only by a multiplicative coefficent and since in this step
- // we don't need that the output distribution is normalized we use the relationship
- // Prob(x1) =(proportional to) WH(WH(Prob(x2))*WH(Prob(x3)))
-
- // In general given the check code x1+x2+x3+..+xm = 0
- // the output distribution of a variable given the distributions of the other m-1 variables
- // is the inverse WHT of the product of the WHTs of the distribution of the other m-1 variables
- // The complexity of this algorithm scales with M*log2(M) instead of the M^2 complexity of
- // the brute force approach (M=size of the alphabet)
-
- for (nc=qra_V;nc1)
- return -2; // bad code tables
-
- msgbase = nc*qra_MAXCDEG; // base to msg index row for the current node
-
- // transforms inputs in the Walsh-Hadamard "frequency" domain
- // v->c -> fwht(v->c)
- for (k=0;kv = prod(fwht(v->c))
- // TODO: we assume that checks degrees are not larger than three but
- // if they are larger the products can be computed more efficiently
- for (kk=0;kkc steps when multipling
- // small fp numbers
- msgout[0]+=1E-7f; // TODO: define the bias accordingly to the field size
-
- np_fwht(qra_m,msgout,msgout);
-
- // inverse weight and output
- imsg = qra_c2vmidx[msgbase+k]; // current output msg index
- wmsg = qra_msgw[imsg]; // current msg weight
-
- if (wmsg==0)
- pd_init(C2VMSG(imsg),msgout,qra_M);
- else
- // output p(alfa^(-w)*x)
- pd_bwdperm(C2VMSG(imsg),msgout, MSGPERM(wmsg), qra_M);
-
- } // for (k=0;kc step -----------------------------------------------------
- for (nv=0;nvc msg = prod(c->v)
- // TODO: factor factors to reduce the number of computations for high degree nodes
- for (kk=0;kkc are null
- // normalize output to a probability distribution
- if (pd_norm(msgout,qra_m)<=0) {
- // dump msgin;
- printf("warning: v->c pd with invalid norm. nit=%d nv=%d k=%d\n",nit,nv,k);
- for (kk=0;kk(1.*(qra_V)-0.01)) {
- // the total maximum extrinsic information of each symbol in the codeword
- // is very close to one. This means that we have reached the (1,1) point in the
- // code EXIT chart(s) and we have successfully decoded the input.
- rc = nit;
- break; // remove the break to evaluate the decoder speed performance as a function of the max iterations number)
- }
-
- } // for (nit=0;nitM;
- const int qra_m = pcode->m;
- const int qra_K = pcode->K;
-
- int k;
-
- for (k=0;k.
-
-#ifndef _qracodes_h_
-#define _qracodes_h_
-
-// type of codes
-#define QRATYPE_NORMAL 0x00 // normal code
-#define QRATYPE_CRC 0x01 // code with crc - last information symbol is a CRC
-#define QRATYPE_CRCPUNCTURED 0x02 // the CRC symbol is punctured (not sent along the channel)
-
-
-typedef struct {
- // code parameters
- const int K; // number of information symbols
- const int N; // codeword length in symbols
- const int m; // bits/symbol
- const int M; // Symbol alphabet cardinality (2^m)
- const int a; // code grouping factor
- const int NC; // number of check symbols (N-K)
- const int V; // number of variables in the code graph (N)
- const int C; // number of factors in the code graph (N +(N-K)+1)
- const int NMSG; // number of msgs in the code graph
- const int MAXVDEG; // maximum variable degree
- const int MAXCDEG; // maximum factor degree
- const int type; // see QRATYPE_xx defines
- const float R; // code rate (K/N)
- const char name[64]; // code name
- // tables used by the encoder
- const int *acc_input_idx;
- const int *acc_input_wlog;
- const int *gflog;
- const int *gfexp;
- // tables used by the decoder -------------------------
- const int *msgw;
- const int *vdeg;
- const int *cdeg;
- const int *v2cmidx;
- const int *c2vmidx;
- const int *gfpmat;
-} qracode;
-// Uncomment the header file of the code which needs to be tested
-
-//#include "qra12_63_64_irr_b.h" // irregular code (12,63) over GF(64)
-//#include "qra13_64_64_irr_e.h" // irregular code with good performance and best UER protection at AP56
-//#include "qra13_64_64_reg_a.h" // regular code with good UER but perf. inferior to that of code qra12_63_64_irr_b
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int qra_encode(const qracode *pcode, int *y, const int *x);
-float qra_mfskbesselmetric(float *pix, const float *rsq, const int m, const int N, float EsNoMetric);
-int qra_extrinsic(const qracode *pcode, float *pex, const float *pix, int maxiter,float *qra_v2cmsg,float *qra_c2vmsg);
-void qra_mapdecode(const qracode *pcode, int *xdec, float *pex, const float *pix);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _qracodes_h_
diff --git a/lib/qso50/g0 b/lib/qso50/g0
deleted file mode 100644
index 02e2aeb..0000000
--- a/lib/qso50/g0
+++ /dev/null
@@ -1,8 +0,0 @@
-gfortran -o twq -Wall -Wno-conversion -fbounds-check twq.f90 \
- ../packjt.f90 wqenc.f90 wqdec.f90 packprop.f90 \
- packname.f90 packtext2.f90 unpackprop.f90 unpackname.f90 \
- unpacktext2.f90 unpackpfx.f90 pack50.f90 unpack50.f90 \
- ../hash.f90 ../deg2grid.f90 ../grid2deg.f90 \
- ../fix_contest_msg.f90 ../to_contest_msg.f90 \
- ../fmtmsg.f90 ../azdist.f90 ../geodist.f90 ../wsprd/nhash.c
-
\ No newline at end of file
diff --git a/lib/qso50/pack50.f90 b/lib/qso50/pack50.f90
deleted file mode 100644
index 12c230c..0000000
--- a/lib/qso50/pack50.f90
+++ /dev/null
@@ -1,26 +0,0 @@
-subroutine pack50(n1,n2,dat)
-
- integer*1 dat(11),i1
-
- i1=iand(ishft(n1,-20),255) !8 bits
- dat(1)=i1
- i1=iand(ishft(n1,-12),255) !8 bits
- dat(2)=i1
- i1=iand(ishft(n1, -4),255) !8 bits
- dat(3)=i1
- i1=16*iand(n1,15)+iand(ishft(n2,-18),15) !4+4 bits
- dat(4)=i1
- i1=iand(ishft(n2,-10),255) !8 bits
- dat(5)=i1
- i1=iand(ishft(n2, -2),255) !8 bits
- dat(6)=i1
- i1=64*iand(n2,3) !2 bits
- dat(7)=i1
- dat(8)=0
- dat(9)=0
- dat(10)=0
- dat(11)=0
-
- return
-end subroutine pack50
-
diff --git a/lib/qso50/packname.f90 b/lib/qso50/packname.f90
deleted file mode 100644
index 5b3936e..0000000
--- a/lib/qso50/packname.f90
+++ /dev/null
@@ -1,23 +0,0 @@
-subroutine packname(name,len,n1,n2)
-
- character*9 name
- real*8 dn
-
- dn=0
- do i=1,len
- n=ichar(name(i:i))
- if(n.ge.97 .and. n.le.122) n=n-32
- dn=27*dn + n-64
- enddo
- if(len.lt.9) then
- do i=len+1,9
- dn=27*dn
- enddo
- endif
-
- n2=mod(dn,32768.d0)
- dn=dn/32768.d0
- n1=dn
-
- return
-end subroutine packname
diff --git a/lib/qso50/packprop.f90 b/lib/qso50/packprop.f90
deleted file mode 100644
index 5d22a37..0000000
--- a/lib/qso50/packprop.f90
+++ /dev/null
@@ -1,36 +0,0 @@
-subroutine packprop(k,muf,ccur,cxp,n1)
-
-! Pack propagation indicators into a 21-bit number.
-
-! k k-index, 0-9; 10="N/A"
-! muf muf, 2-60 MHz; 0=N/A, 1="none", 61=">60 MHz"
-! ccur up to two current events, each indicated by single
-! or double letter.
-! cxp zero or one expected event, indicated by single or
-! double letter
-
- character ccur*4,cxp*2
-
- j=ichar(ccur(1:1))-64
- if(j.lt.0) j=0
- n1=j
- do i=2,4
- if(ccur(i:i).eq.' ') go to 10
- if(ccur(i:i).eq.ccur(i-1:i-1)) then
- n1=n1+26
- else
- j=ichar(ccur(i:i))-64
- if(j.lt.0) j=0
- n1=53*n1 + j
- endif
- enddo
-
-10 j=ichar(cxp(1:1))-64
- if(j.lt.0) j=0
- if(cxp(2:2).eq.cxp(1:1)) j=j+26
- n1=53*n1 + j
- n1=11*n1 + k
- n1=62*n1 + muf
-
- return
-end subroutine packprop
diff --git a/lib/qso50/packtext2.f90 b/lib/qso50/packtext2.f90
deleted file mode 100644
index d54b52f..0000000
--- a/lib/qso50/packtext2.f90
+++ /dev/null
@@ -1,22 +0,0 @@
-subroutine packtext2(msg,n1,ng)
-
- character*8 msg
- real*8 dn
- character*41 c
- data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +./?'/
-
- dn=0.
- do i=1,8
- do j=1,41
- if(msg(i:i).eq.c(j:j)) go to 10
- enddo
- j=37
-10 j=j-1 !Codes should start at zero
- dn=41.d0*dn + j
- enddo
-
- ng=mod(dn,32768.d0)
- n1=(dn-ng)/32768.d0
-
- return
-end subroutine packtext2
diff --git a/lib/qso50/twq.f90 b/lib/qso50/twq.f90
deleted file mode 100644
index 9fdb263..0000000
--- a/lib/qso50/twq.f90
+++ /dev/null
@@ -1,18 +0,0 @@
-program twq
-
- character*22 msg0,msg
- integer*1 data0(11)
-
- open(10,file='wqmsg.txt',status='old')
- write(*,1000)
-1000 format(4x,'Encoded message',9x,'Decoded as',12x,'itype'/55('-'))
-
- do line=1,9999
- read(10,*,end=999) msg0
- call wqenc(msg0,itype,data0)
- call wqdec(data0,msg,ntype)
- write(*,1100) line,msg0,msg,ntype
-1100 format(i2,'.',1x,a22,2x,a22,i3)
- enddo
-
-999 end program twq
diff --git a/lib/qso50/unpack50.f90 b/lib/qso50/unpack50.f90
deleted file mode 100644
index 101f1ab..0000000
--- a/lib/qso50/unpack50.f90
+++ /dev/null
@@ -1,30 +0,0 @@
-subroutine unpack50(dat,n1,n2)
-
- integer*1 dat(11)
-
- i=dat(1)
- i4=iand(i,255)
- n1=ishft(i4,20)
- i=dat(2)
- i4=iand(i,255)
- n1=n1 + ishft(i4,12)
- i=dat(3)
- i4=iand(i,255)
- n1=n1 + ishft(i4,4)
- i=dat(4)
- i4=iand(i,255)
- n1=n1 + iand(ishft(i4,-4),15)
- n2=ishft(iand(i4,15),18)
- i=dat(5)
- i4=iand(i,255)
- n2=n2 + ishft(i4,10)
- i=dat(6)
- i4=iand(i,255)
- n2=n2 + ishft(i4,2)
- i=dat(7)
- i4=iand(i,255)
- n2=n2 + iand(ishft(i4,-6),3)
-
- return
-end subroutine unpack50
-
diff --git a/lib/qso50/unpackname.f90 b/lib/qso50/unpackname.f90
deleted file mode 100644
index 3ae7c5c..0000000
--- a/lib/qso50/unpackname.f90
+++ /dev/null
@@ -1,20 +0,0 @@
-subroutine unpackname(n1,n2,name,len)
-
- character*9 name
- real*8 dn
-
- dn=32768.d0*n1 + n2
- len=0
- do i=9,1,-1
- j=mod(dn,27.d0)
- if(j.ge.1) then
- name(i:i)=char(64+j)
- len=len+1
- else
- name(i:i)=' '
- endif
- dn=dn/27.d0
- enddo
-
- return
-end subroutine unpackname
diff --git a/lib/qso50/unpackpfx.f90 b/lib/qso50/unpackpfx.f90
deleted file mode 100644
index 4234e9e..0000000
--- a/lib/qso50/unpackpfx.f90
+++ /dev/null
@@ -1,35 +0,0 @@
-subroutine unpackpfx(ng,call1)
-
- character*12 call1
- character*3 pfx
-
- if(ng.lt.60000) then
-! Add-on prefix of 1 to 3 characters
- n=ng
- do i=3,1,-1
- nc=mod(n,37)
- if(nc.ge.0 .and. nc.le.9) then
- pfx(i:i)=char(nc+48)
- else if(nc.ge.10 .and. nc.le.35) then
- pfx(i:i)=char(nc+55)
- else
- pfx(i:i)=' '
- endif
- n=n/37
- enddo
- call1=pfx//'/'//call1
- if(call1(1:1).eq.' ') call1=call1(2:)
- if(call1(1:1).eq.' ') call1=call1(2:)
- else
-! Add-on suffix, one character
- i1=index(call1,' ')
- nc=ng-60000
- if(nc.ge.0 .and. nc.le.9) then
- call1=call1(:i1-1)//'/'//char(nc+48)
- else if(nc.ge.10 .and. nc.le.35) then
- call1=call1(:i1-1)//'/'//char(nc+55)
- endif
- endif
-
- return
-end subroutine unpackpfx
diff --git a/lib/qso50/unpackprop.f90 b/lib/qso50/unpackprop.f90
deleted file mode 100644
index 18cc1f5..0000000
--- a/lib/qso50/unpackprop.f90
+++ /dev/null
@@ -1,28 +0,0 @@
-subroutine unpackprop(n1,k,muf,ccur,cxp)
-
- character ccur*4,cxp*2
-
- muf=mod(n1,62)
- n1=n1/62
-
- k=mod(n1,11)
- n1=n1/11
-
- j=mod(n1,53)
- n1=n1/53
- if(j.eq.0) cxp='*'
- if(j.ge.1 .and. j.le.26) cxp=char(64+j)
- if(j.gt.26) cxp=char(64+j-26)//char(64+j-26)
-
- j=mod(n1,53)
- n1=n1/53
- if(j.eq.0) ccur(2:2)='*'
- if(j.ge.1 .and. j.le.26) ccur(2:2)=char(64+j)
- if(j.gt.26) ccur(2:3)=char(64+j-26)//char(64+j-26)
- j=n1
- if(j.eq.0) ccur(1:1)='*'
- if(j.ge.1 .and. j.le.26) ccur(1:1)=char(64+j)
- if(j.gt.26) ccur=char(64+j-26)//char(64+j-26)//ccur(2:3)
-
- return
-end subroutine unpackprop
diff --git a/lib/qso50/unpacktext2.f90 b/lib/qso50/unpacktext2.f90
deleted file mode 100644
index 92dccce..0000000
--- a/lib/qso50/unpacktext2.f90
+++ /dev/null
@@ -1,17 +0,0 @@
-subroutine unpacktext2(n1,ng,msg)
-
- character*22 msg
- real*8 dn
- character*41 c
- data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +./?'/
-
- msg=' '
- dn=32768.d0*n1 + ng
- do i=8,1,-1
- j=mod(dn,41.d0)
- msg(i:i)=c(j+1:j+1)
- dn=dn/41.d0
- enddo
-
- return
-end subroutine unpacktext2
diff --git a/lib/qso50/wqdec.f90 b/lib/qso50/wqdec.f90
deleted file mode 100644
index 791c78c..0000000
--- a/lib/qso50/wqdec.f90
+++ /dev/null
@@ -1,316 +0,0 @@
-subroutine wqdec(data0,message,ntype)
-
- use packjt
- parameter (N15=32758)
- integer*1 data0(11)
- character*22 message
- character*12 callsign
- character*3 cdbm,cf
- character*2 crpt
- character*4 grid,psfx
- character*9 name
- character*36 fmt
- character*6 cwx(4)
- character*7 cwind(5)
- character ccur*4,cxp*2
- logical first
- character*12 dcall(0:N15-1)
- data first/.true./
- data cwx/'CLEAR','CLOUDY','RAIN','SNOW'/
- data cwind/'CALM','BREEZES','WINDY','DRY','HUMID'/
- save first,dcall
-
- if(first) then
- dcall=' '
- first=.false.
- endif
-
- message=' '
- call unpack50(data0,n1,n2)
- call unpackcall(n1,callsign,iv2,psfx)
- i1=index(callsign,' ')
- call unpackgrid(n2/128,grid)
- ntype=iand(n2,127) -64
-
-! Standard WSPR message (types 0 3 7 10 13 17 ... 60)
- nu=mod(ntype,10)
- if(ntype.ge.0 .and. ntype.le.60 .and. (nu.eq.0 .or. nu.eq.3 .or. &
- nu.eq.7)) then
- write(cdbm,'(i3)'),ntype
- if(cdbm(1:1).eq.' ') cdbm=cdbm(2:)
- if(cdbm(1:1).eq.' ') cdbm=cdbm(2:)
- message=callsign(1:i1)//grid//' '//cdbm
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1)
-
-! "Best DX" WSPR response (type 1)
- else if(ntype.eq.1) then
- message=grid//' DE '//callsign
-
-! CQ (msg 3; types 2,4,5)
- else if(ntype.eq.2) then
- message='CQ '//callsign(:i1)//grid
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1)
- else if(ntype.eq.4 .or. ntype.eq.5) then
- ng=n2/128 + 32768*(ntype-4)
- call unpackpfx(ng,callsign)
- message='CQ '//callsign
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1)
-
-! Reply to CQ (msg #2; type 6)
- else if(ntype.eq.6) then
- ih=(n2-64-ntype)/128
- if(dcall(ih)(1:1).ne.' ') then
- i2=index(dcall(ih),' ')
- message='<'//dcall(ih)(:i2-1)//'> '//callsign(:i1-1)
- else
- message='<...> '//callsign
- endif
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! Reply to CQ (msg #2; type 8)
- else if(ntype.eq.8) then
- message='DE '//callsign(:i1)//grid
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! Reply to CQ, DE pfx/call (msg #2; types 9, 11)
- else if(ntype.eq.9 .or. ntype.eq.11) then
- ng=n2/128 + 32768*(ntype-9)/2
- call unpackpfx(ng,callsign)
- message='DE '//callsign
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! Calls and report (msg #3; types -1 to -9)
- else if(ntype.le.-1 .and. ntype.ge.-9) then
- write(crpt,1010) -ntype
-1010 format('S',i1)
- ih=(n2-62-ntype)/128
- if(dcall(ih)(1:1).ne.' ') then
- i2=index(dcall(ih),' ')
- message=callsign(:i1)//'<'//dcall(ih)(:i2-1)//'> '//crpt
- else
- message=callsign(:i1)//'<...> '//crpt
- endif
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! pfx/call and report (msg #3; types -10 to -27)
- else if(ntype.le.-10 .and. ntype.ge.-27) then
- ng=n2/128
- nrpt=-ntype-9
- if(ntype.le.-19) then
- ng=ng + 32768
- nrpt=-ntype-18
- endif
- write(crpt,1010) nrpt
- call unpackpfx(ng,callsign)
- message=callsign//' '//crpt
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! Calls and R and report (msg #4; types -28 to -36)
- else if(ntype.le.-28 .and. ntype.ge.-36) then
- write(crpt,1010) -(ntype+27)
- ih=(n2-64+28-ntype)/128
- if(dcall(ih)(1:1).ne.' ') then
- i2=index(dcall(ih),' ')
- message=callsign(:i1)//'<'//dcall(ih)(:i2-1)//'> '//'R '//crpt
- else
- message=callsign(:i1)//'<...> '//'R '//crpt
- endif
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! pfx/call R and report (msg #4; types -37 to -54)
- else if(ntype.le.-37 .and. ntype.ge.-54) then
- ng=n2/128
- nrpt=-ntype-36
- if(ntype.le.-46) then
- ng=ng + 32768
- nrpt=-ntype-45
- endif
- write(crpt,1010) nrpt
- call unpackpfx(ng,callsign)
- message=callsign//' R '//crpt
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! Calls and RRR (msg#5; type 12)
- else if(ntype.eq.12) then
- ih=(n2-64+28-ntype)/128
- if(dcall(ih)(1:1).ne.' ') then
- i2=index(dcall(ih),' ')
- message=callsign(:i1)//'<'//dcall(ih)(:i2-1)//'> RRR'
- else
- message=callsign(:i1)//'<...> RRR'
- endif
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! Calls and RRR (msg#5; type 14)
- else if(ntype.eq.14) then
- ih=(n2-64+28-ntype)/128
- if(dcall(ih)(1:1).ne.' ') then
- i2=index(dcall(ih),' ')
- message='<'//dcall(ih)(:i2-1)//'> '//callsign(:i1)//'RRR'
- else
- message='<...> '//callsign(:i1)//' RRR'
- endif
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! DE pfx/call and RRR (msg#5; types 15, 16)
- else if(ntype.eq.15 .or. ntype.eq.16) then
- ng=n2/128 + 32768*(ntype-15)
- call unpackpfx(ng,callsign)
- message='DE '//callsign//' RRR'
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! TNX [name] 73 GL (msg #6; type 18)
- else if(ntype.eq.18) then
- ng=(n2-18-64)/128
- call unpackname(n1,ng,name,len)
- message='TNX '//name(:len)//' 73 GL'
-
-! OP [name] 73 GL (msg #6; type 18)
- else if(ntype.eq.-56) then
- ng=(n2+56-64)/128
- call unpackname(n1,ng,name,len)
- message='OP '//name(:len)//' 73 GL'
-
-! 73 DE [call] [grid] (msg #6; type 19)
- else if(ntype.eq.19) then
- ng=(n2-19-64)/128
- message='73 DE '//callsign(:i1)//grid
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! 73 DE pfx/call (msg #6; type 21, 22)
- else if(ntype.eq.21 .or. ntype.eq.22) then
- ng=n2/128 + (ntype-21)*32768
- call unpackpfx(ng,callsign)
- i1=index(callsign,' ')
- message='73 DE '//callsign
- call hash(callsign,i1-1,ih)
- dcall(ih)=callsign(:i1-1)
-
-! [power] W [gain] DBD 73 GL (msg#6; type 24, 25)
- else if(ntype.eq.24 .or. ntype.eq.25) then
- ng=(n2-24-64)/128 - 32
- i1=1
- if(n1.gt.0) i1=log10(float(n1)) + 1
- i2=1
- if(ng.ge.10) i2=2
- if(ng.lt.0) i2=i2+1
- if(n1.le.3000) then
- if(ntype.eq.24) fmt="(i4,' W ',i2,' DBD 73 GL')"
- if(ntype.eq.25) fmt="(i4,' W ',i2,' DBD ')"
- fmt(3:3)=char(48+i1)
- fmt(12:12)=char(48+i2)
- if(ng.le.100) then
- write(message,fmt) n1,ng
- else
- if(ng.eq.30000) fmt=fmt(1:8)//"DIPOLE')"
- if(ng.eq.30001) fmt=fmt(1:8)//"VERTICAL')"
- write(message,fmt) n1
- endif
- else
- mw=n1-3000
- if(ntype.eq.24) fmt="('0.',i3.3,' W ',i2,' DBD 73 GL')"
- if(ntype.eq.25) fmt="('0.',i3.3,' W ',i2,' DBD ')"
- fmt(19:19)=char(48+i2)
- if(ng.le.100) then
- write(message,fmt) mw,ng
- else
- if(ng.eq.30000) fmt=fmt(1:15)//"DIPOLE')"
- if(ng.eq.30001) fmt=fmt(1:15)//"VERTICAL')"
- write(message,fmt) n1
- endif
- if(index(message,'***').gt.0) go to 700
- endif
-
-! QRZ call (msg #3; type 26)
- else if(ntype.eq.26) then
- ng=(n2-24-64)/128 - 32
- message='QRZ '//callsign
-
-! PSE QSY [nnn] KHZ (msg #6; type 28)
- else if(ntype.eq.28) then
- if(n1.gt.0) i1=log10(float(n1)) + 1
- fmt="('PSE QSY ',i2,' KHZ')"
- fmt(14:14)=char(48+i1)
- write(message,fmt) n1
-
-! WX wx temp C/F wind (msg #6; type 29)
- else if(ntype.eq.29) then
- nwx=n1/10000
- ntemp=mod(n1,10000) - 100
- cf=' F '
- if(ntemp.gt.800) then
- ntemp=ntemp-1000
- cf=' C '
- endif
- n2a=n2/128
- if(nwx.ge.1 .and. nwx.le.4 .and. n2a.ge.1 .and. n2a.le.5) then
- write(message,1020) cwx(nwx),ntemp,cf,cwind(n2/128)
-1020 format('WX ',a6,i3,a3,a7)
- else
- message='WX'//' (BadMsg)'
- endif
-
-! Hexadecimal data (type 62)
- else if(ntype.eq.62) then
- ng=n2/128
- write(message,'(z4.4,z7.7)') ng,n1
-
-! Solar/geomagnetic/ionospheric data (type 63)
- else if(ntype.eq.63) then
- ih=(n2-64-ntype)/128
- if(dcall(ih)(1:1).ne.' ') then
- i2=index(dcall(ih),' ')
- message='<'//dcall(ih)(:i2-1)//'> '
- else
- message='<...> '
- endif
- call unpackprop(n1,k,muf,ccur,cxp)
- i2=index(message,'>')
- write(message(i2+1:),'(i3,i3)') k,muf
- message=message(:i2+7)//ccur//' '//cxp
-
-! [plain text] (msg #6; type -57)
- else if(ntype.eq.-57) then
- ng=n2/128
- call unpacktext2(n1,ng,message)
- else
- go to 700
- endif
- go to 750
-
-! message=''
-700 i1=index(callsign,' ')
- if(i1.lt.1) i1=12
- message=callsign(:i1)//' (BadMsg)'
-
-750 do i=1,22
- if(ichar(message(i:i)).eq.0) message(i:i)=' '
- enddo
-
- do i=22,1,-1
- if(message(i:i).ne.' ') go to 800
- enddo
-800 i2=i
- do n=1,20
- i1=index(message(:i2),' ')
- if(i1.le.0) go to 900
- message=message(1:i1)//message(i1+2:)
- i2=i2-1
- enddo
-
-900 return
-end subroutine wqdec
diff --git a/lib/qso50/wqenc.f90 b/lib/qso50/wqenc.f90
deleted file mode 100644
index 0f61292..0000000
--- a/lib/qso50/wqenc.f90
+++ /dev/null
@@ -1,346 +0,0 @@
-subroutine wqenc(msg,ntype,data0)
-
-! Parse and encode a WSPR message.
-
- use packjt
- parameter (MASK15=32767)
- character*22 msg
- character*12 call1,call2
- character*4 grid
- character*9 name
- character ccur*4,cxp*2
- logical lbad1,lbad2
- integer*1 data0(11)
- integer nu(0:9)
- data nu/0,-1,1,0,-1,2,1,0,-1,1/
-
- read(msg,1001,end=1,err=1) ng,n1
-1001 format(z4,z7)
- ntype=62
- n2=128*ng + (ntype+64)
- call pack50(n1,n2,data0) !Pack 8 bits per byte, add tail
- go to 900
-
-1 if(msg(1:6).eq.'73 DE ') go to 80
- if(index(msg,' W ').gt.0 .and. index(msg,' DBD ').gt.0) go to 90
- if(msg(1:4).eq.'QRZ ') go to 100
- if(msg(1:8).eq.'PSE QSY ') go to 110
- if(msg(1:3).eq.'WX ') go to 120
-
-! Standard WSPR message (types 0 3 7 10 13 17 ... 60)
- i1=index(msg,' ')
- if(i1.lt.4 .or. i1.gt.7) go to 10
- call1=msg(:i1-1)
- grid=msg(i1+1:i1+4)
- call packcall(call1,n1,lbad1)
- call packgrid(grid,ng,lbad2)
- if(lbad1 .or. lbad2) go to 10
- ndbm=0
- read(msg(i1+5:),*,err=10,end=800) ndbm
- if(ndbm.lt.0 .or. ndbm.gt.60) go to 800
- ndbm=ndbm+nu(mod(ndbm,10))
- n2=128*ng + (ndbm+64)
- call pack50(n1,n2,data0)
- ntype=ndbm
- go to 900
-
-! "BestDX" automated WSPR reply (type 1)
-10 if(i1.ne.5 .or. msg(5:8).ne.' DE ') go to 20
- grid=msg(1:4)
- call packgrid(grid,ng,lbad2)
- if(lbad2) go to 800
- call1=msg(9:)
- call packcall(call1,n1,lbad1)
- if(lbad1) go to 800
- ntype=1
- n2=128*ng + (ntype+64)
- call pack50(n1,n2,data0) !Pack 8 bits per byte, add tail
- go to 900
-
-! CQ (msg #1; types 2, 4, 5)
-20 if(msg(1:3).ne.'CQ ') go to 30
- if(index(msg,'/').le.0) then
- i2=index(msg(4:),' ')
- call1=msg(4:i2+3)
- grid=msg(i2+4:)
- call packcall(call1,n1,lbad1)
- if(lbad1) go to 30
- call packgrid(grid,ng,lbad2)
- if(lbad2) go to 30
- ntype=2
- n2=128*ng + (ntype+64)
- call pack50(n1,n2,data0)
- else
- ntype=4 ! or 5
- call1=msg(4:)
- call packpfx(call1,n1,ng,nadd)
- ntype=ntype+nadd
- n2=128*ng + ntype + 64
- call pack50(n1,n2,data0)
- endif
- go to 900
-
-! Reply to CQ (msg #2; types 6,8,9,11)
-30 if(msg(1:1).ne.'<' .and. msg(1:3).ne.'DE ') go to 40
- if(index(msg,' RRR ').gt.0) go to 50
- if(msg(1:1).eq.'<') then
- ntype=6
- i1=index(msg,'>')
- call1=msg(2:i1-1)
- read(msg(i1+1:),*,err=31,end=31) k,muf,ccur,cxp
- go to 130
-31 call2=msg(i1+2:)
- call hash(call1,i1-2,ih)
- call packcall(call2,n1,lbad1)
- n2=128*ih + (ntype+64)
- call pack50(n1,n2,data0)
- else
- i1=index(msg(4:),' ')
- call1=msg(4:i1+2)
- if(index(msg,'/').le.0) then
- ntype=8
- ih=0
- call packcall(call1,n1,lbad1)
- grid=msg(i1+4:i1+7)
- call packgrid(grid,ng,lbad2)
- n2=128*ng + (ntype+64)
- call pack50(n1,n2,data0)
- else
- ntype=9 ! or 11
- call1=msg(4:)
- call packpfx(call1,n1,ng,nadd)
- ntype=ntype + 2*nadd
- n2=128*ng + ntype + 64
- call pack50(n1,n2,data0)
- endif
- endif
- go to 900
-
-! Call(s) + report (msg #3; types -1 to -27)
-! Call(s) + R + report (msg #4; types -28 to -54)
-40 if(index(msg,' RRR').gt.0) go to 50
- i1=index(msg,'<')
- if(i1.gt.0 .and. (i1.lt.5 .or. i1.gt.8)) go to 50
- i2=index(msg,'/')
- if(i2.gt.0 .and.i2.le.4) then
- ntype=-10 ! -10 to -27
- i0=index(msg,' ')
- call1=msg(:i0-1)
- call packpfx(call1,n1,ng,nadd)
- ntype=ntype - 9*nadd
- i2=index(msg,' ')
- i3=index(msg,' R ')
- if(i3.gt.0) i2=i2+2 !-28 to -36
- read(msg(i2+2:i2+2),*,end=800,err=800) nrpt
- ntype=ntype - (nrpt-1)
- if(i3.gt.0) ntype=ntype-27
- n2=128*ng + ntype + 64
- call pack50(n1,n2,data0)
- go to 900
- else if(i1.eq.0) then
- go to 50
- endif
- call1=msg(:i1-2) !-1 to -9
- i2=index(msg,'>')
- call2=msg(i1+1:i2-1)
- call hash(call2,i2-i1-1,ih)
- i3=index(msg,' R ')
- if(i3.gt.0) i2=i2+2 !-28 to -36
- read(msg(i2+3:i2+3),*,end=42,err=42) nrpt
- go to 43
-42 nrpt=1
-43 ntype=-nrpt
- if(i3.gt.0) ntype=-(nrpt+27)
- call packcall(call1,n1,lbad1)
- n2=128*ih + (ntype+64)
- call pack50(n1,n2,data0)
- go to 900
-
-50 i0=index(msg,'<')
- if(i0.le.0 .and. msg(1:3).ne.'DE ') go to 60
- i3=index(msg,' RRR')
- if(i3.le.0) go to 60
-! Call or calls and RRR (msg#5; type2 12,14,15,16)
- i0=index(msg,'<')
- if(i0.eq.1) then
- if(index(msg,'/').le.0) then
- ntype=14
- i1=index(msg,'>')
- call1=msg(2:i1-1)
- call2=msg(i1+2:)
- i2=index(call2,' ')
- call2=call2(:i2-1)
- call packcall(call2,n1,lbad1)
- call hash(call1,i1-2,ih)
- n2=128*ih + (ntype+64)
- call pack50(n1,n2,data0)
- else
- stop '0002'
- endif
- else if(i0.ge.5 .and. i0.le.8) then
- if(index(msg,'/').le.0) then
- ntype=12
- i1=index(msg,'>')
- call1=msg(:i0-2)
- call2=msg(i0+1:i1-1)
- call packcall(call1,n1,lbad1)
- call hash(call2,i1-i0-1,ih)
- n2=128*ih + (ntype+64)
- call pack50(n1,n2,data0)
- else
- stop '0002'
- endif
- else
- i1=index(msg(4:),' ')
- call1=msg(4:i1+2)
- if(index(msg,'/').le.0) then
- ntype=9
- grid=msg(i1+4:i1+7)
- else
- ntype=15 ! or 16
- call1=msg(4:)
- i0=index(call1,' ')
- call1=call1(:i0-1)
- call packpfx(call1,n1,ng,nadd)
- ntype=ntype+nadd
- n2=128*ng + ntype + 64
- call pack50(n1,n2,data0)
- endif
- endif
- go to 900
-
-! TNX 73 GL (msg #6; type 18 ...)
-60 if(msg(1:4).ne.'TNX ') go to 70
- ntype=18
- n1=0
- i2=index(msg(5:),' ')
- name=msg(5:i2+4)
- call packname(name,i2-1,n1,ng)
- n2=128*ng + (ntype+64)
- call pack50(n1,n2,data0)
- go to 900
-
-! TNX name 73 GL (msg #6; type -56 ...)
-70 if(msg(1:3).ne.'OP ') go to 80
- ntype=-56
- n1=0
- i2=index(msg(4:),' ')
- name=msg(4:i2+3)
- call packname(name,i2-1,n1,ng)
- n2=128*ng + (ntype+64)
- call pack50(n1,n2,data0)
- go to 900
-
-! 73 DE call grid (msg #6; type 19)
-80 if(msg(1:6).ne.'73 DE ') go to 90
- ntype=19
- i1=index(msg(7:),' ')
- call1=msg(7:)
- if(index(call1,'/').le.0) then
- i1=index(call1,' ')
- grid=call1(i1+1:)
- call1=call1(:i1-1)
- call packcall(call1,n1,lbad1)
- call packgrid(grid,ng,lbad2)
- if(lbad1 .or. lbad2) go to 800
- n2=128*ng + (ntype+64)
- call pack50(n1,n2,data0)
- go to 900
- else
- ntype=21 ! or 22
- call packpfx(call1,n1,ng,nadd)
- ntype=ntype + nadd
- n2=128*ng + ntype + 64
- call pack50(n1,n2,data0)
- go to 900
- endif
-
-! [pwr] W [gain] DBD [73 GL] (msg #6; types 24, 25)
-90 if(index(msg,' W ').le.0) go to 140
- ntype=25
- if(index(msg,' DBD 73 GL').gt.0) ntype=24
- i1=index(msg,' ')
- read(msg(:i1-1),*,end=800,err=800) watts
- if(watts.ge.1.0) nwatts=watts
- if(watts.lt.1.0) nwatts=3000 + nint(1000.*watts)
- if(index(msg,'DIPOLE').gt.0) then
- ndbd=30000
- else if(index(msg,'VERTICAL').gt.0) then
- ndbd=30001
- else
- i2=index(msg(i1+3:),' ')
- read(msg(i1+3:i1+i2+1),*,end=800,err=800) ndbd
- endif
- n1=nwatts
- ng=ndbd + 32
- n2=128*ng + (ntype+64)
- call pack50(n1,n2,data0)
- go to 900
-
-! QRZ call (msg #3; type 26)
-100 call1=msg(5:)
- call packcall(call1,n1,lbad1)
- if(lbad1) go to 800
- ntype=26
- n2=ntype+64
- call pack50(n1,n2,data0)
- go to 900
-
-! PSE QSY [nnn] KHZ (msg #6; type 28)
-110 ntype=28
- read(msg(9:),*,end=800,err=800) n1
- n2=ntype+64
- call pack50(n1,n2,data0)
- go to 900
-
-! WX wx temp C|F wind (msg #6; type 29)
-120 ntype=29
- if(index(msg,' CLEAR ').gt.0) then
- i1=10
- n1=10000
- else if(index(msg,' CLOUDY ').gt.0) then
- i1=11
- n1=20000
- else if(index(msg,' RAIN ').gt.0) then
- i1=9
- n1=30000
- else if(index(msg,' SNOW ').gt.0) then
- i1=9
- n1=40000
- endif
- read(msg(i1:),*,err=800,end=800) ntemp
- ntemp=ntemp+100
- i1=index(msg,' C ')
- if(i1.gt.0) ntemp=ntemp+1000
- n1=n1+ntemp
- if(index(msg,' CALM').gt.0) ng=1
- if(index(msg,' BREEZES').gt.0) ng=2
- if(index(msg,' WINDY').gt.0) ng=3
- if(index(msg,' DRY').gt.0) ng=4
- if(index(msg,' HUMID').gt.0) ng=5
-
- n2=128*ng + (ntype+64)
- call pack50(n1,n2,data0)
-
- go to 900
-
-! Solar/geomagnetic/ionospheric data
-130 ntype=63
- call packprop(k,muf,ccur,cxp,n1)
- call hash(call1,i1-2,ih)
- n2=128*ih + ntype + 64
- call pack50(n1,n2,data0)
- go to 900
-
-140 continue
-
-! Plain text
-800 ntype=-57
- call packtext2(msg(:8),n1,ng)
- n2=128*ng + ntype + 64
- call pack50(n1,n2,data0)
- go to 900
-
-900 continue
- return
-end subroutine wqenc
diff --git a/lib/qso50/wqmsg.txt b/lib/qso50/wqmsg.txt
deleted file mode 100644
index 9f509b3..0000000
--- a/lib/qso50/wqmsg.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-"CQ K1JT FN20"
-"CQ PJ4/K1JT"
-" W6CQZ"
-"DE W6CQZ CM87"
-"DE PJ4/K1JT"
-"W6CQZ S4"
-"QRZ K1JT"
-"PJ4/W6CQZ S4"
-"K1JT R S3"
-"PJ4/K1JT R S3"
-" K1JT RRR"
-"W6CQZ RRR"
-"DE PJ4/K1JT RRR"
-"73 DE W6CQZ CM87"
-"73 DE PJ4/K1JT"
-"TNX VICTORIA 73 GL"
-"OP HARRY 73 GL"
-"5 W DIPOLE"
-"10 W VERTICAL"
-"1 W 0 DBD"
-"1500 W 21 DBD 73 GL"
-"PSE QSY 1811 KHZ"
-"WX SNOW -5 C CALM"
-"CUL JACK"
-"."
-"CQ K1JT FN20"
-" W6CQZ"
-"W6CQZ S4"
-"K1JT R S3"
-" K1JT RRR"
-"TNX JOE 73 GL"
diff --git a/lib/wrapkarn.c b/lib/wrapkarn.c
deleted file mode 100644
index 9e0a51c..0000000
--- a/lib/wrapkarn.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include "rs.h"
-
-static void *rs;
-static int first=1;
-
-void rs_encode_(int *dgen, int *sent)
-// Encode JT65 data dgen[12], producing sent[63].
-{
- int dat1[12];
- int b[51];
- int i;
-
- if(first) {
- // Initialize the JT65 codec
- rs=init_rs_int(6,0x43,3,1,51,0);
- first=0;
- }
-
- // Reverse data order for the Karn codec.
- for(i=0; i<12; i++) {
- dat1[i]=dgen[11-i];
- }
- // Compute the parity symbols
- encode_rs_int(rs,dat1,b);
-
- // Move parity symbols and data into sent[] array, in reverse order.
- for (i = 0; i < 51; i++) sent[50-i] = b[i];
- for (i = 0; i < 12; i++) sent[i+51] = dat1[11-i];
-}
-
-void rs_decode_(int *recd0, int *era0, int *numera0, int *decoded, int *nerr)
-// Decode JT65 received data recd0[63], producing decoded[12].
-// Erasures are indicated in era0[numera]. The number of corrected
-// errors is *nerr. If the data are uncorrectable, *nerr=-1 is returned.
-{
- int numera;
- int i;
- int era_pos[50];
- int recd[63];
-
- if(first) {
- rs=init_rs_int(6,0x43,3,1,51,0);
- first=0;
- }
-
- numera=*numera0;
- for(i=0; i<12; i++) recd[i]=recd0[62-i];
- for(i=0; i<51; i++) recd[12+i]=recd0[50-i];
- if(numera)
- for(i=0; i::finished, this, &MainWindow::diskDat);
- connect(&watcher3, SIGNAL(finished()),this,SLOT(fast_decode_done()));
// Q_EMIT startAudioInputStream (m_config.audio_input_device (), m_framesAudioInputBuffered, &m_detector, m_downSampleFactor, m_config.audio_input_channel ());
Q_EMIT startAudioInputStream (m_config.audio_input_device (), m_framesAudioInputBuffered, m_detector, m_downSampleFactor, m_config.audio_input_channel ());
Q_EMIT initializeAudioOutputStream (m_config.audio_output_device (), AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2, m_msAudioOutputBuffered);
@@ -1065,9 +1033,11 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
if(m_bFast9) m_bFastMode=true;
ui->cbFast9->setChecked(m_bFast9 or m_bFastMode);
- if(true || m_mode=="FT8") on_actionFT8_triggered();
+ if(true || m_mode=="FT8") on_actionJS8_triggered();
+
+ // TODO: jsherer - is this needed?
+ //ui->sbSubmode->setValue (vhf ? m_nSubMode : 0);
- ui->sbSubmode->setValue (vhf ? m_nSubMode : 0);
if(m_mode=="MSK144") {
Q_EMIT transmitFrequency (1000.0);
} else {
@@ -1133,7 +1103,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->cbMenus->setChecked(false);
}
- //UI Customizations
+ //UI Customizations & Tweaks
m_wideGraph.data()->installEventFilter(new EscapeKeyPressEater());
ui->mdiArea->addSubWindow(m_wideGraph.data(), Qt::Dialog | Qt::FramelessWindowHint | Qt::CustomizeWindowHint | Qt::Tool)->showMaximized();
//ui->menuDecode->setEnabled(true);
@@ -1148,15 +1118,39 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
}
ui->dxCallEntry->clear();
ui->dxGridEntry->clear();
- auto f = findFreeFreqOffset(1000, 2000, 50);
- setFreqOffsetForRestore(f, false);
+
+ //auto f = findFreeFreqOffset(1000, 2000, 50);
+ //setFreqOffsetForRestore(f, false);
+
ui->cbVHFcontest->setChecked(false); // this needs to always be false
ui->actionModeAutoreply->setChecked(m_config.autoreply_on_at_startup());
ui->spotButton->setChecked(m_config.spot_to_reporting_networks());
+ QActionGroup * modeActionGroup = new QActionGroup(this);
+ ui->actionModeJS8Normal->setActionGroup(modeActionGroup);
+ ui->actionModeJS8Fast->setActionGroup(modeActionGroup);
+ ui->actionModeJS8Turbo->setActionGroup(modeActionGroup);
+ ui->actionModeJS8Ultra->setActionGroup(modeActionGroup);
+
+ auto mbmp = new MousePressEater();
+ connect(mbmp, &MousePressEater::mousePressed, this, [this](QObject *, QMouseEvent * e, bool *pProcessed){
+ ui->menuModeJS8->popup(e->globalPos());
+ if(pProcessed) *pProcessed = true;
+ });
+ ui->modeButton->installEventFilter(mbmp);
+ if(!JS8_ENABLE_JS8B){
+ ui->actionModeJS8Fast->setVisible(false);
+ }
+ if(!JS8_ENABLE_JS8C){
+ ui->actionModeJS8Turbo->setVisible(false);
+ }
+ if(!JS8_ENABLE_JS8D){
+ ui->actionModeJS8Ultra->setVisible(false);
+ }
+
// prep
- prepareAutoreplyMode(ui->actionModeAutoreply->isChecked());
+ prepareHeartbeatMode(ui->actionModeJS8HB->isChecked());
prepareSpotting();
auto enterFilter = new EnterKeyPressEater();
@@ -1350,6 +1344,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
auto qsyAction = menu->addAction(QString("Jump to %1Hz").arg(selectedOffset));
connect(qsyAction, &QAction::triggered, this, [this, selectedOffset](){
setFreqOffsetForRestore(selectedOffset, false);
+ // TODO: prompt mode switch?
});
menu->addSeparator();
}
@@ -1378,6 +1373,10 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->tableWidgetCalls->clearSelection();
});
+ // savedMenu->setEnabled(savedMenu->isEnabled() && !ui->actionModeJS8HB->isChecked());
+ // directedMenu->setEnabled(directedMenu->isEnabled() && !ui->actionModeJS8HB->isChecked());
+ // relayAction->setEnabled(relayAction->isEnabled() && !ui->actionModeJS8HB->isChecked());
+
menu->addSeparator();
removeActivity->setDisabled(selectedOffset == -1);
@@ -1563,6 +1562,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
auto qsyAction = menu->addAction(QString("Jump to %1Hz").arg(selectedOffset));
connect(qsyAction, &QAction::triggered, this, [this, selectedOffset](){
setFreqOffsetForRestore(selectedOffset, false);
+ // TODO: prompt mode switch?
});
menu->addSeparator();
}
@@ -1598,6 +1598,10 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->tableWidgetCalls->clearSelection();
});
+ // savedMenu->setEnabled(savedMenu->isEnabled() && !ui->actionModeJS8HB->isChecked());
+ // directedMenu->setEnabled(directedMenu->isEnabled() && !ui->actionModeJS8HB->isChecked());
+ // relayAction->setEnabled(relayAction->isEnabled() && !ui->actionModeJS8HB->isChecked());
+
menu->addSeparator();
menu->addAction(addStation);
@@ -1661,6 +1665,18 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
btns.append(b);
}
*/
+ foreach(auto child, ui->buttonGrid->children()){
+ if(!child->isWidgetType()){
+ continue;
+ }
+
+ if(!child->objectName().contains("Button")){
+ continue;
+ }
+
+ auto b = qobject_cast(child);
+ b->setCursor(QCursor(Qt::PointingHandCursor));
+ }
auto buttonLayout = ui->buttonGrid->layout();
auto gridButtonLayout = qobject_cast(buttonLayout);
gridButtonLayout->setColumnMinimumWidth(0, width);
@@ -1783,6 +1799,125 @@ void MainWindow::initializeDummyData(){
return;
}
+#if 0
+ auto t = new QTimer(this);
+ t->setInterval(150);
+ connect(t, &QTimer::timeout, this, [this](){
+ if(!ui->extFreeTextMsgEdit->hasFocus()){
+ return;
+ }
+
+ auto c = ui->extFreeTextMsgEdit->textCursor();
+ int pos = qMin(c.selectionStart(), c.selectionEnd());
+
+ if(pos <= 5 && c.selectionStart() != c.selectionEnd()){
+ c.clearSelection();
+ ui->extFreeTextMsgEdit->setTextCursor(c);
+ }
+ });
+ t->start();
+
+ auto kpe = new KeyPressEater();
+ connect(kpe, &KeyPressEater::keyPressed, this, [this](QObject *obj, QKeyEvent * e, bool *pProcessed){
+ auto t = e->text();
+ auto c = ui->extFreeTextMsgEdit->textCursor();
+ int pos = qMin(c.selectionStart(), c.selectionEnd());
+
+ if(e->key() == Qt::Key_Escape){
+ *pProcessed = false;
+ return;
+ }
+
+ QTextCursor cc(c);
+ cc.setPosition(5);
+ cc.movePosition(QTextCursor::NextWord);
+ int cpos = qMax(cc.selectionStart(), cc.selectionEnd());
+ if(e->key() == Qt::Key_Backspace && e->modifiers().testFlag(Qt::ControlModifier) && pos < cpos){
+ *pProcessed = true;
+ return;
+ }
+
+ if((e->key() == Qt::Key_Backspace && pos <= 5) ||
+ (e->key() == Qt::Key_Delete && pos < 5)){
+ *pProcessed = true;
+ return;
+ }
+
+ if(e->key() == Qt::Key_V && e->modifiers().testFlag(Qt::ControlModifier) && pos <= 5){
+ *pProcessed = true;
+ return;
+ }
+
+ if(!t.isEmpty() && pos < 5){
+ *pProcessed = true;
+ return;
+ }
+ });
+ ui->extFreeTextMsgEdit->installEventFilter(kpe);
+
+ connect(ui->extFreeTextMsgEdit, &QTextEdit::copyAvailable, this, [this](bool available){
+ if(!available){
+ return;
+ }
+ auto c = ui->extFreeTextMsgEdit->textCursor();
+
+ qDebug() << "select" << c.selectionStart() << c.selectionEnd();
+
+ int pos = qMin(c.selectionStart(), c.selectionEnd());
+ if(pos <= 5){
+ auto text = c.selectedText();
+ if(!text.isEmpty()){
+ c.clearSelection();
+ ui->extFreeTextMsgEdit->setTextCursor(c);
+ }
+ }
+ });
+
+ /*
+ connect(ui->extFreeTextMsgEdit->document(), &QTextDocument::cursorPositionChanged, this, [this](const QTextCursor &){
+ auto c = ui->extFreeTextMsgEdit->textCursor();
+ int pos = qMin(c.selectionStart(), c.selectionEnd());
+ if(pos <= 5){
+ auto text = c.selectedText();
+ if(!text.isEmpty()){
+ c.clearSelection();
+ ui->extFreeTextMsgEdit->setTextCursor(c);
+ }
+ }
+ });
+
+ connect(ui->extFreeTextMsgEdit, &QTextEdit::cursorPositionChanged, this, [this](){
+ auto c = ui->extFreeTextMsgEdit->textCursor();
+ int pos = qMin(c.selectionStart(), c.selectionEnd());
+
+ if(pos <= 5){
+ auto text = c.selectedText();
+ if(!text.isEmpty()){
+ c.clearSelection();
+ ui->extFreeTextMsgEdit->setTextCursor(c);
+ }
+ }
+ });
+ */
+
+ /*connect(ui->extFreeTextMsgEdit->document(), &QTextDocument::contentsChange, this, [this](int from, int removed, int added){
+ if(from < 5 && removed == 1){
+ ui->extFreeTextMsgEdit->document()->blockSignals(true);
+ ui->extFreeTextMsgEdit->document()->undo();
+ ui->extFreeTextMsgEdit->document()->clearUndoRedoStacks(QTextDocument::RedoStack);
+ ui->extFreeTextMsgEdit->document()->blockSignals(false);
+ }
+ });*/
+
+ ui->extFreeTextMsgEdit->setText("HELLO BRAVE NEW WORLD");
+ auto c = ui->extFreeTextMsgEdit->textCursor();
+ c.setPosition(0);
+ c.setPosition(5, QTextCursor::KeepAnchor);
+ auto f = c.charFormat();
+ f.setFontStrikeOut(true);
+ c.setCharFormat(f);
+#endif
+
logHeardGraph("KN4CRD", "OH8STN");
logHeardGraph("KN4CRD", "K0OG");
logHeardGraph("K0OG", "KN4CRD");
@@ -1809,11 +1944,8 @@ void MainWindow::initializeDummyData(){
}
}
- auto d = DecodedText("h+vWp6mRPprH", 6);
- qDebug() << d.message() << buildMessageFrames(d.message());
-
- d = DecodedText("bYG4CKYT0cKG", 7);
- qDebug() << d.message();
+ auto d = DecodedText("SN5-lUuJkby0", Varicode::JS8CallFirst, 1);
+ qDebug () << "KN4CRD: K0OG ===>" << d.message();
// qDebug() << Varicode::isValidCallsign("@GROUP1", nullptr);
// qDebug() << Varicode::packAlphaNumeric50("VE7/KN4CRD");
@@ -1854,6 +1986,7 @@ void MainWindow::initializeDummyData(){
cd.utcTimestamp = dt;
cd.grid = i == 5 ? "J042" : i == 6 ? " FN42FN42FN" : "";
cd.tdrift = 0.1*i;
+ cd.mode = currentMode();
logCallActivity(cd, false);
ActivityDetail ad = {};
@@ -1862,6 +1995,7 @@ void MainWindow::initializeDummyData(){
ad.freq = 500 + 100*i;
ad.text = QString("%1: %2 TEST MESSAGE").arg(call).arg(m_config.my_callsign());
ad.utcTimestamp = dt;
+ ad.mode = cd.mode;
m_bandActivity[500+100*i] = { ad };
markOffsetDirected(500+100*i, false);
@@ -2089,7 +2223,9 @@ void MainWindow::writeSettings()
m_settings->setValue("RxFreq",ui->RxFreqSpinBox->value());
m_settings->setValue("TxFreq",ui->TxFreqSpinBox->value());
m_settings->setValue("WSPRfreq",ui->WSPRfreqSpinBox->value());
- m_settings->setValue("SubMode",ui->sbSubmode->value());
+ m_settings->setValue("SubMode",m_nSubMode);
+ m_settings->setValue("SubModeHB", ui->actionModeJS8HB->isChecked());
+ m_settings->setValue("SubModeHBAck", ui->actionHeartbeatAcknowledgements->isChecked());
m_settings->setValue("DTtol",m_DTtol);
m_settings->setValue("Ftol", ui->sbFtol->value ());
m_settings->setValue("MinSync",m_minSync);
@@ -2119,8 +2255,6 @@ void MainWindow::writeSettings()
m_settings->setValue ("JT65AP", ui->actionEnable_AP_JT65->isChecked ());
m_settings->setValue("SortBy", QVariant(m_sortCache));
m_settings->setValue("ShowColumns", QVariant(m_showColumnsCache));
- m_settings->setValue("HBAutoAck", m_hbAutoAck);
- m_settings->setValue("HBHidden", m_hbHidden);
m_settings->setValue("HBInterval", m_hbInterval);
m_settings->setValue("CQInterval", m_cqInterval);
@@ -2163,6 +2297,7 @@ void MainWindow::writeSettings()
{"snr", QVariant(cd.snr)},
{"grid", QVariant(cd.grid)},
{"freq", QVariant(cd.freq)},
+ {"tdrift", QVariant(cd.tdrift)},
#if CACHE_CALL_DATETIME_AS_STRINGS
{"ackTimestamp", QVariant(cd.ackTimestamp.toString("yyyy-MM-dd hh:mm:ss"))},
{"utcTimestamp", QVariant(cd.utcTimestamp.toString("yyyy-MM-dd hh:mm:ss"))},
@@ -2170,6 +2305,7 @@ void MainWindow::writeSettings()
{"ackTimestamp", QVariant(cd.ackTimestamp)},
{"utcTimestamp", QVariant(cd.utcTimestamp)},
#endif
+ {"mode", QVariant(cd.mode)},
});
}
m_settings->endGroup();
@@ -2243,6 +2379,12 @@ void MainWindow::readSettings()
ui->RxFreqSpinBox->setValue(0); // ensure a change is signaled
ui->RxFreqSpinBox->setValue(m_settings->value("RxFreq",1500).toInt());
m_nSubMode=m_settings->value("SubMode",0).toInt();
+ ui->actionModeJS8HB->setChecked(m_nSubMode == Varicode::JS8CallNormal && m_settings->value("SubModeHB", false).toBool());
+ ui->actionHeartbeatAcknowledgements->setChecked(m_settings->value("SubModeHBAck", false).toBool());
+ ui->actionModeJS8Normal->setChecked(m_nSubMode == Varicode::JS8CallNormal);
+ ui->actionModeJS8Fast->setChecked(m_nSubMode == Varicode::JS8CallFast);
+ ui->actionModeJS8Turbo->setChecked(m_nSubMode == Varicode::JS8CallTurbo);
+ ui->actionModeJS8Ultra->setChecked(m_nSubMode == Varicode::JS8CallUltra);
ui->sbFtol->setValue (m_settings->value("Ftol", 20).toInt());
m_minSync=m_settings->value("MinSync",0).toInt();
ui->syncSpinBox->setValue(m_minSync);
@@ -2284,8 +2426,6 @@ void MainWindow::readSettings()
m_sortCache = m_settings->value("SortBy").toMap();
m_showColumnsCache = m_settings->value("ShowColumns").toMap();
- m_hbAutoAck = m_settings->value("HBAutoAck", true).toBool();
- m_hbHidden = m_settings->value("HBHidden", true).toBool();
m_hbInterval = m_settings->value("HBInterval", 0).toInt();
m_cqInterval = m_settings->value("CQInterval", 0).toInt();
@@ -2331,6 +2471,8 @@ void MainWindow::readSettings()
auto snr = values.value("snr", -64).toInt();
auto grid = values.value("grid", "").toString();
auto freq = values.value("freq", 0).toInt();
+ auto tdrift = values.value("tdrift", 0).toFloat();
+
#if CACHE_CALL_DATETIME_AS_STRINGS
auto ackTimestampStr = values.value("ackTimestamp", "").toString();
@@ -2344,14 +2486,17 @@ void MainWindow::readSettings()
auto ackTimestamp = values.value("ackTimestamp").toDateTime();
auto utcTimestamp = values.value("utcTimestamp").toDateTime();
#endif
+ auto mode = values.value("mode", "JS8").toString();
CallDetail cd = {};
cd.call = call;
cd.snr = snr;
cd.grid = grid;
cd.freq = freq;
+ cd.tdrift = tdrift;
cd.ackTimestamp = ackTimestamp;
cd.utcTimestamp = utcTimestamp;
+ cd.mode = mode;
logCallActivity(cd, false);
}
@@ -2393,30 +2538,11 @@ void MainWindow::setDecodedTextFont (QFont const& font)
void MainWindow::fixStop()
{
- m_hsymStop=179;
- if(m_mode=="WSPR") {
- m_hsymStop=396;
- } else if(m_mode=="WSPR-LF") {
- m_hsymStop=813;
- } else if(m_mode=="Echo") {
- m_hsymStop=9;
- } else if (m_mode=="JT4"){
- m_hsymStop=176;
- if(m_config.decode_at_52s()) m_hsymStop=179;
- } else if (m_mode=="JT9"){
- m_hsymStop=173;
- if(m_config.decode_at_52s()) m_hsymStop=179;
- } else if (m_mode=="JT65" or m_mode=="JT9+JT65"){
- m_hsymStop=174;
- if(m_config.decode_at_52s()) m_hsymStop=179;
- } else if (m_mode=="QRA64"){
- m_hsymStop=179;
- if(m_config.decode_at_52s()) m_hsymStop=186;
- } else if (m_mode=="FreqCal"){
- m_hsymStop=((int(m_TRperiod/0.288))/8)*8;
- } else if (m_mode=="FT8") {
- m_hsymStop=JS8_SYMBOL_STOP;
- }
+ m_hsymStop=((int(m_TRperiod/0.288))/8)*8 - 1; // 0.288 because 6912/12000/2 = 0.288
+
+ if(m_nSubMode == Varicode::JS8CallUltra){
+ m_hsymStop++;
+ }
}
//-------------------------------------------------------------- dataSink()
@@ -2442,11 +2568,6 @@ void MainWindow::dataSink(qint64 frames)
&m_bUseRef,c_fname,len);
m_bClearRefSpec=false;
- if(m_mode=="ISCAT" or m_mode=="MSK144" or m_bFast9) {
- fastSink(frames);
- if(m_bFastMode) return;
- }
-
// Get power, spectrum, and ihsym
int trmin=m_TRperiod/60;
// int k (frames - 1);
@@ -2465,36 +2586,6 @@ void MainWindow::dataSink(qint64 frames)
if(m_mode=="MSK144") return;
fixStop();
- if (m_mode == "FreqCal"
- // only calculate after 1st chunk, also skip chunk where rig
- // changed frequency
- && !(m_ihsym % 8) && m_ihsym > 8 && m_ihsym <= m_hsymStop) {
- int RxFreq=ui->RxFreqSpinBox->value ();
- int nkhz=(m_freqNominal+RxFreq)/1000;
- int ftol = ui->sbFtol->value ();
- freqcal_(&dec_data.d2[0],&k,&nkhz,&RxFreq,&ftol,&line[0],80);
- QString t=QString::fromLatin1(line);
- DecodedText decodedtext {t, false, m_config.my_grid ()};
- ui->decodedTextBrowser->displayDecodedText (decodedtext,m_baseCall,m_config.DXCC(),
- m_logBook,m_config.color_primary_highlight(),m_config.color_MyCall(),m_config.color_DXCC(),
- m_config.color_NewCall(),m_config.ppfx());
- if (ui->measure_check_box->isChecked ()) {
- // Append results text to file "fmt.all".
- QFile f {m_config.writeable_data_dir ().absoluteFilePath ("fmt.all")};
- if (f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) {
- QTextStream out(&f);
- out << t << endl;
- f.close();
- } else {
- MessageBox::warning_message (this, tr ("File Open Error")
- , tr ("Cannot open \"%1\" for append: %2")
- .arg (f.fileName ()).arg (f.errorString ()));
- }
- }
- if(m_ihsym==m_hsymStop && ui->actionFrequency_calibration->isChecked()) {
- freqCalStep();
- }
- }
if(m_ihsym==3*m_hsymStop/4) {
m_dialFreqRxWSPR=m_freqNominal;
@@ -2621,120 +2712,6 @@ QString MainWindow::save_wave_file (QString const& name, short const * data, int
//-------------------------------------------------------------- fastSink()
void MainWindow::fastSink(qint64 frames)
{
- int k (frames);
- bool decodeNow=false;
-
- if(k < m_k0) { //New sequence ?
- memcpy(fast_green2,fast_green,4*703); //Copy fast_green[] to fast_green2[]
- memcpy(fast_s2,fast_s,4*703*64); //Copy fast_s[] into fast_s2[]
- fast_jh2=fast_jh;
- if(!m_diskData) memset(dec_data.d2,0,2*30*12000); //Zero the d2[] array
- m_bFastDecodeCalled=false;
- m_bDecoded=false;
- }
-
- QDateTime tnow=DriftingDateTime::currentDateTimeUtc();
- int ihr=tnow.toString("hh").toInt();
- int imin=tnow.toString("mm").toInt();
- int isec=tnow.toString("ss").toInt();
- isec=isec - isec%m_TRperiod;
- int nutc0=10000*ihr + 100*imin + isec;
- if(m_diskData) nutc0=m_UTCdisk;
- char line[80];
- bool bmsk144=((m_mode=="MSK144") and (m_monitoring or m_diskData));
- line[0]=0;
-
- int RxFreq=ui->RxFreqSpinBox->value ();
- int nTRpDepth=m_TRperiod + 1000*(m_ndepth & 3);
- qint64 ms0 = DriftingDateTime::currentMSecsSinceEpoch();
- strncpy(dec_data.params.mycall, (m_baseCall+" ").toLatin1(),12);
- QString hisCall {ui->dxCallEntry->text ()};
- bool bshmsg=ui->cbShMsgs->isChecked();
- bool bcontest=ui->cbVHFcontest->isChecked();
- bool bswl=ui->cbSWL->isChecked();
- strncpy(dec_data.params.hiscall,(Radio::base_callsign (hisCall) + " ").toLatin1 ().constData (), 12);
- strncpy(dec_data.params.mygrid, (m_config.my_grid()+" ").toLatin1(),6);
- QString dataDir;
- dataDir = m_config.writeable_data_dir ().absolutePath ();
- char ddir[512];
- strncpy(ddir,dataDir.toLatin1(), sizeof (ddir) - 1);
- float pxmax = 0;
- float rmsNoGain = 0;
- int ftol = ui->sbFtol->value ();
- hspec_(dec_data.d2,&k,&nutc0,&nTRpDepth,&RxFreq,&ftol,&bmsk144,&bcontest,
- &m_bTrain,m_phaseEqCoefficients.constData(),&m_inGain,&dec_data.params.mycall[0],
- &dec_data.params.hiscall[0],&bshmsg,&bswl,
- &ddir[0],fast_green,fast_s,&fast_jh,&pxmax,&rmsNoGain,&line[0],&dec_data.params.mygrid[0],
- 12,12,512,80,6);
- float px = fast_green[fast_jh];
- QString t;
- t.sprintf(" Rx noise: %5.1f ",px);
- ui->signal_meter_widget->setValue(rmsNoGain,pxmax); // Update thermometer
- m_fastGraph->plotSpec(m_diskData,m_UTCdisk);
-
- if(bmsk144 and (line[0]!=0)) {
- QString message {QString::fromLatin1 (line)};
- DecodedText decodedtext {message.replace (QChar::LineFeed, ""), bcontest, m_config.my_grid ()};
- ui->decodedTextBrowser->displayDecodedText (decodedtext,m_baseCall,m_config.DXCC(),
- m_logBook,m_config.color_primary_highlight(),m_config.color_MyCall(),m_config.color_DXCC(),
- m_config.color_NewCall(),m_config.ppfx());
- m_bDecoded=true;
- if (m_mode != "ISCAT") postDecode (true, decodedtext.string ());
- writeAllTxt(message, decodedtext.bits());
- bool stdMsg = decodedtext.report(m_baseCall,
- Radio::base_callsign(ui->dxCallEntry->text()),m_rptRcvd);
- //if (stdMsg) pskPost (decodedtext);
- }
-
- float fracTR=float(k)/(12000.0*m_TRperiod);
- decodeNow=false;
- if(fracTR>0.92) {
- m_dataAvailable=true;
- fast_decode_done();
- m_bFastDone=true;
- }
-
- m_k0=k;
- if(m_diskData and m_k0 >= dec_data.params.kin - 7 * 512) decodeNow=true;
- if(!m_diskData and m_tRemaining<0.35 and !m_bFastDecodeCalled) decodeNow=true;
- if(m_mode=="MSK144") decodeNow=false;
-
- if(decodeNow) {
- m_dataAvailable=true;
- m_t0=0.0;
- m_t1=k/12000.0;
- m_kdone=k;
- dec_data.params.newdat=1;
- if(!m_decoderBusy) {
- m_bFastDecodeCalled=true;
- decode();
- }
- }
-
- if(decodeNow or m_bFastDone) {
- if(!m_diskData) {
- QDateTime now {DriftingDateTime::currentDateTimeUtc()};
- int n=now.time().second() % m_TRperiod;
- if(n<(m_TRperiod/2)) n=n+m_TRperiod;
- auto const& period_start = now.addSecs (-n);
- m_fnameWE = m_config.save_directory ().absoluteFilePath (period_start.toString ("yyMMdd_hhmmss"));
- m_fileToSave.clear ();
- if(m_saveAll or m_bAltV or (m_bDecoded and m_saveDecoded) or (m_mode!="MSK144" and m_mode!="FT8")) {
- m_bAltV=false;
- // the following is potential a threading hazard - not a good
- // idea to pass pointer to be processed in another thread
- m_saveWAVWatcher.setFuture (QtConcurrent::run (std::bind (&MainWindow::save_wave_file,
- this, m_fnameWE, &dec_data.d2[0], m_TRperiod, m_config.my_callsign(),
- m_config.my_grid(), m_mode, m_nSubMode, m_freqNominal, m_hisCall, m_hisGrid)));
- }
- if(m_mode!="MSK144") {
- killFileTimer.start (3*1000*m_TRperiod/4); //Kill 3/4 period from now
- }
- }
- m_bFastDone=false;
- }
- float tsec=0.001*(DriftingDateTime::currentMSecsSinceEpoch() - ms0);
- m_fCPUmskrtd=0.9*m_fCPUmskrtd + 0.1*tsec;
}
void MainWindow::showSoundInError(const QString& errorMsg)
@@ -2766,6 +2743,14 @@ void rebuildMacQAction(QMenu *menu, QAction *existingAction){
menu->removeAction(dummyAction);
}
+void MainWindow::on_menuModeJS8_aboutToShow(){
+ bool canChangeMode = !m_transmitting && m_txFrameCount == 0 && m_txFrameQueue.isEmpty();
+ ui->actionModeJS8Normal->setEnabled(canChangeMode);
+ ui->actionModeJS8Fast->setEnabled(canChangeMode);
+ ui->actionModeJS8Turbo->setEnabled(canChangeMode);
+ ui->actionModeJS8Ultra->setEnabled(canChangeMode);
+}
+
void MainWindow::on_menuControl_aboutToShow(){
QMenu * freqMenu = new QMenu(this->menuBar());
buildFrequencyMenu(freqMenu);
@@ -2848,7 +2833,7 @@ void MainWindow::on_menuWindow_aboutToShow(){
rebuildMacQAction(ui->menuWindow, ui->actionShow_Call_Activity_Columns);
#endif
- ui->actionShow_Band_Heartbeats_and_ACKs->setChecked(!m_hbHidden);
+ ui->actionShow_Band_Heartbeats_and_ACKs->setChecked(ui->actionModeJS8HB->isChecked());
ui->actionShow_Band_Heartbeats_and_ACKs->setEnabled(ui->actionShow_Band_Activity->isChecked());
}
@@ -2937,7 +2922,6 @@ void MainWindow::on_actionShow_Band_Activity_triggered(bool checked){
}
void MainWindow::on_actionShow_Band_Heartbeats_and_ACKs_triggered(bool checked){
- m_hbHidden = !checked;
displayBandActivity();
}
@@ -3071,7 +3055,7 @@ void MainWindow::openSettings(int tab){
bool b = vhf && (m_mode=="JT4" or m_mode=="JT65" or m_mode=="ISCAT" or
m_mode=="JT9" or m_mode=="MSK144" or m_mode=="QRA64");
if(b) VHF_features_enabled(b);
- if(m_mode=="FT8") on_actionFT8_triggered();
+ if(m_mode=="FT8") on_actionJS8_triggered();
if(b) VHF_features_enabled(b);
m_config.transceiver_online ();
@@ -3255,6 +3239,27 @@ Radio::Frequency MainWindow::dialFrequency() {
m_rigState.tx_frequency () : m_rigState.frequency ()};
}
+QString MainWindow::currentMode(){
+ if(m_nSubMode == Varicode::JS8CallNormal){
+ return "NORMAL";
+ }
+ else if(m_nSubMode == Varicode::JS8CallFast){
+ return "FAST";
+ }
+ else if(m_nSubMode == Varicode::JS8CallTurbo){
+ return "TURBO";
+ }
+ else if(m_nSubMode == Varicode::JS8CallUltra){
+#ifdef JS8D_IS_ULTRA
+ return "ULTRA";
+#else
+ return "SLOW";
+#endif
+ }
+
+ return "?";
+}
+
void MainWindow::updateCurrentBand(){
QVariant state = ui->readFreq->property("state");
if(!state.isValid()){
@@ -4056,89 +4061,10 @@ void MainWindow::decode() //decode()
from += noffset;
size -= noffset;
}
- if(m_mode=="ISCAT" or m_mode=="MSK144" or m_bFast9) {
- float t0=m_t0;
- float t1=m_t1;
- qApp->processEvents(); //Update the waterfall
- if(m_nPick > 0) {
- t0=m_t0Pick;
- t1=m_t1Pick;
- }
- static short int d2b[360000];
- narg[0]=dec_data.params.nutc;
- if(m_kdone>12000*m_TRperiod) {
- m_kdone=12000*m_TRperiod;
- }
- narg[1]=m_kdone;
- narg[2]=m_nSubMode;
- narg[3]=dec_data.params.newdat;
- narg[4]=dec_data.params.minSync;
- narg[5]=m_nPick;
- narg[6]=1000.0*t0;
- narg[7]=1000.0*t1;
- narg[8]=2; //Max decode lines per decode attempt
- if(dec_data.params.minSync<0) narg[8]=50;
- if(m_mode=="ISCAT") narg[9]=101; //ISCAT
- if(m_mode=="JT9") narg[9]=102; //Fast JT9
- if(m_mode=="MSK144") narg[9]=104; //MSK144
- narg[10]=ui->RxFreqSpinBox->value();
- narg[11]=ui->sbFtol->value ();
- narg[12]=0;
- narg[13]=-1;
- narg[14]=m_config.aggressive();
- memcpy(d2b,dec_data.d2,2*360000);
- watcher3.setFuture (QtConcurrent::run (std::bind (fast_decode_,&d2b[0],
- &narg[0],&m_TRperiod,&m_msg[0][0],
- dec_data.params.mycall,dec_data.params.hiscall,8000,12,12)));
- } else {
- memcpy(to, from, qMin(mem_js8->size(), size));
- QFile {m_config.temp_dir ().absoluteFilePath (".lock")}.remove (); // Allow jt9 to start
- decodeBusy(true);
- }
-}
-void::MainWindow::fast_decode_done()
-{
- float t,tmax=-99.0;
- dec_data.params.nagain=false;
- dec_data.params.ndiskdat=false;
-// if(m_msg[0][0]==0) m_bDecoded=false;
- for(int i=0; m_msg[i][0] && i<100; i++) {
- QString message=QString::fromLatin1(m_msg[i]);
- m_msg[i][0]=0;
- if(message.length()>80) message=message.left (80);
- if(narg[13]/8==narg[12]) message=message.trimmed().replace("<...>",m_calls);
-
-//Left (Band activity) window
- DecodedText decodedtext {message.replace (QChar::LineFeed, ""), "FT8" == m_mode &&
- ui->cbVHFcontest->isChecked(), m_config.my_grid ()};
- if(!m_bFastDone) {
- ui->decodedTextBrowser->displayDecodedText (decodedtext,m_baseCall,m_config.DXCC(),
- m_logBook,m_config.color_primary_highlight(),m_config.color_MyCall(),m_config.color_DXCC(),
- m_config.color_NewCall(),m_config.ppfx());
- }
-
- t=message.mid(10,5).toFloat();
- if(t>tmax) {
- tmax=t;
- m_bDecoded=true;
- }
- postDecode (true, decodedtext.string ());
- writeAllTxt(message, decodedtext.bits());
-
- if(m_mode=="JT9" or m_mode=="MSK144") {
- // find and extract any report for myCall
- bool stdMsg = decodedtext.report(m_baseCall,
- Radio::base_callsign(ui->dxCallEntry->text()), m_rptRcvd);
-
- // extract details and send to PSKreporter
- //if (stdMsg) pskPost (decodedtext);
- }
- }
- m_startAnother=m_loopall;
- m_nPick=0;
- ui->DecodeButton->setChecked (false);
- m_bFastDone=false;
+ memcpy(to, from, qMin(mem_js8->size(), size));
+ QFile {m_config.temp_dir ().absoluteFilePath (".lock")}.remove (); // Allow jt9 to start
+ decodeBusy(true);
}
void MainWindow::writeAllTxt(QString message, int bits)
@@ -4153,7 +4079,7 @@ void MainWindow::writeAllTxt(QString message, int bits)
<< "JS8" << endl;
m_RxLog=0;
}
- auto dt = DecodedText(message, bits);
+ auto dt = DecodedText(message, bits, m_nSubMode);
out << dt.message() << endl;
f.close();
} else {
@@ -4285,7 +4211,7 @@ void MainWindow::readFromStdout() //readFromStdout
}
int n=t.length();
auto logText = t.mid(0, n-2);
- auto dt = DecodedText(logText, false, m_config.my_grid());
+ auto dt = DecodedText(logText, false, m_config.my_grid(), m_nSubMode);
out << logText << " " << dt.message() << endl;
f.close();
} else {
@@ -4295,7 +4221,7 @@ void MainWindow::readFromStdout() //readFromStdout
}
DecodedText decodedtext {QString::fromUtf8 (t.constData ()).remove (QRegularExpression {"\r|\n"}), "FT8" == m_mode &&
- ui->cbVHFcontest->isChecked(), m_config.my_grid ()};
+ ui->cbVHFcontest->isChecked(), m_config.my_grid (), m_nSubMode};
bool bValidFrame = decodedtext.snr() > -24;
@@ -4342,6 +4268,7 @@ void MainWindow::readFromStdout() //readFromStdout
d.snr = decodedtext.snr();
d.isBuffered = false;
d.tdrift = decodedtext.dt();
+ d.mode = currentMode();
// if we have any "first" frame, and a buffer is already established, clear it...
int prevBufferOffset = -1;
@@ -4378,6 +4305,7 @@ void MainWindow::readFromStdout() //readFromStdout
cd.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
cd.bits = decodedtext.bits();
cd.tdrift = decodedtext.dt();
+ cd.mode = currentMode();
// Only respond to HEARTBEATS...remember that CQ messages are "Alt" pings
if(decodedtext.isHeartbeat()){
@@ -4401,6 +4329,7 @@ void MainWindow::readFromStdout() //readFromStdout
cmd.freq = cd.freq;
cmd.utcTimestamp = cd.utcTimestamp;
cmd.tdrift = cd.tdrift;
+ cmd.mode = cd.mode;
m_rxCommandQueue.append(cmd);
}
@@ -4429,6 +4358,7 @@ void MainWindow::readFromStdout() //readFromStdout
cmd.bits = decodedtext.bits();
cmd.extra = parts.length() > 2 ? parts.mid(3).join(" ") : "";
cmd.tdrift = decodedtext.dt();
+ cmd.mode = currentMode();
// if the command is a buffered command and its not the last frame OR we have from or to in a separate message (compound call)
if((Varicode::isCommandBuffered(cmd.cmd) && (cmd.bits & Varicode::JS8CallLast) != Varicode::JS8CallLast) || cmd.from == "<....>" || cmd.to == "<....>"){
@@ -4444,6 +4374,7 @@ void MainWindow::readFromStdout() //readFromStdout
cmdcd.utcTimestamp = cmd.utcTimestamp;
cmdcd.ackTimestamp = cmd.to == m_config.my_callsign() ? cmd.utcTimestamp : QDateTime{};
cmdcd.tdrift = cmd.tdrift;
+ cmdcd.mode = currentMode();
logCallActivity(cmdcd, false);
logHeardGraph(cmd.from, cmd.to);
}
@@ -4477,6 +4408,7 @@ void MainWindow::readFromStdout() //readFromStdout
td.freq = cmd.freq;
td.utcTimestamp = cmd.utcTimestamp;
td.tdrift = cmd.tdrift;
+ td.mode = currentMode();
logCallActivity(td, true);
logHeardGraph(cmd.from, cmd.to);
}
@@ -4867,7 +4799,17 @@ void MainWindow::guiUpdate()
if(m_TRperiod==0) m_TRperiod=60;
txDuration=0.0;
- if(m_modeTx=="FT8") txDuration=1.0 + JS8_NUM_SYMBOLS * (double)JS8_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE; // FT8
+ if(m_modeTx=="FT8"){
+ if(m_nSubMode == Varicode::JS8CallNormal){
+ txDuration=JS8A_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8A_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
+ } else if(m_nSubMode == Varicode::JS8CallFast){
+ txDuration=JS8B_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8B_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
+ } else if(m_nSubMode == Varicode::JS8CallTurbo){
+ txDuration=JS8C_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8C_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
+ } else if(m_nSubMode == Varicode::JS8CallUltra){
+ txDuration=JS8D_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8D_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
+ }
+ }
double tx1=0.0;
double tx2=txDuration;
@@ -4941,7 +4883,21 @@ void MainWindow::guiUpdate()
if(msgLength==0 and !m_tune) on_stopTxButton_clicked();
// 15.0 - 12.6
- if(fTR > 1.0-(2.4/15.0) && fTR < 1.0){
+ double ratio = 1.0;
+ if(m_nSubMode == Varicode::JS8CallNormal){
+ ratio = (((double)m_TRperiod - (JS8_NUM_SYMBOLS*(double)JS8A_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE))/(double)m_TRperiod);
+ }
+ else if(m_nSubMode == Varicode::JS8CallFast){
+ ratio = (((double)m_TRperiod - (JS8_NUM_SYMBOLS*(double)JS8B_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE))/(double)m_TRperiod);
+ }
+ else if(m_nSubMode == Varicode::JS8CallTurbo){
+ ratio = (((double)m_TRperiod - (JS8_NUM_SYMBOLS*(double)JS8C_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE))/(double)m_TRperiod);
+ }
+ else if(m_nSubMode == Varicode::JS8CallUltra){
+ ratio = (((double)m_TRperiod - (JS8_NUM_SYMBOLS*(double)JS8D_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE))/(double)m_TRperiod);
+ }
+
+ if(fTR > 1.0-ratio && fTR < 1.0){
if(!m_deadAirTone){
qDebug() << "should start dead air tone";
m_deadAirTone = true;
@@ -4953,7 +4909,16 @@ void MainWindow::guiUpdate()
}
}
- float lateThreshold=(2.5 - m_config.txDelay())/15.0; // 0.75;
+ // the late threshold is the dead air time minus the tx delay time
+ float lateThreshold = ratio - (m_config.txDelay() / m_TRperiod);
+ if(m_nSubMode == Varicode::JS8CallFast){
+ // for the faster mode, only allow 3/4 late threshold
+ lateThreshold *= 0.75;
+ }
+ else if(m_nSubMode == Varicode::JS8CallTurbo){
+ // for the turbo mode, only allow 1/2 late threshold
+ lateThreshold *= 0.5;
+ }
if(g_iptt==0 and ((m_bTxTime and fTR0) or m_tune)) {
//### Allow late starts
icw[0]=m_ncw;
@@ -4963,7 +4928,7 @@ void MainWindow::guiUpdate()
emitPTT(true);
m_tx_when_ready = true;
- qDebug() << "start threshold" << fTR << lateThreshold;
+ qDebug() << "start threshold" << fTR << lateThreshold << ms;
}
// TODO: stop
@@ -5010,10 +4975,18 @@ void MainWindow::guiUpdate()
// 0: [000] <- this is standard set
// 1: [001] <- this is fox/hound
//m_i3bit=0;
- qDebug() << "genft8" << message;
+ qDebug() << "gen tones" << message;
char ft8msgbits[75 + 12]; //packed 75 bit ft8 message plus 12-bit CRC
- genft8_(message, MyGrid, &bcontest, &m_i3bit, msgsent, const_cast (ft8msgbits),
- const_cast (itone), 22, 6, 22);
+
+ if(m_nSubMode == Varicode::JS8CallNormal){
+ qDebug() << "gen ft8";
+ genft8_(message, MyGrid, &bcontest, &m_i3bit, msgsent, const_cast (ft8msgbits),
+ const_cast (itone), 22, 6, 22);
+ } else if (m_nSubMode == Varicode::JS8CallFast || m_nSubMode == Varicode::JS8CallTurbo || m_nSubMode == Varicode::JS8CallUltra){
+ qDebug() << "gen js8";
+ genjs8_(message, MyGrid, &bcontest, &m_i3bit, msgsent, const_cast (ft8msgbits),
+ const_cast (itone), 22, 6, 22);
+ }
msgibits = m_i3bit;
msgsent[22]=0;
@@ -5201,7 +5174,7 @@ void MainWindow::guiUpdate()
if(m_transmitting) {
char s[41];
- auto dt = DecodedText(msgsent, msgibits);
+ auto dt = DecodedText(msgsent, msgibits, m_nSubMode);
sprintf(s,"Tx: %s", dt.message().toLocal8Bit().mid(0, 41).data());
m_nsendingsh=0;
if(s[4]==64) m_nsendingsh=1;
@@ -5387,7 +5360,7 @@ void MainWindow::startTx2()
void MainWindow::stopTx()
{
Q_EMIT endTransmitMessage ();
- auto dt = DecodedText(m_currentMessage.trimmed(), m_currentMessageBits);
+ auto dt = DecodedText(m_currentMessage.trimmed(), m_currentMessageBits, m_nSubMode);
last_tx_label.setText("Last Tx: " + dt.message()); //m_currentMessage.trimmed());
m_btxok = false;
@@ -5779,82 +5752,30 @@ void MainWindow::on_addButton_clicked() //Add button
void MainWindow::msgtype(QString t, QLineEdit* tx) //msgtype()
{
- char message[29];
- char msgsent[29];
- int itone0[NUM_ISCAT_SYMBOLS]; //Dummy array, data not used
- int len1=22;
- QByteArray s=t.toUpper().toLocal8Bit();
- ba2msg(s,message);
- int ichk=1,itype=0;
- gen65_(message,&ichk,msgsent,itone0,&itype,len1,len1);
- msgsent[22]=0;
- bool text=false;
- bool shortMsg=false;
- if(itype==6) text=true;
- if(itype==7 and m_config.enable_VHF_features() and
- m_mode=="JT65") shortMsg=true;
- if(m_mode=="MSK144" and t.mid(0,1)=="<") text=false;
- if((m_mode=="MSK144" or m_mode=="FT8") and ui->cbVHFcontest->isChecked()) {
- int i0=t.trimmed().length()-7;
- if(t.mid(i0,3)==" R ") text=false;
- }
- QPalette p(tx->palette());
- if(text) {
- p.setColor(QPalette::Base,"#ffccff");
- } else {
- if(shortMsg) {
- p.setColor(QPalette::Base,"#66ffff");
- } else {
- p.setColor(QPalette::Base,Qt::transparent);
- if(m_mode=="MSK144" and t.mid(0,1)=="<") {
- p.setColor(QPalette::Base,"#00ffff");
- }
- }
- }
- tx->setPalette(p);
- auto pos = tx->cursorPosition ();
- tx->setText(t.toUpper());
- tx->setCursorPosition (pos);
}
void MainWindow::on_tx1_editingFinished() //tx1 edited
{
- QString t=ui->tx1->text();
- msgtype(t, ui->tx1);
}
void MainWindow::on_tx2_editingFinished() //tx2 edited
{
- QString t=ui->tx2->text();
- msgtype(t, ui->tx2);
}
void MainWindow::on_tx3_editingFinished() //tx3 edited
{
- QString t=ui->tx3->text();
- msgtype(t, ui->tx3);
}
void MainWindow::on_tx4_editingFinished() //tx4 edited
{
- QString t=ui->tx4->text();
- msgtype(t, ui->tx4);
}
void MainWindow::on_tx5_currentTextChanged (QString const& text) //tx5 edited
{
- msgtype(text, ui->tx5->lineEdit ());
}
void MainWindow::on_tx6_editingFinished() //tx6 edited
{
- QString t=ui->tx6->text().toUpper();
- if(t.indexOf(" ")>0) {
- QString t1=t.split(" ").at(1);
- m_CQtype="CQ";
- if(t1.size()==2) m_CQtype="CQ " + t1;
- }
- msgtype(t, ui->tx6);
}
void MainWindow::cacheActivity(QString key){
@@ -6274,7 +6195,7 @@ QString MainWindow::createMessageTransmitQueue(QString const& text, bool reset){
QStringList lines;
foreach(auto frame, frames){
- auto dt = DecodedText(frame.first, frame.second);
+ auto dt = DecodedText(frame.first, frame.second, m_nSubMode);
lines.append(dt.message());
}
@@ -6284,7 +6205,11 @@ QString MainWindow::createMessageTransmitQueue(QString const& text, bool reset){
displayTextForFreq(QString("%1 %2 ").arg(joined).arg(m_config.eot()), freq, DriftingDateTime::currentDateTimeUtc(), true, true, true);
// if we're transmitting a message to be displayed, we should bump the repeat buttons...
+#if JS8HB_RESET_HB_TIMER_ON_TX
resetAutomaticIntervalTransmissions(false, false);
+#else
+ resetCQTimer(false);
+#endif
// keep track of the last message text sent
m_lastTxMessage = text;
@@ -6338,7 +6263,6 @@ void MainWindow::on_textEditRX_mouseDoubleClicked(){
void MainWindow::on_nextFreeTextMsg_currentTextChanged (QString const& text)
{
- msgtype(text, ui->nextFreeTextMsg);
}
void MainWindow::on_extFreeTextMsgEdit_currentTextChanged (QString const& text)
@@ -6399,7 +6323,8 @@ QList> MainWindow::buildMessageFrames(const QString &text){
mygrid,
selectedCall,
text,
- forceIdentify);
+ forceIdentify,
+ m_nSubMode);
#if 0
qDebug() << "frames:";
@@ -6917,26 +6842,119 @@ void MainWindow::displayWidgets(qint64 n)
m_lastCallsign.clear (); // ensures Tx5 is updated for new modes
}
-void MainWindow::on_actionModeJS8_triggered(){
- // TODO: uncheck all other modes
+void MainWindow::on_actionModeJS8HB_toggled(bool checked){
+ // prep hb mode
+ prepareHeartbeatMode(checked);
+ displayActivity(true);
+
+ on_actionJS8_triggered();
+}
+
+void MainWindow::on_actionHeartbeatAcknowledgements_toggled(bool checked){
+ // prep hb ack mode
+ prepareHeartbeatMode(ui->actionModeJS8HB->isChecked());
+ displayActivity(true);
+
+ on_actionJS8_triggered();
+}
+
+void MainWindow::on_actionModeJS8Normal_triggered(){
+ on_actionJS8_triggered();
+}
+
+void MainWindow::on_actionModeJS8Fast_triggered(){
+ on_actionJS8_triggered();
+}
+
+void MainWindow::on_actionModeJS8Turbo_triggered(){
+ on_actionJS8_triggered();
+}
+
+void MainWindow::on_actionModeJS8Ultra_triggered(){
+ on_actionJS8_triggered();
}
void MainWindow::on_actionModeAutoreply_toggled(bool checked){
- prepareAutoreplyMode(checked);
+ // update the HB ack option (needs autoreply on)
+ prepareHeartbeatMode(ui->actionModeJS8HB->isChecked());
+
+ // then update the js8 mode
+ on_actionJS8_triggered();
}
-void MainWindow::prepareAutoreplyMode(bool enabled){
- // heartbeat is now only available in autoreply mode
+void MainWindow::prepareHeartbeatMode(bool enabled){
+ // heartbeat is only available in HB mode
ui->hbMacroButton->setVisible(enabled);
- ui->actionHeartbeat->setVisible(enabled);
+ if(!enabled){
+ ui->hbMacroButton->setChecked(false);
+ }
+ ui->actionHeartbeat->setEnabled(enabled);
+ ui->actionModeJS8HB->setEnabled(m_nSubMode == Varicode::JS8CallNormal);
+ ui->actionHeartbeatAcknowledgements->setEnabled(ui->actionModeAutoreply->isChecked() && enabled);
+
+ //ui->actionCQ->setEnabled(!enabled);
+ //ui->actionFocus_Message_Reply_Area->setEnabled(!enabled);
+
+ // default to not displaying the other buttons
+ // ui->cqMacroButton->setVisible(!enabled);
+ // ui->replyMacroButton->setVisible(!enabled);
+ // ui->snrMacroButton->setVisible(!enabled);
+ // ui->infoMacroButton->setVisible(!enabled);
+ // ui->macrosMacroButton->setVisible(!enabled);
+ // ui->queryButton->setVisible(!enabled);
+ // ui->extFreeTextMsgEdit->setVisible(!enabled);
+ // if(enabled){
+ // ui->extFreeTextMsgEdit->clear();
+ // }
+
+ // show heartbeat and acks in hb mode only
+ // ui->actionShow_Band_Heartbeats_and_ACKs->setChecked(enabled);
+ // ui->actionShow_Band_Heartbeats_and_ACKs->setVisible(true);
+ // ui->actionShow_Band_Heartbeats_and_ACKs->setEnabled(false);
// update the HB button immediately
updateRepeatButtonDisplay();
+ updateButtonDisplay();
}
-void MainWindow::on_actionFT8_triggered()
+void MainWindow::on_actionJS8_triggered()
{
m_mode="FT8";
+ m_nSubMode=0;
+ if(ui->actionModeJS8Normal->isChecked()){
+ m_nSubMode=Varicode::JS8CallNormal;
+ }
+ else if(ui->actionModeJS8Fast->isChecked()){
+ m_nSubMode=Varicode::JS8CallFast;
+ }
+ else if(ui->actionModeJS8Turbo->isChecked()){
+ m_nSubMode=Varicode::JS8CallTurbo;
+ }
+ else if(ui->actionModeJS8Ultra->isChecked()){
+ m_nSubMode=Varicode::JS8CallUltra;
+ }
+
+ // Only enable heartbeat for normal mode
+ ui->actionModeJS8HB->setEnabled(m_nSubMode == Varicode::JS8CallNormal);
+ if(m_nSubMode != Varicode::JS8CallNormal){
+ ui->actionModeJS8HB->setChecked(false);
+ }
+
+ auto modeText = currentMode();
+ if(ui->actionModeAutoreply->isChecked()){
+ modeText += QString("+AUTO");
+ }
+ if(ui->actionModeJS8HB->isChecked()){
+ if(ui->actionHeartbeatAcknowledgements->isChecked()){
+ modeText += QString("+HB+ACK");
+ } else {
+ modeText += QString("+HB");
+ }
+ }
+
+ ui->modeButton->setText(modeText);
+
+ m_wideGraph->setSubMode(m_nSubMode);
bool bVHF=m_config.enable_VHF_features();
m_bFast9=false;
m_bFastMode=false;
@@ -6946,7 +6964,7 @@ void MainWindow::on_actionFT8_triggered()
m_nsps=6912;
m_FFTSize = m_nsps / 2;
Q_EMIT FFTSize (m_FFTSize);
- m_hsymStop=JS8_SYMBOL_STOP;
+ fixStop();
setup_status_bar (bVHF);
m_toneSpacing=0.0; //???
ui->actionFT8->setChecked(true); //???
@@ -6954,7 +6972,19 @@ void MainWindow::on_actionFT8_triggered()
m_wideGraph->setModeTx(m_modeTx);
VHF_features_enabled(bVHF);
ui->cbAutoSeq->setChecked(true);
- m_TRperiod=JS8_TX_SECONDS;
+ m_TRperiod = 0;
+ if(m_nSubMode == Varicode::JS8CallNormal){
+ m_TRperiod = JS8A_TX_SECONDS;
+ }
+ else if(m_nSubMode == Varicode::JS8CallFast){
+ m_TRperiod = JS8B_TX_SECONDS;
+ }
+ else if(m_nSubMode == Varicode::JS8CallTurbo){
+ m_TRperiod = JS8C_TX_SECONDS;
+ }
+ else if(m_nSubMode == Varicode::JS8CallUltra){
+ m_TRperiod = JS8D_TX_SECONDS;
+ }
m_fastGraph->hide();
m_wideGraph->show();
ui->decodedTextLabel2->setText(" UTC dB DT Freq Message");
@@ -6987,6 +7017,8 @@ void MainWindow::on_actionFT8_triggered()
ui->txFirstCheckBox->setEnabled(true);
ui->cbAutoSeq->setEnabled(true);
+ updateTextDisplay();
+ refreshTextDisplay();
statusChanged();
}
@@ -7426,25 +7458,6 @@ void MainWindow::buildFrequencyMenu(QMenu *menu){
}
void MainWindow::buildHeartbeatMenu(QMenu *menu){
- auto selectedCallsign = callsignSelected();
- bool enabled = ui->actionModeAutoreply->isChecked() && selectedCallsign.isEmpty();
- auto text = "Send Heartbeat Acknowledgments (ACK)";
- if(!ui->actionModeAutoreply->isChecked()){
- text = "Send Heartbeat Acknowledgments (ACK) (Disabled: Autoreply is off)";
- }
- if(!selectedCallsign.isEmpty()){
- text = "Send Heartbeat Acknowledgments (ACK) (Disabled: Currently in QSO)";
- }
- auto autoAckHB = menu->addAction(text);
- autoAckHB->setEnabled(enabled);
- autoAckHB->setCheckable(true);
- autoAckHB->setChecked(m_hbAutoAck);
- connect(autoAckHB, &QAction::triggered, this, [this, autoAckHB](){
- m_hbAutoAck = autoAckHB->isChecked();
- updateRepeatButtonDisplay();
- });
- menu->addSeparator();
-
if(m_hbInterval > 0){
auto startStop = menu->addAction(ui->hbMacroButton->isChecked() ? "Stop Heartbeat Timer" : "Start Heartbeat Timer");
connect(startStop, &QAction::triggered, this, [this](){ ui->hbMacroButton->toggle(); });
@@ -7718,9 +7731,11 @@ void MainWindow::buildShowColumnsMenu(QMenu *menu, QString tableKey){
{"Last heard timestamp", "timestamp"},
{"SNR", "snr"},
{"Time Delta", "tdrift"},
+ {"Mode Speed", "mode"},
};
QMap defaultOverride = {
+ {"mode", false},
{"tdrift", false},
{"grid", false},
{"distance", false}
@@ -8015,7 +8030,6 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
addMessageText(QString("%1 MSG [MESSAGE]").arg(selectedCall), true, true);
});
-
auto msgToAction = menu->addAction(QString("%1 MSG TO:[CALLSIGN] [MESSAGE] - Please store this message at your station for later retreival by [CALLSIGN]").arg(call).trimmed());
msgToAction->setDisabled(isAllCall);
connect(msgToAction, &QAction::triggered, this, [this](){
@@ -8061,7 +8075,9 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
addMessageText(QString("%1 QUERY MSG [ID]").arg(selectedCall), true, true);
});
- auto agnAction = menu->addAction(QString("%1 AGN? - Please automatically repeat your last transmission").arg(call).trimmed());
+ menu->addSeparator();
+
+ auto agnAction = menu->addAction(QString("%1 AGN? - Please repeat your last transmission").arg(call).trimmed());
connect(agnAction, &QAction::triggered, this, [this](){
QString selectedCall = callsignSelected();
@@ -8074,8 +8090,6 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
if(m_config.transmit_directed()) toggleTx(true);
});
- menu->addSeparator();
-
auto qslQueryAction = menu->addAction(QString("%1 QSL? - Did you receive my last transmission?").arg(call).trimmed());
connect(qslQueryAction, &QAction::triggered, this, [this](){
@@ -8423,6 +8437,8 @@ void MainWindow::on_tableWidgetRXAll_cellDoubleClicked(int row, int col){
// switch to the offset of this row
setFreqOffsetForRestore(offset, false);
+ // TODO: prompt mode switch?
+
// print the history in the main window...
int activityAging = m_config.activity_aging();
QDateTime now = DriftingDateTime::currentDateTimeUtc();
@@ -8547,7 +8563,6 @@ void MainWindow::on_tableWidgetCalls_selectionChanged(const QItemSelection &sele
void MainWindow::on_freeTextMsg_currentTextChanged (QString const& text)
{
- msgtype(text, ui->freeTextMsg->lineEdit ());
}
void MainWindow::on_driftSpinBox_valueChanged(int n){
@@ -9041,25 +9056,32 @@ void MainWindow::rigFailure (QString const& reason)
void MainWindow::transmit (double snr)
{
double toneSpacing=0.0;
- if (m_modeTx == "JT65") {
- if(m_nSubMode==0) toneSpacing=11025.0/4096.0;
- if(m_nSubMode==1) toneSpacing=2*11025.0/4096.0;
- if(m_nSubMode==2) toneSpacing=4*11025.0/4096.0;
- Q_EMIT sendMessage (NUM_JT65_SYMBOLS,
- 4096.0*12000.0/11025.0, ui->TxFreqSpinBox->value () - m_XIT,
- toneSpacing, m_soundOutput, m_config.audio_output_channel (),
- true, false, snr, m_TRperiod);
- }
if (m_modeTx == "FT8") {
- toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8_SYMBOL_SAMPLES;
- //if(m_config.x2ToneSpacing()) toneSpacing=2.0*(double)RX_SAMPLE_RATE/(double)JS8_SYMBOL_SAMPLES;
- //if(m_config.x4ToneSpacing()) toneSpacing=4.0*(double)RX_SAMPLE_RATE/(double)JS8_SYMBOL_SAMPLES;
+ double symbolSamples = 0.0;
+ if(m_nSubMode == Varicode::JS8CallNormal){
+ symbolSamples=(double)JS8A_SYMBOL_SAMPLES;
+ toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8A_SYMBOL_SAMPLES;
+ }
+ else if(m_nSubMode == Varicode::JS8CallFast){
+ symbolSamples=(double)JS8B_SYMBOL_SAMPLES;
+ toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8B_SYMBOL_SAMPLES;
+ }
+ else if(m_nSubMode == Varicode::JS8CallTurbo){
+ symbolSamples=(double)JS8C_SYMBOL_SAMPLES;
+ toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8C_SYMBOL_SAMPLES;
+ }
+ else if(m_nSubMode == Varicode::JS8CallUltra){
+ symbolSamples=(double)JS8D_SYMBOL_SAMPLES;
+ toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8D_SYMBOL_SAMPLES;
+ }
+ if(m_config.x2ToneSpacing()) toneSpacing*=2.0;
+ if(m_config.x4ToneSpacing()) toneSpacing*=4.0;
if(m_config.bFox() and !m_tune) toneSpacing=-1;
if(TEST_FOX_WAVE_GEN && ui->turboButton->isChecked() && !m_tune) toneSpacing=-1;
Q_EMIT sendMessage (JS8_NUM_SYMBOLS,
- (double)JS8_SYMBOL_SAMPLES, ui->TxFreqSpinBox->value () - m_XIT,
+ symbolSamples, ui->TxFreqSpinBox->value () - m_XIT,
toneSpacing, m_soundOutput, m_config.audio_output_channel (),
true, false, snr, m_TRperiod);
}
@@ -9424,7 +9446,7 @@ void MainWindow::updateButtonDisplay(){
void MainWindow::updateRepeatButtonDisplay(){
auto selectedCallsign = callsignSelected();
- auto hbBase = m_hbAutoAck && ui->actionModeAutoreply->isChecked() && selectedCallsign.isEmpty() ? "HB + ACK" : "HB";
+ auto hbBase = ui->actionModeAutoreply->isChecked() && ui->actionHeartbeatAcknowledgements->isChecked() && selectedCallsign.isEmpty() ? "HB + ACK" : "HB";
if(ui->hbMacroButton->isChecked() && m_hbInterval > 0 && m_nextHeartbeat.isValid()){
auto secs = DriftingDateTime::currentDateTimeUtc().secsTo(m_nextHeartbeat);
if(secs > 0){
@@ -9514,7 +9536,8 @@ void MainWindow::refreshTextDisplay(){
mygrid,
selectedCall,
text,
- forceIdentify
+ forceIdentify,
+ m_nSubMode
);
connect(t, &BuildMessageFramesThread::finished, t, &QObject::deleteLater);
@@ -9547,7 +9570,7 @@ void MainWindow::updateTextWordCheckerDisplay(){
}
void MainWindow::updateTextStatsDisplay(QString text, int count){
- const double fpm = 60.0/JS8_TX_SECONDS;
+ const double fpm = 60.0/m_TRperiod;
if(count > 0){
auto words = text.split(" ", QString::SkipEmptyParts).length();
auto wpm = QString::number(words/(count/fpm), 'f', 1);
@@ -9801,8 +9824,8 @@ void MainWindow::processActivity(bool force) {
}
void MainWindow::observeTimeDeltaForAverage(float delta){
- // delta can only be +/- 15 seconds
- delta = qMax(-15.0F, qMin(delta, 15.0F));
+ // delta can only be +/- the TR period
+ delta = qMax(-(float)m_TRperiod, qMin(delta, (float)m_TRperiod));
// compute average drift
if(m_timeDeltaMsMMA_N == 0){
@@ -9814,7 +9837,7 @@ void MainWindow::observeTimeDeltaForAverage(float delta){
}
// display average
- if(m_timeDeltaMsMMA < -15.0F || m_timeDeltaMsMMA > 15.0F){
+ if(m_timeDeltaMsMMA < -(float)m_TRperiod || m_timeDeltaMsMMA > (float)m_TRperiod){
resetTimeDeltaAverage();
}
ui->driftAvgLabel->setText(QString("Avg Time Delta: %1 ms").arg((int)m_timeDeltaMsMMA));
@@ -9929,6 +9952,7 @@ void MainWindow::processRxActivity() {
cd.bits = d.bits;
cd.tdrift = d.tdrift;
cd.utcTimestamp = d.utcTimestamp;
+ cd.mode = currentMode();
logCallActivity(cd, true);
}
}
@@ -10025,7 +10049,7 @@ void MainWindow::processCompoundActivity() {
bits == Varicode::JS8Call ||
((bits & Varicode::JS8CallFirst) == Varicode::JS8CallFirst) ||
((bits & Varicode::JS8CallLast) == Varicode::JS8CallLast) ||
- ((bits & Varicode::JS8CallFlag) == Varicode::JS8CallFlag)
+ ((bits & Varicode::JS8CallData) == Varicode::JS8CallData)
);
if (!validBits) {
qDebug() << "-> buffer.cmd bits is invalid...skip";
@@ -10265,6 +10289,7 @@ void MainWindow::processCommandActivity() {
cd.ackTimestamp = d.text.contains(": ACK") || toMe ? d.utcTimestamp : QDateTime{};
cd.utcTimestamp = d.utcTimestamp;
cd.tdrift = d.tdrift;
+ cd.mode = currentMode();
logCallActivity(cd, true);
logHeardGraph(d.from, d.to);
@@ -10282,6 +10307,7 @@ void MainWindow::processCommandActivity() {
cd.snr = d.snr;
cd.utcTimestamp = d.utcTimestamp;
cd.tdrift = d.tdrift;
+ cd.mode = currentMode();
m_aprsCallCache.remove(cd.call);
m_aprsCallCache.remove(APRSISClient::replaceCallsignSuffixWithSSID(cd.call, Radio::base_callsign(cd.call)));
@@ -10555,6 +10581,7 @@ void MainWindow::processCommandActivity() {
cd.through = d.from;
cd.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
cd.tdrift = d.tdrift;
+ cd.mode = currentMode();
logCallActivity(cd, false);
}
@@ -10668,11 +10695,12 @@ void MainWindow::processCommandActivity() {
}
// PROCESS ACTIVE HEARTBEAT
- // if we have auto reply enabled and auto ack enabled and no callsign is selected
- else if (d.cmd == " HB" && ui->actionModeAutoreply->isChecked() && m_hbAutoAck && selectedCallsign.isEmpty()){
+ // if we have hb mode enabled and auto reply enabled and auto ack enabled and no callsign is selected update: if we're in HB mode, doesn't matter if a callsign is selected.
+ else if (d.cmd == " HB" && ui->actionModeJS8HB->isChecked() && ui->actionModeAutoreply->isChecked() && ui->actionHeartbeatAcknowledgements->isChecked() && selectedCallsign.isEmpty()){
// check to make sure this callsign isn't blacklisted
if(m_config.hb_blacklist().contains(d.from) || m_config.hb_blacklist().contains(Radio::base_callsign(d.from))){
+ qDebug() << "hb blacklist blocking" << d.from;
continue;
}
@@ -10910,11 +10938,13 @@ void MainWindow::processCommandActivity() {
continue;
}
+#if 0
// TODO: jsherer - HB issue here
// do not queue a reply if it's a HB and HB is not active
- if((!ui->hbMacroButton->isChecked() || m_hbInterval <= 0) && d.cmd.contains("HB")){
- continue;
- }
+ // if((!ui->hbMacroButton->isChecked() || m_hbInterval <= 0) && d.cmd.contains("HB")){
+ // continue;
+ // }
+#endif
// do not queue for reply if there's text in the window
if(!ui->extFreeTextMsgEdit->toPlainText().isEmpty()){
@@ -10982,6 +11012,7 @@ void MainWindow::refreshInboxCounts(){
cd.utcTimestamp = QDateTime::fromString(utc, "yyyy-MM-dd hh:mm:ss");
cd.utcTimestamp.setUtcOffset(0);
cd.ackTimestamp = cd.utcTimestamp;
+ cd.mode = currentMode();
logCallActivity(cd, false);
}
}
@@ -11363,6 +11394,8 @@ void MainWindow::displayBandActivity() {
QString age;
int snr = 0;
float tdrift = 0;
+ QString mode;
+
int activityAging = m_config.activity_aging();
// hide items that shouldn't appear
@@ -11377,9 +11410,10 @@ void MainWindow::displayBandActivity() {
}
// hide heartbeat items
- if (m_hbHidden){
+ if (!ui->actionShow_Band_Heartbeats_and_ACKs->isChecked()){
// hide heartbeats and acks if we have heartbeating hidden
if(item.text.contains(" HB ") || item.text.contains(" ACK ")){
+ // TODO: if text contains MSG ID and previous frame was hidden, hide this one too
shouldDisplay = false;
}
}
@@ -11412,6 +11446,7 @@ void MainWindow::displayBandActivity() {
age = since(item.utcTimestamp);
timestamp = item.utcTimestamp;
tdrift = item.tdrift;
+ mode = item.mode;
}
auto joined = Varicode::rstrip(text.join(""));
@@ -11441,6 +11476,12 @@ void MainWindow::displayBandActivity() {
tdriftItem->setData(Qt::UserRole, QVariant(tdrift));
ui->tableWidgetRXAll->setItem(row, col++, tdriftItem);
+ auto modeItem = new QTableWidgetItem(mode.left(1).replace("H", "N"));
+ modeItem->setToolTip(mode);
+ modeItem->setData(Qt::UserRole, QVariant(mode));
+ modeItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ ui->tableWidgetRXAll->setItem(row, col++, modeItem);
+
// align right if eliding...
int colWidth = ui->tableWidgetRXAll->columnWidth(3);
auto textItem = new QTableWidgetItem(joined);
@@ -11531,12 +11572,14 @@ void MainWindow::displayBandActivity() {
ui->tableWidgetRXAll->setColumnHidden(1, !showColumn("band", "timestamp"));
ui->tableWidgetRXAll->setColumnHidden(2, !showColumn("band", "snr"));
ui->tableWidgetRXAll->setColumnHidden(3, !showColumn("band", "tdrift", false));
+ ui->tableWidgetRXAll->setColumnHidden(4, !showColumn("band", "mode", false));
// Resize the table columns
ui->tableWidgetRXAll->resizeColumnToContents(0);
ui->tableWidgetRXAll->resizeColumnToContents(1);
ui->tableWidgetRXAll->resizeColumnToContents(2);
ui->tableWidgetRXAll->resizeColumnToContents(3);
+ ui->tableWidgetRXAll->resizeColumnToContents(4);
// Reset the scroll position
ui->tableWidgetRXAll->verticalScrollBar()->setValue(currentScrollPos);
@@ -11725,6 +11768,12 @@ void MainWindow::displayCallActivity() {
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem(QString("%1 ms").arg((int)(1000*d.tdrift))));
+ auto modeItem = new QTableWidgetItem(d.mode.left(1).replace("H", "N"));
+ modeItem->setToolTip(d.mode);
+ modeItem->setData(Qt::UserRole, QVariant(d.mode));
+ modeItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ ui->tableWidgetCalls->setItem(row, col++, modeItem);
+
auto gridItem = new QTableWidgetItem(QString("%1").arg(d.grid.trimmed().left(4)));
gridItem->setToolTip(d.grid.trimmed());
ui->tableWidgetCalls->setItem(row, col++, gridItem);
@@ -11782,6 +11831,7 @@ void MainWindow::displayCallActivity() {
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem("")); // snr
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem("")); // freq
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem("")); // tdrift
+ ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem("")); // mode
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem("")); // grid
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem("")); // distance
ui->tableWidgetCalls->setItem(row, col++, new QTableWidgetItem("")); // worked before
@@ -11851,11 +11901,12 @@ void MainWindow::displayCallActivity() {
ui->tableWidgetCalls->setColumnHidden(3, !showColumn("call", "snr"));
ui->tableWidgetCalls->setColumnHidden(4, !showColumn("call", "offset"));
ui->tableWidgetCalls->setColumnHidden(5, !showColumn("call", "tdrift", false));
- ui->tableWidgetCalls->setColumnHidden(6, !showColumn("call", "grid", false));
- ui->tableWidgetCalls->setColumnHidden(7, !showColumn("call", "distance", false));
- ui->tableWidgetCalls->setColumnHidden(8, !showColumn("call", "log"));
- ui->tableWidgetCalls->setColumnHidden(9, !showColumn("call", "logName"));
- ui->tableWidgetCalls->setColumnHidden(10, !showColumn("call", "logComment"));
+ ui->tableWidgetCalls->setColumnHidden(6, !showColumn("call", "mode", false));
+ ui->tableWidgetCalls->setColumnHidden(7, !showColumn("call", "grid", false));
+ ui->tableWidgetCalls->setColumnHidden(8, !showColumn("call", "distance", false));
+ ui->tableWidgetCalls->setColumnHidden(9, !showColumn("call", "log"));
+ ui->tableWidgetCalls->setColumnHidden(10, !showColumn("call", "logName"));
+ ui->tableWidgetCalls->setColumnHidden(11, !showColumn("call", "logComment"));
// Resize the table columns
ui->tableWidgetCalls->resizeColumnToContents(0);
@@ -11868,6 +11919,7 @@ void MainWindow::displayCallActivity() {
ui->tableWidgetCalls->resizeColumnToContents(7);
ui->tableWidgetCalls->resizeColumnToContents(8);
ui->tableWidgetCalls->resizeColumnToContents(9);
+ ui->tableWidgetCalls->resizeColumnToContents(10);
// Reset the scroll position
ui->tableWidgetCalls->verticalScrollBar()->setValue(currentScrollPos);
@@ -11910,6 +11962,7 @@ void MainWindow::emitTones(){
// emit tone numbers to network
QVariantList t;
for(int i = 0; i < JS8_NUM_SYMBOLS; i++){
+ //qDebug() << "tone" << i << "=" << itone[i];
t.append(QVariant((int)itone[i]));
}
@@ -12768,7 +12821,7 @@ void MainWindow::write_transmit_entry (QString const& file_name)
QTextStream out(&f);
auto time = DriftingDateTime::currentDateTimeUtc ();
time = time.addSecs (-(time.time ().second () % m_TRperiod));
- auto dt = DecodedText(m_currentMessage, m_currentMessageBits);
+ auto dt = DecodedText(m_currentMessage, m_currentMessageBits, m_nSubMode);
out << time.toString("yyyy-MM-dd hh:mm:ss")
<< " Transmitting " << qSetRealNumberPrecision (12) << (m_freqNominal / 1.e6)
<< " MHz " << "JS8"
diff --git a/mainwindow.h b/mainwindow.h
index 1ae4045..f2f040b 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -177,6 +177,7 @@ private slots:
void on_tx4_editingFinished();
void on_tx5_currentTextChanged (QString const&);
void on_tx6_editingFinished();
+ void on_menuModeJS8_aboutToShow();
void on_menuControl_aboutToShow();
void on_actionCheck_for_Updates_triggered();
void on_actionEnable_Spotting_toggled(bool checked);
@@ -259,10 +260,15 @@ private slots:
void on_dxCallEntry_returnPressed ();
void on_genStdMsgsPushButton_clicked();
void on_logQSOButton_clicked();
- void on_actionModeJS8_triggered();
+ void on_actionModeJS8HB_toggled(bool checked);
+ void on_actionModeJS8Normal_triggered();
+ void on_actionModeJS8Fast_triggered();
+ void on_actionModeJS8Turbo_triggered();
+ void on_actionModeJS8Ultra_triggered();
+ void on_actionHeartbeatAcknowledgements_toggled(bool checked);
void on_actionModeAutoreply_toggled(bool checked);
- void prepareAutoreplyMode(bool enabled);
- void on_actionFT8_triggered();
+ void prepareHeartbeatMode(bool enabled);
+ void on_actionJS8_triggered();
void on_TxFreqSpinBox_valueChanged(int arg1);
void on_actionSave_decoded_triggered();
void on_actionQuickDecode_toggled (bool);
@@ -409,7 +415,6 @@ private slots:
void on_pbTxNext_clicked(bool b);
void on_actionEcho_Graph_triggered();
void on_actionFast_Graph_triggered();
- void fast_decode_done();
void on_actionMeasure_reference_spectrum_triggered();
void on_actionErase_reference_spectrum_triggered();
void on_actionMeasure_phase_response_triggered();
@@ -729,6 +734,7 @@ private:
int snr;
int bits;
float tdrift;
+ QString mode;
};
struct CommandDetail
@@ -746,6 +752,7 @@ private:
QString text;
QString extra;
float tdrift;
+ QString mode;
QString relayPath;
};
@@ -763,6 +770,7 @@ private:
int snr;
bool shouldDisplay;
float tdrift;
+ QString mode;
};
struct MessageBuffer {
@@ -872,8 +880,6 @@ private:
QQueue m_foxQSOinProgress; //QSOs in progress: Fox has sent a report
QQueue m_foxRateQueue;
- bool m_hbAutoAck;
- bool m_hbHidden;
int m_hbInterval;
int m_cqInterval;
bool m_hbPaused;
@@ -942,6 +948,7 @@ private:
void pskLogReport(QString mode, int offset, int snr, QString callsign, QString grid);
void aprsLogReport(int offset, int snr, QString callsign, QString grid);
Radio::Frequency dialFrequency();
+ QString currentMode();
void updateCurrentBand();
void displayDialFrequency ();
void transmitDisplay (bool);
diff --git a/mainwindow.ui b/mainwindow.ui
index e0d60fb..fa25197 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -694,7 +694,7 @@ QPushButton:checked {
- -
+
-
true
@@ -749,7 +749,7 @@ QPushButton:checked {
- -
+
-
true
@@ -804,8 +804,8 @@ QPushButton:checked {
- -
-
+
-
+
true
@@ -829,19 +829,20 @@ QPushButton:checked {
- 9
+ 75
+ true
- <html><head/><body><p><br/></p></body></html>
+ <html><head/><body><p>Set the JS8 mode settings</p></body></html>
QPushButton {
-background-color:lightgray;
-padding:0.25em 0.25em; font-weight:normal;
+padding:0.25em 0.25em; font-weight:bold;
border-style:solid;
border-width:0px;
border-radius:2px;
+background-color:#6699ff;
}
QPushButton:checked {
@@ -849,7 +850,7 @@ background-color:#6699ff;
}
- ...
+ JS8
true
@@ -888,7 +889,7 @@ background-color:#6699ff;
- <html><head/><body><p>Transmit a tuning tone</p></body></html>
+ <html><head/><body><p>Spot to reporting networks</p></body></html>
QPushButton {
@@ -1079,6 +1080,11 @@ background-color:#6699ff;
Time Delta
+
+
+ Speed
+
+
Message(s)
@@ -1268,6 +1274,11 @@ QTextEdit[transmitting="true"] {
Time Delta
+
+
+ Speed
+
+
Grid
@@ -1331,24 +1342,8 @@ QTextEdit[transmitting="true"] {
0
-
-
-
-
-
- 75
- 30
-
-
-
- <html><head/><body><p>Stop transmitting</p></body></html>
-
-
- Halt
-
-
-
- -
-
+
-
+
0
@@ -1356,7 +1351,7 @@ QTextEdit[transmitting="true"] {
- <html><head/><body><p>Send a CQ message</p></body></html>
+ <html><head/><body><p align="justify">Send a Heartbeat message</p></body></html>
true
@@ -1368,32 +1363,13 @@ QTextEdit[transmitting="true"] {
}
- CQ
+ HB
true
-
- false
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Preferred
-
-
-
- 20
- 10
-
-
-
-
-
@@ -1429,8 +1405,8 @@ color:#222;
- -
-
+
-
+
0
@@ -1438,10 +1414,25 @@ color:#222;
- <html><head/><body><p>Send a directed message to another station</p></body></html>
+ <html><head/><body><p>Send a CQ message</p></body></html>
+
+
+ true
+
+
+ QPushButton:checked {
+ font-weight:bold;
+ color:black;
+}
- Directed
+ CQ
+
+
+ true
+
+
+ false
@@ -1461,68 +1452,40 @@ color:#222;
- -
-
-
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Preferred
+
+
- 0
- 30
+ 20
+ 10
-
- <html><head/><body><p>Send a saved message</p></body></html>
-
-
- Saved
-
-
-
- -
-
-
-
- 0
- 30
-
-
-
- <html><head/><body><p>Reply to a CQ</p></body></html>
-
-
- REPLY
-
-
-
- -
-
-
-
- 0
- 30
-
-
-
- <html><head/><body><p align="justify">Send a Heartbeat message</p></body></html>
-
-
- true
-
-
- QPushButton:checked {
- font-weight:bold;
- color:black;
-}
-
-
- HB
-
-
- true
-
-
+
-
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Preferred
+
+
+
+ 20
+ 10
+
+
+
+
+ -
+
Qt::Horizontal
@@ -1553,6 +1516,70 @@ color:#222;
+ -
+
+
+
+ 0
+ 30
+
+
+
+ <html><head/><body><p>Reply to a CQ</p></body></html>
+
+
+ REPLY
+
+
+
+ -
+
+
+
+ 75
+ 30
+
+
+
+ <html><head/><body><p>Stop transmitting</p></body></html>
+
+
+ Halt
+
+
+
+ -
+
+
+
+ 0
+ 30
+
+
+
+ <html><head/><body><p>Send a saved message</p></body></html>
+
+
+ Saved
+
+
+
+ -
+
+
+
+ 0
+ 30
+
+
+
+ <html><head/><body><p>Send a directed message to another station</p></body></html>
+
+
+ Directed
+
+
+
-
@@ -1575,22 +1602,6 @@ color:#222;
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Preferred
-
-
-
- 20
- 10
-
-
-
-
@@ -4798,9 +4809,14 @@ list. The list can be maintained in Settings (F2).
Mode
-
+
+
+
+
+
+
@@ -5725,23 +5741,15 @@ list. The list can be maintained in Settings (F2).
Ctrl+Alt+A
-
+
true
true
-
- false
-
- JS8
-
-
-
-
- AUTO
+ JS8 (Normal, 15s, 50Hz, ~16 WPM)
@@ -5749,23 +5757,47 @@ list. The list can be maintained in Settings (F2).
true
- Enable Networking && Autoreply
+ Enable Autoreply (AUTO)
-
+
true
- Messaging
+ JS8 (Fast, 10s, 80Hz, ~24 WPM)
-
+
true
- Heartbeat
+ JS8 (Turbo, 6s, 160Hz, ~40 WPM)
+
+
+
+
+ true
+
+
+ JS8 (Ultra, 4s, 250Hz, ~60WPM)
+
+
+
+
+ true
+
+
+ Enable Heartbeat Networking (HB)
+
+
+
+
+ true
+
+
+ Enable Heartbeat Acknowledgments (ACK)
diff --git a/plotter.cpp b/plotter.cpp
index 8309a04..de45141 100644
--- a/plotter.cpp
+++ b/plotter.cpp
@@ -7,6 +7,7 @@
#include
#include "DriftingDateTime.h"
+#include "varicode.h"
#define MAX_SCREENSIZE 2048
@@ -411,7 +412,19 @@ void CPlotter::DrawOverlay() //DrawOverlay()
}
}
- float bw=7.0*(double)RX_SAMPLE_RATE/(double)JS8_SYMBOL_SAMPLES; //JS8
+ float bw = 0;
+ if(m_nSubMode == Varicode::JS8CallNormal){
+ bw = 8.0*(double)RX_SAMPLE_RATE/(double)JS8A_SYMBOL_SAMPLES;
+ }
+ else if(m_nSubMode == Varicode::JS8CallFast){
+ bw = 8.0*(double)RX_SAMPLE_RATE/(double)JS8B_SYMBOL_SAMPLES;
+ }
+ else if(m_nSubMode == Varicode::JS8CallTurbo){
+ bw = 8.0*(double)RX_SAMPLE_RATE/(double)JS8C_SYMBOL_SAMPLES;
+ }
+ else if(m_nSubMode == Varicode::JS8CallUltra){
+ bw = 8.0*(double)RX_SAMPLE_RATE/(double)JS8D_SYMBOL_SAMPLES;
+ }
painter0.setPen(penGreen);
diff --git a/varicode.cpp b/varicode.cpp
index 76202e1..2e76048 100644
--- a/varicode.cpp
+++ b/varicode.cpp
@@ -499,7 +499,7 @@ QList>> Varicode::huffEncode(const QMap const &huff, QVector const& bitvec){
QString text;
- QString bits = Varicode::bitsToStr(bitvec); //.mid(0, bitvec.length()-pad);
+ QString bits = Varicode::bitsToStr(bitvec);
// TODO: jsherer - this is naive...
while(bits.length() > 0){
@@ -1570,7 +1570,7 @@ QStringList Varicode::unpackDirectedMessage(const QString &text, quint8 *pType){
return unpacked;
}
-QString packHuffMessage(const QString &input, int *n){
+QString packHuffMessage(const QString &input, const QVector prefix, int *n){
static const int frameSize = 72;
QString frame;
@@ -1580,7 +1580,10 @@ QString packHuffMessage(const QString &input, int *n){
// but, since none of the other frame types start with a 0, we can drop the two zeros and use
// them for encoding the first two bits of the actuall data sent. boom!
// The second bit is a flag that indicates this is not compressed frame (huffman coding)
- QVector frameBits = {true, false};
+ QVector frameBits;
+ if(!prefix.isEmpty()){
+ frameBits << prefix;
+ }
int i = 0;
@@ -1628,7 +1631,7 @@ QString packHuffMessage(const QString &input, int *n){
return frame;
}
-QString packCompressedMessage(const QString &input, int *n){
+QString packCompressedMessage(const QString &input, QVector prefix, int *n){
static const int frameSize = 72;
QString frame;
@@ -1638,7 +1641,11 @@ QString packCompressedMessage(const QString &input, int *n){
// but, since none of the other frame types start with a 1, we can drop the two zeros and use
// them for encoding the first two bits of the actuall data sent. boom!
// The second bit is a flag that indicates this is a compressed frame (dense coding)
- QVector frameBits = {true, true};
+ // For fast modes, we don't use the prefix since it is indicated by the JS8CallData flag.
+ QVector frameBits;
+ if(!prefix.isEmpty()){
+ frameBits << prefix;
+ }
int i = 0;
foreach(auto pair, JSC::compress(input)){
@@ -1675,14 +1682,15 @@ QString packCompressedMessage(const QString &input, int *n){
return frame;
}
+// pack data message using 70 bits available flagged as data by the first 2 bits
QString Varicode::packDataMessage(const QString &input, int *n){
QString huffFrame;
int huffChars = 0;
- huffFrame = packHuffMessage(input, &huffChars);
+ huffFrame = packHuffMessage(input, {true, false}, &huffChars);
QString compressedFrame;
int compressedChars = 0;
- compressedFrame = packCompressedMessage(input, &compressedChars);
+ compressedFrame = packCompressedMessage(input, {true, true}, &compressedChars);
if(huffChars > compressedChars){
if(n) *n = huffChars;
@@ -1693,7 +1701,7 @@ QString Varicode::packDataMessage(const QString &input, int *n){
}
}
-
+// unpack data message using 70 bits available flagged as data by the first 2 bits
QString Varicode::unpackDataMessage(const QString &text){
QString unpacked;
@@ -1713,8 +1721,9 @@ QString Varicode::unpackDataMessage(const QString &text){
bits = bits.mid(1);
bool compressed = bits.at(0);
-
int n = bits.lastIndexOf(0);
+
+ // trim off the pad bits
bits = bits.mid(1, n-1);
if(compressed){
@@ -1728,14 +1737,82 @@ QString Varicode::unpackDataMessage(const QString &text){
return unpacked;
}
+#define JS8_FAST_DATA_CAN_USE_HUFF 0
+
+// pack data message using the full 72 bits available (with the data flag in the i3bit header)
+QString Varicode::packFastDataMessage(const QString &input, int *n){
+#if JS8_FAST_DATA_CAN_USE_HUFF
+ QString huffFrame;
+ int huffChars = 0;
+ huffFrame = packHuffMessage(input, {false}, &huffChars);
+
+ QString compressedFrame;
+ int compressedChars = 0;
+ compressedFrame = packCompressedMessage(input, {true}, &compressedChars);
+
+ if(huffChars > compressedChars){
+ if(n) *n = huffChars;
+ return huffFrame;
+ } else {
+ if(n) *n = compressedChars;
+ return compressedFrame;
+ }
+#else
+ QString compressedFrame;
+ int compressedChars = 0;
+ compressedFrame = packCompressedMessage(input, {}, &compressedChars);
+
+ if(n) *n = compressedChars;
+ return compressedFrame;
+#endif
+}
+
+// unpack data message using the full 72 bits available (with the data flag in the i3bit header)
+QString Varicode::unpackFastDataMessage(const QString &text){
+ QString unpacked;
+
+ if(text.length() < 12 || text.contains(" ")){
+ return unpacked;
+ }
+
+ quint8 rem = 0;
+ quint64 value = Varicode::unpack72bits(text, &rem);
+ auto bits = Varicode::intToBits(value, 64) + Varicode::intToBits(rem, 8);
+
+#if JS8_FAST_DATA_CAN_USE_HUFF
+ bool compressed = bits.at(0);
+ int n = bits.lastIndexOf(0);
+
+ // trim off the pad bits
+ bits = bits.mid(1, n-1);
+
+ if(compressed){
+ // partial word (s,c)-dense coding with code tables
+ unpacked = JSC::decompress(bits);
+ } else {
+ // huff decode the bits (without escapes)
+ unpacked = Varicode::huffDecode(Varicode::defaultHuffTable(), bits);
+ }
+#else
+ int n = bits.lastIndexOf(0);
+
+ // trim off the pad bits
+ bits = bits.mid(0, n);
+
+ // partial word (s,c)-dense coding with code tables
+ unpacked = JSC::decompress(bits);
+#endif
+
+ return unpacked;
+}
+
// TODO: remove the dependence on providing all this data?
-QList> Varicode::buildMessageFrames(
- QString const& mycall,
+QList> Varicode::buildMessageFrames(QString const& mycall,
QString const& mygrid,
QString const& selectedCall,
QString const& text,
- bool forceIdentify
-){
+ bool forceIdentify,
+ int submode){
#define ALLOW_SEND_COMPOUND 1
#define ALLOW_SEND_COMPOUND_DIRECTED 1
#define AUTO_PREPEND_DIRECTED 1
@@ -1836,7 +1913,15 @@ QList> Varicode::buildMessageFrames(
}
#endif
int m = 0;
- QString datFrame = Varicode::packDataMessage(line, &m);
+ bool fastDataFrame = false;
+ QString datFrame;
+ if(submode == Varicode::JS8CallNormal){
+ datFrame = Varicode::packDataMessage(line, &m);
+ fastDataFrame = false;
+ } else {
+ datFrame = Varicode::packFastDataMessage(line, &m);
+ fastDataFrame = true;
+ }
// if this parses to a standard FT8 free text message
// but it can be parsed as a directed message, then we
@@ -1951,7 +2036,8 @@ QList> Varicode::buildMessageFrames(
}
if(useDat){
- lineFrames.append({ frame, Varicode::JS8Call });
+ // use the standard data frame
+ lineFrames.append({ frame, fastDataFrame ? Varicode::JS8CallData : Varicode::JS8Call });
line = line.mid(m);
}
}
@@ -1972,13 +2058,15 @@ BuildMessageFramesThread::BuildMessageFramesThread(const QString &mycall,
const QString &selectedCall,
const QString &text,
bool forceIdentify,
+ int submode,
QObject *parent):
QThread(parent),
m_mycall{mycall},
m_mygrid{mygrid},
m_selectedCall{selectedCall},
m_text{text},
- m_forceIdentify{forceIdentify}
+ m_forceIdentify{forceIdentify},
+ m_submode{submode}
{
}
@@ -1988,15 +2076,16 @@ void BuildMessageFramesThread::run(){
m_mygrid,
m_selectedCall,
m_text,
- m_forceIdentify
+ m_forceIdentify,
+ m_submode
);
// TODO: jsherer - we wouldn't normally use decodedtext.h here... but it's useful for computing the actual frames transmitted.
QStringList textList;
qDebug() << "frames:";
foreach(auto frame, results){
- auto dt = DecodedText(frame.first, frame.second);
- qDebug() << "->" << frame << dt.message() << Varicode::frameTypeString(dt.frameType());
+ auto dt = DecodedText(frame.first, frame.second, m_submode);
+ qDebug() << "->" << frame << dt.message() << Varicode::frameTypeString(dt.frameType()) << m_submode;
textList.append(dt.message());
}
diff --git a/varicode.h b/varicode.h
index 685db4a..238db99 100644
--- a/varicode.h
+++ b/varicode.h
@@ -16,12 +16,20 @@
class Varicode
{
public:
+ // submode types
+ enum SubmodeType {
+ JS8CallNormal = 0,
+ JS8CallFast = 1,
+ JS8CallTurbo = 2,
+ JS8CallUltra = 3
+ };
+
// frame type transmitted via itype and decoded by the ft8 decoded
enum TransmissionType {
JS8Call = 0, // [000] <- any other frame of the message
JS8CallFirst = 1, // [001] <- the first frame of a message
JS8CallLast = 2, // [010] <- the last frame of a message
- JS8CallFlag = 4, // [100] <- flagged frame (no frame type header)
+ JS8CallData = 4, // [100] <- flagged frame (no frame type header)
};
/*
@@ -156,11 +164,15 @@ public:
static QString packDataMessage(QString const& text, int *n);
static QString unpackDataMessage(QString const& text);
+ static QString packFastDataMessage(QString const& text, int *n);
+ static QString unpackFastDataMessage(QString const& text);
+
static QList> buildMessageFrames(QString const& mycall,
QString const& mygrid,
QString const& selectedCall,
QString const& text,
- bool forceIdentify);
+ bool forceIdentify,
+ int submode);
};
@@ -173,6 +185,7 @@ public:
QString const& selectedCall,
QString const& text,
bool forceIdentify,
+ int submode,
QObject *parent=nullptr);
void run() override;
signals:
@@ -184,6 +197,7 @@ private:
QString m_selectedCall;
QString m_text;
bool m_forceIdentify;
+ int m_submode;
};
#endif // VARICODE_H