Merge branch 'release-wsjtx-2.0.0-rc1'

This commit is contained in:
Joe Taylor 2018-09-17 09:17:50 -04:00
commit 81d6f6a109
146 changed files with 131712 additions and 1957 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
.gitattributes export-ignore
/samples export-ignore
/lib/fsk4hf export-ignore

6
.gitignore vendored
View File

@ -1,3 +1,9 @@
~*
TAGS
tags
*~
junk*
jnq*
*.exe
*.o
*.mod

View File

@ -162,6 +162,7 @@ option (WSJT_SOFT_KEYING "Apply a ramp to CW keying envelope to reduce transient
option (WSJT_SKIP_MANPAGES "Skip *nix manpage generation.")
option (WSJT_GENERATE_DOCS "Generate documentation files." ON)
option (WSJT_RIG_NONE_CAN_SPLIT "Allow split operation with \"None\" as rig.")
option (WSJT_BUILD_UTILS "Build simulators and code demonstrators." ON)
CMAKE_DEPENDENT_OPTION (WSJT_HAMLIB_VERBOSE_TRACE "Debugging option that turns on full Hamlib internal diagnostics." OFF WSJT_HAMLIB_TRACE OFF)
CMAKE_DEPENDENT_OPTION (WSJT_QDEBUG_IN_RELEASE "Leave Qt debugging statements in Release configuration." OFF
@ -176,7 +177,6 @@ If you just want to see the debug output from the application then the easiest w
attach a debugger which will then receive the console output inside its console." ON
"WIN32" OFF)
set (PROJECT_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}")
if (NOT PROJECT_ARCHITECTURE)
# This is supposed to happen already on Windows
@ -186,7 +186,6 @@ message (STATUS "******************************************************")
message (STATUS "Building for for: ${CMAKE_SYSTEM_NAME}-${PROJECT_ARCHITECTURE}")
message (STATUS "******************************************************")
#
# install locations
#
@ -302,6 +301,7 @@ set (wsjtx_CXXSRCS
about.cpp
astro.cpp
messageaveraging.cpp
colorhighlighting.cpp
WsprTxScheduler.cpp
mainwindow.cpp
Configuration.cpp
@ -313,11 +313,15 @@ set (wsjtx_CXXSRCS
set (wsjt_CXXSRCS
lib/crc10.cpp
lib/crc12.cpp
lib/crc13.cpp
lib/crc14.cpp
)
# deal with a GCC v6 UB error message
set_source_files_properties (
lib/crc10.cpp
lib/crc12.cpp
lib/crc13.cpp
lib/crc14.cpp
PROPERTIES COMPILE_FLAGS -fpermissive)
if (WIN32)
@ -346,6 +350,7 @@ set (wsjt_FSRCS
lib/jt9_decode.f90
lib/options.f90
lib/packjt.f90
lib/77bit/packjt77.f90
lib/readwav.f90
lib/timer_C_wrapper.f90
lib/timer_impl.f90
@ -369,25 +374,22 @@ set (wsjt_FSRCS
lib/ft8/baseline.f90
lib/bpdecode40.f90
lib/bpdecode144.f90
lib/fsk4hf/bpdecode120.f90
lib/fsk4hf/bpdecode168.f90
lib/bpdecode128_90.f90
lib/ft8/bpdecode174.f90
lib/fsk4hf/bpdecode300.f90
lib/ft8/bpdecode174_91.f90
lib/baddata.f90
lib/calibrate.f90
lib/ccf2.f90
lib/ccf65.f90
lib/fsk4hf/chkcrc10.f90
lib/fsk4hf/chkcrc12.f90
lib/ft8/chkcrc12a.f90
lib/ft8/chkcrc13a.f90
lib/ft8/chkcrc14a.f90
lib/chkcall.f90
lib/chkhist.f90
lib/chkmsg.f90
lib/chkss2.f90
lib/ft8/compress.f90
lib/coord.f90
lib/fsk4hf/cpolyfit.f90
lib/fsk4hf/cpolyfitw.f90
lib/db.f90
lib/decode4.f90
lib/decode65a.f90
@ -404,17 +406,17 @@ set (wsjt_FSRCS
lib/encode4.f90
lib/encode_msk40.f90
lib/encode_msk144.f90
lib/fsk4hf/encode120.f90
lib/fsk4hf/encode168.f90
lib/encode_128_90.f90
lib/ft8/encode174.f90
lib/fsk4hf/encode300.f90
lib/ft8/encode174_91.f90
lib/entail.f90
lib/ephem.f90
lib/extract.f90
lib/extract4.f90
lib/extractmessage144.f90
lib/fsk4hf/extractmessage168.f90
lib/extractmessage77.f90
lib/ft8/extractmessage174.f90
lib/ft8/extractmessage174_91.f90
lib/fano232.f90
lib/fast9.f90
lib/fast_decode.f90
@ -428,7 +430,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
@ -443,27 +444,22 @@ set (wsjt_FSRCS
lib/ft8/foxgen_wrap.f90
lib/fqso_first.f90
lib/freqcal.f90
lib/fsk4hf/fsk4hf.f90
lib/ft8/ft8apset.f90
lib/ft8/ft8b.f90
lib/ft8/ft8apset_174_91.f90
lib/ft8/ft8b_1.f90
lib/ft8/ft8b_2.f90
lib/ft8/ft8code.f90
lib/ft8/ft8_downsample.f90
lib/ft8/ft8sim.f90
lib/ft8/ft8sim2.f90
lib/gen4.f90
lib/gen65.f90
lib/gen9.f90
lib/geniscat.f90
lib/fsk4hf/genfsk4hf.f90
lib/ft8/genft8.f90
lib/genmsk144.f90
lib/ft8/genft8_174_91.f90
lib/genmsk_128_90.f90
lib/genmsk40.f90
lib/fsk4hf/genmskhf.f90
lib/fsk4hf/genwsprlf.f90
lib/fsk4hf/genwspr_fsk8.f90
lib/fsk4hf/getfc1.f90
lib/fsk4hf/getfc2.f90
lib/fsk4hf/getfc1w.f90
lib/fsk4hf/getfc2w.f90
lib/genqra64.f90
lib/ft8/genft8refsig.f90
lib/genwspr.f90
@ -488,12 +484,6 @@ set (wsjt_FSRCS
lib/jplsubs.f
lib/jt9fano.f90
lib/jtmsg.f90
lib/ldpcsim144.f90
lib/fsk4hf/ldpcsim120.f90
lib/fsk4hf/ldpcsim168.f90
lib/ft8/ldpcsim174.f90
lib/fsk4hf/ldpcsim300.f90
lib/ldpcsim40.f90
lib/libration.f90
lib/lorentzian.f90
lib/lpf1.f90
@ -515,18 +505,17 @@ set (wsjt_FSRCS
lib/mskrtd.f90
lib/msk144signalquality.f90
lib/msk144sim.f90
lib/fsk4hf/mskhfsim.f90
lib/mskrtd.f90
lib/fsk4hf/msksoftsym.f90
lib/fsk4hf/msksoftsymw.f90
lib/77bit/my_hash.f90
lib/ft8/osd174.f90
lib/fsk4hf/osd300.f90
lib/wsprd/osdwspr.f90
lib/ft8/osd174_91.f90
lib/77bit/parse77.f90
lib/pctile.f90
lib/peakdt9.f90
lib/peakup.f90
lib/plotsave.f90
lib/polyfit.f90
lib/fsk4hf/polyfit4.f90
lib/prog_args.f90
lib/ps4.f90
lib/qra64a.f90
@ -545,9 +534,7 @@ set (wsjt_FSRCS
lib/softsym9f.f90
lib/softsym9w.f90
lib/shell.f90
lib/fsk4hf/spec4.f90
lib/spec64.f90
lib/fsk4hf/spec8.f90
lib/spec9f.f90
lib/stdmsg.f90
lib/subtract65.f90
@ -566,7 +553,6 @@ set (wsjt_FSRCS
lib/sync9w.f90
lib/synciscat.f90
lib/timf2.f90
lib/to_contest_msg.f90
lib/tweak1.f90
lib/twkfreq.f90
lib/ft8/twkfreq1.f90
@ -581,11 +567,6 @@ set (wsjt_FSRCS
lib/xcor4.f90
lib/wqdecode.f90
lib/wqencode.f90
lib/fsk4hf/wspr_fsk8d.f90
lib/fsk4hf/wspr_fsk8_sim.f90
lib/fsk4hf/wspr_fsk8_wav.f90
lib/fsk4hf/wspr_fsk8_downsample.f90
lib/fsk4hf/wsprlfsim.f90
lib/wspr_downsample.f90
lib/zplot9.f90
)
@ -659,6 +640,7 @@ set (wsjtx_UISRCS
mainwindow.ui
about.ui
astro.ui
colorhighlighting.ui
echograph.ui
fastgraph.ui
messageaveraging.ui
@ -887,7 +869,9 @@ endif (WIN32)
#
# sub-directories
#
add_subdirectory (samples)
if (EXISTS ${CMAKE_SOURCE_DIR}/samples AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/samples)
add_subdirectory (samples)
endif ()
if (WSJT_GENERATE_DOCS)
add_subdirectory (doc)
endif (WSJT_GENERATE_DOCS)
@ -1165,94 +1149,11 @@ endif (WIN32)
add_library (wsjt_qtmm STATIC ${wsjt_qtmm_CXXSRCS} ${wsjt_qtmm_GENUISRCS})
target_link_libraries (wsjt_qtmm Qt5::Multimedia)
add_executable (jt4sim lib/jt4sim.f90 wsjtx.rc)
target_link_libraries (jt4sim wsjt_fort wsjt_cxx)
add_executable (jt65sim lib/jt65sim.f90 wsjtx.rc)
target_link_libraries (jt65sim wsjt_fort wsjt_cxx)
add_executable (qra64sim lib/qra/qra64/qra64sim.f90 wsjtx.rc)
target_link_libraries (qra64sim wsjt_fort wsjt_cxx)
add_executable (jt49sim lib/jt49sim.f90 wsjtx.rc)
target_link_libraries (jt49sim wsjt_fort wsjt_cxx)
add_executable (allsim lib/allsim.f90 wsjtx.rc)
target_link_libraries (allsim wsjt_fort wsjt_cxx)
add_executable (jt65code lib/jt65code.f90 wsjtx.rc)
target_link_libraries (jt65code wsjt_fort wsjt_cxx)
add_executable (qra64code lib/qra64code.f90 wsjtx.rc)
target_link_libraries (qra64code wsjt_fort wsjt_cxx)
add_executable (jt9code lib/jt9code.f90 wsjtx.rc)
target_link_libraries (jt9code wsjt_fort wsjt_cxx)
add_executable (wsprcode lib/wsprcode/wsprcode.f90 lib/wsprcode/nhash.c
wsjtx.rc)
target_link_libraries (wsprcode wsjt_fort wsjt_cxx)
add_executable (wsprd ${wsprd_CSRCS})
# Always build these:
add_executable (wsprd ${wsprd_CSRCS} lib/indexx.f90 lib/wsprd/osdwspr.f90)
target_include_directories (wsprd PRIVATE ${FFTW3_INCLUDE_DIRS})
target_link_libraries (wsprd ${FFTW3_LIBRARIES})
add_executable (wsprsim ${wsprsim_CSRCS})
add_executable (jt4code lib/jt4code.f90 wsjtx.rc)
target_link_libraries (jt4code wsjt_fort wsjt_cxx)
add_executable (msk144code lib/msk144code.f90 wsjtx.rc)
target_link_libraries (msk144code wsjt_fort wsjt_cxx)
add_executable (jt65 lib/jt65.f90 lib/jt65_test.f90 wsjtx.rc)
target_link_libraries (jt65 wsjt_fort wsjt_cxx)
add_executable (ldpcsim40 lib/ldpcsim40.f90 wsjtx.rc)
target_link_libraries (ldpcsim40 wsjt_fort wsjt_cxx)
add_executable (ldpcsim120 lib/fsk4hf/ldpcsim120.f90 wsjtx.rc)
target_link_libraries (ldpcsim120 wsjt_fort wsjt_cxx)
add_executable (ldpcsim174 lib/ft8/ldpcsim174.f90 wsjtx.rc)
target_link_libraries (ldpcsim174 wsjt_fort wsjt_cxx)
add_executable (ldpcsim144 lib/ldpcsim144.f90 wsjtx.rc)
target_link_libraries (ldpcsim144 wsjt_fort wsjt_cxx)
add_executable (ldpcsim168 lib/fsk4hf/ldpcsim168.f90 wsjtx.rc)
target_link_libraries (ldpcsim168 wsjt_fort wsjt_cxx)
add_executable (fsk4hf lib/fsk4hf/fsk4hf.f90 wsjtx.rc)
target_link_libraries (fsk4hf wsjt_fort wsjt_cxx)
add_executable (ft8code lib/ft8/ft8code.f90 wsjtx.rc)
target_link_libraries (ft8code wsjt_fort wsjt_cxx)
add_executable (ft8sim lib/ft8/ft8sim.f90 wsjtx.rc)
target_link_libraries (ft8sim wsjt_fort wsjt_cxx)
add_executable (wsprlfsim lib/fsk4hf/wsprlfsim.f90 wsjtx.rc)
target_link_libraries (wsprlfsim wsjt_fort wsjt_cxx)
add_executable (wspr_fsk8d lib/fsk4hf/wspr_fsk8d.f90 wsjtx.rc)
target_link_libraries (wspr_fsk8d wsjt_fort wsjt_cxx)
add_executable (wspr_fsk8_sim lib/fsk4hf/wspr_fsk8_sim.f90 wsjtx.rc)
target_link_libraries (wspr_fsk8_sim wsjt_fort wsjt_cxx)
add_executable (mskhfsim lib/fsk4hf/mskhfsim.f90 wsjtx.rc)
target_link_libraries (mskhfsim wsjt_fort wsjt_cxx)
add_executable (msk144sd lib/msk144sd.f90 wsjtx.rc)
target_link_libraries (msk144sd wsjt_fort wsjt_cxx)
add_executable (msk144sim lib/msk144sim.f90 wsjtx.rc)
target_link_libraries (msk144sim wsjt_fort wsjt_cxx)
add_executable (msk144d2 lib/msk144d2.f90 wsjtx.rc)
target_link_libraries (msk144d2 wsjt_fort wsjt_cxx)
add_executable (fmtave lib/fmtave.f90 wsjtx.rc)
add_executable (fcal lib/fcal.f90 wsjtx.rc)
@ -1297,6 +1198,65 @@ else (${OPENMP_FOUND} OR APPLE)
target_link_libraries (jt9 wsjt_fort wsjt_cxx Qt5::Core)
endif (${OPENMP_FOUND} OR APPLE)
if(WSJT_BUILD_UTILS)
add_executable (jt4sim lib/jt4sim.f90 wsjtx.rc)
target_link_libraries (jt4sim wsjt_fort wsjt_cxx)
add_executable (jt65sim lib/jt65sim.f90 wsjtx.rc)
target_link_libraries (jt65sim wsjt_fort wsjt_cxx)
add_executable (qra64sim lib/qra/qra64/qra64sim.f90 wsjtx.rc)
target_link_libraries (qra64sim wsjt_fort wsjt_cxx)
add_executable (jt49sim lib/jt49sim.f90 wsjtx.rc)
target_link_libraries (jt49sim wsjt_fort wsjt_cxx)
add_executable (allsim lib/allsim.f90 wsjtx.rc)
target_link_libraries (allsim wsjt_fort wsjt_cxx)
add_executable (jt65code lib/jt65code.f90 wsjtx.rc)
target_link_libraries (jt65code wsjt_fort wsjt_cxx)
add_executable (qra64code lib/qra64code.f90 wsjtx.rc)
target_link_libraries (qra64code wsjt_fort wsjt_cxx)
add_executable (jt9code lib/jt9code.f90 wsjtx.rc)
target_link_libraries (jt9code wsjt_fort wsjt_cxx)
add_executable (wsprcode lib/wsprcode/wsprcode.f90 lib/wsprcode/nhash.c
wsjtx.rc)
target_link_libraries (wsprcode wsjt_fort wsjt_cxx)
add_executable (wsprsim ${wsprsim_CSRCS})
add_executable (jt4code lib/jt4code.f90 wsjtx.rc)
target_link_libraries (jt4code wsjt_fort wsjt_cxx)
add_executable (msk144code lib/msk144code.f90 wsjtx.rc)
target_link_libraries (msk144code wsjt_fort wsjt_cxx)
add_executable (jt65 lib/jt65.f90 lib/jt65_test.f90 wsjtx.rc)
target_link_libraries (jt65 wsjt_fort wsjt_cxx)
add_executable (ft8code lib/ft8/ft8code.f90 wsjtx.rc)
target_link_libraries (ft8code wsjt_fort wsjt_cxx)
add_executable (ft8sim lib/ft8/ft8sim.f90 wsjtx.rc)
target_link_libraries (ft8sim wsjt_fort wsjt_cxx)
add_executable (ft8sim2 lib/ft8/ft8sim2.f90 wsjtx.rc)
target_link_libraries (ft8sim2 wsjt_fort wsjt_cxx)
add_executable (msk144sd lib/msk144sd.f90 wsjtx.rc)
target_link_libraries (msk144sd wsjt_fort wsjt_cxx)
add_executable (msk144sim lib/msk144sim.f90 wsjtx.rc)
target_link_libraries (msk144sim wsjt_fort wsjt_cxx)
add_executable (msk144d2 lib/msk144d2.f90 wsjtx.rc)
target_link_libraries (msk144d2 wsjt_fort wsjt_cxx)
endif(WSJT_BUILD_UTILS)
# build the main application
add_executable (wsjtx MACOSX_BUNDLE
${wsjtx_CXXSRCS}
@ -1426,12 +1386,19 @@ install (TARGETS udp_daemon message_aggregator
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
install (TARGETS jt9 ft8code jt65code qra64code qra64sim jt9code jt4code
msk144code wsprd wspr_fsk8d fmtave fcal fmeasure
install (TARGETS jt9 wsprd fmtave fcal fmeasure
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
if(WSJT_BUILD_UTILS)
install (TARGETS ft8code jt65code qra64code qra64sim jt9code jt4code
msk144code
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
endif(WSJT_BUILD_UTILS)
install (PROGRAMS
${RIGCTL_EXE}
DESTINATION ${CMAKE_INSTALL_BINDIR}
@ -1460,6 +1427,7 @@ install (FILES
install (FILES
contrib/Ephemeris/JPLEPH
contrib/lotw-user-activity.csv
DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}
#COMPONENT runtime
)

View File

@ -409,6 +409,7 @@ private:
void delete_stations ();
void insert_station ();
void chk77();
Q_SLOT void on_font_push_button_clicked ();
Q_SLOT void on_decoded_text_font_push_button_clicked ();
@ -443,11 +444,18 @@ private:
Q_SLOT void on_pbMyCall_clicked();
Q_SLOT void on_pbTxMsg_clicked();
Q_SLOT void on_pbNewDXCC_clicked();
Q_SLOT void on_pbNewDXCCband_clicked();
Q_SLOT void on_pbNewCall_clicked();
Q_SLOT void on_pbNewCallBand_clicked();
Q_SLOT void on_pbNewGrid_clicked();
Q_SLOT void on_pbNewGridBand_clicked();
Q_SLOT void on_pbLoTW_clicked();
Q_SLOT void on_pbResetDefaults_clicked();
Q_SLOT void on_cbFox_clicked (bool);
Q_SLOT void on_cbHound_clicked (bool);
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
Q_SLOT void on_cbx4ToneSpacing_clicked(bool);
Q_SLOT void on_rbNone_toggled(bool);
// typenames used as arguments must match registered type names :(
Q_SIGNAL void start_transceiver (unsigned seqeunce_number) const;
@ -529,6 +537,8 @@ private:
// configuration fields that we publish
QString my_callsign_;
QString my_grid_;
QString FD_exchange_;
QString RTTY_exchange_;
QColor color_CQ_;
QColor next_color_CQ_;
QColor color_MyCall_;
@ -537,8 +547,19 @@ private:
QColor next_color_TxMsg_;
QColor color_DXCC_;
QColor next_color_DXCC_;
QColor color_DXCCband_;
QColor next_color_DXCCband_;
QColor color_NewCall_;
QColor next_color_NewCall_;
QColor color_NewCallBand_;
QColor next_color_NewCallBand_;
QColor color_NewGrid_;
QColor next_color_NewGrid_;
QColor color_NewGridBand_;
QColor next_color_NewGridBand_;
QColor color_LoTW_;
QColor next_color_LoTW_;
qint32 id_interval_;
qint32 ntrials_;
qint32 aggressive_;
@ -568,6 +589,13 @@ private:
bool twoPass_;
bool bFox_;
bool bHound_;
bool bGenerate77_;
bool bDecode77_;
bool bNoSpecial_;
bool bFieldDay_;
bool bRTTYroundup_;
bool bNA_VHF_Contest_;
bool bEU_VHF_Contest_;
bool x2ToneSpacing_;
bool x4ToneSpacing_;
bool use_dynamic_grid_;
@ -633,7 +661,12 @@ QColor Configuration::color_CQ () const {return m_->color_CQ_;}
QColor Configuration::color_MyCall () const {return m_->color_MyCall_;}
QColor Configuration::color_TxMsg () const {return m_->color_TxMsg_;}
QColor Configuration::color_DXCC () const {return m_->color_DXCC_;}
QColor Configuration::color_DXCCband() const {return m_->color_DXCCband_;}
QColor Configuration::color_NewCall () const {return m_->color_NewCall_;}
QColor Configuration::color_NewCallBand () const {return m_->color_NewCallBand_;}
QColor Configuration::color_NewGrid () const {return m_->color_NewGrid_;}
QColor Configuration::color_NewGridBand () const {return m_->color_NewGridBand_;}
QColor Configuration::color_LoTW() const {return m_->color_LoTW_;}
QFont Configuration::text_font () const {return m_->font_;}
QFont Configuration::decoded_text_font () const {return m_->decoded_text_font_;}
qint32 Configuration::id_interval () const {return m_->id_interval_;}
@ -669,6 +702,13 @@ bool Configuration::single_decode () const {return m_->single_decode_;}
bool Configuration::twoPass() const {return m_->twoPass_;}
bool Configuration::bFox() const {return m_->bFox_;}
bool Configuration::bHound() const {return m_->bHound_;}
bool Configuration::bGenerate77() const {return m_->bGenerate77_;}
bool Configuration::bDecode77() const {return m_->bDecode77_;}
bool Configuration::bNoSpecial() const {return m_->bNoSpecial_;}
bool Configuration::bFieldDay() const {return m_->bFieldDay_;}
bool Configuration::bRTTYroundup() const {return m_->bRTTYroundup_;}
bool Configuration::bNA_VHF_Contest() const {return m_->bNA_VHF_Contest_;}
bool Configuration::bEU_VHF_Contest() const {return m_->bEU_VHF_Contest_;}
bool Configuration::x2ToneSpacing() const {return m_->x2ToneSpacing_;}
bool Configuration::x4ToneSpacing() const {return m_->x4ToneSpacing_;}
bool Configuration::split_mode () const {return m_->split_mode ();}
@ -807,6 +847,24 @@ QString Configuration::my_grid() const
return the_grid;
}
QString Configuration::FieldDayExchange() const
{
return m_->FD_exchange_;
}
void Configuration::setEU_VHF_Contest()
{
m_->bEU_VHF_Contest_ = true;
m_->ui_->rbEU_VHF_Contest->setChecked(m_->bEU_VHF_Contest_);
m_->ui_->cbGenerate77->setChecked(true);
m_->write_settings();
}
QString Configuration::RTTYExchange() const
{
return m_->RTTY_exchange_;
}
void Configuration::set_location (QString const& grid_descriptor)
{
// change the dynamic grid
@ -1127,8 +1185,13 @@ void Configuration::impl::initialize_models ()
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(color_MyCall_.name()));
ui_->labTx->setStyleSheet(QString("background: %1").arg(color_TxMsg_.name()));
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(color_DXCC_.name()));
ui_->labDXCCband->setStyleSheet(QString("background: %1").arg(color_DXCCband_.name()));
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(color_NewCall_.name()));
ui_->CW_id_interval_spin_box->setValue (id_interval_);
ui_->labNewCallBand->setStyleSheet(QString("background: %1").arg(color_NewCallBand_.name()));
ui_->labNewGrid->setStyleSheet(QString("background: %1").arg(color_NewGrid_.name()));
ui_->labNewGridBand->setStyleSheet(QString("background: %1").arg(color_NewGridBand_.name()));
ui_->labLoTW->setStyleSheet(QString("color: %1").arg(color_LoTW_.name()));
ui_->CW_id_interval_spin_box->setValue (id_interval_);
ui_->sbNtrials->setValue (ntrials_);
ui_->sbTxDelay->setValue (txDelay_);
ui_->sbAggressive->setValue (aggressive_);
@ -1160,6 +1223,13 @@ void Configuration::impl::initialize_models ()
ui_->cbTwoPass->setChecked(twoPass_);
ui_->cbFox->setChecked(bFox_);
ui_->cbHound->setChecked(bHound_);
ui_->cbGenerate77->setChecked(bGenerate77_);
ui_->cbDecode77->setChecked(bDecode77_);
ui_->rbNone->setChecked(bNoSpecial_);
ui_->rbFieldDay->setChecked(bFieldDay_);
ui_->rbRTTYroundup->setChecked(bRTTYroundup_);
ui_->rbNA_VHF_Contest->setChecked(bNA_VHF_Contest_);
ui_->rbEU_VHF_Contest->setChecked(bEU_VHF_Contest_);
ui_->cbx2ToneSpacing->setChecked(x2ToneSpacing_);
ui_->cbx4ToneSpacing->setChecked(x4ToneSpacing_);
ui_->type_2_msg_gen_combo_box->setCurrentIndex (type_2_msg_gen_);
@ -1201,6 +1271,7 @@ void Configuration::impl::initialize_models ()
ui_->udpWindowRestore->setChecked(udpWindowRestore_);
ui_->calibration_intercept_spin_box->setValue (calibration_.intercept);
ui_->calibration_slope_ppm_spin_box->setValue (calibration_.slope_ppm);
chk77();
if (rig_params_.ptt_port.isEmpty ())
{
@ -1239,12 +1310,20 @@ void Configuration::impl::read_settings ()
my_callsign_ = settings_->value ("MyCall", QString {}).toString ();
my_grid_ = settings_->value ("MyGrid", QString {}).toString ();
FD_exchange_ = settings_->value ("FieldDayExchange",QString {}).toString ();
RTTY_exchange_ = settings_->value ("RTTYExchange",QString {}).toString ();
ui_->FieldDay_Exchange->setText(FD_exchange_);
ui_->RTTY_Exchange->setText(RTTY_exchange_);
next_color_CQ_ = color_CQ_ = settings_->value("colorCQ","#66ff66").toString();
next_color_MyCall_ = color_MyCall_ = settings_->value("colorMyCall","#ff6666").toString();
next_color_TxMsg_ = color_TxMsg_ = settings_->value("colorTxMsg","#ffff00").toString();
next_color_DXCC_ = color_DXCC_ = settings_->value("colorDXCC","#ff00ff").toString();
next_color_NewCall_ = color_NewCall_ = settings_->value("colorNewCall","#ffaaff").toString();
next_color_DXCCband_ = color_DXCCband_ = settings_->value("colorDXCCband","#ffaaff").toString();
next_color_NewCall_ = color_NewCall_ = settings_->value("colorNewCall","#66b2ff").toString();
next_color_NewCallBand_ = color_NewCallBand_ = settings_->value("colorNewCallBand","#99ffff").toString();
next_color_NewGrid_ = color_NewGrid_ = settings_->value("colorNewGrid","#ffaa00").toString();
next_color_NewGridBand_ = color_NewGridBand_ = settings_->value("colorNewGridBand","#ffcc99").toString();
next_color_LoTW_ = color_LoTW_ = settings_->value("colorLoTW","#990000").toString();
if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
&& next_font_ != font_)
{
@ -1397,6 +1476,13 @@ void Configuration::impl::read_settings ()
twoPass_ = settings_->value("TwoPass",true).toBool ();
bFox_ = settings_->value("Fox",false).toBool ();
bHound_ = settings_->value("Hound",false).toBool ();
bGenerate77_ = settings_->value("Generate77",false).toBool ();
bDecode77_ = settings_->value("Decode77",false).toBool ();
bNoSpecial_ = settings_->value("NoSpecial",false).toBool ();
bFieldDay_ = settings_->value("FieldDay",false).toBool ();
bRTTYroundup_ = settings_->value("RTTYroundup",false).toBool ();
bNA_VHF_Contest_ = settings_->value("NA_VHF_Contest",false).toBool ();
bEU_VHF_Contest_ = settings_->value("EU_VHF_Contest",false).toBool ();
x2ToneSpacing_ = settings_->value("x2ToneSpacing",false).toBool ();
x4ToneSpacing_ = settings_->value("x4ToneSpacing",false).toBool ();
rig_params_.poll_interval = settings_->value ("Polling", 0).toInt ();
@ -1422,11 +1508,18 @@ void Configuration::impl::write_settings ()
settings_->setValue ("MyCall", my_callsign_);
settings_->setValue ("MyGrid", my_grid_);
settings_->setValue ("FieldDayExchange", FD_exchange_);
settings_->setValue ("RTTYExchange", RTTY_exchange_);
settings_->setValue("colorCQ",color_CQ_);
settings_->setValue("colorMyCall",color_MyCall_);
settings_->setValue("colorTxMsg",color_TxMsg_);
settings_->setValue("colorDXCC",color_DXCC_);
settings_->setValue("colorDXCCband",color_DXCCband_);
settings_->setValue("colorNewCall",color_NewCall_);
settings_->setValue("colorNewCallBand",color_NewCallBand_);
settings_->setValue("colorNewGrid",color_NewGrid_);
settings_->setValue("colorNewGridBand",color_NewGridBand_);
settings_->setValue("colorLoTW",color_LoTW_);
settings_->setValue ("Font", font_.toString ());
settings_->setValue ("DecodedTextFont", decoded_text_font_.toString ());
settings_->setValue ("IDint", id_interval_);
@ -1502,6 +1595,13 @@ void Configuration::impl::write_settings ()
settings_->setValue ("TwoPass", twoPass_);
settings_->setValue ("Fox", bFox_);
settings_->setValue ("Hound", bHound_);
settings_->setValue ("Generate77", bGenerate77_);
settings_->setValue ("Decode77", bDecode77_);
settings_->setValue ("NoSpecial", bNoSpecial_);
settings_->setValue ("FieldDay", bFieldDay_);
settings_->setValue ("RTTYroundup", bRTTYroundup_);
settings_->setValue ("NA_VHF_Contest", bNA_VHF_Contest_);
settings_->setValue ("EU_VHF_Contest", bEU_VHF_Contest_);
settings_->setValue ("x2ToneSpacing", x2ToneSpacing_);
settings_->setValue ("x4ToneSpacing", x4ToneSpacing_);
settings_->setValue ("OpCall", opCall_);
@ -1790,7 +1890,12 @@ void Configuration::impl::accept ()
color_MyCall_ = next_color_MyCall_;
color_TxMsg_ = next_color_TxMsg_;
color_DXCC_ = next_color_DXCC_;
color_DXCCband_ = next_color_DXCCband_;
color_NewCall_ = next_color_NewCall_;
color_NewCallBand_ = next_color_NewCallBand_;
color_NewGrid_ = next_color_NewGrid_;
color_NewGridBand_ = next_color_NewGridBand_;
color_LoTW_ = next_color_LoTW_;
rig_params_ = temp_rig_params; // now we can go live with the rig
// related configuration parameters
@ -1872,6 +1977,8 @@ void Configuration::impl::accept ()
my_callsign_ = ui_->callsign_line_edit->text ();
my_grid_ = ui_->grid_line_edit->text ();
FD_exchange_= ui_->FieldDay_Exchange->text ();
RTTY_exchange_= ui_->RTTY_Exchange->text ();
spot_to_psk_reporter_ = ui_->psk_reporter_check_box->isChecked ();
id_interval_ = ui_->CW_id_interval_spin_box->value ();
ntrials_ = ui_->sbNtrials->value ();
@ -1905,6 +2012,14 @@ void Configuration::impl::accept ()
twoPass_ = ui_->cbTwoPass->isChecked ();
bFox_ = ui_->cbFox->isChecked ();
bHound_ = ui_->cbHound->isChecked ();
if(bFox_ or bHound_) ui_->rbNone->setChecked(true); //###
bGenerate77_ = ui_->cbGenerate77->isChecked();
bDecode77_ = ui_->cbDecode77->isChecked();
bNoSpecial_ = ui_->rbNone->isChecked ();
bFieldDay_ = ui_->rbFieldDay->isChecked ();
bRTTYroundup_ = ui_->rbRTTYroundup->isChecked ();
bNA_VHF_Contest_ = ui_->rbNA_VHF_Contest->isChecked ();
bEU_VHF_Contest_ = ui_->rbEU_VHF_Contest->isChecked ();
x2ToneSpacing_ = ui_->cbx2ToneSpacing->isChecked ();
x4ToneSpacing_ = ui_->cbx4ToneSpacing->isChecked ();
calibration_.intercept = ui_->calibration_intercept_spin_box->value ();
@ -2033,6 +2148,16 @@ void Configuration::impl::on_pbNewDXCC_clicked()
}
}
void Configuration::impl::on_pbNewDXCCband_clicked()
{
auto new_color = QColorDialog::getColor(next_color_DXCCband_, this, "New DXCCband Color");
if (new_color.isValid ())
{
next_color_DXCCband_ = new_color;
ui_->labDXCCband->setStyleSheet(QString("background: %1").arg(next_color_DXCCband_.name()));
}
}
void Configuration::impl::on_pbNewCall_clicked()
{
auto new_color = QColorDialog::getColor(next_color_NewCall_, this, "New Call Messages Color");
@ -2043,6 +2168,69 @@ void Configuration::impl::on_pbNewCall_clicked()
}
}
void Configuration::impl::on_pbNewCallBand_clicked()
{
auto new_color = QColorDialog::getColor(next_color_NewCallBand_, this, "New CallBand Color");
if (new_color.isValid ())
{
next_color_NewCallBand_ = new_color;
ui_->labNewCallBand->setStyleSheet(QString("background: %1").arg(next_color_NewCallBand_.name()));
}
}
void Configuration::impl::on_pbNewGrid_clicked()
{
auto new_color = QColorDialog::getColor(next_color_NewGrid_, this, "New Grid Messages Color");
if (new_color.isValid ())
{
next_color_NewGrid_ = new_color;
ui_->labNewGrid->setStyleSheet(QString("background: %1").arg(next_color_NewGrid_.name()));
}
}
void Configuration::impl::on_pbNewGridBand_clicked()
{
auto new_color = QColorDialog::getColor(next_color_NewGridBand_, this, "New GridBand Messages Color");
if (new_color.isValid ())
{
next_color_NewGridBand_ = new_color;
ui_->labNewGridBand->setStyleSheet(QString("background: %1").arg(next_color_NewGridBand_.name()));
}
}
void Configuration::impl::on_pbLoTW_clicked()
{
auto new_color = QColorDialog::getColor(next_color_LoTW_, this, "Not in LoTW Color");
if (new_color.isValid ()) {
next_color_LoTW_ = new_color;
ui_->labLoTW->setStyleSheet(QString("color: %1").arg(next_color_LoTW_.name()));
}
}
void Configuration::impl::on_pbResetDefaults_clicked()
{
next_color_CQ_ = color_CQ_ = "#66ff66";
next_color_MyCall_ = color_MyCall_ = "#ff6666";
next_color_TxMsg_ = color_TxMsg_ = "#ffff00";
next_color_DXCC_ = color_DXCC_ = "#ff00ff";
next_color_DXCCband_ = color_DXCCband_ = "#ffaaff";
next_color_NewCall_ = color_NewCall_ = "#66b2ff";
next_color_NewCallBand_ = color_NewCallBand_ = "#99ffff";
next_color_NewGrid_ = color_NewGrid_ = "#ffaa00";
next_color_NewGridBand_ = color_NewGridBand_ = "#ffcc99";
next_color_LoTW_ = color_LoTW_ = "#5500ff";
ui_->labCQ->setStyleSheet(QString("background: %1").arg(next_color_CQ_.name()));
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(next_color_MyCall_.name()));
ui_->labTx->setStyleSheet(QString("background: %1").arg(next_color_TxMsg_.name()));
ui_->labDXCC->setStyleSheet(QString("background: %1").arg(next_color_DXCC_.name()));
ui_->labDXCCband->setStyleSheet(QString("background: %1").arg(next_color_DXCCband_.name()));
ui_->labNewCall->setStyleSheet(QString("background: %1").arg(next_color_NewCall_.name()));
ui_->labNewCallBand->setStyleSheet(QString("background: %1").arg(next_color_NewCallBand_.name()));
ui_->labNewGrid->setStyleSheet(QString("background: %1").arg(next_color_NewGrid_.name()));
ui_->labNewGridBand->setStyleSheet(QString("background: %1").arg(next_color_NewGridBand_.name()));
ui_->labLoTW->setStyleSheet(QString("color: %1").arg(next_color_LoTW_.name()));
}
void Configuration::impl::on_decoded_text_font_push_button_clicked ()
{
next_decoded_text_font_ = QFontDialog::getFont (0, decoded_text_font_ , this
@ -2391,12 +2579,36 @@ void Configuration::impl::on_calibration_slope_ppm_spin_box_valueChanged (double
void Configuration::impl::on_cbFox_clicked (bool checked)
{
if (checked) ui_->cbHound->setChecked (false);
if(checked) {
ui_->cbHound->setChecked (false);
ui_->rbNone->setChecked(true);
}
chk77();
}
void Configuration::impl::on_cbHound_clicked (bool checked)
{
if (checked) ui_->cbFox->setChecked (false);
if(checked) {
ui_->cbFox->setChecked (false);
ui_->rbNone->setChecked(true);
}
chk77();
}
void Configuration::impl::chk77()
{
bool b77OK = !ui_->cbFox->isChecked() and !ui_->cbHound->isChecked();
ui_->groupBox_8->setEnabled(b77OK);
ui_->groupBox_9->setEnabled(b77OK);
if(!b77OK) {
ui_->cbGenerate77->setChecked(false);
ui_->cbDecode77->setChecked(false);
}
}
void Configuration::impl::on_rbNone_toggled(bool b)
{
if(!b) ui_->cbGenerate77->setChecked(true);
}
void Configuration::impl::on_cbx2ToneSpacing_clicked(bool b)

View File

@ -96,6 +96,9 @@ public:
QString my_callsign () const;
QString my_grid () const;
QString FieldDayExchange() const;
QString RTTYExchange() const;
void setEU_VHF_Contest();
QFont text_font () const;
QFont decoded_text_font () const;
qint32 id_interval () const;
@ -128,9 +131,15 @@ public:
bool twoPass() const;
bool bFox() const;
bool bHound() const;
bool bGenerate77() const;
bool bDecode77() const;
bool bNoSpecial() const;
bool bFieldDay() const;
bool bRTTYroundup() const;
bool bNA_VHF_Contest() const;
bool bEU_VHF_Contest() const;
bool x2ToneSpacing() const;
bool x4ToneSpacing() const;
bool contestMode() const;
bool MyDx() const;
bool CQMyN() const;
bool NDxG() const;
@ -164,7 +173,12 @@ public:
QColor color_MyCall () const;
QColor color_TxMsg () const;
QColor color_DXCC () const;
QColor color_DXCCband () const;
QColor color_NewCall () const;
QColor color_NewCallBand () const;
QColor color_NewGrid () const;
QColor color_NewGridBand () const;
QColor color_LoTW() const;
bool pwrBandTxMemory () const;
bool pwrBandTuneMemory () const;

File diff suppressed because it is too large Load Diff

View File

@ -67,6 +67,7 @@ namespace
{7038600, Modes::WSPR, IARURegions::ALL},
{7074000, Modes::FT8, IARURegions::ALL},
{7076000, Modes::JT65, IARURegions::ALL},
{7078000, Modes::FT8, IARURegions::ALL},
{7078000, Modes::JT9, IARURegions::ALL},
{10136000, Modes::FT8, IARURegions::ALL},
@ -77,6 +78,7 @@ namespace
{14095600, Modes::WSPR, IARURegions::ALL},
{14074000, Modes::FT8, IARURegions::ALL},
{14076000, Modes::JT65, IARURegions::ALL},
{14078000, Modes::FT8, IARURegions::ALL},
{14078000, Modes::JT9, IARURegions::ALL},
{18100000, Modes::FT8, IARURegions::ALL},
@ -102,15 +104,15 @@ namespace
{50200000, Modes::Echo, IARURegions::ALL},
{50276000, Modes::JT65, IARURegions::R2},
{50276000, Modes::JT65, IARURegions::R3},
{50260000, Modes::MSK144, IARURegions::R2},
{50260000, Modes::MSK144, IARURegions::R3},
{50380000, Modes::MSK144, IARURegions::R1},
{50280000, Modes::MSK144, IARURegions::R2},
{50280000, Modes::MSK144, IARURegions::R3},
{50293000, Modes::WSPR, IARURegions::R2},
{50293000, Modes::WSPR, IARURegions::R3},
{50310000, Modes::JT65, IARURegions::ALL},
{50312000, Modes::JT9, IARURegions::ALL},
{50313000, Modes::FT8, IARURegions::ALL},
{50323000, Modes::FT8, IARURegions::ALL},
{50360000, Modes::MSK144, IARURegions::R1},
{70100000, Modes::FT8, IARURegions::R1},
{70102000, Modes::JT65, IARURegions::R1},

View File

@ -1,6 +1,6 @@
# Version number components
set (WSJTX_VERSION_MAJOR 1)
set (WSJTX_VERSION_MINOR 9)
set (WSJTX_VERSION_PATCH 2)
set (WSJTX_RC 0) # release candidate number, comment out or zero for development versions
set (WSJTX_VERSION_MAJOR 2)
set (WSJTX_VERSION_MINOR 0)
set (WSJTX_VERSION_PATCH 0)
set (WSJTX_RC 1) # release candidate number, comment out or zero for development versions
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build

52
colorhighlighting.cpp Normal file
View File

@ -0,0 +1,52 @@
#include "colorhighlighting.h"
#include "ui_colorhighlighting.h"
#include "SettingsGroup.hpp"
#include <QApplication>
#include <QDebug>
ColorHighlighting::ColorHighlighting(QSettings *settings, QWidget *parent) :
QDialog(parent),
settings_ {settings},
ui(new Ui::ColorHighlighting)
{
ui->setupUi(this);
read_settings ();
}
ColorHighlighting::~ColorHighlighting()
{
if (isVisible ()) write_settings ();
delete ui;
}
void ColorHighlighting::read_settings ()
{
SettingsGroup group {settings_, "ColorScheme"};
restoreGeometry (settings_->value ("window/geometry").toByteArray ());
}
void ColorHighlighting::write_settings ()
{
SettingsGroup group {settings_, "ColorScheme"};
settings_->setValue ("window/geometry", saveGeometry ());
}
void ColorHighlighting::colorHighlightlingSetup(QColor color_CQ,QColor color_MyCall,
QColor color_DXCC,QColor color_DXCCband,QColor color_NewCall,
QColor color_NewCallBand,QColor color_NewGrid,QColor color_NewGridBand,
QColor color_TxMsg,QColor color_LoTW)
{
setWindowTitle(QApplication::applicationName() + " - Colors");
ui->label->setStyleSheet(QString("background: %1").arg(color_CQ.name()));
ui->label_3->setStyleSheet(QString("background: %1").arg(color_MyCall.name()));
ui->label_5->setStyleSheet(QString("background: %1").arg(color_TxMsg.name()));
ui->label_7->setStyleSheet(QString("background: %1").arg(color_DXCC.name()));
ui->label_9->setStyleSheet(QString("background: %1").arg(color_DXCCband.name()));
ui->label_11->setStyleSheet(QString("background: %1").arg(color_NewCall.name()));
ui->label_13->setStyleSheet(QString("background: %1").arg(color_NewCallBand.name()));
ui->label_15->setStyleSheet(QString("background: %1").arg(color_NewGrid.name()));
ui->label_17->setStyleSheet(QString("background: %1").arg(color_NewGridBand.name()));
ui->label_19->setStyleSheet(QString("color: %1").arg(color_LoTW.name()));
}

30
colorhighlighting.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef COLORHIGHLIGHTING_H
#define COLORHIGHLIGHTING_H
#include <QDialog>
#include <QSettings>
namespace Ui {
class ColorHighlighting;
}
class ColorHighlighting : public QDialog
{
Q_OBJECT
public:
explicit ColorHighlighting(QSettings *, QWidget *parent = 0);
~ColorHighlighting();
void colorHighlightlingSetup(QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_DXCCband, QColor color_NewCall,
QColor color_NewCallBand, QColor color_NewGrid, QColor color_NewGridBand,
QColor color_TxMsg, QColor color_LoTW);
private:
QSettings * settings_;
void read_settings ();
void write_settings ();
Ui::ColorHighlighting *ui;
};
#endif // COLORHIGHLIGHTING_H

195
colorhighlighting.ui Normal file
View File

@ -0,0 +1,195 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ColorHighlighting</class>
<widget class="QDialog" name="ColorHighlighting">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>212</width>
<height>253</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="6" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Transmitted message</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="label_14">
<property name="text">
<string>New Call on Band</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="label_12">
<property name="text">
<string>New Call</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_16">
<property name="text">
<string>New Grid</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_18">
<property name="text">
<string>New Grid on Band</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>CQ in message</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>My Call in message</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
<string>New DXCC on Band</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>New DXCC</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Not in LoTW</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -44,6 +44,7 @@ extern struct dec_data {
bool lft8apon;
bool lapcqonly;
bool ljt65apon;
bool ldecode77;
int napwid;
int ntxmode;
int nmode;

120885
contrib/lotw-user-activity.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
#include <QDebug>
extern "C" {
bool stdmsg_(char const * msg, bool contest_mode, char const * mygrid, fortran_charlen_t, fortran_charlen_t);
bool stdmsg_(char const * msg, fortran_charlen_t);
}
namespace
@ -13,17 +13,17 @@ namespace
QRegularExpression words_re {R"(^(?:(?<word1>(?:CQ|DE|QRZ)(?:\s?DX|\s(?:[A-Z]{2}|\d{3}))|[A-Z0-9/]+)\s)(?:(?<word2>[A-Z0-9/]+)(?:\s(?<word3>[-+A-Z0-9]+)(?:\s(?<word4>(?: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)
: 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}
, message_ {string_.mid (column_qsoText + padding_).trimmed ()}
, is_standard_ {false}
{
if (message_.length() >= 1)
{
message_ = message_.left (21).remove (QRegularExpression {"[<>]"});
message0_ = message_.left(36);
message_ = message_.left(36).remove (QRegularExpression {"[<>]"});
int i1 = message_.indexOf ('\r');
if (i1 > 0)
{
@ -40,16 +40,11 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
// remove DXCC entity and worked B4 status. TODO need a better way to do this
message_ = message_.left (eom_pos + 1);
}
// stdmsg is a fortran routine that packs the text, unpacks it
// stdmsg is a Fortran routine that packs the text, unpacks it
// and compares the result
auto message_c_string = message_.toLocal8Bit ();
message_c_string += QByteArray {22 - message_c_string.size (), ' '};
auto grid_c_string = my_grid.toLocal8Bit ();
grid_c_string += QByteArray {6 - grid_c_string.size (), ' '};
is_standard_ = stdmsg_ (message_c_string.constData ()
, contest_mode_
, grid_c_string.constData ()
, 22, 6);
auto message_c_string = message0_.toLocal8Bit ();
message_c_string += QByteArray {37 - message_c_string.size (), ' '};
is_standard_ = stdmsg_(message_c_string.constData(),37);
}
};
@ -170,10 +165,13 @@ void DecodedText::deCallAndGrid(/*out*/QString& call, QString& grid) const
auto const& match = words_re.match (message_);
call = match.captured ("word2");
grid = match.captured ("word3");
if (contest_mode_ && "R" == grid)
{
grid = match.captured ("word4");
}
if ("R" == grid) grid = match.captured ("word4");
if(match.captured("word1")=="CQ" and call.length()>=3 and call.length()<=4
and !call.contains(QRegExp("[0-9]"))) {
//Second word has length 3 or 4 and contains no digits
call = match.captured ("word3");
grid = match.captured ("word4");
}
}
unsigned DecodedText::timeInSeconds() const

View File

@ -29,7 +29,7 @@
class DecodedText
{
public:
explicit DecodedText (QString const& message, bool, QString const& my_grid);
explicit DecodedText (QString const& message);
QString string() const { return string_; };
QStringList messageWords () const;
@ -79,6 +79,7 @@ private:
int padding_;
bool contest_mode_;
QString message_;
QString message0_;
bool is_standard_;
};

View File

@ -73,7 +73,8 @@ void DisplayText::insertLineSpacer(QString const& line)
appendText (line, "#d3d3d3");
}
void DisplayText::appendText(QString const& text, QColor bg, QString const& call1, QString const& call2)
void DisplayText::appendText(QString const& text, QColor bg,
QString const& call1, QString const& call2)
{
auto cursor = textCursor ();
cursor.movePosition (QTextCursor::End);
@ -142,6 +143,9 @@ void DisplayText::appendText(QString const& text, QColor bg, QString const& call
}
format.setBackground (bg);
format.clearForeground ();
if(call2.size()>0 and !m_LoTW.contains(call2)) {
format.setForeground(m_color_LoTW); //Mark LoTW non-users
}
cursor.insertText(text.mid (text_index), format);
// position so viewport scrolled to left
@ -151,18 +155,19 @@ void DisplayText::appendText(QString const& text, QColor bg, QString const& call
document ()->setMaximumBlockCount (document ()->maximumBlockCount ());
}
QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign, QColor * bg,
LogBook const& logBook, QColor color_CQ,
QColor color_DXCC,
QColor color_NewCall)
QString DisplayText::appendWorkedB4(QString message, QString const& callsign, QString grid,
QColor * bg, LogBook const& logBook, QString currentBand)
{
// allow for seconds
int padding {message.indexOf (" ") > 4 ? 2 : 0};
QString call = callsign;
QString countryName;
bool callWorkedBefore;
bool callB4onBand;
bool countryWorkedBefore;
bool countryB4onBand;
bool gridB4;
bool gridB4onBand;
if(call.length()==2) {
int i0=message.indexOf("CQ "+call);
@ -173,27 +178,49 @@ QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign
if(call.length()<3) return message;
if(!call.contains(QRegExp("[0-9]|[A-Z]"))) return message;
logBook.match(/*in*/call,/*out*/countryName,callWorkedBefore,countryWorkedBefore);
if(grid=="") {
gridB4=true;
gridB4onBand=true;
} else {
logBook.match(/*in*/call,grid,/*out*/countryName,callWorkedBefore,countryWorkedBefore,gridB4);
logBook.match(/*in*/call,grid,/*out*/countryName,callB4onBand,countryB4onBand,gridB4onBand,
/*in*/ currentBand);
}
message = message.trimmed ();
QString appendage;
if (!countryWorkedBefore) // therefore not worked call either
{
appendage += "!";
*bg = color_DXCC;
}
else
{
if (!callWorkedBefore) // but have worked the country
{
appendage += "~";
*bg = color_NewCall;
}
else
{
appendage += " "; // have worked this call before
*bg = color_CQ;
QString appendage{""};
if (!countryWorkedBefore) {
// therefore not worked call either
// appendage += "!";
*bg = m_color_DXCC;
} else {
if(!countryB4onBand) {
*bg = m_color_DXCCband;
} else {
if(!gridB4) {
*bg = m_color_NewGrid;
} else {
if(!gridB4onBand) {
*bg = m_color_NewGridBand;
} else {
if (!callWorkedBefore) {
// but have worked the country
// appendage += "~";
*bg = m_color_NewCall;
} else {
if(!callB4onBand) {
// appendage += "~";
*bg = m_color_NewCallBand;
} else {
// appendage += " "; // have worked this call before
*bg = m_color_CQ;
}
}
}
}
}
}
int i1=countryName.indexOf(";");
if(m_bPrincipalPrefix) {
@ -228,20 +255,16 @@ QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign
// it again later, align appended data at a fixed column if
// there is space otherwise let it float to the right
int space_count {40 + padding - message.size ()};
if (space_count > 0)
{
message += QString {space_count, QChar {' '}};
}
if (space_count > 0) {
message += QString {space_count, QChar {' '}};
}
message += QChar::Nbsp + appendage;
return message;
}
void DisplayText::displayDecodedText(DecodedText const& decodedText, QString const& myCall,
bool displayDXCCEntity, LogBook const& logBook,
QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_NewCall, bool ppfx,
bool bCQonly)
QString currentBand, bool ppfx, bool bCQonly)
{
m_bPrincipalPrefix=ppfx;
QColor bg {Qt::transparent};
@ -251,33 +274,35 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
|| decodedText.string ().contains (" QRZ "))
{
CQcall = true;
bg = color_CQ;
bg = m_color_CQ;
}
if(bCQonly and !CQcall) return;
if (myCall != "" and (
decodedText.indexOf (" " + myCall + " ") >= 0
or decodedText.indexOf (" " + myCall + "/") >= 0
or decodedText.indexOf ("/" + myCall + " ") >= 0
or decodedText.indexOf ("<" + myCall + " ") >= 0
or decodedText.indexOf (" " + myCall + ">") >= 0)) {
bg = color_MyCall;
if (myCall != "" and (decodedText.indexOf (" " + myCall + " ") >= 0
or decodedText.indexOf (" " + myCall + "/") >= 0
or decodedText.indexOf ("<" + myCall + "/") >= 0
or decodedText.indexOf ("/" + myCall + " ") >= 0
or decodedText.indexOf ("/" + myCall + ">") >= 0
or decodedText.indexOf ("<" + myCall + " ") >= 0
or decodedText.indexOf ("<" + myCall + ">") >= 0
or decodedText.indexOf (" " + myCall + ">") >= 0)) {
bg = m_color_MyCall;
}
auto message = decodedText.string ();
auto message = decodedText.string();
QString dxCall;
QString dxGrid;
decodedText.deCallAndGrid (dxCall, dxGrid);
decodedText.deCallAndGrid (/*out*/ dxCall, dxGrid);
QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"};
if(!dxGrid.contains(grid_regexp)) dxGrid="";
message = message.left (message.indexOf (QChar::Nbsp)); // strip appended info
if (displayDXCCEntity && CQcall)
// if enabled add the DXCC entity and B4 status to the end of the
// preformated text line t1
message = appendDXCCWorkedB4 (message, decodedText.CQersCall (), &bg, logBook, color_CQ,
color_DXCC, color_NewCall);
message = appendWorkedB4 (message, decodedText.CQersCall(), dxGrid, &bg, logBook, currentBand);
appendText (message.trimmed (), bg, decodedText.call (), dxCall);
}
void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 txFreq,
QColor color_TxMsg, bool bFastMode)
void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 txFreq,bool bFastMode)
{
QString t1=" @ ";
if(modeTx=="FT8") t1=" ~ ";
@ -297,7 +322,7 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx
t = QDateTime::currentDateTimeUtc().toString("hhmm") + \
" Tx " + t2 + t1 + text;
}
appendText (t, color_TxMsg);
appendText (t, m_color_TxMsg);
}
void DisplayText::displayQSY(QString text)
@ -352,7 +377,8 @@ namespace
}
}
void DisplayText::highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only)
void DisplayText::highlight_callsign (QString const& callsign, QColor const& bg,
QColor const& fg, bool last_only)
{
QTextCharFormat old_format {currentCharFormat ()};
QTextCursor cursor {document ()};
@ -403,3 +429,20 @@ void DisplayText::highlight_callsign (QString const& callsign, QColor const& bg,
}
setCurrentCharFormat (old_format);
}
void DisplayText::setDecodedTextColors(QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_DXCCband,QColor color_NewCall,QColor color_NewCallBand,
QColor color_NewGrid, QColor color_NewGridBand,QColor color_TxMsg,QColor color_LoTW)
{
// Save the color highlighting scheme selected by the user.
m_color_CQ=color_CQ;
m_color_DXCC=color_DXCC;
m_color_DXCCband=color_DXCCband;
m_color_MyCall=color_MyCall;
m_color_NewCall=color_NewCall;
m_color_NewCallBand=color_NewCallBand;
m_color_NewGrid=color_NewGrid;
m_color_NewGridBand=color_NewGridBand;
m_color_TxMsg=color_TxMsg;
m_color_LoTW=color_LoTW;
}

View File

@ -22,13 +22,16 @@ public:
void setContentFont (QFont const&);
void insertLineSpacer(QString const&);
void displayDecodedText(DecodedText const& decodedText, QString const& myCall, bool displayDXCCEntity,
LogBook const& logBook, QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_NewCall, bool ppfx, bool bCQonly=false);
void displayTransmittedText(QString text, QString modeTx, qint32 txFreq,
QColor color_TxMsg, bool bFastMode);
void displayDecodedText(DecodedText const& decodedText, QString const& myCall,
bool displayDXCCEntity, LogBook const& logBook,
QString currentBand="", bool ppfx=false, bool bCQonly=false);
void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, bool bFastMode);
void displayQSY(QString text);
void displayFoxToBeCalled(QString t, QColor bg);
void setDecodedTextColors(QColor color_CQ, QColor color_MyCall, QColor color_DXCC,
QColor color_DXCCband, QColor color_NewCall, QColor color_NewCallBand,
QColor color_NewGrid, QColor color_NewGridBand, QColor color_TxMsg,
QColor color_LoTW);
Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers);
Q_SIGNAL void erased ();
@ -43,12 +46,23 @@ protected:
private:
bool m_bPrincipalPrefix;
QString appendDXCCWorkedB4(QString message, QString const& callsign, QColor * bg, LogBook const& logBook,
QColor color_CQ, QColor color_DXCC, QColor color_NewCall);
QString appendWorkedB4(QString message, QString const& callsign, QString grid, QColor * bg,
LogBook const& logBook, QString currentBand);
QFont char_font_;
QAction * erase_action_;
QHash<QString, QPair<QColor, QColor>> highlighted_calls_;
QColor m_color_CQ;
QColor m_color_MyCall;
QColor m_color_DXCC;
QColor m_color_DXCCband;
QColor m_color_NewCall;
QColor m_color_NewCallBand;
QColor m_color_NewGrid;
QColor m_color_NewGridBand;
QColor m_color_LoTW;
QColor m_color_TxMsg;
};
extern QHash<QString,int> m_LoTW;
#endif // DISPLAYTEXT_H

View File

@ -22,13 +22,9 @@ the *Tx<-Rx* button, and vice-versa for *Rx<-Tx*. The on-the-air
frequency of your lowest JT9 or JT65 tone is the sum of dial frequency
and audio Tx frequency.
* Check the box *Lock Tx=Rx* to make the frequencies always track one
another.
IMPORTANT: In general we do not recommend using *Lock Tx=Rx* since it
encourages poor radio etiquette when running a frequency. With this
box checked, your own Tx frequency will move around following your
callers.
* Check the box *Hold Tx Freq* to ensure that the specified Tx
frequency is not changed automatically when you double-click on
decoded text or a signal in the waterfall.
* For modes lacking a multi-decode feature, or when *Enable
VHF/UHF/Microwave features* has been checked on the *Settings ->

89
lib/77bit/77bit.txt Normal file
View File

@ -0,0 +1,89 @@
Starting with WSJT-X 2.0, the FT8 and MSK144 protocols convey a 77-bit
payload. For most purposes these bits are interpreted as 3 bits (i3)
for message type and 74 for user information. Any message type that
uses fewer than 74 information bits can assign the remaining bits to
define message subtypes. For example, Type i3=0 uses 71 information
bits and the remaining 3 bits, here called n3, define 8 possible
subtypes.
----------------------------------------------------------------------------------
i3.n3 Example message Bits Total Purpose
----------------------------------------------------------------------------------
0.0 FREE TEXT MSG 71 71 Free text
0.1 K1ABC RR73; W9XYZ <KH1/KH7Z> -11 28 28 10 5 71 DXpedition Mode
0.2 PA3XYZ/P R 590003 IO91NP 28 1 1 3 12 25 70 EU VHF contest
0.3 WA9XYZ KA1ABC R 16A EMA 28 28 1 4 3 7 71 ARRL Field Day
0.4 WA9XYZ KA1ABC R 32A EMA 28 28 1 4 3 7 71 ARRL Field Day
0.5 123456789ABCDEF012 71 71 Telemetry (18 hex)
0.6 ... tbd
0.7 ... tbd
1 WA9XYZ/R KA1ABC/R R FN42 28 1 28 1 1 15 74 Standard msg
2 PA3XYZ/P GM4ABC/P R JO22 28 1 28 1 1 15 74 EU VHF contest
3 TU; W9XYZ K1ABC R 579 MA 1 28 28 1 3 13 74 ARRL RTTY Roundup
4 <WA9XYZ> PJ4/KA1ABC RR73 12 58 1 2 1 74 Nonstandard calls
5 ... tbd
6 ... tbd
7 ... tbd
----------------------------------------------------------------------------------
In case we need them, later:
5 TU; W9XYZ K1ABC R 579 8 MA 1 28 28 1 3 6 7 74 CQ WW RTTY
6 TU; W9XYZ K1ABC R 579 MA 1 28 28 1 3 13 74 CQ WPX RTTY
----------------------------------------------------------------------------------
NB: three 74-bit message types and two 71-bit message subtypes are still TBD.
----------------------------------------------------------------------------------
The 28-bit fields normally used for callsigns are configured rather
differently from before.
Facts about the 28-bit integers used to encode standard callsigns:
2^28 = 268,435,456 Available values
37*36*10*27*27*27 = 262,177,560 Used for standard callsigns
-----------
6,257,896 Difference
2^22 = 4,194,304 Used for 22-bit hash codes
-----------
2,063,592 available for CQ, CQ nnn, CQ xxxx, QRZ, ...
Further details on message types:
-----------------------------------------------------------------------------
i3.n3
-----------------------------------------------------------------------------
0.0 Free text, up to 13 characters.
0.1 DXpedition mode, as developed for KH1/KH7Z.
0.2 Report, QSO serial number from 0001 to 4095, 6-character grid, and Roger
for EU VHF contests.
0.3 ARRL Field Day exchange (1-16 transmitters).
0.4 ARRL Field Day exchange (17-32 transmitters).
0.5 Telemetry, 71 bits
1. Two callsigns, Roger, and grid or report. Each callsign may have
an appended "/R" to indicate Rover status for NA VHF contests.
Either callsign may be nonstandard if enclosed in angle brackets,
for example <YW18FIFA>.
2. Same as Type 1, but uses /P instead of /R. For European VHF contests.
3. Standard message for ARRL RTTY Roundup. Optional "TU;" at
beginning to finish a previous QSO; then two standard callsigns,
optional "R", a 3-bit report (529 to 599), and 13 bits to indicate
US state, Canadian province/territory, or DX serial number from
0001 to 7999.
4. One hashed call or "CQ"; one compound or nonstandard call with up
to 11 characters; and (if not "CQ") an optional RRR, RR73, or 73.
---------------------------------------------------------------------------
The following are tentative and not included in first release.
5. CQ WW RTTY - US/Can: RST CQZ state/prov R 579 5 NJ R1 r3 z6 u7
DX: RST + CQzone R 559 15 R1 r3 z6
6. CQ WPX RTTY - RST + serial R 589 0013 R1 r3 n12

12
lib/77bit/CQ_messages.txt Normal file
View File

@ -0,0 +1,12 @@
CQ K1ABC FN42
DE K1ABC FN42
QRZ K1ABC FN42
CQ AA K1ABC FN42
CQ ZZ K1ABC FN42
CQ 000 K1ABC FN42
CQ 313 K1ABC FN42
CQ 999 K1ABC FN42
CQ AAA K1ABC FN42
CQ ZZZ K1ABC FN42
CQ AAAA K1ABC FN42
CQ ZZZZ K1ABC FN42

49
lib/77bit/NewCode.txt Normal file
View File

@ -0,0 +1,49 @@
i3 n3 isync Operating activity, Message Type
-----------------------------------------------------------
0 0 1 Std QSO msg (bit 72=0)
0 0 1 Free text (bit 72=1)
0 1 1 Fox DXpedition msg with "RR73;"
-----------------------------------------------------------
1 0 2 Std QSO msg
0 1 2 Fox DXpedition msg with "RR73;"
1 * 2 NA VHF contest
2 * 2 EU VHF contest (Tx1, Tx6)
0 2 2 EU VHF contest (Tx2, Tx3)
0 3 2 ARRL Field Day (1-16 transmitters)
0 4 2 ARRL Field Day (17-32 transmitters)
3 * 2 ARRL RTTY Roundup
4 * 2 Compound and non-standard calls
-----------------------------------------------------------
* ==> "don't care" (types i3=1,2,3,4 do not have subtypes)
-----------------------------------------------------------
A. Required GUI Additions (after July 3):
1. Entry widgets for fixed parts of contest exchanges: comboBoxes
for ARRL section, US State/Canadian Province, number of
transmitters and entry Class for Field Day.
2. Spinner control for serial numbers: used for EU_VHF_Contest,
and for DX stations in RTTYroundup.
B. Code near the end of GenStdMsgs():
1. if(m_config.bNA_VHF_Contest()): do as with present checkbox
2. if(m_config.bEU_VHF_Contest()): make EU_VHF messages
3. if(m_config.bFieldDay()): make FD messages
4. if(m_config.bRTTYroundup()): make RR messages
5. if MyCall or DXcall is compound or nonstandard, make new msgs
C. Code just before calling genft8_():
1. m_i3=0, m_n3=0, m_isync=1
2. if(check m_config.bGenerate77()) m_isync=2
3. if msg is not an old-style standard msg, see if it's valid
as a 77-bit msg
4. if NO: transmit as Free Text
if YES: set i3, n3, and isync=2
D. Auto-sequencer code
1. Probably lots of changes needed: details TBD, after we make the
new messages work with Auto-Seq off.

View File

@ -0,0 +1,261 @@
New Features in WSJT-X 2.0
September 17, 2018
--------------------------
This document is an update to the white paper "Plans for WSJT-X
Version 2.0" that was publicly distributed on July 26, 2018. It
describes the most important enhancements in WSJT-X 2.0 relative to
version 1.9.1.
A majority of new program features involve the FT8 and MSK144
protocols. Both modes have been upgraded to use use 77-bit
information payloads rather than the 75 bits of the older FT8 protocol
or 72 bits of JT4, JT9, JT65, MSK144, and QRA64. Cyclic redundancy
checks (CRCs) that protect against false decodes have been increased
from 12 to 14 bits (FT8) and from 8 to 13 bits (MSK144). These
changes bring many benefits, including support of structured messages
optimized for the following special types of QSOs and exchanged
information:
1. NA VHF Contest operation with full and transparent support of grid
locators and "/R" (Rover) callsigns
2. EU VHF Contest operation with the exchange of 6-digit locators, QSO
serial numbers, and "/P" (portable) callsigns
3. ARRL Field Day operation with standard Field Day exchanges such as
"6A SNJ"
4. ARRL RTTY Roundup operation with standard contest exchanges such as
"579 NJ" or "559 0071"
5. Compound and nonstandard callsigns (up tp 11 characters); no need
for distinctions about "Type 1" or "Type 2" prefixes/suffixes
6. A special "telemetry" message format for exchange of arbitrary
information up to 71 bits
7. All features of FT8 DXpedition mode, as in WSJT-X v1.9.1
Enhancements to the FT8 decoder ensure that in most situations
decoding sensitivity is slightly better than for the old protocol.
Symbol rates and occupied bandwidths are the same as before, and
false-decode rates are significantly lower. The decoding threshold
for MSK144 is a fraction of a dB higher than before, owing to the
slightly larger message payload and higher code rate.
OTHER PROGRAM ENHANCEMENTS: WSJT-X 2.0 has several other new features
and capabilities. The WSPR decoder has significantly better
sensitivity, by about 1 dB. Color highlighting of decoded messages
provides worked-before status for callsigns, grid locators, and DXCC
entities on a "by band" basis. Color highlighting can also identify
stations that have (or have not) uploaded their logs to "Logbook of
the World" (LoTW) within the past year. (Recent information from LoTW
for this purpose can be downloaded from the ARRL web site.)
WSJT-X 2.0 introduces no significant changes to any of the modes JT4,
JT9, JT65, QRA64, ISCAT, Echo, or FreqCal.
IMPORTANT: For the convenience of beta-testers, the first and second
release candidates -- releases with "-rc1" or "-rc2" in their names --
will have Rx and Tx capability for both the new FT8 protocol and the
older one. Starting with the third release candidate ("-rc3"), and in
the general-availability full release of WSJT-X 2.0, only the new
protocol will be supported. In contrast, the new MSK144 protocol
replaces the old one from the outset, without backward compatibility.
To minimize on-the-air confusion, it's important that users be aware
of these distinctions and the schedule for release of WSJT-X 2.0, as
detailed below.
MESSAGE FORMATS: The following table shows examples of message formats
supported by the new FT8 and MSK144 protocols. Parameters i3 and n3
(shown in the first column) are used in the software to define major
and minor 77-bit message types.
----------------------------------------------------------------------------------
i3.n3 Example Messages Comments
----------------------------------------------------------------------------------
0.0 TNX BOB 73 GL Free text
0.1 K1ABC RR73; W9XYZ <KH1/KH7Z> -08 DXpedition Mode
0.2 PA9XYZ 590003 IO91NP EU VHF Contest
0.2 G4ABC/P R 570007 JO22DB EU VHF Contest
0.3 K1ABC W9XYZ 6A WI ARRL Field Day
0.3 W9XYZ K1ABC R 2B EMA ARRL Field Day
0.5 123456789ABCDEF012 Telemetry (71 bits, 18 hex digits)
1. CQ FD K1ABC FN42 ARRL Field Day
1. CQ RU K1ABC FN42 ARRL RTTY Roundup
1. CQ K1ABC FN42
1. CQ TEST K1ABC FN42 NA VHF Contest
1. CQ TEST K1ABC/R FN42 NA VHF Contest
1. K1ABC W9XYZ EN37
1. K1ABC W9XYZ -09
1. K1ABC W9XYZ R-17
1. K1ABC W9XYZ RRR
1. K1ABC W9XYZ 73
1. K1ABC W9XYZ RR73
1. K1ABC/R W9XYZ EN37 NA VHF Contest
1. K1ABC W9XYZ/R RR73 NA VHF Contest
1. K1ABC/R W9XYZ/R RR73 NA VHF Contest
1. <PJ4/K1ABC> W9XYZ Compound call
1. W9XYZ <PJ4/K1ABC> 73 Compound call
1. W9XYZ <YW18FIFA> -13 Nonstandard call
1. <YW18FIFA> W9XYZ R+02 Nonstandard call
1. W9XYZ <YW18FIFA> RRR Nonstandard call
1. <YW18FIFA> W9XYZ RR73 Nonstandard call
2. CQ G4ABC/P IO91 EU VHF contest
2. G4ABC/P PA9XYZ JO22 EU VHF contest
2. PA9XYZ G4ABC/P RR73 EU VHF contest
3. K1ABC KA0DEF 559 MO ARRL RTTY Roundup
3. K1ABC W9XYZ 579 WI ARRL RTTY Roundup
3. KA1ABC G3AAA 529 0013 ARRL RTTY Roundup
3. TU; KA0DEF K1ABC R 569 MA ARRL RTTY Roundup
3. TU; K1ABC G3AAA R 559 0194 ARRL RTTY Roundup
3. W9XYZ K1ABC R 589 MA ARRL RTTY Roundup
4. CQ PJ4/K1ABC
4. CQ YW18FIFA Nonstandard call
4. <KA1ABC> YW18FIFA RR73 Nonstandard call
4. <W9XYZ> PJ4/K1ABC RRR Nonstandard call
4. <W9XYZ> YW18FIFA Nonstandard call
4. <W9XYZ> YW18FIFA 73 Nonstandard call
4. PJ4/K1ABC <W9XYZ> Nonstandard call
4. PJ4/K1ABC <W9XYZ> 73 Nonstandard call
4. YW18FIFA <W9XYZ> RRR Nonstandard call
----------------------------------------------------------------------------------
In the above list, callsigns enclosed in angle brackets (e.g.,
<PJ4/K1ABC>, <YW18FIFA>) are transmitted as hash codes. They will be
displayed correctly by receiving stations that have copied the full
callsign without brackets in a previous transmissiion. Otherwise the
receiving software will display <...>. Hash collisions are possible
but should be rare, and extremely rare within a particular QSO.
Some minimal message sequences that take advantage of the new 77-bit
formats are illustrated below. Model QSOs 1 and 2 are the same as
those used by the old FT8 and MSK144 protocols, and QSO number 3 is
the same as the existing FT8 DXpedition Mode. Model QSOs 4 through 9
were not possible with the old protocols.
----------------------------------------------------------------------------------
1. Standard QSO
----------------------------------------------------------------------------------
CQ K1ABC FN42
K1ABC W9XYZ EN37
W9XYZ K1ABC -11
K1ABC W9XYZ R-09
W9XYZ K1ABC RRR
K1ABC W9XYZ 73
----------------------------------------------------------------------------------
2. Short-cycle QSO
----------------------------------------------------------------------------------
CQ K1ABC FN42
K1ABC W9XYZ -09
W9XYZ K1ABC R-11
K1ABC W9XYZ RR73
W9XYZ K1ABC 73
----------------------------------------------------------------------------------
3. FT8 DXpedition Mode
----------------------------------------------------------------------------------
CQ KH1/KH7Z
KH7Z K1ABC FN42
K1ABC KH7Z -12
KH7Z K1ABC R-14
KH7Z W9XYZ EN37
... possibly other callers ...
K1ABC RR73; W9XYZ <KH1/KH7Z> -08
----------------------------------------------------------------------------------
4. ARRL Field Day
----------------------------------------------------------------------------------
CQ FD K1ABC FN42
K1ABC W9XYZ 6A WI
W9XYZ K1ABC R 2B EMA
K1ABC W9XYZ RR73
----------------------------------------------------------------------------------
5. ARRL VHF Contests
----------------------------------------------------------------------------------
CQ TEST K1ABC/R FN42 "/R" is optional
K1ABC/R W9XYZ EN37 on either callsign
W9XYZ K1ABC/R R FN42
K1ABC/R W9XYZ RR73
----------------------------------------------------------------------------------
6. ARRL RTTY Roundup
----------------------------------------------------------------------------------
CQ TEST K1ABC FN42
K1ABC W9XYZ 579 WI
W9XYZ K1ABC R 589 MA
K1ABC KA0DEF 559 MO
TU; KA0DEF K1ABC R 569 MA
KA1ABC G3AAA 529 0013
TU; G3AAA K1ABC R 559 MA
----------------------------------------------------------------------------------
7. EU VHF Contest
----------------------------------------------------------------------------------
CQ TEST G4ABC/P IO91 "/P" is optional
G4ABC/P PA9XYZ JO22 on either callsign
PA9XYZ 590003 IO91NP
G4ABC/P R 570007 JO22DB
PA9XYZ G4ABC/P RR73
----------------------------------------------------------------------------------
8. Compound or nonstandard callsign calling CQ
----------------------------------------------------------------------------------
CQ PJ4/K1ABC
PJ4/K1ABC <W9XYZ>
W9XYZ <PJ4/K1ABC> -11
<PJ4/K1ABC> W9XYZ R-09
<W9XYZ> PJ4/K1ABC RRR
PJ4/K1ABC <W9XYZ> 73
----------------------------------------------------------------------------------
9. Compound or nonstandard callsign answering CQ
----------------------------------------------------------------------------------
CQ W9XYZ EN37
<W9XYZ> YW18FIFA
<YW18FIFA> W9XYZ -11
W9XYZ <YW18FIFA> R-09
YW18FIFA <W9XYZ> RRR
<W9XYZ> YW18FIFA 73
----------------------------------------------------------------------------------
RELEASE SCHEDULE: Candidate releases of WSJT-X 2.0 will have built-in
expiration dates after which they cannot be used. Target dates for
planned releases are as follows:
September 17: -rc1 (expires Oct 31)
October 15: -rc2 (expires Nov 30)
November 12: -rc3 (expires Dec 31)
December 10: GA Full release of WSJT-X 2.0
WSJT-X 2.0-rc1 provides the first chance for beta testers to use the
new 77-bit messages. It supports the old (v1.9.1) FT8 protocol as
well as the new message types illustrated above. To avoid QRMing
legacy FT8 users with incompatible messages they can't decode, and to
help concentrate testing activity into a few sub-bands, we recommend
using the new FT8 capabilities on the 40- or 20-meter bands at dial
frequencies 7.078 or 14.078 MHz. These frequencies are offered as FT8
alternatives on the drop-down frequency-selection control on the main
window.
The new MSK144 is fully functional for QSOs between any two stations
using a WSJT-X v2.0 release. MSK144 is not backward compatible with
earlier program versions. Therefore during the testing period,
approximately Sept 17 through December 10, we recommend using the new
MSK144 capabilities on 50.380 MHz (IARU Region 1) or 50.280 (Regions 2
and 3). By specific arrangement, or as soon as most regular users
have upgraded to a v2.0 release, MSK144 activity can be moved back to
50.360 (Region 1) or 50.260 (Regions 2 and 3).
By design, our proposed release schedule will make WSJT-X 2.0 usable
for all relevant ARRL operating events and Eurpoean VHF contests after
January 1, 2019.
Dates of relevant upcoming ARRL contests
----------------------------------------
RTTY Roundup: January 5-6, 2019
VHF Sweepstakes: January 19-21, 2019

40
lib/77bit/all28.txt Normal file
View File

@ -0,0 +1,40 @@
<KH1/KH7Z>
<VP2E/KA1ABC>
5B1ABC
999ABC
9Y4AB
9Y4XYZ
A00A
A0A
A0AA
A0AAA
A0AAB
AA0AAA
CQ
CQ_000
CQ_313
CQ_999
CQ_A
CQ_AAAA
CQ_AB
CQ_ABC
CQ_ABCD
CQ_DX
CQ_ZZZZ
DE
EI30T
HA70BAY
HB9GOLD
K1ABC
K1JT
KA0ABC
KA1ABC
KA1JT
KH1/KH7Z
QRZ
W2000XYZ
WB9XYZ
YB50ST
YW18FIFA
ZM90DX
ZS9YOTA

83
lib/77bit/arrl_sec.txt Normal file
View File

@ -0,0 +1,83 @@
AB
AK
AL
AR
AZ
BC
CO
CT
DE
EB
EMA
ENY
EPA
EWA
GA
GTA
IA
ID
IL
IN
KS
KY
LA
LAX
MAR
MB
MDC
ME
MI
MN
MO
MS
MT
NC
ND
NE
NFL
NH
NL
NLI
NM
NNJ
NNY
NT
NTX
NV
OH
OK
ONE
ONN
ONS
OR
ORG
PAC
PR
QC
RI
SB
SC
SCV
SD
SDG
SF
SFL
SJV
SK
SNJ
STX
SV
TN
UT
VA
VI
VT
WCF
WI
WMA
WNY
WPA
WTX
WV
WWA
WY

5
lib/77bit/calls.txt Normal file
View File

@ -0,0 +1,5 @@
KA1ABC
WB9XYZ
KH1/KH7Z
<KH1/KH7Z>
CQ DX K1ABC

21
lib/77bit/calls1.txt Normal file
View File

@ -0,0 +1,21 @@
<KH1/KH7Z>
<VP2E/KA1ABC>
K1ABC
WB9XYZ
KA1ABC
WB9XYZ
K1JT
KA1JT
5B1ABC
9Y4XYZ
9Y4AB
999ABC
ZM90DX
EI30T
ZS9YOTA
HA70BAY
HB9GOLD
YW18FIFA
YB50ST
WB2000XYZ
WB2000XYZABCD

7
lib/77bit/calls2.txt Normal file
View File

@ -0,0 +1,7 @@
A0A
A00A
A0AA
A0AAA
KA0ABC
5B1ABC
9Y4XYZ

4
lib/77bit/calls3.txt Normal file
View File

@ -0,0 +1,4 @@
AA0AAA
A0AAA
A0AAB
A0AA

48
lib/77bit/encode77.f90 Normal file
View File

@ -0,0 +1,48 @@
program encode77
use packjt77
character*80 msg0
character msg*37,cerr*1
character*77 c77
character*80 infile
nargs=iargc()
if(nargs.ne.1 .and.nargs.ne.2) then
print*,'Usage: encode77 "message"'
print*,' encode77 -f <infile>'
go to 999
endif
call getarg(1,msg0)
if(nargs.eq.2) then
call getarg(2,infile)
open(10,file=infile,status='old')
write(*,1000)
1000 format('i3.n3 Err Message to be encoded Decoded message' &
/80('-'))
endif
do iline=1,999
if(nargs.eq.2) read(10,1002,end=999) msg0
1002 format(a80)
if(msg0(1:1).eq.'$') exit
if(msg0.eq.' ') cycle
if(msg0(2:2).eq.'.' .or. msg0(3:3).eq.'.') cycle
if(msg0(1:3).eq.'---') cycle
msg0=adjustl(msg0)
i3=-1
n3=-1
call pack77(msg0(1:37),i3,n3,c77)
call unpack77(c77,msg)
cerr=' '
if(msg.ne.msg0(1:37)) cerr='*'
if(i3.eq.0) write(*,1004) i3,n3,cerr,msg0(1:37),msg
1004 format(i2,'.',i1,2x,a1,3x,a37,1x,a37)
if(i3.ge.1) write(*,1005) i3,cerr,msg0(1:37),msg
1005 format(i2,'.',3x,a1,3x,a37,1x,a37)
if(nargs.eq.1) exit
enddo
999 end program encode77
include '../chkcall.f90'

41
lib/77bit/encode77.out Normal file
View File

@ -0,0 +1,41 @@
i3.n3 Err Message to be encoded Decoded message
--------------------------------------------------------------------------------
1. CQ K1ABC FN42 CQ K1ABC FN42
1. K1ABC W9XYZ EN37 K1ABC W9XYZ EN37
1. W9XYZ K1ABC -11 W9XYZ K1ABC -11
1. K1ABC W9XYZ R-09 K1ABC W9XYZ R-09
1. W9XYZ K1ABC RRR W9XYZ K1ABC RRR
1. K1ABC W9XYZ 73 K1ABC W9XYZ 73
1. CQ K1ABC FN42 CQ K1ABC FN42
1. K1ABC W9XYZ -09 K1ABC W9XYZ -09
1. W9XYZ K1ABC R-11 W9XYZ K1ABC R-11
1. K1ABC W9XYZ RR73 K1ABC W9XYZ RR73
1. W9XYZ K1ABC 73 W9XYZ K1ABC 73
4. CQ KH1/KH7Z CQ KH1/KH7Z
1. KH7Z K1ABC FN42 KH7Z K1ABC FN42
1. K1ABC KH7Z -12 K1ABC KH7Z -12
1. KH7Z K1ABC R-14 KH7Z K1ABC R-14
0.1 K1ABC RR73; W9XYZ <KH1/KH7Z> -08 K1ABC RR73; W9XYZ <KH1/KH7Z> -08
1. CQ FD K1ABC FN42 CQ FD K1ABC FN42
0.3 K1ABC W9XYZ 6A WI K1ABC W9XYZ 6A WI
0.3 W9XYZ K1ABC R 2B EMA W9XYZ K1ABC R 2B EMA
1. K1ABC W9XYZ RR73 K1ABC W9XYZ RR73
1. CQ TEST K1ABC/R FN42 CQ TEST K1ABC/R FN42
1. K1ABC/R W9XYZ EN37 K1ABC/R W9XYZ EN37
1. W9XYZ K1ABC/R R FN42 W9XYZ K1ABC/R R FN42
1. K1ABC/R W9XYZ RR73 K1ABC/R W9XYZ RR73
1. CQ TEST K1ABC FN42 CQ TEST K1ABC FN42
3. K1ABC W9XYZ 579 WI K1ABC W9XYZ 579 WI
3. W9XYZ K1ABC R 589 MA W9XYZ K1ABC R 589 MA
1. K1ABC W9XYZ RR73 K1ABC W9XYZ RR73
2. CQ G4ABC/P IO91 CQ G4ABC/P IO91
2. G4ABC/P PA9XYZ JO22 G4ABC/P PA9XYZ JO22
0.2 PA9XYZ 590003 IO91NP PA9XYZ 590003 IO91NP
0.2 G4ABC/P R 570007 JO22DB G4ABC/P R 570007 JO22DB
2. PA9XYZ G4ABC/P RR73 PA9XYZ G4ABC/P RR73
4. CQ PJ4/K1ABC CQ PJ4/K1ABC
4. <PJ4/K1ABC> W9XYZ <PJ4/K1ABC> W9XYZ
1. W9XYZ K1ABC -11 W9XYZ K1ABC -11
1. K1ABC W9XYZ R-09 K1ABC W9XYZ R-09
4. W9XYZ <PJ4/K1ABC> RRR W9XYZ <PJ4/K1ABC> RRR
4. <PJ4/K1ABC> W9XYZ 73 <PJ4/K1ABC> W9XYZ 73

6
lib/77bit/g2 Normal file
View File

@ -0,0 +1,6 @@
gfortran -c ../packjt.f90
gfortran -c packjt77.f90
gfortran -o encode77 -fbounds-check -Wall -Wno-conversion -Wno-real-q-constant \
encode77.f90 ../deg2grid.f90 ../grid2deg.f90 ../fix_contest_msg.f90 \
../to_contest_msg.f90 ../fmtmsg.f90 ../azdist.f90 ../geodist.f90 \
packjt.o packjt77.o

4
lib/77bit/g5 Normal file
View File

@ -0,0 +1,4 @@
gfortran -c -O2 ../packjt.f90
gfortran -o t5 -O2 t5.f90 ../deg2grid.f90 ../grid2deg.f90 \
../fix_contest_msg.f90 ../to_contest_msg.f90 ../fmtmsg.f90 \
../azdist.f90 ../geodist.f90 packjt.o

2
lib/77bit/g8 Normal file
View File

@ -0,0 +1,2 @@
gfortran -o test28 -fbounds-check -Wall -Wno-conversion test28.f90 pack28.f90 \
unpack28.f90 ihashcall.f90 hash22.f90 save_hash_call.f90

84
lib/77bit/messages.txt Normal file
View File

@ -0,0 +1,84 @@
1. Standard QSO
-----------------------------------------------------------
CQ K1ABC FN42
K1ABC W9XYZ EN37
W9XYZ K1ABC -11
K1ABC W9XYZ R-09
W9XYZ K1ABC RRR
K1ABC W9XYZ 73
2. Short-cycle QSO
-----------------------------------------------------------
CQ K1ABC FN42
K1ABC W9XYZ -09
W9XYZ K1ABC R-11
K1ABC W9XYZ RR73
W9XYZ K1ABC 73
3. FT8 DXpedition Mode
-----------------------------------------------------------
CQ KH1/KH7Z
KH7Z K1ABC FN42
K1ABC KH7Z -12
KH7Z K1ABC R-14
K1ABC RR73; W9XYZ <KH1/KH7Z> -08
4. ARRL Field Day
-----------------------------------------------------------
CQ FD K1ABC FN42
K1ABC W9XYZ 6A WI
W9XYZ K1ABC R 2B EMA
K1ABC W9XYZ RR73
5. ARRL VHF Contests
-----------------------------------------------------------
CQ TEST K1ABC/R FN42
K1ABC/R W9XYZ EN37
W9XYZ K1ABC/R R FN42
K1ABC/R W9XYZ RR73
6. ARRL RTTY Contest
-----------------------------------------------------------
CQ TEST K1ABC FN42
K1ABC W9XYZ 579 WI
W9XYZ K1ABC R 589 MA
K1ABC KA0DEF 559 MO
TU; KA0DEF K1ABC R 569 MA
KA1ABC G3AAA 529 0013
TU; G3AAA K1ABC R 559 MA
7. EU VHF Contest
-----------------------------------------------------------
CQ G4ABC/P IO91
G4ABC/P PA9XYZ JO22
PA9XYZ 590003 IO91NP
G4ABC/P R 570007 JO22DB
PA9XYZ G4ABC/P RR73
8. Compound or nonstandard calls CQ
-----------------------------------------------------------
CQ PJ4/K1ABC
PJ4/K1ABC <W9XYZ>
W9XYZ <PJ4/K1ABC> -11
<PJ4/K1ABC> W9XYZ R-09
<W9XYZ> PJ4/K1ABC RRR
PJ4/K1ABC <W9XYZ> 73
9. Compound or nonstandard answers CQ
-----------------------------------------------------------
CQ W9XYZ EN37
<W9XYZ> YW18FIFA
<YW18FIFA> W9XYZ -11
W9XYZ <YW18FIFA> R-09
YW18FIFA <W9XYZ> RRR
<W9XYZ> YW18FIFA 73
10. Other stuff
-----------------------------------------------------------
TNX BOB 73 GL
CQ YW18FIFA
<YW18FIFA> KA1ABC
KA1ABC <YW18FIFA> -11
<YW18FIFA> KA1ABC R-17
<KA1ABC> YW18FIFA RR73
<YW18FIFA> KA1ABC 73
123456789ABCDEF012

49
lib/77bit/messages_2.txt Normal file
View File

@ -0,0 +1,49 @@
FREE TEXT MSG 71 0 71
CQ YW18FIFA
K1ABC RR73; W9XYZ <KH1/KH7Z> -12 28 28 10 5 1 71 DXpedition Mode
PA3XYZ/P R 590003 IO91NP 28 1 1 3 12 25 2 70 EU VHF contest (2)
PA3XYZ 520093 IO91NP 28 1 1 3 12 25 2 70 EU VHF contest (2)
WA9XYZ KA1ABC R 16A EMA 28 28 1 4 3 7 3 71 ARRL Field Day
WA9XYZ KA1ABC 7D EMA 28 28 1 4 3 7 3 71 ARRL Field Day
WA9XYZ G8ABC 1D DX 28 28 1 4 3 7 3 71 ARRL Field Day
WA9XYZ KA1ABC R 32A EMA 28 28 1 4 3 7 4 71 ARRL Field Day
123456789ABCDEF012 71 71 Telemetry (18 hex)
71234567 71 71 Telemetry (18 hex)
81234567 71 71 Telemetry (18 hex)
7123456789ABCDEF01 71 71 Telemetry (18 hex)
8123456789ABCDEF01 71 71 Telemetry (18 hex)
WA9XYZ/R KA1ABC/R R FN42 28 1 28 1 1 15 74 Standard msg
WA9XYZ KA1ABC R-19 28 1 28 1 1 15 74 Standard msg
WA9XYZ KA1ABC +03 28 1 28 1 1 15 74 Standard msg
WA9XYZ KA1ABC -30 28 1 28 1 1 15 74 Standard msg
WA9XYZ KA1ABC +30 28 1 28 1 1 15 74 Standard msg
CQ K1ABC FN42
DE K1ABC FN42
QRZ K1ABC FN42
CQ AA K1ABC FN42
CQ ZZ K1ABC FN42
CQ 000 K1ABC FN42
CQ 313 K1ABC FN42
CQ 999 K1ABC FN42
CQ AAA K1ABC FN42
CQ ZZZ K1ABC FN42
CQ AAAA K1ABC FN42
CQ ZZZZ K1ABC FN42
CQ KH1/KH7Z
CQ YW18FIFA
CQ W4/YW18FIFA
PA1XYZ/P GM4ABC/P R FN42 28 1 28 1 1 15 74 EU VHF Contest
TU; W9XYZ K1ABC R 579 MA 1 28 28 1 3 13 74 ARRL RTTY contest
TU; W9XYZ G8ABC R 559 0013 1 28 28 1 3 13 74 ARRL RTTY (DX)
W9XYZ K1ABC 519 MA 1 28 28 1 3 13 74 ARRL RTTY contest
W9XYZ K1ABC 529 MA 1 28 28 1 3 13 74 ARRL RTTY contest
W9XYZ K1ABC 599 MA 1 28 28 1 3 13 74 ARRL RTTY contest
W9XYZ K1ABC 599 SNJ 1 28 28 1 3 13 74 ARRL RTTY contest
W9XYZ G8ABC 529 0013 1 28 28 1 3 13 74 ARRL RTTY (DX)
W9XYZ G8ABC 599 0013 1 28 28 1 3 13 74 ARRL RTTY (DX)
<WA9XYZ> PJ4/KA1ABC 13 58 1 2 74 Nonstandard call
PJ4/KA1ABC <WA9XYZ> RRR 13 58 1 2 74 Nonstandard call
<WA9XYZ> PJ4/KA1ABC RR73 13 58 1 2 74 Nonstandard call
PJ4/KA1ABC <WA9XYZ> 73 13 58 1 2 74 Nonstandard call
<WA9XYZ> PJ4/KA1ABC 73 13 58 1 2 74 Nonstandard call
CQ 313 YW18FIFA

23
lib/77bit/msgtypes.txt Normal file
View File

@ -0,0 +1,23 @@
i3 n3 Bits Total Message type
---------------------------------------------------------------------------------------
0 0 FREE TEXT MSG 71 71
0 1 K1ABC RR73; W9XYZ <KH1/KH7Z> -12 28 28 10 5 71 DXpedition Mode
0 2 PA3XYZ/P R 590003 IO91NP 28 1 1 3 12 25 70 EU VHF contest (2)
0 2 PA3XYZ 520093 IO91NP 28 1 1 3 12 25 70 EU VHF contest (2)
0 3 WA9XYZ KA1ABC R 16A EMA 28 28 1 4 3 7 71 ARRL Field Day
0 3 WA9XYZ KA1ABC 7D EMA 28 28 1 4 3 7 71 ARRL Field Day
0 3 WA9XYZ G8ABC 1D DX 28 28 1 4 3 7 71 ARRL Field Day
0 4 WA9XYZ KA1ABC R 32A EMA 28 28 1 4 3 7 71 ARRL Field Day
0 5 123456789ABCDEF012 71 71 Telemetry (18 hex)
0 5 7123456789ABCDEF01 71 71 Telemetry (18 hex)
0 5 71234567 71 71 Telemetry (18 hex)
0 5 81234567 71 71 Telemetry (18 hex)
0 5 8123456789ABCDEF01 71 71 Telemetry (18 hex)
1 WA9XYZ/R KA1ABC/R R FN42 28 1 28 1 1 15 74 Standard msg
1 WA9XYZ KA1ABC R-11 28 1 28 1 1 15 74 Standard msg
2 PA1XYZ/P GM4ABC/P R FN42 28 1 28 1 1 15 74 EU VHF Contest
3 TU; W9XYZ K1ABC R 579 MA 1 28 28 1 3 13 74 ARRL RTTY contest
3 TU; W9XYZ G8ABC R 559 0013 1 28 28 1 3 13 74 ARRL RTTY (DX)
4 <WA9XYZ> PJ4/KA1ABC RR73 13 58 1 2 74 Nonstandard call
4 <WA9XYZ> PJ4/KA1ABC 13 58 1 2 74 Nonstandard call
4 PJ4/KA1ABC <WA9XYZ> RRR 13 58 1 2 74 Nonstandard call

23
lib/77bit/msgtypes.txt.0 Normal file
View File

@ -0,0 +1,23 @@
i3 n3
--------------------------------------------------------------------------------------
0 0 FREE TEXT MSG 71 0 71
0 1 K1ABC RR73; W9XYZ <KH1/KH7Z> -11 28 28 10 5 1 71 DXpedition Mode
0 2 PA3XYZ/P R 590003 IO91NP 28 1 1 3 12 25 2 70 EU VHF contest (2)
0 3 WA9XYZ KA1ABC R 16A EMA 28 28 1 4 3 7 3 71 ARRL Field Day
0 4 WA9XYZ KA1ABC R 32A EMA 28 28 1 4 3 7 4 71 ARRL Field Day
1 WA9XYZ/R KA1ABC/R R FN42 28 1 28 1 1 15 74 Standard msg
2 TU; W9XYZ K1ABC R 579 MA 1 28 28 1 3 13 74 ARRL RTTY contest
3 <WA9XYZ> PJ4/KA1ABC R-11 13 53 1 1 6 74 Nonstandard calls
4 PA3XYZ/P GM4ABC/P R IO91 28 1 28 1 1 15 74 EU VHF contest
0 0 HELLO WORLD 1
0 0 hello world 2
0 1 K1ABC RR73; W9XYZ <VP2E/KA1ABC> -11
0 2 PA3XYZ 590003 IO91NP
0 3 WA9XYZ KA1ABC 16A EMA
0 4 WA9XYZ KA1ABC 32A EMA
1 WA9XYZ/R KA1ABC/R R FN42
2 W9XYZ K1ABC 579 MA
3 PJ4/KA1ABC <WA9XYZ> -11
4 PA3XYZ/P GM4ABC/P R IO91

11
lib/77bit/my_hash.f90 Normal file
View File

@ -0,0 +1,11 @@
subroutine my_hash(mycall)
use packjt77
character*(*) mycall
character*13 c13
c13=mycall//' '
call save_hash_call(c13,n10,n12,n22)
return
end subroutine my_hash

1142
lib/77bit/packjt77.f90 Normal file

File diff suppressed because it is too large Load Diff

8
lib/77bit/parse77.f90 Normal file
View File

@ -0,0 +1,8 @@
subroutine parse77(msg,i3,n3)
use packjt77
character msg*37,c77*77
call pack77(msg,i3,n3,c77)
return
end subroutine parse77

54
lib/77bit/t1.f90 Normal file
View File

@ -0,0 +1,54 @@
program t1
real x(13)
real(KIND=16) :: dlong,dlong0
character wd*13,w*13,error*5
character c*44 !NB: 44^13 = 2^(70.973)
data c/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?@$'/
nargs=iargc()
if(nargs.ne.1) then
print*,'Usage: t1 "FreeText13"'
print*,' t1 <iters>'
go to 999
endif
call getarg(1,w)
iters=1
read(w,*,err=10) iters
10 continue
do iter=1,iters
if(iters.gt.1) then
! Create a random free-text word
call random_number(x)
do i=1,13
j=44*x(i) + 1
w(i:i)=c(j:j)
enddo
endif
! Encode a 13-character free-text message into a 71-bit integer.
dlong=0.d0
do i=1,13
n=index(c,w(i:i))-1
dlong=44.d0*dlong + n
enddo
dlong0=dlong
! Decode a a 71-bit integer into a 13-character free-text message.
do i=13,1,-1
j=mod(dlong,44.d0)+1.d0
wd(i:i)=c(j:j)
dlong=dlong/44.d0
enddo
error=' '
if(wd.ne.w) then
error='ERROR'
write(*,1010) w,dlong0,wd,error
1010 format('"',a13,'"',f25.1,2x,'"',a13'"',2x,a5)
endif
if(mod(iter,1000).eq.0) print*,iter
enddo
999 end program t1

25
lib/77bit/t3.f90 Normal file
View File

@ -0,0 +1,25 @@
program t3
character*3 csec
character*70 line
logical eof
eof=.false.
j=1
do i=1,83
read(*,1001,end=1) csec
1001 format(a3)
go to 2
1 eof=.true.
2 line(j:j+5)='"'//csec//'",'
j=j+6
if(j.gt.60 .or. i.eq.83 .or.eof) then
line(j:j+2)=' &'
line(j+3:)=' '
write(*,1010) line
1010 format(a70)
j=1
endif
if(eof) go to 999
enddo
999 end program t3

43
lib/77bit/test28.f90 Normal file
View File

@ -0,0 +1,43 @@
program test28
parameter (NTOKENS=2063592,MAX22=4194304)
character*13 call_0,call_1,bare_call_1
character*1 cerr
nargs=iargc()
open(10,file='test28.txt',status='old')
write(*,1000)
1000 format('Encoded text Recovered text n28 Err? Type'/60('-'))
do iline=1,999999
if(nargs.eq.0) then
read(10,'(a13)',end=999) call_0
else
call getarg(1,call_0)
endif
if(call_0.eq.' ') exit
if(call_0(1:3).eq.'CQ ' .and. call_0(4:4).ne.' ') call_0(3:3)='_'
call_1=' '
call pack28(call_0,n28)
call unpack28(n28,call_1)
cerr=' '
if(call_0.ne.call_1) cerr='*'
if(call_1(1:1).eq.'<') then
i=index(call_1,'>')
bare_call_1=call_1(2:i-1)//' '
endif
if(call_0.eq.bare_call_1) cerr=' '
if(call_0(1:3).eq.'CQ_') call_0(3:3)=' '
if(call_1(1:3).eq.'CQ_') call_1(3:3)=' '
if(n28.lt.NTOKENS) write(*,1010) call_0,call_1,n28,cerr
1010 format(a13,2x,a13,i10,2x,a1,2x,'Special token')
if(n28.ge.NTOKENS .and. n28.lt.NTOKENS+MAX22) write(*,1012) call_0, &
call_1,n28,cerr
1012 format(a13,2x,a13,i10,2x,a1,2x,'22-bit hash')
if(n28.ge.NTOKENS+MAX22) write(*,1014) call_0,call_1,n28,cerr
1014 format(a13,2x,a13,i10,2x,a1,2x,'Standard callsign')
if(nargs.gt.0) exit
enddo
999 end program test28

42
lib/77bit/test28.txt Normal file
View File

@ -0,0 +1,42 @@
DE
QRZ
CQ
CQ_000
CQ_001
CQ_999
CQ_A
CQ_Z
CQ_AA
CQ_ZZ
CQ_AAA
CQ_ZZZ
CQ_AAAA
CQ_ZZZZ
EI30T
YW18FIFA
KH1/KH7Z
<KH1/KH7Z>
ZS9YOTA
YB50ST
00A
99ZZZ
000A
009ZZZ
999ZZZ
HA70BAY
WB2000XYZ
WB2000XYZABCD
ZM90DX
<VP2E/KA1ABC>
HB9GOLD
A0
A0A
K1ABC
K1JT
5B1ABC
9Y4AB
9Y4XYZ
KA1ABC
KA1JT
WB9XYZ
ZZ9ZZZ

59
lib/77bit/todo.txt Normal file
View File

@ -0,0 +1,59 @@
To Do for FT8++
---------------
The following list is for informtion and general guidance. Everything
is subject to change, and not all ideas are necessarily good ones!
1. Nomenclature and parameters for message types
- Old-style = classic 72-bit JT-style source-encoding
FT8: (174,87) code: 72-bit info, i3bit, CRC12, isync=1
MSK144: (128,80) code: 72-bit info, CRC8
- New-style
FT8: (174,91) code: 74+3+14, sync uses isync=2
MSK144: (128,90) code: 74+3+13
2. (K1JT) For backward compatibility (good for, say, 6 months only?),
by default we'll generate old-style messages where possible, new-style
messages where they are needed. We'll decode both old and new types.
3. (K1JT -- DONE) Two new checkboxes on Advanced tab to enable 77-bit
messages:
- "Always generate new-style (77-bit) messages."
- "Decode only 77-bit messages
4. (K9AN -- MOSTLY DONE) New-style messages can be as long as 37
characters. We'll need to allow for that in a number of places.
5. (K9AN -- DONE) Subroutine genft8() will need to parse the message to be
transmitted, determine the effective message type i3 and possibly
subtype, n3. It will then generate itone, calling genft8_174_91(() if
needed.
6. (K1JT) Code to generate the user-readable messages for each
specialized type of operating, e.g., NA VHF contest, EU VHF contest,
ARRL Field Day, ARRL RTTY Roundup, use of nonstandard calls.
7. (??) Code to do the necessary auto-sequencing for each specialized
type of operating.
8. (K9AN -- MOSTLY DONE) What's needed for MSK144 with LDPC(128,90) ?
Still need to work on Sh messages. How will genmsk_128_90 know when to
generate a Sh message?
9. (K9AN) Work on the implementation of AP decoding. For which message types
should AP be implemented? For each message type/QSO state that will use
AP decoding, need to create an AP decoding table that defines the number and
type of AP decoding passes.
==========================================================================
The following are just ideas:
- Options to sort/filter decoded signals
- New Fox message type using constant-envelope waveform and higher
symbol rate to accommodate multiple simultaneous QSOs. RR73 sent to
0-5 calls, report sent to 0-5 calls. Decoding uses AP for missing
calls, thereby effectively making lower-rate codes when not all
slots are used.
- Hound should send spots of Fox to PSK Reporter.

12
lib/77bit/tokens.txt Normal file
View File

@ -0,0 +1,12 @@
DE
QRZ
CQ
CQ_000
CQ_313
CQ_999
CQ_A
CQ_AAAA
CQ_AB
CQ_ABC
CQ_ABCD
CQ_ZZZZ

213
lib/77bit/wsjt-x_v2.0.txt Normal file
View File

@ -0,0 +1,213 @@
Plans for WSJT-X Version 2.0
----------------------------
This white paper describes a number of important enhancements planned
for WSJT-X Version 2.0. Most of them involve the FT8 and MSK144
protocols, which will be upgraded to use use 77-bit information
payloads rather than the present 72 or 75 bits. This modest increase
in information content will make possible new message types that
support the following special types of QSOs and exchanged information:
1. NA VHF Contest operation with full and transparent support of grid
locators and "/R" (Rover) callsigns
2. EU VHF Contest operation with the exchange of 6-digit locators, QSO
serial numbers, and "/P" (portable) callsigns
3. ARRL Field Day operation with standard Field Day exchanges
4. ARRL RTTY Roundup operation with standard contest exchanges
5. Better and more user-friendly support for compound and nonstandard
callsigns
6. A special "telemetry" message format for exchange of arbitrary
information (up to 71 bits)
Decoding sensitivity for the new messages will be essentially the same
as for the FT8 and MSK144 modes presently in WSJT-X v1.9.1. The
existing FT8 DXpedition mode will still be supported, and a more
powerful DXpedition mode may be offered as well.
In this document we'll call the new FT8 protocol "FT8+". It will be a
superset of the FT8 implemented in v1.9.1, providing at least
temporary compatibility and inter-operability with older program
versions. We may decide to remove support for old-style 72- and
75-bit messages after a specified switchover interval.
In contrast, the new MSK144 protocol will replace the old one without
backward compatibility. We believe the smaller and more specialized
group of MSK144 users will upgrade quickly and not find this
restriction to be a problem.
Here are some examples of message formats that will be supported by
FT8+ and MSK144 in WSJT-X v2.0. The list is not exhaustive.
Parameters i3 and n3 (shown in column 1) are used in the software to
define major and minor 77-bit message types.
----------------------------------------------------------------------------------
i3.n3 Example Messages Comments
----------------------------------------------------------------------------------
0.0 TNX BOB 73 GL Free text
0.1 K1ABC RR73; W9XYZ <KH1/KH7Z> -08 DXpedition Mode (sent only by Fox)
0.2 G4ABC/P R 570007 JO22DB EU VHF Contest
0.2 PA9XYZ 590003 IO91NP EU VHF Contest
0.3 K1ABC W9XYZ 6A WI ARRL Field Day
0.3 W9XYZ K1ABC R 2B EMA ARRL Field Day
0.5 123456789ABCD Telemetry (18 hex digits)
1. <PJ4/K1ABC> W9XYZ Compound call
1. W9XYZ <PJ4/K1ABC> 73
1. CQ FD K1ABC FN42
1. CQ K1ABC FN42
1. CQ TEST K1ABC FN42 NA VHF Contest ("TEST" is optional)
1. CQ TEST K1ABC/R FN42
1. K1ABC W9XYZ EN37
1. K1ABC W9XYZ -09
1. K1ABC W9XYZ R-17
1. K1ABC W9XYZ RRR
1. K1ABC W9XYZ 73
1. K1ABC W9XYZ RR73
1. K1ABC/R W9XYZ EN37
1. K1ABC W9XYZ/R RR73
1. W9XYZ <YW18FIFA> -13 Nonstandard call
1. <YW18FIFA> W9XYZ R+02
1. W9XYZ <YW18FIFA> RRR
1. <YW18FIFA> W9XYZ RR73
2. CQ G4ABC/P IO91
2. G4ABC/P PA9XYZ JO22
2. PA9XYZ G4ABC/P RR73
3. K1ABC KA0DEF 559 MO ARRL RTTY Roundup
3. K1ABC W9XYZ 579 WI ARRL RTTY Roundup
3. KA1ABC G3AAA 529 0013 ARRL RTTY Roundup
3. TU; G3AAA K1ABC R 559 MA ARRL RTTY Roundup
3. TU; KA0DEF K1ABC R 569 MA ARRL RTTY Roundup
3. W9XYZ K1ABC R 589 MA ARRL RTTY Roundup
4. CQ KH1/KH7Z Compound call
4. CQ YW18FIFA Nonstandard call
----------------------------------------------------------------------------------
Here are some examples of minimal QSO sequences that take advantage
(where necessary) of the new protocol capabilities. Model QSOs number
1 and 2 are supported already, with the present FT8 and MSK144
protocols, and number 3 with the existing FT8 DXpedition Mode. Model
QSOs 4-8 (and others not illustrated here) require the new protocols
with 77-bit messages.
----------------------------------------------------------------------------------
1. Standard QSO
----------------------------------------------------------------------------------
CQ K1ABC FN42
K1ABC W9XYZ EN37
W9XYZ K1ABC -11
K1ABC W9XYZ R-09
W9XYZ K1ABC RRR
K1ABC W9XYZ 73
----------------------------------------------------------------------------------
2. Short-cycle QSO
----------------------------------------------------------------------------------
CQ K1ABC FN42
K1ABC W9XYZ -09
W9XYZ K1ABC R-11
K1ABC W9XYZ RR73
W9XYZ K1ABC 73
----------------------------------------------------------------------------------
3. FT8 DXpedition Mode
----------------------------------------------------------------------------------
CQ KH1/KH7Z
KH7Z K1ABC FN42
K1ABC KH7Z -12
KH7Z K1ABC R-14
KH7Z W9XYZ EN37
... possibly other callers ...
K1ABC RR73; W9XYZ <KH1/KH7Z> -08
----------------------------------------------------------------------------------
4. ARRL Field Day
----------------------------------------------------------------------------------
CQ FD K1ABC FN42
K1ABC W9XYZ 6A WI
W9XYZ K1ABC R 2B EMA
K1ABC W9XYZ RR73
----------------------------------------------------------------------------------
5. ARRL VHF Contests
----------------------------------------------------------------------------------
CQ TEST K1ABC/R FN42
K1ABC/R W9XYZ EN37
W9XYZ K1ABC/R R FN42
K1ABC/R W9XYZ RR73
----------------------------------------------------------------------------------
6. ARRL RTTY Contest
----------------------------------------------------------------------------------
CQ TEST K1ABC FN42
K1ABC W9XYZ 579 WI
W9XYZ K1ABC R 589 MA
K1ABC W9XYZ RR73
----------------------------------------------------------------------------------
7. EU VHF Contest
----------------------------------------------------------------------------------
CQ TEST G4ABC/P IO91
G4ABC/P PA9XYZ JO22
PA9XYZ 590003 IO91NP
G4ABC/P R 570007 JO22DB
PA9XYZ G4ABC/P RRR
G4ABC/P PA9XYZ 73
----------------------------------------------------------------------------------
8. Compound call
----------------------------------------------------------------------------------
CQ PJ4/K1ABC
<PJ4/K1ABC> W9XYZ
W9XYZ K1ABC -11
K1ABC W9XYZ R-09
W9XYZ <PJ4/K1ABC> RRR
<PJ4/K1ABC> W9XYZ 73
----------------------------------------------------------------------------------
To minimize confusion that's likely to arise during a switchover from
v1.9.1 to v2.0, we propose to follow a well advertised schedule:
"RC1 Date" -- perhaps as early as September 15, 2018?
-------------------------------------------------------
This will be the first chance for beta testers to try WSJT-X using the
77-bit messages. We may restrict this opportunity to specific
volunteer testers, and we'll probably include an "upgrade by
xxxx_date" message to remind people that they are using a release
intended only for testing.
FT8+ will support the old (v1.9.1) protocol as well as the new message
types outlined above. To avoid QRMing legacy FT8 users with messages
they can't decode, we'll recommend testing FT8+ on frequencies
formerly used for JT9.
MSK144 will be fully functional between any two stations using the RC1
software, but it will not be backward compatible with earlier program
versions.
"RC2, RC3,... Date" -- perhaps in October?
--------------------------------------------
As needed, depending on results of testing.
GA Release Date -- perhaps in November?
---------------------------------------------
Official General Availability release of WSJT-X v2.0.0. The original
MSK144 protocol will be declared obsolete.
For reference: Dates of relevant upcoming ARRL contests
-------------------------------------------------------
VHF QSO Party: September 8-10, 2018
RTTY Roundup: January 5-6, 2019
VHF SS: January 19-21, 2019
Our proposed schedule should make WSJT-X Version 2.0 usable for
relevant ARRL operating events in 2019.

View File

@ -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 ... <band>" 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

116
lib/bpdecode128_90.f90 Normal file
View File

@ -0,0 +1,116 @@
subroutine bpdecode128_90(llr,apmask,maxiterations,message77,cw,nharderror,iter)
!
! A log-domain belief propagation decoder for the (128,90) code.
!
use iso_c_binding, only: c_loc,c_size_t
use crc
integer, parameter:: N=128, K=90, M=N-K
integer*1 cw(N),apmask(N)
integer*1 decoded(K)
integer*1 message77(77)
integer Nm(11,M)
integer Mn(3,N)
integer nrw(M)
integer synd(M)
real tov(4,N)
real toc(11,M)
real tanhtoc(11,M)
real zn(N)
real llr(N)
real Tmn
include "ldpc_128_90_reordered_parity.f90"
decoded=0
toc=0
tov=0
tanhtoc=0
! initialize messages to checks
do j=1,M
do i=1,nrw(j)
toc(i,j)=llr((Nm(i,j)))
enddo
enddo
ncnt=0
do iter=0,maxiterations
! Update bit log likelihood ratios (tov=0 in iteration 0).
do i=1,N
if( apmask(i) .ne. 1 ) then
zn(i)=llr(i)+sum(tov(1:ncw,i))
else
zn(i)=llr(i)
endif
enddo
! Check to see if we have a codeword (check before we do any iteration).
cw=0
where( zn .gt. 0. ) cw=1
ncheck=0
do i=1,M
synd(i)=sum(cw(Nm(1:nrw(i),i)))
if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1
! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied'
enddo
! write(*,*) 'number of unsatisfied parity checks ',ncheck
if( ncheck .eq. 0 ) then ! we have a codeword - reorder the columns and return it
decoded=cw(1:K)
call chkcrc13a(decoded,nbadcrc)
if(nbadcrc.eq.0) then
message77=decoded(1:77)
nharderror=count( (2*cw-1)*llr .lt. 0.0 )
return
endif
endif
if( iter.gt.0 ) then ! this code block implements an early stopping criterion
! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion
nd=ncheck-nclast
if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased
ncnt=0 ! reset counter
else
ncnt=ncnt+1
endif
! write(*,*) iter,ncheck,nd,ncnt
if( ncnt .ge. 3 .and. iter .ge. 5 .and. ncheck .gt. 10) then
nharderror=-1
return
endif
endif
nclast=ncheck
! Send messages from bits to check nodes
do j=1,M
do i=1,nrw(j)
ibj=Nm(i,j)
toc(i,j)=zn(ibj)
do kk=1,ncw ! subtract off what the bit had received from the check
if( Mn(kk,ibj) .eq. j ) then
toc(i,j)=toc(i,j)-tov(kk,ibj)
endif
enddo
enddo
enddo
! send messages from check nodes to variable nodes
do i=1,M
tanhtoc(1:11,i)=tanh(-toc(1:11,i)/2)
enddo
do j=1,N
do i=1,ncw
ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j
Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j)
call platanh(-Tmn,y)
! y=atanh(-Tmn)
tov(i,j)=2*y
enddo
enddo
enddo
nharderror=-1
return
end subroutine bpdecode128_90

116
lib/bpdecode128_90.f90.save Normal file
View File

@ -0,0 +1,116 @@
subroutine bpdecode128_90(llr,apmask,maxiterations,message77,cw,nharderror,iter)
!
! A log-domain belief propagation decoder for the (128,90) code.
!
use iso_c_binding, only: c_loc,c_size_t
use crc
integer, parameter:: N=128, K=90, M=N-K
integer*1 cw(N),apmask(N)
integer*1 decoded(K)
integer*1 message77(77)
integer Nm(12,M)
integer Mn(4,N)
integer nrw(M),ncw(N)
integer synd(M)
real tov(4,N)
real toc(12,M)
real tanhtoc(12,M)
real zn(N)
real llr(N)
real Tmn
include "ldpc_128_90_b_reordered_parity.f90"
decoded=0
toc=0
tov=0
tanhtoc=0
! initialize messages to checks
do j=1,M
do i=1,nrw(j)
toc(i,j)=llr((Nm(i,j)))
enddo
enddo
ncnt=0
do iter=0,maxiterations
! Update bit log likelihood ratios (tov=0 in iteration 0).
do i=1,N
if( apmask(i) .ne. 1 ) then
zn(i)=llr(i)+sum(tov(1:ncw(i),i))
else
zn(i)=llr(i)
endif
enddo
! Check to see if we have a codeword (check before we do any iteration).
cw=0
where( zn .gt. 0. ) cw=1
ncheck=0
do i=1,M
synd(i)=sum(cw(Nm(1:nrw(i),i)))
if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1
! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied'
enddo
! write(*,*) 'number of unsatisfied parity checks ',ncheck
if( ncheck .eq. 0 ) then ! we have a codeword - reorder the columns and return it
decoded=cw(1:K)
call chkcrc13a(decoded,nbadcrc)
if(nbadcrc.eq.0) then
message77=decoded(1:77)
nharderror=count( (2*cw-1)*llr .lt. 0.0 )
return
endif
endif
if( iter.gt.0 ) then ! this code block implements an early stopping criterion
! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion
nd=ncheck-nclast
if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased
ncnt=0 ! reset counter
else
ncnt=ncnt+1
endif
! write(*,*) iter,ncheck,nd,ncnt
if( ncnt .ge. 3 .and. iter .ge. 5 .and. ncheck .gt. 10) then
nharderror=-1
return
endif
endif
nclast=ncheck
! Send messages from bits to check nodes
do j=1,M
do i=1,nrw(j)
ibj=Nm(i,j)
toc(i,j)=zn(ibj)
do kk=1,4 ! subtract off what the bit had received from the check
if( Mn(kk,ibj) .eq. j ) then
toc(i,j)=toc(i,j)-tov(kk,ibj)
endif
enddo
enddo
enddo
! send messages from check nodes to variable nodes
do i=1,M
tanhtoc(1:12,i)=tanh(-toc(1:12,i)/2)
enddo
do j=1,N
do i=1,ncw(j)
ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j
Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j)
call platanh(-Tmn,y)
! y=atanh(-Tmn)
tov(i,j)=2*y
enddo
enddo
enddo
nharderror=-1
return
end subroutine bpdecode128_90

View File

@ -10,7 +10,7 @@ module crc
integer (c_int), value :: length
end function crc14
function crc14_check (data, length) bind (C, name="crc16_check")
function crc14_check (data, length) bind (C, name="crc14_check")
use, intrinsic :: iso_c_binding, only: c_bool, c_ptr, c_int
implicit none
logical (c_bool) :: crc14_check
@ -18,6 +18,22 @@ module crc
integer (c_int), value :: length
end function crc14_check
function crc13 (data, length) bind (C, name="crc13")
use, intrinsic :: iso_c_binding, only: c_short, c_ptr, c_int
implicit none
integer (c_short) :: crc13
type (c_ptr), value :: data
integer (c_int), value :: length
end function crc13
function crc13_check (data, length) bind (C, name="crc14_check")
use, intrinsic :: iso_c_binding, only: c_bool, c_ptr, c_int
implicit none
logical (c_bool) :: crc13_check
type (c_ptr), value :: data
integer (c_int), value :: length
end function crc13_check
function crc12 (data, length) bind (C, name="crc12")
use, intrinsic :: iso_c_binding, only: c_short, c_ptr, c_int
implicit none

31
lib/crc13.cpp Normal file
View File

@ -0,0 +1,31 @@
#include <boost/crc.hpp>
#include <boost/config.hpp>
extern "C"
{
short crc13 (unsigned char const * data, int length);
bool crc13_check (unsigned char const * data, int length);
}
#define POLY 0x15D7
#ifdef BOOST_NO_CXX11_CONSTEXPR
#define TRUNCATED_POLYNOMIAL POLY
#else
namespace
{
unsigned long constexpr TRUNCATED_POLYNOMIAL = POLY;
}
#endif
// assumes CRC is last 13 bits of the data and is set to zero
// caller should assign the returned CRC into the message in big endian byte order
short crc13 (unsigned char const * data, int length)
{
return boost::augmented_crc<13, TRUNCATED_POLYNOMIAL> (data, length);
}
bool crc13_check (unsigned char const * data, int length)
{
return !boost::augmented_crc<13, TRUNCATED_POLYNOMIAL> (data, length);
}

View File

@ -93,11 +93,13 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
! We're in FT8 mode
call timer('decft8 ',0)
newdat=params%newdat
ncontest=iand(params%nexp_decode,7)
call my_ft8%decode(ft8_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)
params%ndepth,ncontest,logical(params%nagain), &
logical(params%lft8apon),logical(params%lapcqonly), &
logical(params%ldecode77),params%napwid, &
mycall,hiscall,hisgrid)
call timer('decft8 ',1)
if(nfox.gt.0) then
n30min=minval(n30fox(1:nfox))
@ -495,14 +497,18 @@ contains
annot=' '
if(nap.ne.0) then
write(annot,'(a1,i1)') 'a',nap
if(qual.lt.0.17) decoded0(22:22)='?'
if(qual.lt.0.17) decoded0(37:37)='?'
endif
i0=index(decoded0,';')
! i0=index(decoded0,';')
! Always print 37 characters? Or, send i3,n3 up to here from ft8b_2 and use them
! to decide how many chars to print?
!TEMP
i0=1
if(i0.le.0) write(*,1000) params%nutc,snr,dt,nint(freq),decoded0(1:22),annot
1000 format(i6.6,i4,f5.1,i5,' ~ ',1x,a22,1x,a2)
if(i0.gt.0) write(*,1001) params%nutc,snr,dt,nint(freq),decoded0
1001 format(i6.6,i4,f5.1,i5,' ~ ',1x,a37)
if(i0.gt.0) write(*,1001) params%nutc,snr,dt,nint(freq),decoded0,annot
1001 format(i6.6,i4,f5.1,i5,' ~ ',1x,a37,1x,a2)
write(13,1002) params%nutc,nint(sync),snr,dt,freq,0,decoded0
1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FT8')

277
lib/digi-contest.txt Normal file
View File

@ -0,0 +1,277 @@
Possible FT8 Enhancements for Contesting
----------------------------------------
In addition to all the standard FT8 messages, FT8 DXpedition Mode
defines a new message type to convey messages like this example
acknowledging completion of a QSO with K1ABC and initiating a QSO with
W9XYZ:
K1ABC RR73; W9XYZ <KH1/KH7Z> -11
With 15s T/R sequencing and otherwise using standard FT8 messages,
this feature allows QSO rates up to 120/hour with one Tx signal. The
callsign enclosed in angle brackets is sent as a 10-bit hash code.
High QSO rates are also desirable for contest operating, but some
details are quite different from the DXpedition case. Contesting is a
many-to-many (as opposed to many-to-one) activity. We distinguish
between "Run stations" and "S+P stations" rather than between "Fox"
and "Hounds".
An optimal sequence of messages suitable for contesting looks
something like the list in Table 1, where {exch} represents the
required contest exchange. With 15 s transmissions and a steady
stream of callers, messages like these can support QSO rates
approaching 120/hour.
Table 1. Example sequence of FT8 contest messages
-------------------------------------------------------------------------
Run station S+P stations
-------------------------------------------------------------------------
1. CQ K1ABC
2. K1ABC W9XYZ, K1ABC G4AAA, ...
3. W9XYZ K1ABC {exch}
4. K1ABC W9XYZ {exch}
5. TU; G4AAA K1ABC {exch}
6. K1ABC G4AAA {exch}
7. TU; VE2BBB K1ABC {exch}
8. K1ABC VE2BBB {exch}
9. ...
-------------------------------------------------------------------------
In some circumstances one or both station callsigns may safely be
taken as known by context. High-rate contest transmissions in SSB,
CW, and RTTY can therefore be considerably shortened with no resulting
ambiguity for attentive operators. CQing stations need not include
their own callsign in every transmission, while S+P stations may send
only their own callsign at first, as in line 2 of Table 2, and then
only the contest exchange, as in line 4.
Table 2. Abbreviated contest messages
-------------------------------------------------------------------------
Run station S+P stations
-------------------------------------------------------------------------
1. CQ K1ABC
2. W9XYZ, G4AAA, ...
3. W9XYZ {exch}
4. {exch} (sent by W9XYZ)
5. TU; G4AAA {exch}
6. {exch} (sent by G4AAA)
7. TU; VE2BBB {exch}
8. {exch} (sent by VE2BBB)
9. TU; CQ K1ABC
10. ...
-------------------------------------------------------------------------
There would be no advantage to such message brevity with FT8. FT8
transmissions are of fixed duration, by design; and the AP decoder can
treat the home callsign and previously decoded callsigns as
hypothetically given, thereby making the effective code rate lower and
sensitivity up to 4 dB better.
Required exchange information for some relevant contests is
illustrated in Table 3, along with a breakdown of bit requirements for
each component of the exchange. Lower-case letter-number combinations
such as r1, r3, s7,... in the table suggest the meanings and indicate
the number of bits required to convey each part of the exchange.
Further details are given below the Table. Parameter T1 is the total
number of exchange bits, and T2=T1+56 is the number of bits for the
full message, including two standard 28-bit callsigns.
Table 3. Examples of required contest exchanges {exch}
------------------------------------------------------------------------------
Event Exchange Example Bits T1 T2
------------------------------------------------------------------------------
ARRL RTTY US/Can: rpt state/prov R 579 MA r1 r3 s7 11 67
DX: rpt serial R 559 0013 r1 r3 n12 16 72
Field Day US/Can: OpClass Section R 6A EMA r1 n5 c3 s7 16 72
DX: OpClass DX R 1A DX r1 n5 c3 s7 16 72
CQ WPX RTTY RST + serial R 589 0013 r1 r3 n12 16 72
CQ WW RTTY US/Can: RST CQZ state/prov R 579 8 NJ r1 r3 z6 s6 16 72
DX: RST + CQzone R 559 3 r1 r3 z6 10 66
ARRL VHF+ grid4 R FN42 r1 g15 16 72
EU VHF+ rpt serial grid6 R 590013 IO91NP r1 r3 n12 g25 41 97
------------------------------------------------------------------------------
Meaning and number of bits for each exchange component:
c3 Operating class (A-F)
g15 grid4
g25 grid6
n12 Serial number
n5 Number of transmitters (0-31)
r1 acknowledgment of received exchange
r3 3-bit report (0-7 ==> -24 to +18 dB, effectively "S2 to "S9")
s6 US state or Canadian province (48+14=62)
s7 ARRL/RAC Section (83 sections)
z6 CQ zone
------------------------------------------------------------------------------
How best to accommodate all these possibilities within the 72+3-bit
FT8 message payload? Let i3 (aka "i3bit") denote message type, with
available range 0-7. Type 0 is already used for standard JT-style
structured messages and free text, and type 1 for DXpedition mode.
Examples of suggested new message types 2 through 6 are summarized in
the Table 4.
Table 4. Proposed FT8 message types
------------------------------------------------------------------------------
i3 Example message Bits i72 Total Special purpose
------------------------------------------------------------------------------
0 K1ABC W9XYZ EN37 28 28 15 0 72 Standard message
0 FREE TEXT 71 1 72 Free text
1 K1ABC RR73; W9XYZ <KH1/KH7Z> -11 28 28 10 6 72 DXpedition Mode
2 W9XYZ K1ABC x16 28 28 16 72 Contesting
3 TU; G4AAA K1ABC x16 28 28 16 72 Contesting with "TU;"
4 <K1ABC> W9XYZ/R R x25 17 28 1 1 25 72 Rovers, Grid6
5 <K1ABC> PJ4/W9XYZ 17 49 66 Compound TxCall
6 PA9XYZ R 590003 IO91NP 28 1 3 12 24 68 EU VHF contest
7 tbd...
The first callsign in a message can also be "CQ" and a few other
special tokens. Type 3 messages are the same as type 2 except for
including "TU;", the completion-of-QSO indicator. Message fragments
x16 and x25 represent generic contest exchanges. A "contest template"
will define the specific source encoding/decoding needed for each
event.
Suggested message types 4 and 5 use a 17-bit hash for the first
callsign. I'm imagining that we'd start with a 32-bit crc and then
use its remainder after dividing by the prime number 131063. Values
less than 131063 will be the desired hash code, and the nine values
131063-131071 can be assigned special meanings such as CQ, QRZ, etc.
Type 4 messages identify the transmitting station as a Rover and can
also accommodate 6-digit grid locators. Type 5 messages allow the
transmitting station to send a full compound callsign with add-on
prefixes up to 4 characters and suffixes up to 3. Compound callsigns
are also permissible for the hashed callsigns in message types 4 and
5.
Contest Operating
-----------------
Operating in this proposed FT8 Contest Mode would be similar to that
in current RTTY contests. CQing stations will be distributed over 20
kHz or more on each band, perhaps at ~500 Hz separation. They will
respond to callers on their own frequency +/- ~200 Hz. Thus, a CQing
station and callers should occupy no more than 500 Hz total bandwidth.
CQers might always transmit at Tx audio frequency 1750 Hz and
configure their FT8 decoders to respond to signals between 1500 and
2000 Hz. S+P stations will typically work their way up or down the
band, perhaps in steps of 2 or 3 kHz, looking for unworked CQers. The
FT8 Contest GUI will offer special features for CQ mode and S+P mode
that make such conventions easy to follow.
Some Pertinent Questions
------------------------
1. FT8 is a good mode, but does it make for a good contesting mode?
The model described above maxes out at 120 QSOs/hour. (One can
imagine SO2R or even SO3R extensions, doubling or tripling that
limit.) Should we consider T/R sequences of 10s, or even 5s, to get
potentially higher rates? Should we consider giving up synchronized,
fixed-length sequences entirely, and use operator-determined start
times and transmission lengths? That's a significant departure from
all existing WSJT-X modes.
2. How much automation should be permissible?
We're not aiming to make a contesting robot. We want something that
rewards operator and station performance. The recently introduced FT8
DXpedition Mode offers the "Fox" operator a list of decoded "Hounds"
sorted by Call, Grid, S/N, Distance, or Random order. Hounds must
initiate their calls to Fox, and Fox must manually select each Hound
to be called. Otherwise, QSOs proceed with standard FT8
"auto-sequencing". Is this model acceptable?
3. How much bandwidth? How much sensitivity?
RTTY signals use bandwidth ~220 Hz and require S/N around -5 dB or
better, measured in a 2500 Hz bandwidth. FT8 uses signal bandwidth 50
Hz and reaches threshold sensitivity between -20 and -24 dB, depending
on how much a priori (AP) information is available. Shorter
transmissions conveying the same messages would increase the
bandwidth, S/N threshold, and potential QSO rate proportionally. Has
FT8 already hit the "sweet spot" of such trade-offs?
4. Suitable power limits?
WSJT-X modes are designed as weak-signal modes. They have strong FEC
and don't suffer from partial or corrupted copy. Sensitivity already
beats RTTY by 15-19 dB, so arguably it makes sense for an FT8 contest
or contest category to be limited to 100 W or even QRP power levels.
5. What software should provide the operator's GUI?
Things are described above as though WSJT-X, the software that
introduced FT8, would be used for contest operating. WSJT-X can send
QSO information to N1MM+ and other logging programs, so they could be
used in combination with WSJT-X. Alternatively, we could set things
up so that N1MM+ is the control program and FT8 encoding/decoding is
provided by a plug-in "MMFT8" similar to MMTTY. Operators already
into serious RTTY contesting would probably like the N1MM-in-control
option. However, existing FT8 users might be more comfortable with
WSJT-X in full control. Moreover, WSJT-X offers full support for
Linux and MacOS, which N1MM+ does not.
########################################################################
More thinking, beyond the above...
FT8 currently uses LDPC(174,87), where 87=72+3+12. Suggest going to
LDPC(174,91), with 91=72+5+14. This would give us 32 message types
rather than 7, and stronger suppression of false decodes. SNR penalty
would be 10log(91/87)=0.2 dB.
MSK144 currently uses LDPC(128,80), where 80=72+8. Suggest going to
LDPC(128,87), with 87=72+5+10. SNR penalty is 0.4 dB.
ARRL RTTY Roundup
-------------------------------------------------------------------------
Run station S+P stations
-------------------------------------------------------------------------
1. CQ K1ABC
2. K1ABC W9XYZ, K1ABC G4AAA, ...
3. W9XYZ K1ABC 579 MA
4. K1ABC W9XYZ 599 WI
5. TU; G4AAA K1ABC 559 MA
6. K1ABC G4AAA 579 0013
7. TU; VE2BBB K1ABC 599 MA
8. K1ABC VE2BBB 599 QC
9. TU; CQ K1ABC
-------------------------------------------------------------------------
NA VHF Contest
-------------------------------------------------------------------------
Run station S+P station i3
-------------------------------------------------------------------------
1. CQ K1ABC/R FN54 0
2. K1ABC W9XYZ EN37 0
3. W9XYZ K1ABC R FN54 2
4. K1ABC W9XYZ RR73 0
5. CQ K1ABC/R FN54 0
-------------------------------------------------------------------------
1. CQ K1ABC FN42 0
2. <K1ABC> W9XYZ/R EN47 5
3. W9XYZ K1ABC R FN42 0
4. DE W9XYZ/R RR73 0
5. CQ K1ABC FN42 0
-------------------------------------------------------------------------
EU VHF+ Contest
-------------------------------------------------------------------------
Run station S+P station i3
-------------------------------------------------------------------------
1. CQ G4ABC IO91 0
2. G4ABC PA9XYZ JO22 0
3. PA9XYZ 590003 IO91NP 6
4. G4ABC R 570007 JO22DB 6
5. PA9XYZ G4ABC RR73 0

View File

@ -9,7 +9,7 @@ subroutine encode4(message,ncode)
integer*1 data0(13),symbol(216)
call chkmsg(message,cok,nspecial,flip)
call packmsg(message,dgen,itype,.false.) !Pack 72-bit message into 12 six-bit symbols
call packmsg(message,dgen,itype) !Pack 72-bit message into 12 six-bit symbols
call entail(dgen,data0)
call encode232(data0,206,symbol) !Convolutional encoding
call interleave4(symbol,1) !Apply JT4 interleaving

58
lib/encode_128_90.f90 Normal file
View File

@ -0,0 +1,58 @@
subroutine encode_128_90(message77,codeword)
!
! Add a 13-bit CRC to a 77-bit message and return a 128-bit codeword
!
use, intrinsic :: iso_c_binding
use iso_c_binding, only: c_loc,c_size_t
use crc
integer, parameter:: N=128, K=90, M=N-K
character*90 tmpchar
integer*1 codeword(N)
integer*1 gen(M,K)
integer*1 message77(77),message(K)
integer*1 pchecks(M)
integer*1, target :: i1MsgBytes(12)
include "ldpc_128_90_generator.f90"
logical first
data first/.true./
save first,gen
if( first ) then ! fill the generator matrix
gen=0
do i=1,M
do j=1,23
read(g(i)(j:j),"(Z1)") istr
ibmax=4
if(j.eq.23) ibmax=2
do jj=1, ibmax
icol=(j-1)*4+jj
if( btest(istr,4-jj) ) gen(i,icol)=1
enddo
enddo
enddo
first=.false.
endif
! Add 13 bit CRC to form 90-bit message+CRC13
write(tmpchar,'(77i1)') message77
tmpchar(78:80)='000'
i1MsgBytes=0
read(tmpchar,'(10b8)') i1MsgBytes(1:10)
ncrc13 = crc13 (c_loc (i1MsgBytes), 12)
write(tmpchar(78:90),'(b13)') ncrc13
read(tmpchar,'(90i1)') message
do i=1,M
nsum=0
do j=1,K
nsum=nsum+message(j)*gen(i,j)
enddo
pchecks(i)=mod(nsum,2)
enddo
codeword(1:K)=message
codeword(K+1:N)=pchecks
return
end subroutine encode_128_90

View File

@ -73,27 +73,27 @@ subroutine extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip, &
apsymbols(1,1:4)=(/62,32,32,49/) ! CQ
if(len_trim(mycall).gt.0) then
apmessage=mycall//" "//mycall//" RRR"
call packmsg(apmessage,ap,itype,.false.)
call packmsg(apmessage,ap,itype)
if(itype.ne.1) ap=-1
apsymbols(2,1:4)=ap(1:4)
!write(*,*) 'mycall symbols ',ap(1:4)
if(len_trim(hiscall).gt.0) then
apmessage=mycall//" "//hiscall//" RRR"
call packmsg(apmessage,ap,itype,.false.)
call packmsg(apmessage,ap,itype)
if(itype.ne.1) ap=-1
apsymbols(3,1:9)=ap(1:9)
apsymbols(4,:)=ap
apmessage=mycall//" "//hiscall//" 73"
call packmsg(apmessage,ap,itype,.false.)
call packmsg(apmessage,ap,itype)
if(itype.ne.1) ap=-1
apsymbols(5,:)=ap
if(len_trim(hisgrid(1:4)).gt.0) then
apmessage=mycall//' '//hiscall//' '//hisgrid(1:4)
call packmsg(apmessage,ap,itype,.false.)
call packmsg(apmessage,ap,itype)
if(itype.ne.1) ap=-1
apsymbols(6,:)=ap
apmessage='CQ'//' '//hiscall//' '//hisgrid(1:4)
call packmsg(apmessage,ap,itype,.false.)
call packmsg(apmessage,ap,itype)
if(itype.ne.1) ap=-1
apsymbols(7,:)=ap
endif
@ -211,7 +211,7 @@ subroutine extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip, &
correct(1:63)=tmp(1:63)
call interleave63(correct,63,1)
call graycode65(correct,63,1)
call unpackmsg(dat4,decoded,.false.,' ') !Unpack the user message
call unpackmsg(dat4,decoded) !Unpack the user message
ncount=0
if(iand(dat4(10),8).ne.0) ltext=.true.
endif

View File

@ -57,7 +57,7 @@ subroutine extract4(sym0,ncount,decoded)
read(c72,1102) data4
1102 format(12b6)
call unpackmsg(data4,decoded,.false.,' ')
call unpackmsg(data4,decoded)
if(decoded(1:6).eq.'000AAA') then
! decoded='***WRONG MODE?***'
decoded=' '

17
lib/extractmessage77.f90 Normal file
View File

@ -0,0 +1,17 @@
subroutine extractmessage77(decoded77,msgreceived)
use packjt
character*22 msgreceived
character*77 cbits
integer*1 decoded77(77)
integer*4 i4Dec6BitWords(12)
write(cbits,'(77i1)') decoded77
!**** Temporary: For now, just handle i5bit=0.
read(cbits,'(12b6)') i4Dec6BitWords
read(cbits,'(72x,i5.5)') i5bit
if( i5bit .eq. 0 ) then
call unpackmsg(i4Dec6BitWords,msgreceived)
endif
return
end subroutine extractmessage77

393
lib/fsk4hf/bpdecode174b.f90 Normal file
View File

@ -0,0 +1,393 @@
subroutine bpdecode174b(llr,apmask,maxiterations,decoded,cw,nharderror,iter)
!
! A log-domain belief propagation decoder for the (174,91) code.
!
integer, parameter:: N=174, K=91, M=N-K
integer*1 codeword(N),cw(N),apmask(N)
integer colorder(N)
integer*1 decoded(K)
integer Nm(7,M)
integer Mn(3,N) ! 3 checks per bit
integer synd(M)
real tov(3,N)
real toc(7,M)
real tanhtoc(7,M)
real zn(N)
real llr(N)
real Tmn
integer nrw(M)
data colorder/ &
0, 1, 2, 3, 28, 4, 5, 6, 7, 8, 9, 10, 11, 34, 12, 32, 13, 14, 15, 16,&
17, 18, 36, 29, 40, 19, 20, 38, 21, 41, 30, 42, 22, 44, 37, 47, 48, 23, 33, 43,&
49, 45, 56, 39, 25, 26, 46, 50, 51, 52, 24, 57, 58, 61, 31, 54, 64, 35, 27, 62,&
59, 53, 60, 63, 55, 70, 66, 67, 68, 65, 71, 74, 72, 73, 77, 75, 69, 76, 79, 82,&
83, 78, 81, 80, 84, 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/
data Mn/ &
1, 24, 66, &
2, 5, 70, &
3, 31, 65, &
4, 49, 58, &
6, 60, 67, &
7, 32, 75, &
8, 48, 82, &
9, 35, 41, &
10, 39, 62, &
11, 14, 61, &
12, 71, 74, &
13, 23, 78, &
15, 16, 79, &
17, 54, 63, &
18, 50, 57, &
19, 30, 47, &
20, 64, 80, &
21, 28, 69, &
22, 25, 43, &
26, 34, 72, &
27, 36, 37, &
29, 40, 44, &
33, 52, 53, &
38, 55, 83, &
42, 51, 59, &
45, 76, 81, &
46, 68, 77, &
56, 67, 73, &
1, 4, 5, &
2, 47, 51, &
3, 46, 82, &
6, 24, 76, &
7, 9, 16, &
8, 10, 78, &
11, 35, 55, &
12, 38, 64, &
13, 42, 83, &
14, 27, 54, &
15, 21, 34, &
17, 44, 53, &
18, 25, 28, &
19, 33, 57, &
20, 22, 73, &
23, 40, 81, &
26, 49, 68, &
29, 71, 75, &
30, 65, 79, &
31, 36, 60, &
32, 43, 77, &
37, 62, 70, &
39, 69, 74, &
41, 52, 66, &
45, 50, 61, &
48, 63, 80, &
56, 59, 72, &
58, 64, 65, &
1, 13, 28, &
2, 48, 75, &
3, 53, 69, &
4, 11, 44, &
5, 73, 79, &
6, 12, 17, &
7, 57, 60, &
8, 15, 61, &
9, 39, 59, &
10, 19, 49, &
14, 43, 52, &
16, 54, 68, &
18, 41, 63, &
20, 36, 45, &
21, 67, 77, &
10, 22, 55, &
23, 65, 72, &
24, 27, 82, &
25, 26, 29, &
30, 35, 37, &
31, 51, 66, &
17, 32, 78, &
33, 42, 76, &
34, 70, 83, &
38, 46, 81, &
40, 62, 80, &
45, 47, 74, &
50, 56, 71, &
7, 37, 58, &
1, 16, 71, &
2, 6, 61, &
3, 22, 50, &
4, 59, 77, &
5, 41, 81, &
8, 58, 74, &
9, 20, 26, &
11, 21, 31, &
12, 66, 79, &
13, 14, 57, &
15, 33, 40, &
18, 44, 82, &
19, 69, 83, &
23, 49, 63, &
24, 29, 39, &
25, 47, 56, &
27, 55, 72, &
28, 64, 70, &
30, 48, 77, &
32, 34, 45, &
35, 68, 80, &
36, 38, 52, &
42, 43, 62, &
46, 60, 78, &
51, 54, 67, &
53, 73, 75, &
14, 73, 76, &
1, 22, 30, &
2, 35, 43, &
3, 47, 63, &
4, 25, 76, &
5, 33, 78, &
6, 20, 83, &
7, 12, 72, &
8, 54, 70, &
9, 61, 65, &
10, 34, 51, &
11, 46, 75, &
13, 39, 68, &
15, 17, 56, &
16, 23, 36, &
18, 32, 55, &
19, 31, 81, &
21, 37, 71, &
24, 57, 64, &
26, 38, 48, &
27, 49, 50, &
28, 52, 59, &
29, 41, 58, &
40, 60, 74, &
42, 44, 79, &
51, 53, 80, &
62, 67, 82, &
23, 66, 69, &
1, 53, 61, &
2, 18, 39, &
3, 4, 12, &
5, 26, 74, &
6, 30, 52, &
7, 82, 83, &
8, 35, 73, &
9, 19, 67, &
10, 64, 75, &
11, 20, 33, &
13, 45, 48, &
3, 14, 40, &
15, 43, 49, &
16, 55, 76, &
17, 62, 65, &
21, 47, 78, &
22, 59, 81, &
24, 34, 63, &
25, 37, 66, &
27, 79, 80, &
28, 60, 79, &
29, 31, 70, &
32, 58, 69, &
10, 36, 77, &
38, 50, 51, &
13, 41, 56, &
42, 63, 71, &
44, 47, 68, &
1, 46, 72, &
54, 57, 75, &
2, 33, 58, &
4, 17, 83, &
5, 14, 55, &
6, 23, 48, &
7, 52, 56/
data Nm/ &
1, 29, 57, 86, 113, 140, 168, &
2, 30, 58, 87, 114, 141, 170, &
3, 31, 59, 88, 115, 142, 151, &
4, 29, 60, 89, 116, 142, 171, &
2, 29, 61, 90, 117, 143, 172, &
5, 32, 62, 87, 118, 144, 173, &
6, 33, 63, 85, 119, 145, 174, &
7, 34, 64, 91, 120, 146, 0, &
8, 33, 65, 92, 121, 147, 0, &
9, 34, 66, 72, 122, 148, 163, &
10, 35, 60, 93, 123, 149, 0, &
11, 36, 62, 94, 119, 142, 0, &
12, 37, 57, 95, 124, 150, 165, &
10, 38, 67, 95, 112, 151, 172, &
13, 39, 64, 96, 125, 152, 0, &
13, 33, 68, 86, 126, 153, 0, &
14, 40, 62, 78, 125, 154, 171, &
15, 41, 69, 97, 127, 141, 0, &
16, 42, 66, 98, 128, 147, 0, &
17, 43, 70, 92, 118, 149, 0, &
18, 39, 71, 93, 129, 155, 0, &
19, 43, 72, 88, 113, 156, 0, &
12, 44, 73, 99, 126, 139, 173, &
1, 32, 74, 100, 130, 157, 0, &
19, 41, 75, 101, 116, 158, 0, &
20, 45, 75, 92, 131, 143, 0, &
21, 38, 74, 102, 132, 159, 0, &
18, 41, 57, 103, 133, 160, 0, &
22, 46, 75, 100, 134, 161, 0, &
16, 47, 76, 104, 113, 144, 0, &
3, 48, 77, 93, 128, 161, 0, &
6, 49, 78, 105, 127, 162, 0, &
23, 42, 79, 96, 117, 149, 170, &
20, 39, 80, 105, 122, 157, 0, &
8, 35, 76, 106, 114, 146, 0, &
21, 48, 70, 107, 126, 163, 0, &
21, 50, 76, 85, 129, 158, 0, &
24, 36, 81, 107, 131, 164, 0, &
9, 51, 65, 100, 124, 141, 0, &
22, 44, 82, 96, 135, 151, 0, &
8, 52, 69, 90, 134, 165, 0, &
25, 37, 79, 108, 136, 166, 0, &
19, 49, 67, 108, 114, 152, 0, &
22, 40, 60, 97, 136, 167, 0, &
26, 53, 70, 83, 105, 150, 0, &
27, 31, 81, 109, 123, 168, 0, &
16, 30, 83, 101, 115, 155, 167, &
7, 54, 58, 104, 131, 150, 173, &
4, 45, 66, 99, 132, 152, 0, &
15, 53, 84, 88, 132, 164, 0, &
25, 30, 77, 110, 122, 137, 164, &
23, 52, 67, 107, 133, 144, 174, &
23, 40, 59, 111, 137, 140, 0, &
14, 38, 68, 110, 120, 169, 0, &
24, 35, 72, 102, 127, 153, 172, &
28, 55, 84, 101, 125, 165, 174, &
15, 42, 63, 95, 130, 169, 0, &
4, 56, 85, 91, 134, 162, 170, &
25, 55, 65, 89, 133, 156, 0, &
5, 48, 63, 109, 135, 160, 0, &
10, 53, 64, 87, 121, 140, 0, &
9, 50, 82, 108, 138, 154, 0, &
14, 54, 69, 99, 115, 157, 166, &
17, 36, 56, 103, 130, 148, 0, &
3, 47, 56, 73, 121, 154, 0, &
1, 52, 77, 94, 139, 158, 0, &
5, 28, 71, 110, 138, 147, 0, &
27, 45, 68, 106, 124, 167, 0, &
18, 51, 59, 98, 139, 162, 0, &
2, 50, 80, 103, 120, 161, 0, &
11, 46, 84, 86, 129, 166, 0, &
20, 55, 73, 102, 119, 168, 0, &
28, 43, 61, 111, 112, 146, 0, &
11, 51, 83, 91, 135, 143, 0, &
6, 46, 58, 111, 123, 148, 169, &
26, 32, 79, 112, 116, 153, 0, &
27, 49, 71, 89, 104, 163, 0, &
12, 34, 78, 109, 117, 155, 0, &
13, 47, 61, 94, 136, 159, 160, &
17, 54, 82, 106, 137, 159, 0, &
26, 44, 81, 90, 128, 156, 0, &
7, 31, 74, 97, 138, 145, 0, &
24, 37, 80, 98, 118, 145, 171/
data nrw/ &
7,7,7,7,7,7,7,6,6,7,6,6,7,7,6,6,7,6, &
6,6,6,6,7,6,6,6,6,6,6,6,6,6,7,6,6,6, &
6,6,6,6,6,6,6,6,6,6,7,7,6,6,7,7,6,6, &
7,7,6,7,6,6,6,6,7,6,6,6,6,6,6,6,6,6, &
6,6,7,6,6,6,7,6,6,6,7/
ncw=3
decoded=0
toc=0
tov=0
tanhtoc=0
! initialize messages to checks
do j=1,M
do i=1,nrw(j)
toc(i,j)=llr((Nm(i,j)))
enddo
enddo
ncnt=0
do iter=0,maxiterations
! Update bit log likelihood ratios (tov=0 in iteration 0).
do i=1,N
if( apmask(i) .ne. 1 ) then
zn(i)=llr(i)+sum(tov(1:ncw,i))
else
zn(i)=llr(i)
endif
enddo
! Check to see if we have a codeword (check before we do any iteration).
cw=0
where( zn .gt. 0. ) cw=1
ncheck=0
do i=1,M
synd(i)=sum(cw(Nm(1:nrw(i),i)))
if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1
! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied'
enddo
! write(*,*) 'number of unsatisfied parity checks ',ncheck
if( ncheck .eq. 0 ) then ! we have a codeword - reorder the columns and return it
codeword=cw(colorder+1)
decoded=codeword(M+1:N)
nerr=0
do i=1,N
if( (2*cw(i)-1)*llr(i) .lt. 0.0 ) nerr=nerr+1
enddo
nharderror=nerr
return
endif
if( iter.gt.0 ) then ! this code block implements an early stopping criterion
! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion
nd=ncheck-nclast
if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased
ncnt=0 ! reset counter
else
ncnt=ncnt+1
endif
! write(*,*) iter,ncheck,nd,ncnt
if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then
nharderror=-1
return
endif
endif
nclast=ncheck
! Send messages from bits to check nodes
do j=1,M
do i=1,nrw(j)
ibj=Nm(i,j)
toc(i,j)=zn(ibj)
do kk=1,ncw ! subtract off what the bit had received from the check
if( Mn(kk,ibj) .eq. j ) then
toc(i,j)=toc(i,j)-tov(kk,ibj)
endif
enddo
enddo
enddo
! send messages from check nodes to variable nodes
do i=1,M
tanhtoc(1:6,i)=tanh(-toc(1:6,i)/2)
enddo
do j=1,N
do i=1,ncw
ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j
Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j)
call platanh(-Tmn,y)
! y=atanh(-Tmn)
tov(i,j)=2*y
enddo
enddo
enddo
nharderror=-1
return
end subroutine bpdecode174b

14
lib/fsk4hf/costasxcorr.m Normal file
View File

@ -0,0 +1,14 @@
# Gnu Octave script to calculate
# cross correlation between 2 Costas arrays
costas1=[2,5,6,0,4,1,3];
costas2=[3,1,4,0,6,5,2];
array1=zeros(7,7);
array2=zeros(7,7);
for i=1:7
array1(i,costas1(i)+1)=1;
array2(i,costas2(i)+1)=1;
endfor
xcorr2(array1,array1,"none")
xcorr2(array2,array2,"none")
xcorr2(array1,array2,"none")

View File

@ -0,0 +1,56 @@
subroutine encode4K25A(message,codeword)
! A (280,70) rate 1/4 tailbiting convolutional code using
! the "4K25A" polynomials from EbNaut website.
! Code is transparent, has constraint length 25, and has dmin=58
character*10 g1,g2,g3,g4
integer*1 codeword(280)
!integer*1 p1(25),p2(25),p3(25),p4(25)
integer*1 p1(16),p2(16),p3(16),p4(16)
integer*1 gg(100)
integer*1 gen(280,70)
integer*1 itmp(280)
integer*1 message(70)
logical first
data first/.true./
data g1/"106042635"/
data g2/"125445117"/
data g3/"152646773"/
data g4/"167561761"/
!data p1/1,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,1,1,0,0,1,1,1,0,1/
!data p2/1,0,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,1,1/
!data p3/1,1,0,1,0,1,0,1,1,0,1,0,0,1,1,0,1,1,1,1,1,1,0,1,1/
!data p4/1,1,1,0,1,1,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,1/
data p1/1,0,1,0,1,1,0,0,1,1,0,1,1,1,1,1/
data p2/1,0,1,1,0,1,0,0,1,1,1,1,1,0,0,1/
data p3/1,1,0,0,1,0,1,1,0,1,1,1,0,0,1,1/
data p4/1,1,1,0,1,1,0,1,1,1,1,0,0,1,0,1/
save first,gen
if( first ) then ! fill the generator matrix
gg=0
! gg(1:25)=p1
! gg(26:50)=p2
! gg(51:75)=p3
! gg(76:100)=p4
gg(1:16)=p1
gg(17:32)=p2
gg(33:48)=p3
gg(49:64)=p4
gen=0
! gen(1:100,1)=gg(1:100)
gen(1:64,1)=gg(1:64)
do i=2,70
gen(:,i)=cshift(gen(:,i-1),-4,1)
enddo
first=.false.
endif
codeword=0
do i=1,70
if(message(i).eq.1) codeword=codeword+gen(:,i)
enddo
codeword=mod(codeword,2)
return
end subroutine encode4K25A

View File

@ -0,0 +1,11 @@
data colorder/ &
0, 1, 2, 3, 28, 4, 5, 6, 7, 8, 9, 10, 11, 34, 12, 32, 13, 14, 15, 16,&
17, 18, 36, 29, 40, 19, 20, 38, 21, 41, 30, 42, 22, 44, 37, 47, 48, 23, 33, 43,&
49, 45, 56, 39, 25, 26, 46, 50, 51, 52, 24, 57, 58, 61, 31, 54, 64, 35, 27, 62,&
59, 53, 60, 63, 55, 70, 66, 67, 68, 65, 71, 74, 72, 73, 77, 75, 69, 76, 79, 82,&
83, 78, 81, 80, 84, 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/

View File

@ -0,0 +1,87 @@
character*23 g(83)
data g/ &
"2a6a9ab98f661b797baa21a", &
"5fda604488977fdc30ff630", &
"8a450007032409e8797b13a", &
"0f7923bfa5d559590ef6efe", &
"44dc14bc4461e645f847c78", &
"f8c66224febd3e60f5e3708", &
"6d60329e83fb0e1b1bdac2e", &
"66435a472a7837a0e5d4e12", &
"9d0feced8745a66e328c310", &
"1791b0e7c5eaa43710c4276", &
"e5cbd2d5b4d65d3a432d97e", &
"c2241f8795e0e5bc6bd9052", &
"222d861201a4697c2689576", &
"aa2ee5d6d462e206f59cbe8", &
"e486eb73894e6a0964d8c40", &
"4099d5b42d36301cff6dbd6", &
"40c50b9341f7b5ea08dabde", &
"c90359074895363d428f072", &
"ca819cb6569fbfe26b68ef8", &
"4d983341fb56b8e1dae3450", &
"2dce341bc8fd0e5de04fa52", &
"3e7b01b376e3e5f6080de0e", &
"6c8b0813ca2394c08564f94", &
"c322ca8ea866784adc9451a", &
"6378aa1a03fab3e163aa4b0", &
"3c92ea8df0003883a021d70", &
"c793729067176eca26b83c2", &
"d3fae76046a36dff711207a", &
"bc9bf3ef57137fda1c325da", &
"a4eabe2df65a083ea6387c8", &
"650e3da3a0c0349154131d8", &
"1fb4c59ffc11c648ad06760", &
"1471f9599543f13fd7eb6ae", &
"6111012405186e84cba67ce", &
"c4da3574edafefff976fc08", &
"953f854e40701063115c0f2", &
"1f7ae6982f9a5733c44fb70", &
"83e101fe5e80c1b8541728e", &
"50375654edd53054f81e228", &
"1bb03a21a6cde34dff7ec96", &
"b0b279a934342aa0e188b3a", &
"e1989846a20a09cd77b1f64", &
"4eb68e01cb07fdbc83edee2", &
"f33ac4ec36a7c8e6ea8364c", &
"99b03a21a6c5e34dfffec96", &
"e50e3de3a1c034915413158", &
"fda09f8b05b8fb80ac78600", &
"ca8709be6b193204dd25ab0", &
"35701ff0cc3a03f213a93d2", &
"c2bfdec67f7b5a4c5ee7544", &
"dc184fe7e93a65c1b4b7cd2", &
"8cf8aac820f107d6ec6b30a", &
"e74b3da5a3e43d593d680e2", &
"c1e51f79db6124243fceadc", &
"29237d5d05dc1a4cca2ddd0", &
"050e76be4749b3b279d6414", &
"dd163959ae739673cde18c6", &
"03e100fe5e81c1b85417a8e", &
"06b2b17f70e75fc365bed20", &
"6df9e72abecd3e03e4b77fa", &
"4fa5370361b4bf3cf6b1296", &
"eabbf88f0a88307629bfd1c", &
"190674f88cf69989c8b8a40", &
"37740c13cfad07f61dcac3a", &
"4e7923bfa5d579590ef4ede", &
"fe74d37b8e5a63a2905da28", &
"2101e7a95979b2c5c44257e", &
"841f3ec7a4585a159fb5796", &
"aa7ff31d4b7f859c21254c2", &
"6e69229ba0cdb7ddcd50930", &
"29cfc4288af223bea58b96e", &
"5d03eba9f51956176b87abe", &
"399cbc33a7498b31d9f79e4", &
"034967e48ab80135b1c7fca", &
"721ad006ac715928df9775e", &
"37210b395327446ac7108f8", &
"52acf6de27477ea937e5330", &
"1f3a8549435c198b68231c8", &
"ef6809edb4a3557cd173d0a", &
"09a31639fef9c7a8b6fcae2", &
"03bc87c137eeec711c68d36", &
"b09347742319f90131d3146", &
"a723c9cef1de8c97f34c94c"/

View File

@ -0,0 +1,100 @@
integer, parameter:: N=174, K=91, M=N-K
character*23 g(83)
integer colorder(N)
data g/ &
"2a6a9ab98f661b797baa21a", &
"5fda604488977fdc30ff630", &
"8a450007032409e8797b13a", &
"0f7923bfa5d559590ef6efe", &
"44dc14bc4461e645f847c78", &
"f8c66224febd3e60f5e3708", &
"6d60329e83fb0e1b1bdac2e", &
"66435a472a7837a0e5d4e12", &
"9d0feced8745a66e328c310", &
"1791b0e7c5eaa43710c4276", &
"e5cbd2d5b4d65d3a432d97e", &
"c2241f8795e0e5bc6bd9052", &
"222d861201a4697c2689576", &
"aa2ee5d6d462e206f59cbe8", &
"e486eb73894e6a0964d8c40", &
"4099d5b42d36301cff6dbd6", &
"40c50b9341f7b5ea08dabde", &
"c90359074895363d428f072", &
"ca819cb6569fbfe26b68ef8", &
"4d983341fb56b8e1dae3450", &
"2dce341bc8fd0e5de04fa52", &
"3e7b01b376e3e5f6080de0e", &
"6c8b0813ca2394c08564f94", &
"c322ca8ea866784adc9451a", &
"6378aa1a03fab3e163aa4b0", &
"3c92ea8df0003883a021d70", &
"c793729067176eca26b83c2", &
"d3fae76046a36dff711207a", &
"bc9bf3ef57137fda1c325da", &
"a4eabe2df65a083ea6387c8", &
"650e3da3a0c0349154131d8", &
"1fb4c59ffc11c648ad06760", &
"1471f9599543f13fd7eb6ae", &
"6111012405186e84cba67ce", &
"c4da3574edafefff976fc08", &
"953f854e40701063115c0f2", &
"1f7ae6982f9a5733c44fb70", &
"83e101fe5e80c1b8541728e", &
"50375654edd53054f81e228", &
"1bb03a21a6cde34dff7ec96", &
"b0b279a934342aa0e188b3a", &
"e1989846a20a09cd77b1f64", &
"4eb68e01cb07fdbc83edee2", &
"f33ac4ec36a7c8e6ea8364c", &
"99b03a21a6c5e34dfffec96", &
"e50e3de3a1c034915413158", &
"fda09f8b05b8fb80ac78600", &
"ca8709be6b193204dd25ab0", &
"35701ff0cc3a03f213a93d2", &
"c2bfdec67f7b5a4c5ee7544", &
"dc184fe7e93a65c1b4b7cd2", &
"8cf8aac820f107d6ec6b30a", &
"e74b3da5a3e43d593d680e2", &
"c1e51f79db6124243fceadc", &
"29237d5d05dc1a4cca2ddd0", &
"050e76be4749b3b279d6414", &
"dd163959ae739673cde18c6", &
"03e100fe5e81c1b85417a8e", &
"06b2b17f70e75fc365bed20", &
"6df9e72abecd3e03e4b77fa", &
"4fa5370361b4bf3cf6b1296", &
"eabbf88f0a88307629bfd1c", &
"190674f88cf69989c8b8a40", &
"37740c13cfad07f61dcac3a", &
"4e7923bfa5d579590ef4ede", &
"fe74d37b8e5a63a2905da28", &
"2101e7a95979b2c5c44257e", &
"841f3ec7a4585a159fb5796", &
"aa7ff31d4b7f859c21254c2", &
"6e69229ba0cdb7ddcd50930", &
"29cfc4288af223bea58b96e", &
"5d03eba9f51956176b87abe", &
"399cbc33a7498b31d9f79e4", &
"034967e48ab80135b1c7fca", &
"721ad006ac715928df9775e", &
"37210b395327446ac7108f8", &
"52acf6de27477ea937e5330", &
"1f3a8549435c198b68231c8", &
"ef6809edb4a3557cd173d0a", &
"09a31639fef9c7a8b6fcae2", &
"03bc87c137eeec711c68d36", &
"b09347742319f90131d3146", &
"a723c9cef1de8c97f34c94c"/
data colorder/ &
0, 1, 2, 3, 28, 4, 5, 6, 7, 8, 9, 10, 11, 34, 12, 32, 13, 14, 15, 16,&
17, 18, 36, 29, 40, 19, 20, 38, 21, 41, 30, 42, 22, 44, 37, 47, 48, 23, 33, 43,&
49, 45, 56, 39, 25, 26, 46, 50, 51, 52, 24, 57, 58, 61, 31, 54, 64, 35, 27, 62,&
59, 53, 60, 63, 55, 70, 66, 67, 68, 65, 71, 74, 72, 73, 77, 75, 69, 76, 79, 82,&
83, 78, 81, 80, 84, 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/

View File

@ -0,0 +1,269 @@
data Mn/ &
1, 24, 66, &
2, 5, 70, &
3, 31, 65, &
4, 49, 58, &
6, 60, 67, &
7, 32, 75, &
8, 48, 82, &
9, 35, 41, &
10, 39, 62, &
11, 14, 61, &
12, 71, 74, &
13, 23, 78, &
15, 16, 79, &
17, 54, 63, &
18, 50, 57, &
19, 30, 47, &
20, 64, 80, &
21, 28, 69, &
22, 25, 43, &
26, 34, 72, &
27, 36, 37, &
29, 40, 44, &
33, 52, 53, &
38, 55, 83, &
42, 51, 59, &
45, 76, 81, &
46, 68, 77, &
56, 67, 73, &
1, 4, 5, &
2, 47, 51, &
3, 46, 82, &
6, 24, 76, &
7, 9, 16, &
8, 10, 78, &
11, 35, 55, &
12, 38, 64, &
13, 42, 83, &
14, 27, 54, &
15, 21, 34, &
17, 44, 53, &
18, 25, 28, &
19, 33, 57, &
20, 22, 73, &
23, 40, 81, &
26, 49, 68, &
29, 71, 75, &
30, 65, 79, &
31, 36, 60, &
32, 43, 77, &
37, 62, 70, &
39, 69, 74, &
41, 52, 66, &
45, 50, 61, &
48, 63, 80, &
56, 59, 72, &
58, 64, 65, &
1, 13, 28, &
2, 48, 75, &
3, 53, 69, &
4, 11, 44, &
5, 73, 79, &
6, 12, 17, &
7, 57, 60, &
8, 15, 61, &
9, 39, 59, &
10, 19, 49, &
14, 43, 52, &
16, 54, 68, &
18, 41, 63, &
20, 36, 45, &
21, 67, 77, &
10, 22, 55, &
23, 65, 72, &
24, 27, 82, &
25, 26, 29, &
30, 35, 37, &
31, 51, 66, &
17, 32, 78, &
33, 42, 76, &
34, 70, 83, &
38, 46, 81, &
40, 62, 80, &
45, 47, 74, &
50, 56, 71, &
7, 37, 58, &
1, 16, 71, &
2, 6, 61, &
3, 22, 50, &
4, 59, 77, &
5, 41, 81, &
8, 58, 74, &
9, 20, 26, &
11, 21, 31, &
12, 66, 79, &
13, 14, 57, &
15, 33, 40, &
18, 44, 82, &
19, 69, 83, &
23, 49, 63, &
24, 29, 39, &
25, 47, 56, &
27, 55, 72, &
28, 64, 70, &
30, 48, 77, &
32, 34, 45, &
35, 68, 80, &
36, 38, 52, &
42, 43, 62, &
46, 60, 78, &
51, 54, 67, &
53, 73, 75, &
14, 73, 76, &
1, 22, 30, &
2, 35, 43, &
3, 47, 63, &
4, 25, 76, &
5, 33, 78, &
6, 20, 83, &
7, 12, 72, &
8, 54, 70, &
9, 61, 65, &
10, 34, 51, &
11, 46, 75, &
13, 39, 68, &
15, 17, 56, &
16, 23, 36, &
18, 32, 55, &
19, 31, 81, &
21, 37, 71, &
24, 57, 64, &
26, 38, 48, &
27, 49, 50, &
28, 52, 59, &
29, 41, 58, &
40, 60, 74, &
42, 44, 79, &
51, 53, 80, &
62, 67, 82, &
23, 66, 69, &
1, 53, 61, &
2, 18, 39, &
3, 4, 12, &
5, 26, 74, &
6, 30, 52, &
7, 82, 83, &
8, 35, 73, &
9, 19, 67, &
10, 64, 75, &
11, 20, 33, &
13, 45, 48, &
3, 14, 40, &
15, 43, 49, &
16, 55, 76, &
17, 62, 65, &
21, 47, 78, &
22, 59, 81, &
24, 34, 63, &
25, 37, 66, &
27, 79, 80, &
28, 60, 79, &
29, 31, 70, &
32, 58, 69, &
10, 36, 77, &
38, 50, 51, &
13, 41, 56, &
42, 63, 71, &
44, 47, 68, &
1, 46, 72, &
54, 57, 75, &
2, 33, 58, &
4, 17, 83, &
5, 14, 55, &
6, 23, 48, &
7, 52, 56/
data Nm/ &
1, 29, 57, 86, 113, 140, 168, &
2, 30, 58, 87, 114, 141, 170, &
3, 31, 59, 88, 115, 142, 151, &
4, 29, 60, 89, 116, 142, 171, &
2, 29, 61, 90, 117, 143, 172, &
5, 32, 62, 87, 118, 144, 173, &
6, 33, 63, 85, 119, 145, 174, &
7, 34, 64, 91, 120, 146, 0, &
8, 33, 65, 92, 121, 147, 0, &
9, 34, 66, 72, 122, 148, 163, &
10, 35, 60, 93, 123, 149, 0, &
11, 36, 62, 94, 119, 142, 0, &
12, 37, 57, 95, 124, 150, 165, &
10, 38, 67, 95, 112, 151, 172, &
13, 39, 64, 96, 125, 152, 0, &
13, 33, 68, 86, 126, 153, 0, &
14, 40, 62, 78, 125, 154, 171, &
15, 41, 69, 97, 127, 141, 0, &
16, 42, 66, 98, 128, 147, 0, &
17, 43, 70, 92, 118, 149, 0, &
18, 39, 71, 93, 129, 155, 0, &
19, 43, 72, 88, 113, 156, 0, &
12, 44, 73, 99, 126, 139, 173, &
1, 32, 74, 100, 130, 157, 0, &
19, 41, 75, 101, 116, 158, 0, &
20, 45, 75, 92, 131, 143, 0, &
21, 38, 74, 102, 132, 159, 0, &
18, 41, 57, 103, 133, 160, 0, &
22, 46, 75, 100, 134, 161, 0, &
16, 47, 76, 104, 113, 144, 0, &
3, 48, 77, 93, 128, 161, 0, &
6, 49, 78, 105, 127, 162, 0, &
23, 42, 79, 96, 117, 149, 170, &
20, 39, 80, 105, 122, 157, 0, &
8, 35, 76, 106, 114, 146, 0, &
21, 48, 70, 107, 126, 163, 0, &
21, 50, 76, 85, 129, 158, 0, &
24, 36, 81, 107, 131, 164, 0, &
9, 51, 65, 100, 124, 141, 0, &
22, 44, 82, 96, 135, 151, 0, &
8, 52, 69, 90, 134, 165, 0, &
25, 37, 79, 108, 136, 166, 0, &
19, 49, 67, 108, 114, 152, 0, &
22, 40, 60, 97, 136, 167, 0, &
26, 53, 70, 83, 105, 150, 0, &
27, 31, 81, 109, 123, 168, 0, &
16, 30, 83, 101, 115, 155, 167, &
7, 54, 58, 104, 131, 150, 173, &
4, 45, 66, 99, 132, 152, 0, &
15, 53, 84, 88, 132, 164, 0, &
25, 30, 77, 110, 122, 137, 164, &
23, 52, 67, 107, 133, 144, 174, &
23, 40, 59, 111, 137, 140, 0, &
14, 38, 68, 110, 120, 169, 0, &
24, 35, 72, 102, 127, 153, 172, &
28, 55, 84, 101, 125, 165, 174, &
15, 42, 63, 95, 130, 169, 0, &
4, 56, 85, 91, 134, 162, 170, &
25, 55, 65, 89, 133, 156, 0, &
5, 48, 63, 109, 135, 160, 0, &
10, 53, 64, 87, 121, 140, 0, &
9, 50, 82, 108, 138, 154, 0, &
14, 54, 69, 99, 115, 157, 166, &
17, 36, 56, 103, 130, 148, 0, &
3, 47, 56, 73, 121, 154, 0, &
1, 52, 77, 94, 139, 158, 0, &
5, 28, 71, 110, 138, 147, 0, &
27, 45, 68, 106, 124, 167, 0, &
18, 51, 59, 98, 139, 162, 0, &
2, 50, 80, 103, 120, 161, 0, &
11, 46, 84, 86, 129, 166, 0, &
20, 55, 73, 102, 119, 168, 0, &
28, 43, 61, 111, 112, 146, 0, &
11, 51, 83, 91, 135, 143, 0, &
6, 46, 58, 111, 123, 148, 169, &
26, 32, 79, 112, 116, 153, 0, &
27, 49, 71, 89, 104, 163, 0, &
12, 34, 78, 109, 117, 155, 0, &
13, 47, 61, 94, 136, 159, 160, &
17, 54, 82, 106, 137, 159, 0, &
26, 44, 81, 90, 128, 156, 0, &
7, 31, 74, 97, 138, 145, 0, &
24, 37, 80, 98, 118, 145, 171/
data nrw/ &
7,7,7,7,7,7,7,6,6,7,6,6,7,7,6,6,7,6, &
6,6,6,6,7,6,6,6,6,6,6,6,6,6,7,6,6,6, &
6,6,6,6,6,6,6,6,6,6,7,7,6,6,7,7,6,6, &
7,7,6,7,6,6,6,6,7,6,6,6,6,6,6,6,6,6, &
6,6,7,6,6,6,7,6,6,6,7/
ncw=3

View File

@ -66,8 +66,8 @@ allocate ( rxdata(N), llr(N) )
! msg="K1JT K9AN EN50"
msg="G4WJS K9AN EN50"
call packmsg(msg,i4Msg6BitWords,itype,.false.) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent,.false.,'') !Unpack to get msgsent
call packmsg(msg,i4Msg6BitWords,itype) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent
write(*,*) "message sent ",msgsent
i4=0

View File

@ -67,8 +67,8 @@ allocate ( rxdata(N), llr(N) )
msg="K1JT K9AN EN50"
! 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
call packmsg(msg,i4Msg6BitWords,itype) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent
write(*,*) "message sent ",msgsent
i4=0
@ -129,11 +129,11 @@ allocate ( rxdata(N), llr(N) )
write(*,*) 'codeword'
write(*,'(22(8i1,1x))') codeword
write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma"
write(*,*) "Eb/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)) )
sigma=1/sqrt( 2*rate*(10**(db/10.0)) )
ngood=0
nue=0
nbadcrc=0
@ -163,7 +163,6 @@ do idb = 20,-10,-1
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)

View File

@ -0,0 +1,136 @@
program ldpcsim174_91
! End to end test of the (174,91)/crc14 encoder and decoder.
use crc
use packjt77
integer, parameter:: N=174, K=91, M=N-K
character*37 msg,msgsent,msgreceived
character*77 c77
character*8 arg
character*6 grid
character*96 tmpchar
integer*1, allocatable :: codeword(:), decoded(:), message(:)
integer*1 msgbits(77)
integer*1 message77(77)
integer*1 apmask(N), cw(N)
integer nerrtot(0:N),nerrdec(0:N)
logical unpk77_success
real*8, allocatable :: rxdata(:)
real, allocatable :: llr(:)
nerrtot=0
nerrdec=0
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
! scale Eb/No for a (174,91) 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="K1JT K9AN EN50"
msg="G4WJS K9AN EN50"
i3=0
n3=1
call pack77(msg,i3,n3,c77) !Pack into 12 6-bit bytes
call unpack77(c77,msgsent,unpk77_success) !Unpack to get msgsent
write(*,*) "message sent ",msgsent
read(c77,'(77i1)') msgbits(1:77)
write(*,*) 'message'
write(*,'(a71,1x,a3,1x,a3)') c77(1:71),c77(72:74),c77(75:77)
call encode174_91(msgbits,codeword)
call init_random_seed()
write(*,*) 'codeword'
write(*,'(22(8i1,1x))') codeword
write(*,*) "Eb/N0 SNR2500 ngood nundetected sigma psymerr"
do idb = 20,-10,-1
!do idb = 0,0,-1
db=idb/2.0-1.0
sigma=1/sqrt( 2*rate*(10**(db/10.0)) )
ngood=0
nue=0
nsumerr=0
do itrial=1, ntrials
! Create a realization of a noisy received word
do i=1,N
rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
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
rxav=sum(rxdata)/N
rx2av=sum(rxdata*rxdata)/N
rxsig=sqrt(rx2av-rxav*rxav)
rxdata=rxdata/rxsig
if( s .lt. 0 ) then
ss=sigma
else
ss=s
endif
llr=2.0*rxdata/(ss*ss)
nap=0 ! number of AP bits
llr(1:nap)=5*(2.0*msgbits(1:nap)-1.0)
apmask=0
apmask(1:nap)=1
! max_iterations is max number of belief propagation iterations
call bpdecode174_91(llr, apmask, max_iterations, message77, cw, nharderrors,niterations)
if( ndepth .ge. 0 .and. nharderrors .lt. 0 ) call osd174_91(llr, apmask, ndepth, message77, cw, nharderrors, dmin)
! If the decoder finds a valid codeword, nharderrors will be .ge. 0.
if( nharderrors .ge. 0 ) then
call extractmessage77(message77,msgreceived)
nhw=count(cw.ne.codeword)
if(nhw.eq.0) then ! this is a good decode
ngood=ngood+1
nerrdec(nerr)=nerrdec(nerr)+1
else
nue=nue+1
endif
endif
nsumerr=nsumerr+nerr
enddo
baud=12000/1920
snr2500=db+10.0*log10((baud/2500.0))
pberr=real(nsumerr)/(real(ntrials*N))
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,SNR2500,ngood,nue,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)
end program ldpcsim174_91

372
lib/fsk4hf/osdtbcc.f90 Normal file
View File

@ -0,0 +1,372 @@
subroutine osdtbcc(llr,apmask,ndeep,decoded,cw,nhardmin,dmin)
!
use iso_c_binding
parameter (N=280, K=70, L=16)
integer*1 p1(L),p2(L),p3(L),p4(L)
integer*1 gg(100)
integer*1 apmask(N),apmaskr(N)
integer*1 gen(K,N)
integer*1 genmrb(K,N),g2(N,K)
integer*1 temp(K),m0(K),me(K),mi(K),misub(K),e2sub(N-K),e2(N-K),ui(N-K)
integer*1 r2pat(N-K)
integer indices(N),nxor(N)
integer*1 cw(N),ce(N),c0(N),hdec(N)
integer*1 decoded(K)
integer indx(N)
real llr(N),rx(N),absrx(N)
logical first,reset
data first/.true./
!data p1/1,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,1,1,0,0,1,1,1,0,1/
!data p2/1,0,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,1,1/
!data p3/1,1,0,1,0,1,0,1,1,0,1,0,0,1,1,0,1,1,1,1,1,1,0,1,1/
!data p4/1,1,1,0,1,1,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,1/
data p1/1,0,1,0,1,1,0,0,1,1,0,1,1,1,1,1/
data p2/1,0,1,1,0,1,0,0,1,1,1,1,1,0,0,1/
data p3/1,1,0,0,1,0,1,1,0,1,1,1,0,0,1,1/
data p4/1,1,1,0,1,1,0,1,1,1,1,0,0,1,0,1/
save first,gen
if( first ) then ! fill the generator matrix
gg=0
gg(1:L)=p1
gg(L+1:2*L)=p2
gg(2*L+1:3*L)=p3
gg(3*L+1:4*L)=p4
gen=0
gen(1,1:4*L)=gg(1:4*L)
do i=2,K
gen(i,:)=cshift(gen(i-1,:),-4)
enddo
first=.false.
endif
! Re-order received vector to place systematic msg bits at the end.
rx=llr
apmaskr=apmask
! Hard decisions on the received word.
hdec=0
where(rx .ge. 0) hdec=1
! Use magnitude of received symbols as a measure of reliability.
absrx=abs(rx)
call indexx(absrx,N,indx)
! Re-order the columns of the generator matrix in order of decreasing reliability.
do i=1,N
genmrb(1:K,i)=gen(1:K,indx(N+1-i))
indices(i)=indx(N+1-i)
enddo
! Do gaussian elimination to create a generator matrix with the most reliable
! received bits in positions 1:K in order of decreasing reliability (more or less).
do id=1,K ! diagonal element indices
do icol=id,K+20 ! The 20 is ad hoc - beware
iflag=0
if( genmrb(id,icol) .eq. 1 ) then
iflag=1
if( icol .ne. id ) then ! reorder column
temp(1:K)=genmrb(1:K,id)
genmrb(1:K,id)=genmrb(1:K,icol)
genmrb(1:K,icol)=temp(1:K)
itmp=indices(id)
indices(id)=indices(icol)
indices(icol)=itmp
endif
do ii=1,K
if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then
genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N))
endif
enddo
exit
endif
enddo
enddo
g2=transpose(genmrb)
! The hard decisions for the K MRB bits define the order 0 message, m0.
! Encode m0 using the modified generator matrix to find the "order 0" codeword.
! Flip various combinations of bits in m0 and re-encode to generate a list of
! codewords. Return the member of the list that has the smallest Euclidean
! distance to the received word.
hdec=hdec(indices) ! hard decisions from received symbols
m0=hdec(1:K) ! zero'th order message
absrx=absrx(indices)
rx=rx(indices)
apmaskr=apmaskr(indices)
call mrbencode(m0,c0,g2,N,K)
nxor=ieor(c0,hdec)
nhardmin=sum(nxor)
dmin=sum(nxor*absrx)
cw=c0
ntotal=0
nrejected=0
if(ndeep.eq.0) goto 998 ! norder=0
if(ndeep.gt.5) ndeep=5
if( ndeep.eq. 1) then
nord=1
npre1=0
npre2=0
nt=120
ntheta=12
elseif(ndeep.eq.2) then
nord=1
npre1=1
npre2=0
nt=120
ntheta=12
elseif(ndeep.eq.3) then
nord=1
npre1=1
npre2=1
nt=120
ntheta=12
ntau=15
elseif(ndeep.eq.4) then
nord=2
npre1=1
npre2=0
nt=120
ntheta=12
ntau=15
elseif(ndeep.eq.5) then
nord=3
npre1=1
npre2=1
nt=80
ntheta=22
ntau=16
endif
do iorder=1,nord
misub(1:K-iorder)=0
misub(K-iorder+1:K)=1
iflag=K-iorder+1
do while(iflag .ge.0)
if(iorder.eq.nord .and. npre1.eq.0) then
iend=iflag
else
iend=1
endif
do n1=iflag,iend,-1
mi=misub
mi(n1)=1
if(any(iand(apmaskr(1:K),mi).eq.1)) cycle
ntotal=ntotal+1
me=ieor(m0,mi)
if(n1.eq.iflag) then
call mrbencode(me,ce,g2,N,K)
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
e2=e2sub
nd1Kpt=sum(e2sub(1:nt))+1
d1=sum(ieor(me(1:K),hdec(1:K))*absrx(1:K))
else
e2=ieor(e2sub,g2(K+1:N,n1))
nd1Kpt=sum(e2(1:nt))+2
endif
if(nd1Kpt .le. ntheta) then
call mrbencode(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
if(n1.eq.iflag) then
dd=d1+sum(e2sub*absrx(K+1:N))
else
dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(K+1:N))
endif
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
nd1Kptbest=nd1Kpt
endif
else
nrejected=nrejected+1
endif
enddo
! Get the next test error pattern, iflag will go negative
! when the last pattern with weight iorder has been generated.
call nextpat(misub,k,iorder,iflag)
enddo
enddo
if(npre2.eq.1) then
reset=.true.
ntotal=0
do i1=K,1,-1
do i2=i1-1,1,-1
ntotal=ntotal+1
mi(1:ntau)=ieor(g2(K+1:K+ntau,i1),g2(K+1:K+ntau,i2))
call boxit(reset,mi(1:ntau),ntau,ntotal,i1,i2)
enddo
enddo
ncount2=0
ntotal2=0
reset=.true.
! Now run through again and do the second pre-processing rule
misub(1:K-nord)=0
misub(K-nord+1:K)=1
iflag=K-nord+1
do while(iflag .ge.0)
me=ieor(m0,misub)
call mrbencode(me,ce,g2,N,K)
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
do i2=0,ntau
ntotal2=ntotal2+1
ui=0
if(i2.gt.0) ui(i2)=1
r2pat=ieor(e2sub,ui)
778 continue
call fetchit(reset,r2pat(1:ntau),ntau,in1,in2)
if(in1.gt.0.and.in2.gt.0) then
ncount2=ncount2+1
mi=misub
mi(in1)=1
mi(in2)=1
if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:K),mi).eq.1)) cycle
me=ieor(m0,mi)
call mrbencode(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
dd=sum(nxor*absrx)
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
endif
goto 778
endif
enddo
call nextpat(misub,K,nord,iflag)
enddo
endif
998 continue
! Re-order the codeword to place message bits at the end.
cw(indices)=cw
hdec(indices)=hdec
decoded=0
return
end subroutine osdtbcc
subroutine mrbencode(me,codeword,g2,N,K)
integer*1 me(K),codeword(N),g2(N,K)
! fast encoding for low-weight test patterns
codeword=0
do i=1,K
if( me(i) .eq. 1 ) then
codeword=ieor(codeword,g2(1:N,i))
endif
enddo
return
end subroutine mrbencode
subroutine nextpat(mi,k,iorder,iflag)
integer*1 mi(k),ms(k)
! generate the next test error pattern
ind=-1
do i=1,k-1
if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i
enddo
if( ind .lt. 0 ) then ! no more patterns of this order
iflag=ind
return
endif
ms=0
ms(1:ind-1)=mi(1:ind-1)
ms(ind)=1
ms(ind+1)=0
if( ind+1 .lt. k ) then
nz=iorder-sum(ms)
ms(k-nz+1:k)=1
endif
mi=ms
do i=1,k ! iflag will point to the lowest-index 1 in mi
if(mi(i).eq.1) then
iflag=i
exit
endif
enddo
return
end subroutine nextpat
subroutine boxit(reset,e2,ntau,npindex,i1,i2)
integer*1 e2(1:ntau)
integer indexes(4000,2),fp(0:525000),np(4000)
logical reset
common/boxes/indexes,fp,np
if(reset) then
patterns=-1
fp=-1
np=-1
sc=-1
indexes=-1
reset=.false.
endif
indexes(npindex,1)=i1
indexes(npindex,2)=i2
ipat=0
do i=1,ntau
if(e2(i).eq.1) then
ipat=ipat+ishft(1,ntau-i)
endif
enddo
ip=fp(ipat) ! see what's currently stored in fp(ipat)
if(ip.eq.-1) then
fp(ipat)=npindex
else
do while (np(ip).ne.-1)
ip=np(ip)
enddo
np(ip)=npindex
endif
return
end subroutine boxit
subroutine fetchit(reset,e2,ntau,i1,i2)
integer indexes(4000,2),fp(0:525000),np(4000)
integer lastpat
integer*1 e2(ntau)
logical reset
common/boxes/indexes,fp,np
save lastpat,inext
if(reset) then
lastpat=-1
reset=.false.
endif
ipat=0
do i=1,ntau
if(e2(i).eq.1) then
ipat=ipat+ishft(1,ntau-i)
endif
enddo
index=fp(ipat)
if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices
i1=indexes(index,1)
i2=indexes(index,2)
inext=np(index)
elseif(lastpat.eq.ipat .and. inext.gt.0) then
i1=indexes(inext,1)
i2=indexes(inext,2)
inext=np(inext)
else
i1=-1
i2=-1
inext=-1
endif
lastpat=ipat
return
end subroutine fetchit

373
lib/fsk4hf/osdwspr.f90 Normal file
View File

@ -0,0 +1,373 @@
subroutine osdwspr(ss,apmask,ndeep,cw,nhardmin,dmin)
!
use iso_c_binding
parameter (N=162, K=50, L=32)
!integer*1 p1(L),p2(L),p3(L),p4(L)
integer*1 gg(64)
real ss(N)
integer*1 apmask(N),apmaskr(N)
integer*1 gen(K,N)
integer*1 genmrb(K,N),g2(N,K)
integer*1 temp(K),m0(K),me(K),mi(K),misub(K),e2sub(N-K),e2(N-K),ui(N-K)
integer*1 r2pat(N-K)
integer indices(N),nxor(N)
integer*1 cw(N),ce(N),c0(N),hdec(N)
integer indx(N),ndeep,nhardmin
real rx(N),absrx(N),dmin
logical first,reset
data first/.true./
!data p1/1,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,1,1,0,0,1,1,1,0,1/
!data p2/1,0,1,0,1,0,1,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,1,1,1/
!data p3/1,1,0,1,0,1,0,1,1,0,1,0,0,1,1,0,1,1,1,1,1,1,0,1,1/
!data p4/1,1,1,0,1,1,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0,1/
!data p1/1,0,1,0,1,1,0,0,1,1,0,1,1,1,1,1/
!data p2/1,0,1,1,0,1,0,0,1,1,1,1,1,0,0,1/
!data p3/1,1,0,0,1,0,1,1,0,1,1,1,0,0,1,1/
!data p4/1,1,1,0,1,1,0,1,1,1,1,0,0,1,0,1/
data gg/1,1,0,1,0,1,0,0,1,0,0,0,1,1,0,0,1,0,1,0,0,1,0,1,1,1,0,1,1,0,0,0, &
0,1,0,0,0,0,0,0,1,0,0,1,1,1,1,0,0,0,1,0,0,1,0,0,1,0,1,1,1,1,1,1/
save first,gen
if( first ) then ! fill the generator matrix
! gg=0
! gg(1:L)=p1
! gg(L+1:2*L)=p2
! gg(2*L+1:3*L)=p3
! gg(3*L+1:4*L)=p4
gen=0
gen(1,1:2*L)=gg(1:2*L)
do i=2,K
gen(i,:)=cshift(gen(i-1,:),-2)
enddo
first=.false.
endif
! Re-order received vector to place systematic msg bits at the end.
rx=ss/127.0
apmaskr=apmask
! Hard decisions on the received word.
hdec=0
where(rx .ge. 0) hdec=1
! Use magnitude of received symbols as a measure of reliability.
absrx=abs(rx)
call indexx(absrx,N,indx)
! Re-order the columns of the generator matrix in order of decreasing reliability.
do i=1,N
genmrb(1:K,i)=gen(1:K,indx(N+1-i))
indices(i)=indx(N+1-i)
enddo
! Do gaussian elimination to create a generator matrix with the most reliable
! received bits in positions 1:K in order of decreasing reliability (more or less).
do id=1,K ! diagonal element indices
do icol=id,K+20 ! The 20 is ad hoc - beware
iflag=0
if( genmrb(id,icol) .eq. 1 ) then
iflag=1
if( icol .ne. id ) then ! reorder column
temp(1:K)=genmrb(1:K,id)
genmrb(1:K,id)=genmrb(1:K,icol)
genmrb(1:K,icol)=temp(1:K)
itmp=indices(id)
indices(id)=indices(icol)
indices(icol)=itmp
endif
do ii=1,K
if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then
genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N))
endif
enddo
exit
endif
enddo
enddo
g2=transpose(genmrb)
! The hard decisions for the K MRB bits define the order 0 message, m0.
! Encode m0 using the modified generator matrix to find the "order 0" codeword.
! Flip various combinations of bits in m0 and re-encode to generate a list of
! codewords. Return the member of the list that has the smallest Euclidean
! distance to the received word.
hdec=hdec(indices) ! hard decisions from received symbols
m0=hdec(1:K) ! zero'th order message
absrx=absrx(indices)
rx=rx(indices)
apmaskr=apmaskr(indices)
call mrbencode(m0,c0,g2,N,K)
nxor=ieor(c0,hdec)
nhardmin=sum(nxor)
dmin=sum(nxor*absrx)
cw=c0
ntotal=0
nrejected=0
if(ndeep.eq.0) goto 998 ! norder=0
if(ndeep.gt.5) ndeep=5
if( ndeep.eq. 1) then
nord=1
npre1=0
npre2=0
nt=60
ntheta=12
elseif(ndeep.eq.2) then
nord=1
npre1=1
npre2=0
nt=60
ntheta=12
elseif(ndeep.eq.3) then
nord=1
npre1=1
npre2=1
nt=60
ntheta=22
ntau=16
elseif(ndeep.eq.4) then
nord=2
npre1=1
npre2=0
nt=60
ntheta=22
ntau=16
elseif(ndeep.eq.5) then
nord=3
npre1=1
npre2=1
nt=60
ntheta=22
ntau=16
endif
do iorder=1,nord
misub(1:K-iorder)=0
misub(K-iorder+1:K)=1
iflag=K-iorder+1
do while(iflag .ge.0)
if(iorder.eq.nord .and. npre1.eq.0) then
iend=iflag
else
iend=1
endif
do n1=iflag,iend,-1
mi=misub
mi(n1)=1
if(any(iand(apmaskr(1:K),mi).eq.1)) cycle
ntotal=ntotal+1
me=ieor(m0,mi)
if(n1.eq.iflag) then
call mrbencode(me,ce,g2,N,K)
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
e2=e2sub
nd1Kpt=sum(e2sub(1:nt))+1
d1=sum(ieor(me(1:K),hdec(1:K))*absrx(1:K))
else
e2=ieor(e2sub,g2(K+1:N,n1))
nd1Kpt=sum(e2(1:nt))+2
endif
if(nd1Kpt .le. ntheta) then
call mrbencode(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
if(n1.eq.iflag) then
dd=d1+sum(e2sub*absrx(K+1:N))
else
dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(K+1:N))
endif
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
nd1Kptbest=nd1Kpt
endif
else
nrejected=nrejected+1
endif
enddo
! Get the next test error pattern, iflag will go negative
! when the last pattern with weight iorder has been generated.
call nextpat(misub,k,iorder,iflag)
enddo
enddo
if(npre2.eq.1) then
reset=.true.
ntotal=0
do i1=K,1,-1
do i2=i1-1,1,-1
ntotal=ntotal+1
mi(1:ntau)=ieor(g2(K+1:K+ntau,i1),g2(K+1:K+ntau,i2))
call boxit(reset,mi(1:ntau),ntau,ntotal,i1,i2)
enddo
enddo
ncount2=0
ntotal2=0
reset=.true.
! Now run through again and do the second pre-processing rule
misub(1:K-nord)=0
misub(K-nord+1:K)=1
iflag=K-nord+1
do while(iflag .ge.0)
me=ieor(m0,misub)
call mrbencode(me,ce,g2,N,K)
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
do i2=0,ntau
ntotal2=ntotal2+1
ui=0
if(i2.gt.0) ui(i2)=1
r2pat=ieor(e2sub,ui)
778 continue
call fetchit(reset,r2pat(1:ntau),ntau,in1,in2)
if(in1.gt.0.and.in2.gt.0) then
ncount2=ncount2+1
mi=misub
mi(in1)=1
mi(in2)=1
if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:K),mi).eq.1)) cycle
me=ieor(m0,mi)
call mrbencode(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
dd=sum(nxor*absrx)
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
endif
goto 778
endif
enddo
call nextpat(misub,K,nord,iflag)
enddo
endif
998 continue
! Re-order the codeword to as-received order.
cw(indices)=cw
hdec(indices)=hdec
return
end subroutine osdwspr
subroutine mrbencode(me,codeword,g2,N,K)
integer*1 me(K),codeword(N),g2(N,K)
! fast encoding for low-weight test patterns
codeword=0
do i=1,K
if( me(i) .eq. 1 ) then
codeword=ieor(codeword,g2(1:N,i))
endif
enddo
return
end subroutine mrbencode
subroutine nextpat(mi,k,iorder,iflag)
integer*1 mi(k),ms(k)
! generate the next test error pattern
ind=-1
do i=1,k-1
if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i
enddo
if( ind .lt. 0 ) then ! no more patterns of this order
iflag=ind
return
endif
ms=0
ms(1:ind-1)=mi(1:ind-1)
ms(ind)=1
ms(ind+1)=0
if( ind+1 .lt. k ) then
nz=iorder-sum(ms)
ms(k-nz+1:k)=1
endif
mi=ms
do i=1,k ! iflag will point to the lowest-index 1 in mi
if(mi(i).eq.1) then
iflag=i
exit
endif
enddo
return
end subroutine nextpat
subroutine boxit(reset,e2,ntau,npindex,i1,i2)
integer*1 e2(1:ntau)
integer indexes(4000,2),fp(0:525000),np(4000)
logical reset
common/boxes/indexes,fp,np
if(reset) then
patterns=-1
fp=-1
np=-1
sc=-1
indexes=-1
reset=.false.
endif
indexes(npindex,1)=i1
indexes(npindex,2)=i2
ipat=0
do i=1,ntau
if(e2(i).eq.1) then
ipat=ipat+ishft(1,ntau-i)
endif
enddo
ip=fp(ipat) ! see what's currently stored in fp(ipat)
if(ip.eq.-1) then
fp(ipat)=npindex
else
do while (np(ip).ne.-1)
ip=np(ip)
enddo
np(ip)=npindex
endif
return
end subroutine boxit
subroutine fetchit(reset,e2,ntau,i1,i2)
integer indexes(4000,2),fp(0:525000),np(4000)
integer lastpat
integer*1 e2(ntau)
logical reset
common/boxes/indexes,fp,np
save lastpat,inext
if(reset) then
lastpat=-1
reset=.false.
endif
ipat=0
do i=1,ntau
if(e2(i).eq.1) then
ipat=ipat+ishft(1,ntau-i)
endif
enddo
index=fp(ipat)
if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices
i1=indexes(index,1)
i2=indexes(index,2)
inext=np(index)
elseif(lastpat.eq.ipat .and. inext.gt.0) then
i1=indexes(inext,1)
i2=indexes(inext,2)
inext=np(inext)
else
i1=-1
i2=-1
inext=-1
endif
lastpat=ipat
return
end subroutine fetchit

194
lib/fsk4hf/tccsim.f90 Normal file
View File

@ -0,0 +1,194 @@
!
! Simulator for terminated convolutional codes (so, far, only rate 1/2)
! BPSK on AWGN Channel
!
! Hybrid decoder - Fano Sequential Decoder and Ordered Statistics Decoder (OSD)a
!
program tccsim
parameter (N=162,K=50)
integer*1 gen(K,N)
integer*1 gg(64)
integer*1 mbits(50),mbits2(50)
integer*4 mettab(-128:127,0:1)
parameter (NSYM=162)
parameter (MAXSYM=162)
character*12 arg
character*22 msg,msg2
integer*1 data0(13)
integer*1 data1(13)
integer*1 dat(206)
integer*1 softsym(162)
integer*1 apmask(162),cw0(162),cw(162)
real*4 xx0(0:255)
real ss(162)
character*64 g ! Interleaved polynomial coefficients
data g/'1101010010001100101001011101100001000000100111100010010010111111'/
data xx0/ & !Metric table
1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, &
1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, &
1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, &
1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, &
1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, &
1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, &
0.988, 1.000, 0.991, 0.993, 1.000, 0.995, 1.000, 0.991, &
1.000, 0.991, 0.992, 0.991, 0.990, 0.990, 0.992, 0.996, &
0.990, 0.994, 0.993, 0.991, 0.992, 0.989, 0.991, 0.987, &
0.985, 0.989, 0.984, 0.983, 0.979, 0.977, 0.971, 0.975, &
0.974, 0.970, 0.970, 0.970, 0.967, 0.962, 0.960, 0.957, &
0.956, 0.953, 0.942, 0.946, 0.937, 0.933, 0.929, 0.920, &
0.917, 0.911, 0.903, 0.895, 0.884, 0.877, 0.869, 0.858, &
0.846, 0.834, 0.821, 0.806, 0.790, 0.775, 0.755, 0.737, &
0.713, 0.691, 0.667, 0.640, 0.612, 0.581, 0.548, 0.510, &
0.472, 0.425, 0.378, 0.328, 0.274, 0.212, 0.146, 0.075, &
0.000,-0.079,-0.163,-0.249,-0.338,-0.425,-0.514,-0.606, &
-0.706,-0.796,-0.895,-0.987,-1.084,-1.181,-1.280,-1.376, &
-1.473,-1.587,-1.678,-1.790,-1.882,-1.992,-2.096,-2.201, &
-2.301,-2.411,-2.531,-2.608,-2.690,-2.829,-2.939,-3.058, &
-3.164,-3.212,-3.377,-3.463,-3.550,-3.768,-3.677,-3.975, &
-4.062,-4.098,-4.186,-4.261,-4.472,-4.621,-4.623,-4.608, &
-4.822,-4.870,-4.652,-4.954,-5.108,-5.377,-5.544,-5.995, &
-5.632,-5.826,-6.304,-6.002,-6.559,-6.369,-6.658,-7.016, &
-6.184,-7.332,-6.534,-6.152,-6.113,-6.288,-6.426,-6.313, &
-9.966,-6.371,-9.966,-7.055,-9.966,-6.629,-6.313,-9.966, &
-5.858,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966, &
-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966, &
-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966, &
-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966, &
-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966, &
-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966,-9.966/
bias=0.42
scale=120
! ndelta=nint(3.4*scale)
ndelta=100
ib=150
slope=2
do i=0,255
mettab(i-128,0)=nint(scale*(xx0(i)-bias))
if(i.gt.ib) mettab(i-128,0)=mettab(ib-128,0)-slope*(i-ib)
if(i.ge.1) mettab(128-i,1)=mettab(i-128,0)
enddo
mettab(-128,1)=mettab(-127,1)
! Get command-line argument(s)
nargs=iargc()
if(nargs.ne.3) then
print*,'Usage: tccsim "message" ntrials ndepth'
go to 999
endif
call getarg(1,msg) !Get message from command line
write(*,1000) msg
1000 format('Message: ',a22)
call getarg(2,arg)
read(arg,*) ntrials
call getarg(3,arg)
read(arg,*) ndepth
nbits=50+31 !User bits=99, constraint length=32
nbytes=(nbits+7)/8
limit=20000
data0=0
call wqencode(msg,ntype0,data0) !Source encoding
write(*,*) 'data0 ',data0
! Demonstrates how to create the generator matrix from a string that contains the interleaved
! polynomial coefficients
gen=0
do j=1,64
read(g(j:j),"(i1)") gg(j) ! read polynomial coeffs from string
enddo
do i=1,K
gen(i,2*(i-1)+1:2*(i-1)+64)=gg ! fill the generator matrix with cyclic shifts of gg
enddo
! get message bits from data0
nbits=0
do i=1,7
do ib=7,0,-1
nbits=nbits+1
if(nbits .le. 50) then
mbits(nbits)=0
if(btest(data0(i),ib)) mbits(nbits)=1
endif
enddo
enddo
write(*,*) 'Source encoded message bits: '
write(*,'(6(8i1,1x),2i1)') mbits
! Encode message bits using the generator matrix, generating a 162-bit codeword.
cw0=0
do i=1,50
if(mbits(i).eq.1) cw0=mod(cw0+gen(i,:),2)
enddo
write(*,*) 'Codeword from generator matrix: '
write(*,'(162i1)') cw0
! call encode232(data0,nbytes,dat) !Convolutional encoding
! write(*,*) 'Codeword from encode232: '
! write(*,'(162i2)') dat
! call inter_mept(dat,1) !Interleaving
! Here, we have channel symbols.
! call inter_mept(dat,-1) !Remove interleaving
call init_random_seed()
call sgran()
do isnr=10,-20,-1
sigma=1/sqrt(2*(10**((isnr/2.0)/10.0)))
ngood=0
nbad=0
do i=1,ntrials
do j=1,162
ss(j)=-(2*cw0(j)-1)+sigma*gran() !Simulate soft symbols
enddo
rms=sqrt(sum(ss**2))
ss=100*ss/rms
where(ss>127.0) ss=127.0
where(ss<-127.0) ss=-127.0
softsym=ss
! Call the sequential (Fano algorithm) decoder
nbits=50+31
! call fano232(softsym,nbits,mettab,ndelta,limit,data1,ncycles,metric,nerr)
nerr=1
iflag=0
nhardmin=0
dmin=0.0
! If Fano fails, call OSD
if(nerr.ne.0 .and. ndepth.ge.0) then
apmask=0
cw=0
call osdwspr(softsym,apmask,ndepth,cw,nhardmin,dmin)
! OSD produces a codeword, but code is not systematic
! Use Fano with hard decisions to retrieve the message from the codeword
! cw=-(2*cw-1)*64
! nbits=50+31
!dat=0
!dat(1:162)=cw
! call fano232(dat,nbits,mettab,ndelta,limit,data1,ncycles,metric,nerr)
! iflag=1
endif
! call wqdecode(data1,msg2,ntype1)
! write(*,*) msg2,iflag,nhardmin,dmin
if(any(cw.ne.cw0)) nbad=nbad+1
if(all(cw.eq.cw0)) ngood=ngood+1
enddo
write(*,'(f4.1,i8,i8)') isnr/2.0,ngood,nbad
enddo
999 end program tccsim
#include '../wsprcode/wspr_old_subs.f90'

View File

@ -30,6 +30,8 @@ program wspr5d
complex cd(0:NZ-1) !Complex waveform
complex ca(0:NZ-1) !Complex waveform
complex zz,zzsum
complex cc(110) !Complex correlation coefficients
complex*8 cfac
real*8 fMHz
real rxdata(ND),llr(ND) !Soft symbols
real pp(32) !Shaped pulse for OQPSK
@ -134,7 +136,6 @@ program wspr5d
call getfc1(c400,fs400,fa,fb,fc1,xsnr) !First approx for freq
npeaks=5
call getfc2(c400,npeaks,fs400,fc1,fpks) !Refined freq
! do idf=1,npeaks ! consider the top npeak peaks
do idf=1,1 ! for genie-aided sync
fc1=125.0 ! genie provided
@ -149,7 +150,7 @@ program wspr5d
xdt=real(22+idt)/22.222 - 1.0
ca=cshift(cd,22+idt)
zzsum=0.0
do iseq=3,4
do iseq=1,4,3
if(iseq.eq.4) then
k=1-2*3
nseq=9
@ -159,6 +160,7 @@ program wspr5d
nseq=iseq*3
istep=iseq*4
endif
icc=1
do i=1,408,istep
j=(i+1)*16
if(iseq.eq.4) then
@ -171,6 +173,9 @@ program wspr5d
else
k=k+iseq*2
call mskseqdet(nseq,ca(j),pp,id(k),softbits,1,zz)
cc(icc)=zz
write(32,*) icc,real(cc(icc)),imag(cc(icc))
icc=icc+1
zzsum=zzsum+zz
endif
sbits(i+1)=softbits(1)
@ -190,6 +195,27 @@ program wspr5d
endif
endif
enddo
cm=0.0
do idel=-200,200
df=idel*0.001
! dpha=twopi*df*12.0*(16/22.0)
dpha=twopi*df*4.0*(16/22.0)
phase=0.0
zzsum=0.0
do i=1,102
cfac=cmplx(cos(phase),sin(phase))
zzsum=zzsum+cc(i)*cfac
phase=mod(phase+dpha,twopi)
enddo
if(abs(zzsum).gt.cm) then
cm=abs(zzsum)
dfbest=df
endif
! write(*,*) df,abs(zzsum)
enddo
write(*,*) 'dfbest ',dfbest
write(*,*) 'final estimated frequency is: ',fc1+fc2+dfbest
j=1
do i=1,205
if( abs(id(i)) .ne. 2 ) then
@ -346,7 +372,7 @@ do idf=0,idfmax
bestbits=bit
cbest=cideal
fbest=deltaf
zz=sum(cdat*conjg(cbest))/1.e3
zz=sum(cdat(1:64*ns/3)*conjg(cbest(1:64*ns/3)))/1.e3
endif
enddo
if( ibflag .eq. 1 ) then ! new best found

View File

@ -0,0 +1,14 @@
parameter (KK=64) !Information bits (50 + CRC14) ?
parameter (ND=200) !Data symbols: LDPC (204,68), r=1/3, don't send last 4 bits
parameter (NS=32) !Sync symbols (32)
parameter (NN=NS+ND) !Total symbols (232)
parameter (NSPS0=6000) !Samples per symbol at 12000 S/s
parameter (NDOWN=30) !Downsample to 200 sa/symbol (400 Hz) for candidate selection
parameter (NSPS=NSPS0/NDOWN) !Samples per symbol (200)
parameter (NZ=NSPS*NN) !Samples in baseband waveform
parameter (NZ0=NSPS0*NN) !Samples in waveform at 12000 S/s
parameter (NFFT1=4*NSPS,NH1=NFFT1/2)

115
lib/ft8/bpdecode174_91.f90 Normal file
View File

@ -0,0 +1,115 @@
subroutine bpdecode174_91(llr,apmask,maxiterations,message77,cw,nharderror,iter)
!
! A log-domain belief propagation decoder for the (174,91) code.
!
use iso_c_binding, only: c_loc,c_size_t
use crc
integer, parameter:: N=174, K=91, M=N-K
integer*1 cw(N),apmask(N)
integer*1 decoded(K)
integer*1 message77(77)
integer nrw(M),ncw
integer Nm(7,M)
integer Mn(3,N) ! 3 checks per bit
integer synd(M)
real tov(3,N)
real toc(7,M)
real tanhtoc(7,M)
real zn(N)
real llr(N)
real Tmn
include "ldpc_174_91_c_reordered_parity.f90"
decoded=0
toc=0
tov=0
tanhtoc=0
! initialize messages to checks
do j=1,M
do i=1,nrw(j)
toc(i,j)=llr((Nm(i,j)))
enddo
enddo
ncnt=0
do iter=0,maxiterations
! Update bit log likelihood ratios (tov=0 in iteration 0).
do i=1,N
if( apmask(i) .ne. 1 ) then
zn(i)=llr(i)+sum(tov(1:ncw,i))
else
zn(i)=llr(i)
endif
enddo
! Check to see if we have a codeword (check before we do any iteration).
cw=0
where( zn .gt. 0. ) cw=1
ncheck=0
do i=1,M
synd(i)=sum(cw(Nm(1:nrw(i),i)))
if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1
! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied'
enddo
! write(*,*) 'number of unsatisfied parity checks ',ncheck
if( ncheck .eq. 0 ) then ! we have a codeword - if crc is good, return it
decoded=cw(1:K)
call chkcrc14a(decoded,nbadcrc)
nharderror=count( (2*cw-1)*llr .lt. 0.0 )
if(nbadcrc.eq.0) then
message77=decoded(1:77)
return
endif
endif
if( iter.gt.0 ) then ! this code block implements an early stopping criterion
! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion
nd=ncheck-nclast
if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased
ncnt=0 ! reset counter
else
ncnt=ncnt+1
endif
! write(*,*) iter,ncheck,nd,ncnt
if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then
nharderror=-1
return
endif
endif
nclast=ncheck
! Send messages from bits to check nodes
do j=1,M
do i=1,nrw(j)
ibj=Nm(i,j)
toc(i,j)=zn(ibj)
do kk=1,ncw ! subtract off what the bit had received from the check
if( Mn(kk,ibj) .eq. j ) then
toc(i,j)=toc(i,j)-tov(kk,ibj)
endif
enddo
enddo
enddo
! send messages from check nodes to variable nodes
do i=1,M
tanhtoc(1:7,i)=tanh(-toc(1:7,i)/2)
enddo
do j=1,N
do i=1,ncw
ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j
Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j)
call platanh(-Tmn,y)
! y=atanh(-Tmn)
tov(i,j)=2*y
enddo
enddo
enddo
nharderror=-1
return
end subroutine bpdecode174_91

