diff --git a/NEWS b/NEWS index 227f2274e..0f2f6fc08 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,54 @@ Copyright 2001 - 2021 by Joe Taylor, K1JT. + Release: WSJT-X 2.5.0-rc2 + Jun 28, 2021 + ------------------------- + +This release repairs several MAP65 defects and omissions discovered in +the first release candidate, it also repairs some regressions in +WSJT-X, including some in the Hamlib library. + +Changes for MAP65: + + - Implement linear drift compensation for Q65 mode when FTol >100 Hz. + + - Implement a "Max drift" UI control for Q65. + + - Repair a regression which omitted signal meter scales. + + - Basic instruction document for building an MS Windows portaudio DLL + for MAP65 users who are unable to use WDM/KS drivers for their + multi-channel sound cards. + +Changes for WSJT-X: + + - Implement linear drift compensation for Q65 mode when FTol >100 Hz. + + - Implement a "Max drift" UI control for Q65. + + - Repair a long standing regression with message generation for + 72-bit modes when using a compound callsign. + + - Message averaging window no longer available in Q65 mode as it is + not relevant. + + - Improvements to the frequency/band combo box pop up list width to + address a regression occurring in recent releases. + + - Updated CTY database. + + - Repair a defect in diagnostic logging that could cause crashes on + some platforms. + + - Repair a defect which failed to strip leading and trailing spaces + on input of callsigns during validation. + + - Hamlib updates including repair of defects with PTT handling on a + separate serial port via rigctld, delayed PTT with Elecraft K3 + series rigs, and support for the Icom IC-575 rig. + + Release: WSJT-X 2.5.0-rc1 Jun 3, 2021 ------------------------- diff --git a/Release_Notes.txt b/Release_Notes.txt index 2fd544f04..9989e95a3 100644 --- a/Release_Notes.txt +++ b/Release_Notes.txt @@ -29,19 +29,29 @@ MAP65: - Wideband Q65 synchronization corrected to include single-polarization mode - Corrected a one-symbol (0.6 s) delay in Q65 Tx audio + - Basic instruction document for building an MS Windows portaudio DLL + for MAP65 users who are unable to use WDM/KS drivers for their + multi-channel sound cards. -WSJT-X, including the decoder for Q65 used by MAP65: +WSJT-X (including the decoder for Q65 used by MAP65): - Increase maximum DT to 5.5 s when EME decoding is enabled in Q65 - - Repair a minor defect in callsign input validation - Fix generation of Tx5 message when "hiscall" has suffix /P or /R. - Improve width management of GUI's band-selection combo box - Restore plotting of Q65 sync curve after a q3 decode - Disable selection of "View | Message Averaging F7" for modes other than JT4 and JT65 - Switching to Q65 mode now defaults to "Decode | Fast" + - Repair a long standing regression with message generation for + 72-bit modes when using a compound callsign. + - Repair a defect in diagnostic logging that could cause crashes on + some platforms. + - Repair a defect which failed to strip leading and trailing spaces + on input of callsigns during validation. + - Hamlib updates including repair of defects with PTT handling on a + separate serial port via rigctld, delayed PTT with Elecraft K3 + series rigs, and support for the Icom IC-575 rig. - Updated CTY.DAT database - Release: WSJT-X 2.5.0-rc1 Jun 3, 2021 ------------------------- diff --git a/doc/building portaudio on Windows with ASIO support.txt b/doc/building portaudio on Windows with ASIO support.txt new file mode 100644 index 000000000..71f8bf653 --- /dev/null +++ b/doc/building portaudio on Windows with ASIO support.txt @@ -0,0 +1,76 @@ +Building the MS Windows portaudio DLL with ASIO Support +======================================================= + +Some MAP65 users may not be able to use WDM/KS hosted audio devices +due to sharing issues with other applications, to circumvent this they +can build a version of the portaudio DLL with ASIO support. We cannot +provide a portaudio DLL with ASIO support as the Steinberg ASIO SDK +license prevents redistribution of drivers or hosting applications +without a commercial license agreement, nor is the Steinberg ASIO SDK +license compatible with the GPL v3 license that MAP65 is released +under. Users may build a portaudio DLL themselves, strictly for +personal use, under the terms of the Steinberg ASIO license. + +Building portaudio on MS Windows is done most easily using the MinGW +(GNU) tool-chain which can be installed on MS Windows using the MSYS2 +unix like environment which in turn includes a package manager +(pacman) that allows simple installation of necessary prerequisite +packages like the MinGW 64-bit tool-chain. To install MSYS2 download +the latest 64-bit installer from the MSYS2 project web site. This page +contains links to the installer download and detailed instructions to +install and bring up-to-date the base MSYS2 packages. + +https://www.msys2.org/wiki/MSYS2-installation/ + +Take particular care to restart the MSYS2 shell window when directed +to. + +Once MSYS2 is installed you will find a start menu entry labelled +"MSYS2 MinGW 64-bit", use that to start a fresh MSYS2 shell window for +the rest of these instructions. + +The first step is to install some prerequisite packages which contain +the tools needed to prepare and build the portaudio DLL. Execute the +following command to do that: + + pacman -S make diffutils unzip mingw-w64-x86_64-gcc sed tar curl + +Then make directories to put downloaded sources in and for building: + + mkdir -p ~/src ~/build/portaudio + +Fetch and unpack the Steinberg ASIO SDK (note the ASIO SDK license +document included, particularly that it strictly disallows +redistribution of the DLL we will be building here), and portaudio +sources: + + curl -Lo ~/src/asiosdk.zip https://www.steinberg.net/asiosdk + (cd ~/src ; unzip asiosdk.zip) + curl -O --output-dir ~/src \ + http://files.portaudio.com/archives/pa_stable_v190700_20210406.tgz + tar -C ~/src -xf ~/src/pa_stable_v190700_20210406.tgz + +Patch and build the portaudio library: + + sed -i -e 's/-luuid//g' ~/src/portaudio/configure + cd ~/build/portaudio + ~/src/portaudio/configure --with-winapi=wmme,directx,wdmks,asio \ + --with-asiodir=$HOME/src/asiosdk_2.3.3_2019-06-14 \ + --disable-static --enable-shared + make -j + +You can check the library build is working by running a test program +that was also built: + + bin/pa_devs + +which should list every audio device on your system by every host API, +if all is well that should include the audio devices on your system +with ASIO drivers. + +Copy the new portaudio DLL to your WSJT-X/MAP65 installation directory: + + cp lib/.libs/libportaudio-2.dll /c/WSJT/wsjtx/bin/ + +Note that if you upgrade WSJT-X you will need to copy this DLL again +since it will be overwritten by one with no ASIO support. diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index f707b9947..ec8af755e 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -754,10 +754,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, ui->bandComboBox->setModel (m_config.frequencies ()); ui->bandComboBox->setModelColumn (FrequencyList_v2::frequency_mhz_column); - // combo box drop down width defaults to the line edit + decorator width, - // here we change that to the column width size hint of the model column - ui->bandComboBox->view ()->setMinimumWidth (ui->bandComboBox->view ()->sizeHintForColumn (FrequencyList_v2::frequency_mhz_column)); - // Enable live band combo box entry validation and action. auto band_validator = new LiveFrequencyValidator {ui->bandComboBox , m_config.bands () @@ -5243,27 +5239,32 @@ void MainWindow::setTxMsg(int n) void MainWindow::genCQMsg () { - if(m_config.my_callsign().size () && m_config.my_grid().size ()) { - QString grid{m_config.my_grid()}; + auto const& my_callsign = m_config.my_callsign (); + auto is_compound = my_callsign != m_baseCall; + auto is_type_two = !is77BitMode () && is_compound && stdCall (m_baseCall) && !shortList (my_callsign); + if(my_callsign.size () && m_config.my_grid().size ()) { + auto const& grid = m_config.my_grid (); if (ui->cbCQTx->isEnabled () && ui->cbCQTx->isVisible () && ui->cbCQTx->isChecked ()) { - if(stdCall(m_config.my_callsign())) { + if(stdCall (my_callsign) + || is_type_two) { msgtype (QString {"CQ %1 %2 %3"} .arg (m_freqNominal / 1000 - m_freqNominal / 1000000 * 1000, 3, 10, QChar {'0'}) - .arg (m_config.my_callsign()) + .arg (my_callsign) .arg (grid.left (4)), ui->tx6); } else { msgtype (QString {"CQ %1 %2"} .arg (m_freqNominal / 1000 - m_freqNominal / 1000000 * 1000, 3, 10, QChar {'0'}) - .arg (m_config.my_callsign()), + .arg (my_callsign), ui->tx6); } } else { - if(stdCall(m_config.my_callsign())) { - msgtype (QString {"%1 %2 %3"}.arg(m_CQtype).arg(m_config.my_callsign()) + if (stdCall (my_callsign) + || is_type_two) { + msgtype (QString {"%1 %2 %3"}.arg(m_CQtype).arg(my_callsign) .arg(grid.left(4)),ui->tx6); } else { - msgtype (QString {"%1 %2"}.arg(m_CQtype).arg(m_config.my_callsign()),ui->tx6); + msgtype (QString {"%1 %2"}.arg(m_CQtype).arg(my_callsign),ui->tx6); } } if ((m_mode=="JT4" or m_mode=="Q65") and ui->cbShMsgs->isChecked()) { @@ -5278,15 +5279,15 @@ void MainWindow::genCQMsg () QStringList tlist=t.split(" "); if((m_mode=="FT4" or m_mode=="FT8" or m_mode=="MSK144") and SpecOp::NONE != m_config.special_op_id() and - ( tlist.at(1)==m_config.my_callsign() or - tlist.at(2)==m_config.my_callsign() ) and - stdCall(m_config.my_callsign())) { + ( tlist.at(1)==my_callsign or + tlist.at(2)==my_callsign ) and + stdCall(my_callsign)) { if(SpecOp::NA_VHF == m_config.special_op_id()) m_cqStr="TEST"; if(SpecOp::EU_VHF == m_config.special_op_id()) m_cqStr="TEST"; if(SpecOp::FIELD_DAY == m_config.special_op_id()) m_cqStr="FD"; if(SpecOp::RTTY == m_config.special_op_id()) m_cqStr="RU"; if(SpecOp::WW_DIGI == m_config.special_op_id()) m_cqStr="WW"; - if( tlist.at(1)==m_config.my_callsign() ) { + if( tlist.at(1)==my_callsign ) { t="CQ " + m_cqStr + " " + tlist.at(1) + " " + tlist.at(2); } else { t="CQ " + m_cqStr + " " + tlist.at(2) + " " + tlist.at(3); @@ -5319,6 +5320,12 @@ bool MainWindow::stdCall(QString const& w) return standard_call_re.match (w).hasMatch (); } +bool MainWindow::is77BitMode () const +{ + return "FT8" == m_mode || "FT4" == m_mode || "MSK144" == m_mode + || "FST4" == m_mode || "Q65" == m_mode; +} + void MainWindow::genStdMsgs(QString rpt, bool unconditional) { genCQMsg (); @@ -5335,7 +5342,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } auto const& my_callsign = m_config.my_callsign (); auto is_compound = my_callsign != m_baseCall; - auto is_type_one = is_compound && shortList (my_callsign); + auto is_type_one = !is77BitMode () && is_compound && shortList (my_callsign); auto const& my_grid = m_config.my_grid ().left (4); auto const& hisBase = Radio::base_callsign (hisCall); auto eme_short_codes = m_config.enable_VHF_features () && ui->cbShMsgs->isChecked () @@ -5348,7 +5355,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) QString t0s=hisCall + " " + my_callsign + " "; QString t0a,t0b; - if(bHisCall and bMyCall) t0=hisCall + " " + my_callsign + " "; + if (is77BitMode () && bHisCall && bMyCall) t0=hisCall + " " + my_callsign + " "; t0a="<"+hisCall + "> " + my_callsign + " "; t0b=hisCall + " <" + my_callsign + "> "; @@ -5366,7 +5373,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) int n=rpt.toInt(); rpt = rpt.asprintf("%+2.2d",n); - if(m_mode=="MSK144" or m_mode=="FT8" or m_mode=="FT4" || m_mode=="FST4") { + if (is77BitMode ()) { QString t2,t3; QString sent=rpt; QString rs,rst; @@ -5430,8 +5437,8 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } } - if((m_mode!="MSK144" and m_mode!="FT8" and m_mode!="FT4" && m_mode != "FST4")) { - t=t00 + rpt; + if (!is77BitMode ()) { + t=(is_type_one ? t0 : t00) + rpt; msgtype(t, ui->tx2); t=t0 + "R" + rpt; msgtype(t, ui->tx3); @@ -5470,7 +5477,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } } - if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="MSK144" || m_mode == "FST4") return; + if (is77BitMode ()) return; if (is_compound) { if (is_type_one) { @@ -5483,8 +5490,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) case Configuration::type_2_msg_1_full: msgtype(t + my_grid, ui->tx1); if (!eme_short_codes) { - if((m_mode=="MSK144" || m_mode=="FT8" || m_mode=="FT4" || m_mode == "FST4") && - SpecOp::NA_VHF == m_config.special_op_id()) { + if(is77BitMode () && SpecOp::NA_VHF == m_config.special_op_id()) { msgtype(t + "R " + my_grid, ui->tx3); // #### Unreachable code } else { msgtype(t + "R" + rpt, ui->tx3); @@ -5496,8 +5502,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) break; case Configuration::type_2_msg_3_full: - if ((m_mode=="MSK144" || m_mode=="FT8" || m_mode=="FT4" || m_mode == "FST4") && - SpecOp::NA_VHF == m_config.special_op_id()) { + if (is77BitMode () && SpecOp::NA_VHF == m_config.special_op_id()) { msgtype(t + "R " + my_grid, ui->tx3); msgtype(t + "RRR", ui->tx4); } else { @@ -5512,8 +5517,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) case Configuration::type_2_msg_5_only: msgtype(t00 + my_grid, ui->tx1); if (!eme_short_codes) { - if ((m_mode=="MSK144" || m_mode=="FT8" || m_mode=="FT4" || m_mode == "FST4") && - SpecOp::NA_VHF == m_config.special_op_id()) { + if (is77BitMode () && SpecOp::NA_VHF == m_config.special_op_id()) { msgtype(t + "R " + my_grid, ui->tx3); // #### Unreachable code msgtype(t + "RRR", ui->tx4); } else { @@ -5548,7 +5552,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } } m_rpt=rpt; - if(SpecOp::HOUND == m_config.special_op_id() and is_compound) ui->tx1->setText("DE " + m_config.my_callsign()); + if(SpecOp::HOUND == m_config.special_op_id() and is_compound) ui->tx1->setText("DE " + my_callsign); } void MainWindow::TxAgain() diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 653023b23..854afef2f 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -778,6 +778,7 @@ private: void foxGenWaveform(int i,QString fm); void writeFoxQSO (QString const& msg); void to_jt9(qint32 n, qint32 istart, qint32 idone); + bool is77BitMode () const; }; extern int killbyname(const char* progName);