mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-07-04 19:05:15 -04:00
Compare commits
291 Commits
wsjtx-2.7.
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
2b9d65408d | ||
|
c5a266b5e0 | ||
|
de9dc8e3fb | ||
|
5e410a982b | ||
|
2a9d0b6998 | ||
|
75f6b9b423 | ||
|
c7a93fca4a | ||
|
08785eff56 | ||
|
40fbc208fd | ||
|
1ac2fc23c3 | ||
|
d4a5ea60e6 | ||
|
86fd50304f | ||
|
75b4e0e798 | ||
|
ee68285583 | ||
|
ae50058498 | ||
|
587a16cd21 | ||
|
45151bda3b | ||
|
34b97b53f8 | ||
|
4c0d34477d | ||
|
72651037bd | ||
|
b83c41c8de | ||
|
ae61764af3 | ||
|
ae17011aa4 | ||
|
c228b6fe18 | ||
|
ffe1d11e99 | ||
|
3882953f51 | ||
|
3611f07ad6 | ||
|
98e48e00d3 | ||
|
20c41cf45b | ||
|
200168fd37 | ||
|
b7efe4d26d | ||
|
d67a406bf0 | ||
|
41407dad9f | ||
|
f59b5a48f7 | ||
|
c251764252 | ||
|
2655e41dd6 | ||
|
d4e2c21053 | ||
|
226b17d0ea | ||
|
495170e7a1 | ||
|
90b7ff7da9 | ||
|
aac9de3e4c | ||
|
e205bf0ca6 | ||
|
b84742b1fc | ||
|
7be1c34ea0 | ||
|
0705bd329e | ||
|
6474f7e1cf | ||
|
adc0345ef3 | ||
|
69a19946df | ||
|
4ec84087c7 | ||
|
05c3389307 | ||
|
9223ae3393 | ||
|
e178df928e | ||
|
8a2051e439 | ||
|
47c64f3675 | ||
|
d155abe274 | ||
|
9babd4616b | ||
|
e81cafa2c2 | ||
|
55286b05a9 | ||
|
b3d8750949 | ||
|
3a5da4b2ac | ||
|
ae64b71498 | ||
|
74f07211c3 | ||
|
db3c7c4668 | ||
|
14b60aa146 | ||
|
153c2e4212 | ||
|
9044718e36 | ||
|
cc9c1c62c9 | ||
|
8a899d000e | ||
|
6e6caa0d82 | ||
|
447127a49f | ||
|
24bfc9f30d | ||
|
9c45e510ff | ||
|
059096534b | ||
|
2f46104140 | ||
|
4af9c58bb0 | ||
|
ae1cf334e2 | ||
|
ff39abab58 | ||
|
f7e16671ab | ||
|
8be743e0b8 | ||
|
ae14fa13e9 | ||
|
9c3cc3d685 | ||
|
13a8efd533 | ||
|
80ed717aab | ||
|
8d17c7095c | ||
|
7a0a1736a7 | ||
|
f93d846c22 | ||
|
42f322e461 | ||
|
f98009daab | ||
|
c7e13191f1 | ||
|
2584b5ef3b | ||
|
6dc971d304 | ||
|
fbfc157e79 | ||
|
12042f6ae8 | ||
|
764fcaadcb | ||
|
53db514d42 | ||
|
e6fb080071 | ||
|
32c3cb7c4a | ||
|
faae78e0e6 | ||
|
bd4edcce49 | ||
|
07e82b0c40 | ||
|
d594d14a1e | ||
|
bb4564f734 | ||
|
9e0425ef40 | ||
|
c733c0c123 | ||
|
69f98d5c5c | ||
|
7f7a5322ed | ||
|
606506f578 | ||
|
4a4225bb9c | ||
|
b5bbf4a860 | ||
|
986eaf5d40 | ||
|
232c680a41 | ||
|
69f3186b13 | ||
|
05ed9c050d | ||
|
a4e7b915de | ||
|
a7b6798c99 | ||
|
a7cef9fc89 | ||
|
0d46c8a66e | ||
|
2a4ab7e92f | ||
|
f3be4b47fa | ||
|
fd0336f234 | ||
|
7276e86e60 | ||
|
5cc82189e6 | ||
|
ac0055b303 | ||
|
0f417374c3 | ||
|
ce2a4d2fe7 | ||
|
40cba29e5f | ||
|
f3308b7ee4 | ||
|
2c2deab91a | ||
|
6cab8c3da9 | ||
|
76007c8031 | ||
|
673f74e67b | ||
|
1d21dff93f | ||
|
3ebf72076c | ||
|
5bac396d60 | ||
|
efe8f090c2 | ||
|
1f0ddb92c5 | ||
|
887bc433ec | ||
|
3546fd4ba2 | ||
|
0eaf3360d8 | ||
|
115f850cd1 | ||
|
a4395c5d08 | ||
|
e0078bf01e | ||
|
e92d5ca1f5 | ||
|
fcee51cea8 | ||
|
f086aeb95a | ||
|
c1253954f6 | ||
|
c8cbb481a0 | ||
|
826fa8ae03 | ||
|
d3e9f3fc5a | ||
|
5bacc2d763 | ||
|
6b5db9fd0c | ||
|
08d9ebaf1a | ||
|
6ec9466dc1 | ||
|
cdb7b02835 | ||
|
031f7fc1e6 | ||
|
95daa2d791 | ||
|
b13c7d8dca | ||
|
171662ba50 | ||
|
4e935e01f3 | ||
|
9545c8eaa2 | ||
|
8f8f135e02 | ||
|
50bd14937f | ||
|
e42e995c59 | ||
|
2fb711401f | ||
|
889531fda6 | ||
|
e211bae779 | ||
|
517ca61f5c | ||
|
8be6d702d2 | ||
|
6f8c326717 | ||
|
35a1d37012 | ||
|
97fac57830 | ||
|
44bd5f9ac8 | ||
|
363e301e31 | ||
|
84ec6bb457 | ||
|
50519bc282 | ||
|
1f78fe5f2c | ||
|
20c090e2bc | ||
|
2e715fa47d | ||
|
d5a8ce97e3 | ||
|
bb5e8efd52 | ||
|
6afced7335 | ||
|
90f3c59ea0 | ||
|
f42a1bb357 | ||
|
9d5f3858d4 | ||
|
1aeaec7a6d | ||
|
186abfe99e | ||
|
c45420b194 | ||
|
1b3f4315b1 | ||
|
5e8deecdb4 | ||
|
7255a7c86a | ||
|
1542b7f857 | ||
|
9c7c837dc8 | ||
|
e040c926b9 | ||
|
11f8efd2a9 | ||
|
e2ef2c7dbb | ||
|
c413ea2f14 | ||
|
b0ea3a2eb5 | ||
|
717fd42ac1 | ||
|
d9cab59537 | ||
|
61fc069443 | ||
|
2f1082e973 | ||
|
adc457214f | ||
|
5d94775c7d | ||
|
91c0e43ef6 | ||
|
0cf01f1248 | ||
|
f525f08365 | ||
|
6019101018 | ||
|
115c4c4e30 | ||
|
ac1b5d03b2 | ||
|
6e9dc42881 | ||
|
e6fad89904 | ||
|
fe19a7263d | ||
|
57aca5c222 | ||
|
0d74918634 | ||
|
43019d0cb4 | ||
|
7622915147 | ||
|
62eb8fa3e9 | ||
|
8ae939b573 | ||
|
0455cf23e6 | ||
|
7f660d62fa | ||
|
bf861d9979 | ||
|
d62cdbaf2b | ||
|
ff2f2b00b9 | ||
|
cb7395b504 | ||
|
93dba5e623 | ||
|
05931313b3 | ||
|
7348bc323e | ||
|
76e28298a3 | ||
|
c6fb86067e | ||
|
711ea392ef | ||
|
456c5de125 | ||
|
c02b977c94 | ||
|
d8570e6817 | ||
|
74c6d9eb64 | ||
|
0456b3af8c | ||
|
bfd44f178a | ||
|
4a9c4dac6f | ||
|
f6989c3e6c | ||
|
5e9b9ff2d4 | ||
|
b986c7c81c | ||
|
330db0feb4 | ||
|
933aa29451 | ||
|
f394d77be7 | ||
|
5d3e927648 | ||
|
6546846f2c | ||
|
05ae0ee9af | ||
|
6156cf0d7d | ||
|
48ae40d781 | ||
|
60bcd6291d | ||
|
18b9dbf41b | ||
|
ce7a1c26fc | ||
|
3fcb8d3deb | ||
|
84069fe9e9 | ||
|
d4d47f8323 | ||
|
dece2e9fc5 | ||
|
c5969b0434 | ||
|
d76790adc3 | ||
|
b073fa0550 | ||
|
e8162970de | ||
|
97ed4022a2 | ||
|
893565f40d | ||
|
9913111464 | ||
|
ba453131eb | ||
|
2e3c37d7b2 | ||
|
bf70fae0bf | ||
|
64f53f30ff | ||
|
f75969ffb6 | ||
|
8ecdebaeba | ||
|
a3a02a8996 | ||
|
06d1469c10 | ||
|
ea8737e9f1 | ||
|
c65ebb16d5 | ||
|
b2a1c2d977 | ||
|
2ba2a580ff | ||
|
9a863d6590 | ||
|
b04e1517a9 | ||
|
3b03c9c824 | ||
|
2d9bebddbe | ||
|
fea274ed57 | ||
|
e4dca8e241 | ||
|
cbcf0c0ecd | ||
|
28d014e634 | ||
|
4f874b6507 | ||
|
630f0c34c3 | ||
|
c2883532ed | ||
|
ce2e94de26 | ||
|
88852bebe6 | ||
|
ec9682b57b | ||
|
68aae12588 | ||
|
99876a1916 | ||
|
54e46d90f2 |
@ -71,7 +71,7 @@ message (STATUS "******************************************************")
|
||||
|
||||
include (set_build_type)
|
||||
# RC 0 or omitted is a development build, GA is a General Availability release build
|
||||
set_build_type (RC 2)
|
||||
set_build_type (RC 4)
|
||||
set (wsjtx_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
|
||||
|
||||
#
|
||||
@ -161,7 +161,6 @@ endif ()
|
||||
set (WSJT_PLUGIN_DESTINATION ${PLUGIN_DESTINATION} CACHE PATH "Path for plugins")
|
||||
set (WSJT_QT_CONF_DESTINATION ${QT_CONF_DESTINATION} CACHE PATH "Path for the qt.conf file")
|
||||
|
||||
|
||||
#
|
||||
# Project sources
|
||||
#
|
||||
@ -363,6 +362,7 @@ set (wsjt_FSRCS
|
||||
lib/bpdecode128_90.f90
|
||||
lib/ft8/bpdecode174_91.f90
|
||||
lib/baddata.f90
|
||||
lib/cablog.f90
|
||||
lib/calibrate.f90
|
||||
lib/ccf2.f90
|
||||
lib/ccf65.f90
|
||||
@ -492,6 +492,7 @@ set (wsjt_FSRCS
|
||||
lib/msk144sim.f90
|
||||
lib/mskrtd.f90
|
||||
lib/nuttal_window.f90
|
||||
lib/decode_msk144.f90
|
||||
lib/ft4/ft4sim.f90
|
||||
lib/ft4/ft4sim_mult.f90
|
||||
lib/ft4/ft4_downsample.f90
|
||||
@ -1143,6 +1144,9 @@ target_link_libraries (jt65sim wsjt_fort wsjt_cxx)
|
||||
add_executable (sumsim lib/sumsim.f90)
|
||||
target_link_libraries (sumsim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (cablog lib/cablog.f90)
|
||||
target_link_libraries (cablog)
|
||||
|
||||
add_executable (test_snr lib/test_snr.f90)
|
||||
target_link_libraries (test_snr wsjt_fort)
|
||||
|
||||
@ -1599,7 +1603,7 @@ install (TARGETS jt9 wsprd fmtave fcal fmeasure
|
||||
|
||||
if(WSJT_BUILD_UTILS)
|
||||
install (TARGETS ft8code jt65code jt9code jt4code msk144code
|
||||
q65code fst4sim q65sim echosim hash22calc
|
||||
q65code fst4sim q65sim echosim hash22calc cablog
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
)
|
||||
|
@ -173,7 +173,6 @@
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "qt_helpers.hpp"
|
||||
@ -245,6 +244,9 @@ namespace
|
||||
|X85|X86|X87|X88|X89|X90|X91
|
||||
|X92|X93|X94|X95|X96|X97|X98
|
||||
|X99
|
||||
|[0][0][0][1-9] # 4-digit numbers
|
||||
|[0][0-9][1-9][0-9] # between 0001
|
||||
|[1-7][0-9][0-9][0-9] # and 7999
|
||||
)
|
||||
)", QRegularExpression::CaseInsensitiveOption | QRegularExpression::ExtendedPatternSyntaxOption};
|
||||
|
||||
@ -277,7 +279,6 @@ namespace
|
||||
constexpr quint32 qrg_version_100 {100};
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Dialog to get a new Frequency item
|
||||
//
|
||||
@ -330,9 +331,9 @@ public:
|
||||
|
||||
connect (button_box, &QDialogButtonBox::accepted, this, &FrequencyDialog::accept);
|
||||
connect (button_box, &QDialogButtonBox::rejected, this, &FrequencyDialog::reject);
|
||||
connect(start_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates);
|
||||
connect(end_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates);
|
||||
connect(enable_dates_checkbox_, &QCheckBox::stateChanged, this, &FrequencyDialog::toggleValidity);
|
||||
connect (start_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates);
|
||||
connect (end_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates);
|
||||
connect (enable_dates_checkbox_, &QCheckBox::stateChanged, this, &FrequencyDialog::toggleValidity);
|
||||
toggleValidity();
|
||||
}
|
||||
|
||||
@ -385,7 +386,6 @@ private:
|
||||
QDateTimeEdit *start_date_time_edit_;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Dialog to get a new Station item
|
||||
//
|
||||
@ -458,9 +458,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// Internal implementation of the Configuration class.
|
||||
class Configuration::impl final
|
||||
: public QDialog
|
||||
@ -580,6 +577,11 @@ private:
|
||||
Q_SLOT void on_rescan_log_push_button_clicked (bool);
|
||||
Q_SLOT void on_CTY_download_button_clicked (bool);
|
||||
Q_SLOT void on_LotW_CSV_fetch_push_button_clicked (bool);
|
||||
Q_SLOT void on_hamlib_download_button_clicked (bool);
|
||||
Q_SLOT void on_revert_update_button_clicked (bool);
|
||||
void error_during_hamlib_download (QString const& reason);
|
||||
void after_hamlib_downloaded();
|
||||
void display_file_information();
|
||||
|
||||
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
|
||||
Q_SLOT void on_cbx4ToneSpacing_clicked(bool);
|
||||
@ -684,6 +686,7 @@ private:
|
||||
QString FD_exchange_;
|
||||
QString RTTY_exchange_;
|
||||
QString Contest_Name_;
|
||||
QString hamlib_backed_up_;
|
||||
|
||||
qint32 id_interval_;
|
||||
qint32 ntrials_;
|
||||
@ -758,7 +761,6 @@ private:
|
||||
|
||||
#include "Configuration.moc"
|
||||
|
||||
|
||||
// delegate to implementation class
|
||||
Configuration::Configuration (QNetworkAccessManager * network_manager, QDir const& temp_directory,
|
||||
QSettings * settings, LogBook * logbook, QWidget * parent)
|
||||
@ -1570,6 +1572,7 @@ void Configuration::impl::read_settings ()
|
||||
ui_->Field_Day_Exchange->setText(FD_exchange_);
|
||||
ui_->RTTY_Exchange->setText(RTTY_exchange_);
|
||||
ui_->Contest_Name->setText(Contest_Name_);
|
||||
hamlib_backed_up_ = settings_->value ("HamlibBackedUp",QString {}).toString ();
|
||||
|
||||
if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
|
||||
&& next_font_ != font_)
|
||||
@ -1746,6 +1749,18 @@ void Configuration::impl::read_settings ()
|
||||
pwrBandTuneMemory_ = settings_->value("pwrBandTuneMemory",false).toBool ();
|
||||
highlight_DXcall_ = settings_->value("highlight_DXcall",false).toBool ();
|
||||
highlight_DXgrid_ = settings_->value("highlight_DXgrid",false).toBool ();
|
||||
#ifdef WIN32
|
||||
QTimer::singleShot (2500, [=] {display_file_information ();});
|
||||
#else
|
||||
ui_->hamlib_groupBox->setTitle("Hamlib Version");
|
||||
ui_->rbHamlib64->setVisible(false);
|
||||
ui_->rbHamlib32->setVisible(false);
|
||||
ui_->hamlib_download_button->setVisible(false);
|
||||
ui_->revert_update_button->setVisible(false);
|
||||
ui_->backed_up_text->setVisible(false);
|
||||
ui_->backed_up->setVisible(false);
|
||||
QTimer::singleShot (2500, [=] {display_file_information ();});
|
||||
#endif
|
||||
}
|
||||
|
||||
void Configuration::impl::find_audio_devices ()
|
||||
@ -2484,6 +2499,113 @@ void Configuration::impl::on_decoded_text_font_push_button_clicked ()
|
||||
);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_hamlib_download_button_clicked (bool /*clicked*/)
|
||||
{
|
||||
#ifdef WIN32
|
||||
extern char* hamlib_version2;
|
||||
QString hamlib = QString(QLatin1String(hamlib_version2));
|
||||
SettingsGroup g {settings_, "Configuration"};
|
||||
settings_->setValue ("HamlibBackedUp", hamlib);
|
||||
settings_->sync ();
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
QFile f1 {dataPath.absolutePath() + "/" + "libhamlib-4_old.dll"};
|
||||
QFile f2 {dataPath.absolutePath() + "/" + "libhamlib-4_new.dll"};
|
||||
if (f1.exists()) f1.remove();
|
||||
if (f2.exists()) f2.remove();
|
||||
ui_->hamlib_download_button->setEnabled (false);
|
||||
ui_->revert_update_button->setEnabled (false);
|
||||
if (ui_->rbHamlib32->isChecked()) {
|
||||
cty_download.configure(network_manager_,
|
||||
"https://n0nb.users.sourceforge.net/dll32/libhamlib-4.dll",
|
||||
dataPath.absoluteFilePath("libhamlib-4_new.dll"),
|
||||
"Downloading latest libhamlib-4.dll");
|
||||
} else {
|
||||
cty_download.configure(network_manager_,
|
||||
"https://n0nb.users.sourceforge.net/dll64/libhamlib-4.dll",
|
||||
dataPath.absoluteFilePath("libhamlib-4_new.dll"),
|
||||
"Downloading latest libhamlib-4.dll");
|
||||
}
|
||||
connect (&cty_download, &FileDownload::complete, this, &Configuration::impl::after_hamlib_downloaded, Qt::UniqueConnection);
|
||||
connect (&cty_download, &FileDownload::error, this, &Configuration::impl::error_during_hamlib_download, Qt::UniqueConnection);
|
||||
cty_download.start_download();
|
||||
#else
|
||||
MessageBox::warning_message (this, tr ("Hamlib update only available on Windows."));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Configuration::impl::error_during_hamlib_download (QString const& reason)
|
||||
{
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
MessageBox::warning_message (this, tr ("Error Loading libhamlib-4.dll"), reason);
|
||||
ui_->hamlib_download_button->setEnabled (true);
|
||||
ui_->revert_update_button->setEnabled (true);
|
||||
}
|
||||
|
||||
void Configuration::impl::after_hamlib_downloaded ()
|
||||
{
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
QFile::rename(dataPath.absolutePath() + "/" + "libhamlib-4.dll", dataPath.absolutePath() + "/" + "libhamlib-4_old.dll");
|
||||
QTimer::singleShot (1000, [=] {
|
||||
QFile::rename(dataPath.absolutePath() + "/" + "libhamlib-4_new.dll", dataPath.absolutePath() + "/" + "libhamlib-4.dll");
|
||||
});
|
||||
QTimer::singleShot (2000, [=] {
|
||||
MessageBox::information_message (this, tr ("Hamlib Update successful \n\nNew Hamlib will be used after restart"));
|
||||
ui_->revert_update_button->setEnabled (true);
|
||||
ui_->hamlib_download_button->setEnabled (true);
|
||||
});
|
||||
}
|
||||
|
||||
void Configuration::impl::on_revert_update_button_clicked (bool /*clicked*/)
|
||||
{
|
||||
#ifdef WIN32
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
QFile f {dataPath.absolutePath() + "/" + "libhamlib-4_old.dll"};
|
||||
if (f.exists()) {
|
||||
ui_->revert_update_button->setEnabled (false);
|
||||
ui_->hamlib_download_button->setEnabled (false);
|
||||
QFile::rename(dataPath.absolutePath() + "/" + "libhamlib-4.dll", dataPath.absolutePath() + "/" + "libhamlib-4_new.dll");
|
||||
QTimer::singleShot (1000, [=] {
|
||||
QFile::copy(dataPath.absolutePath() + "/" + "libhamlib-4_old.dll", dataPath.absolutePath() + "/" + "libhamlib-4.dll");
|
||||
});
|
||||
QTimer::singleShot (2000, [=] {
|
||||
MessageBox::information_message (this, tr ("Hamlib successfully reverted \n\nReverted Hamlib will be used after restart"));
|
||||
ui_->revert_update_button->setEnabled (true);
|
||||
ui_->hamlib_download_button->setEnabled (true);
|
||||
});
|
||||
} else {
|
||||
MessageBox::warning_message (this, tr ("No Hamlib update found that could be reverted"));
|
||||
}
|
||||
#else
|
||||
MessageBox::warning_message (this, tr ("Hamlib update only available on Windows."));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Configuration::impl::display_file_information ()
|
||||
{
|
||||
#ifdef WIN32
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
extern char* hamlib_version2;
|
||||
QString hamlib = QString(QLatin1String(hamlib_version2));
|
||||
ui_->in_use->setText(hamlib);
|
||||
QFileInfo fi2(dataPath.absolutePath() + "/" + "libhamlib-4_old.dll");
|
||||
QString birthTime2 = fi2.birthTime().toString("yyyy-MM-dd hh:mm");
|
||||
QFile f {dataPath.absolutePath() + "/" + "libhamlib-4_old.dll"};
|
||||
if (f.exists()) {
|
||||
if (hamlib_backed_up_=="") {
|
||||
ui_->backed_up->setText(QString{"no hamlib data available, file saved %1"}.arg(birthTime2));
|
||||
} else {
|
||||
ui_->backed_up->setText(hamlib_backed_up_);
|
||||
}
|
||||
} else {
|
||||
ui_->backed_up->setText("");
|
||||
}
|
||||
#else
|
||||
extern char* hamlib_version2;
|
||||
QString hamlib = QString(QLatin1String(hamlib_version2));
|
||||
ui_->in_use->setText(hamlib);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Configuration::impl::on_PTT_port_combo_box_activated (int /* index */)
|
||||
{
|
||||
set_rig_invariants ();
|
||||
|
@ -225,8 +225,7 @@ public:
|
||||
// This method queries if a CAT and PTT connection is operational.
|
||||
bool is_transceiver_online () const;
|
||||
|
||||
// Start the rig connection, safe and normal to call when rig is
|
||||
// already open.
|
||||
// Start the rig connection, safe and normal to call when rig is already open.
|
||||
bool transceiver_online ();
|
||||
|
||||
// check if a real rig is configured
|
||||
|
770
Configuration.ui
770
Configuration.ui
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>684</width>
|
||||
<height>662</height>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -529,6 +529,280 @@ quiet period when decoding is done.</string>
|
||||
<string>Radio interface configuration settings.</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="5" column="2">
|
||||
<widget class="QGroupBox" name="mode_group_box">
|
||||
<property name="toolTip">
|
||||
<string>Modulation mode selected on radio.</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="mode_USB_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>USB is usually the correct modulation mode,</p><p>unless the radio has a special data or packet mode setting</p><p>for AFSK operation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>US&B</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="mode_none_radio_button">
|
||||
<property name="toolTip">
|
||||
<string>Don't allow the program to set the radio mode
|
||||
(not recommended but use if the wrong mode
|
||||
or bandwidth is selected).</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QRadioButton" name="mode_data_radio_button">
|
||||
<property name="toolTip">
|
||||
<string>If this is available then it is usually the correct mode for this program.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Data/P&kt</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QGroupBox" name="TX_audio_source_group_box">
|
||||
<property name="toolTip">
|
||||
<string>Some radios can select the audio input using a CAT command,
|
||||
this setting allows you to select which audio input will be used
|
||||
(if it is available then generally the Rear/Data option is best).</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Transmit Audio Source</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="TX_source_data_radio_button">
|
||||
<property name="text">
|
||||
<string>Rear&/Data</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_audio_source_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="TX_source_mic_radio_button">
|
||||
<property name="text">
|
||||
<string>&Front/Mic</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_audio_source_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QGroupBox" name="PTT_method_group_box">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>How this program activates the PTT on your radio?</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>PTT Method</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="PTT_VOX_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>No PTT activation, instead the radio's automatic VOX is used to key the transmitter.</p><p>Use this if you have no radio interface hardware.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>VO&X</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">PTT_method_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="PTT_DTR_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Use the RS-232 DTR control line to toggle your radio's PTT, requires hardware to interface the line.</p><p>Some commercial interface units also use this method.</p><p>The DTR control line of the CAT serial port may be used for this or a DTR control line on a different serial port may be used.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&DTR</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">PTT_method_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="PTT_CAT_radio_button">
|
||||
<property name="toolTip">
|
||||
<string>Some radios support PTT via CAT commands,
|
||||
use this option if your radio supports it and you have no
|
||||
other hardware interface for PTT.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>C&AT</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">PTT_method_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QRadioButton" name="PTT_RTS_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Use the RS-232 RTS control line to toggle your radio's PTT, requires hardware to interface the line.</p><p>Some commercial interface units also use this method.</p><p>The RTS control line of the CAT serial port may be used for this or a RTS control line on a different serial port may be used. Note that this option is not available on the CAT serial port when hardware flow control is used.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>R&TS</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">PTT_method_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" rowspan="2" colspan="2">
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="PTT_port_label">
|
||||
<property name="text">
|
||||
<string>Port:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>PTT_port_combo_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="PTT_port_combo_box">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select the RS-232 serial port utilised for PTT control, this option is available when DTR or RTS is selected above as a transmit method.</p><p>This port can be the same one as the one used for CAT control.</p><p>For some interface types the special value CAT may be chosen, this is used for non-serial CAT interfaces that can control serial port control lines remotely (OmniRig for example).</p></body></html></string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="currentText">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::NoInsert</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QGroupBox" name="split_operation_group_box">
|
||||
<property name="title">
|
||||
<string>Split Operation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="0" column="2">
|
||||
<widget class="QRadioButton" name="split_emulate_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Use only VFO A for split operation (the program temporarily changes the QRG of your rig during transmission).</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fake It</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">split_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="split_rig_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Use VFO A+B for split operation (works with many rigs, but requires the use of both VFOs).</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rig</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">split_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="split_none_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Don't use split (not recommended).</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">split_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<spacer name="verticalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" rowspan="11">
|
||||
<widget class="QGroupBox" name="CAT_control_group_box">
|
||||
<property name="sizePolicy">
|
||||
@ -935,6 +1209,13 @@ a few, particularly some Kenwood rigs, require it).</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="Line" name="line_6">
|
||||
<property name="orientation">
|
||||
@ -942,236 +1223,6 @@ a few, particularly some Kenwood rigs, require it).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="12">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QGroupBox" name="PTT_method_group_box">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>How this program activates the PTT on your radio?</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>PTT Method</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="PTT_VOX_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>No PTT activation, instead the radio's automatic VOX is used to key the transmitter.</p><p>Use this if you have no radio interface hardware.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>VO&X</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">PTT_method_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="PTT_DTR_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Use the RS-232 DTR control line to toggle your radio's PTT, requires hardware to interface the line.</p><p>Some commercial interface units also use this method.</p><p>The DTR control line of the CAT serial port may be used for this or a DTR control line on a different serial port may be used.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&DTR</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">PTT_method_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="PTT_CAT_radio_button">
|
||||
<property name="toolTip">
|
||||
<string>Some radios support PTT via CAT commands,
|
||||
use this option if your radio supports it and you have no
|
||||
other hardware interface for PTT.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>C&AT</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">PTT_method_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QRadioButton" name="PTT_RTS_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Use the RS-232 RTS control line to toggle your radio's PTT, requires hardware to interface the line.</p><p>Some commercial interface units also use this method.</p><p>The RTS control line of the CAT serial port may be used for this or a RTS control line on a different serial port may be used. Note that this option is not available on the CAT serial port when hardware flow control is used.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>R&TS</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">PTT_method_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" rowspan="2" colspan="2">
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="PTT_port_label">
|
||||
<property name="text">
|
||||
<string>Port:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>PTT_port_combo_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="PTT_port_combo_box">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select the RS-232 serial port utilised for PTT control, this option is available when DTR or RTS is selected above as a transmit method.</p><p>This port can be the same one as the one used for CAT control.</p><p>For some interface types the special value CAT may be chosen, this is used for non-serial CAT interfaces that can control serial port control lines remotely (OmniRig for example).</p></body></html></string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="currentText">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::NoInsert</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QGroupBox" name="mode_group_box">
|
||||
<property name="toolTip">
|
||||
<string>Modulation mode selected on radio.</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="mode_USB_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>USB is usually the correct modulation mode,</p><p>unless the radio has a special data or packet mode setting</p><p>for AFSK operation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>US&B</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="mode_none_radio_button">
|
||||
<property name="toolTip">
|
||||
<string>Don't allow the program to set the radio mode
|
||||
(not recommended but use if the wrong mode
|
||||
or bandwidth is selected).</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QRadioButton" name="mode_data_radio_button">
|
||||
<property name="toolTip">
|
||||
<string>If this is available then it is usually the correct mode for this program.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Data/P&kt</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QGroupBox" name="TX_audio_source_group_box">
|
||||
<property name="toolTip">
|
||||
<string>Some radios can select the audio input using a CAT command,
|
||||
this setting allows you to select which audio input will be used
|
||||
(if it is available then generally the Rear/Data option is best).</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Transmit Audio Source</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="TX_source_data_radio_button">
|
||||
<property name="text">
|
||||
<string>Rear&/Data</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_audio_source_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="TX_source_mic_radio_button">
|
||||
<property name="text">
|
||||
<string>&Front/Mic</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">TX_audio_source_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
@ -1179,8 +1230,15 @@ this setting allows you to select which audio input will be used
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<spacer name="verticalSpacer_7">
|
||||
<item row="1" column="1" rowspan="13">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@ -1192,62 +1250,8 @@ this setting allows you to select which audio input will be used
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="rig_label">
|
||||
<property name="text">
|
||||
<string>Rig:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>rig_combo_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="rig_combo_box">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="CAT_poll_interval_label">
|
||||
<property name="text">
|
||||
<string>Poll Interval:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>CAT_poll_interval_spin_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="CAT_poll_interval_spin_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Interval to poll rig for status. Longer intervals will mean that changes to the rig will take longer to be detected.</p></body></html></string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> s</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<layout class="QHBoxLayout" name="testCATPTT_Layout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="test_CAT_push_button">
|
||||
<property name="toolTip">
|
||||
@ -1304,59 +1308,55 @@ radio interface behave as expected.</string>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QGroupBox" name="split_operation_group_box">
|
||||
<property name="title">
|
||||
<string>Split Operation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="0" column="2">
|
||||
<widget class="QRadioButton" name="split_emulate_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Use only VFO A for split operation (the program temporarily changes the QRG of your rig during transmission).</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fake It</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">split_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="split_rig_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Use VFO A+B for split operation (works with many rigs, but requires the use of both VFOs).</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rig</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">split_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="split_none_radio_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Don't use split (not recommended).</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">split_mode_button_group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="rig_label">
|
||||
<property name="text">
|
||||
<string>Rig:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>rig_combo_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="rig_combo_box">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="CAT_poll_interval_label">
|
||||
<property name="text">
|
||||
<string>Poll Interval:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>CAT_poll_interval_spin_box</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="CAT_poll_interval_spin_box">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Interval to poll rig for status. Longer intervals will mean that changes to the rig will take longer to be detected.</p></body></html></string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> s</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<spacer name="verticalSpacer_5">
|
||||
<item row="9" column="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@ -1368,6 +1368,84 @@ radio interface behave as expected.</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QGroupBox" name="hamlib_groupBox">
|
||||
<property name="title">
|
||||
<string>Update Hamlib</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_18">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="rbHamlib64">
|
||||
<property name="text">
|
||||
<string>64-bit</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="rbHamlib32">
|
||||
<property name="text">
|
||||
<string>32-bit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="revert_update_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Revert the last Hamlib update. </p><p>Note: This function is only available on Windows.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Revert Update</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="hamlib_download_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Download the latest libhamlib-4.dll file from https://n0nb.users.sourceforge.net/. </p><p>Note: This function is only available on Windows.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Update Hamlib</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<layout class="QGridLayout" name="hamlib_version_gridLayout" columnstretch="0,1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="in_use_text">
|
||||
<property name="text">
|
||||
<string>In use:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="backed_up_text">
|
||||
<property name="text">
|
||||
<string>Backed up:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="in_use">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="backed_up">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="audio_tab">
|
||||
@ -2435,7 +2513,7 @@ Right click for insert and delete options.</string>
|
||||
<string>URL</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>https://lotw.arrl.org/lotw-user-activity.csv</string>
|
||||
<string>http://lotw.arrl.org/lotw-user-activity.csv</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -3420,13 +3498,13 @@ Right click for insert and delete options.</string>
|
||||
</connection>
|
||||
</connections>
|
||||
<buttongroups>
|
||||
<buttongroup name="split_mode_button_group"/>
|
||||
<buttongroup name="CAT_data_bits_button_group"/>
|
||||
<buttongroup name="PTT_method_button_group"/>
|
||||
<buttongroup name="CAT_handshake_button_group"/>
|
||||
<buttongroup name="split_mode_button_group"/>
|
||||
<buttongroup name="TX_audio_source_button_group"/>
|
||||
<buttongroup name="special_op_activity_button_group"/>
|
||||
<buttongroup name="TX_mode_button_group"/>
|
||||
<buttongroup name="special_op_activity_button_group"/>
|
||||
<buttongroup name="CAT_data_bits_button_group"/>
|
||||
<buttongroup name="CAT_stop_bits_button_group"/>
|
||||
<buttongroup name="PTT_method_button_group"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
33
INSTALL
33
INSTALL
@ -27,7 +27,7 @@ the Boost C++ libraries. For MS Windows see the section "Building
|
||||
from Source on MS Windows" below. For Apple Mac see the section
|
||||
"Building from Source on Apple Mac".
|
||||
|
||||
Qt v5, preferably v5.9 or later is required to build WSJT-X.
|
||||
Qt v5, preferably v5.12 or later is required to build WSJT-X.
|
||||
|
||||
Qt v5 multimedia support, serial port, and Linguist is necessary as
|
||||
well as the core Qt v5 components, normally installing the Qt
|
||||
@ -50,15 +50,13 @@ normally you can choose not to install libusb-1.0-dev but if you have
|
||||
a SoftRock USB or similar SDR that uses a custom USB interface then it
|
||||
is required.
|
||||
|
||||
The Hamlib library is required. Currently WSJT-X needs to be built
|
||||
using a forked version of the Hamlib git master. This fork contains
|
||||
patches not yet accepted by the Hamlib development team which are
|
||||
essential for correct operation of WSJT-X. To build the Hamlib fork
|
||||
from sources something like the following recipe should suffice:
|
||||
The Hamlib library is required. WSJT-X can be built with any version
|
||||
of the Hamlib git master. To build Hamlib from sources something
|
||||
like the following recipe should suffice:
|
||||
|
||||
$ mkdir ~/hamlib-prefix
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ git clone https://github.com/Hamlib/Hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
@ -113,13 +111,13 @@ Building from Source on MS Windows
|
||||
|
||||
Because building on MS Windows is quite complicated there is an
|
||||
Software Development Kit available that provides all the prerequisite
|
||||
libraries and tools for building WSJT-X. This SDK is called JT-SDK-QT
|
||||
libraries and tools for building WSJT-X. This SDK is called HAMLIB SDK
|
||||
which is documented here:
|
||||
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-doc/dev-guide-main.html
|
||||
https://sourceforge.net/projects/hamlib-sdk/
|
||||
|
||||
If you need to build Hamlib rather than use the Hamlib kit included in
|
||||
the JT-SDK the following recipe should help. Reasons for building
|
||||
the HAMLIB SDK the following recipe should help. Reasons for building
|
||||
Hamlib from source might include picking up the very latest patches or
|
||||
building a different branch that you wish to contribute to.
|
||||
|
||||
@ -143,7 +141,7 @@ In an MSYS shell:-
|
||||
|
||||
$ mkdir ~/hamib-prefix
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ git clone https://github.com/Hamlib/Hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
@ -178,10 +176,6 @@ Hamlib binary location as one of the paths in CMAKE_PREFIX_PATH.
|
||||
Building from Source on Apple Mac
|
||||
=================================
|
||||
|
||||
These instructions are adapted from my Evernote page at:
|
||||
|
||||
https://www.evernote.com/pub/bsomervi/wsjt-xmacbuilds
|
||||
|
||||
There are several ways to get the required GNU and other open source
|
||||
tools and libraries installed, my preference is MacPorts because it is
|
||||
easy to use and does everything we need.
|
||||
@ -228,12 +222,11 @@ instructions are here:
|
||||
|
||||
Hamlib
|
||||
------
|
||||
First fetch hamlib from the repository, in this case my fork of Hamlib
|
||||
3 until the official repository has all the fixes we need:
|
||||
First fetch hamlib from the git master repository:
|
||||
|
||||
$ mkdir -p ~/hamlib-prefix/build
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ git clone https://github.com/Hamlib/Hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
@ -352,8 +345,8 @@ which installs the WSJT-X application bundle into ~/wsjtx-prefix
|
||||
Updating and Rebuilding Hamlib
|
||||
==============================
|
||||
|
||||
From time to time new fixes will be pushed to the Hamlib fork
|
||||
repository integration branch. To pick them up type:
|
||||
From time to time new fixes will be pushed to the Hamlib git
|
||||
master repository. To pick them up type:
|
||||
|
||||
$ cd ~/hamlib-prefix/src
|
||||
$ git pull
|
||||
|
101
NEWS
101
NEWS
@ -9,7 +9,106 @@
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
Copyright 2001 - 2023 by Joe Taylor, K1JT, and the WSJT Development Team
|
||||
Copyright 2001 - 2024 by Joe Taylor, K1JT, and the WSJT Development Team
|
||||
|
||||
Release: WSJT-X 2.7.0-rc4
|
||||
March 11, 2024
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 4 brings some improvements for Fox-mode
|
||||
operators, new features for companion program QMAP, and a number of
|
||||
relatively minor enhancements and bug fixes.
|
||||
|
||||
QMAP enhancements -- of particular interest to EME operators:
|
||||
|
||||
- QMAP now decodes Q65 submodes with both 60-second and 30-second T/R
|
||||
sequence lengths. Clicking on a resulting line in the WSJT-X Active
|
||||
Stations window automatically sets dial frequency and working
|
||||
submode as needed to call that station.
|
||||
|
||||
- QMAP operates in 60-second receive sequences, and its Q65 decoder
|
||||
starts at t=19.5, 30.0, 49.5, and 58.5 s into the sequence. Most
|
||||
decoded messages are displayed well before the end of the relevant
|
||||
time slot.
|
||||
|
||||
- A new, more compact file format is now used for wideband data
|
||||
files. A "Save decoded" option has been added to the Save menu.
|
||||
|
||||
- An option has been added to allow exporting a 3 kHz portion of a
|
||||
wideband data file as a standard WSJT-X *.wav file.
|
||||
|
||||
- CTRL+click on QMAP's upper waterfall sends an integer kHz dial
|
||||
frequency request to WSJT-X.
|
||||
|
||||
- With focus on the WSJT-X main window, hit Alt+A on the keyboard to
|
||||
clear the Active Stations window.
|
||||
|
||||
- Many minor enhancements to the User Interface.
|
||||
|
||||
WSJT-X:
|
||||
|
||||
- Enable decoding of MSK144 from the jt9[.exe] executable.
|
||||
|
||||
- Several changes to reduce problems experienced when (contrary to
|
||||
our recommendations) messages with short (10-bit) callsign hashes
|
||||
are used in standard FT4/FT8 sub-bands.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc3
|
||||
January 1, 2024
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 3 brings some new features, as well as
|
||||
numerous detail improvements and bug fixes, such as:
|
||||
|
||||
- Added a new "Update Hamlib" function. On Windows, it allows the user to
|
||||
update Hamlib directly from the program. The previously used version is
|
||||
backed up, so the user can easily revert a hamlib update.
|
||||
|
||||
- The Hamlib version in use is now displayed (also on Linux and macOS).
|
||||
|
||||
- The FT Roundup Messages protocol has been enhanced. It now allows also
|
||||
the exchange of static 4-digit numbers instead of serial numbers. This
|
||||
extends the usability of the FT RU protocol for other contest types.
|
||||
|
||||
- Improved direct switching between modes. Submode, as well as the status
|
||||
of the "Sh" and "Fast" checkboxes are now saved and restored by mode.
|
||||
|
||||
- Some right-click events were made more intuitive and consistent.
|
||||
- Right-clicking the Q65 button enables Q65 Pileup mode, a left-click
|
||||
brings you back to the normal Q65 mode.
|
||||
- Right-click the JT65 button to switch to JT9 mode.
|
||||
|
||||
- For Q65, all messages for us are now displayed in the right window.
|
||||
|
||||
- Message averaging is now allowed only when VHF features are
|
||||
enabled, and label texts are changed to "Single Period Decodes" and
|
||||
"Average Decodes" only if averaging is enabled.
|
||||
|
||||
- Some improvements to the Hamlib Transceiver code. Behavior is now
|
||||
more stable when Rig Split has been selected.
|
||||
|
||||
- Prevented redundant network communication between WSJT-X and DX Lab
|
||||
Suite Commander.
|
||||
|
||||
- Download of the LotW file now works without OpenSSL libraries.
|
||||
|
||||
- Made the spot counter work for WSPR.
|
||||
|
||||
- Prevented insertion of an individual contest name when in Fox mode.
|
||||
|
||||
- WAE entities are now assigned to the correct DXCC when "Include
|
||||
extra WAE entities" is not selected.
|
||||
|
||||
- Added a utility program 'cablog' which can be used to convert the
|
||||
wsjtx.log file to Cabrillo format for the ARRL EME contest.
|
||||
|
||||
- Minor improvements to the Active Stations window.
|
||||
|
||||
- The Rx/Tx frequency for Echo mode has been fixed at 1500 Hz.
|
||||
|
||||
- Some corrections and updates to the INSTALL instructions for Linux.
|
||||
|
||||
- Updated CTY.DAT file.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc2
|
||||
July 7, 2023
|
||||
|
@ -9,7 +9,106 @@
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
Copyright 2001 - 2023 by Joe Taylor, K1JT, and the WSJT Development Team
|
||||
Copyright 2001 - 2024 by Joe Taylor, K1JT, and the WSJT Development Team
|
||||
|
||||
Release: WSJT-X 2.7.0-rc4
|
||||
March 11, 2024
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 4 brings some improvements for Fox-mode
|
||||
operators, new features for companion program QMAP, and a number of
|
||||
relatively minor enhancements and bug fixes.
|
||||
|
||||
QMAP enhancements -- of particular interest to EME operators:
|
||||
|
||||
- QMAP now decodes Q65 submodes with both 60-second and 30-second T/R
|
||||
sequence lengths. Clicking on a resulting line in the WSJT-X Active
|
||||
Stations window automatically sets dial frequency and working
|
||||
submode as needed to call that station.
|
||||
|
||||
- QMAP operates in 60-second receive sequences, and its Q65 decoder
|
||||
starts at t=19.5, 30.0, 49.5, and 58.5 s into the sequence. Most
|
||||
decoded messages are displayed well before the end of the relevant
|
||||
time slot.
|
||||
|
||||
- A new, more compact file format is now used for wideband data
|
||||
files. A "Save decoded" option has been added to the Save menu.
|
||||
|
||||
- An option has been added to allow exporting a 3 kHz portion of a
|
||||
wideband data file as a standard WSJT-X *.wav file.
|
||||
|
||||
- CTRL+click on QMAP's upper waterfall sends an integer kHz dial
|
||||
frequency request to WSJT-X.
|
||||
|
||||
- With focus on the WSJT-X main window, hit Alt+A on the keyboard to
|
||||
clear the Active Stations window.
|
||||
|
||||
- Many minor enhancements to the User Interface.
|
||||
|
||||
WSJT-X:
|
||||
|
||||
- Enable decoding of MSK144 from the jt9[.exe] executable.
|
||||
|
||||
- Several changes to reduce problems experienced when (contrary to
|
||||
our recommendations) messages with short (10-bit) callsign hashes
|
||||
are used in standard FT4/FT8 sub-bands.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc3
|
||||
January 1, 2024
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 3 brings some new features, as well as
|
||||
numerous detail improvements and bug fixes, such as:
|
||||
|
||||
- Added a new "Update Hamlib" function. On Windows, it allows the user to
|
||||
update Hamlib directly from the program. The previously used version is
|
||||
backed up, so the user can easily revert a hamlib update.
|
||||
|
||||
- The Hamlib version in use is now displayed (also on Linux and macOS).
|
||||
|
||||
- The FT Roundup Messages protocol has been enhanced. It now allows also
|
||||
the exchange of static 4-digit numbers instead of serial numbers. This
|
||||
extends the usability of the FT RU protocol for other contest types.
|
||||
|
||||
- Improved direct switching between modes. Submode, as well as the status
|
||||
of the "Sh" and "Fast" checkboxes are now saved and restored by mode.
|
||||
|
||||
- Some right-click events were made more intuitive and consistent.
|
||||
- Right-clicking the Q65 button enables Q65 Pileup mode, a left-click
|
||||
brings you back to the normal Q65 mode.
|
||||
- Right-click the JT65 button to switch to JT9 mode.
|
||||
|
||||
- For Q65, all messages for us are now displayed in the right window.
|
||||
|
||||
- Message averaging is now allowed only when VHF features are
|
||||
enabled, and label texts are changed to "Single Period Decodes" and
|
||||
"Average Decodes" only if averaging is enabled.
|
||||
|
||||
- Some improvements to the Hamlib Transceiver code. Behavior is now
|
||||
more stable when Rig Split has been selected.
|
||||
|
||||
- Prevented redundant network communication between WSJT-X and DX Lab
|
||||
Suite Commander.
|
||||
|
||||
- Download of the LotW file now works without OpenSSL libraries.
|
||||
|
||||
- Made the spot counter work for WSPR.
|
||||
|
||||
- Prevented insertion of an individual contest name when in Fox mode.
|
||||
|
||||
- WAE entities are now assigned to the correct DXCC when "Include
|
||||
extra WAE entities" is not selected.
|
||||
|
||||
- Added a utility program 'cablog' which can be used to convert the
|
||||
wsjtx.log file to Cabrillo format for the ARRL EME contest.
|
||||
|
||||
- Minor improvements to the Active Stations window.
|
||||
|
||||
- The Rx/Tx frequency for Echo mode has been fixed at 1500 Hz.
|
||||
|
||||
- Some corrections and updates to the INSTALL instructions for Linux.
|
||||
|
||||
- Updated CTY.DAT file.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc2
|
||||
July 7, 2023
|
||||
|
@ -206,15 +206,18 @@ void DXLabSuiteCommanderTransceiver::do_frequency (Frequency f, MODE m, bool /*n
|
||||
{
|
||||
CAT_TRACE (f << ' ' << state ());
|
||||
auto f_string = frequency_to_string (f);
|
||||
auto params = ("<xcvrfreq:%1>" + f_string).arg (f_string.size ());
|
||||
simple_command (("<command:10>CmdSetFreq<parameters:%1>" + params).arg (params.size ()));
|
||||
if (UNK != m)
|
||||
if (UNK != m && m != get_mode ())
|
||||
{
|
||||
auto m_string = map_mode (m);
|
||||
auto params = ("<xcvrfreq:%1>" + f_string + "<xcvrmode:%2>" + m_string + "<preservesplitanddual:1>Y").arg (f_string.size ()).arg (m_string.size ());
|
||||
simple_command (("<command:14>CmdSetFreqMode<parameters:%1>" + params).arg (params.size ()));
|
||||
update_mode (m);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto params = ("<xcvrfreq:%1>" + f_string).arg (f_string.size ());
|
||||
simple_command (("<command:10>CmdSetFreq<parameters:%1>" + params).arg (params.size ()));
|
||||
}
|
||||
update_rx_frequency (f);
|
||||
}
|
||||
|
||||
|
@ -760,7 +760,7 @@ int HamlibTransceiver::do_start ()
|
||||
|
||||
m_->reversed_ = RIG_VFO_B == v;
|
||||
|
||||
if (m_->mode_query_works_ && !(rig_get_caps_int (m_->model_, RIG_CAPS_TARGETABLE_VFO) & (RIG_TARGETABLE_MODE | RIG_TARGETABLE_PURE)))
|
||||
if (m_->mode_query_works_ && !(rig_get_caps_int (m_->model_, RIG_CAPS_TARGETABLE_VFO) & RIG_TARGETABLE_MODE))
|
||||
{
|
||||
if (RIG_OK == rig_get_mode (m_->rig_.data (), RIG_VFO_CURR, &m, &w))
|
||||
{
|
||||
@ -911,9 +911,9 @@ void HamlibTransceiver::do_frequency (Frequency f, MODE m, bool no_ignore)
|
||||
// to frequency such as the TS-2000 auto mode setting
|
||||
CAT_TRACE ("rig_set_mode mode=" << rig_strrmode (new_mode));
|
||||
m_->error_check (rig_set_mode (m_->rig_.data (), target_vfo, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting current VFO mode"));
|
||||
// set mode on VFOB too if we are in split
|
||||
if (state ().split()) rig_set_mode (m_->rig_.data (), RIG_VFO_B, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting VFOB mode");
|
||||
}
|
||||
// set mode on VFOB too if we are in split
|
||||
if (state ().split()) rig_set_mode (m_->rig_.data (), RIG_VFO_B, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting VFOB mode");
|
||||
update_mode (m);
|
||||
}
|
||||
}
|
||||
@ -1147,7 +1147,7 @@ void HamlibTransceiver::do_poll ()
|
||||
|
||||
if ((WSJT_RIG_NONE_CAN_SPLIT || !m_->is_dummy_)
|
||||
&& state ().split ()
|
||||
&& (rig_get_caps_int (m_->model_, RIG_CAPS_TARGETABLE_VFO) & (RIG_TARGETABLE_FREQ | RIG_TARGETABLE_PURE))
|
||||
&& (rig_get_caps_int (m_->model_, RIG_CAPS_TARGETABLE_VFO) & RIG_TARGETABLE_FREQ)
|
||||
&& !m_->one_VFO_)
|
||||
{
|
||||
// only read "other" VFO if in split, this allows rigs like
|
||||
|
@ -1,68 +1,60 @@
|
||||
[[NEW_FEATURES]]
|
||||
=== New in Version {VERSION_MAJOR}.{VERSION_MINOR}
|
||||
|
||||
- _WSJT-X 2.6_ implements new features supporting the ARRL
|
||||
International Digital Contest and its distance based scoring. The
|
||||
*Call 1st* checkbox has been replaced by a drop-down control offering
|
||||
*CQ Max Dist* as an alternative. A new window labeled *Active
|
||||
Stations* displays a list of received but unworked callsigns, sorted
|
||||
in decreasing order of potential contest points. With option *CQ Max
|
||||
Dist* selected, the program will select the reply to your CQ that
|
||||
yields the most contest points. You can click on a line in the Active
|
||||
Stations window to call that station.
|
||||
_WSJT-X 2.7_ introduces a new program called *QMAP*, a new Special
|
||||
Operating Activity *Q65 Pileup*, an option to *Update Hamlib* at the
|
||||
click of a button, and a number of other enhancements and bug fixes.
|
||||
|
||||
- Decoding performance for FT8 and Q65 has been improved in a variety
|
||||
of situations with available _a priori_ (AP) information.
|
||||
- QMAP and Q65 Pileup mode are of particular interest to those engaged
|
||||
in Earth-Moon-Earth (EME) communication, but other applications may
|
||||
be found for them as well. QMAP is currently available for Windows
|
||||
only; it is derived from MAP65, an older program used since 2007 for
|
||||
EME. QMAP provides single-polarization receive-only capabilities for
|
||||
any one of the 60-second submodes of Q65. It allows you to monitor
|
||||
all traffic in a 90 kHz sub-band while conducting EME QSOs in the
|
||||
usual way with _WSJT-X_. Q65 Pileup mode helps DX operators using
|
||||
Q65 in pileup circumstances with many simultaneous callers and very
|
||||
weak signals, such as those experienced by 6-meter EME DXpeditions.
|
||||
Further details on QMAP and Q65 Pileup mode are available in a
|
||||
Quick-Start guide posted here:
|
||||
https://wsjt.sourceforge.io/Quick_Start_WSJT-X_2.7_QMAP.pdf
|
||||
|
||||
- *Echo* mode now offers a *Clear Avg* button and produces reliable
|
||||
measurements of SNR even when Doppler spread is large. Its *Monitor*
|
||||
function can be used to measure SNR for a received unmodulated carrier
|
||||
such as a key-down test signal emitted by another station and
|
||||
reflected from the Moon, and also to measure Sun, Moon, and ground
|
||||
noise as aids for optimizing an EME station's performance.
|
||||
- A button *Update Hamlib* now appears on the *Settings -> Radio* tab.
|
||||
On Windows it allows the user to automatically download and install
|
||||
the latest version of the rig-control features in Hamlib. The
|
||||
previously used version is backed up, so you can easily revert the
|
||||
procedure if necessary. Names and dates of the active and backup
|
||||
versions are clearly displayed.
|
||||
|
||||
- New buttons on the main window allow quick changes between modes
|
||||
FT4, FT8, MSK144, Q65, and JT65, and toggling FT8 Hound mode ON/OFF.
|
||||
- Spotting to *PSK Reporter* has been made more efficient. Redundant
|
||||
spots are omitted, and all posts are spread more widely in time. If
|
||||
your station locator is changed, for example during portable
|
||||
operations, your new locator will be sent automatically to PSK
|
||||
Reporter.
|
||||
|
||||
- New convenience features allow Fox operators to react more quickly
|
||||
to particular QSO situations. A two-column table in Tab 2 provides an
|
||||
overview of the queue and of callsigns with QSOs in progress. Fox
|
||||
operator can change the ordering of callsigns in the queue, allowing
|
||||
reaction to changes in propagation. Fox now responds automatically
|
||||
for another two cycles to stations whose report has not been received,
|
||||
increasing the success rate for difficult QSOs.
|
||||
- *Fox* mode now provides more convenient handling of the two callsign
|
||||
queues, and Fox's Log window displays statistical data on recent QSO
|
||||
rate. Multi-streamed messages transmitted by _MSHV_ are now handled
|
||||
properly when _WSJT-X_ is in *Hound* mode.
|
||||
|
||||
- The Working frequency table now offers save/restore capability and
|
||||
better handling of more than one frequency per mode-band
|
||||
combination. You can set preferred frequencies, and WSJT-X will select
|
||||
these when you change band or mode. You can label a tabled frequency
|
||||
with a description, for example a DXpedition callsign, and set Start
|
||||
and End date and time so the frequencies automatically appear and
|
||||
disappear from the displayed options. You can load a publicly
|
||||
available frequency table from a file, to easily make such DXpedition
|
||||
data available to the program.
|
||||
- The cty.dat file can now be updated by clicking a button on the
|
||||
*Settings -> Colors* tab.
|
||||
|
||||
- Optional color highlighting is provided for specified DX Call and DX
|
||||
Grid, and for messages containing RR73 or 73.
|
||||
- The FT Roundup message protocol now allows the exchange of static
|
||||
4-digit numbers in place of serial numbers. This extends the
|
||||
usability of the FT RU protocol for other contest types.
|
||||
|
||||
- New options are provided for writing to file ALL.TXT. You can
|
||||
request automatic starting of a new file every month or every year,
|
||||
and you can disable writing altogether.
|
||||
- Features for main-window switching between modes have been enhanced
|
||||
so that submode and status of the *Sh* and *Fast* checkboxes are
|
||||
saved and restored by mode. Right-click events were made more
|
||||
intuitive and consistent. Right-clicking the Q65 button enables Q65
|
||||
Pileup mode, and a left-click brings you back to the normal Q65
|
||||
mode. Right-click on the JT65 button switches to JT9 mode.
|
||||
|
||||
- Settings for T/R period and Submode are remembered by mode when you
|
||||
switch directly between modes: for example, MSK144-15, Q65-60A, or
|
||||
FST4-120.
|
||||
- Message averaging is now allowed only when *VHF features* are
|
||||
enabled. Main window text box labels are changed to read "`Single
|
||||
Period Decodes`" and "`Average Decodes`" when averaging is enabled.
|
||||
|
||||
- Tx and Rx audio frequencies are remembered and restored when you
|
||||
return from a mode that sets a default frequency 1500 Hz (MSK144,
|
||||
FST4W, Echo, WSPR, FreqCal), then switching back to FT4, FT8, Q65,
|
||||
FST4, or JT65.
|
||||
Further details on minor changes can be found in the Release Notes,
|
||||
accessible from the _WSJT-X_ *Help* menu.
|
||||
|
||||
- Rig control is provided for some new radios, and bug fixes for
|
||||
controlling others.
|
||||
|
||||
- New features in _MAP65_ (available for Windows only) include an aid
|
||||
for measuring antenna pointing errors and an ability to read the file
|
||||
wsjtx.log (kept by _WSJT-X_) to recognize EME contest dupes. In
|
||||
addition, _MAP65_ now sends additional information to file azel.dat
|
||||
and offers optional digital scaling of input I/Q data.
|
||||
|
@ -31,7 +31,7 @@ image::RadioTab.png[align="center",alt="Radio Tab"]
|
||||
suitable.
|
||||
|
||||
* _CAT Control_: To have _WSJT-X_ control the radio directly rather
|
||||
than though another program, make the following settings:
|
||||
than through another program, make the following settings:
|
||||
|
||||
** Select the *Serial Port* or *Network Server* including the service
|
||||
port number used to communicate with your radio.
|
||||
|
@ -26,7 +26,7 @@ on bands above 1.2 GHz.
|
||||
|
||||
To activate the VHF-and-up features:
|
||||
|
||||
- On the *Settings | General* tab check *Enable VHF/UHF/Microwave
|
||||
- On the *Settings | General* tab check *Enable VHF and submode
|
||||
features* and *Single decode*.
|
||||
|
||||
- For EME, check *Decode after EME delay* to allow for extra path
|
||||
@ -291,14 +291,16 @@ communication.
|
||||
|
||||
For lunar echoes, _WSJT_ generates short fixed-frequency transmissions
|
||||
that alternate with reception intervals at the appropriate
|
||||
Doppler-shifted frequency. With *Split Operation* set to *Rig* or
|
||||
*Fake It* on the *Settings | Radio* tab, check *Doppler tracking* and
|
||||
*Own Echo* on the Astronomical Data window. Point your antenna at the
|
||||
Moon and click *Enable Tx* on the main window to start a sequence of
|
||||
echo measurements. Each cycle takes 6 seconds. If strong enough,
|
||||
echoes will be visible in the waterfall. Their average spectrum will
|
||||
be displayed in the Echo Graph window, and numerical parameters of the
|
||||
measurements appear in the main window:
|
||||
Doppler-shifted frequency. Be sure that *Enable VHF and submode
|
||||
features* has been checked on the *Settings | General* tab. With
|
||||
*Split Operation* set to *Rig* or *Fake It* on the *Settings | Radio*
|
||||
tab, check *Doppler tracking* and *Own Echo* on the Astronomical Data
|
||||
window. Point your antenna at the Moon and click *Enable Tx* on the
|
||||
main window to start a sequence of echo measurements. Each cycle
|
||||
takes 6 seconds. If strong enough, echoes will be visible in the
|
||||
waterfall. Their average spectrum will be displayed in the Echo Graph
|
||||
window, and numerical parameters of the measurements appear in the
|
||||
main window:
|
||||
|
||||
image::Echo_1296.png[align="center",alt="Echo 144 MHz"]
|
||||
|
||||
|
@ -474,13 +474,17 @@ subroutine unpack77(c77,nrx,msg,unpk77_success)
|
||||
i=index(call_1,' ')
|
||||
if(i.ge.4 .and. ipa.eq.1 .and. i3.eq.1) call_1(i:i+1)='/R'
|
||||
if(i.ge.4 .and. ipa.eq.1 .and. i3.eq.2) call_1(i:i+1)='/P'
|
||||
if(i.ge.4) call add_call_to_recent_calls(call_1)
|
||||
if(i.ge.4) call add_call_to_recent_calls(call_1)
|
||||
endif
|
||||
if(index(call_2,'<').le.0) then
|
||||
i=index(call_2,' ')
|
||||
if(i.ge.4 .and. ipb.eq.1 .and. i3.eq.1) call_2(i:i+1)='/R'
|
||||
if(i.ge.4 .and. ipb.eq.1 .and. i3.eq.2) call_2(i:i+1)='/P'
|
||||
if(i.ge.4) call add_call_to_recent_calls(call_2)
|
||||
if(i.ge.4) then
|
||||
call add_call_to_recent_calls(call_2)
|
||||
! only hash the "from" call
|
||||
call save_hash_call(call_2,ndum10,ndum12,ndum22)
|
||||
endif
|
||||
endif
|
||||
if(igrid4.le.MAXGRID4) then
|
||||
call to_grid4(igrid4,grid4,unpkg4_success)
|
||||
@ -560,6 +564,7 @@ subroutine unpack77(c77,nrx,msg,unpk77_success)
|
||||
call_1=call_3
|
||||
call_2=adjustl(c11)//' '
|
||||
call add_call_to_recent_calls(call_2)
|
||||
call save_hash_call(call_2,ndum10,ndum12,ndum22)
|
||||
if(nrx.eq.1 .and. &
|
||||
dxcall13_set .and. mycall13_set .and. &
|
||||
call_2.eq.dxcall13 .and. &
|
||||
@ -1540,7 +1545,7 @@ subroutine add_call_to_recent_calls(callsign)
|
||||
endif
|
||||
|
||||
! Make sure that callsign is hashed
|
||||
call save_hash_call(callsign,n10,n12,n22)
|
||||
! call save_hash_call(callsign,n10,n12,n22) ! commented out - do this in the calling routine:
|
||||
|
||||
return
|
||||
end subroutine add_call_to_recent_calls
|
||||
|
142
lib/cablog.f90
Normal file
142
lib/cablog.f90
Normal file
@ -0,0 +1,142 @@
|
||||
program cablog
|
||||
|
||||
character*100 line,infile,outfile
|
||||
character cband*4,cmode*2,cdate*10,cutc*4,callsign*10,mycall*10
|
||||
character csent*4,crcvd*4,dsent*4,drcvd*4,g1*4
|
||||
character*3 cmo(12)
|
||||
integer icomma(20)
|
||||
logical map65
|
||||
logical isgrid,gridx
|
||||
data cmo/'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep', &
|
||||
'Oct','Nov','Dec'/
|
||||
|
||||
isgrid(g1)=g1(1:1).ge.'A' .and. g1(1:1).le.'R' .and. g1(2:2).ge.'A' .and. &
|
||||
g1(2:2).le.'R' .and. g1(3:3).ge.'0' .and. g1(3:3).le.'9' .and. &
|
||||
g1(4:4).ge.'0' .and. g1(4:4).le.'9' .and. g1(1:4).ne.'RR73'
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.4) then
|
||||
print*,"Program cablog converts file 'wsjtx.log' written by WSJT-X"
|
||||
print*,"(or wsjt.log written by MAP65) to a bare-bones Cabrillo"
|
||||
print*,"log for the ARRL International EME Contest. You will"
|
||||
print*,"certainly need to edit the header information, and you may"
|
||||
print*,"edit the log elsewhere as required."
|
||||
print*,' '
|
||||
print*,'Usage: cablog <MyCall> <sent> <rcvd> <infile>'
|
||||
print*,'Examples: cablog W2ZQ -15 -16 wsjtx.log'
|
||||
print*,' cablog W2ZQ O O wsjt.log'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,mycall)
|
||||
outfile=trim(mycall)//'.log'
|
||||
call getarg(2,dsent)
|
||||
gridx=isgrid(dsent)
|
||||
call getarg(3,drcvd)
|
||||
call getarg(4,infile)
|
||||
open(10,file=trim(infile),status='old')
|
||||
open(12,file=trim(outfile),status='unknown')
|
||||
|
||||
write(12,1000)
|
||||
1000 format('START-OF-LOG: 3.0'/ &
|
||||
'CONTEST: ARRL-EME'/ &
|
||||
'CALLSIGN: '/ &
|
||||
'CATEGORY-OPERATOR: '/ &
|
||||
'CATEGORY-BAND: '/ &
|
||||
'CATEGORY-MODE: '/ &
|
||||
'EMAIL: '/ &
|
||||
'OPERATORS: '/ &
|
||||
'CATEGORY-POWER: HIGH'/ &
|
||||
'CATEGORY-TRANSMITTER: ONE'/ &
|
||||
'CATEGORY-STATION: FIXED'/ &
|
||||
'CATEGORY-TIME: 24-HOURS'/ &
|
||||
'CATEGORY-ASSISTED: ASSISTED'/ &
|
||||
'LOCATION: SNJ'/ &
|
||||
'CLAIMED-SCORE: '/ &
|
||||
'CLUB: '/ &
|
||||
'NAME: '/ &
|
||||
'ADDRESS: '/ &
|
||||
'ADDRESS: '/ &
|
||||
'ADDRESS: '/ &
|
||||
'CREATED-BY: cablog (C) K1JT')
|
||||
|
||||
n=0
|
||||
map65=.false.
|
||||
|
||||
do nn=1,9999
|
||||
read(10,'(a100)',end=900) line
|
||||
if(len(trim(line)).eq.0) cycle
|
||||
if(line(6:6).ge.'A' .and. line(6:6).le.'Z') map65=.true.
|
||||
n=n+1
|
||||
k=0
|
||||
do j=1,100
|
||||
if(line(j:j).eq.',') then
|
||||
k=k+1
|
||||
icomma(k)=j
|
||||
endif
|
||||
enddo
|
||||
cmode='DG'
|
||||
if(index(line,',CW,').gt.10) cmode='CW'
|
||||
|
||||
if(map65) then
|
||||
do i=1,12
|
||||
if(cmo(i).eq.line(6:8)) write(cdate(6:7),'(i2.2)') i
|
||||
enddo
|
||||
cdate(1:5)=line(1:5)
|
||||
cdate(8:10)=line(9:11)
|
||||
cutc=line(13:14)//line(16:17)
|
||||
i0=index(line(19:),',')
|
||||
callsign=line(19:17+i0)
|
||||
cband='144 '
|
||||
csent=dsent
|
||||
crcvd=drcvd
|
||||
else
|
||||
cdate=line(1:10)
|
||||
cutc=line(32:33)//line(35:36)
|
||||
i0=index(line(41:),',')
|
||||
callsign=line(41:39+i0)
|
||||
read(line(icomma(6)+1:icomma(7)-1),*,err=10,end=10) freq
|
||||
go to 20
|
||||
10 print*,'***Error at line ',n
|
||||
print*,trim(line)
|
||||
20 if(freq.ge.50.0 .and. freq.le.54.0) cband='50 '
|
||||
if(freq.ge.144.0 .and. freq.le.148.0) cband='144 '
|
||||
if(freq.ge.28.0 .and. freq.le.29.0) cband='144 '
|
||||
if(freq.ge.222.0 .and. freq.le.225.0) cband='222 '
|
||||
if(freq.ge.420.0 .and. freq.le.450.0) cband='432 '
|
||||
if(freq.ge.902.0 .and. freq.le.928.0) cband='902 '
|
||||
if(freq.ge.1240.0 .and. freq.le.1300.0) cband='1.2G'
|
||||
if(freq.ge.2300.0 .and. freq.le.2450.0) cband='2.3G'
|
||||
if(freq.ge.3300.0 .and. freq.le.3500.0) cband='3.4G'
|
||||
if(freq.ge.5650.0 .and. freq.le.5925.0) cband='5.7G'
|
||||
if(freq.ge.10000.0 .and. freq.le.10500.0) cband='10G '
|
||||
if(freq.ge.24000.0 .and. freq.le.24250.0) cband='24G '
|
||||
if(icomma(8).eq.icomma(9)-1) then
|
||||
csent=dsent
|
||||
else
|
||||
csent=line(icomma(8)+1:icomma(9)-1)
|
||||
endif
|
||||
if(icomma(9).eq.icomma(10)-1) then
|
||||
crcvd=drcvd
|
||||
else
|
||||
crcvd=line(icomma(9)+1:icomma(10)-1)
|
||||
endif
|
||||
endif
|
||||
if(gridx) then
|
||||
csent=dsent
|
||||
crcvd=line(icomma(5)+1:icomma(6)-1)
|
||||
endif
|
||||
|
||||
write(12,1030) cband,cmode,cdate,cutc,mycall,csent,callsign,crcvd
|
||||
1030 format('QSO: ',a4,1x,a2,1x,a10,1x,a4,1x,a6,1x,a4,4x,a10,1x,a4)
|
||||
enddo
|
||||
|
||||
900 write(12,1900)
|
||||
1900 format('END-OF-LOG:')
|
||||
write(*,1910) n,trim(outfile)
|
||||
1910 format('Processed',i5,' QSOs.'/'Output file: ',a)
|
||||
|
||||
999 end program cablog
|
||||
|
||||
!2023-10-28,00:17:00,2023-10-28,00:21:00,G7TZZ,IO92,1296.083100,Q65,-17,-17,,,,
|
||||
!2023-Nov-30,20:31,W8WN,EM77,0,Q65A
|
||||
|
57
lib/decode_msk144.f90
Normal file
57
lib/decode_msk144.f90
Normal file
@ -0,0 +1,57 @@
|
||||
subroutine decode_msk144(audio_samples, params, data_dir)
|
||||
include 'jt9com.f90'
|
||||
|
||||
! constants
|
||||
integer, parameter :: SAMPLING_RATE = 12000
|
||||
integer, parameter :: BLOCK_SIZE = 7168
|
||||
integer, parameter :: STEP_SIZE = BLOCK_SIZE / 2
|
||||
integer, parameter :: CALL_LENGTH = 12
|
||||
|
||||
! aguments
|
||||
integer*2 audio_samples(NMAX)
|
||||
type(params_block) :: params
|
||||
character(len = 500) :: data_dir
|
||||
|
||||
! parameters of mskrtd
|
||||
integer*2 :: buffer(BLOCK_SIZE)
|
||||
real :: tsec
|
||||
logical :: bshmsg = .false. ! enables shorthand messages
|
||||
logical :: btrain = .false. ! turns on training in MSK144 mode
|
||||
real*8 :: pcoeffs(5) = (/ 0.0, 0.0, 0.0, 0.0, 0.0 /); ! phase equalization
|
||||
logical :: bswl = .false.
|
||||
character(len = 80) :: line
|
||||
character(len = CALL_LENGTH) :: mycall
|
||||
character(len = CALL_LENGTH) :: hiscall
|
||||
|
||||
! local variables
|
||||
integer :: sample_count
|
||||
integer :: position
|
||||
integer :: message_count = 0
|
||||
|
||||
|
||||
! decode in 0.3s blocks
|
||||
sample_count = params%ntr * SAMPLING_RATE
|
||||
mycall = transfer(params%mycall, mycall) ! string to char[]
|
||||
hiscall = transfer(params%hiscall, hiscall)
|
||||
|
||||
do position = 1, sample_count - BLOCK_SIZE + 1, STEP_SIZE
|
||||
buffer = audio_samples(position : position + BLOCK_SIZE - 1)
|
||||
tsec = position / REAL(SAMPLING_RATE)
|
||||
|
||||
call mskrtd(buffer, params%nutc, tsec, params%ntol, params%nfqso, params%ndepth, &
|
||||
mycall, hiscall, bshmsg, btrain, pcoeffs, bswl, data_dir, line)
|
||||
|
||||
if (line(1:1) .ne. char(0)) then
|
||||
line = line(1:index(line, char(0))-1)
|
||||
write(*, 1001) line
|
||||
1001 format(a80)
|
||||
message_count = message_count + 1;
|
||||
end if
|
||||
end do
|
||||
|
||||
if (.not. params%ndiskdat) then
|
||||
write(*, 1002) 0, message_count, 0
|
||||
1002 format('<DecodeFinished>', 2i4, i9)
|
||||
end if
|
||||
|
||||
end subroutine decode_msk144
|
@ -20,7 +20,7 @@ subroutine four2a(a,nfft,ndim,isign,iform)
|
||||
! actual computations.
|
||||
|
||||
use fftw3
|
||||
parameter (NPMAX=2100) !Max numberf of stored plans
|
||||
parameter (NPMAX=2100) !Max number of stored plans
|
||||
parameter (NSMALL=16385) !Max half complex size of "small" FFTs
|
||||
complex a(nfft) !Array to be transformed
|
||||
complex aa(NSMALL) !Local copy of "small" a()
|
||||
|
@ -171,15 +171,15 @@ subroutine fastosd240_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin)
|
||||
if( ndeep.eq. 1) then
|
||||
nord=1
|
||||
xlambda=0.0
|
||||
nsyncmax=np
|
||||
nsyndmax=np
|
||||
elseif(ndeep.eq.2) then
|
||||
nord=2
|
||||
xlambda=0.0
|
||||
nsyncmax=np
|
||||
nsyndmax=np
|
||||
elseif(ndeep.eq.3) then
|
||||
nord=3
|
||||
xlambda=4.0
|
||||
nsyncmax=11
|
||||
nsyndmax=11
|
||||
elseif(ndeep.eq.4) then
|
||||
nord=4
|
||||
xlambda=3.4
|
||||
@ -190,7 +190,6 @@ subroutine fastosd240_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin)
|
||||
s2=sum(absrx(k+1:N))
|
||||
rho=s1/(s1+xlambda*s2)
|
||||
rhodmin=rho*dmin
|
||||
nerr64=-1
|
||||
do iorder=1,nord
|
||||
!beta=0.0
|
||||
!if(iorder.ge.3) beta=0.4
|
||||
@ -216,7 +215,6 @@ subroutine fastosd240_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin)
|
||||
cw=ce
|
||||
nhardmin=sum(nxor)
|
||||
nwhspmin=nwhsp
|
||||
nerr64=sum(nxor(1:K))
|
||||
endif
|
||||
endif
|
||||
! Get the next test error pattern, iflag will go negative
|
||||
@ -224,7 +222,6 @@ subroutine fastosd240_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin)
|
||||
call nextpat74(mi,k,iorder,iflag)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
998 continue
|
||||
! Re-order the codeword to [message bits][parity bits] format.
|
||||
cw(indices)=cw
|
||||
|
@ -4,33 +4,47 @@ program ldpcsim240_74
|
||||
|
||||
use packjt77
|
||||
|
||||
parameter(N=240, K=74, M=N-K)
|
||||
parameter(N=240, NN=120)
|
||||
character*8 arg
|
||||
character*37 msg0
|
||||
character*37 msg0,msgsent,msg
|
||||
character*77 c77
|
||||
character*24 c24
|
||||
integer*1 msgbits(74)
|
||||
integer*1 msgbits(101)
|
||||
integer*1 apmask(240)
|
||||
integer*1 cw(240)
|
||||
integer*1 codeword(N),message74(74)
|
||||
integer ncrc24
|
||||
real rxdata(N),llr(N)
|
||||
integer modtype, graymap(0:3)
|
||||
integer*4 itone(120)
|
||||
integer channeltype
|
||||
integer lmax(1)
|
||||
real rxdata(N)
|
||||
real llr(240)
|
||||
real bitmetrics(2*NN,4)
|
||||
complex c1(4,8),c2(16,4),c4(256,2),cs(0:3,NN)
|
||||
real s2(0:65535)
|
||||
logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits
|
||||
logical first
|
||||
data first/.true./
|
||||
data graymap/0,1,3,2/
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.5 .and. nargs.ne.6) then
|
||||
print*,'Usage: ldpcsim niter ndeep #trials s K [msg]'
|
||||
print*,'e.g. ldpcsim240_74 20 5 1000 0.85 64 "K9AN K1JT FN20"'
|
||||
if(nargs.ne.7 .and. nargs.ne.8) then
|
||||
print*,'Usage: ldpcsim maxosd norder #trials s Keff modtype channel '
|
||||
print*,'e.g. ldpcsim240_74 2 4 1000 0.85 50 1 0'
|
||||
print*,'s : if negative, then value is ignored and sigma is calculated from SNR.'
|
||||
print*,'niter: is the number of BP iterations.'
|
||||
print*,'ndeep: -1 is BP only, ndeep>=0 is OSD order'
|
||||
print*,'K :is the number of message+CRC bits and must be in the range [50,74]'
|
||||
print*,'maxosd<0: do bp only'
|
||||
print*,'maxosd=0: do bp and then call osd once with channel llrs.'
|
||||
print*,'maxosd>0: do bp and then call osc maxosd times with saved bp outputs.'
|
||||
print*,'norder : osd decoding depth'
|
||||
print*,'Keff : # of message bits, Keff must be in the range 50:74'
|
||||
print*,'modtype : 0 coherent BPSK, 1 4FSK'
|
||||
print*,'channel : 0 AWGN, 1 Rayleigh (4FSK only)'
|
||||
print*,'WSPR-format message is optional'
|
||||
return
|
||||
endif
|
||||
call getarg(1,arg)
|
||||
read(arg,*) max_iterations
|
||||
read(arg,*) maxosd
|
||||
call getarg(2,arg)
|
||||
read(arg,*) norder
|
||||
call getarg(3,arg)
|
||||
@ -39,17 +53,26 @@ program ldpcsim240_74
|
||||
read(arg,*) s
|
||||
call getarg(5,arg)
|
||||
read(arg,*) Keff
|
||||
msg0='K9AN K1JT FN20 '
|
||||
if(nargs.eq.6) call getarg(6,msg0)
|
||||
call getarg(6,arg)
|
||||
read(arg,*) modtype
|
||||
call getarg(7,arg)
|
||||
read(arg,*) channeltype
|
||||
call getarg(8,arg)
|
||||
|
||||
msg0='K9AN EN50 20 '
|
||||
call pack77(msg0,i3,n3,c77)
|
||||
|
||||
rate=real(Keff)/real(N)
|
||||
|
||||
write(*,*) "code rate: ",rate
|
||||
write(*,*) "niter : ",max_iterations
|
||||
write(*,*) "maxosd : ",maxosd
|
||||
write(*,*) "norder : ",norder
|
||||
write(*,*) "s : ",s
|
||||
write(*,*) "K : ",Keff
|
||||
if(modtype.eq.0) write(*,*) "modtype : coherent BPSK"
|
||||
if(modtype.eq.1) write(*,*) "modtype : noncoherent 4FSK"
|
||||
if(channeltype.eq.0) write(*,*) "channel : AWGN"
|
||||
if(channeltype.eq.1) write(*,*) "channel : Rayleigh"
|
||||
|
||||
msgbits=0
|
||||
read(c77,'(50i1)') msgbits(1:50)
|
||||
@ -59,49 +82,170 @@ program ldpcsim240_74
|
||||
call get_crc24(msgbits,74,ncrc24)
|
||||
write(c24,'(b24.24)') ncrc24
|
||||
read(c24,'(24i1)') msgbits(51:74)
|
||||
write(*,'(24i1)') msgbits(51:74)
|
||||
write(*,'(24i1)') msgbits(51:74)
|
||||
write(*,*) 'message with crc24'
|
||||
write(*,'(74i1)') msgbits(1:74)
|
||||
call encode240_74(msgbits,codeword)
|
||||
call init_random_seed()
|
||||
call sgran()
|
||||
|
||||
call encode240_74(msgbits(1:74),codeword)
|
||||
do i=1,120
|
||||
is=codeword(2*i)+2*codeword(2*i-1)
|
||||
itone(i)=graymap(is)
|
||||
enddo
|
||||
|
||||
write(*,*) 'codeword'
|
||||
write(*,'(77i1,1x,24i1,1x,73i1)') codeword
|
||||
|
||||
write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma symbol error rate"
|
||||
do idb = 8,-3,-1
|
||||
! call init_random_seed()
|
||||
! call sgran()
|
||||
|
||||
one=.false.
|
||||
do i=0,65535
|
||||
do j=0,15
|
||||
if(iand(i,2**j).ne.0) one(i,j)=.true.
|
||||
enddo
|
||||
enddo
|
||||
|
||||
write(*,*) "Eb/N0 Es/N0 ngood nundetected symbol error rate"
|
||||
do idb = 24,-8,-1
|
||||
db=idb/2.0-1.0
|
||||
sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No
|
||||
sigma=1/sqrt( 2*rate*iq*(10**(db/10.0)) ) ! to make db represent Eb/No
|
||||
! sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No
|
||||
ngood=0
|
||||
nue=0
|
||||
nberr=0
|
||||
nsymerr=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
|
||||
nberr=nberr+nerr
|
||||
if(modtype.eq.0) then
|
||||
iq = 1 ! bits per symbol
|
||||
sigma=1/sqrt( 2*rate*iq*(10**(db/10.0)) ) ! to make db represent Eb/No
|
||||
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
|
||||
nberr=nberr+nerr
|
||||
|
||||
rxav=sum(rxdata)/N
|
||||
rx2av=sum(rxdata*rxdata)/N
|
||||
rxsig=sqrt(rx2av-rxav*rxav)
|
||||
rxdata=rxdata/rxsig
|
||||
if( s .lt. 0 ) then
|
||||
ss=sigma
|
||||
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)
|
||||
else
|
||||
ss=s
|
||||
! noncoherent MFSK
|
||||
iq = 2 ! bits per symbol
|
||||
sigma=1/sqrt( 2*rate*iq*(10**(db/10.0)) ) ! to make db represent Eb/No
|
||||
A=1
|
||||
do i=1,120
|
||||
do j=0,3
|
||||
if(j.eq.itone(i)) then
|
||||
if(channeltype.eq.0) then
|
||||
A=1.0
|
||||
elseif(channeltype.eq.1) then
|
||||
xI=gran()**2+gran()**2
|
||||
A=sqrt(xI/2)
|
||||
endif
|
||||
cs(j,i)= A + sigma*gran() + cmplx(0,1)*sigma*gran()
|
||||
elseif(j.ne.itone(i)) then
|
||||
cs(j,i)= sigma*gran() + cmplx(0,1)*sigma*gran()
|
||||
endif
|
||||
enddo
|
||||
lmax=maxloc(abs(cs(:,i)))
|
||||
if(lmax(1)-1.ne.itone(i) ) nsymerr=nsymerr+1
|
||||
enddo
|
||||
|
||||
do k=1,NN,8
|
||||
|
||||
do m=1,8 ! do 4 1-symbol correlations for each of 8 symbs
|
||||
s2=0
|
||||
do is=1,4
|
||||
c1(is,m)=cs(graymap(is-1),k+m-1)
|
||||
s2(is-1)=abs(c1(is,m))
|
||||
enddo
|
||||
ipt=(k-1)*2+2*(m-1)+1
|
||||
do ib=0,1
|
||||
bm=maxval(s2(0:3),one(0:3,1-ib)) - &
|
||||
maxval(s2(0:3),.not.one(0:3,1-ib))
|
||||
if(ipt+ib.gt.2*NN) cycle
|
||||
bitmetrics(ipt+ib,1)=bm
|
||||
enddo
|
||||
enddo
|
||||
|
||||
do m=1,4 ! do 16 2-symbol correlations for each of 4 2-symbol groups
|
||||
s2=0
|
||||
do i=1,4
|
||||
do j=1,4
|
||||
is=(i-1)*4+j
|
||||
c2(is,m)=c1(i,2*m-1)+c1(j,2*m)
|
||||
s2(is-1)=abs(c2(is,m))**2
|
||||
enddo
|
||||
enddo
|
||||
ipt=(k-1)*2+4*(m-1)+1
|
||||
do ib=0,3
|
||||
bm=maxval(s2(0:15),one(0:15,3-ib)) - &
|
||||
maxval(s2(0:15),.not.one(0:15,3-ib))
|
||||
if(ipt+ib.gt.2*NN) cycle
|
||||
bitmetrics(ipt+ib,2)=bm
|
||||
enddo
|
||||
enddo
|
||||
|
||||
do m=1,2 ! do 256 4-symbol corrs for each of 2 4-symbol groups
|
||||
s2=0
|
||||
do i=1,16
|
||||
do j=1,16
|
||||
is=(i-1)*16+j
|
||||
c4(is,m)=c2(i,2*m-1)+c2(j,2*m)
|
||||
s2(is-1)=abs(c4(is,m))
|
||||
enddo
|
||||
enddo
|
||||
ipt=(k-1)*2+8*(m-1)+1
|
||||
do ib=0,7
|
||||
bm=maxval(s2(0:255),one(0:255,7-ib)) - &
|
||||
maxval(s2(0:255),.not.one(0:255,7-ib))
|
||||
if(ipt+ib.gt.2*NN) cycle
|
||||
bitmetrics(ipt+ib,3)=bm
|
||||
enddo
|
||||
enddo
|
||||
|
||||
s2=0 ! do 65536 8-symbol correlations for the entire group
|
||||
do i=1,256
|
||||
do j=1,256
|
||||
is=(i-1)*256+j
|
||||
s2(is-1)=abs(c4(i,1)+c4(j,2))
|
||||
enddo
|
||||
enddo
|
||||
ipt=(k-1)*2+1
|
||||
do ib=0,15
|
||||
bm=maxval(s2(0:65535),one(0:65535,15-ib)) - &
|
||||
maxval(s2(0:65535),.not.one(0:65535,15-ib))
|
||||
if(ipt+ib.gt.2*NN) cycle
|
||||
bitmetrics(ipt+ib,4)=bm
|
||||
enddo
|
||||
|
||||
enddo
|
||||
|
||||
call normalizebmet(bitmetrics(:,1),2*NN)
|
||||
call normalizebmet(bitmetrics(:,2),2*NN)
|
||||
call normalizebmet(bitmetrics(:,3),2*NN)
|
||||
call normalizebmet(bitmetrics(:,4),2*NN)
|
||||
|
||||
scalefac=2.83
|
||||
bitmetrics=scalefac*bitmetrics
|
||||
|
||||
llr=bitmetrics(:,1)
|
||||
endif
|
||||
|
||||
llr=2.0*rxdata/(ss*ss)
|
||||
apmask=0
|
||||
dmin=0.0
|
||||
maxosd=2
|
||||
call decode240_74(llr, Keff, maxosd, norder, apmask, message74, cw, ntype, nharderror, dmin)
|
||||
if(nharderror.ge.0) then
|
||||
n2err=0
|
||||
@ -116,9 +260,10 @@ write(*,'(24i1)') msgbits(51:74)
|
||||
endif
|
||||
enddo
|
||||
! snr2500=db+10*log10(200.0/116.0/2500.0)
|
||||
esn0=db+10*log10(rate)
|
||||
pberr=real(nberr)/(real(ntrials*N))
|
||||
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,e10.3)") db,esn0,ngood,nue,pberr
|
||||
esn0=db+10*log10(rate*iq)
|
||||
pberr=real(nberr)/real(ntrials*N)
|
||||
pserr=real(nsymerr)/real(ntrials*120)
|
||||
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,e10.3)") db,esn0,ngood,nue,pserr
|
||||
|
||||
enddo
|
||||
|
||||
|
@ -996,7 +996,7 @@ contains
|
||||
do i=-ia,ia !Find freq range that has 50% of signal power
|
||||
sum2=sum2 + ss(i)-avg
|
||||
if(sum2.ge.0.25*sum1 .and. xi1.eq.-999.0) then
|
||||
xi1=i - 1 + (sum2-0.25*sum1)/(sum2-sum2z)
|
||||
xi1=i - 1 + (0.25*sum1-sum2)/(sum2-sum2z)
|
||||
endif
|
||||
if(sum2.ge.0.50*sum1 .and. xi2.eq.-999.0) then
|
||||
xi2=i - 1 + (sum2-0.50*sum1)/(sum2-sum2z)
|
||||
|
@ -15,7 +15,7 @@ subroutine foxgen()
|
||||
! common block.
|
||||
|
||||
parameter (NN=79,ND=58,NSPS=4*1920)
|
||||
parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST4-1800 at 48kHz)
|
||||
parameter (NWAVE=(160+2)*134400*4) ! the biggest waveform we generate (FST4-1800 at 48kHz)
|
||||
parameter (NFFT=614400,NH=NFFT/2)
|
||||
character*40 cmsg
|
||||
character*37 msg,msgsent
|
||||
|
@ -2,38 +2,50 @@ program ldpcsim174_91
|
||||
! End to end test of the (174,91)/crc14 encoder and decoder.
|
||||
use packjt77
|
||||
|
||||
integer, parameter:: N=174, K=91, M=N-K
|
||||
character*37 msg,msgsent,msgreceived
|
||||
integer, parameter:: N=174, K=91, M=N-K, NN=58
|
||||
character*37 msg,msgsent
|
||||
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),message91(91)
|
||||
integer*1 message91(91)
|
||||
integer*1 apmask(N), cw(N)
|
||||
integer lmax(1)
|
||||
integer modtype, itone(79), itonecw(58), graymap(0:7)
|
||||
integer nerrtot(0:N),nerrdec(0:N)
|
||||
integer channeltype
|
||||
logical unpk77_success
|
||||
logical one(0:511,0:8)
|
||||
real*8, allocatable :: rxdata(:)
|
||||
real, allocatable :: llr(:)
|
||||
real llr(174),llra(174),llrb(174),llrc(174),llrd(174)
|
||||
real bmeta(174),bmetb(174),bmetc(174),bmetd(174)
|
||||
complex cs(0:7,NN)
|
||||
real s2(0:511)
|
||||
data graymap/0,1,3,2,5,6,4,7/
|
||||
|
||||
nerrtot=0
|
||||
nerrdec=0
|
||||
|
||||
!
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.6) then
|
||||
print*,'Usage: ldpcsim niter ndepth #trials s Keff nbposd'
|
||||
print*,'eg: ldpcsim 10 2 1000 0.84 91 1'
|
||||
print*,'niter: max BP iterations'
|
||||
print*,'ndepth: OSD order'
|
||||
print*,'s: noise sigma; if negative value is ignored and sigma is calculated from SNR.'
|
||||
print*,'nbposd=0, no coupling. nbposd>0, maxsuper=nbposd; nbposd<0, no OSD'
|
||||
if(nargs.ne.7) then
|
||||
print*,'Usage: ldpcsim maxosd norder #trials s Keff modtype channel'
|
||||
print*,'eg: ldpcsim 10 2 1000 0.84 91 1 0'
|
||||
print*,' maxosd<0: do bp only'
|
||||
print*,' maxosd=0: do bp and then call osd once with channel llrs'
|
||||
print*,' maxosd>1: do bp and then call osd maxosd times with saved bp outputs'
|
||||
print*,' norder : osd decoding depth'
|
||||
print*,' s : BPSK only, noise sigma, if s<0 value is ignored and sigma is calculated from SNR.'
|
||||
print*,' Keff : Keff must be in the range [77,91]; Keff-77 is the # of bits to use as CRC.'
|
||||
print*,' modtype : 0, coherent BPSK; 1 noncoherent 8FSK'
|
||||
print*,' channel : 0, AWGN; 1, block Rayleigh (Rayleigh only works with 8FSK!)'
|
||||
return
|
||||
endif
|
||||
call getarg(1,arg)
|
||||
read(arg,*) max_iterations
|
||||
read(arg,*) maxosd
|
||||
call getarg(2,arg)
|
||||
read(arg,*) ndepth
|
||||
read(arg,*) norder
|
||||
call getarg(3,arg)
|
||||
read(arg,*) ntrials
|
||||
call getarg(4,arg)
|
||||
@ -41,16 +53,24 @@ program ldpcsim174_91
|
||||
call getarg(5,arg)
|
||||
read(arg,*) Keff
|
||||
call getarg(6,arg)
|
||||
read(arg,*) nbposd
|
||||
read(arg,*) modtype
|
||||
call getarg(7,arg)
|
||||
read(arg,*) channeltype
|
||||
|
||||
! 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) )
|
||||
allocate ( rxdata(N) )
|
||||
|
||||
one=.false.
|
||||
do i=0,511
|
||||
do j=0,8
|
||||
if(iand(i,2**j).ne.0) one(i,j)=.true.
|
||||
enddo
|
||||
enddo
|
||||
|
||||
msg="K9ABC K1ABC FN20"
|
||||
i3=0
|
||||
@ -65,47 +85,144 @@ program ldpcsim174_91
|
||||
|
||||
call init_random_seed()
|
||||
|
||||
iq=1
|
||||
if(modtype.gt.0) then ! MFSK - get tones
|
||||
i3=-1
|
||||
n3=-1
|
||||
call genft8(msg,i3,n3,msgsent,msgbits,itone)
|
||||
write(*,*) 'message tones'
|
||||
write(*,'(79(i1,1x))') itone
|
||||
itonecw(1:29)=itone(8:36)
|
||||
itonecw(30:58)=itone(44:72)
|
||||
iq=3 ! bits per symbol
|
||||
endif
|
||||
call encode174_91(msgbits,codeword)
|
||||
write(*,*) 'crc14'
|
||||
write(*,'(14i1)') codeword(78:91)
|
||||
write(*,*) 'codeword'
|
||||
write(*,'(22(8i1,1x))') codeword
|
||||
|
||||
write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma psymerr"
|
||||
do idb = 10,-4,-1
|
||||
write(*,*) 'Eb/N0 Es/N0 SNR2500 ngood nundetected sigma psymerr pbiterr'
|
||||
do idb = 20,-4,-1
|
||||
nsymerr=0
|
||||
nbiterr=0
|
||||
db=idb/2.0-1.0
|
||||
sigma=1/sqrt( 2*rate*(10**(db/10.0)) )
|
||||
sigma=1/sqrt( 2*rate*iq*(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
|
||||
if(modtype.eq.0) then
|
||||
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
|
||||
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)
|
||||
else
|
||||
ss=s
|
||||
! noncoherent MFSK
|
||||
do i=1,58
|
||||
do j=0,7
|
||||
if(j.eq.itonecw(i)) then
|
||||
if(channeltype.eq.0) then
|
||||
A=1.0
|
||||
elseif(channeltype.eq.1) then
|
||||
xI=gran()**2 + gran()**2
|
||||
A=sqrt(xI/2)
|
||||
endif
|
||||
cs(j,i)= A + sigma*gran() + cmplx(0,1)*sigma*gran()
|
||||
elseif(j.ne.itonecw(i)) then
|
||||
cs(j,i)= sigma*gran() + cmplx(0,1)*sigma*gran()
|
||||
endif
|
||||
enddo
|
||||
lmax=maxloc(abs(cs(:,i)))
|
||||
if(lmax(1)-1.ne.itonecw(i) ) nsymerr=nsymerr+1
|
||||
enddo
|
||||
do nsym=1,3
|
||||
nt=2**(3*nsym)
|
||||
do ks=1,58,nsym
|
||||
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
|
||||
if(ks.ne.58) then
|
||||
s2(i)=abs(cs(graymap(i1),ks)+cs(graymap(i2),ks+1)+cs(graymap(i3),ks+2))
|
||||
else
|
||||
s2(i)=abs(cs(graymap(i1),ks))
|
||||
endif
|
||||
else
|
||||
print*,"Error - nsym must be 1, 2, or 3."
|
||||
endif
|
||||
enddo
|
||||
|
||||
i32=1+(ks-1)*3
|
||||
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))
|
||||
if(i32+ib .gt.174) cycle
|
||||
if(nsym.eq.1) then
|
||||
bmeta(i32+ib)=bm
|
||||
den=max(maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)), &
|
||||
maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib)))
|
||||
if(den.gt.0.0) then
|
||||
cm=bm/den
|
||||
else ! erase it
|
||||
cm=0.0
|
||||
endif
|
||||
bmetd(i32+ib)=cm
|
||||
elseif(nsym.eq.2) then
|
||||
bmetb(i32+ib)=bm
|
||||
elseif(nsym.eq.3) then
|
||||
bmetc(i32+ib)=bm
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
call normalizebmet(bmeta,174)
|
||||
call normalizebmet(bmetb,174)
|
||||
call normalizebmet(bmetc,174)
|
||||
call normalizebmet(bmetd,174)
|
||||
|
||||
scalefac=2.83
|
||||
llra=scalefac*bmeta
|
||||
llrb=scalefac*bmetb
|
||||
llrc=scalefac*bmetc
|
||||
llrd=scalefac*bmetd
|
||||
|
||||
llr=llrc
|
||||
endif
|
||||
|
||||
llr=2.0*rxdata/(ss*ss)
|
||||
do i=1, 174
|
||||
if(llr(i)*(codeword(i)-0.5).lt.0) nbiterr=nbiterr+1
|
||||
enddo
|
||||
|
||||
nap=0 ! number of AP bits
|
||||
llr(1:nap)=5*(2.0*msgbits(1:nap)-1.0)
|
||||
apmask=0
|
||||
apmask(1:nap)=1
|
||||
call decode174_91(llr,Keff,nbposd,ndepth,apmask,message91,cw,ntype,nharderrors,dmin)
|
||||
call decode174_91(llr,Keff,maxosd,norder,apmask,message91,cw,ntype,nharderrors,dmin)
|
||||
! If the decoder finds a valid codeword, nharderrors will be .ge. 0.
|
||||
if( nharderrors.ge.0 ) then
|
||||
nhw=count(cw.ne.codeword)
|
||||
@ -119,9 +236,12 @@ program ldpcsim174_91
|
||||
nsumerr=nsumerr+nerr
|
||||
enddo
|
||||
|
||||
esn0=db+10.0*log10(rate)
|
||||
pberr=real(nsumerr)/(real(ntrials*N))
|
||||
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,esn0,ngood,nue,ss,pberr
|
||||
esn0=db+10.0*log10(iq*rate) ! iq=3 bits per symbol for 8FSK
|
||||
snr2500=esn0-10.0*log10(2500/6.25)
|
||||
! pberr=real(nsumerr)/(real(ntrials*N))
|
||||
psymerr=real(nsymerr)/(ntrials*174.0/iq)
|
||||
pbiterr=real(nbiterr)/(ntrials*174.0)
|
||||
write(*,"(f4.1,4x,f5.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3,8x,e10.3)") db,esn0,snr2500,ngood,nue,ss,psymerr,pbiterr
|
||||
|
||||
enddo
|
||||
|
||||
@ -132,3 +252,18 @@ program ldpcsim174_91
|
||||
close(23)
|
||||
|
||||
end program ldpcsim174_91
|
||||
|
||||
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
|
||||
|
14
lib/jt9.f90
14
lib/jt9.f90
@ -27,7 +27,7 @@ program jt9
|
||||
logical :: read_files = .true., tx9 = .false., display_help = .false., &
|
||||
bLowSidelobes = .false., nexp_decode_set = .false., &
|
||||
have_ntol = .false.
|
||||
type (option) :: long_options(32) = [ &
|
||||
type (option) :: long_options(33) = [ &
|
||||
option ('help', .false., 'h', 'Display this help message', ''), &
|
||||
option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), &
|
||||
option ('tr-period', .true., 'p', 'Tx/Rx period, default SECONDS=60', &
|
||||
@ -64,6 +64,7 @@ program jt9
|
||||
option ('ft8', .false., '8', 'FT8 mode', ''), &
|
||||
option ('jt9', .false., '9', 'JT9 mode', ''), &
|
||||
option ('qra64', .false., 'q', 'QRA64 mode', ''), &
|
||||
option ('msk144', .false., 'k', 'MSK144 mode', ''), &
|
||||
option ('QSOprog', .true., 'Q', 'QSO progress (0-5), default PROGRESS=1',&
|
||||
'QSOprogress'), &
|
||||
option ('sub-mode', .true., 'b', 'Sub mode, default SUBMODE=A', 'A'), &
|
||||
@ -91,7 +92,7 @@ program jt9
|
||||
TRperiod=60.d0
|
||||
|
||||
do
|
||||
call getopt('hs:e:a:b:r:m:p:d:f:F:w:t:9876543WYqTL:S:H:c:G:x:g:X:Q:', &
|
||||
call getopt('hs:e:a:b:r:m:p:d:f:F:w:t:9876543WYqkTL:S:H:c:G:x:g:X:Q:', &
|
||||
long_options,c,optarg,arglen,stat,offset,remain,.true.)
|
||||
if (stat .ne. 0) then
|
||||
exit
|
||||
@ -129,7 +130,9 @@ program jt9
|
||||
read (optarg(:arglen), *) fhigh
|
||||
case ('q')
|
||||
mode = 164
|
||||
case ('Q')
|
||||
case ('k')
|
||||
mode = 144
|
||||
case ('Q')
|
||||
read (optarg(:arglen), *) nQSOProg
|
||||
case ('3')
|
||||
mode = 66
|
||||
@ -352,7 +355,12 @@ program jt9
|
||||
call multimode_decoder(shared_data%ss,id2a, &
|
||||
shared_data%params,nfsample)
|
||||
cycle
|
||||
|
||||
! MSK144
|
||||
else if (mode .eq. 144) then
|
||||
call decode_msk144(shared_data%id2, shared_data%params, data_dir)
|
||||
endif
|
||||
|
||||
! Normal decoding pass
|
||||
call multimode_decoder(shared_data%ss,shared_data%id2, &
|
||||
shared_data%params,nfsample)
|
||||
|
11
lib/jt9a.f90
11
lib/jt9a.f90
@ -70,8 +70,15 @@ subroutine jt9a()
|
||||
call multimode_decoder(shared_data%ss,id2a,local_params,12000)
|
||||
local_params%nzhsym=50
|
||||
endif
|
||||
! Normal decoding pass
|
||||
call multimode_decoder(shared_data%ss,shared_data%id2,local_params,12000)
|
||||
|
||||
if(local_params%nmode .eq. 144) then
|
||||
! MSK144
|
||||
call decode_msk144(shared_data%id2, shared_data%params, data_dir)
|
||||
else
|
||||
! Normal decoding pass
|
||||
call multimode_decoder(shared_data%ss,shared_data%id2,local_params,12000)
|
||||
endif
|
||||
|
||||
call timer('decoder ',1)
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
subroutine map65_mmdec(nutc,id2,nqd,nsubmode,nfa,nfb,nfqso,ntol,newdat, &
|
||||
nagain,max_drift,ndepth,mycall,hiscall,hisgrid)
|
||||
subroutine map65_mmdec(nutc,id2,nqd,ntrperiod, nsubmode,nfa,nfb,nfqso, &
|
||||
ntol,newdat,nagain,max_drift,ndepth,mycall,hiscall,hisgrid)
|
||||
|
||||
use prog_args
|
||||
use timer_module, only: timer
|
||||
@ -39,7 +39,7 @@ subroutine map65_mmdec(nutc,id2,nqd,nsubmode,nfa,nfb,nfqso,ntol,newdat, &
|
||||
lagain=(nagain.ne.0)
|
||||
bVHF=.true.
|
||||
emedelay=2.5
|
||||
ntrperiod=60
|
||||
! ntrperiod=60
|
||||
|
||||
call timer('dec_q65 ',0)
|
||||
call my_q65%decode(q65_decoded,id2,nqd,nutc,ntrperiod,nsubmode,nfqso, &
|
||||
|
@ -3,6 +3,10 @@ subroutine pctile(x,npts,npct,xpct)
|
||||
real x(npts)
|
||||
real,allocatable :: tmp(:)
|
||||
|
||||
if(npts.lt.0 .or. npct.lt.0 .or. npct.gt.100) then
|
||||
xpct=1.0
|
||||
go to 900
|
||||
endif
|
||||
allocate(tmp(npts))
|
||||
|
||||
tmp=x
|
||||
@ -11,6 +15,7 @@ subroutine pctile(x,npts,npct,xpct)
|
||||
if(j.lt.1) j=1
|
||||
if(j.gt.npts) j=npts
|
||||
xpct=tmp(j)
|
||||
deallocate(tmp)
|
||||
|
||||
return
|
||||
900 return
|
||||
end subroutine pctile
|
||||
|
@ -17,7 +17,6 @@ module q65
|
||||
integer navg(0:1)
|
||||
logical lnewdat
|
||||
real candidates(20,3) !snr, xdt, and f0 of top candidates
|
||||
real, allocatable :: s1raw(:,:) !Symbol spectra, 1/8-symbol steps
|
||||
real, allocatable :: s1(:,:) !Symbol spectra w/suppressed peaks
|
||||
real, allocatable :: s1w(:,:) !Symbol spectra w/suppressed peaks (W3SZ)
|
||||
real, allocatable,save :: s1a(:,:,:) !Cumulative symbol spectra
|
||||
@ -106,8 +105,6 @@ subroutine q65_dec0(iavg,iwave,ntrperiod,nfqso,ntol,lclearave, &
|
||||
allocate(s3(-64:LL-65,63))
|
||||
allocate(ccf1(-ia2:ia2))
|
||||
if(LL.ne.LL0 .or. iz.ne.iz0 .or. jz.ne.jz0 .or. lclearave) then
|
||||
if(allocated(s1raw)) deallocate(s1raw)
|
||||
allocate(s1raw(iz,jz))
|
||||
if(allocated(s1)) deallocate(s1)
|
||||
allocate(s1(iz,jz))
|
||||
if(allocated(s1a)) deallocate(s1a)
|
||||
@ -146,19 +143,6 @@ subroutine q65_dec0(iavg,iwave,ntrperiod,nfqso,ntol,lclearave, &
|
||||
endif
|
||||
|
||||
i0=nint(nfqso/df) !Target QSO frequency
|
||||
ii1=max(1,i0-64)
|
||||
ii2=i0-65+LL
|
||||
call pctile(s1(ii1:ii2,1:jz),ii2-ii1+1*jz,45,base)
|
||||
! s1=s1/base
|
||||
s1raw=s1
|
||||
|
||||
! Apply fast AGC to the symbol spectra
|
||||
! s1max=20.0 !Empirical choice
|
||||
! do j=1,jz !### Maybe wrong way? ###
|
||||
! smax=maxval(s1(ii1:ii2,j))
|
||||
! if(smax.gt.s1max) s1(ii1:ii2,j)=s1(ii1:ii2,j)*s1max/smax
|
||||
! enddo
|
||||
|
||||
dat4=0
|
||||
if(ncw.gt.0 .and. iavg.le.1) then
|
||||
! Try list decoding via "Deep Likelihood".
|
||||
@ -506,12 +490,12 @@ subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,iavg,ipk,jpk, &
|
||||
ia=max(nint(100/df),nint((nfqso-ntol)/df))
|
||||
ib=min(nint(4900/df),nint((nfqso+ntol)/df))
|
||||
endif
|
||||
if(ia.ge.ib) ia=ib-ntol/df !Protect against wacky settings
|
||||
|
||||
do i=ia,ib
|
||||
s1avg(i)=sum(s1(i,1:jz))
|
||||
enddo
|
||||
|
||||
call pctile(s1avg(ia:ib),ib-ia+1,40,base0)
|
||||
ccfbest=0.
|
||||
ibest=0
|
||||
lagpk=0
|
||||
@ -788,7 +772,7 @@ subroutine q65_snr(dat4,dtdec,f0dec,mode_q65,snr2)
|
||||
if(j.ge.1 .and. j.le.jz0) then
|
||||
do i=1,iz0
|
||||
ii=i+mode_q65*itone(k)
|
||||
if(ii.ge.1 .and. ii.le.iz0) spec(i)=spec(i) + s1raw(ii,j)
|
||||
if(ii.ge.1 .and. ii.le.iz0) spec(i)=spec(i) + s1(ii,j)
|
||||
enddo
|
||||
endif
|
||||
enddo
|
||||
|
@ -50,7 +50,7 @@ subroutine sun(y,m,DD,UT,lon,lat,RA,Dec,LST,Az,El,mjd,day)
|
||||
MM = mod(356.0470d0 + 0.9856002585d0 * d + 360000.d0,360.d0)
|
||||
Ls = mod(w+MM+720.0,360.0)
|
||||
|
||||
EE = MM + e*rad*sin(MM/rad) * (1.0 + e*cos(M/rad))
|
||||
EE = MM + e*rad*sin(MM/rad) * (1.0 + e*cos(MM/rad))
|
||||
EE = EE - (EE - e*rad*sin(EE/rad)-MM) / (1.0 - e*cos(EE/rad))
|
||||
|
||||
xv = cos(EE/rad) - e
|
||||
|
@ -146,6 +146,7 @@ unsigned long readwavfile(char *ptr_to_infile, int ntrmin, float *idat, float *q
|
||||
nr=fread(buf2,2,npoints,fp); //Read raw data
|
||||
fclose(fp);
|
||||
if( nr == 0 ) {
|
||||
free(buf2);
|
||||
fprintf(stderr, "No data in file '%s'\n", ptr_to_infile);
|
||||
return 1;
|
||||
}
|
||||
|
@ -446,8 +446,8 @@ auto AD1CCty::lookup (QString const& call) const -> Record
|
||||
if (p != m_->prefixes_.end ())
|
||||
{
|
||||
impl::entity_by_id::iterator e = m_->lookup_entity (call, *p);
|
||||
if ((m_->configuration_->include_WAE_entities () || !e->WAE_only_)
|
||||
&& (!p->exact_ || call.size () == search_prefix.size ()))
|
||||
// always lookup WAE entities, we substitute them later in displaytext.cpp if "Include extra WAE entites" is not selected
|
||||
if (!p->exact_ || call.size () == search_prefix.size ())
|
||||
{
|
||||
return m_->fixup (*p, *e);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ QByteArray LogBook::QSOToADIF (QString const& hisCall, QString const& hisGrid, Q
|
||||
t += " <band:" + QString::number(band.size()) + ">" + band;
|
||||
t += " <freq:" + QString::number(strDialFreq.size()) + ">" + strDialFreq;
|
||||
t += " <station_callsign:" + QString::number(myCall.size()) + ">" + myCall;
|
||||
t += " <my_gridsquare:" + QString::number(myGrid.size()) + ">" + myGrid;
|
||||
if(myGrid!="") t += " <my_gridsquare:" + QString::number(myGrid.size()) + ">" + myGrid;
|
||||
if(txPower!="") t += " <tx_pwr:" + QString::number(txPower.size()) + ">" + txPower;
|
||||
if(comments!="") t += " <comment:" + QString::number(comments.size()) + ">" + comments;
|
||||
if(name!="") t += " <name:" + QString::number(name.size()) + ">" + name;
|
||||
|
@ -140,7 +140,7 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
ndpth=3
|
||||
|
||||
! NB: Frequency of ipk is now shifted to 1000 Hz.
|
||||
call map65_mmdec(nutc,iwave,nqd,nsubmode,nfa,nfb,1000,ntol, &
|
||||
call map65_mmdec(nutc,iwave,nqd,60,nsubmode,nfa,nfb,1000,ntol, &
|
||||
newdat,nagain,max_drift,ndepth,mycall,hiscall0,hisgrid)
|
||||
|
||||
MHz=fcenter
|
||||
|
@ -659,7 +659,7 @@ QModelIndex FrequencyList_v2_101::impl::add (Item f)
|
||||
endInsertRows ();
|
||||
|
||||
// if we added one that had a preferred frequency, unprefer everything else
|
||||
unprefer_all_but(f, row, {Qt::DisplayRole, Qt::CheckStateRole});
|
||||
if (f.preferred_) unprefer_all_but(f, row, {Qt::DisplayRole, Qt::CheckStateRole});
|
||||
|
||||
return index (row, 0);
|
||||
}
|
||||
@ -1335,8 +1335,10 @@ FrequencyList_v2_101::FrequencyItems FrequencyList_v2_101::from_json_file(QFile
|
||||
{
|
||||
throw ReadFileException{tr ("No Frequencies were found")};
|
||||
}
|
||||
int valid_entry_count [[maybe_unused]] = 0;
|
||||
int skipped_entry_count [[maybe_unused]] = 0;
|
||||
#ifdef DUMP_ENTRY_COUNTS
|
||||
int valid_entry_count = 0;
|
||||
int skipped_entry_count = 0;
|
||||
#endif
|
||||
for (auto const &item: arr)
|
||||
{
|
||||
QString mode_s, region_s;
|
||||
@ -1359,13 +1361,21 @@ FrequencyList_v2_101::FrequencyItems FrequencyList_v2_101::from_json_file(QFile
|
||||
freq.isSane())
|
||||
{
|
||||
list.push_back(freq);
|
||||
#ifdef DUMP_ENTRY_COUNTS
|
||||
valid_entry_count++;
|
||||
} else
|
||||
#endif
|
||||
} else {
|
||||
#ifdef DUMP_ENTRY_COUNTS
|
||||
skipped_entry_count++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//MessageBox::information_message(this, tr("Loaded Frequencies from %1").arg(file_name),
|
||||
// tr("Entries Valid/Skipped %1").arg(QString::number(valid_entry_count) + "/" +
|
||||
// QString::number(skipped_entry_count)));
|
||||
|
||||
#ifdef DUMP_ENTRY_COUNTS
|
||||
MessageBox::information_message(this, tr("Loaded Frequencies from %1").arg(file_name),
|
||||
tr("Entries Valid/Skipped %1").arg(QString::number(valid_entry_count) + "/" +
|
||||
QString::number(skipped_entry_count)));
|
||||
#endif
|
||||
return list;
|
||||
}
|
||||
// write JSON format to a file
|
||||
|
@ -13,7 +13,7 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
"QMAP is a wideband receiver for the Q65 protocol, intnded<br />"
|
||||
"primarily for amateur radio EME communication. It works <br />"
|
||||
"in close cooperation with WSJT-X, versions 2.7 and later. <br /><br />"
|
||||
"Copyright 2001-2023 by Joe Taylor, K1JT. Additional <br />"
|
||||
"Copyright 2001-2024 by Joe Taylor, K1JT. Additional <br />"
|
||||
"acknowledgments are contained in the source code.");
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About MAP65</string>
|
||||
<string>About QMAP</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
|
@ -44,10 +44,8 @@ Astro::~Astro()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid,
|
||||
int fQSO, int nsetftx, int ntxFreq, QString azelDir, double xavg)
|
||||
void Astro::astroUpdate(QDateTime t, QString mygrid, QString azelDir, double xavg)
|
||||
{
|
||||
static int ntxFreq0=-99;
|
||||
char cc[300];
|
||||
double azsun,elsun,azmoon,elmoon,azmoondx,elmoondx;
|
||||
double ramoon,decmoon,dgrd,poloffset,xnr;
|
||||
@ -63,32 +61,29 @@ void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid,
|
||||
int isec=sec;
|
||||
double uth=nhr + nmin/60.0 + sec/3600.0;
|
||||
int nfreq=(int)datcom_.fcenter;
|
||||
// if(nfreq<10 or nfreq > 50000) nfreq=144;
|
||||
|
||||
astrosub_(&nyear, &month, &nday, &uth, &nfreq, mygrid.toLatin1(),
|
||||
hisgrid.toLatin1(), &azsun, &elsun, &azmoon, &elmoon,
|
||||
mygrid.toLatin1(), &azsun, &elsun, &azmoon, &elmoon,
|
||||
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00,&ramoon, &decmoon,
|
||||
&dgrd, &poloffset, &xnr, 6, 6);
|
||||
|
||||
datcom_.ndop00=ndop00; //Send self Doppler to decoder, via datcom
|
||||
// qDebug() << "aa" << isec << datcom_.fcenter << nfreq << ndop00;
|
||||
m_ndop00=ndop00;
|
||||
|
||||
snprintf(cc, sizeof(cc),
|
||||
"Az: %6.1f\n"
|
||||
"El: %6.1f\n"
|
||||
"MyDop: %6d\n"
|
||||
"DxAz: %6.1f\n"
|
||||
"DxEl: %6.1f\n"
|
||||
"DxDop: %6d\n"
|
||||
"Dec: %6.1f\n"
|
||||
"SunAz: %6.1f\n"
|
||||
"SunEl: %6.1f\n"
|
||||
"Freq: %6d\n"
|
||||
"Tsky: %6d\n"
|
||||
"MNR: %6.1f\n"
|
||||
"Dgrd: %6.1f",
|
||||
azmoon,elmoon,ndop00,azmoondx,elmoondx,ndop,decmoon,azsun,elsun,
|
||||
"Az: %6.1f\n"
|
||||
"El: %6.1f\n"
|
||||
"SelfDop:%6d\n"
|
||||
"MoonDec:%6.1f\n"
|
||||
"SunAz: %6.1f\n"
|
||||
"SunEl: %6.1f\n"
|
||||
"Freq: %6d\n"
|
||||
"Tsky: %6d\n"
|
||||
"MNR: %6.1f\n"
|
||||
"Dgrd: %6.1f",
|
||||
azmoon,elmoon,ndop00,decmoon,azsun,elsun,
|
||||
nfreq,ntsky,xnr,dgrd);
|
||||
ui->astroTextBrowser->setText(" "+ date + "\nUTC: " + utc + "\n" + cc);
|
||||
ui->astroTextBrowser->setText(" "+ date + "\nUTC: " + utc + "\n" + cc);
|
||||
|
||||
double azOffset=0.0;
|
||||
double elOffset=0.0;
|
||||
@ -154,7 +149,6 @@ void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid,
|
||||
|
||||
// Write pointing data to azel.dat
|
||||
QString fname=azelDir+"/azel.dat";
|
||||
// qDebug() << "aa" << fname << isec << bPointing << azOffset << elOffset;
|
||||
QFile f(fname);
|
||||
if(!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
if(azelDir==m_AzElDir0) return;
|
||||
@ -164,22 +158,18 @@ void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid,
|
||||
mb.exec();
|
||||
return;
|
||||
}
|
||||
int ndiff=0;
|
||||
if(ntxFreq != ntxFreq0) ndiff=1;
|
||||
ntxFreq0=ntxFreq;
|
||||
|
||||
QTextStream out(&f);
|
||||
snprintf(cc,sizeof(cc),"%2.2d:%2.2d:%2.2d,%5.1f,%5.1f,Moon\n"
|
||||
"%2.2d:%2.2d:%2.2d,%5.1f,%5.1f,Sun\n"
|
||||
"%2.2d:%2.2d:%2.2d,%5.1f,%5.1f,Source\n"
|
||||
"%4d,%6d,%6d,Doppler\n"
|
||||
"%3d,%1d,fQSO\n"
|
||||
"%3d,%1d,fQSO2\n",
|
||||
"%3d,%1d,fQSO\n",
|
||||
nhr,nmin,isec,azmoon,elmoon,
|
||||
nhr,nmin,isec,azsun+azOffset,elsun+elOffset,
|
||||
nhr,nmin,isec,0.0,0.0,
|
||||
nfreq,ndop,ndop00,
|
||||
fQSO,nsetftx,
|
||||
ntxFreq,ndiff);
|
||||
datcom_.mousefqso,0);
|
||||
out << cc;
|
||||
f.close();
|
||||
}
|
||||
@ -199,3 +189,7 @@ void Astro::on_cbOnOff_clicked(bool checked)
|
||||
if(checked) ui->cbAutoCycle->setChecked(false);
|
||||
}
|
||||
|
||||
int Astro::getSelfDop()
|
||||
{
|
||||
return m_ndop00;
|
||||
}
|
||||
|
@ -14,9 +14,10 @@ class Astro : public QWidget
|
||||
|
||||
public:
|
||||
explicit Astro (QString const& settings_filename, QWidget *parent = 0);
|
||||
void astroUpdate(QDateTime t, QString mygrid, QString hisgrid,
|
||||
int fQSO, int nsetftx, int ntxFreq, QString azelDir, double xavg);
|
||||
void astroUpdate(QDateTime t, QString mygrid, QString azelDir, double xavg);
|
||||
void setFontSize(int n);
|
||||
int getSelfDop();
|
||||
|
||||
~Astro ();
|
||||
|
||||
private slots:
|
||||
@ -27,6 +28,8 @@ private:
|
||||
Ui::Astro *ui;
|
||||
QString m_settings_filename;
|
||||
QString m_AzElDir0;
|
||||
|
||||
qint32 m_ndop00=0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>441</width>
|
||||
<height>483</height>
|
||||
<width>431</width>
|
||||
<height>393</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -19,7 +19,7 @@
|
||||
<x>269</x>
|
||||
<y>19</y>
|
||||
<width>151</width>
|
||||
<height>431</height>
|
||||
<height>361</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
@ -29,7 +29,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>100</y>
|
||||
<y>70</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
@ -42,7 +42,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>100</y>
|
||||
<y>70</y>
|
||||
<width>40</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
@ -58,7 +58,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>110</x>
|
||||
<y>100</y>
|
||||
<y>70</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
@ -71,7 +71,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>150</y>
|
||||
<y>120</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
@ -84,7 +84,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>50</y>
|
||||
<y>20</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
@ -97,7 +97,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>230</y>
|
||||
<y>180</y>
|
||||
<width>130</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
@ -131,7 +131,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>330</y>
|
||||
<y>260</y>
|
||||
<width>91</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
@ -144,7 +144,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>380</y>
|
||||
<y>300</y>
|
||||
<width>70</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
@ -157,7 +157,7 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>280</y>
|
||||
<y>220</y>
|
||||
<width>130</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
@ -172,28 +172,46 @@
|
||||
<string>Dwell </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>300</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="">
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>10</y>
|
||||
<width>258</width>
|
||||
<height>471</height>
|
||||
<height>371</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="astroTextBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>325</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Courier New</family>
|
||||
@ -207,7 +225,7 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@ -227,7 +245,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@ -241,6 +259,22 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -7,7 +7,7 @@ extern "C" {
|
||||
|
||||
extern struct { //This is "common/datcom/..." in Fortran
|
||||
float d4[2*5760000]; //Raw I/Q data from Linrad
|
||||
float ss[322*NFFT]; //Half-symbol spectra at 0,45,90,135 deg pol
|
||||
float ss[400*NFFT]; //Half-symbol spectra at 0,45,90,135 deg pol
|
||||
float savg[NFFT]; //Avg spectra at 0,45,90,135 deg pol
|
||||
double fcenter; //Center freq from Linrad (MHz)
|
||||
int nutc; //UTC as integer, HHMM
|
||||
@ -17,23 +17,24 @@ extern struct { //This is "common/datcom/..." in Fortran
|
||||
int nagain; //1 ==> decode only at fQSO +/- Tol
|
||||
int ndepth; //How much hinted decoding to do?
|
||||
int ndiskdat; //1 ==> data read from *.iq file
|
||||
int neme; //Hinted decoding tries only for EME calls
|
||||
int ntx60; //Number of seconds transmitted in Q65-60x
|
||||
int newdat; //1 ==> new data, must do long FFT
|
||||
int nfa; //Low decode limit (kHz)
|
||||
int nfb; //High decode limit (kHz)
|
||||
int nfcal; //Frequency correction, for calibration (Hz)
|
||||
int nfshift; //Shift of displayed center freq (kHz)
|
||||
int mcall3; //1 ==> CALL3.TXT has been modified
|
||||
int ntimeout; //Max for timeouts in Messages and BandMap
|
||||
int ntx30a; //Number of seconds transmitted in first half minute , Q65-30x
|
||||
int ntx30b; //Number of seconds transmitted in second half minute, Q65-30x
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int nxant; //1 ==> add 45 deg to measured pol angle
|
||||
int junk_1;
|
||||
int n60; //nsecs%60
|
||||
int junk4; //
|
||||
int nfsample; //Input sample rate
|
||||
int nxpol; //1 if using xpol antennas, 0 otherwise
|
||||
int nmode; //nmode = 10*m_modeQ65 + m_modeJT65
|
||||
int ndop00; //EME Self Doppler
|
||||
int nsave; //Number of s3(64,63) spectra saved
|
||||
int ndop58; //EME Self Doppler at t=58
|
||||
int nBaseSubmode; //Base submode for Q65-60x (aka m_modeQ65)
|
||||
int ndop00; //EME Self Doppler at t=0
|
||||
int nsave; //0=None, 1=SaveDecoded, 2=SaveAll
|
||||
int max_drift; //Maximum Q65 drift: units symbol_rate/TxT
|
||||
int offset; //Offset in Hz
|
||||
int nhsym; //Number of available JT65 half-symbols
|
||||
char mycall[12];
|
||||
char mygrid[6];
|
||||
@ -42,11 +43,12 @@ extern struct { //This is "common/datcom/..." in Fortran
|
||||
char datetime[20];
|
||||
int junk1; //Used to test extent of copy to shared memory
|
||||
int junk2;
|
||||
bool bAlso30; //Process for 30-second submode as well as 60-second
|
||||
} datcom_;
|
||||
|
||||
extern struct { //This is "common/datcom/..." in Fortran
|
||||
float d4[2*5760000]; //Raw I/Q data from Linrad
|
||||
float ss[322*NFFT]; //Half-symbol spectra at 0,45,90,135 deg pol
|
||||
float ss[400*NFFT]; //Half-symbol spectra at 0,45,90,135 deg pol
|
||||
float savg[NFFT]; //Avg spectra at 0,45,90,135 deg pol
|
||||
double fcenter; //Center freq from Linrad (MHz)
|
||||
int nutc; //UTC as integer, HHMM
|
||||
@ -56,23 +58,24 @@ extern struct { //This is "common/datcom/..." in Fortran
|
||||
int nagain; //1 ==> decode only at fQSO +/- Tol
|
||||
int ndepth; //How much hinted decoding to do?
|
||||
int ndiskdat; //1 ==> data read from *.iq file
|
||||
int neme; //Hinted decoding tries only for EME calls
|
||||
int ntx60; //Number of seconds transmitted in Q65-60x
|
||||
int newdat; //1 ==> new data, must do long FFT
|
||||
int nfa; //Low decode limit (kHz)
|
||||
int nfb; //High decode limit (kHz)
|
||||
int nfcal; //Frequency correction, for calibration (Hz)
|
||||
int nfshift; //Shift of displayed center freq (kHz)
|
||||
int mcall3; //1 ==> CALL3.TXT has been modified
|
||||
int ntimeout; //Max for timeouts in Messages and BandMap
|
||||
int ntx30a; //Number of seconds transmitted in first half minute , Q65-30x
|
||||
int ntx30b; //Number of seconds transmitted in second half minute, Q65-30x
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int nxant; //1 ==> add 45 deg to measured pol angle
|
||||
int junk_1;
|
||||
int n60; //nsecs%60
|
||||
int junk4; //
|
||||
int nfsample; //Input sample rate
|
||||
int nxpol; //1 if using xpol antennas, 0 otherwise
|
||||
int nmode; //nmode = 10*m_modeQ65 + m_modeJT65
|
||||
int ndop00; //EME Self Doppler
|
||||
int nsave; //Number of s3(64,63) spectra saved
|
||||
int ndop58; //EME Self Doppler at t=58
|
||||
int nBaseSubmode; //Base submode for Q65-60x (aka m_modeQ65)
|
||||
int ndop00; //EME Self Doppler at t=0
|
||||
int nsave; //0=None, 1=SaveDecoded, 2=SaveAll
|
||||
int max_drift; //Maximum Q65 drift: units symbol_rate/TxT
|
||||
int offset; //Offset in Hz
|
||||
int nhsym; //Number of available JT65 half-symbols
|
||||
char mycall[12];
|
||||
char mygrid[6];
|
||||
@ -81,6 +84,7 @@ extern struct { //This is "common/datcom/..." in Fortran
|
||||
char datetime[20];
|
||||
int junk1; //Used to test extent of copy to shared memory
|
||||
int junk2;
|
||||
bool bAlso30; //Process for 30-second submode as well as 60-second
|
||||
} datcom2_;
|
||||
|
||||
extern struct {
|
||||
@ -88,10 +92,16 @@ extern struct {
|
||||
int ncand; //between QMAP and WSJT-X
|
||||
int nQDecoderDone; //1 for real-time decodes, 2 for data from disk
|
||||
int nWDecoderBusy; //Set to 1 when WSJT-X decoder is busy
|
||||
int nWTransmitting; //Set to 1 when WSJT-X is transmitting
|
||||
char result[50][60]; //Staging area for QMAP decodes
|
||||
int nWTransmitting; //Set to TRperiod when WSJT-X is transmitting
|
||||
int kHzRequested; //Integer kHz dial frequency request to WSJT-X
|
||||
char result[50][64]; //Staging area for QMAP decodes
|
||||
} decodes_;
|
||||
|
||||
extern struct {
|
||||
char revision[22];
|
||||
char saveFileName[120];
|
||||
} savecom_;
|
||||
|
||||
}
|
||||
|
||||
#endif // COMMONS_H
|
||||
|
@ -20,6 +20,8 @@ void DevSetup::initDlg()
|
||||
ui.myCallEntry->setText(m_myCall);
|
||||
ui.myGridEntry->setText(m_myGrid);
|
||||
ui.astroFont->setValue(m_astroFont);
|
||||
ui.myCallColor->addItems({"","red","green","cyan"});
|
||||
ui.myCallColor->setCurrentIndex(m_myCallColor);
|
||||
ui.saveDirEntry->setText(m_saveDir);
|
||||
ui.azelDirEntry->setText(m_azelDir);
|
||||
ui.fCalSpinBox->setValue(m_fCal);
|
||||
@ -38,6 +40,7 @@ void DevSetup::accept()
|
||||
m_myCall=ui.myCallEntry->text();
|
||||
m_myGrid=ui.myGridEntry->text();
|
||||
m_astroFont=ui.astroFont->value();
|
||||
m_myCallColor=ui.myCallColor->currentIndex();
|
||||
m_saveDir=ui.saveDirEntry->text();
|
||||
m_azelDir=ui.azelDirEntry->text();
|
||||
m_fCal=ui.fCalSpinBox->value();
|
||||
|
@ -12,10 +12,6 @@ public:
|
||||
~DevSetup();
|
||||
|
||||
void initDlg();
|
||||
qint32 m_idInt;
|
||||
qint32 m_pttPort;
|
||||
qint32 m_timeout;
|
||||
qint32 m_dPhi;
|
||||
qint32 m_fCal;
|
||||
qint32 m_udpPort;
|
||||
qint32 m_astroFont;
|
||||
@ -25,14 +21,14 @@ public:
|
||||
double m_TxOffset;
|
||||
|
||||
bool m_network;
|
||||
bool m_fs96000;
|
||||
bool m_restartSoundIn;
|
||||
|
||||
int m_myCallColor;
|
||||
|
||||
QString m_myCall;
|
||||
QString m_myGrid;
|
||||
QString m_saveDir;
|
||||
QString m_azelDir;
|
||||
QString m_editorCommand;
|
||||
|
||||
public slots:
|
||||
void accept();
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>250</height>
|
||||
<height>268</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -63,6 +63,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Highlight My Call:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@ -106,6 +113,9 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="myCallColor"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@ -175,10 +185,10 @@
|
||||
<item>
|
||||
<widget class="QSpinBox" name="fCalSpinBox">
|
||||
<property name="minimum">
|
||||
<number>-20000</number>
|
||||
<number>-50000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20000</number>
|
||||
<number>50000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -287,7 +297,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Input from Linrad</string>
|
||||
<string>Input from Linrad or SDR Console</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
@ -312,7 +322,7 @@
|
||||
<number>-50</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
extern qint16 id[2*60*96000];
|
||||
|
||||
void getfile(QString fname, bool xpol, int dbDgrd)
|
||||
void getfile(QString fname, int dbDgrd)
|
||||
{
|
||||
int npts=2*56*96000;
|
||||
if(xpol) npts=2*npts;
|
||||
// int npts=2*56*96000;
|
||||
int npts=2*60*96000;
|
||||
|
||||
// Degrade S/N by dbDgrd dB -- for tests only!!
|
||||
float dgrd=0.0;
|
||||
@ -23,31 +23,32 @@ void getfile(QString fname, bool xpol, int dbDgrd)
|
||||
|
||||
if(fp != NULL) {
|
||||
auto n = fread(&datcom_.fcenter,sizeof(datcom_.fcenter),1,fp);
|
||||
// qDebug() << "aa0" << sizeof(datcom_.fcenter) << n << datcom_.fcenter;
|
||||
n = fread(id,2,npts,fp);
|
||||
Q_UNUSED (n);
|
||||
n=fread(id,2,npts,fp);
|
||||
n=fread(&datcom_.ntx30a,4,1,fp);
|
||||
n=fread(&datcom_.ntx30b,4,1,fp);
|
||||
if(n==0) {
|
||||
datcom_.ntx30a=0;
|
||||
datcom_.ntx30b=0;
|
||||
}
|
||||
int j=0;
|
||||
|
||||
if(dbDgrd<0) {
|
||||
for(int i=0; i<npts; i+=2) {
|
||||
datcom_.d4[j++]=fac*((float)id[i] + dgrd*gran());
|
||||
datcom_.d4[j++]=fac*((float)id[i+1] + dgrd*gran());
|
||||
// if(!xpol) j+=2; //Skip over d4(3,x) and d4(4,x)
|
||||
}
|
||||
} else {
|
||||
for(int i=0; i<npts; i+=2) {
|
||||
datcom_.d4[j++]=(float)id[i];
|
||||
datcom_.d4[j++]=(float)id[i+1];
|
||||
// if(!xpol) j+=2; //Skip over d4(3,x) and d4(4,x)
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
datcom_.ndiskdat=1;
|
||||
int nfreq=(int)datcom_.fcenter;
|
||||
if(nfreq!=144 and nfreq != 432 and nfreq != 1296) datcom_.fcenter=1296.080;
|
||||
int i0=fname.indexOf(".tf2");
|
||||
if(i0<0) i0=fname.indexOf(".iq");
|
||||
if(nfreq!=144 and nfreq != 432 and nfreq != 1296) datcom_.fcenter=1296.090;
|
||||
int i0=fname.indexOf(".iq");
|
||||
datcom_.nutc=0;
|
||||
if(i0>0) {
|
||||
datcom_.nutc=100*fname.mid(i0-4,2).toInt() + fname.mid(i0-2,2).toInt();
|
||||
@ -55,11 +56,9 @@ void getfile(QString fname, bool xpol, int dbDgrd)
|
||||
}
|
||||
}
|
||||
|
||||
void savetf2(QString fname, bool xpol)
|
||||
void save_iq(QString fname)
|
||||
{
|
||||
int npts=2*56*96000;
|
||||
if(xpol) npts=2*npts;
|
||||
|
||||
int npts=2*60*96000;
|
||||
qint16* buf=(qint16*)malloc(2*npts);
|
||||
char name[80];
|
||||
strcpy(name,fname.toLocal8Bit());
|
||||
@ -69,11 +68,11 @@ void savetf2(QString fname, bool xpol)
|
||||
fwrite(&datcom_.fcenter,sizeof(datcom_.fcenter),1,fp);
|
||||
int j=0;
|
||||
for(int i=0; i<npts; i+=2) {
|
||||
buf[i]=(qint16)datcom_.d4[j++];
|
||||
buf[i+1]=(qint16)datcom_.d4[j++];
|
||||
// if(!xpol) j+=2; //Skip over d4(3,x) and d4(4,x)
|
||||
buf[i]=(qint16)qRound(datcom_.d4[j++]);
|
||||
buf[i+1]=(qint16)qRound(datcom_.d4[j++]);
|
||||
}
|
||||
fwrite(buf,2,npts,fp);
|
||||
fwrite(&datcom_.ntx30a,4,2,fp); //Write ntx30a and ntx30b to disk
|
||||
fclose(fp);
|
||||
}
|
||||
free(buf);
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include <QDebug>
|
||||
#include "commons.h"
|
||||
|
||||
void getfile(QString fname, bool xpol, int dbDgrd);
|
||||
void savetf2(QString fname, bool xpol);
|
||||
void getfile(QString fname, int dbDgrd);
|
||||
void save_iq(QString fname);
|
||||
float gran();
|
||||
|
||||
#endif // GETFILE_H
|
||||
|
@ -5,14 +5,14 @@ set (libq65_FSRCS
|
||||
astro.f90
|
||||
astro0.f90
|
||||
astrosub.f90
|
||||
chkstat.f90
|
||||
dcoord.f90
|
||||
decode0.f90
|
||||
dot.f90
|
||||
fchisq0.f90
|
||||
filbig.f90
|
||||
four2a.f90
|
||||
fftbig.f90
|
||||
ftninit.f90
|
||||
ftnquit.f90
|
||||
# ftnquit.f90
|
||||
geocentric.f90
|
||||
getcand2.f90
|
||||
grid2deg.f90
|
||||
@ -24,12 +24,15 @@ set (libq65_FSRCS
|
||||
q65c.f90
|
||||
q65_sync.f90
|
||||
qmapa.f90
|
||||
read_qm.f90
|
||||
recvpkt.f90
|
||||
save_qm.f90
|
||||
sun.f90
|
||||
symspec.f90
|
||||
timf2.f90
|
||||
tm2.f90
|
||||
toxyz.f90
|
||||
zaptx.f90
|
||||
|
||||
f77_wisdom.f
|
||||
)
|
||||
|
40
qmap/libqmap/cfom.f90
Normal file
40
qmap/libqmap/cfom.f90
Normal file
@ -0,0 +1,40 @@
|
||||
subroutine cfom(dd,k0,k,ndop0)
|
||||
|
||||
parameter(NMAX=60*96000)
|
||||
real dd(2,NMAX)
|
||||
complex*16 w,wstep
|
||||
complex*8 c
|
||||
real*8 twopi,dphi
|
||||
logical first
|
||||
data first/.true./
|
||||
save twopi,w,first
|
||||
|
||||
if(first) then
|
||||
twopi=8.d0*atan(1.d0)
|
||||
w=1.d0
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
dop0=0.5*ndop0
|
||||
dphi=dop0*twopi/96000.0
|
||||
wstep=cmplx(cos(dphi),sin(dphi))
|
||||
|
||||
do j=k0+1,k
|
||||
c=w*cmplx(dd(1,j),dd(2,j))
|
||||
dd(1,j)=real(c)
|
||||
dd(2,j)=aimag(c)
|
||||
w=w*wstep
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine cfom
|
||||
|
||||
subroutine zaptx(dd,k0,k)
|
||||
|
||||
parameter(NMAX=60*96000)
|
||||
real dd(2,NMAX)
|
||||
|
||||
dd(1:2,k0+1:k)=0.
|
||||
|
||||
return
|
||||
end subroutine zaptx
|
48
qmap/libqmap/cfom_iq.f90
Normal file
48
qmap/libqmap/cfom_iq.f90
Normal file
@ -0,0 +1,48 @@
|
||||
program cfom_iq
|
||||
|
||||
parameter(NMAX=60*96000)
|
||||
integer*2 id2(2,NMAX)
|
||||
complex*16 c,w,wstep
|
||||
real*8 fcenter,uth8,twopi,dphi
|
||||
character*6 mygrid
|
||||
|
||||
twopi=8.d0*atan(1.d0)
|
||||
open(10,file='231028_0131.iq',status='old',access='stream')
|
||||
open(12,file='231028_0131.cfom',status='unknown',access='stream')
|
||||
|
||||
mygrid='FN20OG'
|
||||
nyear=2023
|
||||
month=10
|
||||
nday=28
|
||||
uth8=01 + 31.d0/60
|
||||
nfreq=1296
|
||||
call astrosub00(nyear,month,nday,uth8,nfreq,mygrid,ndop0)
|
||||
call astrosub00(nyear,month,nday,uth8+1.d0/60.d0,nfreq,mygrid,ndop1)
|
||||
|
||||
print*,ndop0,ndop1
|
||||
|
||||
read(10) fcenter,id2(1:2,1:56*96000)
|
||||
id2(1:2,56*96000+1:NMAX)=0
|
||||
|
||||
dop0=0.5*ndop0
|
||||
dop1=0.5*ndop1
|
||||
j=0
|
||||
w=1.0
|
||||
do isec=1,60
|
||||
dop=dop0 + (isec-0.5)*(dop1-dop0)/60.
|
||||
dphi=dop*twopi/96000.0
|
||||
wstep=cmplx(cos(dphi),sin(dphi))
|
||||
do n=1,96000
|
||||
j=j+1
|
||||
x=id2(1,j)
|
||||
y=id2(2,j)
|
||||
w=w*wstep
|
||||
c=100.d0*w*cmplx(x,y)
|
||||
id2(1,j)=0.01d0*real(c)
|
||||
id2(2,j)=0.01d0*aimag(c)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
write(12) fcenter,id2
|
||||
|
||||
end program cfom_iq
|
28
qmap/libqmap/chkstat.f90
Normal file
28
qmap/libqmap/chkstat.f90
Normal file
@ -0,0 +1,28 @@
|
||||
subroutine chkstat(dd,nhsym,pdb)
|
||||
|
||||
real dd(2,5760000)
|
||||
real pdb(4)
|
||||
integer ia(4),ib(4)
|
||||
logical*1 btx0,btx1
|
||||
|
||||
btx0=.false.
|
||||
btx1=.false.
|
||||
ia(1)=23*96000+1
|
||||
ib(1)=24*96000
|
||||
ia(2)=27*96000+1
|
||||
ib(2)=28*96000
|
||||
ia(3)=53*96000+1
|
||||
ib(3)=54*96000
|
||||
ia(4)=57*96000+1
|
||||
ib(4)=58*96000
|
||||
|
||||
do j=1,4
|
||||
sq=0.
|
||||
do i=ia(j),ib(j)
|
||||
sq=sq + dd(1,i)*dd(1,i) + dd(2,i)*dd(2,i)
|
||||
enddo
|
||||
pdb(j)=db(1.0 + sq/(2.0*96000.0))
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine chkstat
|
@ -3,24 +3,26 @@ subroutine decode0(dd,ss,savg)
|
||||
use timer_module, only: timer
|
||||
parameter (NSMAX=60*96000)
|
||||
|
||||
real*4 dd(2,NSMAX),ss(322,NFFT),savg(NFFT)
|
||||
real*4 dd(2,NSMAX),ss(400,NFFT),savg(NFFT)
|
||||
real*8 fcenter
|
||||
integer offset
|
||||
integer hist(0:32768)
|
||||
logical*1 bAlso30
|
||||
character mycall*12,hiscall*12,mygrid*6,hisgrid*6,datetime*20
|
||||
character mycall0*12,hiscall0*12,hisgrid0*6
|
||||
character*60 result
|
||||
common/decodes/ndecodes,ncand,nQDecoderDone,nWDecoderBusy, &
|
||||
nWTransmitting,result(50)
|
||||
common/npar/fcenter,nutc,fselected,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
|
||||
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
|
||||
ndop00,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
data neme0/-99/
|
||||
character*64 result
|
||||
common/decodes/ndecodes,ncand2,nQDecoderDone,nWDecoderBusy, &
|
||||
nWTransmitting,kHzRequested,result(50)
|
||||
common/npar/fcenter,nutc,fselected,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,ntx60,newdat,nfa,nfb,nfcal,nfshift, &
|
||||
ntx30a,ntx30b,ntol,n60,nCFOM,nfsample,ndop58,nmode, &
|
||||
ndop00,nsave,max_drift,offset,nhsym,mycall,mygrid, &
|
||||
hiscall,hisgrid,datetime,junk1,junk2,bAlso30
|
||||
save
|
||||
|
||||
nQDecoderDone=0
|
||||
if(newdat.ne.0) then
|
||||
nz=96000*nhsym/5.3833
|
||||
nz=96000*nhsym*0.15
|
||||
hist=0
|
||||
do i=1,nz
|
||||
j1=min(abs(dd(1,i)),32768.0)
|
||||
@ -39,13 +41,12 @@ subroutine decode0(dd,ss,savg)
|
||||
mycall0=mycall
|
||||
hiscall0=hiscall
|
||||
hisgrid0=hisgrid
|
||||
neme0=neme
|
||||
|
||||
call timer('qmapa ',0)
|
||||
call qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
|
||||
mousedf,mousefqso,nagain,nfshift,max_drift, &
|
||||
nfcal,mycall,hiscall,hisgrid,nfsample,nmode,ndepth, &
|
||||
datetime,ndop00,fselected)
|
||||
call qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
|
||||
mousedf,mousefqso,nagain,ntx30a,ntx30b,nfshift,max_drift,offset, &
|
||||
nfcal,mycall,hiscall,hisgrid,nfsample,nmode,ndepth, &
|
||||
datetime,ndop00,fselected,bAlso30,nhsym,NCFOM)
|
||||
call timer('qmapa ',1)
|
||||
|
||||
return
|
||||
|
56
qmap/libqmap/fftbig.f90
Normal file
56
qmap/libqmap/fftbig.f90
Normal file
@ -0,0 +1,56 @@
|
||||
subroutine fftbig(dd,nmax)
|
||||
|
||||
! Do the full length FFT of complex data stored in array dd(2,nmax).
|
||||
|
||||
use, intrinsic :: iso_c_binding
|
||||
|
||||
use FFTW3
|
||||
use timer_module, only: timer
|
||||
parameter (MAXFFT1=5376000)
|
||||
real*4 dd(2,nmax) !Input data
|
||||
complex ca(MAXFFT1) !FFT of input
|
||||
real*8 df
|
||||
type(C_PTR) :: plan1 !Pointer to FFTW plan
|
||||
logical first
|
||||
common/cacb/ca
|
||||
equivalence (rfilt,cfilt)
|
||||
data first/.true./,npatience/0/
|
||||
save
|
||||
|
||||
if(nmax.lt.0) go to 900
|
||||
|
||||
nfft1=MAXFFT1
|
||||
if(first) then
|
||||
nflags=FFTW_ESTIMATE
|
||||
if(npatience.eq.1) nflags=FFTW_ESTIMATE_PATIENT
|
||||
if(npatience.eq.2) nflags=FFTW_MEASURE
|
||||
if(npatience.eq.3) nflags=FFTW_PATIENT
|
||||
if(npatience.eq.4) nflags=FFTW_EXHAUSTIVE
|
||||
|
||||
! Plan the big FFT just once
|
||||
call timer('FFTplan ',0)
|
||||
plan1=fftwf_plan_dft_1d(nfft1,ca,ca,+1,nflags)
|
||||
call timer('FFTplan ',1)
|
||||
df=96000.d0/nfft1
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
nz=min(nmax,nfft1)
|
||||
do i=1,nz
|
||||
ca(i)=cmplx(dd(1,i),dd(2,i))
|
||||
enddo
|
||||
|
||||
if(nmax.lt.nfft1) then
|
||||
do i=nmax+1,nfft1
|
||||
ca(i)=0.
|
||||
enddo
|
||||
endif
|
||||
call timer('FFTbig ',0)
|
||||
call fftwf_execute_dft(plan1,ca,ca)
|
||||
call timer('FFTbig ',1)
|
||||
go to 999
|
||||
|
||||
900 call fftwf_destroy_plan(plan1)
|
||||
|
||||
999 return
|
||||
end subroutine fftbig
|
@ -1,123 +0,0 @@
|
||||
subroutine filbig(dd,nmax,f0,newdat,nfsample,c4a,n4)
|
||||
|
||||
! Filter and downsample complex data stored in array dd(2,nmax).
|
||||
! Output is downsampled from 96000 Hz to 1375.125 Hz.
|
||||
|
||||
use timer_module, only: timer
|
||||
parameter (MAXFFT1=5376000,MAXFFT2=77175)
|
||||
real*4 dd(2,nmax) !Input data
|
||||
complex ca(MAXFFT1) !FFT of input
|
||||
complex c4a(MAXFFT2) !Output data
|
||||
real*8 df
|
||||
real halfpulse(8) !Impulse response of filter (one sided)
|
||||
complex cfilt(MAXFFT2) !Filter (complex; imag = 0)
|
||||
real rfilt(MAXFFT2) !Filter (real)
|
||||
integer*8 plan1,plan2,plan3,plan4,plan5
|
||||
logical first
|
||||
include 'fftw3.f'
|
||||
common/cacb/ca
|
||||
equivalence (rfilt,cfilt)
|
||||
data first/.true./,npatience/1/
|
||||
data halfpulse/114.97547150,36.57879257,-20.93789101, &
|
||||
5.89886379,1.59355187,-2.49138308,0.60910773,-0.04248129/
|
||||
save
|
||||
|
||||
if(nmax.lt.0) go to 900
|
||||
|
||||
nfft1=MAXFFT1
|
||||
nfft2=MAXFFT2
|
||||
if(nfsample.eq.95238) then
|
||||
nfft1=5120000
|
||||
nfft2=74088
|
||||
endif
|
||||
|
||||
if(first) then
|
||||
nflags=FFTW_ESTIMATE
|
||||
if(npatience.eq.1) nflags=FFTW_ESTIMATE_PATIENT
|
||||
if(npatience.eq.2) nflags=FFTW_MEASURE
|
||||
if(npatience.eq.3) nflags=FFTW_PATIENT
|
||||
if(npatience.eq.4) nflags=FFTW_EXHAUSTIVE
|
||||
|
||||
! Plan the FFTs just once
|
||||
call timer('FFTplans ',0)
|
||||
call sfftw_plan_dft_1d(plan1,nfft1,ca,ca,FFTW_BACKWARD,nflags)
|
||||
call sfftw_plan_dft_1d(plan3,nfft2,c4a,c4a,FFTW_FORWARD,nflags)
|
||||
call sfftw_plan_dft_1d(plan5,nfft2,cfilt,cfilt,FFTW_BACKWARD,nflags)
|
||||
call timer('FFTplans ',1)
|
||||
|
||||
! Convert impulse response to filter function
|
||||
do i=1,nfft2
|
||||
cfilt(i)=0.
|
||||
enddo
|
||||
fac=0.00625/nfft1
|
||||
cfilt(1)=fac*halfpulse(1)
|
||||
do i=2,8
|
||||
cfilt(i)=fac*halfpulse(i)
|
||||
cfilt(nfft2+2-i)=fac*halfpulse(i)
|
||||
enddo
|
||||
call sfftw_execute(plan5)
|
||||
|
||||
base=cfilt(nfft2/2+1)
|
||||
do i=1,nfft2
|
||||
rfilt(i)=real(cfilt(i))-base
|
||||
enddo
|
||||
|
||||
df=96000.d0/nfft1
|
||||
if(nfsample.eq.95238) df=95238.1d0/nfft1
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
! When new data comes along, we need to compute a new "big FFT"
|
||||
! If we just have a new f0, continue with the existing ca.
|
||||
|
||||
if(newdat.ne.0 .or. sum(abs(ca)).eq.0.0) then !### Test on ca should be unnecessary?
|
||||
nz=min(nmax,nfft1)
|
||||
do i=1,nz
|
||||
ca(i)=cmplx(dd(1,i),dd(2,i))
|
||||
enddo
|
||||
|
||||
if(nmax.lt.nfft1) then
|
||||
do i=nmax+1,nfft1
|
||||
ca(i)=0.
|
||||
enddo
|
||||
endif
|
||||
call timer('FFTbig ',0)
|
||||
call sfftw_execute(plan1)
|
||||
call timer('FFTbig ',1)
|
||||
!### newdat=0
|
||||
endif
|
||||
|
||||
! NB: f0 is the frequency at which we want our filter centered.
|
||||
! i0 is the bin number in ca closest to f0.
|
||||
|
||||
i0=nint(f0/df) + 1
|
||||
nh=nfft2/2
|
||||
do i=1,nh !Copy data into c4a
|
||||
j=i0+i-1 !and apply the filter function
|
||||
if(j.ge.1 .and. j.le.nfft1) then
|
||||
c4a(i)=rfilt(i)*ca(j)
|
||||
else
|
||||
c4a(i)=0.
|
||||
endif
|
||||
enddo
|
||||
do i=nh+1,nfft2
|
||||
j=i0+i-1-nfft2
|
||||
if(j.lt.1) j=j+nfft1
|
||||
c4a(i)=rfilt(i)*ca(j)
|
||||
enddo
|
||||
|
||||
! Do the short reverse transform, to go back to time domain.
|
||||
call timer('FFTsmall',0)
|
||||
call sfftw_execute(plan3)
|
||||
call timer('FFTsmall',1)
|
||||
n4=min(nmax/64,nfft2)
|
||||
go to 999
|
||||
|
||||
900 call sfftw_destroy_plan(plan1)
|
||||
call sfftw_destroy_plan(plan2)
|
||||
call sfftw_destroy_plan(plan3)
|
||||
call sfftw_destroy_plan(plan4)
|
||||
call sfftw_destroy_plan(plan5)
|
||||
|
||||
999 return
|
||||
end subroutine filbig
|
@ -1,115 +0,0 @@
|
||||
subroutine four2a(a,nfft,ndim,isign,iform)
|
||||
|
||||
! IFORM = 1, 0 or -1, as data is
|
||||
! complex, real, or the first half of a complex array. Transform
|
||||
! values are returned in array DATA. They are complex, real, or
|
||||
! the first half of a complex array, as IFORM = 1, -1 or 0.
|
||||
|
||||
! The transform of a real array (IFORM = 0) dimensioned N(1) by N(2)
|
||||
! by ... will be returned in the same array, now considered to
|
||||
! be complex of dimensions N(1)/2+1 by N(2) by .... Note that if
|
||||
! IFORM = 0 or -1, N(1) must be even, and enough room must be
|
||||
! reserved. The missing values may be obtained by complex conjugation.
|
||||
|
||||
! The reverse transformation of a half complex array dimensioned
|
||||
! N(1)/2+1 by N(2) by ..., is accomplished by setting IFORM
|
||||
! to -1. In the N array, N(1) must be the true N(1), not N(1)/2+1.
|
||||
! The transform will be real and returned to the input array.
|
||||
|
||||
! This version of four2a makes calls to the FFTW library to do the
|
||||
! actual computations.
|
||||
|
||||
use fftw3
|
||||
parameter (NPMAX=2100) !Max numberf of stored plans
|
||||
parameter (NSMALL=16384) !Max size of "small" FFTs
|
||||
complex a(nfft+1) !Array to be transformed
|
||||
complex aa(NSMALL) !Local copy of "small" a()
|
||||
integer nn(NPMAX),ns(NPMAX),nf(NPMAX) !Params of stored plans
|
||||
integer*8 nl(NPMAX),nloc !More params of plans
|
||||
integer*8 plan(NPMAX) !Pointers to stored plans
|
||||
logical found_plan
|
||||
data nplan/0/ !Number of stored plans
|
||||
common/patience/npatience,nthreads !Patience and threads for FFTW plans
|
||||
save plan,nplan,nn,ns,nf,nl
|
||||
|
||||
if(nfft.lt.0) go to 999
|
||||
|
||||
nloc=loc(a)
|
||||
|
||||
found_plan = .false.
|
||||
!$omp critical(four2a_setup)
|
||||
do i=1,nplan
|
||||
if(nfft.eq.nn(i) .and. isign.eq.ns(i) .and. &
|
||||
iform.eq.nf(i) .and. nloc.eq.nl(i)) then
|
||||
found_plan = .true.
|
||||
exit
|
||||
end if
|
||||
enddo
|
||||
|
||||
if(i.ge.NPMAX) stop 'Too many FFTW plans requested.'
|
||||
|
||||
if (.not. found_plan) then
|
||||
nplan=nplan+1
|
||||
i=nplan
|
||||
|
||||
nn(i)=nfft
|
||||
ns(i)=isign
|
||||
nf(i)=iform
|
||||
nl(i)=nloc
|
||||
|
||||
! Planning: FFTW_ESTIMATE, FFTW_ESTIMATE_PATIENT, FFTW_MEASURE,
|
||||
! FFTW_PATIENT, FFTW_EXHAUSTIVE
|
||||
nflags=FFTW_ESTIMATE
|
||||
if(npatience.eq.1) nflags=FFTW_ESTIMATE_PATIENT
|
||||
if(npatience.eq.2) nflags=FFTW_MEASURE
|
||||
if(npatience.eq.3) nflags=FFTW_PATIENT
|
||||
if(npatience.eq.4) nflags=FFTW_EXHAUSTIVE
|
||||
|
||||
if(nfft.le.NSMALL) then
|
||||
jz=nfft
|
||||
if(iform.eq.0) jz=nfft/2
|
||||
aa(1:jz)=a(1:jz)
|
||||
endif
|
||||
|
||||
!$omp critical(fftw) ! serialize non thread-safe FFTW3 calls
|
||||
if(isign.eq.-1 .and. iform.eq.1) then
|
||||
call sfftw_plan_dft_1d(plan(i),nfft,a,a,FFTW_FORWARD,nflags)
|
||||
else if(isign.eq.1 .and. iform.eq.1) then
|
||||
call sfftw_plan_dft_1d(plan(i),nfft,a,a,FFTW_BACKWARD,nflags)
|
||||
else if(isign.eq.-1 .and. iform.eq.0) then
|
||||
call sfftw_plan_dft_r2c_1d(plan(i),nfft,a,a,nflags)
|
||||
else if(isign.eq.1 .and. iform.eq.-1) then
|
||||
call sfftw_plan_dft_c2r_1d(plan(i),nfft,a,a,nflags)
|
||||
else
|
||||
stop 'Unsupported request in four2a'
|
||||
endif
|
||||
!$omp end critical(fftw)
|
||||
|
||||
if(nfft.le.NSMALL) then
|
||||
jz=nfft
|
||||
if(iform.eq.0) jz=nfft/2
|
||||
a(1:jz)=aa(1:jz)
|
||||
endif
|
||||
end if
|
||||
!$omp end critical(four2a_setup)
|
||||
|
||||
call sfftw_execute(plan(i))
|
||||
return
|
||||
|
||||
999 continue
|
||||
|
||||
!$omp critical(four2a)
|
||||
do i=1,nplan
|
||||
! The test is only to silence a compiler warning:
|
||||
if(ndim.ne.-999) then
|
||||
!$omp critical(fftw) ! serialize non thread-safe FFTW3 calls
|
||||
call sfftw_destroy_plan(plan(i))
|
||||
!$omp end critical(fftw)
|
||||
end if
|
||||
enddo
|
||||
|
||||
nplan=0
|
||||
!$omp end critical(four2a)
|
||||
|
||||
return
|
||||
end subroutine four2a
|
@ -3,10 +3,8 @@ subroutine ftninit
|
||||
use timer_impl, only: init_timer !,fini_timer, limtrace
|
||||
use, intrinsic :: iso_c_binding, only: C_NULL_CHAR
|
||||
use FFTW3
|
||||
! character*(*) appd
|
||||
character*1 appd
|
||||
character addpfx*8
|
||||
character wisfile*256
|
||||
common/pfxcom/addpfx
|
||||
|
||||
lu=8
|
||||
@ -17,17 +15,6 @@ subroutine ftninit
|
||||
open(12,file=appd//'/all_qmap.txt',status='unknown',position='append')
|
||||
open(17,file=appd//'/red.dat',status='unknown')
|
||||
open(19,file=appd//'/livecq.txt',status='unknown')
|
||||
open(71,file=appd//'/fort.71',status='unknown')
|
||||
open(72,file=appd//'/fort.72',status='unknown')
|
||||
open(73,file=appd//'/fort.73',status='unknown')
|
||||
|
||||
! Import FFTW wisdom, if available:
|
||||
iret=fftwf_init_threads() !Initialize FFTW threading
|
||||
! Default to 1 thread, but use nthreads for the big ones
|
||||
call fftwf_plan_with_nthreads(1)
|
||||
! Import FFTW wisdom, if available
|
||||
wisfile=trim(appd)//'/m65_wisdom.dat'// C_NULL_CHAR
|
||||
iret=fftwf_import_wisdom_from_filename(wisfile)
|
||||
|
||||
return
|
||||
end subroutine ftninit
|
||||
|
@ -2,7 +2,7 @@ subroutine ftnquit
|
||||
|
||||
! Destroy the FFTW plans
|
||||
call four2a(a,-1,1,1,1)
|
||||
call filbig(id,-1,f0,newdat,nfsample,c4a,n4)
|
||||
call fftbig(id,-1)
|
||||
|
||||
return
|
||||
end subroutine ftnquit
|
||||
|
@ -1,4 +1,5 @@
|
||||
subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,cand,ncand)
|
||||
subroutine getcand2(ss,savg0,nts_q65,nagain,nhsym,ntx30a,ntx30b, &
|
||||
ntol,f0_selected,bAlso30,cand,ncand2)
|
||||
|
||||
! Get candidates for Q65 decodes, based on presence of sync tone.
|
||||
|
||||
@ -6,15 +7,18 @@ subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,cand,ncand)
|
||||
real :: snr !Relative S/N of sync detection
|
||||
real :: f !Freq of sync tone, 0 to 96000 Hz
|
||||
real :: xdt !DT of matching sync pattern, -1.0 to +4.0 s
|
||||
integer :: ntrperiod !60 for Q65-60x, 30 for Q65-30x
|
||||
integer :: iseq !0 for first half-minute, 1 for second half
|
||||
end type candidate
|
||||
|
||||
parameter (NFFT=32768) !FFTs done in symspec()
|
||||
parameter (MAX_CANDIDATES=50)
|
||||
type(candidate) :: cand(MAX_CANDIDATES)
|
||||
real ss(322,NFFT) !Symbol spectra
|
||||
real ss(400,NFFT) !Symbol spectra
|
||||
real savg0(NFFT),savg(NFFT) !Average spectra over whole Rx sequence
|
||||
integer ipk1(1) !Peak index of local portion of spectrum
|
||||
logical sync_ok !True if sync pattern is present
|
||||
logical*1 bAlso30
|
||||
data nseg/16/,npct/40/
|
||||
|
||||
savg=savg0 !Save the original spectrum
|
||||
@ -35,7 +39,7 @@ subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,cand,ncand)
|
||||
nguard=5 !Guard range in bins
|
||||
i1=1
|
||||
i2=NFFT-nbw-nguard
|
||||
if(nagain.eq.1) then
|
||||
if(nagain.ge.1) then
|
||||
i1=nint((1000.0*f0_selected-ntol)/df)
|
||||
i2=nint((1000.0*f0_selected+ntol)/df)
|
||||
endif
|
||||
@ -48,20 +52,65 @@ subroutine getcand2(ss,savg0,nts_q65,nagain,ntol,f0_selected,cand,ncand)
|
||||
i0=ipk1(1) + i - 1 !Index of local peak in savg()
|
||||
fpk=0.001*i0*df !Frequency of peak (kHz)
|
||||
! Check to see if sync tone is present.
|
||||
call q65_sync(ss,i0,nts_q65,sync_ok,snr_sync,xdt)
|
||||
if(.not.sync_ok) cycle
|
||||
|
||||
ntrperiod=60
|
||||
iseq=0
|
||||
if(nhsym.ge.200) then
|
||||
call q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr_sync,xdt)
|
||||
if(sync_ok) then
|
||||
! Sync tone is present, we have a candidate for decoding
|
||||
j=j+1
|
||||
cand(j)%f=fpk
|
||||
cand(j)%xdt=xdt
|
||||
cand(j)%snr=snr_sync
|
||||
ia=max(1,min(i,i0-nguard))
|
||||
ib=min(i0+nbw+nguard,32768)
|
||||
savg(ia:ib)=0.
|
||||
if(j.ge.MAX_CANDIDATES) exit
|
||||
j=j+1
|
||||
cand(j)%f=fpk
|
||||
cand(j)%xdt=xdt
|
||||
cand(j)%snr=snr_sync
|
||||
cand(j)%ntrperiod=ntrperiod
|
||||
cand(j)%iseq=iseq
|
||||
ia=max(1,min(i,i0-nguard))
|
||||
ib=min(i0+nbw+nguard,32768)
|
||||
savg(ia:ib)=0.
|
||||
if(j.ge.MAX_CANDIDATES) exit
|
||||
endif
|
||||
endif
|
||||
|
||||
if(.not.bAlso30) cycle
|
||||
ntrperiod=30
|
||||
|
||||
if(nhsym.le.200 .and. ntx30a.le.5) then
|
||||
call q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr_sync,xdt)
|
||||
if(sync_ok) then
|
||||
! Sync tone is present, we have a candidate for decoding
|
||||
j=j+1
|
||||
cand(j)%f=fpk
|
||||
cand(j)%xdt=xdt
|
||||
cand(j)%snr=snr_sync
|
||||
cand(j)%ntrperiod=ntrperiod
|
||||
cand(j)%iseq=iseq
|
||||
ia=max(1,min(i,i0-nguard))
|
||||
ib=min(i0+nbw+nguard,32768)
|
||||
savg(ia:ib)=0.
|
||||
if(j.ge.MAX_CANDIDATES) exit
|
||||
endif
|
||||
endif
|
||||
|
||||
iseq=1
|
||||
if(nhsym.ge.330 .and. ntx30b.le.5) then
|
||||
call q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr_sync,xdt)
|
||||
if(sync_ok) then
|
||||
! Sync tone is present, we have a candidate for decoding
|
||||
j=j+1
|
||||
cand(j)%f=fpk
|
||||
cand(j)%xdt=xdt
|
||||
cand(j)%snr=snr_sync
|
||||
cand(j)%ntrperiod=ntrperiod
|
||||
cand(j)%iseq=iseq
|
||||
ia=max(1,min(i,i0-nguard))
|
||||
ib=min(i0+nbw+nguard,32768)
|
||||
savg(ia:ib)=0.
|
||||
if(j.ge.MAX_CANDIDATES) exit
|
||||
endif
|
||||
endif
|
||||
|
||||
enddo
|
||||
ncand=j !Total number of candidates found
|
||||
ncand2=j !Total number of candidates found
|
||||
|
||||
return
|
||||
end subroutine getcand2
|
||||
|
@ -1 +1 @@
|
||||
parameter(NJUNK=40)
|
||||
parameter(NJUNK=42)
|
||||
|
@ -1,38 +1,42 @@
|
||||
subroutine q65_sync(ss,i0,nts_q65,sync_ok,snr,xdt)
|
||||
subroutine q65_sync(ss,i0,nts_q65,ntrperiod,iseq,sync_ok,snr,xdt)
|
||||
|
||||
! Test for presence of Q65 sync tone
|
||||
|
||||
parameter (NFFT=32768)
|
||||
parameter (LAGMAX=33)
|
||||
real ss(322,NFFT) !Symbol spectra
|
||||
real ss(400,NFFT) !Symbol spectra
|
||||
real ccf(0:LAGMAX) !The WSJT "blue curve", peak at DT
|
||||
logical sync_ok
|
||||
logical first
|
||||
integer isync(22),ipk(1)
|
||||
integer isync0(22),isync(22),ipk(1)
|
||||
|
||||
! Q65 sync symbols
|
||||
data isync/1,9,12,13,15,22,23,26,27,33,35,38,46,50,55,60,62,66,69,74,76,85/
|
||||
data first/.true./
|
||||
save first,isync
|
||||
data isync0/1,9,12,13,15,22,23,26,27,33,35,38,46,50,55,60,62,66,69,74,76,85/
|
||||
|
||||
tstep=2048.0/11025.0 !0.185760 s: 0.5*tsym_jt65, 0.3096*tsym_q65
|
||||
if(first) then
|
||||
fac=0.6/tstep !3.230
|
||||
do i=1,22 !Expand the Q65 sync stride
|
||||
isync(i)=nint((isync(i)-1)*fac) + 1
|
||||
enddo
|
||||
first=.false.
|
||||
endif
|
||||
sync_ok=.false.
|
||||
! if(ntrperiod.ne.60) return
|
||||
|
||||
tstep=0.15 !0.5*tsym_Q65-30x, 0.25*tsys_Q65-60x
|
||||
nfac=4
|
||||
if(ntrperiod.eq.30) nfac=2
|
||||
do i=1,22 !Expand sync stride for Q65-60x
|
||||
isync(i)=nfac*(isync0(i)-1) + 1
|
||||
enddo
|
||||
|
||||
m=nts_q65/2
|
||||
if(ntrperiod.eq.30) m=nts_q65/4
|
||||
i1=max(1,i0-m)
|
||||
i2=min(NFFT,i0+m)
|
||||
ccf=0.
|
||||
do lag=0,LAGMAX !Search over range of DT
|
||||
do j=1,22 !Test for Q65 sync
|
||||
k=isync(j) + lag
|
||||
ccf(lag)=ccf(lag) + sum(ss(k,i1:i2)) + sum(ss(k+1,i1:i2)) &
|
||||
+ sum(ss(k+2,i1:i2))
|
||||
k=isync(j) + lag + iseq*200
|
||||
if(k.ge.400) cycle
|
||||
if(ntrperiod.eq.60) then
|
||||
ccf(lag)=ccf(lag) + sum(ss(k,i1:i2)) + sum(ss(k+1,i1:i2)) &
|
||||
+ sum(ss(k+2,i1:i2)) + sum(ss(k+3,i1:i2))
|
||||
else
|
||||
ccf(lag)=ccf(lag) + sum(ss(k,i1:i2)) + sum(ss(k+1,i1:i2))
|
||||
endif
|
||||
! Q: Should we use weighted sums, perhaps a Lorentzian peak?
|
||||
enddo
|
||||
enddo
|
||||
@ -40,16 +44,20 @@ subroutine q65_sync(ss,i0,nts_q65,sync_ok,snr,xdt)
|
||||
ipk=maxloc(ccf)
|
||||
lagbest=ipk(1)-1
|
||||
xdt=lagbest*tstep - 1.0
|
||||
if(ntrperiod.eq.30) xd=xdt+0.6 !Why ???
|
||||
|
||||
xsum=0.
|
||||
sq=0.
|
||||
nsum=0
|
||||
fpk=0.001*i0*96000.0/32768.0 + 32.0
|
||||
do i=0,lagmax !Compute ave and rms of "blue curve"
|
||||
if(abs(i-lagbest).gt.2) then
|
||||
xsum=xsum+ccf(i)
|
||||
sq=sq+ccf(i)**2
|
||||
nsum=nsum+1
|
||||
endif
|
||||
! write(40,3040) i,i*tstep-1.0,ccf(i),fpk
|
||||
!3040 format(i5,3f8.2)
|
||||
enddo
|
||||
ave=xsum/nsum
|
||||
rms=sqrt(sq/nsum - ave*ave)
|
||||
|
@ -1,6 +1,7 @@
|
||||
subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
mycall0,hiscall0,hisgrid,mode_q65,f0,fqso,nkhz_center, newdat,nagain, &
|
||||
max_drift,ndepth,datetime,ndop00,idec)
|
||||
ntrperiod,iseq,mycall0,hiscall0,hisgrid,mode_q65,f0,fqso,nkhz_center, &
|
||||
newdat,nagain,bClickDecode,max_drift,offset,ndepth,datetime,nCFOM, &
|
||||
ndop00,nhsym,idec)
|
||||
|
||||
! This routine provides an interface between QMAP and the Q65 decoder
|
||||
! in WSJT-X. All arguments are input data obtained from the QMAP GUI.
|
||||
@ -8,27 +9,34 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
! in common/cacb. Decoded messages are sent back to the GUI.
|
||||
|
||||
use q65_decode
|
||||
use wavhdr
|
||||
use timer_module, only: timer
|
||||
|
||||
parameter (MAXFFT1=5376000) !56*96000
|
||||
parameter (MAXFFT2=336000) !56*6000 (downsampled by 1/16)
|
||||
parameter (NMAX=60*12000)
|
||||
parameter (RAD=57.2957795)
|
||||
type(hdr) h
|
||||
integer*2 iwave(60*12000)
|
||||
integer offset
|
||||
complex ca(MAXFFT1) !FFT of raw I/Q data from Linrad
|
||||
complex cx(0:MAXFFT2-1),cz(0:MAXFFT2)
|
||||
real*8 fcenter,freq0,freq1
|
||||
logical*1 bClickDecode
|
||||
character*12 mycall0,hiscall0
|
||||
character*12 mycall,hiscall
|
||||
character*6 hisgrid
|
||||
character*4 grid4
|
||||
character*60 result
|
||||
character*20 datetime
|
||||
common/decodes/ndecodes,ncand,nQDecoderDone,nWDecoderBusy, &
|
||||
nWTransmitting,result(50)
|
||||
character*3 csubmode
|
||||
character*17 fname
|
||||
character*64 result,ctmp
|
||||
character*20 datetime,datetime1
|
||||
common/decodes/ndecodes,ncand2,nQDecoderDone,nWDecoderBusy, &
|
||||
nWTransmitting,kHzRequested,result(50)
|
||||
common/cacb/ca
|
||||
data ifile/0/
|
||||
save
|
||||
|
||||
|
||||
if(mycall0(1:1).ne.' ') mycall=mycall0
|
||||
if(hiscall0(1:1).ne.' ') hiscall=hiscall0
|
||||
if(hisgrid(1:4).ne.' ') grid4=hisgrid(1:4)
|
||||
@ -36,26 +44,18 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
! Find best frequency from sync_dat, the "orange sync curve".
|
||||
df3=96000.0/32768.0
|
||||
ipk=(1000.0*f0-1.0)/df3
|
||||
if(nagain.ge.2) ipk = nint(1000.0*(fqso-nkhz_center+48.0)/df3)
|
||||
nfft1=MAXFFT1
|
||||
nfft2=MAXFFT2
|
||||
df=96000.0/NFFT1
|
||||
if(nfsample.eq.95238) then
|
||||
nfft1=5120000
|
||||
nfft2=322560
|
||||
df=96000.0/nfft1
|
||||
endif
|
||||
nh=nfft2/2
|
||||
f_mouse=1000.0*(fqso+48.0) + mousedf
|
||||
k0=nint((ipk*df3-1000.0)/df)
|
||||
if(nagain.eq.1) k0=nint((f_mouse-1000.0)/df)
|
||||
|
||||
if(k0.lt.nh .or. k0.gt.MAXFFT1-nfft2+1) go to 900
|
||||
fac=1.0/nfft2
|
||||
cx(0:nfft2-1)=ca(k0:k0+nfft2-1)
|
||||
cx=fac*cx
|
||||
cx(0:nfft2-1)=fac*ca(k0:k0+nfft2-1)
|
||||
|
||||
! Here cx is frequency-domain data around the selected
|
||||
! QSO frequency, taken from the full-length FFT computed in filbig().
|
||||
! QSO frequency, taken from the full-length FFT computed in fftbig().
|
||||
! Values for fsample, nfft1, nfft2, df, and the downsampled data rate
|
||||
! are as follows:
|
||||
|
||||
@ -88,19 +88,65 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
nsubmode=mode_q65-1
|
||||
nfa=990 !Tight limits around ipk for the wideband decode
|
||||
nfb=1010
|
||||
if(nagain.eq.1) then !For nagain=1, use limits of +/- ntol
|
||||
if(nagain.ge.1) then !For nagain>=1, use limits of +/- ntol
|
||||
nfa=max(100,1000-ntol)
|
||||
nfb=min(2500,1000+ntol)
|
||||
endif
|
||||
nsnr0=-99 !Default snr for no decode
|
||||
|
||||
if(iseq.eq.1) iwave(1:360000)=iwave(360001:720000)
|
||||
|
||||
csubmode(1:2)='60'
|
||||
csubmode(3:3)=char(ichar('A')+nsubmode)
|
||||
nhhmmss=100*nutc
|
||||
nutc1=nutc
|
||||
datetime(12:13)='00'
|
||||
datetime1=datetime
|
||||
if(ntrperiod.eq.30) then
|
||||
csubmode(1:2)='30'
|
||||
nhhmmss=100*nutc + iseq*30
|
||||
nutc1=nhhmmss
|
||||
if(iseq.eq.1) datetime1(12:13)='30'
|
||||
endif
|
||||
|
||||
if(nagain.ge.2) then
|
||||
ifile=ifile+1
|
||||
write(fname,1000) ifile
|
||||
1000 format('000000_',i6.6,'.wav')
|
||||
open(27,file=fname,status='unknown',access='stream')
|
||||
if(nagain.eq.2) then
|
||||
h=default_header(12000,60*12000)
|
||||
ia=1
|
||||
ib=60*12000
|
||||
else if(nagain.eq.3) then
|
||||
h=default_header(12000,30*12000)
|
||||
ia=1
|
||||
ib=30*12000
|
||||
else
|
||||
h=default_header(12000,30*12000)
|
||||
ia=30*12000 + 1
|
||||
ib=60*12000
|
||||
endif
|
||||
write(27) h,iwave(ia:ib)
|
||||
close(27)
|
||||
go to 900
|
||||
endif
|
||||
|
||||
! NB: Frequency of ipk is now shifted to 1000 Hz.
|
||||
call map65_mmdec(nutc,iwave,nqd,nsubmode,nfa,nfb,1000,ntol, &
|
||||
newdat,nagain,max_drift,ndepth,mycall,hiscall,hisgrid)
|
||||
MHz=fcenter
|
||||
nagain2=0
|
||||
call map65_mmdec(nutc1,iwave,nqd,ntrperiod,nsubmode,nfa,nfb,1000,ntol, &
|
||||
newdat,nagain2,max_drift,ndepth,mycall,hiscall,hisgrid)
|
||||
MHz=fcenter
|
||||
freq0=MHz + 0.001d0*ikhz
|
||||
|
||||
if(nsnr0.gt.-99) then
|
||||
|
||||
do i=1,ndecodes !Check for dupes
|
||||
i1=index(result(i)(42:),trim(msg0))
|
||||
! If this is a dupe, don't save it again:
|
||||
if(i1.gt.0 .and. (.not.bClickDecode .or. nhsym.eq.390)) go to 800
|
||||
enddo
|
||||
|
||||
nq65df=nint(1000*(0.001*k0*df+nkhz_center-48.0+1.000-1.27046-ikhz))-nfcal
|
||||
nq65df=nq65df + nfreq0 - 1000
|
||||
ikhz1=ikhz
|
||||
@ -109,15 +155,16 @@ subroutine q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
if(ndf.lt.-500) ikhz1=ikhz + (nq65df-500)/1000
|
||||
ndf=nq65df - 1000*(ikhz1-ikhz)
|
||||
freq1=freq0 + 0.001d0*(ikhz1-ikhz)
|
||||
ndecodes=ndecodes+1
|
||||
frx=0.001*k0*df+nkhz_center-48.0+1.0 - 0.001*nfcal
|
||||
fsked=frx - 0.001*ndop00/2.0 - 1.5
|
||||
write(result(ndecodes),1120) nutc,frx,fsked,xdt0,nsnr0,trim(msg0)
|
||||
1120 format(i4.4,f9.3,f7.1,f7.2,i5,2x,a)
|
||||
write(12,1130) datetime,trim(result(ndecodes)(5:))
|
||||
1130 format(a11,1x,a)
|
||||
fsked=frx - 0.001*ndop00/2.0 - 0.001*offset
|
||||
ctmp=csubmode//' '//trim(msg0)
|
||||
ndecodes=min(ndecodes+1,50)
|
||||
write(result(ndecodes),1120) nhhmmss,frx,fsked,xdt0,nsnr0,trim(ctmp)
|
||||
1120 format(i6.6,f9.3,f7.1,f7.2,i5,2x,a)
|
||||
write(12,1130) datetime1,trim(result(ndecodes)(7:))
|
||||
1130 format(a13,1x,a)
|
||||
result(ndecodes)=trim(result(ndecodes))//char(0)
|
||||
idec=0
|
||||
800 idec=0
|
||||
endif
|
||||
|
||||
900 flush(12)
|
||||
|
@ -1,4 +1,4 @@
|
||||
subroutine q65c(itimer)
|
||||
subroutine q65c
|
||||
|
||||
use timer_module, only: timer
|
||||
use timer_impl, only: fini_timer !, limtrace
|
||||
@ -10,42 +10,96 @@ subroutine q65c(itimer)
|
||||
parameter (NFFT=32768)
|
||||
include 'njunk.f90'
|
||||
real*8 fcenter
|
||||
real*4 pdb(4)
|
||||
integer nparams0(NJUNK+3),nparams(NJUNK+3)
|
||||
! integer values(8)
|
||||
logical first
|
||||
logical*1 bAlso30
|
||||
character*120 fname
|
||||
character*22 revision
|
||||
character*12 mycall,hiscall
|
||||
character*6 mygrid,hisgrid
|
||||
character*20 datetime
|
||||
|
||||
common/datcom2/dd(2,5760000),ss(322,NFFT),savg(NFFT),nparams0
|
||||
|
||||
character*64 result
|
||||
common/decodes/ndecodes,ncand2,nQDecoderDone,nWDecoderBusy, &
|
||||
nWTransmitting,kHzRequested,result(50)
|
||||
common/datcom2/dd(2,5760000),ss(400,NFFT),savg(NFFT),nparams0
|
||||
common/savecom/revision,fname
|
||||
!### REMEMBER that /npar/ is not updated until nparams=nparams0 is executed. ###
|
||||
common/npar/fcenter,nutc,fselected,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,neme,newdat,nfcal,nfshift, &
|
||||
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
|
||||
ndop00,nsave,max_nhsym,mycall,mygrid,hiscall,hisgrid, &
|
||||
datetime,junk1,junk2
|
||||
ndepth,ndiskdat,ntx60,newdat,nn1,nn2,nfcal,nfshift, &
|
||||
ntx30a,ntx30b,ntol,n60,nCFOM,nfsample,ndop58,nmode, &
|
||||
ndop00,nsave,nn3,nn4,nhsym,mycall,mygrid,hiscall,hisgrid, &
|
||||
datetime,junk1,junk2,bAlso30
|
||||
equivalence (nparams,fcenter)
|
||||
data first/.true./
|
||||
save first
|
||||
|
||||
nparams=nparams0 !Copy parameters into common/npar/
|
||||
if(itimer.ne.0) then
|
||||
call timer('decode0 ',101)
|
||||
call fini_timer
|
||||
return
|
||||
endif
|
||||
|
||||
datetime(18:20)=':00'
|
||||
datetime(12:)='00 '
|
||||
npatience=1
|
||||
newdat=1 !Always on ??
|
||||
|
||||
! write(*,3001) 'aa',newdat,nagain,nfa,nfb,ntol,fselected
|
||||
!3001 format(a2,5i6,f10.3)
|
||||
! write(*,3001) 'bb',newdat,nagain,nfa,nfb,ntol,fselected
|
||||
if(ndiskdat.eq.1) then
|
||||
call chkstat(dd,nhsym,pdb)
|
||||
if((abs(pdb(1)-pdb(2)).gt.3.0 .and. pdb(1).gt.1.0) .or. &
|
||||
pdb(1).lt.1.0) ntx30a=20 !Tx 1st half
|
||||
if((abs(pdb(3)-pdb(4)).gt.3.0 .and. pdb(3).gt.1.0) .or. &
|
||||
pdb(3).lt.1.0) ntx30b=20 !Tx 2nd half
|
||||
if(pdb(4).lt.0.04) then
|
||||
ntx30a=0 !Older 56s files have no Tx
|
||||
ntx30b=0 !Older 56s files have no Tx
|
||||
endif
|
||||
endif
|
||||
|
||||
if(ntx30a.gt.5) then
|
||||
dd(1:2,1:30*96000)=0.
|
||||
ss(1:200,1:NFFT)=0.
|
||||
do i=1,NFFT
|
||||
savg(i)=sum(ss(201:400,i))
|
||||
enddo
|
||||
endif
|
||||
if(ntx30b.gt.5) then
|
||||
dd(1:2,30*96000+1:60*96000)=0.
|
||||
ss(201:400,1:NFFT)=0.
|
||||
do i=1,NFFT
|
||||
savg(i)=sum(ss(1:200,i))
|
||||
enddo
|
||||
endif
|
||||
|
||||
if(nhsym.gt.200 .and. ntx30b.gt.5) go to 10
|
||||
call timer('decode0 ',0)
|
||||
call decode0(dd,ss,savg)
|
||||
call timer('decode0 ',1)
|
||||
|
||||
10 continue
|
||||
! call date_and_time(VALUES=values)
|
||||
! n60b=values(7)
|
||||
! nd=n60b-n60
|
||||
! if(nd.lt.0) nd=nd+60
|
||||
! write(*,3002) nutc,nagain,nhsym,n60,n60b,nd,ntx30a,ntx30b,ndecodes, &
|
||||
! nsave,revision
|
||||
!3002 format('A',i5.4,i3,i5,7i4,1x,a22)
|
||||
! flush(6)
|
||||
|
||||
if(ndiskdat.eq.0) then
|
||||
if(nhsym.eq.390 .and. &
|
||||
(nsave.eq.2 .or. (nsave.eq.1 .and. ndecodes.ge.1))) then
|
||||
call save_qm(fname,revision,mycall,mygrid,dd,ntx30a,ntx30b,fcenter, &
|
||||
nutc,ndop00,ndop58)
|
||||
endif
|
||||
endif
|
||||
|
||||
return
|
||||
end subroutine q65c
|
||||
|
||||
subroutine all_done
|
||||
|
||||
use timer_module, only: timer
|
||||
use timer_impl, only: fini_timer
|
||||
|
||||
call timer('decode0 ',101)
|
||||
call fini_timer
|
||||
|
||||
return
|
||||
end subroutine all_done
|
||||
|
@ -1,6 +1,7 @@
|
||||
subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
|
||||
mousedf,mousefqso,nagain,nfshift,max_drift,nfcal,mycall, &
|
||||
hiscall,hisgrid,nfsample,nmode,ndepth,datetime,ndop00,fselected)
|
||||
mousedf,mousefqso,nagain,ntx30a,ntx30b,nfshift,max_drift,offset, &
|
||||
nfcal,mycall,hiscall,hisgrid,nfsample,nBaseSubmode,ndepth, &
|
||||
datetime,ndop00,fselected,bAlso30,nhsym,nCFOM)
|
||||
|
||||
! Processes timf2 data received from Linrad to find and decode Q65 signals.
|
||||
|
||||
@ -10,64 +11,109 @@ subroutine qmapa(dd,ss,savg,newdat,nutc,fcenter,ntol,nfa,nfb, &
|
||||
real :: snr !Relative S/N of sync detection
|
||||
real :: f !Freq of sync tone, 0 to 96000 Hz
|
||||
real :: xdt !DT of matching sync pattern, -1.0 to +4.0 s
|
||||
integer :: ntrperiod !60 for Q65-60x, 30 for Q65-30x
|
||||
integer :: iseq !0 for first half-minute, 1 for second half
|
||||
end type candidate
|
||||
|
||||
type good_decode
|
||||
real :: f !Freq of sync tone, 0 to 96000 Hz
|
||||
integer :: ntrperiod !60 for Q65-60x, 30 for Q65-30x
|
||||
integer :: iseq !0 for first half-minute, 1 for second half
|
||||
end type good_decode
|
||||
|
||||
parameter (NFFT=32768) !Size of FFTs done in symspec()
|
||||
parameter (MAX_CANDIDATES=50)
|
||||
parameter (MAXMSG=1000) !Size of decoded message list
|
||||
parameter (NSMAX=60*96000)
|
||||
complex cx(NSMAX/64) !Data at 1378.125 samples/s
|
||||
real dd(2,NSMAX) !I/Q data from Linrad
|
||||
real ss(322,NFFT) !Symbol spectra
|
||||
real ss(400,NFFT) !Symbol spectra
|
||||
real savg(NFFT) !Average spectrum
|
||||
real*8 fcenter !Center RF frequency, MHz
|
||||
real*8 fcenter !Center RF frequency, MHz
|
||||
logical*1 bAlso30,bClickDecode
|
||||
character mycall*12,hiscall*12,hisgrid*6
|
||||
type(candidate) :: cand(MAX_CANDIDATES)
|
||||
character*60 result
|
||||
type(good_decode) found(MAX_CANDIDATES)
|
||||
character*64 result
|
||||
character*20 datetime
|
||||
common/decodes/ndecodes,ncand,nQDecoderDone,nWDecoderBusy, &
|
||||
nWTransmitting,result(50)
|
||||
common/decodes/ndecodes,ncand2,nQDecoderDone,nWDecoderBusy, &
|
||||
nWTransmitting,kHzRequested,result(50)
|
||||
save
|
||||
|
||||
tsec0=sec_midn()
|
||||
if(nagain.eq.1) ndepth=3 !Use full depth for click-to-decode
|
||||
if(nagain.ge.1) ndepth=3 !Use full depth for click-to-decode
|
||||
nkhz_center=nint(1000.0*(fcenter-int(fcenter)))
|
||||
mfa=nfa-nkhz_center+48
|
||||
mfb=nfb-nkhz_center+48
|
||||
mode_q65=nmode/10
|
||||
mode_q65=nBaseSubmode
|
||||
nts_q65=2**(mode_q65-1) !Q65 tone separation factor
|
||||
f0_selected=fselected - nkhz_center + 48.0
|
||||
|
||||
call timer('get_cand',0)
|
||||
! Get a list of decoding candidates
|
||||
call getcand2(ss,savg,nts_q65,nagain,ntol,f0_selected,cand,ncand)
|
||||
call timer('get_cand',1)
|
||||
if(nagain.le.1) then
|
||||
call timer('get_cand',0)
|
||||
! Get a list of decoding candidates
|
||||
call getcand2(ss,savg,nts_q65,nagain,nhsym,ntx30a,ntx30b,ntol, &
|
||||
f0_selected,bAlso30,cand,ncand2)
|
||||
call timer('get_cand',1)
|
||||
endif
|
||||
|
||||
nwrite_q65=0
|
||||
df=96000.0/NFFT !df = 96000/NFFT = 2.930 Hz
|
||||
if(nfsample.eq.95238) df=95238.1/NFFT
|
||||
ftol=0.010 !Frequency tolerance (kHz)
|
||||
foffset=0.001*(1270 + nfcal) !Offset from sync tone, plus CAL
|
||||
fqso=mousefqso + foffset - 0.5*(nfa+nfb) + nfshift !fqso at baseband (khz)
|
||||
nqd=0
|
||||
nagain2=0
|
||||
bClickDecode=(nagain.ge.1)
|
||||
|
||||
call timer('filbig ',0)
|
||||
call filbig(dd,NSMAX,f0,newdat,nfsample,cx,n5) !Do the full-length FFT
|
||||
call timer('filbig ',1)
|
||||
call timer('fftbig ',0)
|
||||
call fftbig(dd,NSMAX) !Do the full-length FFT
|
||||
call timer('fftbig ',1)
|
||||
|
||||
do icand=1,ncand !Attempt to decode each candidate
|
||||
if(nagain.ge.2) then
|
||||
ncand2=1
|
||||
fqso=fselected
|
||||
endif
|
||||
|
||||
do icand=1,ncand2 !Attempt to decode each candidate
|
||||
tsec=sec_midn() - tsec0
|
||||
if(ndiskdat.eq.0) then
|
||||
! No more realtime decode attempts if it's nearly too late, already
|
||||
if(nhsym.eq.130 .and. tsec.gt.6.0) exit
|
||||
if(nhsym.eq.200 .and. tsec.gt.10.0) exit
|
||||
if(nhsym.eq.330 .and. tsec.gt.6.0) exit
|
||||
if(nhsym.eq.390 .and. tsec.gt.16.0) exit
|
||||
endif
|
||||
f0=cand(icand)%f
|
||||
freq=cand(icand)%f+nkhz_center-48.0-1.27046
|
||||
ntrperiod=cand(icand)%ntrperiod
|
||||
iseq=cand(icand)%iseq
|
||||
|
||||
if(nagain.eq.0) then
|
||||
! Skip this candidate if we already decoded it.
|
||||
do j=1,ndecodes
|
||||
if(abs(f0-found(j)%f).lt.0.005 .and. &
|
||||
ntrperiod.eq.found(j)%ntrperiod .and. &
|
||||
iseq.eq.found(j)%iseq) go to 10
|
||||
enddo
|
||||
endif
|
||||
|
||||
mode_q65_tmp=mode_q65
|
||||
if(ntrperiod.eq.30) mode_q65_tmp=max(1,mode_q65-1)
|
||||
freq=f0+nkhz_center-48.0-1.27046
|
||||
ikhz=nint(freq)
|
||||
idec=-1
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
mycall,hiscall,hisgrid,mode_q65,f0,fqso,nkhz_center,newdat, &
|
||||
nagain2,max_drift,ndepth,datetime,ndop00,idec)
|
||||
call q65b(nutc,nqd,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
ntrperiod,iseq,mycall,hiscall,hisgrid,mode_q65_tmp,f0,fqso, &
|
||||
nkhz_center,newdat,nagain,bClickDecode,max_drift,offset, &
|
||||
ndepth,datetime,nCFOM,ndop00,nhsym,idec)
|
||||
call timer('q65b ',1)
|
||||
tsec=sec_midn() - tsec0
|
||||
if(tsec.gt.30.0) exit !Don't start another decode attempt after t=30 s.
|
||||
if(bClickDecode .and. idec.ge.0) exit
|
||||
if(idec.ge.0) then
|
||||
! Save some details on good decodes, to avoid duplicated effort
|
||||
found(ndecodes)%f=f0
|
||||
found(ndecodes)%ntrperiod=ntrperiod
|
||||
found(ndecodes)%iseq=iseq
|
||||
end if
|
||||
10 continue
|
||||
enddo ! icand
|
||||
|
||||
return
|
||||
|
44
qmap/libqmap/read_qm.f90
Normal file
44
qmap/libqmap/read_qm.f90
Normal file
@ -0,0 +1,44 @@
|
||||
subroutine read_qm(fname,iret)
|
||||
|
||||
include 'njunk.f90'
|
||||
parameter(NMAX=60*96000,NFFT=32768)
|
||||
character*(*) fname
|
||||
character prog_id*24,mycall*12,mygrid*6
|
||||
real*8 fcenter
|
||||
integer nxtra(15) !For possible future additions
|
||||
integer*1 id1(2,NMAX)
|
||||
common/datcom/dd(2,5760000),ss(400,NFFT),savg(NFFT), &
|
||||
fcenter,nutc,fselected,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,ntx60,newdat,nn1,nn2,nfcal,nfshift, &
|
||||
ntx30a,ntx30b !...
|
||||
|
||||
open(28,file=trim(fname),status='old',access='stream',err=900)
|
||||
read(28,end=910) prog_id,mycall,mygrid,fcenter,nutc,ntx30a, &
|
||||
ntx30b,ndop00,ndop58,ia,ib,fac0,nxtra
|
||||
iret=3
|
||||
if(ib.eq.NMAX/2) iret=1
|
||||
if(ia.eq.NMAX/2+1) iret=2
|
||||
fac=1.0
|
||||
if(fac0.gt.0.0) fac=1.0/fac0
|
||||
id1=0
|
||||
read(28,end=910) id1(1:2,ia:ib)
|
||||
dd=0.
|
||||
dd(1:2,ia:ib)=fac*id1(1:2,ia:ib) !Boost back to previous level
|
||||
go to 999
|
||||
|
||||
900 iret=-1; go to 999
|
||||
910 iret=-2
|
||||
|
||||
999 close(28)
|
||||
|
||||
! sq1=0.
|
||||
! sq2=0.
|
||||
! NH=NMAX/2
|
||||
! do i=1,NMAX
|
||||
! if(i.le.NH) sq1=sq1 + dd(1,i)*dd(1,i) + dd(2,i)*dd(2,i)
|
||||
! if(i.gt.NH) sq2=sq2 + dd(1,i)*dd(1,i) + dd(2,i)*dd(2,i)
|
||||
! enddo
|
||||
! print*,'B',sqrt(sq1/NMAX),sqrt(sq2/NMAX)
|
||||
|
||||
return
|
||||
end subroutine read_qm
|
@ -1,4 +1,4 @@
|
||||
subroutine recvpkt(nsam,nblock2,userx_no,k,buf4,buf8)
|
||||
subroutine recvpkt(nsam,nblock2,userx_no,k,buf4,buf8,ndb)
|
||||
|
||||
! Reformat timf2 data from Linrad and stuff data into r*4 array dd().
|
||||
|
||||
@ -11,11 +11,12 @@ subroutine recvpkt(nsam,nblock2,userx_no,k,buf4,buf8)
|
||||
integer*2 jd(4),kd(2),nblock2
|
||||
real*4 yd(2)
|
||||
real*8 fcenter
|
||||
common/datcom/dd(2,5760000),ss(322,NFFT),savg(NFFT),fcenter,nutc, &
|
||||
common/datcom/dd(2,5760000),ss(400,NFFT),savg(NFFT),fcenter,nutc, &
|
||||
junk(NJUNK)
|
||||
equivalence (kd,d4)
|
||||
equivalence (jd,d8,yd)
|
||||
|
||||
gain=10.0**(0.05*ndb)
|
||||
if(nblock2.eq.-9999) nblock2=-9998 !Silence a compiler warning
|
||||
if(nsam.eq.-1) then
|
||||
! Move data from the UDP packet buffer into array dd().
|
||||
@ -23,15 +24,15 @@ subroutine recvpkt(nsam,nblock2,userx_no,k,buf4,buf8)
|
||||
do i=1,174 !One RF channel, r*4 data
|
||||
k=k+1
|
||||
d8=buf8(i)
|
||||
dd(1,k)=yd(1)
|
||||
dd(2,k)=yd(2)
|
||||
dd(1,k)=yd(1)*gain
|
||||
dd(2,k)=yd(2)*gain
|
||||
enddo
|
||||
else if(userx_no.eq.1) then
|
||||
do i=1,348 !One RF channel, i*2 data
|
||||
k=k+1
|
||||
d4=buf4(i)
|
||||
dd(1,k)=kd(1)
|
||||
dd(2,k)=kd(2)
|
||||
dd(1,k)=kd(1)*gain
|
||||
dd(2,k)=kd(2)*gain
|
||||
enddo
|
||||
endif
|
||||
else
|
||||
@ -39,12 +40,12 @@ subroutine recvpkt(nsam,nblock2,userx_no,k,buf4,buf8)
|
||||
do i=1,nsam !One RF channel, r*4 data
|
||||
k=k+1
|
||||
d4=buf4(i)
|
||||
dd(1,k)=kd(1)
|
||||
dd(2,k)=kd(2)
|
||||
dd(1,k)=kd(1)*gain
|
||||
dd(2,k)=kd(2)*gain
|
||||
|
||||
k=k+1
|
||||
dd(1,k)=kd(1)
|
||||
dd(2,k)=kd(2)
|
||||
dd(1,k)=kd(1)*gain
|
||||
dd(2,k)=kd(2)*gain
|
||||
enddo
|
||||
endif
|
||||
endif
|
||||
|
63
qmap/libqmap/save_qm.f90
Normal file
63
qmap/libqmap/save_qm.f90
Normal file
@ -0,0 +1,63 @@
|
||||
subroutine save_qm(fname,revision,mycall,mygrid,dd,ntx30a,ntx30b,fcenter, &
|
||||
nutc,ndop00,ndop58)
|
||||
|
||||
parameter(NMAX=60*96000)
|
||||
character*120 fname
|
||||
character*22 revision
|
||||
character*12 mycall
|
||||
character*6 mygrid
|
||||
real*4 dd(2,NMAX)
|
||||
real*8 fcenter
|
||||
integer nxtra(15) !For possible future additions
|
||||
integer*1,allocatable :: id1(:,:)
|
||||
|
||||
ia=1
|
||||
ib=NMAX
|
||||
if(ntx30a.gt.5) ia=NMAX/2+1
|
||||
if(ntx30b.gt.5) ib=NMAX/2
|
||||
|
||||
sq=0.
|
||||
do i=ia,ib
|
||||
x=dd(1,i)
|
||||
y=dd(2,i)
|
||||
sq=sq + x*x + y*y
|
||||
enddo
|
||||
nsum=2*(ib-ia+1)
|
||||
rms=sqrt(sq/nsum)
|
||||
|
||||
nbad=0
|
||||
dmax=0.
|
||||
fac0=10.0/rms
|
||||
allocate(id1(1:2,1:NMAX))
|
||||
|
||||
do i=ia,ib
|
||||
x=fac0*dd(1,i)
|
||||
y=fac0*dd(2,i)
|
||||
ax=abs(x)
|
||||
ay=abs(y)
|
||||
dmax=max(dmax,ax,ay)
|
||||
if(ax.gt.127.0) then
|
||||
x=0.
|
||||
nbad=nbad+1
|
||||
endif
|
||||
if(ay.gt.127.0) then
|
||||
y=0.
|
||||
nbad=nbad+1
|
||||
endif
|
||||
id1(1,i)=nint(x)
|
||||
id1(2,i)=nint(y)
|
||||
enddo
|
||||
if(ia.gt.30*96000) id1(1:2,1:ia-1)=0
|
||||
if(ib.eq.30*96000) id1(1:2,ib+1:60*96000)=0
|
||||
|
||||
open(29,file=trim(fname),status='unknown',access='stream')
|
||||
nxtra=0
|
||||
write(29) revision//' ',mycall,mygrid,fcenter,nutc,ntx30a,ntx30b, &
|
||||
ndop00,ndop58,ia,ib,fac0,nxtra !Write header to disk
|
||||
write(29) id1(1:2,ia:ib) !Write 8-bit data to disk
|
||||
close(29)
|
||||
deallocate(id1)
|
||||
|
||||
return
|
||||
end subroutine save_qm
|
||||
|
@ -8,7 +8,7 @@ subroutine symspec(k,ndiskdat,nb,nbslider,nfsample, &
|
||||
! pxdb power in x channel (0-60 dB)
|
||||
! ssz5a polarized spectrum, for waterfall display
|
||||
! nkhz integer kHz portion of center frequency, e.g., 125 for 144.125
|
||||
! ihsym index number of this half-symbol (1-322)
|
||||
! ihsym index number of this half-symbol (1-400)
|
||||
! nzap number of samples zero'ed by noise blanker
|
||||
|
||||
include 'njunk.f90'
|
||||
@ -16,9 +16,9 @@ subroutine symspec(k,ndiskdat,nb,nbslider,nfsample, &
|
||||
parameter (NFFT=32768) !Length of FFTs
|
||||
real*8 ts,hsym
|
||||
real*8 fcenter
|
||||
common/datcom/dd(2,5760000),ss(322,NFFT),savg(NFFT),fcenter,nutc, &
|
||||
common/datcom/dd(2,5760000),ss(400,NFFT),savg(NFFT),fcenter,nutc, &
|
||||
junk(NJUNK)
|
||||
real*4 ssz5a(NFFT),w(NFFT),w2a(NFFT),w2b(NFFT)
|
||||
real*4 ssz5a(NFFT),w(NFFT)
|
||||
complex cx(NFFT)
|
||||
complex cx00(NFFT)
|
||||
complex cx0(0:1023),cx1(0:1023)
|
||||
@ -26,31 +26,24 @@ subroutine symspec(k,ndiskdat,nb,nbslider,nfsample, &
|
||||
data rms/999.0/,k0/99999999/,nadjx/0/,nadjy/0/
|
||||
save
|
||||
|
||||
nfast=1
|
||||
hsym=0.15d0*96000.d0 !Samples per Q65-30x half-symbol
|
||||
npts=2*hsym !Full Q65-30x symbol
|
||||
if(k.gt.5751000) go to 999
|
||||
if(k.lt.NFFT) then
|
||||
if(k.lt.npts) then
|
||||
ihsym=0
|
||||
go to 999 !Wait for enough samples to start
|
||||
endif
|
||||
if(k0.eq.99999999) then
|
||||
pi=4.0*atan(1.0)
|
||||
w2a=0.
|
||||
w2b=0.
|
||||
do i=1,NFFT
|
||||
w(i)=(sin(i*pi/NFFT))**2 !Window for nfast=1
|
||||
if(i.lt.17833) w2a(i)=(sin(i*pi/17832.925))**2 !Window a for nfast=2
|
||||
j=i-8916
|
||||
if(j.gt.0 .and. j.lt.17833) w2b(i)=(sin(j*pi/17832.925))**2 ! b
|
||||
enddo
|
||||
w2a=sqrt(2.0)*w2a
|
||||
w2b=sqrt(2.0)*w2b
|
||||
! pi=4.0*atan(1.0)
|
||||
! do i=1,NFFT
|
||||
! w(i)=(sin(i*pi/NFFT))**2 !Window
|
||||
! enddo
|
||||
w=0.7 !Flat window
|
||||
endif
|
||||
|
||||
hsym=2048.d0*96000.d0/11025.d0 !Samples per JT65 half-symbol
|
||||
if(nfsample.eq.95238) hsym=2048.d0*95238.1d0/11025.d0
|
||||
|
||||
if(k.lt.k0) then
|
||||
ts=1.d0 - hsym
|
||||
ss=0.
|
||||
savg=0.
|
||||
ihsym=0
|
||||
k1=0
|
||||
@ -85,12 +78,9 @@ subroutine symspec(k,ndiskdat,nb,nbslider,nfsample, &
|
||||
k1=k1+kstep
|
||||
enddo
|
||||
|
||||
npts=NFFT !Samples used in each half-symbol FFT
|
||||
|
||||
ts=ts+hsym
|
||||
ja=ts !Index of first sample
|
||||
jb=ja+npts-1 !Last sample
|
||||
|
||||
i=0
|
||||
fac=0.0002
|
||||
do j=ja,jb !Copy data into cx
|
||||
@ -99,11 +89,12 @@ subroutine symspec(k,ndiskdat,nb,nbslider,nfsample, &
|
||||
i=i+1
|
||||
cx(i)=fac*cmplx(x1,x2)
|
||||
enddo
|
||||
cx(npts+1:)=0.
|
||||
|
||||
if(nzap/178.lt.50 .and. (ndiskdat.eq.0 .or. ihsym.lt.280)) then
|
||||
nsum=nblks*kstep - nzap
|
||||
if(nsum.le.0) nsum=1
|
||||
rmsx=sqrt(0.5*px/nsum)
|
||||
rmsx=sqrt(px/nsum)
|
||||
rms=rmsx
|
||||
endif
|
||||
pxdb=0.
|
||||
@ -112,31 +103,21 @@ subroutine symspec(k,ndiskdat,nb,nbslider,nfsample, &
|
||||
|
||||
cx00=cx
|
||||
|
||||
do mm=1,nfast
|
||||
ihsym=ihsym+1
|
||||
if(nfast.eq.1) then
|
||||
cx=w*cx00 !Apply window for 2nd forward FFT
|
||||
else
|
||||
if(mm.eq.1) then
|
||||
cx=w2a*cx00
|
||||
else
|
||||
cx=w2b*cx00
|
||||
endif
|
||||
endif
|
||||
|
||||
call four2a(cx,NFFT,1,1,1) !Second forward FFT (X)
|
||||
|
||||
n=min(322,ihsym)
|
||||
do i=1,NFFT
|
||||
sx=real(cx(i))**2 + aimag(cx(i))**2
|
||||
ss(n,i)=sx ! Pol = 0
|
||||
savg(i)=savg(i) + sx
|
||||
ssz5a(i)=sx
|
||||
enddo
|
||||
ihsym=ihsym+1
|
||||
cx=w*cx00 !Apply window for 2nd forward FFT
|
||||
call four2a(cx,NFFT,1,1,1) !Second forward FFT (X)
|
||||
n=min(400,ihsym)
|
||||
do i=1,NFFT
|
||||
sx=real(cx(i))**2 + aimag(cx(i))**2
|
||||
ss(n,i)=sx ! Pol = 0
|
||||
savg(i)=savg(i) + sx
|
||||
ssz5a(i)=sx
|
||||
enddo
|
||||
|
||||
nkhz=nint(1000.d0*(fcenter-int(fcenter)))
|
||||
if(fcenter.eq.0.d0) nkhz=125
|
||||
! write(*,3001) hsym,ts,ja,jb,ihsym
|
||||
!3001 format(2f12.3,3i10)
|
||||
|
||||
999 return
|
||||
end subroutine symspec
|
||||
|
9
qmap/libqmap/zaptx.f90
Normal file
9
qmap/libqmap/zaptx.f90
Normal file
@ -0,0 +1,9 @@
|
||||
subroutine zaptx(dd,k0,k)
|
||||
|
||||
parameter(NMAX=60*96000)
|
||||
real dd(2,NMAX)
|
||||
|
||||
dd(1:2,k0+1:k)=0.
|
||||
|
||||
return
|
||||
end subroutine zaptx
|
@ -16,6 +16,7 @@ extern "C" {
|
||||
void _gfortran_set_args(int argc, char *argv[]);
|
||||
void _gfortran_set_convert(int conv);
|
||||
void ftninit_(void);
|
||||
void fftbig_(float dd[], int* nfft);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -29,7 +30,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Override programs executable basename as application name.
|
||||
a.setApplicationName ("QMAP");
|
||||
a.setApplicationVersion ("0.2");
|
||||
a.setApplicationVersion ("0.4");
|
||||
// switch off as we share an Info.plist file with WSJT-X
|
||||
a.setAttribute (Qt::AA_DontUseNativeMenuBar);
|
||||
MainWindow w;
|
||||
@ -45,9 +46,9 @@ int main(int argc, char *argv[])
|
||||
int iform {1};
|
||||
// free FFT plan resources
|
||||
four2a_ (nullptr, &nfft, &ndim, &isign, &iform, 0);
|
||||
fftbig_(nullptr, &nfft);
|
||||
}
|
||||
fftwf_forget_wisdom ();
|
||||
fftwf_cleanup ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -60,8 +60,9 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
ui->actionQ65E->setActionGroup(modeGroup2);
|
||||
|
||||
QActionGroup* saveGroup = new QActionGroup(this);
|
||||
ui->actionSave_all->setActionGroup(saveGroup);
|
||||
ui->actionNone->setActionGroup(saveGroup);
|
||||
ui->actionSave_all->setActionGroup(saveGroup);
|
||||
ui->actionSave_decoded->setActionGroup(saveGroup);
|
||||
|
||||
setWindowTitle (program_title ());
|
||||
|
||||
@ -71,27 +72,25 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
createStatusBar();
|
||||
connect(m_gui_timer, &QTimer::timeout, this, &MainWindow::guiUpdate);
|
||||
|
||||
m_waterfallAvg = 1;
|
||||
m_network = true;
|
||||
m_waterfallAvg=1;
|
||||
m_network=true;
|
||||
m_restart=false;
|
||||
m_myCall="K1JT";
|
||||
m_myGrid="FN20qi";
|
||||
m_myCallColor=0;
|
||||
m_saveDir="";
|
||||
m_azelDir="";
|
||||
m_loopall=false;
|
||||
m_startAnother=false;
|
||||
m_saveAll=false;
|
||||
m_onlyEME=false;
|
||||
m_saveDecoded=false;
|
||||
m_sec0=-1;
|
||||
m_hsym0=-1;
|
||||
m_palette="CuteSDR";
|
||||
m_nutc0=9999;
|
||||
m_kb8rq=false;
|
||||
m_NB=false;
|
||||
m_mode="Q65";
|
||||
m_fs96000=true;
|
||||
m_udpPort=50004;
|
||||
m_nsave=0;
|
||||
m_modeQ65=0;
|
||||
m_TRperiod=60;
|
||||
|
||||
@ -110,8 +109,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
memset(ipc_wsjtx,0,memSize); //Zero all of shared memory
|
||||
mem_qmap.unlock();
|
||||
|
||||
fftwf_import_wisdom_from_filename (QDir {m_appDir}.absoluteFilePath ("qmap_wisdom.dat").toLocal8Bit ());
|
||||
|
||||
// fftwf_import_wisdom_from_filename (QDir {m_appDir}.absoluteFilePath ("qmap_wisdom.dat").toLocal8Bit ());
|
||||
readSettings(); //Restore user's setup params
|
||||
|
||||
m_pbdecoding_style1="QPushButton{background-color: cyan; \
|
||||
@ -134,14 +132,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
if(m_modeQ65==4) on_actionQ65D_triggered();
|
||||
if(m_modeQ65==5) on_actionQ65E_triggered();
|
||||
|
||||
future1 = new QFuture<void>;
|
||||
watcher1 = new QFutureWatcher<void>;
|
||||
connect(watcher1, SIGNAL(finished()),this,SLOT(diskDat()));
|
||||
|
||||
future2 = new QFuture<void>;
|
||||
watcher2 = new QFutureWatcher<void>;
|
||||
connect(watcher2, SIGNAL(finished()),this,SLOT(diskWriteFinished()));
|
||||
|
||||
connect(&watcher3, SIGNAL(finished()),this,SLOT(decoderFinished()));
|
||||
|
||||
// Assign input device and start input thread
|
||||
@ -159,6 +149,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
m_wide_graph_window->setTol(m_tol);
|
||||
m_wide_graph_window->setFcal(m_fCal);
|
||||
m_wide_graph_window->setFsample(96000);
|
||||
QString rev{"QMAP v" + QCoreApplication::applicationVersion() + " " + revision()};
|
||||
m_revision=rev;
|
||||
|
||||
// Create "m_worked", a dictionary of all calls in wsjt.log
|
||||
QFile f("wsjt.log");
|
||||
@ -194,14 +186,12 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
writeSettings();
|
||||
int itimer=1;
|
||||
q65c_(&itimer);
|
||||
all_done_();
|
||||
|
||||
if (soundInThread.isRunning()) {
|
||||
soundInThread.quit();
|
||||
soundInThread.wait(3000);
|
||||
}
|
||||
fftwf_export_wisdom_to_filename (QDir {m_appDir}.absoluteFilePath ("qmap_wisdom.dat").toLocal8Bit ());
|
||||
delete ui;
|
||||
}
|
||||
|
||||
@ -218,15 +208,13 @@ void MainWindow::writeSettings()
|
||||
SettingsGroup g {&settings, "Common"};
|
||||
settings.setValue("MyCall",m_myCall);
|
||||
settings.setValue("MyGrid",m_myGrid);
|
||||
settings.setValue("IDint",m_idInt);
|
||||
settings.setValue("AstroFont",m_astroFont);
|
||||
settings.setValue("MyCallColor",m_myCallColor);
|
||||
settings.setValue("SaveDir",m_saveDir);
|
||||
settings.setValue("AzElDir",m_azelDir);
|
||||
settings.setValue("Timeout",m_timeout);
|
||||
settings.setValue("Fcal",m_fCal);
|
||||
settings.setValue("Fadd",m_fAdd);
|
||||
settings.setValue("NetworkInput", m_network);
|
||||
settings.setValue("FSam96000", m_fs96000);
|
||||
settings.setValue("paInDevice",m_paInDevice);
|
||||
settings.setValue("Scale_dB",m_dB);
|
||||
settings.setValue("UDPport",m_udpPort);
|
||||
@ -238,15 +226,13 @@ void MainWindow::writeSettings()
|
||||
settings.setValue("nModeQ65",m_modeQ65);
|
||||
settings.setValue("SaveNone",ui->actionNone->isChecked());
|
||||
settings.setValue("SaveAll",ui->actionSave_all->isChecked());
|
||||
settings.setValue("NEME",m_onlyEME);
|
||||
settings.setValue("KB8RQ",m_kb8rq);
|
||||
settings.setValue("SaveDecoded",ui->actionSave_decoded->isChecked());
|
||||
settings.setValue("ContinuousWaterfall",ui->continuous_waterfall->isChecked());
|
||||
settings.setValue("NB",m_NB);
|
||||
settings.setValue("NBslider",m_NBslider);
|
||||
settings.setValue("GainX",(double)m_gainx);
|
||||
settings.setValue("GainY",(double)m_gainy);
|
||||
settings.setValue("PhaseX",(double)m_phasex);
|
||||
settings.setValue("PhaseY",(double)m_phasey);
|
||||
settings.setValue("MaxDrift",ui->sbMaxDrift->value());
|
||||
settings.setValue("Offset",ui->sbOffset->value());
|
||||
settings.setValue("Also30",m_bAlso30);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------- readSettings()
|
||||
@ -262,16 +248,14 @@ void MainWindow::readSettings()
|
||||
SettingsGroup g {&settings, "Common"};
|
||||
m_myCall=settings.value("MyCall","").toString();
|
||||
m_myGrid=settings.value("MyGrid","").toString();
|
||||
m_idInt=settings.value("IDint",0).toInt();
|
||||
m_astroFont=settings.value("AstroFont",20).toInt();
|
||||
m_astroFont=settings.value("AstroFont",18).toInt();
|
||||
m_myCallColor=settings.value("MyCallColor",1).toInt();
|
||||
m_saveDir=settings.value("SaveDir",m_appDir + "/save").toString();
|
||||
m_azelDir=settings.value("AzElDir",m_appDir).toString();
|
||||
m_timeout=settings.value("Timeout",20).toInt();
|
||||
m_fCal=settings.value("Fcal",0).toInt();
|
||||
m_fAdd=settings.value("FAdd",0).toDouble();
|
||||
soundInThread.setFadd(m_fAdd);
|
||||
m_network = settings.value("NetworkInput",true).toBool();
|
||||
m_fs96000 = settings.value("FSam96000",true).toBool();
|
||||
m_dB = settings.value("Scale_dB",0).toInt();
|
||||
m_udpPort = settings.value("UDPport",50004).toInt();
|
||||
soundInThread.setScale(m_dB);
|
||||
@ -281,7 +265,7 @@ void MainWindow::readSettings()
|
||||
ui->actionLinrad->setChecked(settings.value(
|
||||
"PaletteLinrad",false).toBool());
|
||||
|
||||
m_modeQ65=settings.value("nModeQ65",2).toInt();
|
||||
m_modeQ65=settings.value("nModeQ65",3).toInt();
|
||||
if(m_modeQ65==1) ui->actionQ65A->setChecked(true);
|
||||
if(m_modeQ65==2) ui->actionQ65B->setChecked(true);
|
||||
if(m_modeQ65==3) ui->actionQ65C->setChecked(true);
|
||||
@ -290,20 +274,29 @@ void MainWindow::readSettings()
|
||||
|
||||
ui->actionNone->setChecked(settings.value("SaveNone",true).toBool());
|
||||
ui->actionSave_all->setChecked(settings.value("SaveAll",false).toBool());
|
||||
ui->actionSave_decoded->setChecked(settings.value("SaveDecoded",false).toBool());
|
||||
ui->continuous_waterfall->setChecked(settings.value("ContinuousWaterfall",false).toBool());
|
||||
m_saveAll=ui->actionSave_all->isChecked();
|
||||
m_onlyEME=settings.value("NEME",false).toBool();
|
||||
ui->actionOnly_EME_calls->setChecked(m_onlyEME);
|
||||
m_kb8rq=settings.value("KB8RQ",false).toBool();
|
||||
m_saveDecoded=ui->actionSave_decoded->isChecked();
|
||||
if(m_saveAll) {
|
||||
lab5->setStyleSheet("QLabel{background-color: #ffff00}");
|
||||
lab5->setText("Save all");
|
||||
} else if(m_saveDecoded) {
|
||||
lab5->setStyleSheet("QLabel{background-color: #ffff00}");
|
||||
lab5->setText("Save decoded");
|
||||
} else {
|
||||
lab5->setStyleSheet("");
|
||||
lab5->setText("");
|
||||
}
|
||||
m_NB=settings.value("NB",false).toBool();
|
||||
ui->NBcheckBox->setChecked(m_NB);
|
||||
ui->sbMaxDrift->setValue(settings.value("MaxDrift",0).toInt());
|
||||
ui->sbOffset->setValue(settings.value("Offset",1500).toInt());
|
||||
m_NBslider=settings.value("NBslider",40).toInt();
|
||||
ui->NBslider->setValue(m_NBslider);
|
||||
m_gainx=settings.value("GainX",1.0).toFloat();
|
||||
m_gainy=settings.value("GainY",1.0).toFloat();
|
||||
m_phasex=settings.value("PhaseX",0.0).toFloat();
|
||||
m_phasey=settings.value("PhaseY",0.0).toFloat();
|
||||
|
||||
m_bAlso30=settings.value("Also30",true).toBool();
|
||||
ui->actionAlso_Q65_30x->setChecked(m_bAlso30);
|
||||
on_actionAlso_Q65_30x_toggled(m_bAlso30);
|
||||
if(!ui->actionLinrad->isChecked() && !ui->actionCuteSDR->isChecked() &&
|
||||
!ui->actionAFMHot->isChecked() && !ui->actionBlue->isChecked()) {
|
||||
on_actionLinrad_triggered();
|
||||
@ -317,6 +310,7 @@ void MainWindow::dataSink(int k)
|
||||
static float s[NFFT],splot[NFFT];
|
||||
static int n=0;
|
||||
static int ihsym=0;
|
||||
static int ihsym0=0;
|
||||
static int nzap=0;
|
||||
static int ntrz=0;
|
||||
static int nkhz;
|
||||
@ -325,6 +319,7 @@ void MainWindow::dataSink(int k)
|
||||
static int nsum=0;
|
||||
static int ndiskdat;
|
||||
static int nb;
|
||||
static int k0=0;
|
||||
static float px=0.0;
|
||||
static uchar lstrong[1024];
|
||||
static float slimit;
|
||||
@ -341,7 +336,10 @@ void MainWindow::dataSink(int k)
|
||||
nb=0;
|
||||
if(m_NB) nb=1;
|
||||
nfsample=96000;
|
||||
if(!m_fs96000) nfsample=95238;
|
||||
|
||||
if(m_bWTransmitting) zaptx_(datcom_.d4, &k0, &k);
|
||||
k0=k;
|
||||
|
||||
symspec_(&k, &ndiskdat, &nb, &m_NBslider, &nfsample,
|
||||
&px, s, &nkhz, &ihsym, &nzap, &slimit, lstrong);
|
||||
|
||||
@ -357,6 +355,7 @@ void MainWindow::dataSink(int k)
|
||||
}
|
||||
nsec0=nsec;
|
||||
|
||||
if(m_bWTransmitting) px=0.0;
|
||||
QString t;
|
||||
m_pctZap=nzap/178.3;
|
||||
|
||||
@ -366,9 +365,9 @@ void MainWindow::dataSink(int k)
|
||||
.arg (m_pctZap, 5, 'f', 1)
|
||||
);
|
||||
|
||||
xSignalMeter->setValue(px); // Update the signal meters
|
||||
xSignalMeter->setValue(px); // Update the signal meter
|
||||
//Suppress scrolling if WSJT-X is transmitting
|
||||
if((m_monitoring and ipc_wsjtx[4] != 1) or m_diskData) {
|
||||
if((m_monitoring and (!m_bWTransmitting or ui->continuous_waterfall->isChecked())) or m_diskData) {
|
||||
m_wide_graph_window->dataSink2(s,nkhz,ihsym,m_diskData,lstrong);
|
||||
}
|
||||
|
||||
@ -399,26 +398,26 @@ void MainWindow::dataSink(int k)
|
||||
n=0;
|
||||
}
|
||||
|
||||
bool bCallDecoder=false;
|
||||
if(ihsym < m_hsymStop) m_decode_called=false;
|
||||
if(ihsym==m_hsymStop and !m_decode_called) bCallDecoder=true; //Decode at t=58.5 s
|
||||
if(ihsym==130) bCallDecoder=true;
|
||||
if(m_bAlso30 and (ihsym==200)) bCallDecoder=true;
|
||||
if(ihsym==330) bCallDecoder=true;
|
||||
if(ihsym==ihsym0) bCallDecoder=false;
|
||||
|
||||
if(ihsym >= m_hsymStop and !m_decode_called) { //Decode at t=56 s (for Q65 and data from disk)
|
||||
m_decode_called=true;
|
||||
datcom_.newdat=1;
|
||||
ihsym0=ihsym;
|
||||
if(bCallDecoder) {
|
||||
if(ihsym==m_hsymStop) m_decode_called=true;
|
||||
datcom_.nagain=0;
|
||||
datcom_.nhsym=ihsym;
|
||||
QDateTime t = QDateTime::currentDateTimeUtc();
|
||||
m_dateTime=t.toString("yymmdd_hhmm");
|
||||
decode(); //Start the decoder
|
||||
if(m_saveAll and !m_diskData and m_nTransmitted<10) {
|
||||
QString fname=m_saveDir + "/" + t.date().toString("yyMMdd") + "_" +
|
||||
t.time().toString("hhmm");
|
||||
fname += ".iq";
|
||||
*future2 = QtConcurrent::run(savetf2, fname, false);
|
||||
watcher2->setFuture(*future2);
|
||||
decode(); //Prepare to start the decoder
|
||||
if(ihsym==m_hsymStop) {
|
||||
m_nTx30a=0;
|
||||
m_nTx30b=0;
|
||||
m_nTx60=0;
|
||||
}
|
||||
m_nTransmitted=0;
|
||||
}
|
||||
|
||||
soundInThread.m_dataSinkBusy=false;
|
||||
}
|
||||
|
||||
@ -433,33 +432,29 @@ void MainWindow::on_actionSettings_triggered()
|
||||
DevSetup dlg(this);
|
||||
dlg.m_myCall=m_myCall;
|
||||
dlg.m_myGrid=m_myGrid;
|
||||
dlg.m_idInt=m_idInt;
|
||||
dlg.m_astroFont=m_astroFont;
|
||||
dlg.m_myCallColor=m_myCallColor;
|
||||
dlg.m_saveDir=m_saveDir;
|
||||
dlg.m_azelDir=m_azelDir;
|
||||
dlg.m_timeout=m_timeout;
|
||||
dlg.m_fCal=m_fCal;
|
||||
dlg.m_fAdd=m_fAdd;
|
||||
dlg.m_network=m_network;
|
||||
dlg.m_fs96000=m_fs96000;
|
||||
dlg.m_udpPort=m_udpPort;
|
||||
dlg.m_dB=m_dB;
|
||||
dlg.initDlg();
|
||||
if(dlg.exec() == QDialog::Accepted) {
|
||||
m_myCall=dlg.m_myCall;
|
||||
m_myGrid=dlg.m_myGrid;
|
||||
m_idInt=dlg.m_idInt;
|
||||
m_astroFont=dlg.m_astroFont;
|
||||
m_myCallColor=dlg.m_myCallColor;
|
||||
if(m_astro_window && m_astro_window->isVisible()) m_astro_window->setFontSize(m_astroFont);
|
||||
ui->actionFind_Delta_Phi->setEnabled(false);
|
||||
m_saveDir=dlg.m_saveDir;
|
||||
m_azelDir=dlg.m_azelDir;
|
||||
m_timeout=dlg.m_timeout;
|
||||
m_fCal=dlg.m_fCal;
|
||||
m_fAdd=dlg.m_fAdd;
|
||||
soundInThread.setFadd(m_fAdd);
|
||||
m_wide_graph_window->setFcal(m_fCal);
|
||||
m_fs96000=dlg.m_fs96000;
|
||||
m_network=dlg.m_network;
|
||||
m_udpPort=dlg.m_udpPort;
|
||||
m_dB=dlg.m_dB;
|
||||
@ -595,9 +590,16 @@ void MainWindow::createStatusBar() //createStatusBar
|
||||
|
||||
lab4 = new QLabel("");
|
||||
lab4->setAlignment(Qt::AlignHCenter);
|
||||
lab4->setMinimumSize(QSize(50,10));
|
||||
lab4->setMinimumSize(QSize(80,10));
|
||||
lab4->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
||||
statusBar()->addWidget(lab4);
|
||||
|
||||
lab5 = new QLabel("");
|
||||
lab5->setAlignment(Qt::AlignHCenter);
|
||||
lab5->setMinimumSize(QSize(100,10));
|
||||
lab5->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
||||
lab5->setStyleSheet("");
|
||||
statusBar()->addWidget(lab5);
|
||||
}
|
||||
|
||||
void MainWindow::on_tolSpinBox_valueChanged(int i) //tolSpinBox
|
||||
@ -644,11 +646,11 @@ void MainWindow::on_actionOpen_triggered() //Open File
|
||||
soundInThread.setMonitoring(m_monitoring);
|
||||
QString fname;
|
||||
fname=QFileDialog::getOpenFileName(this, "Open File", m_path,
|
||||
"MAP65/QMAP Files (*.iq)");
|
||||
"MAP65/QMAP Files (*.iq *.qm)");
|
||||
if(fname != "") {
|
||||
m_path=fname;
|
||||
int i;
|
||||
i=fname.indexOf(".iq") - 11;
|
||||
i=qMax(fname.indexOf(".iq") - 11, fname.indexOf(".qm") - 11);
|
||||
if(i>=0) {
|
||||
lab1->setStyleSheet("QLabel{background-color: #66ff66}");
|
||||
lab1->setText(" " + fname.mid(i,15) + " ");
|
||||
@ -656,9 +658,13 @@ void MainWindow::on_actionOpen_triggered() //Open File
|
||||
if(m_monitoring) on_monitorButton_clicked();
|
||||
m_diskData=true;
|
||||
int dbDgrd=0;
|
||||
if(m_myCall=="K1JT" and m_idInt<0) dbDgrd=m_idInt;
|
||||
*future1 = QtConcurrent::run(getfile, fname, false, dbDgrd);
|
||||
watcher1->setFuture(*future1);
|
||||
int iret=4;
|
||||
if(m_path.indexOf(".iq")>0) {
|
||||
getfile(fname, dbDgrd);
|
||||
} else {
|
||||
read_qm_(fname.toLatin1(), &iret, fname.length());
|
||||
}
|
||||
if(iret > 0) diskDat(iret);
|
||||
}
|
||||
}
|
||||
|
||||
@ -667,7 +673,11 @@ void MainWindow::on_actionOpen_next_in_directory_triggered() //Open Next
|
||||
int i,len;
|
||||
QFileInfo fi(m_path);
|
||||
QStringList list;
|
||||
list= fi.dir().entryList().filter(".iq");
|
||||
if(m_path.indexOf(".iq")>0) {
|
||||
list= fi.dir().entryList().filter(".iq");
|
||||
} else {
|
||||
list= fi.dir().entryList().filter(".qm");
|
||||
}
|
||||
for (i = 0; i < list.size()-1; ++i) {
|
||||
if(i==list.size()-2) m_loopall=false;
|
||||
len=list.at(i).length();
|
||||
@ -676,16 +686,20 @@ void MainWindow::on_actionOpen_next_in_directory_triggered() //Open Next
|
||||
QString fname=m_path.replace(n-len,len,list.at(i+1));
|
||||
m_path=fname;
|
||||
int i;
|
||||
i=fname.indexOf(".iq") - 11;
|
||||
i=qMax(fname.indexOf(".iq") - 11, fname.indexOf(".qm") - 11);
|
||||
if(i>=0) {
|
||||
lab1->setStyleSheet("QLabel{background-color: #66ff66}");
|
||||
lab1->setText(" " + fname.mid(i,len) + " ");
|
||||
}
|
||||
m_diskData=true;
|
||||
int dbDgrd=0;
|
||||
if(m_myCall=="K1JT" and m_idInt<0) dbDgrd=m_idInt;
|
||||
*future1 = QtConcurrent::run(getfile, fname, false, dbDgrd);
|
||||
watcher1->setFuture(*future1);
|
||||
int iret=4;
|
||||
if(m_path.indexOf(".iq")>0) {
|
||||
getfile(fname, dbDgrd);
|
||||
} else {
|
||||
read_qm_(fname.toLatin1(), &iret, fname.length());
|
||||
}
|
||||
if(iret > 0) diskDat(iret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -697,41 +711,54 @@ void MainWindow::on_actionDecode_remaining_files_in_directory_triggered()
|
||||
on_actionOpen_next_in_directory_triggered();
|
||||
}
|
||||
|
||||
void MainWindow::diskDat() //diskDat()
|
||||
void MainWindow::diskDat(int iret) //diskDat()
|
||||
{
|
||||
int ia=0;
|
||||
int ib=400;
|
||||
if(iret==1) ib=202;
|
||||
m_bDiskDatBusy=true;
|
||||
double hsym;
|
||||
//These may be redundant??
|
||||
m_diskData=true;
|
||||
datcom_.newdat=1;
|
||||
hsym=2048.0*96000.0/11025.0; //Samples per JT65 half-symbol
|
||||
for(int i=0; i<304; i++) { // Do the half-symbol FFTs
|
||||
int k = i*hsym + 2048.5;
|
||||
m_nTx30a=datcom_.ntx30a;
|
||||
m_nTx30b=datcom_.ntx30b;
|
||||
hsym=0.15*96000.0; //Samples per Q65-30x half-symbol or Q65-60x quarter-symbol
|
||||
for(int i=ia; i<ib; i++) { // Do the half-symbol FFTs
|
||||
int k = i*hsym + 0.5;
|
||||
if(k > 60*96000) break;
|
||||
dataSink(k);
|
||||
qApp->processEvents(); // Allow the waterfall to update
|
||||
while(m_decoderBusy) {
|
||||
qApp->processEvents(); // Wait for an early decode to finish
|
||||
}
|
||||
}
|
||||
m_bDiskDatBusy=false;
|
||||
}
|
||||
|
||||
void MainWindow::diskWriteFinished() //diskWriteFinished
|
||||
{
|
||||
// qDebug() << "diskWriteFinished";
|
||||
}
|
||||
|
||||
void MainWindow::decoderFinished() //diskWriteFinished
|
||||
void MainWindow::decoderFinished()
|
||||
{
|
||||
m_startAnother=m_loopall;
|
||||
ui->DecodeButton->setStyleSheet("");
|
||||
decodeBusy(false);
|
||||
decodes_.nQDecoderDone=1;
|
||||
decodes_.kHzRequested=0;
|
||||
if(m_diskData) decodes_.nQDecoderDone=2;
|
||||
mem_qmap.lock();
|
||||
decodes_.nWDecoderBusy=ipc_wsjtx[3]; //Prevent overwriting values
|
||||
decodes_.nWTransmitting=ipc_wsjtx[4]; //written here by WSJT-X
|
||||
m_bWTransmitting=decodes_.nWTransmitting>0;
|
||||
memcpy((char*)ipc_wsjtx, &decodes_, sizeof(decodes_)); //Send decodes and flags to WSJT-X
|
||||
mem_qmap.unlock();
|
||||
QString t1;
|
||||
t1=t1.asprintf(" %d ",decodes_.ndecodes);
|
||||
t1=t1.asprintf(" %.1f s %d/%d ", 0.15*datcom2_.nhsym, decodes_.ndecodes, decodes_.ncand);
|
||||
lab4->setText(t1);
|
||||
QDateTime now=QDateTime::currentDateTimeUtc();
|
||||
decodeBusy(false);
|
||||
|
||||
if(m_bDecodeAgain) {
|
||||
datcom_.nhsym=390;
|
||||
datcom_.nagain=1;
|
||||
m_bDecodeAgain=false;
|
||||
decode();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionDelete_all_iq_files_in_SaveDir_triggered()
|
||||
@ -739,7 +766,7 @@ void MainWindow::on_actionDelete_all_iq_files_in_SaveDir_triggered()
|
||||
int i;
|
||||
QString fname;
|
||||
int ret = QMessageBox::warning(this, "Confirm Delete",
|
||||
"Are you sure you want to delete all *.iq files in\n" +
|
||||
"Are you sure you want to delete all *.iq and *.qm files in\n" +
|
||||
QDir::toNativeSeparators(m_saveDir) + " ?",
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
|
||||
if(ret==QMessageBox::Yes) {
|
||||
@ -750,6 +777,8 @@ void MainWindow::on_actionDelete_all_iq_files_in_SaveDir_triggered()
|
||||
fname=*f;
|
||||
i=(fname.indexOf(".iq"));
|
||||
if(i==11) dir.remove(fname);
|
||||
i=(fname.indexOf(".qm"));
|
||||
if(i==11) dir.remove(fname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -757,13 +786,25 @@ void MainWindow::on_actionDelete_all_iq_files_in_SaveDir_triggered()
|
||||
void MainWindow::on_actionNone_triggered() //Save None
|
||||
{
|
||||
m_saveAll=false;
|
||||
m_saveDecoded=false;
|
||||
lab5->setStyleSheet("");
|
||||
lab5->setText("");
|
||||
}
|
||||
|
||||
// ### Implement "Save Last" here? ###
|
||||
void MainWindow::on_actionSave_decoded_triggered()
|
||||
{
|
||||
m_saveDecoded=true;
|
||||
m_saveAll=false;
|
||||
lab5->setStyleSheet("QLabel{background-color: #ffff00}");
|
||||
lab5->setText("Save decoded");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSave_all_triggered() //Save All
|
||||
void MainWindow::on_actionSave_all_triggered()
|
||||
{
|
||||
m_saveAll=true;
|
||||
m_saveDecoded=false;
|
||||
lab5->setStyleSheet("QLabel{background-color: #ffff00}");
|
||||
lab5->setText("Save all");
|
||||
}
|
||||
|
||||
void MainWindow::on_DecodeButton_clicked() //Decode request
|
||||
@ -771,12 +812,23 @@ void MainWindow::on_DecodeButton_clicked() //Decode request
|
||||
if(!m_decoderBusy) {
|
||||
datcom_.newdat=0;
|
||||
datcom_.nagain=1;
|
||||
if(m_bAlso30 and m_nTx30a<5) {
|
||||
datcom_.nhsym=200; //Decode the first half-minute
|
||||
if(m_nTx30b<5) m_bDecodeAgain=true; //Queue up decoding of the seciond half minute
|
||||
}
|
||||
decode();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::freezeDecode(int n) //freezeDecode()
|
||||
{
|
||||
if(n==3) {
|
||||
decodes_.kHzRequested=m_wide_graph_window->QSOfreq();
|
||||
mem_qmap.lock();
|
||||
ipc_wsjtx[5]=decodes_.kHzRequested;
|
||||
mem_qmap.unlock();
|
||||
return;
|
||||
}
|
||||
if(n==2) {
|
||||
ui->tolSpinBox->setValue(5);
|
||||
datcom_.ntol=m_tol;
|
||||
@ -789,17 +841,17 @@ void MainWindow::freezeDecode(int n) //freezeDecode()
|
||||
if(!m_decoderBusy) {
|
||||
datcom_.nagain=1;
|
||||
datcom_.newdat=0;
|
||||
decode();
|
||||
on_DecodeButton_clicked();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::decode() //decode()
|
||||
{
|
||||
//Don't attempt to decode if decoder is already busy, or if we transmitted for 10 s or more.
|
||||
if(m_decoderBusy or m_nTransmitted>10) return;
|
||||
if(m_decoderBusy) {
|
||||
return; //Don't attempt decode if decoder already busy
|
||||
}
|
||||
decodeBusy(true);
|
||||
QString fname=" ";
|
||||
ui->DecodeButton->setStyleSheet(m_pbdecoding_style1);
|
||||
|
||||
if(datcom_.nagain==0 && (!m_diskData)) {
|
||||
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
|
||||
int imin=ms/60000;
|
||||
@ -814,24 +866,11 @@ void MainWindow::decode() //decode()
|
||||
datcom_.ndiskdat=0;
|
||||
if(m_diskData) {
|
||||
datcom_.ndiskdat=1;
|
||||
int i0=m_path.indexOf(".iq");
|
||||
int i0=qMax(m_path.indexOf(".iq"),m_path.indexOf(".qm"));
|
||||
if(i0>0) {
|
||||
// Compute self Doppler using the filename for Date and Time
|
||||
int nyear=m_path.mid(i0-11,2).toInt()+2000;
|
||||
int month=m_path.mid(i0-9,2).toInt();
|
||||
int nday=m_path.mid(i0-7,2).toInt();
|
||||
int nhr=m_path.mid(i0-4,2).toInt();
|
||||
int nmin=m_path.mid(i0-2,2).toInt();
|
||||
double uth=nhr + nmin/60.0;
|
||||
int nfreq=(int)datcom_.fcenter;
|
||||
int ndop00;
|
||||
astrosub00_(&nyear, &month, &nday, &uth, &nfreq, m_myGrid.toLatin1(),&ndop00,6);
|
||||
datcom_.ndop00=ndop00; //Send self Doppler to decoder, via datcom
|
||||
fname=m_path.mid(i0-11,11);
|
||||
}
|
||||
}
|
||||
datcom_.neme=0;
|
||||
if(ui->actionOnly_EME_calls->isChecked()) datcom_.neme=1;
|
||||
|
||||
int ispan=int(m_wide_graph_window->fSpan());
|
||||
if(ispan%2 == 1) ispan++;
|
||||
@ -844,19 +883,12 @@ void MainWindow::decode() //decode()
|
||||
datcom_.nfb=nfb;
|
||||
datcom_.nfcal=m_fCal;
|
||||
datcom_.nfshift=nfshift;
|
||||
datcom_.mcall3=0;
|
||||
if(m_call3Modified) datcom_.mcall3=1;
|
||||
datcom_.ntimeout=m_timeout;
|
||||
datcom_.ntol=m_tol;
|
||||
datcom_.nxant=0;
|
||||
m_nutc0=datcom_.nutc;
|
||||
datcom_.junk_1=0;
|
||||
datcom_.nfsample=96000;
|
||||
if(!m_fs96000) datcom_.nfsample=95238;
|
||||
datcom_.nxpol=0;
|
||||
datcom_.nmode=10*m_modeQ65;
|
||||
datcom_.nsave=m_nsave;
|
||||
datcom_.nBaseSubmode=m_modeQ65;
|
||||
datcom_.max_drift=ui->sbMaxDrift->value();
|
||||
datcom_.offset=ui->sbOffset->value();
|
||||
datcom_.ndepth=1;
|
||||
if(datcom_.nagain==1) datcom_.ndepth=3;
|
||||
|
||||
@ -870,24 +902,64 @@ void MainWindow::decode() //decode()
|
||||
} else {
|
||||
memcpy(datcom_.datetime, m_dateTime.toLatin1(), 11);
|
||||
}
|
||||
datcom_.junk1=1234; //Cecck for these values in m65
|
||||
datcom_.ntx30a=m_nTx30a;
|
||||
datcom_.ntx30b=m_nTx30b;
|
||||
datcom_.ntx60=m_nTx60;
|
||||
|
||||
datcom_.nsave=0;
|
||||
if(m_saveDecoded) datcom_.nsave=1;
|
||||
if(m_saveAll) datcom_.nsave=2;
|
||||
|
||||
datcom_.n60=m_n60;
|
||||
datcom_.junk1=1234; //Check for these values in m65
|
||||
datcom_.junk2=5678;
|
||||
datcom_.bAlso30=m_bAlso30;
|
||||
datcom_.ndop00=m_dop00;
|
||||
datcom_.ndop58=m_dop58;
|
||||
|
||||
char *to = (char*) datcom2_.d4;
|
||||
char *from = (char*) datcom_.d4;
|
||||
memcpy(to, from, sizeof(datcom_));
|
||||
datcom_.nagain=0;
|
||||
datcom_.ndiskdat=0;
|
||||
m_call3Modified=false;
|
||||
memcpy(to, from, sizeof(datcom_)); //Copy the full datcom_ common block into datcom2_
|
||||
|
||||
decodes_.ndecodes=0;
|
||||
datcom_.ndiskdat=0;
|
||||
|
||||
if((!m_bAlso30 and (datcom2_.nhsym==330)) or (m_bAlso30 and (datcom2_.nhsym==130))) {
|
||||
decodes_.ndecodes=0; //Start the decode cycle with a clean slate
|
||||
m_fetched=0;
|
||||
}
|
||||
decodes_.ncand=0;
|
||||
decodes_.nQDecoderDone=0;
|
||||
m_fetched=0;
|
||||
int itimer=0;
|
||||
m_decoder_start_time=QDateTime::currentDateTimeUtc();
|
||||
watcher3.setFuture(QtConcurrent::run (std::bind (q65c_, &itimer)));
|
||||
|
||||
m_saveFileName="NoSave";
|
||||
if(!m_diskData) {
|
||||
QDateTime t = QDateTime::currentDateTimeUtc();
|
||||
m_dateTime=t.toString("yyMMdd_hhmm");
|
||||
QDir dir(m_saveDir);
|
||||
if (!dir.exists()) dir.mkpath(".");
|
||||
m_saveFileName=m_saveDir + "/" + m_dateTime + ".qm";
|
||||
}
|
||||
|
||||
bool bSkipDecode=false;
|
||||
//No need to call decoder for first half, if we transmitted in the first half:
|
||||
if((datcom2_.nhsym<=200) and (m_nTx30a>5)) bSkipDecode=true;
|
||||
//No need to call decoder at 330, if we transmitted in 2nd half:
|
||||
if((datcom2_.nhsym==330) and (m_nTx30b>5)) bSkipDecode=true;
|
||||
//No need to call decoder at all, if we transmitted in a 60 s submode.
|
||||
if(m_nTx60>5) bSkipDecode=true;
|
||||
|
||||
if(bSkipDecode) {
|
||||
decodeBusy(false);
|
||||
return;
|
||||
}
|
||||
|
||||
int len1=m_saveFileName.length();
|
||||
int len2=m_revision.length();
|
||||
|
||||
memcpy(savecom_.revision, m_revision.toLatin1(), len2);
|
||||
memcpy(savecom_.saveFileName, m_saveFileName.toLatin1(),len1);
|
||||
|
||||
ui->actionExport_wav_file_at_fQSO->setEnabled(m_diskData);
|
||||
watcher3.setFuture(QtConcurrent::run (q65c_));
|
||||
decodeBusy(true);
|
||||
}
|
||||
|
||||
@ -895,6 +967,7 @@ void MainWindow::on_EraseButton_clicked()
|
||||
{
|
||||
ui->decodedTextBrowser->clear();
|
||||
lab4->clear();
|
||||
m_nline=0;
|
||||
}
|
||||
|
||||
|
||||
@ -902,6 +975,8 @@ void MainWindow::decodeBusy(bool b) //decodeBusy()
|
||||
{
|
||||
m_decoderBusy=b;
|
||||
ui->DecodeButton->setEnabled(!b);
|
||||
if(!b) ui->DecodeButton->setStyleSheet("");
|
||||
if(b) ui->DecodeButton->setStyleSheet(m_pbdecoding_style1);
|
||||
ui->actionOpen->setEnabled(!b);
|
||||
ui->actionOpen_next_in_directory->setEnabled(!b);
|
||||
ui->actionDecode_remaining_files_in_directory->setEnabled(!b);
|
||||
@ -923,7 +998,7 @@ void MainWindow::guiUpdate()
|
||||
|
||||
m_wide_graph_window->updateFreqLabel();
|
||||
|
||||
if(m_startAnother) {
|
||||
if(m_startAnother and !m_bDiskDatBusy) {
|
||||
m_startAnother=false;
|
||||
on_actionOpen_next_in_directory_triggered();
|
||||
}
|
||||
@ -934,30 +1009,59 @@ void MainWindow::guiUpdate()
|
||||
QString t=QString::fromLatin1(decodes_.result[m_fetched]);
|
||||
if(m_UTC0!="" and m_UTC0!=t.left(4)) {
|
||||
t1="-";
|
||||
ui->decodedTextBrowser->append(t1.repeated(56));
|
||||
ui->decodedTextBrowser->append(t1.repeated(60));
|
||||
m_nline++;
|
||||
QTextCursor cursor(ui->decodedTextBrowser->document()->findBlockByLineNumber(m_nline-1));
|
||||
QTextBlockFormat f = cursor.blockFormat();
|
||||
f.setBackground(QBrush(Qt::white));
|
||||
cursor.setBlockFormat(f);
|
||||
}
|
||||
m_UTC0=t.left(4);
|
||||
ui->decodedTextBrowser->append(t.trimmed());
|
||||
t=t.trimmed();
|
||||
ui->decodedTextBrowser->append(t);
|
||||
m_fetched++;
|
||||
m_nline++;
|
||||
QTextCursor cursor(ui->decodedTextBrowser->document()->findBlockByLineNumber(m_nline-1));
|
||||
QTextBlockFormat f = cursor.blockFormat();
|
||||
f.setBackground(QBrush(Qt::white));
|
||||
if(t.mid(36,2)=="30") f.setBackground(QBrush(Qt::yellow));
|
||||
if(t.indexOf(m_myCall)>10 and m_myCallColor==1) f.setBackground(QColor(255,102,102));
|
||||
if(t.indexOf(m_myCall)>10 and m_myCallColor==2) f.setBackground(QBrush(Qt::green));
|
||||
if(t.indexOf(m_myCall)>10 and m_myCallColor==3) f.setBackground(QBrush(Qt::cyan));
|
||||
cursor.setBlockFormat(f);
|
||||
}
|
||||
}
|
||||
|
||||
t1="";
|
||||
t1=t1.asprintf("%.3f",datcom_.fcenter);
|
||||
ui->labFreq->setText(t1);
|
||||
|
||||
if(nsec != m_sec0) { //Once per second
|
||||
// qDebug() << "AAA" << nsec << m_fAdd;
|
||||
|
||||
static int n60z=99;
|
||||
int n60=nsec%60;
|
||||
m_n60=nsec%60;
|
||||
|
||||
// See if WSJT-X is transmitting
|
||||
int itest[5];
|
||||
mem_qmap.lock();
|
||||
memcpy(&itest, (char*)ipc_wsjtx, 20);
|
||||
mem_qmap.unlock();
|
||||
if(itest[4]==1) m_nTransmitted++;
|
||||
// qDebug() << "AAA" << n60 << itest[0] << itest[1] << itest[2] << itest[3] << itest[4]
|
||||
// << m_nTransmitted;
|
||||
if(n60<n60z) m_nTransmitted=0;
|
||||
n60z=n60;
|
||||
if(itest[4]>0) {
|
||||
m_WSJTX_TRperiod=itest[4];
|
||||
m_bWTransmitting=true;
|
||||
if(m_WSJTX_TRperiod==30 and m_n60<30) m_nTx30a++;
|
||||
if(m_WSJTX_TRperiod==30 and m_n60>=30) m_nTx30b++;
|
||||
if(m_WSJTX_TRperiod==60) m_nTx60++;
|
||||
} else {
|
||||
m_bWTransmitting=false;
|
||||
}
|
||||
|
||||
if((m_n60<n60z) and !m_diskData) {
|
||||
m_nTx30a=0;
|
||||
m_nTx30b=0;
|
||||
m_nTx60=0;
|
||||
}
|
||||
n60z=m_n60;
|
||||
|
||||
if(m_pctZap>30.0) {
|
||||
lab2->setStyleSheet("QLabel{background-color: #ff0000}");
|
||||
@ -965,8 +1069,7 @@ void MainWindow::guiUpdate()
|
||||
lab2->setStyleSheet("");
|
||||
}
|
||||
|
||||
|
||||
if(m_monitoring) {
|
||||
if(m_monitoring and !m_bWTransmitting) {
|
||||
lab1->setStyleSheet("QLabel{background-color: #00ff00}");
|
||||
m_nrx=soundInThread.nrx();
|
||||
khsym=soundInThread.mhsym();
|
||||
@ -985,26 +1088,30 @@ void MainWindow::guiUpdate()
|
||||
lab1->setStyleSheet("QLabel{background-color: #ffc0cb}");
|
||||
}
|
||||
lab1->setText("Receiving " + t);
|
||||
} else if (!m_diskData) {
|
||||
} else if(m_bWTransmitting) {
|
||||
lab1->setStyleSheet("QLabel{background-color: #ffff00}"); //Yellow
|
||||
lab1->setText("WSJT-X Transmitting");
|
||||
} else if(!m_diskData) {
|
||||
lab1->setStyleSheet("");
|
||||
lab1->setText("");
|
||||
}
|
||||
|
||||
datcom_.mousefqso=m_wide_graph_window->QSOfreq();
|
||||
QDateTime t = QDateTime::currentDateTimeUtc();
|
||||
int fQSO=m_wide_graph_window->QSOfreq();
|
||||
m_astro_window->astroUpdate(t, m_myGrid, m_hisGrid, fQSO, m_setftx,
|
||||
m_txFreq, m_azelDir, m_xavg);
|
||||
m_setftx=0;
|
||||
m_astro_window->astroUpdate(t, m_myGrid, m_azelDir, m_xavg);
|
||||
QString utc = t.date().toString(" yyyy MMM dd \n") + t.time().toString();
|
||||
ui->labUTC->setText(utc);
|
||||
m_hsym0=khsym;
|
||||
m_sec0=nsec;
|
||||
if(m_n60==0) m_dop00=datcom_.ndop00;
|
||||
if(m_n60==58) m_dop58=datcom_.ndop00;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionQ65A_triggered()
|
||||
{
|
||||
m_modeQ65=1;
|
||||
ui->actionAlso_Q65_30x->setText("Also Q65-30A");
|
||||
lab3->setStyleSheet("QLabel{background-color: #ffb266}");
|
||||
lab3->setText("Q65-60A");
|
||||
}
|
||||
@ -1012,6 +1119,7 @@ void MainWindow::on_actionQ65A_triggered()
|
||||
void MainWindow::on_actionQ65B_triggered()
|
||||
{
|
||||
m_modeQ65=2;
|
||||
ui->actionAlso_Q65_30x->setText("Also Q65-30A");
|
||||
lab3->setStyleSheet("QLabel{background-color: #b2ff66}");
|
||||
lab3->setText("Q65-60B");
|
||||
}
|
||||
@ -1019,6 +1127,7 @@ void MainWindow::on_actionQ65B_triggered()
|
||||
void MainWindow::on_actionQ65C_triggered()
|
||||
{
|
||||
m_modeQ65=3;
|
||||
ui->actionAlso_Q65_30x->setText("Also Q65-30B");
|
||||
lab3->setStyleSheet("QLabel{background-color: #66ffff}");
|
||||
lab3->setText("Q65-60C");
|
||||
}
|
||||
@ -1026,13 +1135,15 @@ void MainWindow::on_actionQ65C_triggered()
|
||||
void MainWindow::on_actionQ65D_triggered()
|
||||
{
|
||||
m_modeQ65=4;
|
||||
lab3->setStyleSheet("QLabel{background-color: #b266ff}");
|
||||
ui->actionAlso_Q65_30x->setText("Also Q65-30C");
|
||||
lab3->setStyleSheet("QLabel{background-color: #d9b3ff}");
|
||||
lab3->setText("Q65-60D");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionQ65E_triggered()
|
||||
{
|
||||
m_modeQ65=5;
|
||||
ui->actionAlso_Q65_30x->setText("Also Q65-30D");
|
||||
lab3->setStyleSheet("QLabel{background-color: #ff66ff}");
|
||||
lab3->setText("Q65-60E");
|
||||
}
|
||||
@ -1069,3 +1180,35 @@ void MainWindow::on_actionQuick_Start_Guide_to_WSJT_X_2_7_and_QMAP_triggered()
|
||||
QDesktopServices::openUrl (QUrl {"https://wsjt.sourceforge.io/Quick_Start_WSJT-X_2.7_QMAP.pdf"});
|
||||
}
|
||||
|
||||
void MainWindow::on_actionAlso_Q65_30x_toggled(bool b)
|
||||
{
|
||||
m_bAlso30=b;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_sbMaxDrift_valueChanged(int n)
|
||||
{
|
||||
if(n==0) ui->sbMaxDrift->setStyleSheet("");
|
||||
if(n==5) ui->sbMaxDrift->setStyleSheet("QSpinBox { background-color: #ffff82; }");
|
||||
if(n>=10) ui->sbMaxDrift->setStyleSheet("QSpinBox { background-color: #ffff00; }");
|
||||
}
|
||||
|
||||
void MainWindow::on_actionExport_wav_file_at_fQSO_triggered()
|
||||
{
|
||||
datcom_.newdat=0;
|
||||
datcom_.nagain=2;
|
||||
decode();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionExport_wav_file_at_fQSO_30a_triggered()
|
||||
{
|
||||
datcom_.newdat=0;
|
||||
datcom_.nagain=3;
|
||||
decode();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionExport_wav_file_at_fQSO_30b_triggered()
|
||||
{
|
||||
datcom_.newdat=0;
|
||||
datcom_.nagain=4;
|
||||
decode();}
|
||||
|
@ -39,8 +39,7 @@ public slots:
|
||||
void showSoundInError(const QString& errorMsg);
|
||||
void showStatusMessage(const QString& statusMsg);
|
||||
void dataSink(int k);
|
||||
void diskDat();
|
||||
void diskWriteFinished();
|
||||
void diskDat(int iret);
|
||||
void decoderFinished();
|
||||
void freezeDecode(int n);
|
||||
void guiUpdate();
|
||||
@ -82,6 +81,14 @@ private slots:
|
||||
void on_actionQ65E_triggered();
|
||||
void on_actionQuick_Start_Guide_to_Q65_triggered();
|
||||
void on_actionQuick_Start_Guide_to_WSJT_X_2_7_and_QMAP_triggered();
|
||||
void on_actionAlso_Q65_30x_toggled(bool b);
|
||||
void on_sbMaxDrift_valueChanged(int arg1);
|
||||
void on_actionSave_decoded_triggered();
|
||||
void on_actionExport_wav_file_at_fQSO_triggered();
|
||||
|
||||
void on_actionExport_wav_file_at_fQSO_30a_triggered();
|
||||
|
||||
void on_actionExport_wav_file_at_fQSO_30b_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
@ -90,16 +97,11 @@ private:
|
||||
QScopedPointer<Astro> m_astro_window;
|
||||
QScopedPointer<WideGraph> m_wide_graph_window;
|
||||
QPointer<QTimer> m_gui_timer;
|
||||
qint32 m_idInt;
|
||||
qint32 m_waterfallAvg;
|
||||
qint32 m_DF;
|
||||
qint32 m_tol;
|
||||
qint32 m_QSOfreq0;
|
||||
qint32 m_astroFont;
|
||||
qint32 m_timeout;
|
||||
qint32 m_fCal;
|
||||
qint32 m_txFreq;
|
||||
qint32 m_setftx;
|
||||
qint32 m_sec0;
|
||||
qint32 m_nutc0;
|
||||
qint32 m_nrx;
|
||||
@ -107,15 +109,20 @@ private:
|
||||
qint32 m_paInDevice;
|
||||
qint32 m_udpPort;
|
||||
qint32 m_NBslider;
|
||||
qint32 m_nsum;
|
||||
qint32 m_nsave;
|
||||
qint32 m_TRperiod;
|
||||
qint32 m_modeQ65;
|
||||
qint32 m_dB;
|
||||
qint32 m_fetched=0;
|
||||
qint32 m_hsymStop=302;
|
||||
qint32 m_nTransmitted=0;
|
||||
qint32 m_hsymStop=390; //390*0.15 = 58.5 s
|
||||
qint32 m_nTx30a=0;
|
||||
qint32 m_nTx30b=0;
|
||||
qint32 m_nTx60=0;
|
||||
qint32 m_nDoubleClicked=0;
|
||||
qint32 m_nline=0;
|
||||
qint32 m_WSJTX_TRperiod=0;
|
||||
qint32 m_dop00=0;
|
||||
qint32 m_dop58=0;
|
||||
qint32 m_n60;
|
||||
|
||||
double m_fAdd;
|
||||
double m_xavg;
|
||||
@ -125,21 +132,20 @@ private:
|
||||
bool m_loopall;
|
||||
bool m_decoderBusy=false;
|
||||
bool m_restart;
|
||||
bool m_call3Modified;
|
||||
bool m_startAnother;
|
||||
bool m_saveAll;
|
||||
bool m_onlyEME;
|
||||
bool m_kb8rq;
|
||||
bool m_saveDecoded;
|
||||
bool m_NB;
|
||||
bool m_fs96000;
|
||||
bool m_decode_called=false;
|
||||
bool m_bAlso30=true;
|
||||
bool m_bDiskDatBusy=false;
|
||||
bool m_bWTransmitting=false;
|
||||
bool m_bDecodeAgain=false;
|
||||
|
||||
float m_gainx;
|
||||
float m_gainy;
|
||||
float m_phasex;
|
||||
float m_phasey;
|
||||
float m_pctZap;
|
||||
|
||||
int m_myCallColor;
|
||||
|
||||
QRect m_wideGraphGeom;
|
||||
|
||||
QLabel* lab1; // labels in status bar
|
||||
@ -152,15 +158,8 @@ private:
|
||||
|
||||
QMessageBox msgBox0;
|
||||
|
||||
QFuture<void>* future1;
|
||||
QFuture<void>* future2;
|
||||
QFutureWatcher<void>* watcher1;
|
||||
QFutureWatcher<void>* watcher2;
|
||||
|
||||
QFutureWatcher<void> watcher3; //For decoder
|
||||
|
||||
QDateTime m_decoder_start_time;
|
||||
|
||||
QString m_path;
|
||||
QString m_pbdecoding_style1;
|
||||
QString m_pbmonitor_style;
|
||||
@ -175,13 +174,12 @@ private:
|
||||
QString m_dateTime;
|
||||
QString m_mode;
|
||||
QString m_UTC0="";
|
||||
QString m_revision;
|
||||
QString m_saveFileName;
|
||||
|
||||
QDateTime m_dateTimeSeqStart; //Nominal start time of Rx sequence about to be decoded
|
||||
QHash<QString,bool> m_worked;
|
||||
|
||||
SignalMeter *xSignalMeter;
|
||||
SignalMeter *ySignalMeter;
|
||||
|
||||
|
||||
SoundInThread soundInThread; //Instantiate the audio threads
|
||||
|
||||
//---------------------------------------------------- private functions
|
||||
@ -194,7 +192,7 @@ private:
|
||||
};
|
||||
|
||||
extern void getfile(QString fname, bool xpol, int idInt);
|
||||
extern void savetf2(QString fname, bool xpol);
|
||||
extern void save_iq(QString fname);
|
||||
extern int killbyname(const char* progName);
|
||||
|
||||
extern "C" {
|
||||
@ -206,7 +204,18 @@ extern "C" {
|
||||
void astrosub00_ (int* nyear, int* month, int* nday, double* uth, int* nfreq,
|
||||
const char* mygrid, int* ndop00, int len1);
|
||||
|
||||
void q65c_(int* itimer);
|
||||
void q65c_();
|
||||
|
||||
void all_done_();
|
||||
|
||||
void zaptx_(float d4[], int* k0, int* k);
|
||||
|
||||
void save_qm_(const char* fname, const char* prog_id, const char* mycall, const char* mygrid,
|
||||
float d4[], int* ntx30a, int* ntx30b, double* fcenter, int* nutc,
|
||||
int* dop00, int* dop58, int len1, int len2, int len3, int len4);
|
||||
|
||||
void read_qm_(const char* fname, int* iret, int len);
|
||||
|
||||
}
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -24,8 +24,8 @@
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>640</width>
|
||||
<height>1080</height>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -40,8 +40,8 @@
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="3" colspan="2">
|
||||
<widget class="QPushButton" name="EraseButton">
|
||||
<item row="0" column="5">
|
||||
<widget class="QPushButton" name="DecodeButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
@ -49,26 +49,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Erase</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4" colspan="2">
|
||||
<widget class="QSpinBox" name="sbMaxDrift">
|
||||
<property name="toolTip">
|
||||
<string>Maximum drift rate in units of symbol rate per transmissiion.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Max Drift </string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
<string>&Decode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -96,95 +77,34 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QPushButton" name="DecodeButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
<item row="3" column="4" colspan="2">
|
||||
<widget class="QSlider" name="NBslider">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Decode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QCheckBox" name="NBcheckBox">
|
||||
<property name="text">
|
||||
<string>NB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="2">
|
||||
<widget class="QLabel" name="labUTC">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>165</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> 2023 Feb 02
|
||||
01:23:45 </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="3">
|
||||
<widget class="QFrame" name="xMeterFrame">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="monitorButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Monitor</string>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>40</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -274,33 +194,141 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="4" colspan="2">
|
||||
<widget class="QSlider" name="NBslider">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<widget class="QSpinBox" name="sbOffset">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select offset announced by calling station, or use commonly used value for the band in use. Manually set WSJT-X TX and RX offset to same value.</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> Hz</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Offset </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1500</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" colspan="2">
|
||||
<widget class="QPushButton" name="EraseButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Erase</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="4">
|
||||
<widget class="QFrame" name="xMeterFrame">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="3">
|
||||
<widget class="QLabel" name="labUTC">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>165</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> 2023 Feb 02
|
||||
01:23:45 </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="monitorButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
<property name="text">
|
||||
<string>&Monitor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QCheckBox" name="NBcheckBox">
|
||||
<property name="text">
|
||||
<string>NB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4" colspan="2">
|
||||
<widget class="QSpinBox" name="sbMaxDrift">
|
||||
<property name="toolTip">
|
||||
<string>Maximum drift rate in units of symbol rate per transmission.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Max Drift </string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>40</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -309,7 +337,7 @@
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
@ -322,31 +350,31 @@
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>620</width>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string> UTC Frx Fsked DT dB Message</string>
|
||||
<string> UTC Frx Fsked DT dB Q65- Message</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="DisplayText" name="decodedTextBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>100</height>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>610</width>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -370,9 +398,8 @@
|
||||
</property>
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
hr { height: 1px; border-width: 0; }
|
||||
</style></head><body style=" font-family:'Courier New'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||
</property>
|
||||
@ -394,7 +421,7 @@ hr { height: 1px; border-width: 0; }
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>22</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@ -407,6 +434,9 @@ hr { height: 1px; border-width: 0; }
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionDelete_all_iq_files_in_SaveDir"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionExport_wav_file_at_fQSO"/>
|
||||
<addaction name="actionExport_wav_file_at_fQSO_30a"/>
|
||||
<addaction name="actionExport_wav_file_at_fQSO_30b"/>
|
||||
<addaction name="actionSettings"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionExit"/>
|
||||
@ -426,12 +456,15 @@ hr { height: 1px; border-width: 0; }
|
||||
<addaction name="actionWide_Waterfall"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="menuWaterfall_palette"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="continuous_waterfall"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuSave">
|
||||
<property name="title">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<addaction name="actionNone"/>
|
||||
<addaction name="actionSave_decoded"/>
|
||||
<addaction name="actionSave_all"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuHelp">
|
||||
@ -453,6 +486,8 @@ hr { height: 1px; border-width: 0; }
|
||||
<addaction name="actionQ65C"/>
|
||||
<addaction name="actionQ65D"/>
|
||||
<addaction name="actionQ65E"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAlso_Q65_30x"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuView"/>
|
||||
@ -476,7 +511,7 @@ hr { height: 1px; border-width: 0; }
|
||||
</action>
|
||||
<action name="actionAbout">
|
||||
<property name="text">
|
||||
<string> About QMAP</string>
|
||||
<string>About QMAP</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+F1</string>
|
||||
@ -528,7 +563,7 @@ hr { height: 1px; border-width: 0; }
|
||||
</action>
|
||||
<action name="actionDelete_all_iq_files_in_SaveDir">
|
||||
<property name="text">
|
||||
<string>Delete all *.iq files in SaveDir</string>
|
||||
<string>Delete all *.iq and *.qm files in SaveDir</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionErase_Band_Map_and_Messages">
|
||||
@ -730,7 +765,7 @@ hr { height: 1px; border-width: 0; }
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Q65A</string>
|
||||
<string>Q65-60A</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQ65B">
|
||||
@ -738,7 +773,7 @@ hr { height: 1px; border-width: 0; }
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Q65B</string>
|
||||
<string>Q65-60B</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQ65C">
|
||||
@ -749,7 +784,7 @@ hr { height: 1px; border-width: 0; }
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Q65C</string>
|
||||
<string>Q65-60C</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQ65D">
|
||||
@ -757,7 +792,7 @@ hr { height: 1px; border-width: 0; }
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Q65D</string>
|
||||
<string>Q65-60D</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQ65E">
|
||||
@ -765,7 +800,7 @@ hr { height: 1px; border-width: 0; }
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Q65E</string>
|
||||
<string>Q65-60E</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQSG_Q65">
|
||||
@ -773,16 +808,6 @@ hr { height: 1px; border-width: 0; }
|
||||
<string>Quick-Start Guide to Q65</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQSG_MAP65_v3">
|
||||
<property name="text">
|
||||
<string>Quick-Start Guide to WSJT-X 2.5.0 and MAP65 3.0</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQ65_Sensitivity_in_MAP65_3_0">
|
||||
<property name="text">
|
||||
<string>Q65 Sensitivity in MAP65 3.0</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRelease_Notes">
|
||||
<property name="text">
|
||||
<string>Release Notes</string>
|
||||
@ -806,6 +831,48 @@ hr { height: 1px; border-width: 0; }
|
||||
<string>Quick-Start Guide to Q65</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="continuous_waterfall">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Continuous Waterfall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAlso_Q65_30x">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Also Q65-30x</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave_decoded">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save decoded</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExport_wav_file_at_fQSO">
|
||||
<property name="text">
|
||||
<string>Export .wav file at fQSO (60 s)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExport_wav_file_at_fQSO_30b">
|
||||
<property name="text">
|
||||
<string>Export .wav file at fQSO (30 s, second part)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExport_wav_file_at_fQSO_30a">
|
||||
<property name="text">
|
||||
<string>Export .wav file at fQSO (30 s, first part)</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
@ -824,8 +891,8 @@ hr { height: 1px; border-width: 0; }
|
||||
<slot>update()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>269</x>
|
||||
<y>255</y>
|
||||
<x>287</x>
|
||||
<y>281</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>126</x>
|
||||
|
@ -602,6 +602,7 @@ void CPlotter::mousePressEvent(QMouseEvent *event) //mousePressEvent
|
||||
if(y < h+30) { // Wideband waterfall
|
||||
if(button==1) {
|
||||
setFQSO(x,false);
|
||||
if(event->modifiers() & Qt::ControlModifier) emit freezeDecode1(3);
|
||||
}
|
||||
if(button==2 and !m_bLockTxRx) {
|
||||
if(x<0) x=0; // x is pixel number
|
||||
|
@ -15,37 +15,43 @@ extern "C"
|
||||
struct
|
||||
{
|
||||
double d8[60*96000]; //This is "common/datcom/..." in fortran
|
||||
float ss[322*NFFT];
|
||||
float savg[NFFT];
|
||||
double fcenter;
|
||||
int nutc;
|
||||
float ss[400*NFFT];
|
||||
float savg[NFFT]; //Avg spectra at 0,45,90,135 deg pol
|
||||
double fcenter; //Center freq from Linrad (MHz)
|
||||
int nutc; //UTC as integer, HHMM
|
||||
float fselected; //Selected frequency for nagain decodes
|
||||
int mousedf; //User-selected DF
|
||||
int mousefqso; //User-selected QSO freq (kHz)
|
||||
int nagain; //1 ==> decode only at fQSO +/- Tol
|
||||
int ndepth; //How much hinted decoding to do?
|
||||
int ndiskdat; //1 ==> data read from *.tf2 or *.iq file
|
||||
int neme; //Hinted decoding tries only for EME calls
|
||||
int ndiskdat; //1 ==> data read from *.iq file
|
||||
int ntx60; //Number of seconds transmitted in Q65-60x
|
||||
int newdat; //1 ==> new data, must do long FFT
|
||||
int nfa; //Low decode limit (kHz)
|
||||
int nfb; //High decode limit (kHz)
|
||||
int nfcal; //Frequency correction, for calibration (Hz)
|
||||
int nfshift; //Shift of displayed center freq (kHz)
|
||||
int mcall3; //1 ==> CALL3.TXT has been modified
|
||||
int ntimeout; //Max for timeouts in Messages and BandMap
|
||||
int ntx30a; //Number of seconds transmitted in first half minute , Q65-30x
|
||||
int ntx30b; //Number of seconds transmitted in second half minute, Q65-30x
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int nxant; //1 ==> add 45 deg to measured pol angle
|
||||
int junk_1; //Flags to control log files
|
||||
int junk5; //
|
||||
int junk4; //
|
||||
int nfsample; //Input sample rate
|
||||
int nxpol; //1 if using xpol antennas, 0 otherwise
|
||||
int mode65; //JT65 sub-mode: A=1, B=2, C=4
|
||||
int nfast; //1No longer used
|
||||
int junk3; //
|
||||
int nBaseSubmode; //Base submode for Q65-60x (aka m_modeQ65)
|
||||
int ndop00; //EME Self Doppler
|
||||
int nsave; //Number of s3(64,63) spectra saved
|
||||
int max_drift; //Maximum Q65 drift: units symbol_rate/TxT
|
||||
int offset; //Offset in Hz
|
||||
int nhsym; //Number of available JT65 half-symbols
|
||||
char mycall[12];
|
||||
char mygrid[6];
|
||||
char hiscall[12];
|
||||
char hisgrid[6];
|
||||
char datetime[20];
|
||||
int junk1; //Used to test extent of copy to shared memory
|
||||
int junk2;
|
||||
bool bAlso30; //Process for 30-second submode as well as 60-second
|
||||
} datcom_;
|
||||
}
|
||||
|
||||
@ -208,12 +214,10 @@ void SoundInThread::inputUDP()
|
||||
// If buffer will not overflow, move data into datcom_
|
||||
if ((k+iz) <= 60*96000) {
|
||||
int nsam=-1;
|
||||
recvpkt_(&nsam, &b.iblk, &b.nrx, &k, b.d8, b.d8);
|
||||
recvpkt_(&nsam, &b.iblk, &b.nrx, &k, b.d8, b.d8, &m_dB);
|
||||
datcom_.fcenter=b.cfreq + m_fAdd;
|
||||
// qDebug() << "bb" << b.cfreq << m_fAdd << datcom_.fcenter;
|
||||
}
|
||||
|
||||
m_hsym=(k-2048)*11025.0/(2048.0*m_rate);
|
||||
m_hsym=(k-2048)/14400; //14400 = 0.15 * 96000
|
||||
if(m_hsym != nhsym0) {
|
||||
if(!m_dataSinkBusy) {
|
||||
m_dataSinkBusy=true;
|
||||
|
@ -67,7 +67,8 @@ private:
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
void recvpkt_(int* nsam, quint16* iblk, qint8* nrx, int* k, double s1[], double s2[]);
|
||||
void recvpkt_(int* nsam, quint16* iblk, qint8* nrx, int* k,
|
||||
double s1[], double s2[], int* ndb);
|
||||
}
|
||||
|
||||
#endif // SOUNDIN_H
|
||||
|
@ -318,7 +318,7 @@
|
||||
<message>
|
||||
<location filename="../widgets/colorhighlighting.ui" line="150"/>
|
||||
<source>New Call</source>
|
||||
<translation>Nou Indicatiu</translation>
|
||||
<translation>Indicatiu nou</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/colorhighlighting.ui" line="157"/>
|
||||
@ -2238,12 +2238,12 @@ Error(%2): %3</translation>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="1683"/>
|
||||
<source>Maximum drift rate in units of symbol rate per transmission.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Taxa de deriva màxima en unitats de taxa de símbols per transmissió.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="1686"/>
|
||||
<source>Max Drift </source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Deriva màxima </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="2604"/>
|
||||
@ -3658,7 +3658,7 @@ La llista es pot mantenir a la configuració (F2).</translation>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="3429"/>
|
||||
<source>Quick-Start Guide to WSJT-X 2.5.0 and MAP65 3.0</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Guia d'inici ràpid de WSJT-X 2.5.0 i MAP65 3.0</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.cpp" line="258"/>
|
||||
@ -3685,7 +3685,7 @@ La llista es pot mantenir a la configuració (F2).</translation>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.cpp" line="523"/>
|
||||
<source>Scanned ADIF log, %1 worked-before records created. CTY: %2</source>
|
||||
<translation>Log ADIF escanejat, %1 funcionava abans de la creació de registres</translation>
|
||||
<translation>Log ADIF escanejat, %1 funcionava abans de la creació de registres. CTY: %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.cpp" line="631"/>
|
||||
|
@ -2480,17 +2480,17 @@ Error(%2): %3</translation>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="1683"/>
|
||||
<source>Maximum drift rate in units of symbol rate per transmission.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Tasa de deriva máxima en unidades de tasa de símbolos por transmisión.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="1686"/>
|
||||
<source>Max Drift </source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Máxima deriva </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="3416"/>
|
||||
<source>Quick-Start Guide to Q65</source>
|
||||
<translation>Guía de inicio rápido de Q65</translation>
|
||||
<translation>Guía de inicio rápido de Q65 (inglés)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="3424"/>
|
||||
@ -2500,7 +2500,7 @@ Error(%2): %3</translation>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="3429"/>
|
||||
<source>Quick-Start Guide to WSJT-X 2.5.0 and MAP65 3.0</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Guía de inicio rápido para WSJT-X 2.5.0 y MAP65 3.0 (inglés)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="1588"/>
|
||||
@ -2703,7 +2703,7 @@ Amarillo cuando esta muy bajo.</translation>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="876"/>
|
||||
<source>&Lookup</source>
|
||||
<translation>Buscar</translation>
|
||||
<translation>Buscar (&L)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="988"/>
|
||||
@ -3044,7 +3044,7 @@ No está disponible para los titulares de indicativo no estándar.</translatorco
|
||||
<location filename="../widgets/mainwindow.ui" line="1215"/>
|
||||
<source>Best S+P</source>
|
||||
<translatorcomment>El mejor S+P </translatorcomment>
|
||||
<translation>Mejor S+P (&B)</translation>
|
||||
<translation>Mejor S+P</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="1225"/>
|
||||
@ -3181,7 +3181,8 @@ Cuando no está marcado, puede verse los resultados de la calibración.</transla
|
||||
Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</source>
|
||||
<translatorcomment>Enviar este mensaje en el siguiente intervalo de transmisión.
|
||||
Haz doble clic para alternar el uso del mensaje TX1 para iniciar un QSO con una estación (no está permitido para titulares de indicativos compuestos de tipo 1).</translatorcomment>
|
||||
<translation>Enviar este mensaje en el siguiente intervalo de TX. Doble clic para alternar el uso del mensaje TX1 para iniciar un QSO con una estación (no está permitido para titulares de indicativos compuestos de tipo 1).</translation>
|
||||
<translation>Enviar este mensaje en el siguiente intervalo de TX.
|
||||
Doble clic para alternar el uso del mensaje TX1 para iniciar un QSO con una estación (no está permitido para titulares de indicativos compuestos de tipo 1).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="1826"/>
|
||||
@ -3246,7 +3247,8 @@ Haz doble clic para alternar el uso del mensaje TX1 para iniciar un QSO con una
|
||||
<location filename="../widgets/mainwindow.ui" line="2035"/>
|
||||
<source>Send this message in next Tx interval
|
||||
Double-click to reset to the standard 73 message</source>
|
||||
<translation>Enviar este mensaje en el siguiente intervalo de TX. Doble clic para restablecer el mensaje 73 estándar.</translation>
|
||||
<translation>Enviar este mensaje en el siguiente intervalo de TX.
|
||||
Doble clic para restablecer el mensaje 73 estándar.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="2045"/>
|
||||
@ -3300,7 +3302,9 @@ RR73 messages should only be used when you are reasonably confident that no mess
|
||||
<translatorcomment>Cambia a este mensaje de TX AHORA.
|
||||
Haz doble clic para alternar entre los mensajes RRR y RR73 en TX4 (no está permitido para titulares de indicativos compuestos de tipo 2).
|
||||
Los mensajes RR73 solo deben usarse cuando esté razonablemente seguro de que no se requerirán repeticiones de mensajes.</translatorcomment>
|
||||
<translation>Cambiar a este mensaje de TX AHORA. Doble clic para alternar entre los mensajes RRR y RR73 en TX4 (no está permitido para titulares de indicativos compuestos de tipo 2). Los mensajes RR73 solo deben usarse cuando esté razonablemente seguro de que no se requerirán repeticiones de mensajes.</translation>
|
||||
<translation>Cambiar a este mensaje de TX AHORA.
|
||||
Doble clic para alternar entre los mensajes RRR y RR73 en TX4 (no está permitido para titulares de indicativos compuestos de tipo 2).
|
||||
Los mensajes RR73 solo deben usarse cuando esté razonablemente seguro de que no se requerirán repeticiones de mensajes.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="1951"/>
|
||||
@ -3397,7 +3401,7 @@ predefinida. La lista se puede modificar en "Ajustes" (F2).</translati
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="3358"/>
|
||||
<source>Quick-Start Guide to FST4 and FST4W</source>
|
||||
<translation>Guía de inicio rápido a FST4 y FST4W</translation>
|
||||
<translation>Guía de inicio rápido a FST4 y FST4W (inglés)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.ui" line="3384"/>
|
||||
@ -4239,7 +4243,7 @@ predefinida. La lista se puede modificar en "Ajustes" (F2).</translati
|
||||
<location filename="../widgets/mainwindow.cpp" line="523"/>
|
||||
<source>Scanned ADIF log, %1 worked-before records created. CTY: %2</source>
|
||||
<translatorcomment>Log ADIF escaneado, %1 funcionaba antes de la creación de registros</translatorcomment>
|
||||
<translation>Log ADIF escaneado, %1 registros trabajados B4 creados</translation>
|
||||
<translation>Log ADIF escaneado, %1 registros trabajados B4 creados. CTY: %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.cpp" line="631"/>
|
||||
@ -4912,7 +4916,7 @@ ya está en CALL3.TXT, ¿desea reemplazarlo?</translation>
|
||||
<location filename="../widgets/mainwindow.cpp" line="8593"/>
|
||||
<source>Confirm Reset</source>
|
||||
<translatorcomment>Confirmar reinicio</translatorcomment>
|
||||
<translation>Confirmar restablecer</translation>
|
||||
<translation>Confirmar borrado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/mainwindow.cpp" line="6841"/>
|
||||
@ -5354,7 +5358,7 @@ Error(%2): %3</translation>
|
||||
<message>
|
||||
<location filename="../SampleDownloader.cpp" line="112"/>
|
||||
<source>Base URL for samples:</source>
|
||||
<translation>Enlace para muestras:</translation>
|
||||
<translation>Enlace de las muestras:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SampleDownloader.cpp" line="113"/>
|
||||
@ -5483,7 +5487,7 @@ Error(%2): %3</translation>
|
||||
<message>
|
||||
<location filename="../Audio/soundout.cpp" line="95"/>
|
||||
<source>No audio output device configured.</source>
|
||||
<translation>No hay dispositivo de salida de audio configurado</translation>
|
||||
<translation>No hay dispositivo de salida de audio configurado.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Audio/soundout.cpp" line="184"/>
|
||||
@ -5974,7 +5978,7 @@ Error(%2): %3</translation>
|
||||
<location filename="../Configuration.ui" line="237"/>
|
||||
<source>Font...</source>
|
||||
<translatorcomment>Letra...</translatorcomment>
|
||||
<translation>Tipo de letra para la aplicación</translation>
|
||||
<translation>Tipo de letra para la aplicación..</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Configuration.ui" line="244"/>
|
||||
@ -6220,7 +6224,7 @@ período de silencio cuando se ha realizado la decodificación.</translation>
|
||||
<message>
|
||||
<location filename="../Configuration.ui" line="628"/>
|
||||
<source>4800</source>
|
||||
<translation></translation>
|
||||
<translation>4800</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Configuration.ui" line="633"/>
|
||||
@ -6832,7 +6836,7 @@ Haz clic derecho para acciones específicas del artículo.
|
||||
Clic, Mayúsculas+Clic y, CTRL+Clic para seleccionar elementos.</translatorcomment>
|
||||
<translation>Arrastre y suelte elementos para reorganizar el orden
|
||||
Clic derecho para acciones específicas del elemento.
|
||||
Clic, Mayús+Clic y CTRL+Clic para seleccionar elementos.</translation>
|
||||
Clic, Mayús+Clic y CTRL+Clic para seleccionar elementos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Configuration.ui" line="1709"/>
|
||||
@ -7559,7 +7563,7 @@ Clic derecho para insertar y eliminar opciones.</translation>
|
||||
<location filename="../Configuration.ui" line="2970"/>
|
||||
<source>Waterfall spectra</source>
|
||||
<translatorcomment>Espectros de la cascada</translatorcomment>
|
||||
<translation>Espectro de la cascada (waterfall)</translation>
|
||||
<translation>Cascada (Waterfall)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../Configuration.ui" line="2976"/>
|
||||
|
@ -21,7 +21,7 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
|
||||
"WSJT-X implements a number of digital modes designed for <br />"
|
||||
"weak-signal Amateur Radio communication. <br /><br />"
|
||||
"© 2001-2023 by Joe Taylor, K1JT, Bill Somerville, G4WJS, <br />"
|
||||
"© 2001-2024 by Joe Taylor, K1JT, Bill Somerville, G4WJS, <br />"
|
||||
"Steve Franke, K9AN, Nico Palermo, IV3NWV, <br />"
|
||||
"Uwe Risse, DG2YCB, and Brian Moran, N9ADG <br /><br />"
|
||||
"We gratefully acknowledge contributions from AC6SL, AE4JY,<br />"
|
||||
|
@ -47,7 +47,7 @@ void ActiveStations::read_settings ()
|
||||
ui->sbMaxRecent->setValue(settings_->value("MaxRecent",10).toInt());
|
||||
ui->sbMaxAge->setValue(settings_->value("MaxAge",10).toInt());
|
||||
ui->cbReadyOnly->setChecked(settings_->value("ReadyOnly",false).toBool());
|
||||
ui->cbWantedOnly->setChecked(settings_->value("WantedOnly",false).toBool());
|
||||
ui->cbWantedOnly->setChecked(settings_->value("# WantedOnly",false).toBool());
|
||||
}
|
||||
|
||||
void ActiveStations::write_settings ()
|
||||
@ -64,9 +64,11 @@ void ActiveStations::displayRecentStations(QString mode, QString const& t)
|
||||
{
|
||||
if(mode!=m_mode) {
|
||||
m_mode=mode;
|
||||
ui->cbReadyOnly->setText(" Ready only");
|
||||
if(m_mode=="Q65") {
|
||||
ui->header_label2->setText(" N Frx Fsked S/N Call Grid Tx Age");
|
||||
ui->header_label2->setText(" N Frx Fsked S/N Q65 Call Grid Tx Age");
|
||||
ui->label->setText("QSOs:");
|
||||
ui->cbReadyOnly->setText("* CQ only");
|
||||
} else if(m_mode=="Q65-pileup") {
|
||||
ui->header_label2->setText(" N Freq Call Grid El Age(h)");
|
||||
} else {
|
||||
@ -90,6 +92,32 @@ void ActiveStations::displayRecentStations(QString mode, QString const& t)
|
||||
bool bClickOK=m_clickOK;
|
||||
m_clickOK=false;
|
||||
ui->RecentStationsPlainTextEdit->setPlainText(t);
|
||||
|
||||
//White background for Q65-60x decodes, yellow for Q65-30x:
|
||||
int i0=0;
|
||||
int i1=0;
|
||||
int npos=0;
|
||||
int nlines=t.count("\n");
|
||||
QTextCursor cursor=ui->RecentStationsPlainTextEdit->textCursor();
|
||||
QTextCharFormat fmt;
|
||||
for(int i=0; i<nlines; i++) {
|
||||
i1=t.indexOf("\n",i0);
|
||||
npos=t.indexOf(QRegularExpression(" 30[ABCD] "), i0);
|
||||
if(npos>0) {
|
||||
cursor.setPosition(npos);
|
||||
cursor.select(QTextCursor::LineUnderCursor);
|
||||
fmt.setBackground(QBrush(Qt::yellow));
|
||||
fmt.setForeground(QBrush(Qt::black));
|
||||
} else {
|
||||
cursor.setPosition(i0+10);
|
||||
cursor.select(QTextCursor::LineUnderCursor);
|
||||
fmt.clearForeground();
|
||||
fmt.clearBackground();
|
||||
}
|
||||
cursor.setCharFormat(fmt);
|
||||
i0=i1+1;
|
||||
}
|
||||
|
||||
m_clickOK=bClickOK;
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>395</width>
|
||||
<height>339</height>
|
||||
<width>400</width>
|
||||
<height>340</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -17,32 +17,30 @@
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="sbMaxRecent">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="1,0,1,0,0,1">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Band Changes:</string>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLineEdit" name="score">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Set maximum number of displayed lines.</p></body></html></string>
|
||||
<string><html><head/><body><p>Total score accumulated since most recent reset of Cabrillo log.</p></body></html></string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Max N </string>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -50,7 +48,7 @@
|
||||
<widget class="QLineEdit" name="rate">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -78,30 +76,24 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Band Changes:</string>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="cbWantedOnly">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
<property name="text">
|
||||
<string># Wanted only</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLineEdit" name="score">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Total score accumulated since most recent reset of Cabrillo log.</p></body></html></string>
|
||||
</property>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
<string>Score:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
@ -124,19 +116,22 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Set maximum elapsed number of T/R sequences.</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Max Age </string>
|
||||
</property>
|
||||
@ -151,13 +146,34 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Score:</string>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="sbMaxRecent">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Set maximum number of displayed lines.</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Max N </string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -177,16 +193,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="cbWantedOnly">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Wanted only</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
|
@ -387,6 +387,17 @@ QString DisplayText::appendWorkedB4 (QString message, QString call, QString cons
|
||||
countryName.replace ("European", "EU");
|
||||
countryName.replace ("African", "AF");
|
||||
|
||||
// assign WAE entities to the correct DXCC when "Include extra WAE entities" is not selected
|
||||
if (!(m_config->include_WAE_entities())) {
|
||||
countryName.replace ("Bear Is.", "Svalbard");
|
||||
countryName.replace ("Shetland Is.", "Scotland");
|
||||
countryName.replace ("AF Italy", "Italy");
|
||||
countryName.replace ("Sicily", "Italy");
|
||||
countryName.replace ("Vienna Intl Ctr", "Austria");
|
||||
countryName.replace ("AF Turkey", "Turkey");
|
||||
countryName.replace ("EU Turkey", "Turkey");
|
||||
}
|
||||
|
||||
extra += countryName;
|
||||
}
|
||||
}
|
||||
@ -520,7 +531,8 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx
|
||||
QString t2;
|
||||
t2 = t2.asprintf("%4d",txFreq);
|
||||
QString t;
|
||||
if(bFastMode or modeTx=="FT8" or modeTx=="FT4" or (TRperiod<60)) {
|
||||
if(bFastMode or modeTx=="FT8" or modeTx=="FT4" or (TRperiod<60) or
|
||||
(modeTx=="Q65" and TRperiod==60)) {
|
||||
t = QDateTime::currentDateTimeUtc().toString("hhmmss") + \
|
||||
" Tx " + t2 + t1 + text;
|
||||
} else if(modeTx.mid(0,6)=="FT8fox") {
|
||||
|
@ -213,6 +213,7 @@ QVector<QColor> g_ColorTbl;
|
||||
|
||||
using SpecOp = Configuration::SpecialOperatingActivity;
|
||||
|
||||
bool blocked = false;
|
||||
bool m_displayBand = false;
|
||||
bool no_a7_decodes = false;
|
||||
bool keep_frequency = false;
|
||||
@ -224,7 +225,8 @@ struct {
|
||||
int nQDecoderDone; //QMAP decoder is finished (0 or 1)
|
||||
int nWDecoderBusy; //WSJT-X decoder is busy (0 or 1)
|
||||
int nWTransmitting; //WSJT-X is transmitting (0 or 1)
|
||||
char result[50][60]; //Decodes as character*60 arrays
|
||||
int kHzRequested; //Integer kHz dial frequency requested from QMAP
|
||||
char result[50][64]; //Decodes as character*64 arrays
|
||||
} qmapcom;
|
||||
int* ipc_qmap;
|
||||
|
||||
@ -1084,18 +1086,35 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
QString jpleph = m_config.data_dir().absoluteFilePath("JPLEPH");
|
||||
jpl_setup_(const_cast<char *>(jpleph.toLocal8Bit().constData()),256);
|
||||
|
||||
#ifdef WIN32
|
||||
// backup libhamlib-4.dll file, so it is still available after the next program update
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
QFile f {dataPath.absolutePath() + "/" + "libhamlib-4_old.dll"};
|
||||
if (!f.exists()) {
|
||||
QFile::copy(dataPath.absolutePath() + "/" + "libhamlib-4.dll", dataPath.absolutePath() + "/" + "libhamlib-4_old.dll");
|
||||
QTimer::singleShot (5000, [=] { //wait until hamlib has been started
|
||||
extern char* hamlib_version2;
|
||||
QString hamlib = QString(QLatin1String(hamlib_version2));
|
||||
m_settings->beginGroup("Configuration");
|
||||
m_settings->setValue ("HamlibBackedUp", hamlib);
|
||||
m_settings->endGroup();
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
// this must be the last statement of constructor
|
||||
if (!m_valid) throw std::runtime_error {"Fatal initialization exception"};
|
||||
}
|
||||
|
||||
void MainWindow::not_GA_warning_message ()
|
||||
{
|
||||
if(m_config.my_callsign()=="K1JT" or m_config.my_callsign()=="W2ZQ") return;
|
||||
MessageBox::critical_message (this,
|
||||
"This is a pre-release version of WSJT-X 2.7.0-rc2 made\n"
|
||||
"This is a pre-release version of WSJT-X " + version (false) + " made\n"
|
||||
"available for testing purposes. By design it will\n"
|
||||
"be nonfunctional after Jan 15, 2024.");
|
||||
"be nonfunctional after October 30, 2024.");
|
||||
auto now = QDateTime::currentDateTimeUtc ();
|
||||
if (now >= QDateTime {{2024, 01, 15}, {23, 59, 59, 999}, Qt::UTC}) {
|
||||
if (now >= QDateTime {{2024, 10, 30}, {23, 59, 59, 999}, Qt::UTC}) {
|
||||
Q_EMIT finished ();
|
||||
}
|
||||
}
|
||||
@ -1206,6 +1225,16 @@ void MainWindow::writeSettings()
|
||||
m_settings->setValue ("SerialNumber",ui->sbSerialNumber->value ());
|
||||
m_settings->endGroup();
|
||||
|
||||
// do this in the General group because we save the parameters from various places
|
||||
if(m_mode=="JT9") {
|
||||
m_settings->setValue("SubMode",ui->sbSubmode->value());
|
||||
m_settings->setValue("TRPeriod", ui->sbTR->value());
|
||||
}
|
||||
if(m_mode=="MSK144") m_settings->setValue("ShMsgs_MSK144",m_bShMsgs);
|
||||
if(m_mode=="Q65") m_settings->setValue("ShMsgs_Q65",m_bShMsgs);
|
||||
if(m_mode=="JT65") m_settings->setValue("ShMsgs_JT65",m_bShMsgs);
|
||||
if(m_mode=="JT4") m_settings->setValue("ShMsgs_JT4",m_bShMsgs);
|
||||
|
||||
m_settings->beginGroup("Common");
|
||||
m_settings->setValue("Mode",m_mode);
|
||||
m_settings->setValue("SaveNone",ui->actionNone->isChecked());
|
||||
@ -1219,13 +1248,12 @@ void MainWindow::writeSettings()
|
||||
m_settings->setValue("FST4W_FTol",ui->sbFST4W_FTol->value());
|
||||
m_settings->setValue("FST4_FLow",ui->sbF_Low->value());
|
||||
m_settings->setValue("FST4_FHigh",ui->sbF_High->value());
|
||||
// m_settings->setValue("SubMode",ui->sbSubmode->value());
|
||||
m_settings->setValue("DTtol",m_DTtol);
|
||||
m_settings->setValue("Ftol", ui->sbFtol->value ());
|
||||
m_settings->setValue("MinSync",m_minSync);
|
||||
m_settings->setValue ("AutoSeq", ui->cbAutoSeq->isChecked ());
|
||||
m_settings->setValue ("RxAll", ui->cbRxAll->isChecked ());
|
||||
m_settings->setValue("ShMsgs",m_bShMsgs);
|
||||
// m_settings->setValue("ShMsgs",m_bShMsgs);
|
||||
m_settings->setValue("SWL",ui->cbSWL->isChecked());
|
||||
m_settings->setValue ("DialFreq", QVariant::fromValue(m_lastMonitoredFrequency));
|
||||
m_settings->setValue("OutAttenuation", ui->outAttenuation->value ());
|
||||
@ -1241,7 +1269,6 @@ void MainWindow::writeSettings()
|
||||
m_settings->setValue("UploadSpots",m_uploadWSPRSpots);
|
||||
m_settings->setValue("NoOwnCall",ui->cbNoOwnCall->isChecked());
|
||||
m_settings->setValue ("BandHopping", ui->band_hopping_group_box->isChecked ());
|
||||
// m_settings->setValue ("TRPeriod", ui->sbTR->value ());
|
||||
m_settings->setValue ("MaxDrift", ui->sbMaxDrift->value());
|
||||
m_settings->setValue ("TRPeriod_FST4W", ui->sbTR_FST4W->value ());
|
||||
m_settings->setValue("FastMode",m_bFastMode);
|
||||
@ -1309,16 +1336,58 @@ void MainWindow::readSettings()
|
||||
ui->sbSerialNumber->setValue (m_settings->value ("SerialNumber", 1).toInt ());
|
||||
m_settings->endGroup();
|
||||
|
||||
m_settings->beginGroup("Common");
|
||||
m_mode=m_settings->value("Mode","FT8").toString();
|
||||
m_settings->endGroup();
|
||||
|
||||
|
||||
// do this outside of settings group because it uses groups internally
|
||||
ui->actionAstronomical_data->setChecked (displayAstro);
|
||||
|
||||
// do this in the General group because we save the parameters from various places
|
||||
if(m_mode=="JT9") {
|
||||
blocked=true;
|
||||
m_nSubMode=m_settings->value("SubMode",0).toInt();
|
||||
ui->sbSubmode->setValue(m_nSubMode);
|
||||
ui->sbFtol->setValue (m_settings->value("Ftol_JT9", 50).toInt());
|
||||
ui->sbTR->setValue (m_settings->value ("TRPeriod", 15).toInt());
|
||||
QTimer::singleShot (50, [=] {blocked = false;});
|
||||
}
|
||||
if (m_mode=="Q65") {
|
||||
m_nSubMode=m_settings->value("SubMode_Q65",0).toInt();
|
||||
ui->sbSubmode->setValue(m_nSubMode_Q65);
|
||||
ui->sbFtol->setValue (m_settings->value("Ftol_Q65", 50).toInt());
|
||||
ui->sbTR->setValue (m_settings->value ("TRPeriod_Q65", 30).toInt());
|
||||
}
|
||||
if (m_mode=="JT65") {
|
||||
m_nSubMode=m_settings->value("SubMode_JT65",0).toInt();
|
||||
ui->sbSubmode->setValue(m_nSubMode_JT65);
|
||||
ui->sbFtol->setValue (m_settings->value("Ftol_JT65", 50).toInt());
|
||||
}
|
||||
if (m_mode=="JT4") {
|
||||
m_nSubMode=m_settings->value("SubMode_JT4",0).toInt();
|
||||
ui->sbSubmode->setValue(m_nSubMode_JT4);
|
||||
ui->sbFtol->setValue (m_settings->value("Ftol_JT4", 50).toInt());
|
||||
ui->sbTR->setValue (m_settings->value ("TRPeriod_FST4", 60).toInt());
|
||||
}
|
||||
if (m_mode=="MSK144") {
|
||||
ui->sbFtol->setValue (m_settings->value("Ftol_MSK144",50).toInt());
|
||||
if (!(m_currentBand=="6m" or m_currentBand=="4m" or m_currentBand=="2m")) ui->sbTR->setValue (m_settings->value ("TRPeriod_MSK144", 30).toInt());
|
||||
if (m_currentBand=="6m" or m_currentBand=="4m") ui->sbTR->setValue (m_settings->value ("TRPeriod_MSK144_6m", 15).toInt());
|
||||
if (m_currentBand=="2m") ui->sbTR->setValue (m_settings->value ("TRPeriod_MSK144_2m", 30).toInt());
|
||||
}
|
||||
if (m_mode=="MSK144") m_bShMsgs=m_settings->value("ShMsgs_MSK144",false).toBool();
|
||||
if (m_mode=="Q65") m_bShMsgs=m_settings->value("ShMsgs_Q65",false).toBool();
|
||||
if (m_mode=="JT65") m_bShMsgs=m_settings->value("ShMsgs_JT65",false).toBool();
|
||||
if (m_mode=="JT4") m_bShMsgs=m_settings->value("ShMsgs_JT4",false).toBool();
|
||||
|
||||
m_settings->beginGroup("Common");
|
||||
ui->labDXped->setText(m_settings->value("labDXpedText",QString {}).toString ());
|
||||
ui->actionDon_t_split_ALL_TXT->setChecked(m_settings->value("actionDontSplitALLTXT", true).toBool());
|
||||
ui->actionSplit_ALL_TXT_yearly->setChecked(m_settings->value("splitAllTxtYearly", false).toBool());
|
||||
ui->actionSplit_ALL_TXT_monthly->setChecked(m_settings->value("splitAllTxtMonthly", false).toBool());
|
||||
ui->actionDisable_writing_of_ALL_TXT->setChecked(m_settings->value("disableWritingOfAllTxt", false).toBool());
|
||||
m_mode=m_settings->value("Mode","FT8").toString();
|
||||
// m_mode=m_settings->value("Mode","FT8").toString();
|
||||
ui->actionNone->setChecked(m_settings->value("SaveNone",true).toBool());
|
||||
ui->actionSave_decoded->setChecked(m_settings->value("SaveDecoded",false).toBool());
|
||||
ui->actionSave_all->setChecked(m_settings->value("SaveAll",false).toBool());
|
||||
@ -1328,28 +1397,16 @@ void MainWindow::readSettings()
|
||||
ui->sbFST4W_RxFreq->setValue(m_settings->value("FST4W_RxFreq",1500).toInt());
|
||||
ui->sbF_Low->setValue(m_settings->value("FST4_FLow",600).toInt());
|
||||
ui->sbF_High->setValue(m_settings->value("FST4_FHigh",1400).toInt());
|
||||
// m_nSubMode=m_settings->value("SubMode",0).toInt();
|
||||
if (m_mode=="Q65") m_nSubMode=m_settings->value("SubMode_Q65",0).toInt();
|
||||
if (m_mode=="JT65") m_nSubMode=m_settings->value("SubMode_JT65",0).toInt();
|
||||
if (m_mode=="JT4") m_nSubMode=m_settings->value("SubMode_JT4",0).toInt();
|
||||
// ui->sbSubmode->setValue(m_nSubMode);
|
||||
if (m_mode=="Q65") ui->sbSubmode->setValue(m_nSubMode_Q65);
|
||||
if (m_mode=="JT65") ui->sbSubmode->setValue(m_nSubMode_JT65);
|
||||
if (m_mode=="JT4") ui->sbSubmode->setValue(m_nSubMode_JT4);
|
||||
ui->sbFtol->setValue (m_settings->value("Ftol", 50).toInt());
|
||||
ui->sbFST4W_FTol->setValue(m_settings->value("FST4W_FTol",100).toInt());
|
||||
m_minSync=m_settings->value("MinSync",0).toInt();
|
||||
ui->syncSpinBox->setValue(m_minSync);
|
||||
ui->cbAutoSeq->setChecked (m_settings->value ("AutoSeq", false).toBool());
|
||||
ui->cbRxAll->setChecked (m_settings->value ("RxAll", false).toBool());
|
||||
m_bShMsgs=m_settings->value("ShMsgs",false).toBool();
|
||||
// m_bShMsgs=m_settings->value("ShMsgs",false).toBool();
|
||||
m_bSWL=m_settings->value("SWL",false).toBool();
|
||||
m_bFast9=m_settings->value("Fast9",false).toBool();
|
||||
m_bFastMode=m_settings->value("FastMode",false).toBool();
|
||||
// ui->sbTR->setValue (m_settings->value ("TRPeriod", 15).toInt());
|
||||
if (m_mode=="Q65") ui->sbTR->setValue (m_settings->value ("TRPeriod_Q65", 30).toInt());
|
||||
if (m_mode=="MSK144") ui->sbTR->setValue (m_settings->value ("TRPeriod_MSK144", 15).toInt());
|
||||
if (m_mode=="FST4") ui->sbTR->setValue (m_settings->value ("TRPeriod_FST4", 60).toInt());
|
||||
ui->sbMaxDrift->setValue (m_settings->value ("MaxDrift",0).toInt());
|
||||
ui->sbTR_FST4W->setValue (m_settings->value ("TRPeriod_FST4W", 15).toInt());
|
||||
m_lastMonitoredFrequency = m_settings->value ("DialFreq",
|
||||
@ -1677,6 +1734,7 @@ void MainWindow::dataSink(qint64 frames)
|
||||
float width=m_fSpread;
|
||||
echocom_.nclearave=m_nclearave;
|
||||
int nDop=m_fAudioShift;
|
||||
if(m_astroWidget->DopplerMethod()==2) nDop=0; //Using CFOM
|
||||
int nDopTotal=m_fDop;
|
||||
int navg=ui->sbEchoAvg->value();
|
||||
if(m_diskData) {
|
||||
@ -2193,6 +2251,13 @@ void MainWindow::keyPressEvent (QKeyEvent * e)
|
||||
bool bAltF1F6=m_config.alternate_bindings();
|
||||
switch(e->key())
|
||||
{
|
||||
case Qt::Key_A:
|
||||
if(m_mode=="Q65" && e->modifiers() & Qt::AltModifier) {
|
||||
m_EMECall.clear();
|
||||
qmapcom.ndecodes=0;
|
||||
readWidebandDecodes();
|
||||
}
|
||||
return;
|
||||
case Qt::Key_B:
|
||||
if(m_mode=="FT4" && e->modifiers() & Qt::AltModifier) {
|
||||
on_pbBestSP_clicked();
|
||||
@ -2491,16 +2556,37 @@ void MainWindow::statusChanged()
|
||||
.arg (f.fileName ()).arg (f.errorString ()));
|
||||
}
|
||||
on_dxGridEntry_textChanged(m_hisGrid);
|
||||
if(m_specOp!=SpecOp::HOUND) {
|
||||
ui->txb2->setEnabled(true);
|
||||
ui->txrb2->setEnabled(true);
|
||||
ui->txb4->setEnabled(true);
|
||||
ui->txrb4->setEnabled(true);
|
||||
ui->txb5->setEnabled(true);
|
||||
ui->txrb5->setEnabled(true);
|
||||
ui->txb6->setEnabled(true);
|
||||
ui->txrb6->setEnabled(true);
|
||||
ui->houndButton->setChecked(false);
|
||||
if (m_specOp!=SpecOp::HOUND) {
|
||||
ui->txb2->setEnabled(true);
|
||||
ui->txrb2->setEnabled(true);
|
||||
ui->txb4->setEnabled(true);
|
||||
ui->txrb4->setEnabled(true);
|
||||
ui->txb5->setEnabled(true);
|
||||
ui->txrb5->setEnabled(true);
|
||||
ui->txb6->setEnabled(true);
|
||||
ui->txrb6->setEnabled(true);
|
||||
ui->houndButton->setChecked(false);
|
||||
}
|
||||
if (m_config.enable_VHF_features() && (m_mode=="JT4" or m_mode=="Q65" or m_mode=="JT65")) {
|
||||
ui->actionInclude_averaging->setVisible(true);
|
||||
ui->actionAuto_Clear_Avg->setVisible(true);
|
||||
} else {
|
||||
ui->actionInclude_averaging->setVisible(false);
|
||||
ui->actionAuto_Clear_Avg->setVisible(false);
|
||||
}
|
||||
if (m_mode=="JT4" or m_mode=="Q65" or m_mode=="JT65") {
|
||||
if (ui->actionInclude_averaging->isVisible() && ui->actionInclude_averaging->isChecked()) {
|
||||
ui->lh_decodes_title_label->setText(tr ("Single-Period Decodes"));
|
||||
ui->rh_decodes_title_label->setText(tr ("Average Decodes"));
|
||||
} else {
|
||||
if (m_config.enable_VHF_features()) {
|
||||
ui->lh_decodes_title_label->setText(tr ("Band Activity"));
|
||||
ui->rh_decodes_title_label->setText(tr ("Decodes containing My Call"));
|
||||
} else {
|
||||
ui->lh_decodes_title_label->setText(tr ("Band Activity"));
|
||||
ui->rh_decodes_title_label->setText(tr ("Rx Frequency"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2803,7 +2889,7 @@ void MainWindow::on_actionCopyright_Notice_triggered()
|
||||
"\"The algorithms, source code, look-and-feel of WSJT-X and related "
|
||||
"programs, and protocol specifications for the modes FSK441, FST4, FT8, "
|
||||
"JT4, JT6M, JT9, JT65, JTMS, QRA64, Q65, MSK144 are Copyright (C) "
|
||||
"2001-2023 by one or more of the following authors: Joseph Taylor, "
|
||||
"2001-2024 by one or more of the following authors: Joseph Taylor, "
|
||||
"K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo, "
|
||||
"IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR; "
|
||||
"Philip Karn, KA9Q; Uwe Risse, DG2YCB; Brian Moran, N9ADG; "
|
||||
@ -3180,6 +3266,7 @@ void MainWindow::on_actionKeyboard_shortcuts_triggered()
|
||||
<tr><td><b>Ctrl+Shift+F12 </b></td><td>Move dial frequency up 1000 Hz</td></tr>
|
||||
<tr><td><b>Alt+1-6 </b></td><td>Set now transmission to this number on Tab 1</td></tr>
|
||||
<tr><td><b>Ctl+1-6 </b></td><td>Set next transmission to this number on Tab 1</td></tr>
|
||||
<tr><td><b>Alt+A </b></td><td>Clear Active Stations for QMAP</td></tr>
|
||||
<tr><td><b>Alt+B </b></td><td>Toggle "Best S+P" status</td></tr>
|
||||
<tr><td><b>Alt+C </b></td><td>Toggle "Call 1st" checkbox</td></tr>
|
||||
<tr><td><b>Alt+D </b></td><td>Decode again at QSO frequency</td></tr>
|
||||
@ -3226,7 +3313,7 @@ void MainWindow::on_actionSpecial_mouse_commands_triggered()
|
||||
<td><b>Click</b> to set Rx frequency.<br/>
|
||||
<b>Shift-click</b> to set Tx frequency.<br/>
|
||||
<b>Ctrl-click</b> or <b>Right-click</b> to set Rx and Tx frequencies.<br/>
|
||||
<b>Double-click</b> to also decode at Rx frequency.<br/>
|
||||
<b>Double-click</b> to also decode at Rx frequency.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -3237,7 +3324,7 @@ void MainWindow::on_actionSpecial_mouse_commands_triggered()
|
||||
messages.<br/>
|
||||
If <b>Hold Tx Freq</b> is checked or first callsign in message<br/>
|
||||
is your own call, Tx frequency is not changed unless <br/>
|
||||
<b>Ctrl</b> is held down.<br/>
|
||||
<b>Ctrl</b> is held down.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -3246,6 +3333,18 @@ void MainWindow::on_actionSpecial_mouse_commands_triggered()
|
||||
<b>Double-click</b> to erase QSO and Band Activity windows.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Q65 Button:</td>
|
||||
<td><b>Click</b> to switch to Q65 Mode.<br/>
|
||||
<b>Right-click</b> to switch to Q65 Pileup Mode.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">JT65 Button:</td>
|
||||
<td><b>Click</b> to switch to JT65 Mode.<br/>
|
||||
<b>Right-click</b> to switch to JT9 Mode.
|
||||
</td>
|
||||
</tr>
|
||||
</table>)"), font});
|
||||
}
|
||||
m_mouseCmnds->showNormal ();
|
||||
@ -3830,9 +3929,9 @@ void MainWindow::callSandP2(int n)
|
||||
int nMHz=m_freqNominal/1000000;
|
||||
m_freqNominal=(nMHz*1000 + kHz)* 1000;
|
||||
}
|
||||
m_deCall=w[3];
|
||||
m_deGrid=w[4];
|
||||
m_txFirst=(w[5]=="0");
|
||||
m_deCall=w[4];
|
||||
m_deGrid=w[5];
|
||||
m_txFirst=(w[6]=="0");
|
||||
// ui->TxFreqSpinBox->setValue(1500);
|
||||
} else {
|
||||
m_deCall=w[0];
|
||||
@ -3840,6 +3939,18 @@ void MainWindow::callSandP2(int n)
|
||||
ui->RxFreqSpinBox->setValue(w[4].toInt());
|
||||
m_txFirst = (w[5]=="0");
|
||||
}
|
||||
|
||||
if(w[3].left(2)=="30") {
|
||||
ui->sbTR->setValue(30);
|
||||
} else {
|
||||
ui->sbTR->setValue(60);
|
||||
}
|
||||
if(w[3].right(1)=="A") ui->sbSubmode->setValue(0);
|
||||
if(w[3].right(1)=="B") ui->sbSubmode->setValue(1);
|
||||
if(w[3].right(1)=="C") ui->sbSubmode->setValue(2);
|
||||
if(w[3].right(1)=="D") ui->sbSubmode->setValue(3);
|
||||
if(w[3].right(1)=="E") ui->sbSubmode->setValue(4);
|
||||
|
||||
m_bDoubleClicked=true; //### needed?
|
||||
ui->dxCallEntry->setText(m_deCall);
|
||||
ui->dxGridEntry->setText(m_deGrid);
|
||||
@ -3851,7 +3962,14 @@ void MainWindow::callSandP2(int n)
|
||||
}
|
||||
setTxMsg(1);
|
||||
ui->txFirstCheckBox->setChecked(m_txFirst);
|
||||
if (!ui->autoButton->isChecked()) ui->autoButton->click(); // Enable Tx
|
||||
static qint64 ms0=0;
|
||||
qint64 ms=QDateTime::currentMSecsSinceEpoch();
|
||||
if(ui->autoButton->isChecked()) {
|
||||
if((ms-ms0)<=500) ui->autoButton->click(); // Disable Tx on double click
|
||||
} else if((ms-ms0)>500) {
|
||||
ui->autoButton->click(); // Enable Tx on single click
|
||||
}
|
||||
ms0=ms;
|
||||
if(m_transmitting) m_restart=true;
|
||||
}
|
||||
|
||||
@ -4154,7 +4272,9 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
if((abs(audioFreq - m_wideGraph->rxFreq()) <= 10) and
|
||||
!m_config.enable_VHF_features()) bDisplayRight=true;
|
||||
}
|
||||
if(m_mode=="Q65" and !bAvgMsg) bDisplayRight=false;
|
||||
if(m_mode=="Q65" and !bAvgMsg and !decodedtext.string().contains(m_baseCall)) bDisplayRight=false;
|
||||
if((m_mode=="JT4" or m_mode=="Q65" or m_mode=="JT65") and decodedtext.string().contains(m_baseCall) && ui->actionInclude_averaging->isVisible() && !ui->actionInclude_averaging->isChecked()) bDisplayRight=true;
|
||||
if(m_mode=="FT8" and SpecOp::HOUND==m_specOp && decodedtext0.string().replace("<","").replace(">","").contains(" " + m_baseCall + " ")) bDisplayRight=true;
|
||||
|
||||
if (bDisplayRight) {
|
||||
// This msg is within 10 hertz of our tuned frequency, or a JT4 or JT65 avg,
|
||||
@ -4980,19 +5100,24 @@ void MainWindow::guiUpdate()
|
||||
if(m_decoderBusy) n=1;
|
||||
ipc_qmap[3]=n;
|
||||
n=0;
|
||||
if(m_transmitting) n=1;
|
||||
if(m_transmitting) n=m_TRperiod;
|
||||
ipc_qmap[4]=n;
|
||||
if(ipc_qmap[0] > 0) { //ndecodes
|
||||
memcpy(&qmapcom, (char*)ipc_qmap, sizeof(qmapcom)); //Fetch the new decode(s)
|
||||
readWidebandDecodes();
|
||||
}
|
||||
if(ipc_qmap[5]>0) {
|
||||
// qDebug() << "aa" << m_freqNominal << ipc_qmap[5];
|
||||
setRig((m_freqNominal/1000000)*1000000 + 1000*ipc_qmap[5]);
|
||||
ipc_qmap[5]=0;
|
||||
// qDebug() << "bb" << m_freqNominal << ipc_qmap[5];
|
||||
}
|
||||
mem_qmap.unlock();
|
||||
}
|
||||
|
||||
//Once per second (onesec)
|
||||
if(nsec != m_sec0) {
|
||||
// qDebug() << "AAA" << nsec%60 << int(m_specOp);
|
||||
|
||||
// qDebug() << "AAA" << nsec%60 << ipc_qmap[5];
|
||||
if(m_mode=="FST4") chk_FST4_freq_range();
|
||||
m_currentBand=m_config.bands()->find(m_freqNominal);
|
||||
if( SpecOp::HOUND == m_specOp ) {
|
||||
@ -5398,7 +5523,24 @@ void MainWindow::doubleClickOnCall(Qt::KeyboardModifiers modifiers)
|
||||
} else {
|
||||
cursor=ui->decodedTextBrowser2->textCursor();
|
||||
}
|
||||
|
||||
DecodedText message {cursor.block().text().trimmed().left(61).remove("TU; ")};
|
||||
if(message.string().contains(";") && message.string().contains("<")) {
|
||||
QVector<qint32> Freq = {1840000,3573000,7074000,10136000,14074000,18100000,21074000,24915000,28074000,50313000,70154000,3575000,7047500,10140000,14080000,18104000,21140000,24919000,28180000,50318000};
|
||||
for(int i=0; i<Freq.length()-1; i++) {
|
||||
int kHzdiff=m_freqNominal - Freq[i];
|
||||
if(qAbs(kHzdiff) < 3000 ) {
|
||||
m_bTxTime=false;
|
||||
if (m_auto) auto_tx_mode (false);
|
||||
if (m_tune) stop_tuning();
|
||||
// auto const& msg2 = tr("Double-clicking on combined messages\n"
|
||||
// "not allowed on the standard FT8 sub-bands.");
|
||||
// QTimer::singleShot (0, [=] { // don't block guiUpdate
|
||||
// MessageBox::warning_message (this, tr ("Potential hash collision"), msg2);
|
||||
// });
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(modifiers==(Qt::ShiftModifier + Qt::ControlModifier + Qt::AltModifier)) {
|
||||
//### What was the purpose of this ??? ###
|
||||
cursor.setPosition(0);
|
||||
@ -5413,7 +5555,6 @@ void MainWindow::doubleClickOnCall(Qt::KeyboardModifiers modifiers)
|
||||
}
|
||||
return;
|
||||
}
|
||||
DecodedText message {cursor.block().text().trimmed().left(61).remove("TU; ")};
|
||||
m_bDoubleClicked = true;
|
||||
processMessage (message, modifiers);
|
||||
}
|
||||
@ -5517,7 +5658,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
||||
|
||||
QString firstcall = message.call();
|
||||
if(firstcall.length()>=4 and firstcall.mid(0,3)=="CQ ") firstcall="CQ";
|
||||
if(!m_bFastMode and (!m_config.enable_VHF_features() or m_mode=="FT8")) {
|
||||
if(!m_bFastMode and (!m_config.enable_VHF_features() or m_mode=="FT8" or m_mode=="FT4" or m_mode=="FST4")) {
|
||||
// Don't change Tx freq if in a fast mode, or VHF features enabled; also not if a
|
||||
// station is calling me, unless CTRL or SHIFT is held down.
|
||||
if ((Radio::is_callsign (firstcall)
|
||||
@ -5973,7 +6114,7 @@ void MainWindow::genCQMsg ()
|
||||
( tlist.at(1)==my_callsign or
|
||||
tlist.at(2)==my_callsign ) and
|
||||
stdCall(my_callsign)) {
|
||||
if(m_config.Individual_Contest_Name()) {
|
||||
if(m_config.Individual_Contest_Name() && SpecOp::FOX != m_specOp) {
|
||||
m_cqStr = m_config.Contest_Name();
|
||||
} else {
|
||||
if(SpecOp::NA_VHF == m_specOp) m_cqStr="TEST";
|
||||
@ -6102,6 +6243,9 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional)
|
||||
t1 = t1.asprintf("%4.4d",ui->sbSerialNumber->value());
|
||||
sent=rst + t1;
|
||||
}
|
||||
if(t1.contains(QRegularExpression {"\\d\\d\\d\\d"})) {
|
||||
t1 = m_config.RTTY_Exchange();
|
||||
}
|
||||
}
|
||||
if(SpecOp::EU_VHF==m_specOp) {
|
||||
QString a;
|
||||
@ -6290,7 +6434,7 @@ void MainWindow::lookup()
|
||||
{
|
||||
QString hisCall {ui->dxCallEntry->text()};
|
||||
QString hisgrid0 {ui->dxGridEntry->text()};
|
||||
if (!hisCall.size ()) return;
|
||||
if (!hisCall.size () or (!(m_specOp==SpecOp::NONE or m_specOp==SpecOp::HOUND or m_specOp==SpecOp::Q65_PILEUP))) return;
|
||||
QFile f {m_config.writeable_data_dir ().absoluteFilePath ("CALL3.TXT")};
|
||||
if (f.open (QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
@ -6520,18 +6664,14 @@ void MainWindow::on_RoundRobin_currentTextChanged(QString text)
|
||||
|
||||
void MainWindow::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if(ui->q65Button->hasFocus() && (event->button() & Qt::RightButton)) {
|
||||
m_specOp=m_config.special_op_id();
|
||||
if (m_specOp==SpecOp::Q65_PILEUP) {
|
||||
m_config.setSpecial_None();
|
||||
ui->tx1->setEnabled(true);
|
||||
ui->txb1->setEnabled(true);
|
||||
} else {
|
||||
m_config.setSpecial_Q65_Pileup();
|
||||
}
|
||||
if(ui->q65Button->hasFocus() && (event->button() & Qt::RightButton)) { // switch to Q65_Pileup mode
|
||||
m_config.setSpecial_Q65_Pileup();
|
||||
m_specOp=m_config.special_op_id();
|
||||
on_actionQ65_triggered();
|
||||
}
|
||||
if(ui->jt65Button->hasFocus() && (event->button() & Qt::RightButton)) { // switch to JT9 mode
|
||||
on_actionJT9_triggered();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_dxCallEntry_textChanged (QString const& call)
|
||||
@ -6651,6 +6791,10 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button
|
||||
m_xSent=m_config.my_grid().left(4);
|
||||
m_xRcvd=m_hisGrid;
|
||||
break;
|
||||
case SpecOp::Q65_PILEUP:
|
||||
m_xSent=m_config.my_grid().left(4);
|
||||
m_xRcvd=m_hisGrid;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
@ -6840,6 +6984,10 @@ void MainWindow::on_actionFST4_triggered()
|
||||
on_sbSubmode_valueChanged(ui->sbSubmode->value());
|
||||
});
|
||||
m_mode="FST4";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
ui->actionFST4->setChecked(true);
|
||||
m_bFast9=false;
|
||||
m_bFastMode=false;
|
||||
@ -6882,6 +7030,10 @@ void MainWindow::on_actionFST4_triggered()
|
||||
void MainWindow::on_actionFST4W_triggered()
|
||||
{
|
||||
m_mode="FST4W";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
ui->actionFST4W->setChecked(true);
|
||||
m_bFast9=false;
|
||||
m_bFastMode=false;
|
||||
@ -6917,6 +7069,10 @@ void MainWindow::on_actionFT4_triggered()
|
||||
on_sbSubmode_valueChanged(ui->sbSubmode->value());
|
||||
});
|
||||
m_mode="FT4";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
m_TRperiod=7.5;
|
||||
bool bVHF=m_config.enable_VHF_features();
|
||||
m_bFast9=false;
|
||||
@ -7083,6 +7239,10 @@ void MainWindow::on_actionJT4_triggered()
|
||||
ui->RxFreqSpinBox->setValue(m_settings->value("RxFreq_old",1500).toInt());
|
||||
});
|
||||
m_mode="JT4";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
bool bVHF=m_config.enable_VHF_features();
|
||||
WSPR_config(false);
|
||||
switch_mode (Modes::JT4);
|
||||
@ -7103,15 +7263,16 @@ void MainWindow::on_actionJT4_triggered()
|
||||
m_bFast9=false;
|
||||
setup_status_bar (bVHF);
|
||||
ui->sbSubmode->setMaximum(6);
|
||||
ui->lh_decodes_title_label->setText(tr ("Single-Period Decodes"));
|
||||
ui->rh_decodes_title_label->setText(tr ("Average Decodes"));
|
||||
ui->lh_decodes_headings_label->setText("UTC dB DT Freq " + tr ("Message"));
|
||||
ui->rh_decodes_headings_label->setText("UTC dB DT Freq " + tr ("Message"));
|
||||
if(bVHF) {
|
||||
// ui->sbSubmode->setValue(m_nSubMode);
|
||||
QTimer::singleShot (50, [=] {m_nSubMode=m_settings->value("SubMode_JT4",0).toInt();});
|
||||
QTimer::singleShot (75, [=] {ui->sbSubmode->setValue(m_settings->value("SubMode_JT4",0).toInt());});
|
||||
QTimer::singleShot (100, [=] {on_sbSubmode_valueChanged(m_nSubMode);});
|
||||
// restore last used parameters
|
||||
ui->sbFtol->setValue (m_settings->value ("Ftol_JT4", 50).toInt());
|
||||
m_nSubMode=m_settings->value("SubMode_JT4",0).toInt();
|
||||
ui->sbSubmode->setValue(m_settings->value("SubMode_JT4",0).toInt());
|
||||
QTimer::singleShot (50, [=] {on_sbSubmode_valueChanged(ui->sbSubmode->value());});
|
||||
m_bShMsgs=m_settings->value("ShMsgs_JT4",false).toBool();
|
||||
ui->cbShMsgs->setChecked(m_bShMsgs);
|
||||
} else {
|
||||
ui->sbSubmode->setValue(0);
|
||||
}
|
||||
@ -7128,8 +7289,25 @@ void MainWindow::on_actionJT4_triggered()
|
||||
void MainWindow::on_actionJT9_triggered()
|
||||
{
|
||||
m_mode="JT9";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
bool bVHF=m_config.enable_VHF_features();
|
||||
m_bFast9=ui->cbFast9->isChecked();
|
||||
// restore last used parameters
|
||||
if(bVHF && m_mode!="JT65" && !blocked) {
|
||||
ui->sbSubmode->setMaximum(7);
|
||||
m_bFast9=m_settings->value("JT9_Fast",false).toBool();
|
||||
ui->cbFast9->setChecked(m_bFast9 or m_bFastMode);
|
||||
ui->sbFtol->setValue (m_settings->value ("Ftol_JT9", 50).toInt());
|
||||
m_nSubMode=m_settings->value("SubMode",0).toInt();
|
||||
ui->sbSubmode->setValue(m_nSubMode);
|
||||
QTimer::singleShot (50, [=] {
|
||||
on_sbTR_valueChanged (ui->sbTR->value());
|
||||
on_sbSubmode_valueChanged(ui->sbSubmode->value());
|
||||
});
|
||||
}
|
||||
// m_bFast9=ui->cbFast9->isChecked();
|
||||
m_bFastMode=m_bFast9;
|
||||
WSPR_config(false);
|
||||
switch_mode (Modes::JT9);
|
||||
@ -7152,6 +7330,7 @@ void MainWindow::on_actionJT9_triggered()
|
||||
ui->sbSubmode->setMaximum(7);
|
||||
if(m_bFast9) {
|
||||
ui->sbTR->values ({5, 10, 15, 30});
|
||||
if(bVHF && m_mode!="JT65" && !blocked) ui->sbTR->setValue (m_settings->value ("TRPeriod", 15).toInt()); // restore last used TRperiod
|
||||
on_sbTR_valueChanged (ui->sbTR->value());
|
||||
m_wideGraph->hide();
|
||||
m_fastGraph->showNormal();
|
||||
@ -7191,6 +7370,10 @@ void MainWindow::on_actionJT65_triggered()
|
||||
ui->RxFreqSpinBox->setValue(m_settings->value("RxFreq_old",1500).toInt());
|
||||
});
|
||||
on_actionJT9_triggered();
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
m_mode="JT65";
|
||||
bool bVHF=m_config.enable_VHF_features();
|
||||
WSPR_config(false);
|
||||
@ -7216,12 +7399,13 @@ void MainWindow::on_actionJT65_triggered()
|
||||
m_bFast9=false;
|
||||
ui->sbSubmode->setMaximum(2);
|
||||
if(bVHF) {
|
||||
// ui->sbSubmode->setValue(m_nSubMode);
|
||||
QTimer::singleShot (50, [=] {m_nSubMode=m_settings->value("SubMode_JT65",0).toInt();});
|
||||
QTimer::singleShot (75, [=] {ui->sbSubmode->setValue(m_settings->value("SubMode_JT65",0).toInt());});
|
||||
QTimer::singleShot (100, [=] {on_sbSubmode_valueChanged(m_nSubMode);});
|
||||
ui->lh_decodes_title_label->setText(tr ("Single-Period Decodes"));
|
||||
ui->rh_decodes_title_label->setText(tr ("Average Decodes"));
|
||||
// restore last used parameters
|
||||
ui->sbFtol->setValue (m_settings->value ("Ftol_JT65", 50).toInt());
|
||||
m_nSubMode=m_settings->value("SubMode_JT65",0).toInt();
|
||||
ui->sbSubmode->setValue(m_settings->value("SubMode_JT65",0).toInt());
|
||||
QTimer::singleShot (50, [=] {on_sbSubmode_valueChanged(ui->sbSubmode->value());});
|
||||
m_bShMsgs=m_settings->value("ShMsgs_JT65",false).toBool();
|
||||
ui->cbShMsgs->setChecked(m_bShMsgs);
|
||||
} else {
|
||||
ui->sbSubmode->setValue(0);
|
||||
ui->lh_decodes_title_label->setText(tr ("Band Activity"));
|
||||
@ -7248,6 +7432,10 @@ void MainWindow::on_actionQ65_triggered()
|
||||
ui->RxFreqSpinBox->setValue(m_settings->value("RxFreq_old",1500).toInt());
|
||||
});
|
||||
m_mode="Q65";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
ui->actionQ65->setChecked(true);
|
||||
switch_mode(Modes::Q65);
|
||||
ui->cbAutoSeq->setChecked(true);
|
||||
@ -7261,12 +7449,17 @@ void MainWindow::on_actionQ65_triggered()
|
||||
Q_EMIT FFTSize(m_FFTSize);
|
||||
m_hsymStop=49;
|
||||
ui->sbTR->values ({15, 30, 60, 120, 300});
|
||||
ui->sbTR->setValue (m_settings->value ("TRPeriod_Q65", 30).toInt()); // remember sbTR settings by mode
|
||||
QTimer::singleShot (50, [=] {on_sbTR_valueChanged (ui->sbTR->value());});
|
||||
// ui->sbSubmode->setValue(m_nSubMode);
|
||||
QTimer::singleShot (50, [=] {m_nSubMode=m_settings->value("SubMode_Q65",0).toInt();});
|
||||
QTimer::singleShot (75, [=] {ui->sbSubmode->setValue(m_settings->value("SubMode_Q65",0).toInt());});
|
||||
QTimer::singleShot (100, [=] {on_sbSubmode_valueChanged(m_nSubMode);});
|
||||
// restore last used parameters
|
||||
ui->sbTR->setValue (m_settings->value ("TRPeriod_Q65", 30).toInt());
|
||||
ui->sbFtol->setValue (m_settings->value ("Ftol_Q65", 50).toInt());
|
||||
m_nSubMode=m_settings->value("SubMode_Q65",0).toInt();
|
||||
ui->sbSubmode->setValue(m_settings->value("SubMode_Q65",0).toInt());
|
||||
QTimer::singleShot (50, [=] {
|
||||
on_sbTR_valueChanged (ui->sbTR->value());
|
||||
on_sbSubmode_valueChanged(ui->sbSubmode->value());
|
||||
});
|
||||
m_bShMsgs=m_settings->value("ShMsgs_Q65",false).toBool();
|
||||
ui->cbShMsgs->setChecked(m_bShMsgs);
|
||||
QString fname {QDir::toNativeSeparators(m_config.temp_dir().absoluteFilePath ("red.dat"))};
|
||||
m_wideGraph->setRedFile(fname);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
@ -7277,8 +7470,6 @@ void MainWindow::on_actionQ65_triggered()
|
||||
switch_mode (Modes::Q65);
|
||||
// 01234567890123456789012345678901234567
|
||||
displayWidgets(nWidgets("11111101011011010011100000010000000011"));
|
||||
ui->lh_decodes_title_label->setText(tr ("Single-Period Decodes"));
|
||||
ui->rh_decodes_title_label->setText(tr ("Average Decodes"));
|
||||
ui->lh_decodes_headings_label->setText("UTC dB DT Freq " + tr ("Message"));
|
||||
ui->rh_decodes_headings_label->setText("UTC dB DT Freq " + tr ("Message"));
|
||||
|
||||
@ -7330,6 +7521,10 @@ void MainWindow::on_actionMSK144_triggered()
|
||||
return;
|
||||
}
|
||||
m_mode="MSK144";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
ui->actionMSK144->setChecked(true);
|
||||
switch_mode (Modes::MSK144);
|
||||
m_nsps=6;
|
||||
@ -7343,11 +7538,10 @@ void MainWindow::on_actionMSK144_triggered()
|
||||
m_bFastMode=true;
|
||||
m_bFast9=false;
|
||||
ui->sbTR->values ({5, 10, 15, 30});
|
||||
ui->sbTR->setValue (m_settings->value ("TRPeriod_MSK144", 15).toInt()); // remember sbTR settings by mode
|
||||
QTimer::singleShot (50, [=] {
|
||||
on_sbTR_valueChanged (ui->sbTR->value());
|
||||
on_sbSubmode_valueChanged(ui->sbSubmode->value());
|
||||
});
|
||||
ui->sbTR->setValue (m_settings->value ("TRPeriod_MSK144", 15).toInt()); // restore last used TRperiod
|
||||
QTimer::singleShot (50, [=] {on_sbTR_valueChanged (ui->sbTR->value());});
|
||||
m_bShMsgs=m_settings->value("ShMsgs_MSK144",false).toBool();
|
||||
ui->cbShMsgs->setChecked(m_bShMsgs);
|
||||
m_wideGraph->hide();
|
||||
m_fastGraph->showNormal();
|
||||
ui->TxFreqSpinBox->setValue(1500);
|
||||
@ -7388,6 +7582,10 @@ void MainWindow::on_actionMSK144_triggered()
|
||||
void MainWindow::on_actionWSPR_triggered()
|
||||
{
|
||||
m_mode="WSPR";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
WSPR_config(true);
|
||||
switch_mode (Modes::WSPR);
|
||||
m_TRperiod=120.0;
|
||||
@ -7424,6 +7622,10 @@ void MainWindow::on_actionEcho_triggered()
|
||||
if(nd==3) ui->actionDeepestDecode->setChecked (true);
|
||||
|
||||
m_mode="Echo";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
ui->actionEcho->setChecked(true);
|
||||
m_TRperiod=3.0;
|
||||
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||
@ -7458,6 +7660,10 @@ void MainWindow::on_actionFreqCal_triggered()
|
||||
{
|
||||
on_actionJT9_triggered();
|
||||
m_mode="FreqCal";
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
ui->actionFreqCal->setChecked(true);
|
||||
switch_mode(Modes::FreqCal);
|
||||
m_wideGraph->setMode(m_mode);
|
||||
@ -7652,6 +7858,7 @@ void MainWindow::on_actionDeepestDecode_toggled (bool checked)
|
||||
void MainWindow::on_actionInclude_averaging_toggled (bool checked)
|
||||
{
|
||||
m_ndepth ^= (-checked ^ m_ndepth) & 0x00000010;
|
||||
statusChanged();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionInclude_correlation_toggled (bool checked)
|
||||
@ -8008,6 +8215,7 @@ void MainWindow::setXIT(int n, Frequency base)
|
||||
|
||||
void MainWindow::setFreq4(int rxFreq, int txFreq)
|
||||
{
|
||||
if (m_mode=="ECHO") return; // we do not adjust rx/tx for echo mode -- always 1500Hz
|
||||
if (ui->RxFreqSpinBox->isEnabled ()) ui->RxFreqSpinBox->setValue(rxFreq);
|
||||
if(m_mode=="WSPR" or m_mode=="FST4W") {
|
||||
ui->WSPRfreqSpinBox->setValue(txFreq);
|
||||
@ -8449,6 +8657,14 @@ void MainWindow::on_sbFtol_valueChanged(int value)
|
||||
{
|
||||
m_wideGraph->setTol (value);
|
||||
statusUpdate ();
|
||||
// save last used parameters
|
||||
QTimer::singleShot (200, [=] {
|
||||
if (m_mode=="Q65") m_settings->setValue ("Ftol_Q65", ui->sbFtol->value());
|
||||
if (m_mode=="MSK144") m_settings->setValue ("Ftol_MSK144", ui->sbFtol->value());
|
||||
if (m_mode=="JT65") m_settings->setValue ("Ftol_JT65", ui->sbFtol->value ());
|
||||
if (m_mode=="JT4") m_settings->setValue ("Ftol_JT4", ui->sbFtol->value());
|
||||
if (m_mode=="JT9") m_settings->setValue ("Ftol_JT9", ui->sbFtol->value ());
|
||||
});
|
||||
}
|
||||
|
||||
void::MainWindow::VHF_features_enabled(bool b)
|
||||
@ -8510,19 +8726,25 @@ void MainWindow::on_sbTR_valueChanged(int value)
|
||||
m_wideGraph->setPeriod (value, m_nsps);
|
||||
progressBar.setMaximum (value);
|
||||
}
|
||||
if (m_mode=="Q65") {
|
||||
QTimer::singleShot (200, [=] {m_settings->setValue ("TRPeriod_Q65", ui->sbTR->value ());});
|
||||
}
|
||||
if (m_mode=="MSK144") {
|
||||
QTimer::singleShot (200, [=] {m_settings->setValue ("TRPeriod_MSK144", ui->sbTR->value ());});
|
||||
}
|
||||
if (m_mode=="FST4") {
|
||||
chk_FST4_freq_range();
|
||||
QTimer::singleShot (200, [=] {m_settings->setValue ("TRPeriod_FST4", ui->sbTR->value ());});
|
||||
}
|
||||
// if(m_transmitting) on_stopTxButton_clicked(); //### Is this needed or desirable? ###
|
||||
if (m_mode=="FST4") chk_FST4_freq_range();
|
||||
on_sbSubmode_valueChanged(ui->sbSubmode->value());
|
||||
statusUpdate ();
|
||||
// save last used parameters
|
||||
QTimer::singleShot (200, [=] {
|
||||
if (m_mode=="Q65") m_settings->setValue ("TRPeriod_Q65", ui->sbTR->value ());
|
||||
if (m_mode=="MSK144" && (!(m_currentBand=="6m" or m_currentBand=="4m" or m_currentBand=="2m"))) {
|
||||
m_settings->setValue ("TRPeriod_MSK144", ui->sbTR->value ());
|
||||
}
|
||||
if (m_mode=="MSK144" && (m_currentBand=="6m" or m_currentBand=="4m")) {
|
||||
m_settings->setValue ("TRPeriod_MSK144_6m", ui->sbTR->value ());
|
||||
}
|
||||
if (m_mode=="MSK144" && m_currentBand=="2m") {
|
||||
m_settings->setValue ("TRPeriod_MSK144_2m", ui->sbTR->value ());
|
||||
}
|
||||
if (m_mode=="FST4") m_settings->setValue ("TRPeriod_FST4", ui->sbTR->value ());
|
||||
if (m_mode=="JT9") m_settings->setValue ("TRPeriod", ui->sbTR->value ());
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::on_sbTR_FST4W_valueChanged(int value)
|
||||
@ -8569,17 +8791,21 @@ void MainWindow::on_sbSubmode_valueChanged(int n)
|
||||
ui->sbTR->setVisible(false);
|
||||
m_TRperiod=60.0;
|
||||
} else {
|
||||
ui->cbFast9->setEnabled(true);
|
||||
if(!blocked) ui->cbFast9->setEnabled(true);
|
||||
}
|
||||
ui->sbTR->setVisible(m_bFast9);
|
||||
if(m_bFast9) ui->TxFreqSpinBox->setValue(700);
|
||||
}
|
||||
if(m_transmitting and m_bFast9 and m_nSubMode>=4) transmit (99.0);
|
||||
if (m_mode !="Q65") ui->TxFreqSpinBox->setStyleSheet("");
|
||||
if (m_mode=="Q65") {QTimer::singleShot (200, [=] {m_settings->setValue("SubMode_Q65",ui->sbSubmode->value());});}
|
||||
if (m_mode=="JT65") {QTimer::singleShot (200, [=] {m_settings->setValue("SubMode_JT65",ui->sbSubmode->value());});}
|
||||
if (m_mode=="JT4") {QTimer::singleShot (200, [=] {m_settings->setValue("SubMode_JT4",ui->sbSubmode->value());});}
|
||||
statusUpdate ();
|
||||
// save last used parameters
|
||||
QTimer::singleShot (200, [=] {
|
||||
if (m_mode=="Q65") m_settings->setValue("SubMode_Q65",ui->sbSubmode->value());
|
||||
if (m_mode=="JT65") m_settings->setValue("SubMode_JT65",ui->sbSubmode->value());
|
||||
if (m_mode=="JT4") m_settings->setValue("SubMode_JT4",ui->sbSubmode->value());
|
||||
if (m_mode=="JT9") m_settings->setValue("SubMode",ui->sbSubmode->value());
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::on_cbFast9_clicked(bool b)
|
||||
@ -8587,7 +8813,12 @@ void MainWindow::on_cbFast9_clicked(bool b)
|
||||
if(m_mode=="JT9") {
|
||||
m_bFast9=b;
|
||||
// ui->cbAutoSeq->setVisible(b);
|
||||
blocked=true; // needed to prevent a loop
|
||||
on_actionJT9_triggered();
|
||||
QTimer::singleShot (50, [=] {blocked = false;}); // needed to prevent a loop
|
||||
QTimer::singleShot (200, [=] {
|
||||
if(m_mode=="JT9") m_settings->setValue("JT9_Fast",m_bFast9);
|
||||
});
|
||||
}
|
||||
|
||||
if(b) {
|
||||
@ -8619,6 +8850,12 @@ void MainWindow::on_cbShMsgs_toggled(bool b)
|
||||
if(ntx==4) ui->txrb4->setChecked(true);
|
||||
if(ntx==5) ui->txrb5->setChecked(true);
|
||||
if(ntx==6) ui->txrb6->setChecked(true);
|
||||
QTimer::singleShot (200, [=] {
|
||||
if(m_mode=="MSK144") m_settings->setValue("ShMsgs_MSK144",m_bShMsgs);
|
||||
if(m_mode=="Q65") m_settings->setValue("ShMsgs_Q65",m_bShMsgs);
|
||||
if(m_mode=="JT65") m_settings->setValue("ShMsgs_JT65",m_bShMsgs);
|
||||
if(m_mode=="JT4") m_settings->setValue("ShMsgs_JT4",m_bShMsgs);
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::on_cbSWL_toggled(bool b)
|
||||
@ -8823,6 +9060,7 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout
|
||||
}
|
||||
killFileTimer.start (45*1000); //Kill in 45s (for slow modes)
|
||||
}
|
||||
ndecodes_label.setText(QString::number(m_nWSPRdecodes));
|
||||
m_nWSPRdecodes=0;
|
||||
ui->DecodeButton->setChecked (false);
|
||||
if(m_uploadWSPRSpots && m_config.is_transceiver_online()) { // need working rig control
|
||||
@ -9440,28 +9678,35 @@ void MainWindow::readWidebandDecodes()
|
||||
if(m_ActiveStationsWidget==NULL) return;
|
||||
int nhr=0;
|
||||
int nmin=0;
|
||||
int nsec=0;
|
||||
int nsnr=0;
|
||||
while(m_fetched < qmapcom.ndecodes) {
|
||||
// Recover and parse each decoded line.
|
||||
QString line=QString::fromLatin1(qmapcom.result[m_fetched]);
|
||||
m_fetched++;
|
||||
nhr=line.mid(0,2).toInt();
|
||||
nmin=line.mid(2,2).toInt();
|
||||
double frx=line.mid(4,9).toDouble();
|
||||
double fsked=line.mid(13,7).toDouble();
|
||||
QString msg=line.mid(34,-1);
|
||||
nsec=line.mid(4,2).toInt();
|
||||
double frx=line.mid(6,9).toDouble();
|
||||
double fsked=line.mid(16,7).toDouble();
|
||||
QString submode=line.mid(36,3);
|
||||
QString msg=line.mid(41,-1);
|
||||
int i1=msg.indexOf(" ");
|
||||
int i2=i1 +1 + msg.mid(i1+1,-1).indexOf(" ");
|
||||
QString dxcall=msg.mid(i1+1,i2-i1-1);
|
||||
if(stdCall(dxcall)) {
|
||||
QString w3=msg.mid(i2+1,-1);
|
||||
nsnr=line.mid(29,3).toInt();
|
||||
nsnr=line.mid(31,3).toInt();
|
||||
m_EMECall[dxcall].frx=frx;
|
||||
m_EMECall[dxcall].fsked=fsked;
|
||||
m_EMECall[dxcall].nsnr=nsnr;
|
||||
m_EMECall[dxcall].t=60*nhr + nmin;
|
||||
m_EMECall[dxcall].t=3600*nhr + 60*nmin + nsec;
|
||||
m_EMECall[dxcall].submode=submode;
|
||||
//### Make sure WSJT-X is set to a Q65 submode consistent with the executing QMAP.
|
||||
if(w3.contains(grid_regexp)) m_EMECall[dxcall].grid4=w3;
|
||||
bool bCQ=line.contains(" CQ ");
|
||||
m_EMECall[dxcall].ready2call=(bCQ or line.contains(" 73") or line.contains(" RR73"));
|
||||
// m_EMECall[dxcall].ready2call=(bCQ or line.contains(" 73") or line.contains(" RR73"));
|
||||
m_EMECall[dxcall].ready2call=(bCQ);
|
||||
Frequency frequency = (m_freqNominal/1000000) * 1000000 + int(fsked*1000.0);
|
||||
bool bFromDisk=qmapcom.nQDecoderDone==2;
|
||||
if(!bFromDisk and (m_EMECall[dxcall].grid4.contains(grid_regexp) or bCQ)) {
|
||||
@ -9497,8 +9742,11 @@ void MainWindow::readWidebandDecodes()
|
||||
if(m_ActiveStationsWidget->readyOnly() and !i->ready2call) bSkip=true;
|
||||
if(!bSkip) {
|
||||
int snr=i->nsnr;
|
||||
int odd=1 - (i->t)%2;
|
||||
int age=60*nhr + nmin - (i->t);
|
||||
QString submode=i->submode;
|
||||
int odd=0;
|
||||
if(submode.left(2)=="30" and (i->t%60)==0) odd=1;
|
||||
if(submode.left(2)=="60" and (i->t%120)==0) odd=1;
|
||||
int age=(3600*nhr + 60*nmin + nsec - (i->t))/60;
|
||||
char c2[3]={32,32,0};
|
||||
if(age<0) age += 1440;
|
||||
if(age<=maxAge) {
|
||||
@ -9506,7 +9754,8 @@ void MainWindow::readWidebandDecodes()
|
||||
dxgrid4=(i->grid4+"... ").left(4);
|
||||
if(!m_EMEworked[dxcall.trimmed()]) c2[0]=35; //# for not in log
|
||||
if(i->ready2call) c2[1]=42; //* for ready to call
|
||||
t1=t1.asprintf("%7.3f %5.1f %+03d %8s %4s %3d %3d %2s\n",i->frx,i->fsked,snr,dxcall.toLatin1().constData(),
|
||||
t1=t1.asprintf("%7.3f %5.1f %+03d %3s %8s %4s %3d %3d %2s\n",i->frx,i->fsked,snr,
|
||||
submode.toLatin1().constData(),dxcall.toLatin1().constData(),
|
||||
dxgrid4.toLatin1().constData(),odd,age,c2);
|
||||
f[k]=i->fsked;
|
||||
list.append(t1);
|
||||
@ -9963,10 +10212,7 @@ list1Done:
|
||||
if(list2.size()==m_Nslots) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(m_foxQSO.count()>=5*3 /* could have 5 slots * 3 states ([0-2],4,5) */) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
list2Done:
|
||||
@ -10475,7 +10721,7 @@ void MainWindow::remote_configure (QString const& mode, quint32 frequency_tolera
|
||||
{
|
||||
if (mode.size ())
|
||||
{
|
||||
set_mode (mode);
|
||||
if (mode != m_mode) set_mode (mode);
|
||||
}
|
||||
auto is_FST4W = "FST4W" == m_mode;
|
||||
if (frequency_tolerance != quint32_max && (ui->sbFtol->isVisible () || is_FST4W))
|
||||
@ -10596,45 +10842,33 @@ void MainWindow::on_houndButton_clicked (bool checked)
|
||||
|
||||
void MainWindow::on_ft8Button_clicked()
|
||||
{
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
on_actionFT8_triggered();
|
||||
if (m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
on_actionFT8_triggered();
|
||||
}
|
||||
|
||||
void MainWindow::on_ft4Button_clicked()
|
||||
{
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
on_actionFT4_triggered();
|
||||
on_actionFT4_triggered();
|
||||
}
|
||||
|
||||
void MainWindow::on_msk144Button_clicked()
|
||||
{
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
on_actionMSK144_triggered();
|
||||
on_actionMSK144_triggered();
|
||||
}
|
||||
|
||||
void MainWindow::on_q65Button_clicked()
|
||||
{
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
on_actionQ65_triggered();
|
||||
if (m_specOp==SpecOp::Q65_PILEUP) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
on_actionQ65_triggered();
|
||||
}
|
||||
|
||||
void MainWindow::on_jt65Button_clicked()
|
||||
{
|
||||
if(m_specOp==SpecOp::HOUND) {
|
||||
m_config.setSpecial_None();
|
||||
m_specOp=m_config.special_op_id();
|
||||
}
|
||||
on_actionJT65_triggered();
|
||||
on_actionJT65_triggered();
|
||||
}
|
||||
|
@ -719,6 +719,7 @@ private:
|
||||
qint32 t;
|
||||
bool worked;
|
||||
bool ready2call;
|
||||
QString submode;
|
||||
};
|
||||
QMap<QString,EMECall> m_EMECall;
|
||||
|
||||
|
@ -3017,7 +3017,7 @@ QLabel[oob="true"] {
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Switch to Q65 mode. Right-click to toggle Q65 Pileup mode On/Off.</p></body></html></string>
|
||||
<string><html><head/><body><p>Switch to Q65 mode.<br> Right-click to switch to Q65 Pileup mode.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Q65</string>
|
||||
@ -3038,8 +3038,11 @@ QLabel[oob="true"] {
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Switch to JT65 mode</string>
|
||||
<string><html><head/><body><p>Switch to JT65 mode. <br>Right-click to switch to JT9 mode.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>JT65</string>
|
||||
|
@ -263,7 +263,7 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
|
||||
painter1.drawText (5, painter1.fontMetrics ().ascent (), t);
|
||||
}
|
||||
|
||||
if(m_mode=="JT4" or (m_mode=="Q65" and m_nSubMode>=2)) {
|
||||
if(m_mode=="JT4" or (m_mode=="Q65" and m_nSubMode>=3)) {
|
||||
DrawOverlay();
|
||||
QPen pen3(Qt::yellow); //Mark freqs of JT4/Q65 single-tone msgs
|
||||
painter2D.setPen(pen3);
|
||||
|
Loading…
x
Reference in New Issue
Block a user