24
lib/ft8/chkcrc13a.f90 Normal file
View File

@ -0,0 +1,24 @@
subroutine chkcrc13a(decoded,nbadcrc)
use crc
integer*1 decoded(90)
integer*1, target:: i1Dec8BitBytes(12)
character*90 cbits
! Write decoded bits into cbits: 77-bit message plus 13-bit CRC
write(cbits,1000) decoded
1000 format(90i1)
read(cbits,1001) i1Dec8BitBytes
1001 format(12b8)
read(cbits,1002) ncrc13 !Received CRC13
1002 format(77x,b13)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32+16+8)
i1Dec8BitBytes(11:12)=0
icrc13=crc13(c_loc(i1Dec8BitBytes),12) !CRC13 computed from 77 msg bits
nbadcrc=1
if(ncrc13.eq.icrc13) nbadcrc=0
return
end subroutine chkcrc13a

24
lib/ft8/chkcrc14a.f90 Normal file
View File

@ -0,0 +1,24 @@
subroutine chkcrc14a(decoded,nbadcrc)
use crc
integer*1 decoded(91)
integer*1, target:: i1Dec8BitBytes(12)
character*91 cbits
! Write decoded bits into cbits: 77-bit message plus 14-bit CRC
write(cbits,1000) decoded
1000 format(91i1)
read(cbits,1001) i1Dec8BitBytes
1001 format(12b8)
read(cbits,1002) ncrc14 !Received CRC14
1002 format(77x,b14)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32+16+8)
i1Dec8BitBytes(11:12)=0
icrc14=crc14(c_loc(i1Dec8BitBytes),12) !CRC14 computed from 77 msg bits
nbadcrc=1
if(ncrc14.eq.icrc14) nbadcrc=0
return
end subroutine chkcrc14a

