Merged master 8748

This commit is contained in:
Jordan Sherer
2018-08-05 11:33:30 -04:00
parent 8f8772f1bd
commit 62899069bf
1222 changed files with 70382 additions and 406763 deletions
@@ -1,75 +0,0 @@
#ifndef HAMLIB_TRANSCEIVER_HPP_
#define HAMLIB_TRANSCEIVER_HPP_
#include <tuple>
#include <QString>
#include <hamlib/rig.h>
#include "TransceiverFactory.hpp"
#include "PollingTransceiver.hpp"
extern "C"
{
typedef struct rig RIG;
struct rig_caps;
typedef int vfo_t;
}
// hamlib transceiver and PTT mostly delegated directly to hamlib Rig class
class HamlibTransceiver final
: public PollingTransceiver
{
Q_OBJECT; // for translation context
public:
static void register_transceivers (TransceiverFactory::Transceivers *);
static void unregister_transceivers ();
explicit HamlibTransceiver (int model_number, TransceiverFactory::ParameterPack const&,
QObject * parent = nullptr);
explicit HamlibTransceiver (TransceiverFactory::PTTMethod ptt_type, QString const& ptt_port,
QObject * parent = nullptr);
private:
int do_start () override;
void do_stop () override;
void do_frequency (Frequency, MODE, bool no_ignore) override;
void do_tx_frequency (Frequency, MODE, bool no_ignore) override;
void do_mode (MODE) override;
void do_ptt (bool) override;
void poll () override;
void error_check (int ret_code, QString const& doing) const;
void set_conf (char const * item, char const * value);
QByteArray get_conf (char const * item);
Transceiver::MODE map_mode (rmode_t) const;
rmode_t map_mode (Transceiver::MODE mode) const;
std::tuple<vfo_t, vfo_t> get_vfos (bool for_split) const;
struct RIGDeleter {static void cleanup (RIG *);};
QScopedPointer<RIG, RIGDeleter> rig_;
bool back_ptt_port_;
bool one_VFO_;
bool is_dummy_;
// these are saved on destruction so we can start new instances
// where the last one left off
static freq_t dummy_frequency_;
static rmode_t dummy_mode_;
bool mutable reversed_;
bool freq_query_works_;
bool mode_query_works_;
bool split_query_works_;
bool tickle_hamlib_; // Hamlib requires a
// rig_set_split_vfo() call to
// establish the Tx VFO
bool get_vfo_works_; // Net rigctl promises what it can't deliver
};
#endif
@@ -1,83 +0,0 @@
subroutine ft8b(s,nfqso,f1,xdt,nharderrors,dmin,nbadcrc,message)
use timer_module, only: timer
include 'ft8_params.f90'
parameter(NRECENT=10)
character*12 recent_calls(NRECENT)
character message*22
real s(NH1,NHSYM)
real s1(0:7,ND)
real ps(0:7)
real rxdata(3*ND),llr(3*ND) !Soft symbols
integer*1 decoded(KK),apmask(3*ND),cw(3*ND)
max_iterations=40
norder=2
! if(abs(nfqso-f1).lt.10.0) norder=3
tstep=0.5*NSPS/12000.0
df=12000.0/NFFT1
i0=max(1,nint(f1/df))
j0=nint(xdt/tstep)
j=0
ia=i0
ib=i0+14
do k=1,NN
if(k.le.7) cycle
if(k.ge.37 .and. k.le.43) cycle
if(k.gt.72) cycle
n=j0+2*(k-1)+1
if(n.lt.1) cycle
j=j+1
s1(0:7,j)=s(ia:ib:2,n)
enddo
do j=1,ND
ps=s1(0:7,j)
where (ps.gt.0.0) ps=log(ps)
r1=max(ps(1),ps(3),ps(5),ps(7))-max(ps(0),ps(2),ps(4),ps(6))
r2=max(ps(2),ps(3),ps(6),ps(7))-max(ps(0),ps(1),ps(4),ps(5))
r4=max(ps(4),ps(5),ps(6),ps(7))-max(ps(0),ps(1),ps(2),ps(3))
rxdata(3*j-2)=r4
rxdata(3*j-1)=r2
rxdata(3*j)=r1
enddo
rxav=sum(rxdata)/(3.0*ND)
rx2av=sum(rxdata*rxdata)/(3.0*ND)
var=rx2av-rxav*rxav
if( var .gt. 0.0 ) then
rxsig=sqrt(var)
else
rxsig=sqrt(rx2av)
endif
rxdata=rxdata/rxsig
ss=0.84
llr=2.0*rxdata/(ss*ss)
apmask=0
cw=0
! cw will be needed for subtraction.
! dmin is the correlation discrepancy of a returned codeword - it is
! used to select the best codeword within osd174.
call timer('bpd174 ',0)
call bpdecode174(llr,apmask,max_iterations,decoded,cw,nharderrors)
call timer('bpd174 ',1)
dmin=0.0
if(nharderrors.lt.0) then
call timer('osd174 ',0)
call osd174(llr,norder,decoded,cw,nharderrors,dmin)
call timer('osd174 ',1)
! This threshold needs to be tuned. 99.0 should pass everything.
if( dmin .gt. 99.0 ) nharderrors=-1
endif
nbadcrc=1
message=' '
if(count(cw.eq.0).eq.174) go to 900 !Reject the all-zero codeword
if(nharderrors.ge.0) call chkcrc12a(decoded,nbadcrc)
if(nbadcrc.eq.0) then
call extractmessage174(decoded,message,ncrcflag,recent_calls,nrecent)
endif
900 continue
return
end subroutine ft8b
@@ -0,0 +1,187 @@
program chkfft
! Tests and times one-dimensional FFTs computed by FFTW3
use FFTW3
parameter (NMAX=8*1024*1024) !Maximum FFT length
complex a(NMAX),b(NMAX),c(NMAX)
real ar(NMAX),br(NMAX),cr(NMAX)
real mflops
integer*8 plan1,plan2 !Pointers to stored plans
character infile*12,arg*8
logical list
common/patience/npatience
equivalence (a,ar),(b,br),(c,cr)
! include 'fftw3.f90' !FFTW definitions
nargs=iargc()
if(nargs.ne.6) then
print*,'Usage: chkfft <nfft | infile> nr nw nc np inplace'
print*,' nfft: length of FFT'
print*,' nfft=0: do lengths 2^n, n=2^4 to 2^23'
print*,' infile: name of file with nfft values, one per line'
print*,' nr: 0/1 to not read (or read) wisdom'
print*,' nw: 0/1 to not write (or write) wisdom'
print*,' nc: 0/1 for real or complex data'
print*,' np: 0-4 patience for finding best algorithm'
print*,' inplace: 1 for inplace, 0 otherwise'
go to 999
endif
list=.false.
nfft=-1
call getarg(1,infile)
open(10,file=infile,status='old',err=1)
list=.true. !A valid file name was provided
go to 2
1 read(infile,*) nfft !Take first argument to be nfft
2 call getarg(2,arg)
read(arg,*) nr
call getarg(3,arg)
read(arg,*) nw
call getarg(4,arg)
read(arg,*) ncomplex
call getarg(5,arg)
read(arg,*) npatience
call getarg(6,arg)
read(arg,*) inplace
if(list) write(*,1000) infile,nr,nw,ncomplex,npatience
1000 format(/'infile: ',a12,' nr:',i2,' nw',i2,' nc:',i2,' np:',i2/)
if(.not.list) write(*,1002) nfft,nr,nw,ncomplex,npatience
1002 format(/'nfft: ',i10,' nr:',i2,' nw',i2,' nc:',i2,' np:',i2/)
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
open(12,file='chkfft.out',status='unknown')
open(13,file='fftwf_wisdom.dat',status='unknown')
if(nr.ne.0) then
call import_wisdom_from_file(isuccess,13)
if(isuccess.eq.0) then
write(*,1010)
1010 format('Failed to import FFTW wisdom.')
go to 999
endif
endif
idum=-1 !Set random seed
ndim=1 !One-dimensional transforms
do i=1,NMAX !Set random data
x=gran()
y=gran()
b(i)=cmplx(x,y) !Generate random data
enddo
iters=1000000
if(list .or. (nfft.gt.0)) then
n1=1
n2=1
if(nfft.eq.-1) n2=999999
write(*,1020)
1020 format(' NFFT Time rms MHz MFlops iters', &
' tplan'/61('-'))
else
n1=4
n2=23
write(*,1030)
1030 format(' n N=2^n Time rms MHz MFlops iters', &
' tplan'/63('-'))
endif
do ii=n1,n2 !Test one or more FFT lengths
if(list) then
read(10,*,end=900) nfft !Read nfft from file
else if(n2.gt.n1) then
nfft=2**ii !Do powers of 2
endif
iformf=1
iformb=1
if(ncomplex.eq.0) then
iformf=0 !Real-to-complex transform
iformb=-1 !Complex-to-real (inverse) transform
endif
if(nfft.gt.NMAX) go to 900
a(1:nfft)=b(1:nfft) !Copy test data into a()
t0=second()
if(inplace.ne.0) then
if(ncomplex.ne.0) then
call sfftw_plan_dft_1d(plan1,nfft,a,a,FFTW_FORWARD,nflags)
call sfftw_plan_dft_1d(plan2,nfft,a,a,FFTW_BACKWARD,nflags)
else
call sfftw_plan_dft_r2c_1d(plan1,nfft,a,a,nflags)
call sfftw_plan_dft_c2r_1d(plan2,nfft,a,a,nflags)
endif
else
if(ncomplex.ne.0) then
call sfftw_plan_dft_1d(plan1,nfft,a,c,FFTW_FORWARD,nflags)
call sfftw_plan_dft_1d(plan2,nfft,c,a,FFTW_BACKWARD,nflags)
else
call sfftw_plan_dft_r2c_1d(plan1,nfft,a,c,nflags)
call sfftw_plan_dft_c2r_1d(plan2,nfft,c,a,nflags)
endif
endif
t2=second()
tplan=t2-t0 !Total planning time for this length
total=0.
do iter=1,iters !Now do many iterations
a(1:nfft)=b(1:nfft) !Copy test data into a()
t0=second()
call sfftw_execute(plan1)
call sfftw_execute(plan2)
t1=second()
total=total+t1-t0
if(total.ge.1.0) go to 40 !Cut iterations short if t>1 s
enddo
iter=iters
40 time=0.5*total/iter !Time for one FFT of current length
tplan=0.5*tplan-time !Planning time for one FFT
if(tplan.lt.0) tplan=0.
a(1:nfft)=a(1:nfft)/nfft
! Compute RMS difference between original array and back-transformed array.
sq=0.
if(ncomplex.eq.1) then
do i=1,nfft
sq=sq + real(a(i)-b(i))**2 + imag(a(i)-b(i))**2
enddo
else
do i=1,nfft
sq=sq + (ar(i)-br(i))**2
enddo
endif
rms=sqrt(sq/nfft)
freq=1.e-6*nfft/time
mflops=5.0/(1.e6*time/(nfft*log(float(nfft))/log(2.0)))
if(n2.eq.1 .or. n2.eq.999999) then
write(*,1050) nfft,time,rms,freq,mflops,iter,tplan
write(12,1050) nfft,time,rms,freq,mflops,iter,tplan
1050 format(i8,f11.7,f12.8,f7.2,f8.1,i8,f6.1)
else
write(*,1060) ii,nfft,time,rms,freq,mflops,iter,tplan
write(12,1060) ii,nfft,time,rms,freq,mflops,iter,tplan
1060 format(i2,i8,f11.7,f12.8,f7.2,f8.1,i8,f6.1)
endif
enddo
900 continue
if(nw.eq.1) then
rewind 13
call export_wisdom_to_file(13)
! write(*,1070)
!1070 format(/'Exported FFTW wisdom')
endif
call sfftw_destroy_plan(plan1)
call sfftw_destroy_plan(plan2)
999 end program chkfft
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

