Add basic ap functionality. Needs testing for decoding speed.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7806 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Steven Franke 2017-07-07 20:24:00 +00:00
parent 5e0265a5ab
commit cdfd224974
6 changed files with 117 additions and 49 deletions

View File

@ -1,4 +1,4 @@
subroutine ft8b(dd0,newdat,nfqso,ndepth,icand,sync0,f1,xdt,nharderrors, & subroutine ft8b(dd0,newdat,nfqso,ndepth,icand,sync0,f1,xdt,apsym,nharderrors, &
dmin,nbadcrc,message,xsnr) dmin,nbadcrc,message,xsnr)
use timer_module, only: timer use timer_module, only: timer
@ -9,14 +9,17 @@ subroutine ft8b(dd0,newdat,nfqso,ndepth,icand,sync0,f1,xdt,nharderrors, &
real a(5) real a(5)
real s1(0:7,ND),s2(0:7,NN) real s1(0:7,ND),s2(0:7,NN)
real ps(0:7) real ps(0:7)
real rxdata(3*ND),llr(3*ND) !Soft symbols real rxdata(3*ND),llr(3*ND),llrap(3*ND) !Soft symbols
real dd0(15*12000) real dd0(15*12000)
integer*1 decoded(KK),apmask(3*ND),cw(3*ND) integer*1 decoded(KK),apmask(3*ND),cw(3*ND)
integer*1 msgbits(KK)
integer apsym(KK),rr73(11)
integer itone(NN) integer itone(NN)
complex cd0(3200) complex cd0(3200)
complex ctwk(32) complex ctwk(32)
complex csymb(32) complex csymb(32)
logical newdat logical newdat
data rr73/-1,1,1,1,1,1,1,-1,1,1,-1/
max_iterations=40 max_iterations=40
norder=2 norder=2
@ -106,34 +109,69 @@ subroutine ft8b(dd0,newdat,nfqso,ndepth,icand,sync0,f1,xdt,nharderrors, &
rxdata=rxdata/rxsig rxdata=rxdata/rxsig
ss=0.84 ss=0.84
llr=2.0*rxdata/(ss*ss) llr=2.0*rxdata/(ss*ss)
apmask=0
cw=0 do iap=0,3
call timer('bpd174 ',0) if(iap.eq.0) then
call bpdecode174(llr,apmask,max_iterations,decoded,cw,nharderrors) apmask=0
call timer('bpd174 ',1) apmask(160:162)=1
dmin=0.0 llrap=llr
if(nharderrors.lt.0) then llrap(160:162)=5.0*apsym(73:75)/ss
call timer('osd174 ',0) elseif(iap.eq.1) then
call osd174(llr,norder,decoded,cw,nharderrors,dmin) apmask=0
call timer('osd174 ',1) apmask(88:115)=1 ! mycall
endif apmask(160:162)=1 ! 3 extra bits
nbadcrc=1 llrap=0.0
message=' ' llrap(88:115)=5.0*apsym(1:28)/ss
xsnr=-99.0 llrap(160:162)=5.0*apsym(73:75)/ss
if(count(cw.eq.0).eq.174) go to 900 !Reject the all-zero codeword where(apmask.eq.0) llrap=llr
if( nharderrors.ge.0 .and. dmin.le.30.0 .and. nharderrors .lt. 30) then elseif(iap.eq.2) then
call chkcrc12a(decoded,nbadcrc) apmask=0
else apmask(88:115)=1 ! mycall
nharderrors=-1 apmask(116:143)=1 ! hiscall
go to 900 apmask(160:162)=1 ! 3 extra bits
endif llrap=0.0
if(nbadcrc.eq.0) then llrap(88:143)=5.0*apsym(1:56)/ss
call extractmessage174(decoded,message,ncrcflag,recent_calls,nrecent) llrap(160:162)=5.0*apsym(73:75)/ss
call genft8(message,msgsent,itone) where(apmask.eq.0) llrap=llr
elseif(iap.eq.3) then
apmask=0
apmask(88:115)=1 ! mycall
apmask(116:143)=1 ! hiscall
apmask(144:154)=1 ! RRR or 73
apmask(160:162)=1 ! 3 extra bits
llrap=0.0
llrap(88:143)=5.0*apsym(1:56)/ss
llrap(144:154)=5.0*rr73/ss
llrap(160:162)=5.0*apsym(73:75)/ss
where(apmask.eq.0) llrap=llr
endif
cw=0
call timer('bpd174 ',0)
call bpdecode174(llrap,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)
endif
nbadcrc=1
message=' '
xsnr=-99.0
if(count(cw.eq.0).eq.174) cycle !Reject the all-zero codeword
if( nharderrors.ge.0 .and. dmin.le.30.0 .and. nharderrors .lt. 30) then
call chkcrc12a(decoded,nbadcrc)
else
nharderrors=-1
cycle
endif
if(nbadcrc.eq.0) then
call extractmessage174(decoded,message,ncrcflag,recent_calls,nrecent)
call genft8(message,msgsent,msgbits,itone)
! call subtractft8(dd0,itone,f1,xdt2) ! call subtractft8(dd0,itone,f1,xdt2)
xsig=0.0 xsig=0.0
xnoi=0.0 xnoi=0.0
do i=1,79 do i=1,79
xsig=xsig+s2(itone(i),i)**2 xsig=xsig+s2(itone(i),i)**2
ios=mod(itone(i)+4,7) ios=mod(itone(i)+4,7)
xnoi=xnoi+s2(ios,i)**2 xnoi=xnoi+s2(ios,i)**2
@ -142,10 +180,10 @@ subroutine ft8b(dd0,newdat,nfqso,ndepth,icand,sync0,f1,xdt,nharderrors, &
if( xnoi.gt.0 .and. xnoi.lt.xsig ) xsnr=xsig/xnoi-1.0 if( xnoi.gt.0 .and. xnoi.lt.xsig ) xsnr=xsig/xnoi-1.0
xsnr=10.0*log10(xsnr)-27.0 xsnr=10.0*log10(xsnr)-27.0
if( xsnr .lt. -24.0 ) xsnr=-24.0 if( xsnr .lt. -24.0 ) xsnr=-24.0
! write(50,3050) icand,sync0,f1,xdt,nharderrors,dmin,message ! write(50,3050) icand,sync0,f1,xdt,nharderrors,dmin,message,iap
!3050 format(i3,3f10.3,i5,f10.3,2x,a22) !3050 format(i3,3f10.3,i5,f10.3,2x,a22,i3)
endif return
endif
900 continue enddo
return return
end subroutine ft8b end subroutine ft8b

View File

@ -11,6 +11,7 @@ program ft8sim
complex c0(0:NMAX-1) complex c0(0:NMAX-1)
complex c(0:NMAX-1) complex c(0:NMAX-1)
integer itone(NN) integer itone(NN)
integer*1 msgbits(KK)
integer*2 iwave(NMAX) !Generated full-length waveform integer*2 iwave(NMAX) !Generated full-length waveform
! Get command-line argument(s) ! Get command-line argument(s)
@ -44,11 +45,16 @@ program ft8sim
if(snrdb.gt.90.0) sig=1.0 if(snrdb.gt.90.0) sig=1.0
txt=NN*NSPS/12000.0 txt=NN*NSPS/12000.0
call genft8(msg,msgsent,itone) !Source-encode, then get itone() call genft8(msg,msgsent,msgbits,itone) !Source-encode, then get itone()
write(*,1000) f0,xdt,txt,snrdb,bw,msgsent write(*,1000) f0,xdt,txt,snrdb,bw,msgsent
1000 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, & 1000 format('f0:',f9.3,' DT:',f6.2,' TxT:',f6.1,' SNR:',f6.1, &
' BW:',f4.1,2x,a22) ' BW:',f4.1,2x,a22)
write(*,'(28i1,1x,28i1)') msgbits(1:56)
write(*,'(16i1)') msgbits(57:72)
write(*,'(3i1)') msgbits(73:75)
write(*,'(12i1)') msgbits(76:87)
! call sgran() ! call sgran()
c=0. c=0.
do ifile=1,nfiles do ifile=1,nfiles

View File

@ -1,4 +1,4 @@
subroutine genft8(msg,msgsent,itone) subroutine genft8(msg,msgsent,msgbits,itone)
! Encode an FT8 message, producing array itone(). ! Encode an FT8 message, producing array itone().

View File

@ -23,7 +23,7 @@ module ft8_decode
contains contains
subroutine decode(this,callback,iwave,nfqso,newdat,nutc,nfa, & subroutine decode(this,callback,iwave,nfqso,newdat,nutc,nfa, &
nfb,nagain,ndepth,nsubmode,mycall,hiscall,hisgrid) nfb,nagain,ndepth,nsubmode,mycall12,hiscall12,hisgrid6)
!use wavhdr !use wavhdr
use timer_module, only: timer use timer_module, only: timer
include 'fsk4hf/ft8_params.f90' include 'fsk4hf/ft8_params.f90'
@ -35,9 +35,10 @@ contains
real candidate(3,200) real candidate(3,200)
real dd(15*12000) real dd(15*12000)
logical, intent(in) :: newdat, nagain logical, intent(in) :: newdat, nagain
character*12 mycall, hiscall character*12 mycall12, hiscall12
character*6 hisgrid character*6 hisgrid6
integer*2 iwave(15*12000) integer*2 iwave(15*12000)
integer apsym(KK)
character datetime*13,message*22 character datetime*13,message*22
save s,dd save s,dd
@ -45,8 +46,10 @@ contains
write(datetime,1001) nutc !### TEMPORARY ### write(datetime,1001) nutc !### TEMPORARY ###
1001 format("000000_",i6.6) 1001 format("000000_",i6.6)
dd=iwave if(index(hisgrid6," ").eq.0) hisgrid6="EN50"
call ft8apset(mycall12,hiscall12,hisgrid6,apsym)
dd=iwave
call timer('sync8 ',0) call timer('sync8 ',0)
call sync8(dd,nfa,nfb,nfqso,s,candidate,ncand) call sync8(dd,nfa,nfb,nfqso,s,candidate,ncand)
call timer('sync8 ',1) call timer('sync8 ',1)
@ -59,7 +62,7 @@ contains
xdt=candidate(2,icand) xdt=candidate(2,icand)
nsnr0=min(99,nint(10.0*log10(sync) - 25.5)) !### empirical ### nsnr0=min(99,nint(10.0*log10(sync) - 25.5)) !### empirical ###
call timer('ft8b ',0) call timer('ft8b ',0)
call ft8b(dd,newdat,nfqso,ndepth,icand,sync,f1,xdt,nharderrors, & call ft8b(dd,newdat,nfqso,ndepth,icand,sync,f1,xdt,apsym,nharderrors, &
dmin,nbadcrc,message,xsnr) dmin,nbadcrc,message,xsnr)
nsnr=xsnr nsnr=xsnr
xdt=xdt-0.6 xdt=xdt-0.6
@ -82,3 +85,23 @@ contains
end subroutine decode end subroutine decode
end module ft8_decode end module ft8_decode
subroutine ft8apset(mycall12,hiscall12,hisgrid6,apsym)
parameter(NAPM=4,KK=87)
character*12 mycall12,hiscall12
character*22 msg,msgsent
character*6 mycall,hiscall
character*6 hisgrid6
character*4 hisgrid
integer apsym(KK)
integer*1 msgbits(KK)
integer itone(KK)
mycall=mycall12(1:6)
hiscall=hiscall12(1:6)
hisgrid=hisgrid6(1:4)
msg=mycall//' '//hiscall//' '//hisgrid
call genft8(msg,msgsent,msgbits,itone)
apsym=2*msgbits-1
return
end subroutine ft8apset

View File

@ -50,7 +50,7 @@ program jt9
'THREADS'), & 'THREADS'), &
option ('jt65', .false., '6', 'JT65 mode', ''), & option ('jt65', .false., '6', 'JT65 mode', ''), &
option ('jt9', .false., '9', 'JT9 mode', ''), & option ('jt9', .false., '9', 'JT9 mode', ''), &
option ('ft9', .false., '8', 'FT8 mode', ''), & option ('ft8', .false., '8', 'FT8 mode', ''), &
option ('jt4', .false., '4', 'JT4 mode', ''), & option ('jt4', .false., '4', 'JT4 mode', ''), &
option ('qra64', .false., 'q', 'QRA64 mode', ''), & option ('qra64', .false., 'q', 'QRA64 mode', ''), &
option ('sub-mode', .true., 'b', 'Sub mode, default SUBMODE=A', 'A'), & option ('sub-mode', .true., 'b', 'Sub mode, default SUBMODE=A', 'A'), &
@ -264,9 +264,9 @@ program jt9
shared_data%params%minsync=0 !### TEST ONLY shared_data%params%minsync=0 !### TEST ONLY
! shared_data%params%nfqso=1500 !### TEST ONLY ! shared_data%params%nfqso=1500 !### TEST ONLY
mycall="G3WDG " !### TEST ONLY ! mycall="G3WDG " !### TEST ONLY
hiscall="VK7MO " !### TEST ONLY ! hiscall="VK7MO " !### TEST ONLY
hisgrid="QE37 " !### TEST ONLY ! hisgrid="QE37 " !### TEST ONLY
if(mode.eq.164 .and. nsubmode.lt.100) nsubmode=nsubmode+100 if(mode.eq.164 .and. nsubmode.lt.100) nsubmode=nsubmode+100
shared_data%params%naggressive=0 shared_data%params%naggressive=0