58
lib/ft8/encode174_91.f90 Normal file
View File

@ -0,0 +1,58 @@
subroutine encode174_91(message77,codeword)
!
! Add a 14-bit CRC to a 77-bit message and return a 174-bit codeword
!
use, intrinsic :: iso_c_binding
use iso_c_binding, only: c_loc,c_size_t
use crc
integer, parameter:: N=174, K=91, M=N-K
character*91 tmpchar
integer*1 codeword(N)
integer*1 gen(M,K)
integer*1 message77(77),message(K)
integer*1 pchecks(M)
integer*1, target :: i1MsgBytes(12)
include "ldpc_174_91_c_generator.f90"
logical first
data first/.true./
save first,gen
if( first ) then ! fill the generator matrix
gen=0
do i=1,M
do j=1,23
read(g(i)(j:j),"(Z1)") istr
ibmax=4
if(j.eq.23) ibmax=3
do jj=1, ibmax
icol=(j-1)*4+jj
if( btest(istr,4-jj) ) gen(i,icol)=1
enddo
enddo
enddo
first=.false.
endif
! Add 14-bit CRC to form 91-bit message+CRC14
write(tmpchar,'(77i1)') message77
tmpchar(78:80)='000'
i1MsgBytes=0
read(tmpchar,'(10b8)') i1MsgBytes(1:10)
ncrc14 = crc14 (c_loc (i1MsgBytes), 12)
write(tmpchar(78:91),'(b14)') ncrc14
read(tmpchar,'(91i1)') message
do i=1,M
nsum=0
do j=1,K
nsum=nsum+message(j)*gen(i,j)
enddo
pchecks(i)=mod(nsum,2)
enddo
codeword(1:K)=message
codeword(K+1:N)=pchecks
return
end subroutine encode174_91