@@ -1,285 +0,0 @@
program wsprlfsim
! Simulate characteristics of a potential "WSPR-LF" mode using LDPC (300,60)
! code, OQPSK modulation, and 5 minute T/R sequences.
! Reception and Demodulation algorithm:
! 1. Compute coarse spectrum; find fc1 = approx carrier freq
! 2. Mix from fc1 to 0; LPF at +/- 0.75*R
! 3. Square, FFT; find peaks near -R/2 and +R/2 to get fc2
! 4. Mix from fc2 to 0
! 5. Fit cb13 (central part of csync) to c -> lag, phase
! 6. Fit complex ploynomial for channel equalization
! 7. Get soft bits from equalized data
include 'wsprlf_params.f90'
! Q: Would it be better for central Sync array to use both I and Q channels?
character*8 arg
complex cbb(0:NZ-1) !Complex baseband waveform
complex csync(0:NZ-1) !Sync symbols only, from cbb
complex c(0:NZ-1) !Complex waveform
complex c0(0:NZ-1) !Complex waveform
complex c1(0:NZ-1) !Complex waveform
complex zz(NS+ND) !Complex symbol values (intermediate)
complex z
real xnoise(0:NZ-1) !Generated random noise
real ynoise(0:NZ-1) !Generated random noise
real rxdata(ND),llr(ND) !Soft symbols
real pp(2*NSPS) !Shaped pulse for OQPSK
real a(5) !For twkfreq1
real aa(20),bb(20) !Fitted polyco's
real t(11)
character*12 label(11)
integer*8 count0,count1,count2,count3,clkfreq
integer nc(11)
integer id(NS+ND) !NRZ values (+/-1) for Sync and Data
integer ierror(NS+ND)
integer icw(NN)
integer itone(NN)
integer*1 msgbits(KK),decoded(KK),apmask(ND),cw(ND)
! integer*1 codeword(ND)
data msgbits/0,0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1, &
1,1,1,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,1,0,1,0,1,1,0,0,1,1/
data label/'genwsprlf','twkfreq1 a','watterson','noise gen','getfc1w', &
'getfc2w','twkfreq1 b','xdt loop','cpolyfitw','msksoftsym', &
'bpdecode300'/
nargs=iargc()
if(nargs.ne.6) then
print*,'Usage: wsprlfsim f0(Hz) delay(ms) fspread(Hz) maxn iters snr(dB)'
print*,'Example: wsprlfsim 0 0 0 5 10 -20'
print*,'Set snr=0 to cycle through a range'
go to 999
endif
call getarg(1,arg)
read(arg,*) f0 !Generated carrier frequency
call getarg(2,arg)
read(arg,*) delay !Delta_t (ms) for Watterson model
call getarg(3,arg)
read(arg,*) fspread !Fspread (Hz) for Watterson model
call getarg(4,arg)
read(arg,*) maxn !Max nterms for polyfit
call getarg(5,arg)
read(arg,*) iters !Iterations at each SNR
call getarg(6,arg)
read(arg,*) snrdb !Specified SNR_2500
nc=0
twopi=8.0*atan(1.0)
fs=NSPS*12000.0/NSPS0 !Sample rate = 22.2222... Hz
dt=1.0/fs !Sample interval (s)
tt=NSPS*dt !Duration of "itone" symbols (s)
ts=2*NSPS*dt !Duration of OQPSK symbols (s)
baud=1.0/tt !Keying rate for "itone" symbols (baud)
txt=NZ*dt !Transmission length (s)
bandwidth_ratio=2500.0/(fs/2.0)
write(*,1000) fs,f0,delay,fspread,maxn,baud,3*baud,txt,iters
1000 format('fs:',f10.3,' f0:',f5.1,' Delay:',f4.1,' fSpread:',f5.2, &
' maxn:',i3,/'Baud:',f8.3,' BW:',f5.1,' TxT:',f6.1,' iters:',i4/)
write(*,1004)
1004 format(/' SNR sync data ser ber fer fsigma tsigma', &
' tsec'/68('-'))
do i=1,N2 !Half-sine pulse shape
pp(i)=sin(0.5*(i-1)*twopi/(2*NSPS))
enddo
t=0.
call system_clock(count0,clkfreq)
call genwsprlf(msgbits,id,icw,cbb,csync,itone)!Generate baseband waveform
call system_clock(count1,clkfreq)
t(1)=float(count1-count0)/float(clkfreq)
nc(1)=nc(1)+1
do i=0,NZ-1
write(40,4001) i,cbb(i),csync(i)
4001 format(i8,4f12.6)
enddo
call system_clock(count0,clkfreq)
a=0.
a(1)=f0
call twkfreq1(cbb,NZ,fs,a,c0) !Mix baseband to specified frequency
call system_clock(count1,clkfreq)
t(2)=float(count1-count0)/float(clkfreq)
nc(2)=nc(2)+1
isna=-20
isnb=-40
if(snrdb.ne.0.0) then
isna=nint(snrdb)
isnb=isna
endif
do isnr=isna,isnb,-1 !Loop over SNR range
if(isna.ne.isnb) snrdb=isnr
sig=sqrt(bandwidth_ratio) * 10.0**(0.05*snrdb)
if(snrdb.gt.90.0) sig=1.0
nhard=0
nhardsync=0
nfe=0
sqf=0.
sqt=0.
call system_clock(count2,clkfreq)
do iter=1,iters !Loop over requested iterations
c=c0
call system_clock(count0,clkfreq)
if(delay.ne.0.0 .or. fspread.ne.0.0) then
call watterson(c,NZ,fs,delay,fspread)
endif
call system_clock(count1,clkfreq)
t(3)=t(3)+float(count1-count0)/float(clkfreq)
nc(3)=nc(3)+1
call system_clock(count0,clkfreq)
c=sig*c !Scale to requested SNR
if(snrdb.lt.90) then
do i=0,NZ-1 !Generate gaussian noise
xnoise(i)=gran()
ynoise(i)=gran()
enddo
c=c + cmplx(xnoise,ynoise) !Add AWGN noise
endif
call system_clock(count1,clkfreq)
t(4)=t(4)+float(count1-count0)/float(clkfreq)
nc(4)=nc(4)+1
call system_clock(count0,clkfreq)
call getfc1w(c,fs,fc1) !First approx for freq
call system_clock(count1,clkfreq)
t(5)=t(5)+float(count1-count0)/float(clkfreq)
nc(5)=nc(5)+1
call system_clock(count0,clkfreq)
call getfc2w(c,csync,fs,fc1,fc2,fc3) !Refined freq
call system_clock(count1,clkfreq)
t(6)=t(6)+float(count1-count0)/float(clkfreq)
nc(6)=nc(6)+1
sqf=sqf + (fc1+fc2-f0)**2
call system_clock(count0,clkfreq)
!NB: Measured performance is about equally good using fc2 or fc3 here:
a(1)=-(fc1+fc2)
a(2:5)=0.
call twkfreq1(c,NZ,fs,a,c) !Mix c down by fc1+fc2
call system_clock(count1,clkfreq)
t(7)=t(7)+float(count1-count0)/float(clkfreq)
nc(7)=nc(7)+1
! The following may not be necessary?
! z=sum(c(3088:3503)*cb13)/208.0 !Get phase from Barker 13 vector
! z0=z/abs(z)
! c=c*conjg(z0)
call system_clock(count0,clkfreq)
!---------------------------------------------------------------- DT
! Not presently used:
amax=0.
jpk=0
iaa=0
ibb=NZ-1
do j=-20*NSPS,20*NSPS,NSPS/8
ia=j
ib=NZ-1+j
if(ia.lt.0) then
ia=0
iaa=-j
else
iaa=0
endif
if(ib.gt.NZ-1) then
ib=NZ-1
ibb=NZ-1-j
endif
z=sum(c(ia:ib)*conjg(csync(iaa:ibb)))
if(abs(z).gt.amax) then
amax=abs(z)
jpk=j
endif
enddo
xdt=jpk/fs
sqt=sqt + xdt**2
call system_clock(count1,clkfreq)
t(8)=t(8)+float(count1-count0)/float(clkfreq)
nc(8)=nc(8)+1
!-----------------------------------------------------------------
nterms=maxn
c1=c
do itry=1,20
idf=itry/2
if(mod(itry,2).eq.0) idf=-idf
nhard0=0
nhardsync0=0
ifer=1
a(1)=idf*0.00085
a(2:5)=0.
call system_clock(count0,clkfreq)
call twkfreq1(c1,NZ,fs,a,c) !Mix c1 into c
call cpolyfitw(c,pp,id,maxn,aa,bb,zz,nhs)
call system_clock(count1,clkfreq)
t(9)=t(9)+float(count1-count0)/float(clkfreq)
nc(9)=nc(9)+1
call system_clock(count0,clkfreq)
call msksoftsymw(zz,aa,bb,id,nterms,ierror,rxdata,nhard0,nhardsync0)
call system_clock(count1,clkfreq)
t(10)=t(10)+float(count1-count0)/float(clkfreq)
nc(10)=nc(10)+1
if(nhardsync0.gt.35) cycle
rxav=sum(rxdata)/ND
rx2av=sum(rxdata*rxdata)/ND
rxsig=sqrt(rx2av-rxav*rxav)
rxdata=rxdata/rxsig
ss=0.84
llr=2.0*rxdata/(ss*ss)
apmask=0
max_iterations=40
ifer=0
call system_clock(count0,clkfreq)
call bpdecode300(llr,apmask,max_iterations,decoded,niterations,cw)
call system_clock(count1,clkfreq)
t(11)=t(11)+float(count1-count0)/float(clkfreq)
nc(11)=nc(11)+1
nbadcrc=0
if(niterations.ge.0) call chkcrc10(decoded,nbadcrc)
if(niterations.lt.0 .or. count(msgbits.ne.decoded).gt.0 .or. &
nbadcrc.ne.0) ifer=1
if(ifer.eq.0) exit
enddo !Freq dither loop
nhard=nhard+nhard0
nhardsync=nhardsync+nhardsync0
nfe=nfe+ifer
if(nhardsync0+nhard0+niterations+ifer.gt.0) write(42,1045) snrdb, &
nhardsync0,nhard0,niterations,ifer,xdt
1045 format(f6.1,4i6,f8.2)
enddo
call system_clock(count3,clkfreq)
tsec=float(count3-count2)/float(clkfreq)
fsigma=sqrt(sqf/iters)
tsigma=sqrt(sqt/iters)
ser=float(nhardsync)/(NS*iters)
ber=float(nhard)/(ND*iters)
fer=float(nfe)/iters
write(*,1050) snrdb,nhardsync,nhard,ser,ber,fer,fsigma,tsigma,tsec
1050 format(f6.1,2i7,2f8.4,f7.3,2f8.2f8.3)
enddo
write(*,1060) NS*iters,ND*iters
1060 format(68('-')/6x,2i7)
write(*,1065)
1065 format(/'Timing sec frac calls'/39('-'))
do i=1,11
write(*,1070) label(i),t(i),t(i)/sum(t),nc(i)
1070 format(a12,2f9.3,i8)
enddo
write(*,1072) sum(t),1.0
1072 format(39('-')/12x,2f10.3)
999 end program wsprlfsim
@@ -1,620 +0,0 @@
// -*- Mode: C++ -*-
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#ifdef QT5
#include <QtWidgets>
#else
#include <QtGui>
#endif
#include <QThread>
#include <QTimer>
#include <QDateTime>
#include <QList>
#include <QAudioDeviceInfo>
#include <QScopedPointer>
#include <QDir>
#include <QProgressDialog>
#include <QAbstractSocket>
#include <QHostAddress>
#include <QPointer>
#include <QSet>
#include <QVector>
#include <QFuture>
#include <QFutureWatcher>
#include "AudioDevice.hpp"
#include "commons.h"
#include "Radio.hpp"
#include "Modes.hpp"
#include "FrequencyList.hpp"
#include "Configuration.hpp"
#include "WSPRBandHopping.hpp"
#include "Transceiver.hpp"
#include "DisplayManual.hpp"
#include "psk_reporter.h"
#include "logbook/logbook.h"
#include "decodedtext.h"
#include "commons.h"
#include "astro.h"
#include "MessageBox.hpp"
#include "NetworkAccessManager.hpp"
#define NUM_JT4_SYMBOLS 206 //(72+31)*2, embedded sync
#define NUM_JT65_SYMBOLS 126 //63 data + 63 sync
#define NUM_JT9_SYMBOLS 85 //69 data + 16 sync
#define NUM_WSPR_SYMBOLS 162 //(50+31)*2, embedded sync
#define NUM_WSPR_LF_SYMBOLS 412 //300 data + 109 sync + 3 ramp
#define NUM_ISCAT_SYMBOLS 1291 //30*11025/256
#define NUM_MSK144_SYMBOLS 144 //s8 + d48 + s8 + d80
#define NUM_QRA64_SYMBOLS 84 //63 data + 21 sync
#define NUM_FT8_SYMBOLS 79
#define NUM_CW_SYMBOLS 250
#define TX_SAMPLE_RATE 48000
#define N_WIDGETS 24
extern int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols
extern int volatile icw[NUM_CW_SYMBOLS]; //Dits for CW ID
//--------------------------------------------------------------- MainWindow
namespace Ui {
class MainWindow;
}
class QSettings;
class QLineEdit;
class QFont;
class QHostInfo;
class EchoGraph;
class FastGraph;
class WideGraph;
class LogQSO;
class Transceiver;
class MessageAveraging;
class MessageClient;
class QTime;
class WSPRBandHopping;
class HelpTextWindow;
class WSPRNet;
class SoundOutput;
class Modulator;
class SoundInput;
class Detector;
class SampleDownloader;
class MultiSettings;
class PhaseEqualizationDialog;
class MainWindow : public QMainWindow
{
Q_OBJECT;
public:
using Frequency = Radio::Frequency;
using FrequencyDelta = Radio::FrequencyDelta;
using Mode = Modes::Mode;
explicit MainWindow(QDir const& temp_directory, bool multiple, MultiSettings *,
QSharedMemory *shdmem, unsigned downSampleFactor,
QSplashScreen *,
QWidget *parent = nullptr);
~MainWindow();
public slots:
void showSoundInError(const QString& errorMsg);
void showSoundOutError(const QString& errorMsg);
void showStatusMessage(const QString& statusMsg);
void dataSink(qint64 frames);
void fastSink(qint64 frames);
void diskDat();
void freezeDecode(int n);
void guiUpdate();
void doubleClickOnCall(bool shift, bool ctrl);
void doubleClickOnCall2(bool shift, bool ctrl);
void readFromStdout();
void p1ReadFromStdout();
void setXIT(int n, Frequency base = 0u);
void setFreq4(int rxFreq, int txFreq);
void msgAvgDecode2();
void fastPick(int x0, int x1, int y);
protected:
void keyPressEvent (QKeyEvent *) override;
void closeEvent(QCloseEvent *) override;
void childEvent(QChildEvent *) override;
bool eventFilter(QObject *, QEvent *) override;
private slots:
void on_tx1_editingFinished();
void on_tx2_editingFinished();
void on_tx3_editingFinished();
void on_tx4_editingFinished();
void on_tx5_currentTextChanged (QString const&);
void on_tx6_editingFinished();
void on_actionSettings_triggered();
void on_monitorButton_clicked (bool);
void on_actionAbout_triggered();
void on_autoButton_clicked (bool);
void on_stopTxButton_clicked();
void on_stopButton_clicked();
void on_actionRelease_Notes_triggered ();
void on_actionOnline_User_Guide_triggered();
void on_actionLocal_User_Guide_triggered();
void on_actionWide_Waterfall_triggered();
void on_actionOpen_triggered();
void on_actionOpen_next_in_directory_triggered();
void on_actionDecode_remaining_files_in_directory_triggered();
void on_actionDelete_all_wav_files_in_SaveDir_triggered();
void on_actionOpen_log_directory_triggered ();
void on_actionNone_triggered();
void on_actionSave_all_triggered();
void on_actionKeyboard_shortcuts_triggered();
void on_actionSpecial_mouse_commands_triggered();
void on_DecodeButton_clicked (bool);
void decode();
void decodeBusy(bool b);
void on_EraseButton_clicked();
void on_txb1_clicked();
void on_txFirstCheckBox_stateChanged(int arg1);
void set_dateTimeQSO(int m_ntx);
void set_ntx(int n);
void on_txrb1_toggled(bool status);
void on_txrb2_toggled(bool status);
void on_txrb3_toggled(bool status);
void on_txb2_clicked();
void on_txb3_clicked();
void on_txb4_clicked();
void on_txb5_clicked();
void on_txb6_clicked();
void on_lookupButton_clicked();
void on_addButton_clicked();
void on_dxCallEntry_textChanged (QString const&);
void on_dxGridEntry_textChanged (QString const&);
void on_dxCallEntry_returnPressed ();
void on_genStdMsgsPushButton_clicked();
void on_logQSOButton_clicked();
void on_actionJT9_triggered();
void on_actionJT65_triggered();
void on_actionJT9_JT65_triggered();
void on_actionJT4_triggered();
void on_actionFT8_triggered();
void on_TxFreqSpinBox_valueChanged(int arg1);
void on_actionSave_decoded_triggered();
void on_actionQuickDecode_toggled (bool);
void on_actionMediumDecode_toggled (bool);
void on_actionDeepestDecode_toggled (bool);
void on_inGain_valueChanged(int n);
void bumpFqso(int n);
void on_actionErase_ALL_TXT_triggered();
void on_actionErase_wsjtx_log_adi_triggered();
void startTx2();
void startP1();
void stopTx();
void stopTx2();
void on_pbCallCQ_clicked();
void on_pbAnswerCaller_clicked();
void on_pbSendRRR_clicked();
void on_pbAnswerCQ_clicked();
void on_pbSendReport_clicked();
void on_pbSend73_clicked();
void on_rbGenMsg_clicked(bool checked);
void on_rbFreeText_clicked(bool checked);
void on_freeTextMsg_currentTextChanged (QString const&);
void on_rptSpinBox_valueChanged(int n);
void killFile();
void on_tuneButton_clicked (bool);
void on_pbR2T_clicked();
void on_pbT2R_clicked();
void acceptQSO2(QDateTime const&, QString const& call, QString const& grid
, Frequency dial_freq, QString const& mode
, QString const& rpt_sent, QString const& rpt_received
, QString const& tx_power, QString const& comments
, QString const& name, QDateTime const&);
void on_bandComboBox_currentIndexChanged (int index);
void on_bandComboBox_activated (int index);
void on_readFreq_clicked();
void on_pbTxMode_clicked();
void on_RxFreqSpinBox_valueChanged(int n);
void on_cbTxLock_clicked(bool checked);
void on_outAttenuation_valueChanged (int);
void rigOpen ();
void handle_transceiver_update (Transceiver::TransceiverState const&);
void handle_transceiver_failure (QString const& reason);
void on_actionAstronomical_data_toggled (bool);
void on_actionShort_list_of_add_on_prefixes_and_suffixes_triggered();
void band_changed (Frequency);
void monitor (bool);
void stop_tuning ();
void stopTuneATU();
void auto_tx_mode(bool);
void on_actionMessage_averaging_triggered();
void on_actionInclude_averaging_toggled (bool);
void on_actionInclude_correlation_toggled (bool);
void on_actionEnable_AP_DXcall_toggled (bool);
void VHF_features_enabled(bool b);
void on_sbSubmode_valueChanged(int n);
void on_cbShMsgs_toggled(bool b);
void on_cbSWL_toggled(bool b);
void on_cbTx6_toggled(bool b);
void on_cbMenus_toggled(bool b);
void networkError (QString const&);
void on_ClrAvgButton_clicked();
void on_actionWSPR_triggered();
void on_actionWSPR_LF_triggered();
void on_syncSpinBox_valueChanged(int n);
void on_TxPowerComboBox_currentIndexChanged(const QString &arg1);
void on_sbTxPercent_valueChanged(int n);
void on_cbUploadWSPR_Spots_toggled(bool b);
void WSPR_config(bool b);
void uploadSpots();
void TxAgain();
void uploadResponse(QString response);
void on_WSPRfreqSpinBox_valueChanged(int n);
void on_pbTxNext_clicked(bool b);
void on_actionEcho_Graph_triggered();
void on_actionEcho_triggered();
void on_actionISCAT_triggered();
void on_actionFast_Graph_triggered();
void on_actionHide_Controls_toggled (bool chaecked);
void fast_decode_done();
void on_actionMeasure_reference_spectrum_triggered();
void on_actionErase_reference_spectrum_triggered();
void on_actionMeasure_phase_response_triggered();
void on_sbTR_valueChanged (int);
void on_sbFtol_valueChanged (int);
void on_cbFast9_clicked(bool b);
void on_sbCQTxFreq_valueChanged(int n);
void on_cbCQTx_toggled(bool b);
void on_actionMSK144_triggered();
void on_actionQRA64_triggered();
void on_actionFreqCal_triggered();
void splash_done ();
private:
Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo,
unsigned channels, unsigned msBuffered) const;
Q_SIGNAL void stopAudioOutputStream () const;
Q_SIGNAL void startAudioInputStream (QAudioDeviceInfo const&,
int framesPerBuffer, AudioDevice * sink,
unsigned downSampleFactor, AudioDevice::Channel) const;
Q_SIGNAL void suspendAudioInputStream () const;
Q_SIGNAL void resumeAudioInputStream () const;
Q_SIGNAL void startDetector (AudioDevice::Channel) const;
Q_SIGNAL void FFTSize (unsigned) const;
Q_SIGNAL void detectorClose () const;
Q_SIGNAL void finished () const;
Q_SIGNAL void transmitFrequency (double) const;
Q_SIGNAL void endTransmitMessage (bool quick = false) const;
Q_SIGNAL void tune (bool = true) const;
Q_SIGNAL void sendMessage (unsigned symbolsLength, double framesPerSymbol,
double frequency, double toneSpacing,
SoundOutput *, AudioDevice::Channel = AudioDevice::Mono,
bool synchronize = true, bool fastMode = false, double dBSNR = 99.,
int TRperiod=60) const;
Q_SIGNAL void outAttenuationChanged (qreal) const;
Q_SIGNAL void toggleShorthand () const;
private:
void astroUpdate ();
void writeAllTxt(QString message);
void FT8_AutoSeq(QString message);
NetworkAccessManager m_network_manager;
bool m_valid;
QSplashScreen * m_splash;
QDir m_dataDir;
QString m_revision;
bool m_multiple;
MultiSettings * m_multi_settings;
QPushButton * m_configurations_button;
QSettings * m_settings;
QScopedPointer<Ui::MainWindow> ui;
// other windows
Configuration m_config;
WSPRBandHopping m_WSPR_band_hopping;
bool m_WSPR_tx_next;
MessageBox m_rigErrorMessageBox;
QScopedPointer<SampleDownloader> m_sampleDownloader;
QScopedPointer<PhaseEqualizationDialog> m_phaseEqualizationDialog;
QScopedPointer<WideGraph> m_wideGraph;
QScopedPointer<EchoGraph> m_echoGraph;
QScopedPointer<FastGraph> m_fastGraph;
QScopedPointer<LogQSO> m_logDlg;
QScopedPointer<Astro> m_astroWidget;
QScopedPointer<HelpTextWindow> m_shortcuts;
QScopedPointer<HelpTextWindow> m_prefixes;
QScopedPointer<HelpTextWindow> m_mouseCmnds;
QScopedPointer<MessageAveraging> m_msgAvgWidget;
Transceiver::TransceiverState m_rigState;
Frequency m_lastDialFreq;
QString m_lastBand;
Frequency m_dialFreqRxWSPR; // best guess at WSPR QRG
Detector * m_detector;
unsigned m_FFTSize;
SoundInput * m_soundInput;
Modulator * m_modulator;
SoundOutput * m_soundOutput;
QThread m_audioThread;
qint64 m_msErase;
qint64 m_secBandChanged;
qint64 m_freqMoon;
Frequency m_freqNominal;
Frequency m_freqTxNominal;
Astro::Correction m_astroCorrection;
double m_s6;
double m_tRemaining;
float m_DTtol;
float m_t0;
float m_t1;
float m_t0Pick;
float m_t1Pick;
float m_fCPUmskrtd;
qint32 m_waterfallAvg;
qint32 m_ntx;
bool m_gen_message_is_cq;
qint32 m_timeout;
qint32 m_XIT;
qint32 m_setftx;
qint32 m_ndepth;
qint32 m_sec0;
qint32 m_RxLog;
qint32 m_nutc0;
qint32 m_ntr;
qint32 m_tx;
qint32 m_hsym;
qint32 m_TRperiod;
qint32 m_nsps;
qint32 m_hsymStop;
qint32 m_inGain;
qint32 m_ncw;
qint32 m_secID;
qint32 m_idleMinutes;
qint32 m_nSubMode;
qint32 m_nclearave;
qint32 m_minSync;
qint32 m_dBm;
qint32 m_pctx;
qint32 m_nseq;
qint32 m_nWSPRdecodes;
qint32 m_k0;
qint32 m_kdone;
qint32 m_nPick;
FrequencyList::const_iterator m_frequency_list_fcal_iter;
qint32 m_nTx73;
qint32 m_UTCdisk;
qint32 m_wait;
bool m_btxok; //True if OK to transmit
bool m_diskData;
bool m_loopall;
bool m_decoderBusy;
bool m_txFirst;
bool m_auto;
bool m_restart;
bool m_startAnother;
bool m_saveDecoded;
bool m_saveAll;
bool m_widebandDecode;
bool m_call3Modified;
bool m_dataAvailable;
bool m_bDecoded;
bool m_noSuffix;
bool m_blankLine;
bool m_decodedText2;
bool m_freeText;
bool m_sentFirst73;
int m_currentMessageType;
QString m_currentMessage;
int m_lastMessageType;
QString m_lastMessageSent;
bool m_lockTxFreq;
bool m_bShMsgs;
bool m_bSWL;
bool m_uploadSpots;
bool m_uploading;
bool m_txNext;
bool m_grid6;
bool m_tuneup;
bool m_bTxTime;
bool m_rxDone;
bool m_bSimplex; // not using split even if it is available
bool m_bEchoTxOK;
bool m_bTransmittedEcho;
bool m_bEchoTxed;
bool m_bFastMode;
bool m_bFast9;
bool m_bFastDecodeCalled;
bool m_bDoubleClickAfterCQnnn;
bool m_bRefSpec;
bool m_bClearRefSpec;
bool m_bTrain;
bool m_bUseRef;
bool m_bFastDone;
bool m_bAltV;
bool m_bNoMoreFiles;
bool m_bQRAsyncWarned;
bool m_bDoubleClicked;
int m_ihsym;
int m_nzap;
int m_npts8;
float m_px;
float m_pxmax;
float m_df3;
int m_iptt0;
bool m_btxok0;
int m_nsendingsh;
double m_onAirFreq0;
bool m_first_error;
char m_msg[100][80];
// labels in status bar
QLabel tx_status_label;
QLabel config_label;
QLabel mode_label;
QLabel last_tx_label;
QLabel auto_tx_label;
QLabel band_hopping_label;
QProgressBar progressBar;
QLabel watchdog_label;
QFuture<void> m_wav_future;
QFutureWatcher<void> m_wav_future_watcher;
QFutureWatcher<void> watcher3;
QFutureWatcher<QString> m_saveWAVWatcher;
QProcess proc_jt9;
QProcess p1;
QProcess p3;
WSPRNet *wsprNet;
QTimer m_guiTimer;
QTimer ptt1Timer; //StartTx delay
QTimer ptt0Timer; //StopTx delay
QTimer logQSOTimer;
QTimer killFileTimer;
QTimer tuneButtonTimer;
QTimer uploadTimer;
QTimer tuneATU_Timer;
QTimer TxAgainTimer;
QTimer minuteTimer;
QTimer splashTimer;
QTimer p1Timer;
QString m_path;
QString m_baseCall;
QString m_hisCall;
QString m_hisGrid;
QString m_appDir;
QString m_palette;
QString m_dateTime;
QString m_mode;
QString m_modeTx;
QString m_fnameWE; // save path without extension
QString m_rpt;
QString m_rptSent;
QString m_rptRcvd;
QString m_qsoStart;
QString m_qsoStop;
QString m_cmnd;
QString m_cmndP1;
QString m_msgSent0;
QString m_fileToSave;
QString m_calls;
QSet<QString> m_pfx;
QSet<QString> m_sfx;
QDateTime m_dateTimeQSOOn;
QDateTime m_dateTimeQSOOff;
QDateTime m_dateTimeDefault;
QSharedMemory *mem_jt9;
LogBook m_logBook;
DecodedText m_QSOText;
unsigned m_msAudioOutputBuffered;
unsigned m_framesAudioInputBuffered;
unsigned m_downSampleFactor;
QThread::Priority m_audioThreadPriority;
bool m_bandEdited;
bool m_splitMode;
bool m_monitoring;
bool m_tx_when_ready;
bool m_transmitting;
bool m_tune;
bool m_tx_watchdog; // true when watchdog triggered
bool m_block_pwr_tooltip;
bool m_PwrBandSetOK;
bool m_bVHFwarned;
Frequency m_lastMonitoredFrequency;
double m_toneSpacing;
int m_firstDecode;
QProgressDialog m_optimizingProgress;
QTimer m_heartbeat;
MessageClient * m_messageClient;
PSK_Reporter *psk_Reporter;
DisplayManual m_manual;
QHash<QString, QVariant> m_pwrBandTxMemory; // Remembers power level by band
QHash<QString, QVariant> m_pwrBandTuneMemory; // Remembers power level by band for tuning
QByteArray m_geometryNoControls;
QVector<double> m_phaseEqCoefficients;
//---------------------------------------------------- private functions
void readSettings();
void setDecodedTextFont (QFont const&);
void writeSettings();
void createStatusBar();
void updateStatusBar();
void genStdMsgs(QString rpt);
void genCQMsg();
void clearDX ();
void lookup();
void ba2msg(QByteArray ba, char* message);
void msgtype(QString t, QLineEdit* tx);
void stub();
void statusChanged();
void fixStop();
bool shortList(QString callsign);
void transmit (double snr = 99.);
void rigFailure (QString const& reason);
void pskSetLocal ();
void pskPost(DecodedText decodedtext);
void displayDialFrequency ();
void transmitDisplay (bool);
void processMessage(QString const& messages, qint32 position, bool ctrl);
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text);
void replayDecodes ();
void postDecode (bool is_new, QString const& message);
void postWSPRDecode (bool is_new, QStringList message_parts);
void enable_DXCC_entity (bool on);
void switch_mode (Mode);
void WSPR_scheduling ();
void freqCalStep();
void setRig (Frequency = 0); // zero frequency means no change
void WSPR_history(Frequency dialFreq, int ndecodes);
QString WSPR_hhmm(int n);
void fast_config(bool b);
void CQTxFreq();
QString save_wave_file (QString const& name
, short const * data
, int seconds
, QString const& my_callsign
, QString const& my_grid
, QString const& mode
, qint32 sub_mode
, Frequency frequency
, QString const& his_call
, QString const& his_grid) const;
void read_wav_file (QString const& fname);
void decodeDone ();
void subProcessFailed (QProcess *, int exit_code, QProcess::ExitStatus);
void subProcessError (QProcess *, QProcess::ProcessError);
void statusUpdate () const;
void update_watchdog_label ();
void on_the_minute ();
void add_child_to_event_filter (QObject *);
void remove_child_from_event_filter (QObject *);
void setup_status_bar (bool vhf);
void tx_watchdog (bool triggered);
int nWidgets(QString t);
void displayWidgets(int n);
void vhfWarning();
QChar current_submode () const; // returns QChar {0} if sub mode is
// not appropriate
};
extern int killbyname(const char* progName);
extern void getDev(int* numDevices,char hostAPI_DeviceName[][50],
int minChan[], int maxChan[],
int minSpeed[], int maxSpeed[]);
extern int next_tx_state(int pctx);
#endif // MAINWINDOW_H
@@ -0,0 +1,20 @@
subroutine unpackname(n1,n2,name,len)
character*9 name
real*8 dn
dn=32768.d0*n1 + n2
len=0
do i=9,1,-1
j=mod(dn,27.d0)
if(j.ge.1) then
name(i:i)=char(64+j)
len=len+1
else
name(i:i)=' '
endif
dn=dn/27.d0
enddo
return
end subroutine unpackname