View File

@ -75,7 +75,7 @@ extern "C" {
int len1, int len2, int len3, int len4, int len5); int len1, int len2, int len3, int len4, int len5);
// float s[], int* jh, char line[], char mygrid[], // float s[], int* jh, char line[], char mygrid[],
void genft8_(char* msg, char* msgsent, int itone[], int len1, int len2); void genft8_(char* msg, char* msgsent, char ft8msgbits[], int itone[], int len1, int len2);
void gen4_(char* msg, int* ichk, char* msgsent, int itone[], void gen4_(char* msg, int* ichk, char* msgsent, int itone[],
int* itext, int len1, int len2); int* itext, int len1, int len2);
@ -132,6 +132,7 @@ extern "C" {
} }
int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols
char volatile ft8msgbits[75]; //packed 75 bit ft8 message
int volatile icw[NUM_CW_SYMBOLS]; //Dits for CW ID int volatile icw[NUM_CW_SYMBOLS]; //Dits for CW ID
struct dec_data dec_data; // for sharing with Fortran struct dec_data dec_data; // for sharing with Fortran
@ -3059,7 +3060,7 @@ void MainWindow::guiUpdate()
len1, len1); len1, len1);
if(m_mode=="WSPR-LF") genwspr_fsk8_(message, msgsent, const_cast<int *> (itone), if(m_mode=="WSPR-LF") genwspr_fsk8_(message, msgsent, const_cast<int *> (itone),
len1, len1); len1, len1);
if(m_mode=="FT8") genft8_(message, msgsent, const_cast<int *> (itone), len1, len1); if(m_mode=="FT8") genft8_(message, msgsent, const_cast<char *> (ft8msgbits), const_cast<int *> (itone), len1, len1);
if(m_modeTx=="MSK144") { if(m_modeTx=="MSK144") {
bool bcontest=m_config.contestMode(); bool bcontest=m_config.contestMode();
char MyGrid[6]; char MyGrid[6];