View File

@ -30,7 +30,7 @@ subroutine extractmessage174(decoded,msgreceived,ncrcflag)
enddo
i4Dec6BitWords(ibyte)=itmp
enddo
call unpackmsg(i4Dec6BitWords,msgreceived,.false.,' ')
call unpackmsg(i4Dec6BitWords,msgreceived)
ncrcflag=1
else
msgreceived=' '

View File

@ -0,0 +1,40 @@
subroutine extractmessage174_91(decoded,msgreceived,ncrcflag)
use iso_c_binding, only: c_loc,c_size_t
use crc
use packjt
character*22 msgreceived
character*91 cbits
integer*1 decoded(91)
integer*1, target:: i1Dec8BitBytes(12)
integer*4 i4Dec6BitWords(12)
! Write decoded bits into cbits: 77-bit message plus 14-bit CRC
write(cbits,1000) decoded
1000 format(91i1)
read(cbits,1001) i1Dec8BitBytes
1001 format(12b8)
read(cbits,1002) ncrc14 !Received CRC12
1002 format(77x,b14)
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32+16+8)
i1Dec8BitBytes(11:12)=0
icrc14=crc14(c_loc(i1Dec8BitBytes),12) !CRC12 computed from 75 msg bits
if(ncrc14.eq.icrc14 .or. sum(decoded(57:87)).eq.0) then !### Kludge ###
! CRC14 checks out --- unpack 72-bit message
do ibyte=1,12
itmp=0
do ibit=1,6
itmp=ishft(itmp,1)+iand(1,decoded((ibyte-1)*6+ibit))
enddo
i4Dec6BitWords(ibyte)=itmp
enddo
call unpackmsg(i4Dec6BitWords,msgreceived)
ncrcflag=1
else
msgreceived=' '
ncrcflag=-1
endif
return
end subroutine extractmessage174_91

