Merge branch 'release-2.1.0' into develop

This commit is contained in:
Bill Somerville 2019-04-05 11:15:21 +01:00
commit 8d3bb379f9
13 changed files with 192 additions and 144 deletions

View File

@ -181,7 +181,11 @@ attach a debugger which will then receive the console output inside its console.
set (PROJECT_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}")
if (NOT PROJECT_ARCHITECTURE)
# This is supposed to happen already on Windows
set (PROJECT_ARCHITECTURE "$ENV{PROCESSOR_ARCHITECTURE}")
if (CMAKE_SIZEOF_VOID_P MATCHES 8)
set (PROJECT_ARCHITECTURE "x64")
else ()
set (PROJECT_ARCHITECTURE "$ENV{PROCESSOR_ARCHITECTURE}")
endif ()
endif (NOT PROJECT_ARCHITECTURE)
message (STATUS "******************************************************")
message (STATUS "Building for for: ${CMAKE_SYSTEM_NAME}-${PROJECT_ARCHITECTURE}")
@ -558,7 +562,6 @@ set (wsjt_FSRCS
lib/sync64.f90
lib/sync65.f90
lib/ft4/getcandidates4.f90
lib/fsk4hf/getcandidates2.f90
lib/ft4/syncft4.f90
lib/ft8/sync8.f90
lib/ft8/sync8d.f90
@ -809,7 +812,7 @@ if (WIN32)
endif (NOT AXSERVER)
string (REPLACE "\"" "" AXSERVER ${AXSERVER})
file (TO_CMAKE_PATH ${AXSERVER} AXSERVERSRCS)
endif (WIN32)
endif ()
#
@ -1633,6 +1636,7 @@ if (NOT is_debug_build)
install (
DIRECTORY
${QT_PLUGINS_DIR}/platforms
${QT_PLUGINS_DIR}/styles
${QT_PLUGINS_DIR}/accessible
${QT_PLUGINS_DIR}/audio
${QT_PLUGINS_DIR}/imageformats

View File

@ -152,7 +152,7 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
// message format is described in NetworkMessage.hpp
//
NetworkMessage::Reader in {msg};
if (OK == check_status (in) && id_ == in.id ()) // OK and for us
if (OK == check_status (in))
{
if (schema_ < in.schema ()) // one time record of server's
// negotiated schema

View File

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

View File

@ -19,7 +19,7 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, &
complex cd2(0:NMAX/NDOWN-1) !Complex waveform
complex cb(0:NMAX/NDOWN-1)
complex cd(0:NN*NSS-1) !Complex waveform
complex ctwk(4*NSS),ctwk2(4*NSS)
complex ctwk(2*NSS),ctwk2(2*NSS,-16:16)
complex csymb(NSS)
complex cs(0:3,NN)
real s4(0:3,NN)
@ -46,7 +46,7 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, &
logical nohiscall,unpk77_success
logical one(0:255,0:7) ! 256 4-symbol sequences, 8 bits
logical first
logical first, dobigfft
data icos4a/0,1,3,2/
data icos4b/1,0,2,3/
@ -63,7 +63,7 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, &
1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1,1,1,0,0,1,0,1, &
0,1,0,1,0,1,1,0,1,1,1,1,1,0,0,0,1,0,1/
save fs,dt,tt,txt,twopi,h,one,first,linex,apbits,nappasses,naptypes, &
mycall0,hiscall0,msg0,cqstr0
mycall0,hiscall0,msg0,cqstr0,ctwk2
call clockit('ft4_deco',0)
hhmmss=cdatetime0(8:13)
@ -82,6 +82,15 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, &
enddo
enddo
do idf=-16,16
a=0.
a(1)=real(idf)
ctwk=1.
call clockit('twkfreq1',0)
call twkfreq1(ctwk,2*NSS,fs/2.0,a,ctwk2(:,idf))
call clockit('twkfreq1',1)
enddo
mrrr=2*mod(mrrr+rvec(59:77),2)-1
m73=2*mod(m73+rvec(59:77),2)-1
mrr73=2*mod(mrr73+rvec(59:77),2)-1
@ -180,12 +189,14 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, &
call clockit('getcand4',1)
ndecodes=0
dobigfft=.true.
do icand=1,ncand
f0=candidate(1,icand)
snr=candidate(3,icand)-1.0
if( f0.le.10.0 .or. f0.ge.4990.0 ) cycle
call clockit('ft4_down',0)
call ft4_downsample(iwave,f0,cd2) !Downsample from 512 to 32 Sa/Symbol
call ft4_downsample(iwave,dobigfft,f0,cd2) !Downsample from 512 to 32 Sa/Symbol
if(dobigfft) dobigfft=.false.
call clockit('ft4_down',1)
sum2=sum(cd2*conjg(cd2))/(real(NMAX)/real(NDOWN))
@ -211,16 +222,10 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, &
smax=-99.
idfbest=0
do idf=idfmin,idfmax,idfstp
a=0.
a(1)=real(idf)
ctwk=1.
call clockit('twkfreq1',0)
call twkfreq1(ctwk,4*NSS,fs,a,ctwk2)
call clockit('twkfreq1',1)
call clockit('sync4d ',0)
do istart=ibmin,ibmax,ibstp
call sync4d(cd2,istart,ctwk2,1,sync,sync2) !Find sync power
call sync4d(cd2,istart,ctwk2(:,idf),1,sync) !Find sync power
if(sync.gt.smax) then
smax=sync
ibest=istart
@ -235,7 +240,7 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, &
if( f0.le.10.0 .or. f0.ge.4990.0 ) cycle
call clockit('ft4down ',0)
call ft4_downsample(iwave,f0,cb) !Final downsample with corrected f0
call ft4_downsample(iwave,dobigfft,f0,cb) !Final downsample with corrected f0
call clockit('ft4down ',1)
sum2=sum(abs(cb)**2)/(real(NSS)*NN)
if(sum2.gt.0.0) cb=cb/sqrt(sum2)
@ -265,7 +270,7 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, &
ip=maxloc(s4(:,k+99))
if(icos4d(k-1).eq.(ip(1)-1)) is4=is4+1
enddo
nsync=is1+is2+is3+is4 !Number of hard sync errors, 0-16
nsync=is1+is2+is3+is4 !Number of correct hard sync symbols, 0-16
if(smax .lt. 0.7 .or. nsync .lt. 8) cycle
do nseq=1,3 !Try coherent sequences of 1, 2, and 4 symbols
@ -460,17 +465,15 @@ subroutine ft4_decode(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, &
fname=data_dir(1:l1+1)//'all_ft4.txt'
open(24,file=trim(fname),status='unknown',position='append')
write(24,1002) cdatetime0,nsnr,tsig,nint(freq),message, &
nharderror,nsync_qual,ipass,niterations,iaptype
nharderror,nsync_qual,ipass,niterations,iaptype,nsync
if(hhmmss.eq.' ') write(*,1002) cdatetime0,nsnr, &
tsig,nint(freq),message,nharderror,nsync_qual,ipass, &
niterations,iaptype
1002 format(a17,i4,f5.1,i5,' Rx ',a37,5i5)
1002 format(a17,i4,f5.1,i5,' Rx ',a37,6i4)
close(24)
linex(ndecodes)=line
if(ibest.ge.ibmax-15) msg0=message !Possible dupe candidate
exit
endif
enddo !Sequence estimation
enddo !Candidate list

View File

@ -1,4 +1,4 @@
subroutine ft4_downsample(iwave,f0,c)
subroutine ft4_downsample(iwave,newdata,f0,c)
! Input: i*2 data in iwave() at sample rate 12000 Hz
! Output: Complex data in c(), sampled at 1200 Hz
@ -11,9 +11,9 @@ subroutine ft4_downsample(iwave,f0,c)
complex cx(0:NMAX/2)
real x(NMAX), window(0:NFFT2-1)
equivalence (x,cx)
logical first
logical first, newdata
data first/.true./
save first,window
save first,window,x
df=12000.0/NMAX
baud=12000.0/NSPS
@ -32,8 +32,10 @@ subroutine ft4_downsample(iwave,f0,c)
first=.false.
endif
x=iwave
call four2a(x,NMAX,1,-1,0) !r2c FFT to freq domain
if(newdata) then
x=iwave
call four2a(x,NMAX,1,-1,0) !r2c FFT to freq domain
endif
i0=nint(f0/df)
c1=0.
c1(0)=cx(i0)

View File

@ -11,7 +11,7 @@ program ft4d
character*4 cqstr
real*8 fMHz
integer ihdr(11)
integer*2 iwave(180000) !15*12000
integer*2 iwave(240000) !20*12000
fs=12000.0/NDOWN !Sample rate
dt=1/fs !Sample interval after downsample (s)
@ -54,14 +54,14 @@ program ft4d
do ifile=iarg,nargs
call getarg(ifile,infile)
j2=index(infile,'.wav')
open(10,file=infile,status='old',access='stream')
read(10) ihdr
npts=ihdr(11)/2
npts=min(ihdr(11)/2,180000)
read(10) iwave(1:npts)
close(10)
cdatetime=infile(1:13)//'.000'
cdatetime=infile
j2=index(infile,'.wav')
if(j2.ge.14) cdatetime=infile(j2-13:j2)//'000'
istep=3456
nsteps=(npts-52800)/istep + 1
do n=1,nsteps

View File

@ -25,9 +25,8 @@ program ft4sim
nargs=iargc()
if(nargs.ne.7) then
print*,'Usage: ft4sim "message" f0 DT fdop del nfiles snr'
print*,'Examples: ft4sim "K1ABC W9XYZ EN37" 1500.0 0.0 0.1 1.0 10 -15'
print*,' ft4sim "WA9XYZ/R KA1ABC/R FN42" 1500.0 0.0 0.1 1.0 10 -15'
print*,' ft4sim "K1ABC RR73; W9XYZ <KH1/KH7Z> -11" 300 0 0 0 1 -10'
print*,'Examples: ft4sim "CQ W9XYZ EN37" 1500 0.0 0.1 1.0 10 -15'
print*,' ft4sim "K1ABC W9XYZ R 539 WI" 1500 0.0 0.1 1.0 10 -15'
go to 999
endif
call getarg(1,msg37) !Message to be transmitted

View File

@ -27,7 +27,7 @@ subroutine getcandidates4(id,fa,fb,syncmin,nfqso,maxcand,savg,candidate, &
! Compute symbol spectra, stepping by NSTEP steps.
savg=0.
tstep=NSTEP/12000.0
df=12000.0/NFFT1 !5.86 Hz
df=12000.0/NFFT1
fac=1.0/300.0
do j=1,NHSYM
ia=(j-1)*NSTEP + 1
@ -48,25 +48,38 @@ subroutine getcandidates4(id,fa,fb,syncmin,nfqso,maxcand,savg,candidate, &
if(nfa.lt.1) nfa=1
nfb=fb/df
if(nfb.gt.nint(5000.0/df)) nfb=nint(5000.0/df)
np=nfb-nfa+1
n300=300/df
n2500=2500/df
! np=nfb-nfa+1
np=n2500-n300+1
indx=0
call indexx(savsm(nfa:nfb),np,indx)
xn=savsm(nfa+indx(nint(0.3*np)))
savsm=savsm/xn
call indexx(savsm(n300:n2500),np,indx)
xn=savsm(n300+indx(nint(0.3*np)))
ncand=0
if(xn.le.1.e-8) return
savsm=savsm/xn
! call ft4_baseline(savg,nfa,nfb,sbase)
! savsm=savsm/sbase
f_offset = -1.5*12000/512
do i=nfa+1,nfb-1
if(savsm(i).ge.savsm(i-1) .and. savsm(i).ge.savsm(i+1) .and. savsm(i).ge.syncmin) then
del=0.5*(savsm(i-1)-savsm(i+1))/(savsm(i-1)-2*savsm(i)+savsm(i+1))
fpeak=(i+del)*df+f_offset
speak=savsm(i) - 0.25*(savsm(i-1)-savsm(i+1))*del
ncand=ncand+1
if(ncand.gt.maxcand) exit
candidate(1,ncand)=fpeak
candidate(2,ncand)=-99.99
candidate(3,ncand)=speak
endif
if(savsm(i).ge.savsm(i-1) .and. savsm(i).ge.savsm(i+1) .and. &
savsm(i).ge.syncmin) then
den=savsm(i-1)-2*savsm(i)+savsm(i+1)
del=0.
if(den.ne.0.0) del=0.5*(savsm(i-1)-savsm(i+1))/den
fpeak=(i+del)*df+f_offset
speak=savsm(i) - 0.25*(savsm(i-1)-savsm(i+1))*del
ncand=ncand+1
if(ncand.gt.maxcand) then
ncand=maxcand
exit
endif
candidate(1,ncand)=fpeak
candidate(2,ncand)=-99.99
candidate(3,ncand)=speak
if(ncand.eq.maxcand) exit
endif
enddo
return

View File

@ -1,13 +1,13 @@
subroutine sync4d(cd0,i0,ctwk,itwk,sync,sync2)
subroutine sync4d(cd0,i0,ctwk,itwk,sync)
! Compute sync power for a complex, downsampled FT4 signal.
include 'ft4_params.f90'
parameter(NP=NMAX/NDOWN,NSS=NSPS/NDOWN)
complex cd0(0:NP-1)
complex csynca(4*NSS),csyncb(4*NSS),csyncc(4*NSS),csyncd(4*NSS)
complex csync2(4*NSS)
complex ctwk(4*NSS)
complex csynca(2*NSS),csyncb(2*NSS),csyncc(2*NSS),csyncd(2*NSS)
complex csync2(2*NSS)
complex ctwk(2*NSS)
complex z1,z2,z3,z4
complex zz1,zz2,zz3,zz4
logical first
@ -29,11 +29,11 @@ subroutine sync4d(cd0,i0,ctwk,itwk,sync,sync2)
phic=0.0
phid=0.0
do i=0,3
dphia=twopi*icos4a(i)/real(NSS)
dphib=twopi*icos4b(i)/real(NSS)
dphic=twopi*icos4c(i)/real(NSS)
dphid=twopi*icos4d(i)/real(NSS)
do j=1,NSS
dphia=2*twopi*icos4a(i)/real(NSS)
dphib=2*twopi*icos4b(i)/real(NSS)
dphic=2*twopi*icos4c(i)/real(NSS)
dphid=2*twopi*icos4d(i)/real(NSS)
do j=1,NSS/2
csynca(k)=cmplx(cos(phia),sin(phia))
csyncb(k)=cmplx(cos(phib),sin(phib))
csyncc(k)=cmplx(cos(phic),sin(phic))
@ -46,7 +46,7 @@ subroutine sync4d(cd0,i0,ctwk,itwk,sync,sync2)
enddo
enddo
first=.false.
fac=1.0/(4.0*NSS)
fac=1.0/(2.0*NSS)
endif
i1=i0 !four Costas arrays
@ -60,36 +60,18 @@ subroutine sync4d(cd0,i0,ctwk,itwk,sync,sync2)
z4=0.
if(itwk.eq.1) csync2=ctwk*csynca !Tweak the frequency
if(i1.ge.0 .and. i1+4*NSS-1.le.NP-1) z1=sum(cd0(i1:i1+4*NSS-1)*conjg(csync2))
if(i1.ge.0 .and. i1+4*NSS-1.le.NP-1) z1=sum(cd0(i1:i1+4*NSS-1:2)*conjg(csync2))
if(itwk.eq.1) csync2=ctwk*csyncb !Tweak the frequency
if(i2.ge.0 .and. i2+4*NSS-1.le.NP-1) z2=sum(cd0(i2:i2+4*NSS-1)*conjg(csync2))
if(i2.ge.0 .and. i2+4*NSS-1.le.NP-1) z2=sum(cd0(i2:i2+4*NSS-1:2)*conjg(csync2))
if(itwk.eq.1) csync2=ctwk*csyncc !Tweak the frequency
if(i3.ge.0 .and. i3+4*NSS-1.le.NP-1) z3=sum(cd0(i3:i3+4*NSS-1)*conjg(csync2))
if(i3.ge.0 .and. i3+4*NSS-1.le.NP-1) z3=sum(cd0(i3:i3+4*NSS-1:2)*conjg(csync2))
if(itwk.eq.1) csync2=ctwk*csyncd !Tweak the frequency
if(i4.ge.0 .and. i4+4*NSS-1.le.NP-1) z4=sum(cd0(i4:i4+4*NSS-1)*conjg(csync2))
if(i4.ge.0 .and. i4+4*NSS-1.le.NP-1) z4=sum(cd0(i4:i4+4*NSS-1:2)*conjg(csync2))
sync = p(z1) + p(z2) + p(z3) + p(z4)
sync2=0.0
!do i=1,4
! i1=i0+(i-1)*33*NSS
! if(i.eq.1) csync2=ctwk*csynca
! if(i.eq.2) csync2=ctwk*csyncb
! if(i.eq.3) csync2=ctwk*csyncc
! if(i.eq.4) csync2=ctwk*csyncd
! z1=sum(cd0(i1 :i1+ NSS-1)*conjg(csync2( 1: NSS)))
! z2=sum(cd0(i1+ NSS:i1+2*NSS-1)*conjg(csync2( NSS+1:2*NSS)))
! z3=sum(cd0(i1+2*NSS:i1+3*NSS-1)*conjg(csync2(2*NSS+1:3*NSS)))
! z4=sum(cd0(i1+3*NSS:i1+4*NSS-1)*conjg(csync2(3*NSS+1:4*NSS)))
! sync2=sync2 + abs(z1)**2+abs(z2)**2+abs(z3)**2+abs(z4)**2+&
! 2*abs(z1*conjg(z2)+z2*conjg(z3)+z3*conjg(z4)) + &
! 2*abs(z1*conjg(z3)+z2*conjg(z4)) + &
! 2*abs(z1*conjg(z4))
!enddo
!sync2=sync2*(fac**2)
return
end subroutine sync4d

View File

@ -1,9 +1,12 @@
#include "logqso.h"
#include <random>
#include <limits>
#include <QString>
#include <QSettings>
#include <QStandardPaths>
#include <QDir>
#include <QPushButton>
#include "logbook/logbook.h"
#include "MessageBox.hpp"
@ -15,17 +18,40 @@
#include "ui_logqso.h"
#include "moc_logqso.cpp"
namespace
{
using dist_type = std::uniform_int_distribution<int>;
std::random_device rd;
std::mt19937 twister (rd ());
dist_type int_distribution;
}
LogQSO::LogQSO(QString const& programTitle, QSettings * settings
, Configuration const * config, QWidget *parent)
: QDialog {parent, Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint}
, ui(new Ui::LogQSO)
, ok_ {new QPushButton {"OK", this}}
, cancel_ {new QPushButton {"Cancel", this}}
, m_settings (settings)
, m_config {config}
{
ui->setupUi(this);
setWindowTitle(programTitle + " - Log QSO");
loadSettings ();
ui->grid->setValidator (new MaidenheadLocatorValidator {this});
ok_->setAutoDefault (false);
ok_->setFocusPolicy (Qt::ClickFocus);
cancel_->setAutoDefault (false);
ui->button_layout->addStretch ();
ui->button_layout->addWidget (ok_);
ui->button_layout->addStretch ();
ui->button_layout->addWidget (cancel_);
ui->button_layout->addStretch ();
loadSettings ();
connect (ok_, &QAbstractButton::clicked, [this] (bool) {accept ();});
connect (cancel_, &QAbstractButton::clicked, [this] (bool) {reject ();});
}
LogQSO::~LogQSO ()
@ -113,7 +139,22 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString
}
else
{
show();
// randomize accessible name of buttons
ok_->setAccessibleName (QString::number (int_distribution (twister)));
cancel_->setAccessibleName (QString::number (int_distribution (twister)));
// random sibling order of buttons
if (int_distribution (twister, dist_type::param_type {0, 1})) ok_->stackUnder (cancel_); else cancel_->stackUnder (ok_);
// random shuffle of layout items
for (int item = ui->button_layout->count () - 1; item > 0; --item)
{
auto other_item = int_distribution (twister, dist_type::param_type {0, item});
if (item != other_item)
{
ui->button_layout->insertItem (other_item, ui->button_layout->takeAt (item));
ui->button_layout->insertItem (item, ui->button_layout->takeAt (other_item + 1));
}
}
show ();
}
}

View File

@ -18,6 +18,7 @@ class QSettings;
class Configuration;
class QByteArray;
class CabrilloLog;
class QPushButton;
class LogQSO : public QDialog
{
@ -52,6 +53,8 @@ private:
void storeSettings () const;
QScopedPointer<Ui::LogQSO> ui;
QPushButton * ok_;
QPushButton * cancel_;
QSettings * m_settings;
Configuration const * m_config;
QString m_txPower;

View File

@ -461,14 +461,7 @@
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<layout class="QHBoxLayout" name="button_layout"/>
</item>
</layout>
</widget>
@ -488,38 +481,5 @@
<tabstop>cbComments</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>LogQSO</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>LogQSO</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

View File

@ -3700,6 +3700,15 @@ void MainWindow::guiUpdate()
char ft8msgbits[77];
genft8_(message, &i3, &n3, msgsent, const_cast<char *> (ft8msgbits),
const_cast<int *> (itone), 37, 37);
int nsym=79;
int nsps=4*1920;
float fsample=48000.0;
float f0=ui->TxFreqSpinBox->value() - m_XIT;
int icmplx=0;
int nwave=nsym*nsps;
gen_ft8wave_(const_cast<int *>(itone),&nsym,&nsps,&fsample,&f0,foxcom_.wave,
foxcom_.wave,&icmplx,&nwave);
if(SpecOp::FOX == m_config.special_op_id()) {
//Fox must generate the full Tx waveform, not just an itone[] array.
QString fm = QString::fromStdString(message).trimmed();
@ -3892,10 +3901,12 @@ void MainWindow::guiUpdate()
SpecOp::RTTY==m_config.special_op_id()) ) {
//We're in a contest-like mode other than EU_VHF: start QSO with Tx2.
ui->tx1->setEnabled(false);
ui->txb1->setEnabled(false);
}
if(!ui->tx1->isEnabled() and SpecOp::EU_VHF==m_config.special_op_id()) {
//We're in EU_VHF mode: start QSO with Tx1.
ui->tx1->setEnabled(true);
ui->txb1->setEnabled(true);
}
}
@ -4206,7 +4217,11 @@ void MainWindow::on_txb1_clicked()
m_ntx=1;
m_QSOProgress = REPLYING;
ui->txrb1->setChecked(true);
if (m_transmitting) m_restart=true;
if(m_mode=="FT4") {
ft4_tx(1);
} else {
if(m_transmitting) m_restart=true;
}
}
else {
on_txb2_clicked ();
@ -4227,7 +4242,11 @@ void MainWindow::on_txb2_clicked()
m_ntx=2;
m_QSOProgress = REPORT;
ui->txrb2->setChecked(true);
if (m_transmitting) m_restart=true;
if(m_mode=="FT4") {
ft4_tx(2);
} else {
if(m_transmitting) m_restart=true;
}
}
void MainWindow::on_txb3_clicked()
@ -4235,7 +4254,11 @@ void MainWindow::on_txb3_clicked()
m_ntx=3;
m_QSOProgress = ROGER_REPORT;
ui->txrb3->setChecked(true);
if (m_transmitting) m_restart=true;
if(m_mode=="FT4") {
ft4_tx(3);
} else {
if(m_transmitting) m_restart=true;
}
}
void MainWindow::on_txb4_clicked()
@ -4243,7 +4266,11 @@ void MainWindow::on_txb4_clicked()
m_ntx=4;
m_QSOProgress = ROGERS;
ui->txrb4->setChecked(true);
if (m_transmitting) m_restart=true;
if(m_mode=="FT4") {
ft4_tx(4);
} else {
if(m_transmitting) m_restart=true;
}
}
void MainWindow::on_txb4_doubleClicked()
@ -4261,7 +4288,11 @@ void MainWindow::on_txb5_clicked()
m_ntx=5;
m_QSOProgress = SIGNOFF;
ui->txrb5->setChecked(true);
if (m_transmitting) m_restart=true;
if(m_mode=="FT4") {
ft4_tx(5);
} else {
if(m_transmitting) m_restart=true;
}
}
void MainWindow::on_txb5_doubleClicked()
@ -4275,12 +4306,16 @@ void MainWindow::on_txb6_clicked()
m_QSOProgress = CALLING;
set_dateTimeQSO(-1);
ui->txrb6->setChecked(true);
if (m_transmitting) m_restart=true;
if(m_mode=="FT4") {
ft4_tx(6);
} else {
if(m_transmitting) m_restart=true;
}
}
void MainWindow::doubleClickOnCall2(Qt::KeyboardModifiers modifiers)
{
if(m_mode=="FT4" and m_inQSOwith!="") return;
//Confusing: come here after double-click on left text window, not right window.
set_dateTimeQSO(-1); // reset our QSO start time
m_decodedText2=true;
doubleClickOnCall(modifiers);
@ -4289,7 +4324,6 @@ void MainWindow::doubleClickOnCall2(Qt::KeyboardModifiers modifiers)
void MainWindow::doubleClickOnCall(Qt::KeyboardModifiers modifiers)
{
if(m_mode=="FT4" and m_inQSOwith!="") return;
QTextCursor cursor;
if(m_mode=="ISCAT") {
MessageBox::information_message (this,
@ -4348,6 +4382,21 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
ui->TxFreqSpinBox->setValue(frequency); //Set Tx freq
}
}
if(m_mode=="FT4") {
int i0=message.string().indexOf(" + ");
QString t=message.string().trimmed().mid(i0+4,-1);
int n=0;
if(t==ui->tx1->text()) n=1;
if(t==ui->tx2->text()) n=2;
if(t==ui->tx3->text()) n=3;
if(t==ui->tx4->text()) n=4;
if(t==ui->tx5->currentText()) n=5;
if(t==ui->tx6->text()) n=6;
if(n>0) {
if(ctrl) ui->TxFreqSpinBox->setValue(frequency);
ft4_tx(n);
}
}
return;
}
@ -5149,6 +5198,7 @@ void MainWindow::clearDX ()
m_rptRcvd.clear ();
m_qsoStart.clear ();
m_qsoStop.clear ();
m_inQSOwith.clear();
genStdMsgs (QString {});
if (ui->tabWidget->currentIndex() == 1) {
ui->genMsg->setText(ui->tx6->text());
@ -6895,15 +6945,6 @@ void MainWindow::transmit (double snr)
if (m_modeTx == "FT8") {
// toneSpacing=12000.0/1920.0;
toneSpacing=-3;
int nsym=79;
int nsps=4*1920;
float fsample=48000.0;
float f0=ui->TxFreqSpinBox->value() - m_XIT;
int icmplx=0;
int nwave=nsym*nsps;
gen_ft8wave_(const_cast<int *>(itone),&nsym,&nsps,&fsample,&f0,foxcom_.wave,
foxcom_.wave,&icmplx,&nwave);
if(m_config.x2ToneSpacing()) toneSpacing=2*12000.0/1920.0;
if(m_config.x4ToneSpacing()) toneSpacing=4*12000.0/1920.0;
if(SpecOp::FOX==m_config.special_op_id() and !m_tune) toneSpacing=-1;