diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a4604e5a..030488fa8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -428,6 +428,7 @@ set (wsjt_FSRCS lib/fspread_lorentz.f90 lib/ft8/foxfilt.f90 lib/ft8/foxgen.f90 + lib/superfox/foxgen2.f90 lib/ft8/foxgen_wrap.f90 lib/freqcal.f90 lib/ft8/ft8apset.f90 diff --git a/Configuration.cpp b/Configuration.cpp index 6c387bcbd..870639172 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -725,6 +725,7 @@ private: bool decode_at_52s_; bool single_decode_; bool twoPass_; + bool bSuperFox_; bool Individual_Contest_Name_; bool bSpecialOp_; int SelectedActivity_; @@ -833,6 +834,7 @@ bool Configuration::enable_VHF_features () const {return m_->enable_VHF_features bool Configuration::decode_at_52s () const {return m_->decode_at_52s_;} bool Configuration::single_decode () const {return m_->single_decode_;} bool Configuration::twoPass() const {return m_->twoPass_;} +bool Configuration::superFox() const {return m_->bSuperFox_;} bool Configuration::Individual_Contest_Name() const {return m_->Individual_Contest_Name_;} bool Configuration::x2ToneSpacing() const {return m_->x2ToneSpacing_;} bool Configuration::x4ToneSpacing() const {return m_->x4ToneSpacing_;} @@ -1463,6 +1465,7 @@ void Configuration::impl::initialize_models () ui_->decode_at_52s_check_box->setChecked(decode_at_52s_); ui_->single_decode_check_box->setChecked(single_decode_); ui_->cbTwoPass->setChecked(twoPass_); + ui_->cbSuperFox->setChecked(bSuperFox_); ui_->cbContestName->setChecked(Individual_Contest_Name_); ui_->gbSpecialOpActivity->setChecked(bSpecialOp_); ui_->special_op_activity_button_group->button (SelectedActivity_)->setChecked (true); @@ -1731,6 +1734,7 @@ void Configuration::impl::read_settings () decode_at_52s_ = settings_->value("Decode52",false).toBool (); single_decode_ = settings_->value("SingleDecode",false).toBool (); twoPass_ = settings_->value("TwoPass",true).toBool (); + bSuperFox_ = settings_->value("SuperFox",true).toBool (); Individual_Contest_Name_ = settings_->value("Individual_Contest_Name",true).toBool (); bSpecialOp_ = settings_->value("SpecialOpActivity",false).toBool (); SelectedActivity_ = settings_->value("SelectedActivity",1).toInt (); @@ -1879,6 +1883,7 @@ void Configuration::impl::write_settings () settings_->setValue ("Decode52", decode_at_52s_); settings_->setValue ("SingleDecode", single_decode_); settings_->setValue ("TwoPass", twoPass_); + settings_->setValue ("SuperFox", bSuperFox_); settings_->setValue ("Individual_Contest_Name", Individual_Contest_Name_); settings_->setValue ("SelectedActivity", SelectedActivity_); settings_->setValue ("SpecialOpActivity", bSpecialOp_); @@ -2308,6 +2313,7 @@ void Configuration::impl::accept () decode_at_52s_ = ui_->decode_at_52s_check_box->isChecked (); single_decode_ = ui_->single_decode_check_box->isChecked (); twoPass_ = ui_->cbTwoPass->isChecked (); + bSuperFox_ = ui_->cbSuperFox->isChecked (); Individual_Contest_Name_ = ui_->cbContestName->isChecked (); bSpecialOp_ = ui_->gbSpecialOpActivity->isChecked (); SelectedActivity_ = ui_->special_op_activity_button_group->checkedId(); diff --git a/Configuration.hpp b/Configuration.hpp index bb2322c3d..6ae241f76 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -137,6 +137,7 @@ public: bool decode_at_52s () const; bool single_decode () const; bool twoPass() const; + bool superFox() const; bool bFox() const; bool bHound() const; bool bLowSidelobes() const; diff --git a/Configuration.ui b/Configuration.ui index c29cc5722..8f6662590 100644 --- a/Configuration.ui +++ b/Configuration.ui @@ -2907,20 +2907,33 @@ Right click for insert and delete options. false - - - - - <html><head/><body><p>FT8 DXpedition mode: Hound operator calling the DX.</p></body></html> + + + + + Qt::Horizontal - - Hound + + + 40 + 20 + + + + + + + + + 0 + 18 + + + + <html><head/><body><p>Exchange 4-character locator instead of signal report. Provides q3-level sensitivities for the DX operator. Especially useful for 6m EME DXpeditions.</p></body></html> - Hound - - - true + Q65 Pileup special_op_activity_button_group @@ -2949,101 +2962,6 @@ Right click for insert and delete options. - - - - - - <html><head/><body><p>ARRL Field Day exchange: number of transmitters, Class, and ARRL/RAC section or &quot;DX&quot;.</p></body></html> - - - A R R L Field Day - - - ARRL Field Day - - - special_op_activity_button_group - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Field Day exchange - - - FD Exch: - - - Field_Day_Exchange - - - - - - - - 70 - 0 - - - - <html><head/><body><p>ARRL Field Day exchange: number of transmitters, Class, and ARRL/RAC section or &quot;DX&quot;.</p></body></html> - - - 6A SNJ - - - Qt::AlignCenter - - - - - - - - - - - <html><head/><body><p>ARRL International Digital Contest</p></body></html> - - - ARRL Digi Contest - - - special_op_activity_button_group - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -3066,26 +2984,7 @@ Right click for insert and delete options. - - - - - 0 - 18 - - - - <html><head/><body><p>Exchange 4-character locator instead of signal report. Provides q3-level sensitivities for the DX operator. Especially useful for 6m EME DXpeditions.</p></body></html> - - - Q65 Pileup - - - special_op_activity_button_group - - - - + @@ -3154,48 +3053,7 @@ Right click for insert and delete options. - - - - <html><head/><body><p>FT8 DXpedition mode: Fox (DXpedition) operator.</p></body></html> - - - Fox - - - Fox - - - false - - - special_op_activity_button_group - - - - - - - - 0 - 0 - - - - <html><head/><body><p>European VHF+ contests requiring a signal report, serial number, and 6-character locator.</p></body></html> - - - EU VHF Contest - - - EU VHF Contest - - - special_op_activity_button_group - - - - + @@ -3255,6 +3113,155 @@ Right click for insert and delete options. + + + + <html><head/><body><p>ARRL International Digital Contest</p></body></html> + + + ARRL Digi Contest + + + special_op_activity_button_group + + + + + + + + 0 + 0 + + + + <html><head/><body><p>European VHF+ contests requiring a signal report, serial number, and 6-character locator.</p></body></html> + + + EU VHF Contest + + + EU VHF Contest + + + special_op_activity_button_group + + + + + + + <html><head/><body><p>FT8 DXpedition mode: Fox (DXpedition) operator.</p></body></html> + + + Fox + + + Fox + + + false + + + special_op_activity_button_group + + + + + + + + + <html><head/><body><p>ARRL Field Day exchange: number of transmitters, Class, and ARRL/RAC section or &quot;DX&quot;.</p></body></html> + + + A R R L Field Day + + + ARRL Field Day + + + special_op_activity_button_group + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Field Day exchange + + + FD Exch: + + + Field_Day_Exchange + + + + + + + + 70 + 0 + + + + <html><head/><body><p>ARRL Field Day exchange: number of transmitters, Class, and ARRL/RAC section or &quot;DX&quot;.</p></body></html> + + + 6A SNJ + + + Qt::AlignCenter + + + + + + + + + + + <html><head/><body><p>FT8 DXpedition mode: Hound operator calling the DX.</p></body></html> + + + Hound + + + Hound + + + true + + + special_op_activity_button_group + + + + + + + SuperFox + + + @@ -3498,13 +3505,13 @@ Right click for insert and delete options. - - - + + + diff --git a/lib/ft8/foxgen.f90 b/lib/ft8/foxgen.f90 index a2899e526..18450395e 100644 --- a/lib/ft8/foxgen.f90 +++ b/lib/ft8/foxgen.f90 @@ -1,4 +1,4 @@ -subroutine foxgen() +subroutine foxgen(bSuperFox) ! Called from MainWindow::foxTxSequencer() to generate the Tx waveform in ! FT8 Fox mode. The Tx message can contain up to 5 "slots", each carrying @@ -17,6 +17,7 @@ subroutine foxgen() parameter (NN=79,ND=58,NSPS=4*1920) parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST4-1800 at 48kHz) parameter (NFFT=614400,NH=NFFT/2) + logical*1 bSuperFox character*40 cmsg character*37 msg,msgsent integer itone(79) @@ -29,6 +30,11 @@ subroutine foxgen() common/foxcom2/itone2(NN),msgbits2(77) equivalence (x,cx),(y,cy) + if(bSuperFox) then + call foxgen2(nslots,cmsg) + return + endif + fstep=60.d0 dfreq=6.25d0 dt=1.d0/48000.d0 diff --git a/lib/superfox/foxgen2.f90 b/lib/superfox/foxgen2.f90 new file mode 100644 index 000000000..c77a2b492 --- /dev/null +++ b/lib/superfox/foxgen2.f90 @@ -0,0 +1,140 @@ +subroutine foxgen2(nslots,cmsg) + + use packjt77 + character*40 cmsg(5) + character*37 msg + character*22 sfmsg + character*12 mycall + character*4 mygrid + character*6 hiscall_1,hiscall_2 + character*4 rpt_1,rpt_2 + character*13 w(19) + integer nw(19) + integer ntype !Message type: 0 Free Text + ! 1 CQ MyCall MyGrid + ! 2 Call_1 MyCall RR73 + ! 3 Call_1 MyCall rpt_1 + ! 4 Call_1 RR73; Call_2 rpt_2 + + if(nslots.lt.1 .or. nslots.gt.5) return + k=0 + do i=1,nslots + hiscall_1='' + hiscall_2='' + mycall='' + mygrid='' + rpt_1='' + rpt_2='' + msg=cmsg(i)(1:37) + call split77(msg,nwords,nw,w) + ntype=0 + if(msg(1:3).eq.'CQ ') then + ntype=1 + mycall=w(2)(1:12) + mygrid=w(3)(1:4) + else if(index(msg,';').gt.0) then + ntype=4 + hiscall_1=w(1)(1:6) + hiscall_2=w(3)(1:6) + rpt_1='RR73' + rpt_2=w(5)(1:4) + mycall=w(4)(2:nw(4)-1) + else if(index(msg,' RR73').gt.0) then + ntype=2 + hiscall_1=w(1)(1:6) + mycall=w(2)(1:12) + rpt_1='RR73' + else if(nwords.eq.3 .and. nw(3).eq.3 .and. & + (w(3)(1:1).eq.'-' .or. w(3)(1:1).eq.'+')) then + ntype=3 + hiscall_1=w(1)(1:6) + mycall=w(2)(1:12) + rpt_1=w(3)(1:4) + endif +! write(*,3001) ntype,cmsg(i),hiscall_1,rpt_1,hiscall_2,rpt_2, & +! mycall(1:6),mygrid +!3001 format(i1,2x,a37,1x,a6,1x,a4,1x,a6,1x,a4,1x,a6,1x,a4) + + k=k+1 + if(ntype.le.3) call sfox_assemble(ntype,k,msg(1:22),mycall,mygrid) + if(ntype.eq.4) then + sfmsg=w(1)(1:nw(1))//' '//mycall(1:len(trim(mycall))+1)//'RR73' + call sfox_assemble(2,k,sfmsg,mycall,mygrid) + sfmsg=w(3)(1:nw(3))//' '//mycall(1:len(trim(mycall))+1)//w(5)(1:3) + k=k+1 + call sfox_assemble(3,k,sfmsg,mycall,mygrid) + endif + + enddo + call sfox_assemble(ntype,11,msg(1:22),mycall,mygrid) !k=11 to finish up + + return +end subroutine foxgen2 + +subroutine sfox_assemble(ntype,k,msg,mycall0,mygrid0) + + character*22 msg + character*22 msg0,msg1,msg2(10),msg3(5) + character*12 mycall0,mycall + character*4 mygrid0,mygrid + integer ntype !Message type: 0 Free Text + ! 1 CQ MyCall MyGrid + ! 2 Call_1 MyCall RR73 + ! 3 Call_1 MyCall rpt + integer nmsg(0:3) !Number of messages of type ntype + data nmsg/0,0,0,0/,nbits/0/,ntx/0/ + save +! save mycall,mygrid,nmsg,nbits,ntx + + if(mycall0(1:1).ne.' ') mycall=mycall0 + if(mygrid0(1:1).ne.' ') mygrid=mygrid0 + if(k.le.10) then + if(ntype.eq.0) then + if(nbits.le.262) then + nmsg(ntype)=nmsg(ntype)+1 + nbits=nbits+71 + msg0=msg + endif + else if(ntype.eq.1) then + if(nbits.le.290) then + nmsg(ntype)=nmsg(ntype)+1 + nbits=nbits+43 + msg1=msg + endif + else if(ntype.eq.2) then + if(nbits.le.305) then + nmsg(ntype)=nmsg(ntype)+1 + nbits=nbits+28 + j=nmsg(ntype) + msg2(j)=msg + endif + else + if(nbits.le.300) then + nmsg(ntype)=nmsg(ntype)+1 + nbits=nbits+33 + j=nmsg(ntype) + msg3(j)=msg + endif + endif + return + endif + + if(k.ge.11) then + ntx=ntx+1 !Transmission number + write(*,3002) ntx,ntype,nmsg(0:3),nbits +3002 format(i3,i5,2x,4i3,i6) + if(nmsg(0).ge.1) write(*,3010) ntx,msg0 +3010 format(i3,2x,a22) + if(nmsg(1).ge.1) write(*,3010) ntx,msg1 + do i=1,nmsg(2) + write(*,3010) ntx,msg2(i) + enddo + do i=1,nmsg(3) + write(*,3010) ntx,msg3(i) + enddo + nmsg=0 + nbits=0 + endif + + return +end subroutine sfox_assemble diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index ae8766572..c96205f3c 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -176,7 +176,7 @@ extern "C" { void calibrate_(char const * data_dir, int* iz, double* a, double* b, double* rms, double* sigmaa, double* sigmab, int* irc, fortran_charlen_t); - void foxgen_(); + void foxgen_(bool* bSuperFox); void plotsave_(float swide[], int* m_w , int* m_h1, int* irow); @@ -2224,13 +2224,13 @@ void MainWindow::keyPressEvent (QKeyEvent * e) case Qt::Key_Backspace: qDebug() << "Key Backspace"; return; -#ifdef DEBUG_FOX +//#ifdef DEBUG_FOX case Qt::Key_X: if(e->modifiers() & Qt::AltModifier) { foxTest(); return; } -#endif +//#endif } QMainWindow::keyPressEvent (e); } @@ -4823,7 +4823,8 @@ void MainWindow::guiUpdate() if(m_config.split_mode()) foxcom_.nfreq = foxcom_.nfreq - m_XIT; //Fox Tx freq QString foxCall=m_config.my_callsign() + " "; ::memcpy(foxcom_.mycall, foxCall.toLatin1(), sizeof foxcom_.mycall); //Copy Fox callsign into foxcom_ - foxgen_(); + bool bSuperFox=m_config.superFox(); + foxgen_(&bSuperFox); } } } @@ -10297,7 +10298,8 @@ Transmit: if(m_config.split_mode()) foxcom_.nfreq = foxcom_.nfreq - m_XIT; //Fox Tx freq QString foxCall=m_config.my_callsign() + " "; ::memcpy(foxcom_.mycall, foxCall.toLatin1(),sizeof foxcom_.mycall); //Copy Fox callsign into foxcom_ - foxgen_(); + bool bSuperFox=m_config.superFox(); + foxgen_(&bSuperFox); m_tFoxTxSinceCQ++; for(QString hc: m_foxQSO.keys()) { //Check for strikeout or timeout