View File

@ -18,11 +18,9 @@ subroutine foxgen()
parameter (NN=79,ND=58,KK=87,NSPS=4*1920)
parameter (NWAVE=NN*NSPS,NFFT=614400,NH=NFFT/2)
character*40 cmsg
character*22 msg,msgsent
character*6 mygrid
character*37 msg,msgsent
character*87 cbits
character*88 cb88
logical bcontest
integer itone(NN)
integer icos7(0:6)
integer*1 msgbits(KK),codeword(3*ND),msgbits2
@ -36,12 +34,10 @@ subroutine foxgen()
equivalence (x,cx),(y,cy)
data icos7/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern
bcontest=.false.
fstep=60.d0
dfreq=6.25d0
dt=1.d0/48000.d0
twopi=8.d0*atan(1.d0)
mygrid=' '
irpt=0
nplot=0
wave=0.
@ -58,7 +54,7 @@ subroutine foxgen()
msg=cmsg(n)(1:i1)//cmsg(n)(i2+1:i3-2)//' '
read(cmsg(n)(i4+2:i4+4),*) irpt
endif
call genft8(msg,mygrid,bcontest,0,msgsent,msgbits,itone)
call genft8(msg,0,1,1,msgsent,msgbits,itone)
! print*,'Foxgen:',n,cmsg(n),msgsent
if(i3b.eq.1) then

View File

@ -5,15 +5,23 @@ subroutine ft8_downsample(dd,newdat,f0,c1)
parameter (NMAX=15*12000,NSPS=1920)
parameter (NFFT1=192000,NFFT2=3200) !192000/60 = 3200
logical newdat
logical newdat,first
complex c1(0:NFFT2-1)
complex cx(0:NFFT1/2)
real dd(NMAX),x(NFFT1)
real dd(NMAX),x(NFFT1),taper(0:100)
equivalence (x,cx)
save cx
data first/.true./
save cx,first,taper
if(first) then
pi=4.0*atan(1.0)
do i=0,100
taper(i)=0.5*(1.0+cos(i*pi/100))
enddo
first=.false.
endif
if(newdat) then
! Data in dd have changed, recompute the long FFT
! Data in dd have changed, recompute the long FFT
x(1:NMAX)=dd
x(NMAX+1:NFFT1)=0. !Zero-pad the x array
call four2a(cx,NFFT1,1,-1,0) !r2c FFT to freq domain
@ -23,9 +31,9 @@ subroutine ft8_downsample(dd,newdat,f0,c1)
df=12000.0/NFFT1
baud=12000.0/NSPS
i0=nint(f0/df)
ft=f0+8.0*baud
ft=f0+8.5*baud
it=min(nint(ft/df),NFFT1/2)
fb=f0-1.0*baud
fb=f0-1.5*baud
ib=max(1,nint(fb/df))
k=0
c1=0.
@ -33,6 +41,8 @@ subroutine ft8_downsample(dd,newdat,f0,c1)
c1(k)=cx(i)
k=k+1
enddo
c1(0:100)=c1(0:100)*taper(100:0:-1)
c1(k-1-100:k-1)=c1(k-1-100:k-1)*taper
c1=cshift(c1,i0-ib)
call four2a(c1,NFFT2,1,1,1) !c2c FFT back to time domain
fac=1.0/sqrt(float(NFFT1)*NFFT2)

View File

@ -1,31 +1,22 @@
subroutine ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype)
subroutine ft8apset(mycall12,hiscall12,apsym)
parameter(NAPM=4,KK=87)
character*12 mycall12,hiscall12
character*22 msg,msgsent
character*37 msg,msgsent
character*6 mycall,hiscall
character*6 mygrid6,hisgrid6
character*6 hisgrid6
character*4 hisgrid
logical bcontest
integer apsym(KK)
integer*1 msgbits(KK)
integer itone(KK)
integer apsym(75)
integer*1 msgbits(77)
integer itone(79)
mycall=mycall12(1:6)
hiscall=hiscall12(1:6)
hisgrid=hisgrid6(1:4)
if(len_trim(hiscall).eq.0) then
iaptype=1
hiscall="K9AN"
else
iaptype=2
endif
hisgrid=hisgrid6(1:4)
! if(len_trim(hisgrid).eq.0) hisgrid="EN50"
if(index(hisgrid," ").eq.0) hisgrid="EN50"
msg=mycall//' '//hiscall//' '//hisgrid
i3bit=0 ! ### TEMPORARY ??? ###
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
apsym=2*msgbits-1
if(len(trim(hiscall)).eq.0) hiscall="K9ABC"
msg=mycall//' '//hiscall//' RRR'
i3=0
n3=0
isync=1
call genft8(msg,i3,n3,isync,msgsent,msgbits,itone)
apsym=2*msgbits(1:75)-1
return
end subroutine ft8apset

View File

@ -0,0 +1,20 @@
subroutine ft8apset_174_91(mycall12,hiscall12,hisgrid6,ncontest,apsym)
parameter(NAPM=4,KK=91)
character*37 msg,msgsent
character*12 mycall12,hiscall12
character*6 hisgrid6
character*4 hisgrid
integer apsym(77)
integer*1 msgbits(77)
integer itone(KK)
if(index(hiscall12," ").eq.0) hiscall12="K9ABC"
msg=trim(mycall12)//' '//trim(hiscall12)//' RRR'
i3=1
n3=0
!write(*,*) 'apset msg ',msg
call genft8_174_91(msg,i3,n3,msgsent,msgbits,itone)
apsym=2*msgbits-1
!write(*,'(29i1,1x,29i1,1x,19i1)') (apsym(1:77)+1)/2
return
end subroutine ft8apset_174_91

View File

@ -1,17 +1,16 @@
subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
napwid,lsubtract,nagain,iaptype,mycall12,mygrid6,hiscall12,bcontest, &
subroutine ft8b_1(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
napwid,lsubtract,nagain,iaptype,mycall12,hiscall12, &
sync0,f1,xdt,xbase,apsym,nharderrors,dmin,nbadcrc,ipass,iera,msg37,xsnr)
use crc
use timer_module, only: timer
include 'ft8_params.f90'
parameter(NP2=2812)
character*37 msg37
character*37 msg37,msgsent37
character message*22,msgsent*22
character*12 mycall12,hiscall12
character*6 mycall6,mygrid6,hiscall6,c1,c2
character*6 mycall6,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)
@ -20,7 +19,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
real dd0(15*12000)
integer*1 decoded(KK),decoded0(KK),apmask(3*ND),cw(3*ND)
integer*1 msgbits(KK)
integer apsym(KK)
integer apsym(75)
integer mcq(28),mde(28),mrrr(16),m73(16),mrr73(16)
integer itone(NN)
integer indxs1(8*ND)
@ -28,7 +27,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
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(3200)
complex cd0(0:3199)
complex ctwk(32)
complex csymb(32)
logical first,newdat,lsubtract,lapon,lapcqonly,nagain
@ -89,7 +88,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
i0=nint((xdt+0.5)*fs2) !Initial guess for start of signal
smax=0.0
do idt=i0-8,i0+8 !Search over +/- one quarter symbol
call sync8d(cd0,idt,ctwk,0,sync)
call sync8d(cd0,idt,ctwk,0,1,sync)
if(sync.gt.smax) then
smax=sync
ibest=idt
@ -108,7 +107,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
ctwk(i)=cmplx(cos(phi),sin(phi))
phi=mod(phi+dphi,twopi)
enddo
call sync8d(cd0,i0,ctwk,1,sync)
call sync8d(cd0,i0,ctwk,1,1,sync)
if( sync .gt. smax ) then
smax=sync
delfbest=delf
@ -120,13 +119,13 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
xdt=xdt2
f1=f1+delfbest !Improved estimate of DF
call sync8d(cd0,i0,ctwk,2,sync)
call sync8d(cd0,i0,ctwk,2,1,sync)
j=0
do k=1,NN
i1=ibest+(k-1)*32
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+31 .le. NP2-1 ) csymb=cd0(i1:i1+31)
call four2a(csymb,32,1,-1,1)
s2(0:7,k)=abs(csymb(1:8))/1e3
enddo
@ -380,8 +379,13 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
if(i3bit.eq.1) decoded(57:)=0
call extractmessage174(decoded,message,ncrcflag)
decoded=decoded0
! This needs fixing for messages with i3bit=1:
call genft8(message,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
! This needs fixing for messages with i3bit=1:
i3=0 !TEMPORARY
n3=0
isync=1
msg37=' '
msg37(1:22)=message
call genft8(msg37,i3,n3,isync,msgsent37,msgbits,itone)
if(lsubtract) call subtractft8(dd0,itone,f1,xdt2)
xsig=0.0
xnoi=0.0
@ -437,7 +441,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
enddo
return
end subroutine ft8b
end subroutine ft8b_1
subroutine normalizebmet(bmet,n)
real bmet(n)

369
lib/ft8/ft8b_2.f90 Normal file
View File

@ -0,0 +1,369 @@
subroutine ft8b_2(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
napwid,lsubtract,nagain,iaptype,mycall12,hiscall12, &
sync0,f1,xdt,xbase,apsym,nharderrors,dmin,nbadcrc,ipass,iera,msg37,xsnr)
use crc
use timer_module, only: timer
use packjt77
include 'ft8_params.f90'
parameter(NP2=2812)
character*37 msg37,msgsent37
character*12 mycall12,hiscall12,hiscall12_0
character*77 c77
character*6 mycall6,hiscall6,c1,c2
character*13 c13
character*87 cbits
real a(5)
real s8(0:7,NN)
real s2(0:511),s2l(0:511)
real bmeta(3*ND),bmetb(3*ND),bmetc(3*ND)
real bmetal(3*ND),bmetbl(3*ND),bmetcl(3*ND)
real llra(3*ND),llrb(3*ND),llrc(3*ND),llrd(3*ND) !Soft symbols
real llral(3*ND),llrbl(3*ND),llrcl(3*ND) !Soft symbols
real dd0(15*12000)
integer*1 message77(77),apmask(3*ND),cw(3*ND)
integer*1 msgbits(77)
integer apsym(77)
integer mcq(29),mrrr(19),m73(19),mrr73(19)
integer itone(NN)
integer icos7(0:6),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)
logical one(0:511,0:8)
integer graymap(0:7)
complex cd0(0:3199)
complex ctwk(32)
complex csymb(32)
complex cs(0:7,NN)
logical first,newdat,lsubtract,lapon,lapcqonly,nagain,unpk77_success
data icos7/3,1,4,0,6,5,2/ ! Flipped w.r.t. original FT8 sync array
data mcq/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,1,0,0/
data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/
data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/
data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/
data first/.true./
data graymap/0,1,3,2,5,6,4,7/
save nappasses,naptypes,one,hiscall12_0
if(first) then
mcq=2*mcq-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 ??? ??? (29+3=32 ap bits)
! 2 MyCall ??? ??? (29+3=32 ap bits)
! 3 MyCall DxCall ??? (58+3=61 ap bits)
! 4 MyCall DxCall RRR (77 ap bits)
! 5 MyCall DxCall 73 (77 ap bits)
! 6 MyCall DxCall RR73 (77 ap bits)
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/)
one=.false.
do i=0,511
do j=0,8
if(iand(i,2**j).ne.0) one(i,j)=.true.
enddo
enddo
first=.false.
endif
if(hiscall12.ne.hiscall12_0) then
c13=hiscall12//' '
call save_hash_call(c13,n10,n12,n22)
hiscall12_0=hiscall12
endif
max_iterations=30
nharderrors=-1
nbadcrc=1 ! this is used upstream to flag good decodes.
fs2=12000.0/NDOWN
dt2=1.0/fs2
twopi=8.0*atan(1.0)
delfbest=0.
ibest=0
call timer('ft8_down',0)
call ft8_downsample(dd0,newdat,f1,cd0) !Mix f1 to baseband and downsample
call timer('ft8_down',1)
i0=nint((xdt+0.5)*fs2) !Initial guess for start of signal
smax=0.0
do idt=i0-8,i0+8 !Search over +/- one quarter symbol
call sync8d(cd0,idt,ctwk,0,2,sync)
if(sync.gt.smax) then
smax=sync
ibest=idt
endif
enddo
xdt2=ibest*dt2 !Improved estimate for DT
! 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,32
ctwk(i)=cmplx(cos(phi),sin(phi))
phi=mod(phi+dphi,twopi)
enddo
call sync8d(cd0,i0,ctwk,1,2,sync)
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
call sync8d(cd0,i0,ctwk,0,2,sync)
do k=1,NN
i1=ibest+(k-1)*32
csymb=cmplx(0.0,0.0)
if( i1.ge.0 .and. i1+31 .le. NP2-1 ) csymb=cd0(i1:i1+31)
call four2a(csymb,32,1,-1,1)
cs(0:7,k)=csymb(1:8)/1e3
s8(0:7,k)=abs(csymb(1:8))
enddo
! sync quality check
is1=0
is2=0
is3=0
do k=1,7
ip=maxloc(s8(:,k))
if(icos7(k-1).eq.(ip(1)-1)) is1=is1+1
ip=maxloc(s8(:,k+36))
if(icos7(k-1).eq.(ip(1)-1)) is2=is2+1
ip=maxloc(s8(:,k+72))
if(icos7(k-1).eq.(ip(1)-1)) is3=is3+1
enddo
! hard sync sum - max is 21
nsync=is1+is2+is3
if(nsync .le. 6) then ! bail out
nbadcrc=1
return
endif
do nsym=1,3
nt=2**(3*nsym)
do ihalf=1,2
do k=1,29,nsym
if(ihalf.eq.1) ks=k+7
if(ihalf.eq.2) ks=k+43
amax=-1.0
do i=0,nt-1
i1=i/64
i2=iand(i,63)/8
i3=iand(i,7)
if(nsym.eq.1) then
s2(i)=abs(cs(graymap(i3),ks))
elseif(nsym.eq.2) then
s2(i)=abs(cs(graymap(i2),ks)+cs(graymap(i3),ks+1))
elseif(nsym.eq.3) then
s2(i)=abs(cs(graymap(i1),ks)+cs(graymap(i2),ks+1)+cs(graymap(i3),ks+2))
else
print*,"Error - nsym must be 1, 2, or 3."
endif
enddo
s2l(0:nt-1)=log(s2(0:nt-1)+1e-32)
i32=1+(k-1)*3+(ihalf-1)*87
if(nsym.eq.1) ibmax=2
if(nsym.eq.2) ibmax=5
if(nsym.eq.3) ibmax=8
do ib=0,ibmax
bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - &
maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib))
! bml=maxval(s2l(0:nt-1),one(0:nt-1,ibmax-ib)) - &
! maxval(s2l(0:nt-1),.not.one(0:nt-1,ibmax-ib))
if(i32+ib .gt.174) cycle
if(nsym.eq.1) then
bmeta(i32+ib)=bm
! bmetal(i32+ib)=bml
elseif(nsym.eq.2) then
bmetb(i32+ib)=bm
! bmetbl(i32+ib)=bml
elseif(nsym.eq.3) then
bmetc(i32+ib)=bm
! bmetcl(i32+ib)=bml
endif
enddo
enddo
enddo
enddo
call normalizebmet(bmeta,3*ND)
! call normalizebmet(bmetal,3*ND)
call normalizebmet(bmetb,3*ND)
! call normalizebmet(bmetbl,3*ND)
call normalizebmet(bmetc,3*ND)
! call normalizebmet(bmetcl,3*ND)
scalefac=2.83
llra=scalefac*bmeta
! llral=scalefac*bmetal
llrb=scalefac*bmetb
! llrbl=scalefac*bmetbl
llrc=scalefac*bmetc
! llrcl=scalefac*bmetcl
apmag=maxval(abs(llrb))*1.01
! pass #
!------------------------------
! 1 regular decoding, nsym=1
! 2 regular decoding, nsym=2
! 3 regular decoding, nsym=3
! 4 ap pass 1, nsym=1 (for now?)
! 5 ap pass 2
! 6 ap pass 3
! 7 ap pass 4
if(lapon) then
if(.not.lapcqonly) then
npasses=3+nappasses(nQSOProgress)
else
npasses=4
endif
else
npasses=3
endif
do ipass=1,npasses
llrd=llra
if(ipass.eq.2) llrd=llrb
if(ipass.eq.3) llrd=llrc
if(ipass.le.3) then
apmask=0
iaptype=0
endif
if(ipass .gt. 3) then
llrd=llra
if(.not.lapcqonly) then
iaptype=naptypes(nQSOProgress,ipass-3)
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(1:29)=1
apmask(75:77)=1
llrd(75:77)=apmag*apsym(75:77)
if(iaptype.eq.1) llrd(1:29)=apmag*mcq(1:29)
if(iaptype.eq.2) llrd(1:29)=apmag*apsym(1:29)
endif
if(iaptype.eq.3) then ! mycall, dxcall, ???
apmask=0
apmask(1:56)=1
apmask(75:77)=1
llrd(1:56)=apmag*apsym(1:56)
llrd(75:77)=apmag*apsym(75:77)
endif
if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then
apmask=0
apmask(1:77)=1 ! mycall, hiscall, RRR|73|RR73
llrd(1:58)=apmag*apsym(1:58)
if(iaptype.eq.4) llrd(59:77)=apmag*mrrr
if(iaptype.eq.5) llrd(59:77)=apmag*m73
if(iaptype.eq.6) llrd(59:77)=apmag*mrr73
endif
endif
cw=0
call timer('bpd174_91 ',0)
call bpdecode174_91(llrd,apmask,max_iterations,message77,cw,nharderrors, &
niterations)
call timer('bpd174_91 ',1)
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_91 ',0)
call osd174_91(llrd,apmask,ndeep,message77,cw,nharderrors,dmin)
call timer('osd174_91 ',1)
endif
msg37=' '
xsnr=-99.0
if(nharderrors.lt.0 .or. nharderrors.gt.36) cycle
if(count(cw.eq.0).eq.174) cycle !Reject the all-zero codeword
write(c77,'(77i1)') message77
read(c77(72:74),'(b3)') n3
read(c77(75:77),'(b3)') i3
if(i3.gt.4 .or. (i3.eq.0.and.n3.gt.5)) then
cycle
endif
call unpack77(c77,msg37,unpk77_success)
if(.not.unpk77_success) then
cycle
endif
nbadcrc=0 ! If we get this far: valid codeword, valid (i3,n3), nonquirky message.
call genft8_174_91(msg37,i3,n3,msgsent37,msgbits,itone)
if(lsubtract) call subtractft8(dd0,itone,f1,xdt)
xsig=0.0
xnoi=0.0
do i=1,79
xsig=xsig+s8(itone(i),i)**2
ios=mod(itone(i)+4,7)
xnoi=xnoi+s8(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
! need to reconcile signal normalization between this routine and the old ft8b_1 so
! that SNRs come out the same.
xsnr2=db(xsig/xbase - 1.0) - 32.0
! if(.not.nagain) xsnr=xsnr2
if(xsnr .lt. -24.0) xsnr=-24.0
return
enddo
return
end subroutine ft8b_2
! This currently resides in ft8b_1.f90
!subroutine normalizebmet(bmet,n)
! real bmet(n)
!
! bmetav=sum(bmet)/real(n)
! bmet2av=sum(bmet*bmet)/real(n)
! var=bmet2av-bmetav*bmetav
! if( var .gt. 0.0 ) then
! bmetsig=sqrt(var)
! else
! bmetsig=sqrt(bmet2av)
! endif
! bmet=bmet/bmetsig
! return
!end subroutine normalizebmet

View File

@ -14,14 +14,11 @@ program ft8code
character*6 c1,c2
character*9 comment
character*22 msgsent,message
character*6 mygrid6
character bad*1,msgtype*10
character*87 cbits
logical bcontest
integer itone(NN)
integer dgen(12)
integer*1 msgbits(KK),decoded(KK),decoded0(KK)
data mygrid6/'EM48 '/
! Get command-line argument(s)
nargs=iargc()
@ -36,17 +33,10 @@ program ft8code
go to 999
endif
bcontest=.false.
call getarg(1,msg) !Message to be transmitted
if(len(trim(msg)).eq.2 .and. msg(1:2).eq.'-t') then
testmsg(NTEST+1)='KA1ABC RR73; WB9XYZ <KH1/KH7Z> -11'
nmsg=NTEST+1
else if(len(trim(msg)).eq.2 .and. msg(1:2).eq.'-c') then
bcontest=.true.
call getarg(2,mygrid6)
call getarg(3,msg)
msgchk=msg
nmsg=1
else
msgchk=msg
call fmtmsg(msgchk,iz) !To upper case; collapse multiple blanks
@ -63,7 +53,7 @@ program ft8code
! Generate msgsent, msgbits, and itone
if(index(msg,';').le.0) then
call packmsg(msg(1:22),dgen,itype,bcontest)
call packmsg(msg(1:22),dgen,itype)
msgtype=""
if(itype.eq.1) msgtype="Std Msg"
if(itype.eq.2) msgtype="Type 1 pfx"
@ -72,7 +62,7 @@ program ft8code
if(itype.eq.5) msgtype="Type 2 sfx"
if(itype.eq.6) msgtype="Free text"
i3bit=0
call genft8(msg(1:22),mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
call genft8(msg(1:22),i3bit,msgsent,msgbits,itone)
else
call foxgen_wrap(msg,msgbits,itone)
i3bit=1
@ -86,7 +76,6 @@ program ft8code
decoded=decoded0
if(i3bit.eq.0) then
if(bcontest) call fix_contest_msg(mygrid6,message)
bad=" "
comment=' '
if(itype.ne.6 .and. message.ne.msgchk) bad="*"

View File

@ -8,16 +8,13 @@ program ft8sim
parameter (NWAVE=NN*NSPS)
type(hdr) h !Header for .wav file
character arg*12,fname*17
character msg40*40,msg*22,msgsent*22,msg0*22
character*6 mygrid6
logical bcontest
character msg*37,msgsent*37,msg0*37
complex c0(0:NMAX-1)
complex c(0:NMAX-1)
real wave(NMAX)
integer itone(NN)
integer*1 msgbits(KK)
integer*1 msgbits(77)
integer*2 iwave(NMAX) !Generated full-length waveform
data mygrid6/'EM48 '/
! Get command-line argument(s)
nargs=iargc()
@ -27,10 +24,9 @@ program ft8sim
print*,' ft8sim "K1ABC W9XYZ EN37" 10 0.0 0.1 1.0 25 10 -18'
print*,' ft8sim "K1ABC W9XYZ EN37" 25 0.0 0.1 1.0 25 10 -18'
print*,' ft8sim "K1ABC RR73; W9XYZ <KH1/KH7Z> -11" 300 0 0 0 25 1 -10'
print*,'Make nfiles negative to invoke 72-bit contest mode.'
go to 999
endif
call getarg(1,msg40) !Message to be transmitted
call getarg(1,msg) !Message to be transmitted
call getarg(2,arg)
read(arg,*) f0 !Frequency (only used for single-signal)
call getarg(3,arg)
@ -45,13 +41,13 @@ program ft8sim
read(arg,*) nfiles !Number of files
call getarg(8,arg)
read(arg,*) snrdb !SNR_2500
nsig=1
if(f0.lt.100.0) then
nsig=f0
f0=1500
endif
bcontest=nfiles.lt.0
nfiles=abs(nfiles)
twopi=8.0*atan(1.0)
fs=12000.0 !Sample rate (Hz)
@ -66,27 +62,28 @@ program ft8sim
txt=NN*NSPS/12000.0
! Source-encode, then get itone()
if(index(msg40,';').le.0) then
if(index(msg,';').le.0) then
i3bit=0
msg=msg40(1:22)
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
call genft8(msg,i3bit,0,1,msgsent,msgbits,itone)
write(*,1000) f0,xdt,txt,snrdb,bw,msgsent
1000 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, &
' BW:',f4.1,2x,a22)
else
call foxgen_wrap(msg40,msgbits,itone)
write(*,1001) f0,xdt,txt,snrdb,bw,msg40
call foxgen_wrap(msg,msgbits,itone)
write(*,1001) f0,xdt,txt,snrdb,bw,msg
1001 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, &
' BW:',f4.1,2x,a40)
' BW:',f4.1,2x,a37)
endif
write(*,1030) msgbits(1:56)
1030 format(/'Call1: ',28i1,' Call2: ',28i1)
write(*,1032) msgbits(57:72),msgbits(73:75),msgbits(76:87)
1032 format('Grid: ',16i1,' 3Bit: ',3i1,' CRC12: ',12i1)
write(*,1032) msgbits(57:72),msgbits(73:75)
1032 format('Grid: ',16i1,' 3Bit: ',3i1)
write(*,1034) itone
1034 format(/'Channel symbols:'/79i1/)
call sgran()
msg0=msg
do ifile=1,nfiles
c=0.
@ -99,7 +96,7 @@ program ft8sim
if(isig.eq.2) then
f0=f0+100
endif
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
call genft8(msg,i3bit,msgsent,msgbits,itone)
endif
if(nsig.eq.25) then
f0=(isig+2)*100.0
@ -118,18 +115,18 @@ program ft8sim
1002 format('R',i3.2)
f0=600.0 + mod(isig-1,5)*60.0
endif
call genft8(msg,mygrid6,bcontest,i3bit,msgsent,msgbits,itone)
call genft8(msg,i3bit,msgsent,msgbits,itone)
endif
k=-1 + nint((xdt+0.5+0.01*gran())/dt)
! k=-1 + nint((xdt+0.5)/dt)
ia=k+1
! k=nint((xdt+0.5+0.01*gran())/dt)
k=nint((xdt+0.5)/dt)
ia=k
phi=0.0
do j=1,NN !Generate complex waveform
dphi=twopi*(f0+itone(j)*baud)*dt
dphi=twopi*(f0*dt+itone(j)/real(NSPS))
do i=1,NSPS
if(k.ge.0 .and. k.lt.NMAX) c0(k)=cmplx(cos(phi),sin(phi))
k=k+1
phi=mod(phi+dphi,twopi)
if(k.ge.0 .and. k.lt.NMAX) c0(k)=cmplx(cos(phi),sin(phi))
enddo
enddo
if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c0,NMAX,fs,delay,fspread)
@ -145,9 +142,6 @@ program ft8sim
if(snrdb.lt.90) then
do i=1,NMAX !Add gaussian noise at specified SNR
xnoise=gran()
! wave(i)=wave(i) + xnoise
! if(i.ge.ia .and. i.le.ib) write(30,3001) i,wave(i)/peak
!3001 format(i8,f12.6)
wave(i)=wave(i) + xnoise
enddo
endif

134
lib/ft8/ft8sim2.f90 Normal file
View File

@ -0,0 +1,134 @@
program ft8sim2
! Generate simulated "type 2" ft8 files
! Output is saved to a *.wav file.
use wavhdr
use packjt77
include 'ft8_params.f90' !Set various constants
parameter (NWAVE=NN*NSPS)
type(hdr) h !Header for .wav file
character arg*12,fname*17
character msg37*37,msgsent37*37,msg40*40
character c77*77
complex c0(0:NMAX-1)
complex c(0:NMAX-1)
real wave(NMAX)
integer itone(NN)
integer*1 msgbits(77)
integer*2 iwave(NMAX) !Generated full-length waveform
! Get command-line argument(s)
nargs=iargc()
if(nargs.ne.8) then
print*,'Usage: ft8sim2 "message" f0 DT fdop del width nfiles snr'
print*,'Examples: ft8sim2 "K1ABC W9XYZ EN37" 1500.0 0.0 0.1 1.0 0 10 -18'
print*,' ft8sim2 "WA9XYZ/R KA1ABC/R FN42" 1500.0 0.0 0.1 1.0 0 10 -18'
print*,' ft8sim2 "K1ABC RR73; W9XYZ <KH1/KH7Z> -11" 300 0 0 0 25 1 -10'
go to 999
endif
call getarg(1,msg37) !Message to be transmitted
call getarg(2,arg)
read(arg,*) f0 !Frequency (only used for single-signal)
call getarg(3,arg)
read(arg,*) xdt !Time offset from nominal (s)
call getarg(4,arg)
read(arg,*) fspread !Watterson frequency spread (Hz)
call getarg(5,arg)
read(arg,*) delay !Watterson delay (ms)
call getarg(6,arg)
read(arg,*) width !Filter transition width (Hz)
call getarg(7,arg)
read(arg,*) nfiles !Number of files
call getarg(8,arg)
read(arg,*) snrdb !SNR_2500
nsig=1
if(f0.lt.100.0) then
nsig=f0
f0=1500
endif
nfiles=abs(nfiles)
twopi=8.0*atan(1.0)
fs=12000.0 !Sample rate (Hz)
dt=1.0/fs !Sample interval (s)
tt=NSPS*dt !Duration of symbols (s)
baud=1.0/tt !Keying rate (baud)
bw=8*baud !Occupied bandwidth (Hz)
txt=NZ*dt !Transmission length (s)
bandwidth_ratio=2500.0/(fs/2.0)
sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb)
if(snrdb.gt.90.0) sig=1.0
txt=NN*NSPS/12000.0
! Source-encode, then get itone()
call pack77(msg37,i3,n3,c77)
call genft8_174_91(msg37,i3,n3,msgsent37,msgbits,itone)
write(*,*)
write(*,'(a23,a37,3x,a7,i1,a1,i1)') 'New Style FT8 Message: ',msgsent37,'i3.n3: ',i3,'.',n3
write(*,1000) f0,xdt,txt,snrdb,bw
1000 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, &
' BW:',f4.1)
write(*,*)
if(i3.eq.1) then
write(*,*) ' mycall hiscall hisgrid'
write(*,'(28i1,1x,i1,1x,28i1,1x,i1,1x,i1,1x,15i1,1x,3i1)') msgbits(1:77)
else
write(*,'(a14)') 'Message bits: '
write(*,'(77i1)') msgbits
endif
write(*,*)
write(*,'(a17)') 'Channel symbols: '
write(*,'(79i1)') itone
write(*,*)
call sgran()
msg0=msg
do ifile=1,nfiles
k=nint((xdt+0.5)/dt)
ia=k
phi=0.0
c0=0.0
do j=1,NN !Generate complex waveform
dphi=twopi*(f0*dt+itone(j)/real(NSPS))
do i=1,NSPS
if(k.ge.0 .and. k.lt.NMAX) c0(k)=cmplx(cos(phi),sin(phi))
k=k+1
phi=mod(phi+dphi,twopi)
enddo
enddo
if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c0,NMAX,fs,delay,fspread)
c=sig*c0
ib=k
wave=real(c)
peak=maxval(abs(wave(ia:ib)))
rms=sqrt(dot_product(wave(ia:ib),wave(ia:ib))/NWAVE)
nslots=1
if(width.gt.0.0) call filt8(f0,nslots,width,wave)
if(snrdb.lt.90) then
do i=1,NMAX !Add gaussian noise at specified SNR
xnoise=gran()
wave(i)=wave(i) + xnoise
enddo
endif
fac=32767.0
rms=100.0
if(snrdb.ge.90.0) iwave(1:NMAX)=nint(fac*wave)
if(snrdb.lt.90.0) iwave(1:NMAX)=nint(rms*wave)
h=default_header(12000,NMAX)
write(fname,1102) ifile
1102 format('000000_',i6.6,'.wav')
open(10,file=fname,status='unknown',access='stream')
write(10) h,iwave !Save to *.wav file
close(10)
write(*,1110) ifile,xdt,f0,snrdb,fname
1110 format(i4,f7.2,f8.2,f7.1,2x,a17)
enddo
999 end program ft8sim2

View File

@ -1,4 +1,4 @@
subroutine genft8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
subroutine genft8(msg37,i3,n3,isync,msgsent37,msgbits77,itone)
! Encode an FT8 message, producing array itone().
@ -6,20 +6,26 @@ subroutine genft8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
use packjt
include 'ft8_params.f90'
character*22 msg,msgsent
character*6 mygrid
character*37 msg37,msgsent37
character*87 cbits
logical bcontest,checksumok
logical checksumok
integer*4 i4Msg6BitWords(12) !72-bit message as 6-bit words
integer*1 msgbits(KK),codeword(3*ND)
integer*1 msgbits77(77)
integer*1, target:: i1Msg8BitBytes(11)
integer itone(NN)
integer icos7(0:6)
data icos7/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern
call packmsg(msg,i4Msg6BitWords,itype,bcontest) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent,bcontest,mygrid) !Unpack to get msgsent
if(isync.eq.2 ) goto 900
msg=msg37(1:22)
call packmsg(msg,i4Msg6BitWords,istdtype) !Pack into 12 6-bit bytes
call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent
msgsent37(1:22)=msgsent
msgsent37(23:37)=' '
write(cbits,1000) i4Msg6BitWords,32*i3bit
write(cbits,1000) i4Msg6BitWords,32*i3
1000 format(12b6.6,b8.8)
read(cbits,1001) i1Msg8BitBytes(1:10)
1001 format(10b8)
@ -27,19 +33,14 @@ subroutine genft8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
i1Msg8BitBytes(11)=0
icrc12=crc12(c_loc(i1Msg8BitBytes),11)
! 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
write(cbits,1003) i4Msg6BitWords,i3,icrc12
1003 format(12b6.6,b3.3,b12.12)
read(cbits,1004) msgbits
1004 format(87i1)
call encode174(msgbits,codeword) !Encode the test message
msgbits77=-1
msgbits77(1:75)=msgbits(1:75)
! Message structure: S7 D29 S7 D29 S7
itone(1:7)=icos7
itone(36+1:36+7)=icos7
@ -51,6 +52,11 @@ subroutine genft8(msg,mygrid,bcontest,i3bit,msgsent,msgbits,itone)
if(j.eq.30) k=k+7
itone(k)=codeword(i)*4 + codeword(i+1)*2 + codeword(i+2)
enddo
return
900 continue
call genft8_174_91(msg37,i3,n3,msgsent37,msgbits77,itone)
return
end subroutine genft8

39
lib/ft8/genft8_174_91.f90 Normal file
View File

@ -0,0 +1,39 @@
subroutine genft8_174_91(msg,i3,n3,msgsent,msgbits,itone)
! Encode an FT8 message, producing array itone().
use packjt77
include 'ft8_params.f90'
character msg*37,msgsent*37
character*77 c77
integer*1 msgbits(77),codeword(174)
integer itone(79)
integer icos7(0:6)
integer graymap(0:7)
logical unpk77_success
data icos7/3,1,4,0,6,5,2/ !Costas 7x7 tone pattern
data graymap/0,1,3,2,5,6,4,7/
call pack77(msg,i3,n3,c77)
call unpack77(c77,msgsent,unpk77_success)
read(c77,'(77i1)',err=1) msgbits
go to 2
1 write(81,*) msg,c77 ; flush(81)
2 call encode174_91(msgbits,codeword) !Encode the test message
! Message structure: S7 D29 S7 D29 S7
itone(1:7)=icos7
itone(36+1:36+7)=icos7
itone(NN-6:NN)=icos7
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)=graymap(indx)
enddo
return
end subroutine genft8_174_91

View File

@ -1,7 +1,8 @@
subroutine genft8refsig(itone,cref,f0)
complex cref(79*1920)
integer itone(79)
real*8 twopi,phi,dphi,dt,xnsps
! real*8 twopi,phi,dphi,dt,xnsps
real twopi,phi,dphi,dt,xnsps
data twopi/0.d0/
save twopi
if( twopi .lt. 0.1 ) twopi=8.d0*atan(1.d0)

View File

@ -0,0 +1,11 @@
data colorder/ &
0, 1, 2, 3, 28, 4, 5, 6, 7, 8, 9, 10, 11, 34, 12, 32, 13, 14, 15, 16, &
17, 18, 36, 29, 43, 19, 20, 42, 21, 40, 30, 37, 22, 47, 61, 45, 44, 23, 41, 39, &
49, 24, 46, 50, 48, 26, 31, 33, 51, 38, 52, 59, 55, 66, 57, 27, 60, 35, 54, 58, &
25, 56, 62, 64, 67, 69, 63, 68, 70, 72, 65, 73, 75, 74, 71, 77, 78, 76, 79, 80, &
53, 81, 83, 82, 84, 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/

View File

@ -0,0 +1,86 @@
character*23 g(83)
data g/ &
"8329ce11bf31eaf509f27fc", &
"761c264e25c259335493132", &
"dc265902fb277c6410a1bdc", &
"1b3f417858cd2dd33ec7f62", &
"09fda4fee04195fd034783a", &
"077cccc11b8873ed5c3d48a", &
"29b62afe3ca036f4fe1a9da", &
"6054faf5f35d96d3b0c8c3e", &
"e20798e4310eed27884ae90", &
"775c9c08e80e26ddae56318", &
"b0b811028c2bf997213487c", &
"18a0c9231fc60adf5c5ea32", &
"76471e8302a0721e01b12b8", &
"ffbccb80ca8341fafb47b2e", &
"66a72a158f9325a2bf67170", &
"c4243689fe85b1c51363a18", &
"0dff739414d1a1b34b1c270", &
"15b48830636c8b99894972e", &
"29a89c0d3de81d665489b0e", &
"4f126f37fa51cbe61bd6b94", &
"99c47239d0d97d3c84e0940", &
"1919b75119765621bb4f1e8", &
"09db12d731faee0b86df6b8", &
"488fc33df43fbdeea4eafb4", &
"827423ee40b675f756eb5fe", &
"abe197c484cb74757144a9a", &
"2b500e4bc0ec5a6d2bdbdd0", &
"c474aa53d70218761669360", &
"8eba1a13db3390bd6718cec", &
"753844673a27782cc42012e", &
"06ff83a145c37035a5c1268", &
"3b37417858cc2dd33ec3f62", &
"9a4a5a28ee17ca9c324842c", &
"bc29f465309c977e89610a4", &
"2663ae6ddf8b5ce2bb29488", &
"46f231efe457034c1814418", &
"3fb2ce85abe9b0c72e06fbe", &
"de87481f282c153971a0a2e", &
"fcd7ccf23c69fa99bba1412", &
"f0261447e9490ca8e474cec", &
"4410115818196f95cdd7012", &
"088fc31df4bfbde2a4eafb4", &
"b8fef1b6307729fb0a078c0", &
"5afea7acccb77bbc9d99a90", &
"49a7016ac653f65ecdc9076", &
"1944d085be4e7da8d6cc7d0", &
"251f62adc4032f0ee714002", &
"56471f8702a0721e00b12b8", &
"2b8e4923f2dd51e2d537fa0", &
"6b550a40a66f4755de95c26", &
"a18ad28d4e27fe92a4f6c84", &
"10c2e586388cb82a3d80758", &
"ef34a41817ee02133db2eb0", &
"7e9c0c54325a9c15836e000", &
"3693e572d1fde4cdf079e86", &
"bfb2cec5abe1b0c72e07fbe", &
"7ee18230c583cccc57d4b08", &
"a066cb2fedafc9f52664126", &
"bb23725abc47cc5f4cc4cd2", &
"ded9dba3bee40c59b5609b4", &
"d9a7016ac653e6decdc9036", &
"9ad46aed5f707f280ab5fc4", &
"e5921c77822587316d7d3c2", &
"4f14da8242a8b86dca73352", &
"8b8b507ad467d4441df770e", &
"22831c9cf1169467ad04b68", &
"213b838fe2ae54c38ee7180", &
"5d926b6dd71f085181a4e12", &
"66ab79d4b29ee6e69509e56", &
"958148682d748a38dd68baa", &
"b8ce020cf069c32a723ab14", &
"f4331d6d461607e95752746", &
"6da23ba424b9596133cf9c8", &
"a636bcbc7b30c5fbeae67fe", &
"5cb0d86a07df654a9089a20", &
"f11f106848780fc9ecdd80a", &
"1fbb5364fb8d2c9d730d5ba", &
"fcb86bc70a50c9d02a5d034", &
"a534433029eac15f322e34c", &
"c989d9c7c3d3b8c55d75130", &
"7bb38b2f0186d46643ae962", &
"2644ebadeb44b9467d1f42c", &
"608cc857594bfbb55d69600"/

View File

@ -0,0 +1,269 @@
data Mn/ &
1, 24, 66, &
2, 5, 70, &
3, 31, 65, &
4, 49, 58, &
6, 60, 67, &
7, 32, 75, &
8, 48, 82, &
9, 35, 41, &
10, 39, 62, &
11, 14, 61, &
12, 71, 74, &
13, 23, 78, &
15, 16, 79, &
17, 54, 63, &
18, 50, 57, &
19, 30, 47, &
20, 64, 80, &
21, 28, 69, &
22, 25, 43, &
26, 34, 72, &
27, 36, 37, &
29, 40, 44, &
33, 52, 53, &
38, 55, 83, &
42, 51, 59, &
45, 76, 81, &
46, 68, 77, &
56, 67, 73, &
1, 4, 5, &
2, 47, 51, &
3, 46, 82, &
6, 24, 76, &
7, 9, 16, &
8, 10, 78, &
11, 35, 55, &
12, 38, 64, &
13, 22, 37, &
14, 15, 58, &
17, 50, 53, &
18, 29, 56, &
19, 26, 57, &
20, 39, 77, &
21, 36, 63, &
23, 54, 74, &
25, 69, 73, &
27, 33, 65, &
28, 44, 79, &
30, 43, 52, &
31, 45, 61, &
32, 48, 71, &
34, 60, 62, &
40, 41, 70, &
42, 66, 68, &
49, 75, 83, &
59, 72, 80, &
36, 64, 81, &
1, 65, 74, &
2, 8, 81, &
3, 26, 79, &
4, 22, 72, &
5, 38, 50, &
6, 9, 52, &
7, 18, 77, &
10, 28, 55, &
11, 56, 59, &
12, 67, 68, &
13, 29, 47, &
14, 39, 54, &
15, 60, 70, &
16, 37, 66, &
17, 25, 82, &
19, 21, 71, &
20, 30, 31, &
23, 75, 80, &
24, 69, 75, &
27, 32, 62, &
33, 59, 76, &
34, 53, 61, &
35, 46, 47, &
40, 43, 83, &
41, 42, 63, &
20, 44, 48, &
16, 45, 73, &
42, 49, 57, &
25, 51, 62, &
33, 58, 78, &
1, 44, 45, &
2, 7, 61, &
3, 6, 54, &
4, 35, 48, &
5, 13, 21, &
8, 56, 79, &
9, 64, 69, &
10, 19, 66, &
11, 36, 60, &
12, 37, 58, &
14, 32, 43, &
15, 63, 80, &
17, 28, 77, &
18, 74, 83, &
22, 53, 81, &
23, 30, 34, &
24, 31, 40, &
26, 41, 76, &
27, 57, 70, &
29, 49, 65, &
3, 38, 78, &
5, 39, 82, &
46, 50, 73, &
51, 52, 74, &
55, 71, 72, &
44, 67, 72, &
43, 68, 78, &
1, 32, 59, &
2, 6, 71, &
4, 16, 54, &
7, 65, 67, &
8, 30, 42, &
9, 22, 31, &
10, 18, 76, &
11, 23, 82, &
12, 28, 61, &
13, 52, 79, &
14, 50, 51, &
15, 81, 83, &
17, 29, 60, &
19, 33, 64, &
20, 26, 73, &
21, 34, 40, &
24, 27, 77, &
25, 55, 58, &
35, 53, 66, &
36, 48, 68, &
37, 46, 75, &
38, 45, 47, &
39, 57, 69, &
41, 56, 62, &
20, 49, 53, &
46, 52, 63, &
45, 70, 75, &
27, 35, 80, &
1, 15, 30, &
2, 68, 80, &
3, 36, 51, &
4, 28, 51, &
5, 31, 56, &
6, 20, 37, &
7, 40, 82, &
8, 60, 69, &
9, 10, 49, &
11, 44, 57, &
12, 39, 59, &
13, 24, 55, &
14, 21, 65, &
16, 71, 78, &
17, 30, 76, &
18, 25, 80, &
19, 61, 83, &
22, 38, 77, &
23, 41, 50, &
7, 26, 58, &
29, 32, 81, &
33, 40, 73, &
18, 34, 48, &
13, 42, 64, &
5, 26, 43, &
47, 69, 72, &
54, 55, 70, &
45, 62, 68, &
10, 63, 67, &
14, 66, 72, &
22, 60, 74, &
35, 39, 79, &
1, 46, 64/
data Nm/ &
1, 29, 57, 87, 114, 142, 174, &
2, 30, 58, 88, 115, 143, 0, &
3, 31, 59, 89, 107, 144, 0, &
4, 29, 60, 90, 116, 145, 0, &
2, 29, 61, 91, 108, 146, 166, &
5, 32, 62, 89, 115, 147, 0, &
6, 33, 63, 88, 117, 148, 161, &
7, 34, 58, 92, 118, 149, 0, &
8, 33, 62, 93, 119, 150, 0, &
9, 34, 64, 94, 120, 150, 170, &
10, 35, 65, 95, 121, 151, 0, &
11, 36, 66, 96, 122, 152, 0, &
12, 37, 67, 91, 123, 153, 165, &
10, 38, 68, 97, 124, 154, 171, &
13, 38, 69, 98, 125, 142, 0, &
13, 33, 70, 83, 116, 155, 0, &
14, 39, 71, 99, 126, 156, 0, &
15, 40, 63, 100, 120, 157, 164, &
16, 41, 72, 94, 127, 158, 0, &
17, 42, 73, 82, 128, 138, 147, &
18, 43, 72, 91, 129, 154, 0, &
19, 37, 60, 101, 119, 159, 172, &
12, 44, 74, 102, 121, 160, 0, &
1, 32, 75, 103, 130, 153, 0, &
19, 45, 71, 85, 131, 157, 0, &
20, 41, 59, 104, 128, 161, 166, &
21, 46, 76, 105, 130, 141, 0, &
18, 47, 64, 99, 122, 145, 0, &
22, 40, 67, 106, 126, 162, 0, &
16, 48, 73, 102, 118, 142, 156, &
3, 49, 73, 103, 119, 146, 0, &
6, 50, 76, 97, 114, 162, 0, &
23, 46, 77, 86, 127, 163, 0, &
20, 51, 78, 102, 129, 164, 0, &
8, 35, 79, 90, 132, 141, 173, &
21, 43, 56, 95, 133, 144, 0, &
21, 37, 70, 96, 134, 147, 0, &
24, 36, 61, 107, 135, 159, 0, &
9, 42, 68, 108, 136, 152, 173, &
22, 52, 80, 103, 129, 148, 163, &
8, 52, 81, 104, 137, 160, 0, &
25, 53, 81, 84, 118, 165, 0, &
19, 48, 80, 97, 113, 166, 0, &
22, 47, 82, 87, 112, 151, 0, &
26, 49, 83, 87, 135, 140, 169, &
27, 31, 79, 109, 134, 139, 174, &
16, 30, 67, 79, 135, 167, 0, &
7, 50, 82, 90, 133, 164, 0, &
4, 54, 84, 106, 138, 150, 0, &
15, 39, 61, 109, 124, 160, 0, &
25, 30, 85, 110, 124, 144, 145, &
23, 48, 62, 110, 123, 139, 0, &
23, 39, 78, 101, 132, 138, 0, &
14, 44, 68, 89, 116, 168, 0, &
24, 35, 64, 111, 131, 153, 168, &
28, 40, 65, 92, 137, 146, 0, &
15, 41, 84, 105, 136, 151, 0, &
4, 38, 86, 96, 131, 161, 0, &
25, 55, 65, 77, 114, 152, 0, &
5, 51, 69, 95, 126, 149, 172, &
10, 49, 78, 88, 122, 158, 0, &
9, 51, 76, 85, 137, 169, 0, &
14, 43, 81, 98, 139, 170, 0, &
17, 36, 56, 93, 127, 165, 174, &
3, 46, 57, 106, 117, 154, 0, &
1, 53, 70, 94, 132, 171, 0, &
5, 28, 66, 112, 117, 170, 0, &
27, 53, 66, 113, 133, 143, 169, &
18, 45, 75, 93, 136, 149, 167, &
2, 52, 69, 105, 140, 168, 0, &
11, 50, 72, 111, 115, 155, 0, &
20, 55, 60, 111, 112, 167, 171, &
28, 45, 83, 109, 128, 163, 0, &
11, 44, 57, 100, 110, 172, 0, &
6, 54, 74, 75, 134, 140, 0, &
26, 32, 77, 104, 120, 156, 0, &
27, 42, 63, 99, 130, 159, 0, &
12, 34, 86, 107, 113, 155, 0, &
13, 47, 59, 92, 123, 173, 0, &
17, 55, 74, 98, 141, 143, 157, &
26, 56, 58, 101, 125, 162, 0, &
7, 31, 71, 108, 121, 148, 0, &
24, 54, 80, 100, 125, 158, 0/
data nrw/ &
7,6,6,6,7,6,7,6,6,7,6,6,7,7,6,6,6, &
7,6,7,6,7,6,6,6,7,6,6,6,7,6,6,6,6, &
7,6,6,6,7,7,6,6,6,6,7,7,6,6,6,6,7, &
6,6,6,7,6,6,6,6,7,6,6,6,7,6,6,6,7, &
7,6,6,7,6,6,6,6,6,6,6,7,6,6,6/
ncw=3

View File

@ -0,0 +1,270 @@
data Mn/ &
16, 45, 73, &
25, 51, 62, &
33, 58, 78, &
1, 44, 45, &
2, 7, 61, &
3, 6, 54, &
4, 35, 48, &
5, 13, 21, &
8, 56, 79, &
9, 64, 69, &
10, 19, 66, &
11, 36, 60, &
12, 37, 58, &
14, 32, 43, &
15, 63, 80, &
17, 28, 77, &
18, 74, 83, &
22, 53, 81, &
23, 30, 34, &
24, 31, 40, &
26, 41, 76, &
27, 57, 70, &
29, 49, 65, &
3, 38, 78, &
5, 39, 82, &
46, 50, 73, &
51, 52, 74, &
55, 71, 72, &
44, 67, 72, &
43, 68, 78, &
1, 32, 59, &
2, 6, 71, &
4, 16, 54, &
7, 65, 67, &
8, 30, 42, &
9, 22, 31, &
10, 18, 76, &
11, 23, 82, &
12, 28, 61, &
13, 52, 79, &
14, 50, 51, &
15, 81, 83, &
17, 29, 60, &
19, 33, 64, &
20, 26, 73, &
21, 34, 40, &
24, 27, 77, &
25, 55, 58, &
35, 53, 66, &
36, 48, 68, &
37, 46, 75, &
38, 45, 47, &
39, 57, 69, &
41, 56, 62, &
20, 49, 53, &
46, 52, 63, &
45, 70, 75, &
27, 35, 80, &
1, 15, 30, &
2, 68, 80, &
3, 36, 51, &
4, 28, 51, &
5, 31, 56, &
6, 20, 37, &
7, 40, 82, &
8, 60, 69, &
9, 10, 49, &
11, 44, 57, &
12, 39, 59, &
13, 24, 55, &
14, 21, 65, &
16, 71, 78, &
17, 30, 76, &
18, 25, 80, &
19, 61, 83, &
22, 38, 77, &
23, 41, 50, &
7, 26, 58, &
29, 32, 81, &
33, 40, 73, &
18, 34, 48, &
13, 42, 64, &
5, 26, 43, &
47, 69, 72, &
54, 55, 70, &
45, 62, 68, &
10, 63, 67, &
14, 66, 72, &
22, 60, 74, &
35, 39, 79, &
1, 46, 64, &
1, 24, 66, &
2, 5, 70, &
3, 31, 65, &
4, 49, 58, &
1, 4, 5, &
6, 60, 67, &
7, 32, 75, &
8, 48, 82, &
9, 35, 41, &
10, 39, 62, &
11, 14, 61, &
12, 71, 74, &
13, 23, 78, &
11, 35, 55, &
15, 16, 79, &
7, 9, 16, &
17, 54, 63, &
18, 50, 57, &
19, 30, 47, &
20, 64, 80, &
21, 28, 69, &
22, 25, 43, &
13, 22, 37, &
2, 47, 51, &
23, 54, 74, &
26, 34, 72, &
27, 36, 37, &
21, 36, 63, &
29, 40, 44, &
19, 26, 57, &
3, 46, 82, &
14, 15, 58, &
33, 52, 53, &
30, 43, 52, &
6, 9, 52, &
27, 33, 65, &
25, 69, 73, &
38, 55, 83, &
20, 39, 77, &
18, 29, 56, &
32, 48, 71, &
42, 51, 59, &
28, 44, 79, &
34, 60, 62, &
31, 45, 61, &
46, 68, 77, &
6, 24, 76, &
8, 10, 78, &
40, 41, 70, &
17, 50, 53, &
42, 66, 68, &
4, 22, 72, &
36, 64, 81, &
13, 29, 47, &
2, 8, 81, &
56, 67, 73, &
5, 38, 50, &
12, 38, 64, &
59, 72, 80, &
3, 26, 79, &
45, 76, 81, &
1, 65, 74, &
7, 18, 77, &
11, 56, 59, &
14, 39, 54, &
16, 37, 66, &
10, 28, 55, &
15, 60, 70, &
17, 25, 82, &
20, 30, 31, &
12, 67, 68, &
23, 75, 80, &
27, 32, 62, &
24, 69, 75, &
19, 21, 71, &
34, 53, 61, &
35, 46, 47, &
33, 59, 76, &
40, 43, 83, &
41, 42, 63, &
49, 75, 83, &
20, 44, 48, &
42, 49, 57/
data Nm/ &
4, 31, 59, 91, 92, 96, 153, &
5, 32, 60, 93, 115, 146, 0, &
6, 24, 61, 94, 122, 151, 0, &
7, 33, 62, 95, 96, 143, 0, &
8, 25, 63, 83, 93, 96, 148, &
6, 32, 64, 97, 126, 138, 0, &
5, 34, 65, 78, 98, 107, 154, &
9, 35, 66, 99, 139, 146, 0, &
10, 36, 67, 100, 107, 126, 0, &
11, 37, 67, 87, 101, 139, 158, &
12, 38, 68, 102, 105, 155, 0, &
13, 39, 69, 103, 149, 162, 0, &
8, 40, 70, 82, 104, 114, 145, &
14, 41, 71, 88, 102, 123, 156, &
15, 42, 59, 106, 123, 159, 0, &
1, 33, 72, 106, 107, 157, 0, &
16, 43, 73, 108, 141, 160, 0, &
17, 37, 74, 81, 109, 131, 154, &
11, 44, 75, 110, 121, 166, 0, &
45, 55, 64, 111, 130, 161, 173, &
8, 46, 71, 112, 119, 166, 0, &
18, 36, 76, 89, 113, 114, 143, &
19, 38, 77, 104, 116, 163, 0, &
20, 47, 70, 92, 138, 165, 0, &
2, 48, 74, 113, 128, 160, 0, &
21, 45, 78, 83, 117, 121, 151, &
22, 47, 58, 118, 127, 164, 0, &
16, 39, 62, 112, 134, 158, 0, &
23, 43, 79, 120, 131, 145, 0, &
19, 35, 59, 73, 110, 125, 161, &
20, 36, 63, 94, 136, 161, 0, &
14, 31, 79, 98, 132, 164, 0, &
3, 44, 80, 124, 127, 169, 0, &
19, 46, 81, 117, 135, 167, 0, &
7, 49, 58, 90, 100, 105, 168, &
12, 50, 61, 118, 119, 144, 0, &
13, 51, 64, 114, 118, 157, 0, &
24, 52, 76, 129, 148, 149, 0, &
25, 53, 69, 90, 101, 130, 156, &
20, 46, 65, 80, 120, 140, 170, &
21, 54, 77, 100, 140, 171, 0, &
35, 82, 133, 142, 171, 174, 0, &
14, 30, 83, 113, 125, 170, 0, &
4, 29, 68, 120, 134, 173, 0, &
1, 4, 52, 57, 86, 136, 152, &
26, 51, 56, 91, 122, 137, 168, &
52, 84, 110, 115, 145, 168, 0, &
7, 50, 81, 99, 132, 173, 0, &
23, 55, 67, 95, 172, 174, 0, &
26, 41, 77, 109, 141, 148, 0, &
2, 27, 41, 61, 62, 115, 133, &
27, 40, 56, 124, 125, 126, 0, &
18, 49, 55, 124, 141, 167, 0, &
6, 33, 85, 108, 116, 156, 0, &
28, 48, 70, 85, 105, 129, 158, &
9, 54, 63, 131, 147, 155, 0, &
22, 53, 68, 109, 121, 174, 0, &
3, 13, 48, 78, 95, 123, 0, &
31, 69, 133, 150, 155, 169, 0, &
12, 43, 66, 89, 97, 135, 159, &
5, 39, 75, 102, 136, 167, 0, &
2, 54, 86, 101, 135, 164, 0, &
15, 56, 87, 108, 119, 171, 0, &
10, 44, 82, 91, 111, 144, 149, &
23, 34, 71, 94, 127, 153, 0, &
11, 49, 88, 92, 142, 157, 0, &
29, 34, 87, 97, 147, 162, 0, &
30, 50, 60, 86, 137, 142, 162, &
10, 53, 66, 84, 112, 128, 165, &
22, 57, 85, 93, 140, 159, 0, &
28, 32, 72, 103, 132, 166, 0, &
28, 29, 84, 88, 117, 143, 150, &
1, 26, 45, 80, 128, 147, 0, &
17, 27, 89, 103, 116, 153, 0, &
51, 57, 98, 163, 165, 172, 0, &
21, 37, 73, 138, 152, 169, 0, &
16, 47, 76, 130, 137, 154, 0, &
3, 24, 30, 72, 104, 139, 0, &
9, 40, 90, 106, 134, 151, 0, &
15, 58, 60, 74, 111, 150, 163, &
18, 42, 79, 144, 146, 152, 0, &
25, 38, 65, 99, 122, 160, 0, &
17, 42, 75, 129, 170, 172, 0/
data nrw/ &
7,6,6,6,7,6,7,6,6,7,6,6,7,7,6,6, &
6,7,6,7,6,7,6,6,6,7,6,6,6,7,6,6, &
6,6,7,6,6,6,7,7,6,6,6,6,7,7,6,6, &
6,6,7,6,6,6,7,6,6,6,6,7,6,6,6,7, &
6,6,6,7,7,6,6,7,6,6,6,6,6,6,6,7, &
6,6,6/
ncw=3

372
lib/ft8/osd174_91.f90 Normal file
View File

@ -0,0 +1,372 @@
subroutine osd174_91(llr,apmask,ndeep,message77,cw,nhardmin,dmin)
!
! An ordered-statistics decoder for the (174,91) code.
!
integer, parameter:: N=174, K=91, M=N-K
integer*1 apmask(N),apmaskr(N)
integer*1 gen(K,N)
integer*1 genmrb(K,N),g2(N,K)
integer*1 temp(K),m0(K),me(K),mi(K),misub(K),e2sub(N-K),e2(N-K),ui(N-K)
integer*1 r2pat(N-K)
integer indices(N),nxor(N)
integer*1 cw(N),ce(N),c0(N),hdec(N)
integer*1 decoded(K)
integer*1 message77(77)
integer indx(N)
real llr(N),rx(N),absrx(N)
include "ldpc_174_91_c_generator.f90"
logical first,reset
data first/.true./
save first,gen
if( first ) then ! fill the generator matrix
gen=0
do i=1,M
do j=1,23
read(g(i)(j:j),"(Z1)") istr
ibmax=4
if(j.eq.23) ibmax=3
do jj=1, ibmax
irow=(j-1)*4+jj
if( btest(istr,4-jj) ) gen(irow,K+i)=1
enddo
enddo
enddo
do irow=1,K
gen(irow,irow)=1
enddo
first=.false.
endif
rx=llr
apmaskr=apmask
! Hard decisions on the received word.
hdec=0
where(rx .ge. 0) hdec=1
! Use magnitude of received symbols as a measure of reliability.
absrx=abs(rx)
call indexx(absrx,N,indx)
! Re-order the columns of the generator matrix in order of decreasing reliability.
do i=1,N
genmrb(1:K,i)=gen(1:K,indx(N+1-i))
indices(i)=indx(N+1-i)
enddo
! Do gaussian elimination to create a generator matrix with the most reliable
! received bits in positions 1:K in order of decreasing reliability (more or less).
do id=1,K ! diagonal element indices
do icol=id,K+20 ! The 20 is ad hoc - beware
iflag=0
if( genmrb(id,icol) .eq. 1 ) then
iflag=1
if( icol .ne. id ) then ! reorder column
temp(1:K)=genmrb(1:K,id)
genmrb(1:K,id)=genmrb(1:K,icol)
genmrb(1:K,icol)=temp(1:K)
itmp=indices(id)
indices(id)=indices(icol)
indices(icol)=itmp
endif
do ii=1,K
if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then
genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N))
endif
enddo
exit
endif
enddo
enddo
g2=transpose(genmrb)
! The hard decisions for the K MRB bits define the order 0 message, m0.
! Encode m0 using the modified generator matrix to find the "order 0" codeword.
! Flip various combinations of bits in m0 and re-encode to generate a list of
! codewords. Return the member of the list that has the smallest Euclidean
! distance to the received word.
hdec=hdec(indices) ! hard decisions from received symbols
m0=hdec(1:K) ! zero'th order message
absrx=absrx(indices)
rx=rx(indices)
apmaskr=apmaskr(indices)
call mrbencode91(m0,c0,g2,N,K)
nxor=ieor(c0,hdec)
nhardmin=sum(nxor)
dmin=sum(nxor*absrx)
cw=c0
ntotal=0
nrejected=0
if(ndeep.eq.0) goto 998 ! norder=0
if(ndeep.gt.5) ndeep=5
if( ndeep.eq. 1) then
nord=1
npre1=0
npre2=0
nt=40
ntheta=12
elseif(ndeep.eq.2) then
nord=1
npre1=1
npre2=0
nt=40
ntheta=12
elseif(ndeep.eq.3) then
nord=1
npre1=1
npre2=1
nt=40
ntheta=12
ntau=14
elseif(ndeep.eq.4) then
nord=2
npre1=1
npre2=0
nt=40
ntheta=12
ntau=19
elseif(ndeep.eq.5) then
nord=2
npre1=1
npre2=1
nt=40
ntheta=12
ntau=19
endif
do iorder=1,nord
misub(1:K-iorder)=0
misub(K-iorder+1:K)=1
iflag=K-iorder+1
do while(iflag .ge.0)
if(iorder.eq.nord .and. npre1.eq.0) then
iend=iflag
else
iend=1
endif
do n1=iflag,iend,-1
mi=misub
mi(n1)=1
if(any(iand(apmaskr(1:K),mi).eq.1)) cycle
ntotal=ntotal+1
me=ieor(m0,mi)
if(n1.eq.iflag) then
call mrbencode91(me,ce,g2,N,K)
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
e2=e2sub
nd1Kpt=sum(e2sub(1:nt))+1
d1=sum(ieor(me(1:K),hdec(1:K))*absrx(1:K))
else
e2=ieor(e2sub,g2(K+1:N,n1))
nd1Kpt=sum(e2(1:nt))+2
endif
if(nd1Kpt .le. ntheta) then
call mrbencode91(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
if(n1.eq.iflag) then
dd=d1+sum(e2sub*absrx(K+1:N))
else
dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(K+1:N))
endif
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
nd1Kptbest=nd1Kpt
endif
else
nrejected=nrejected+1
endif
enddo
! Get the next test error pattern, iflag will go negative
! when the last pattern with weight iorder has been generated.
call nextpat91(misub,k,iorder,iflag)
enddo
enddo
if(npre2.eq.1) then
reset=.true.
ntotal=0
do i1=K,1,-1
do i2=i1-1,1,-1
ntotal=ntotal+1
mi(1:ntau)=ieor(g2(K+1:K+ntau,i1),g2(K+1:K+ntau,i2))
call boxit91(reset,mi(1:ntau),ntau,ntotal,i1,i2)
enddo
enddo
ncount2=0
ntotal2=0
reset=.true.
! Now run through again and do the second pre-processing rule
misub(1:K-nord)=0
misub(K-nord+1:K)=1
iflag=K-nord+1
do while(iflag .ge.0)
me=ieor(m0,misub)
call mrbencode91(me,ce,g2,N,K)
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
do i2=0,ntau
ntotal2=ntotal2+1
ui=0
if(i2.gt.0) ui(i2)=1
r2pat=ieor(e2sub,ui)
778 continue
call fetchit91(reset,r2pat(1:ntau),ntau,in1,in2)
if(in1.gt.0.and.in2.gt.0) then
ncount2=ncount2+1
mi=misub
mi(in1)=1
mi(in2)=1
if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:K),mi).eq.1)) cycle
me=ieor(m0,mi)
call mrbencode91(me,ce,g2,N,K)
nxor=ieor(ce,hdec)
dd=sum(nxor*absrx)
if( dd .lt. dmin ) then
dmin=dd
cw=ce
nhardmin=sum(nxor)
endif
goto 778
endif
enddo
call nextpat91(misub,K,nord,iflag)
enddo
endif
998 continue
! Re-order the codeword to [message bits][parity bits] format.
cw(indices)=cw
hdec(indices)=hdec
decoded=cw(1:K)
call chkcrc14a(decoded,nbadcrc)
message77=decoded(1:77)
if(nbadcrc.eq.1) nhardmin=-nhardmin
return
end subroutine osd174_91
subroutine mrbencode91(me,codeword,g2,N,K)
integer*1 me(K),codeword(N),g2(N,K)
! fast encoding for low-weight test patterns
codeword=0
do i=1,K
if( me(i) .eq. 1 ) then
codeword=ieor(codeword,g2(1:N,i))
endif
enddo
return
end subroutine mrbencode91
subroutine nextpat91(mi,k,iorder,iflag)
integer*1 mi(k),ms(k)
! generate the next test error pattern
ind=-1
do i=1,k-1
if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i
enddo
if( ind .lt. 0 ) then ! no more patterns of this order
iflag=ind
return
endif
ms=0
ms(1:ind-1)=mi(1:ind-1)
ms(ind)=1
ms(ind+1)=0
if( ind+1 .lt. k ) then
nz=iorder-sum(ms)
ms(k-nz+1:k)=1
endif
mi=ms
do i=1,k ! iflag will point to the lowest-index 1 in mi
if(mi(i).eq.1) then
iflag=i
exit
endif
enddo
return
end subroutine nextpat91
subroutine boxit91(reset,e2,ntau,npindex,i1,i2)
integer*1 e2(1:ntau)
integer indexes(5000,2),fp(0:525000),np(5000)
logical reset
common/boxes/indexes,fp,np
if(reset) then
patterns=-1
fp=-1
np=-1
sc=-1
indexes=-1
reset=.false.
endif
indexes(npindex,1)=i1
indexes(npindex,2)=i2
ipat=0
do i=1,ntau
if(e2(i).eq.1) then
ipat=ipat+ishft(1,ntau-i)
endif
enddo
ip=fp(ipat) ! see what's currently stored in fp(ipat)
if(ip.eq.-1) then
fp(ipat)=npindex
else
do while (np(ip).ne.-1)
ip=np(ip)
enddo
np(ip)=npindex
endif
return
end subroutine boxit91
subroutine fetchit91(reset,e2,ntau,i1,i2)
integer indexes(5000,2),fp(0:525000),np(5000)
integer lastpat
integer*1 e2(ntau)
logical reset
common/boxes/indexes,fp,np
save lastpat,inext
if(reset) then
lastpat=-1
reset=.false.
endif
ipat=0
do i=1,ntau
if(e2(i).eq.1) then
ipat=ipat+ishft(1,ntau-i)
endif
enddo
index=fp(ipat)
if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices
i1=indexes(index,1)
i2=indexes(index,2)
inext=np(index)
elseif(lastpat.eq.ipat .and. inext.gt.0) then
i1=indexes(inext,1)
i2=indexes(inext,2)
inext=np(inext)
else
i1=-1
i2=-1
inext=-1
endif
lastpat=ipat
return
end subroutine fetchit91

View File

@ -1,23 +1,25 @@
subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
subroutine sync8(dd,nfa,nfb,syncmin,nfqso,ldecode77,maxcand,s,candidate,ncand,sbase)
include 'ft8_params.f90'
! Search over +/- 2.5s relative to 0.5s TX start time.
parameter (JZ=62)
complex cx(0:NH1)
logical ldecode77
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 candidate0(4,maxcand)
real candidate(4,maxcand)
real dd(NMAX)
integer jpeak(NH1)
integer indx(NH1)
integer ii(1)
integer icos7(0:6)
data icos7/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern
integer icos7_1(0:6),icos7_2(0:6),icos7(0:6)
data icos7_1/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern
data icos7_2/3,1,4,0,6,5,2/ !Costas 7x7 tone pattern
equivalence (x,cx)
! Compute symbol spectra, stepping by NSTEP steps.
@ -49,8 +51,16 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
nfos=NFFT1/NSPS ! # frequency bin oversampling factor
jstrt=0.5/tstep
do i=ia,ib
do j=-JZ,+JZ
candidate0=0.
k=0
is1=1
if(ldecode77) is1=2
do isync=is1,2
if(isync.eq.1) icos7=icos7_1
if(isync.eq.2) icos7=icos7_2
do i=ia,ib
do j=-JZ,+JZ
ta=0.
tb=0.
tc=0.
@ -58,16 +68,16 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
t0b=0.
t0c=0.
do n=0,6
k=j+jstrt+nssy*n
if(k.ge.1.and.k.le.NHSYM) then
ta=ta + s(i+nfos*icos7(n),k)
t0a=t0a + sum(s(i:i+nfos*6:nfos,k))
m=j+jstrt+nssy*n
if(m.ge.1.and.m.le.NHSYM) then
ta=ta + s(i+nfos*icos7(n),m)
t0a=t0a + sum(s(i:i+nfos*6:nfos,m))
endif
tb=tb + s(i+nfos*icos7(n),k+nssy*36)
t0b=t0b + sum(s(i:i+nfos*6:nfos,k+nssy*36))
if(k+nssy*72.le.NHSYM) then
tc=tc + s(i+nfos*icos7(n),k+nssy*72)
t0c=t0c + sum(s(i:i+nfos*6:nfos,k+nssy*72))
tb=tb + s(i+nfos*icos7(n),m+nssy*36)
t0b=t0b + sum(s(i:i+nfos*6:nfos,m+nssy*36))
if(m+nssy*72.le.NHSYM) then
tc=tc + s(i+nfos*icos7(n),m+nssy*72)
t0c=t0c + sum(s(i:i+nfos*6:nfos,m+nssy*72))
endif
enddo
t=ta+tb+tc
@ -80,34 +90,36 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
t0=(t0-t)/6.0
sync_bc=t/t0
sync2d(i,j)=max(sync_abc,sync_bc)
enddo
enddo
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)
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)
! write(52,3052) i*df,red(i),db(red(i))
!3052 format(3f12.3)
enddo
iz=ib-ia+1
call indexx(red(ia:ib),iz,indx)
ibase=indx(nint(0.40*iz)) - 1 + ia
base=red(ibase)
red=red/base
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
candidate0=0.
k=0
do i=1,200
n=ia + indx(iz+1-i) - 1
if(red(n).lt.syncmin) exit
if(k.lt.200) k=k+1
candidate0(1,k)=n*df
candidate0(2,k)=(jpeak(n)-1)*tstep
candidate0(3,k)=red(n)
enddo
do i=1,min(maxcand,iz)
n=ia + indx(iz+1-i) - 1
if(red(n).lt.syncmin.or.isnan(red(n)).or.k.eq.maxcand) exit
k=k+1
candidate0(1,k)=n*df
candidate0(2,k)=(jpeak(n)-1)*tstep
candidate0(3,k)=red(n)
candidate0(4,k)=isync
enddo
enddo ! isync loop
ncand=k
! Put nfqso at top of list, and save only the best of near-dupe freqs.
@ -121,9 +133,6 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
if(candidate0(3,i).lt.candidate0(3,j)) candidate0(3,i)=0.
endif
enddo
! write(*,3001) i,candidate0(1,i-1),candidate0(1,i),candidate0(3,i-1), &
! candidate0(3,i)
!3001 format(i2,4f8.1)
endif
enddo
@ -143,6 +152,7 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
candidate(1,k)=abs(candidate0(1,j))
candidate(2,k)=candidate0(2,j)
candidate(3,k)=candidate0(3,j)
candidate(4,k)=candidate0(4,j)
k=k+1
endif
enddo

View File

@ -1,18 +1,20 @@
subroutine sync8d(cd0,i0,ctwk,itwk,sync)
subroutine sync8d(cd0,i0,ctwk,itwk,itype,sync)
! Compute sync power for a complex, downsampled FT8 signal.
! itype specifies which Costas array to use
parameter(NP2=2812,NDOWN=60)
complex cd0(3125)
complex csync(0:6,32)
complex cd0(0:3199)
complex csync_1(0:6,32),csync_2(0:6,32)
complex csync2(32)
complex ctwk(32)
complex z1,z2,z3
logical first
integer icos7(0:6)
data icos7/2,5,6,0,4,1,3/
integer icos7_1(0:6),icos7_2(0:6)
data icos7_1/2,5,6,0,4,1,3/
data icos7_2/3,1,4,0,6,5,2/
data first/.true./
save first,twopi,fs2,dt2,taus,baud,csync
save first,twopi,fs2,dt2,taus,baud,csync_1,csync_2
p(z1)=real(z1)**2 + aimag(z1)**2 !Statement function for power
@ -24,11 +26,15 @@ subroutine sync8d(cd0,i0,ctwk,itwk,sync)
taus=32*dt2 !Symbol duration
baud=1.0/taus !Keying rate
do i=0,6
phi=0.0
dphi=twopi*icos7(i)*baud*dt2
phi1=0.0
phi2=0.0
dphi1=twopi*icos7_1(i)*baud*dt2
dphi2=twopi*icos7_2(i)*baud*dt2
do j=1,32
csync(i,j)=cmplx(cos(phi),sin(phi)) !Waveform for 7x7 Costas array
phi=mod(phi+dphi,twopi)
csync_1(i,j)=cmplx(cos(phi1),sin(phi1)) !Waveform for 7x7 Costas array
csync_2(i,j)=cmplx(cos(phi2),sin(phi2)) !Waveform for 7x7 Costas array
phi1=mod(phi1+dphi1,twopi)
phi2=mod(phi2+dphi2,twopi)
enddo
enddo
first=.false.
@ -39,14 +45,18 @@ subroutine sync8d(cd0,i0,ctwk,itwk,sync)
i1=i0+i*32 !three Costas arrays
i2=i1+36*32
i3=i1+72*32
csync2=csync(i,1:32)
if(itype.eq.1) then
csync2=csync_1(i,1:32)
else
csync2=csync_2(i,1:32)
endif
if(itwk.eq.1) csync2=ctwk*csync2 !Tweak the frequency
z1=0.
z2=0.
z3=0.
if(i1.ge.1 .and. i1+31.le.NP2) z1=sum(cd0(i1:i1+31)*conjg(csync2))
if(i2.ge.1 .and. i2+31.le.NP2) z2=sum(cd0(i2:i2+31)*conjg(csync2))
if(i3.ge.1 .and. i3+31.le.NP2) z3=sum(cd0(i3:i3+31)*conjg(csync2))
if(i1.ge.0 .and. i1+31.le.NP2-1) z1=sum(cd0(i1:i1+31)*conjg(csync2))
if(i2.ge.0 .and. i2+31.le.NP2-1) z2=sum(cd0(i2:i2+31)*conjg(csync2))
if(i3.ge.0 .and. i3+31.le.NP2-1) z3=sum(cd0(i3:i3+31)*conjg(csync2))
sync = sync + p(z1) + p(z2) + p(z3)
enddo

View File

@ -33,8 +33,8 @@ module ft8_decode
contains
subroutine decode(this,callback,iwave,nQSOProgress,nfqso,nftx,newdat, &
nutc,nfa,nfb,nexp_decode,ndepth,nagain,lft8apon,lapcqonly,napwid, &
mycall12,mygrid6,hiscall12,hisgrid6)
nutc,nfa,nfb,ndepth,ncontest,nagain,lft8apon,lapcqonly,ldecode77, &
napwid,mycall12,hiscall12,hisgrid6)
! use wavhdr
use timer_module, only: timer
include 'ft8/ft8_params.f90'
@ -42,30 +42,38 @@ contains
class(ft8_decoder), intent(inout) :: this
procedure(ft8_decode_callback) :: callback
parameter (MAXCAND=300)
real s(NH1,NHSYM)
real sbase(NH1)
real candidate(3,200)
real candidate(4,MAXCAND)
real dd(15*12000)
logical, intent(in) :: lft8apon,lapcqonly,nagain
logical newdat,lsubtract,ldupe,bcontest
character*12 mycall12, hiscall12
character*6 mygrid6,hisgrid6
logical, intent(in) :: lft8apon,lapcqonly,ldecode77,nagain
logical newdat,lsubtract,ldupe
character*12 mycall12,hiscall12,mycall12_0
character*6 hisgrid6
integer*2 iwave(15*12000)
integer apsym(KK)
character datetime*13,message*22,msg37*37
character*22 allmessages(100)
integer apsym1(KK),apsym2(77)
character datetime*13,msg37*37
! character message*22
character*37 allmessages(100)
integer allsnrs(100)
save s,dd
data mycall12_0/'dummy'/
save s,dd,mycall12_0
if(mycall12.ne.mycall12_0) then
call my_hash(mycall12)
mycall12_0=mycall12
endif
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)
call ft8apset(mycall12,hiscall12,apsym1)
call ft8apset_174_91(mycall12,hiscall12,hisgrid6,ncontest,apsym2)
dd=iwave
ndecodes=0
allmessages=' '
allmessages=' '
allsnrs=0
ifa=nfa
ifb=nfb
@ -94,46 +102,51 @@ contains
if((ndecodes-n2).eq.0) cycle
lsubtract=.false.
endif
call timer('sync8 ',0)
call sync8(dd,ifa,ifb,syncmin,nfqso,s,candidate,ncand,sbase)
maxc=MAXCAND
call sync8(dd,ifa,ifb,syncmin,nfqso,ldecode77,maxc,s,candidate,ncand,sbase)
call timer('sync8 ',1)
do icand=1,ncand
sync=candidate(3,icand)
f1=candidate(1,icand)
xdt=candidate(2,icand)
isync=candidate(4,icand)
xbase=10.0**(0.1*(sbase(nint(f1/3.125))-40.0))
nsnr0=min(99,nint(10.0*log10(sync) - 25.5)) !### empirical ###
call timer('ft8b ',0)
call ft8b(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) !###
if(isync.eq.1) then
call ft8b_1(dd,newdat,nQSOProgress,nfqso,nftx,ndepth,lft8apon, &
lapcqonly,napwid,lsubtract,nagain,iaptype,mycall12, &
hiscall12,sync,f1,xdt,xbase,apsym1,nharderrors,dmin, &
nbadcrc,iappass,iera,msg37,xsnr)
else
call ft8b_2(dd,newdat,nQSOProgress,nfqso,nftx,ndepth,lft8apon, &
lapcqonly,napwid,lsubtract,nagain,iaptype,mycall12, &
hiscall12,sync,f1,xdt,xbase,apsym2,nharderrors,dmin, &
nbadcrc,iappass,iera,msg37,xsnr)
endif
! message=msg37(1:22) !###
nsnr=nint(xsnr)
xdt=xdt-0.5
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
! This probably needs to be re-visited for the new message type
! 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.
if(msg37.eq.allmessages(id).and.nsnr.le.allsnrs(id)) ldupe=.true.
enddo
if(.not.ldupe) then
ndecodes=ndecodes+1
allmessages(ndecodes)=message
allmessages(ndecodes)=msg37
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)
! xdt,nint(f1),msg37,isync
!1004 format(i6.6,2i4,3i2,i3,3f6.1,i4,f6.2,i5,2x,a37,i4)
! flush(81)
if(.not.ldupe .and. associated(this%callback)) then
qual=1.0-(nharderrors+dmin)/60.0 ! scale qual to [0.0,1.0]

Some files were not shown because too many files have changed in this diff Show More